Commit e65c7058 authored by Enrico Ros's avatar Enrico Ros

Added the MiniBar class, a layouted widget that displays current page

 number, the total number of pages and a little grahical 'progress'
 indicator. Moved 'next page' and 'prev page' buttons from the main toolbar
 to the MiniBar. Minibar lets you edit the page number, click or wheel on
 progress, go to next/prev page, show the gotoPage dialog.
Added rmb popup when clicking on thumbnails. When clicking, the
 ThumbnailList only emits the same signal emitted by PageView so the same
 context menu is displayed.
Misc fixes: [MEM] enabled allocated pages raising in queue when displayed
 again, [ThumbnailList] enabled PageUp/PageDown.

svn path=/trunk/kdegraphics/kpdf/; revision=382597
parent bbfb5301
...@@ -12,19 +12,13 @@ Status: ...@@ -12,19 +12,13 @@ Status:
In progress: In progress:
-> new word highlighting for searches / other highlights -> new word highlighting for searches / other highlights
-> implement history (for actionNamed and restoring previous viewports on navigation)
High priority 3.4 features (deadline is 2k5-Feb-2): High priority 3.4 features (deadline is 2k5-Feb-2):
-> display current page / total pages (with analog indicator too (progressbar/...)) - empty! -
maybe this can be done on a small widget at the top of the toolbox, displaying
'document' informations (pages, current pg, some metadata, etc..)
Tested a 16px ktoolbar in the left-bottom corner.. looks goos and can be used to
insert some actions that aren't so useful in the main (and bigger) toolbar
-> implement history (for actionNamed and restoring previous viewports on navigation)
-> rmb popup for bookmarking pages on thumbnailslist, showing bkmarked pages and
go to next/previous bookmark actions (support for showing bookmarked pages
is already in, but disabled)
More items (first items will enter 'In progress list' first): More items (first items will enter 'In progress list' first):
-> go to next/previous bookmark actions (showing in thumbnailslist rmb popup too)
-> viewport restoring: sometimes it seems to restore the viewport a bit under where it was -> viewport restoring: sometimes it seems to restore the viewport a bit under where it was
-> presentation: provide a pageX/totalPages indicator in addition to the circle one -> presentation: provide a pageX/totalPages indicator in addition to the circle one
-> add scrollbar marks for bookmarks (like kate) -> add scrollbar marks for bookmarks (like kate)
...@@ -91,6 +85,8 @@ More items (first items will enter 'In progress list' first): ...@@ -91,6 +85,8 @@ More items (first items will enter 'In progress list' first):
-> export: export to other formats keeping formatting (a dream.. except for PNG :-) (PS is easy, we just have PSOutputDev that does it :-D) -> export: export to other formats keeping formatting (a dream.. except for PNG :-) (PS is easy, we just have PSOutputDev that does it :-D)
Done (newest features come first): Done (newest features come first):
-> ADD: rmb popup on thumbnailslist (the popup shared with pageView: same behavior)
-> ADD: display 'current page' / 'total pages' with analog indicator, active labels, etc
-> CHG: Presentation mode is now Ctrl+Shift+p instead of F9 because it was colliding with Konqueror's toggle sidebar -> CHG: Presentation mode is now Ctrl+Shift+p instead of F9 because it was colliding with Konqueror's toggle sidebar
-> FIX: various in memory unallocator, preload with single pages, pageview -> FIX: various in memory unallocator, preload with single pages, pageview
-> FIX: optimized pageView (removed 1 waster req on start, lowered reqs) -> FIX: optimized pageView (removed 1 waster req on start, lowered reqs)
......
...@@ -51,7 +51,7 @@ class KPDFDocumentPrivate ...@@ -51,7 +51,7 @@ class KPDFDocumentPrivate
QString docFileName; QString docFileName;
QString xmlFileName; QString xmlFileName;
// observers / requests stuff // observers / requests / allocator stuff
QMap< int, DocumentObserver * > observers; QMap< int, DocumentObserver * > observers;
QValueList< PixmapRequest * > pixmapRequestsStack; QValueList< PixmapRequest * > pixmapRequestsStack;
QValueList< class AllocatedPixmap * > allocatedPixmapsFifo; QValueList< class AllocatedPixmap * > allocatedPixmapsFifo;
...@@ -76,6 +76,9 @@ struct AllocatedPixmap ...@@ -76,6 +76,9 @@ struct AllocatedPixmap
QMap< int, DocumentObserver * >::iterator it=d->observers.begin(), end=d->observers.end();\ QMap< int, DocumentObserver * >::iterator it=d->observers.begin(), end=d->observers.end();\
for ( ; it != end ; ++ it ) { (*it)-> cmd ; } } for ( ; it != end ; ++ it ) { (*it)-> cmd ; } }
/** KPDFDocument **/
KPDFDocument::KPDFDocument() KPDFDocument::KPDFDocument()
: generator( 0 ), d( new KPDFDocumentPrivate ) : generator( 0 ), d( new KPDFDocumentPrivate )
{ {
...@@ -201,7 +204,7 @@ void KPDFDocument::closeDocument() ...@@ -201,7 +204,7 @@ void KPDFDocument::closeDocument()
delete *pIt; delete *pIt;
pages_vector.clear(); pages_vector.clear();
// clear memory allocation descriptors // clear 'memory allocation' descriptors
QValueList< AllocatedPixmap * >::iterator aIt = d->allocatedPixmapsFifo.begin(); QValueList< AllocatedPixmap * >::iterator aIt = d->allocatedPixmapsFifo.begin();
QValueList< AllocatedPixmap * >::iterator aEnd = d->allocatedPixmapsFifo.end(); QValueList< AllocatedPixmap * >::iterator aEnd = d->allocatedPixmapsFifo.end();
for ( ; aIt != aEnd; ++aIt ) for ( ; aIt != aEnd; ++aIt )
...@@ -260,7 +263,7 @@ void KPDFDocument::reparseConfig() ...@@ -260,7 +263,7 @@ void KPDFDocument::reparseConfig()
d->allocatedPixmapsTotalMemory = 0; d->allocatedPixmapsTotalMemory = 0;
// send reload signals to observers // send reload signals to observers
foreachObserver( notifyContentsCleared( DocumentObserver::Pixmap) ); foreachObserver( notifyContentsCleared( DocumentObserver::Pixmap ) );
} }
// free memory if in 'low' profile // free memory if in 'low' profile
...@@ -320,12 +323,6 @@ void KPDFDocument::requestPixmaps( const QValueList< PixmapRequest * > & request ...@@ -320,12 +323,6 @@ void KPDFDocument::requestPixmaps( const QValueList< PixmapRequest * > & request
if ( !generator || requests.isEmpty() ) if ( !generator || requests.isEmpty() )
return; return;
#ifndef NDEBUG
//TODO REMOVE THIS
if ( !d->pixmapRequestsStack.isEmpty() && (*d->pixmapRequestsStack.begin())->priority == 0 )
kdDebug() << "calling requestPixmaps when SYNC generation has not yet finished." << endl;
#endif
// 1. [CLEAN STACK] remove previous requests of requesterID // 1. [CLEAN STACK] remove previous requests of requesterID
int requesterID = requests.first()->id; int requesterID = requests.first()->id;
QValueList< PixmapRequest * >::iterator sIt = d->pixmapRequestsStack.begin(), sEnd = d->pixmapRequestsStack.end(); QValueList< PixmapRequest * >::iterator sIt = d->pixmapRequestsStack.begin(), sEnd = d->pixmapRequestsStack.end();
...@@ -427,24 +424,26 @@ void KPDFDocument::setViewport( const DocumentViewport & viewport, int id ) ...@@ -427,24 +424,26 @@ void KPDFDocument::setViewport( const DocumentViewport & viewport, int id )
if ( it.key() != id ) if ( it.key() != id )
(*it)->notifyViewportChanged(); (*it)->notifyViewportChanged();
/* [MEM] raise position of currently viewed page in allocation queue // [MEM] raise position of currently viewed page in allocation queue
if ( d->allocatedPixmapsFifo.count() > 1 ) if ( d->allocatedPixmapsFifo.count() > 1 )
{ {
const int page = viewport.pageNumber;
QValueList< AllocatedPixmap * > viewportPixmaps;
QValueList< AllocatedPixmap * >::iterator aIt = d->allocatedPixmapsFifo.begin(); QValueList< AllocatedPixmap * >::iterator aIt = d->allocatedPixmapsFifo.begin();
QValueList< AllocatedPixmap * >::iterator aLast = d->allocatedPixmapsFifo.end(); QValueList< AllocatedPixmap * >::iterator aEnd = d->allocatedPixmapsFifo.end();
--aLast; while ( aIt != aEnd )
while ( aIt != aLast )
{ {
if ( (*aIt)->page == viewport.pageNumber ) if ( (*aIt)->page == page )
{ {
d->allocatedPixmapsFifo.append( *aIt ); viewportPixmaps.append( *aIt );
aIt = d->allocatedPixmapsFifo.remove( aIt ); aIt = d->allocatedPixmapsFifo.remove( aIt );
p--rintf("%d raised prio of %d %d\n",d->allocatedPixmapsFifo.count(), (*aIt)->id, (*aIt)->page); continue;
} }
else ++aIt;
++aIt;
} }
}*/ if ( !viewportPixmaps.isEmpty() )
d->allocatedPixmapsFifo += viewportPixmaps;
}
} }
bool KPDFDocument::findText( const QString & string, bool keepCase, bool findAhead ) bool KPDFDocument::findText( const QString & string, bool keepCase, bool findAhead )
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define PAGEVIEW_ID 3 #define PAGEVIEW_ID 3
#define THUMBNAILS_ID 4 #define THUMBNAILS_ID 4
#define TOC_ID 5 #define TOC_ID 5
#define MINIBAR_ID 6
/** PRIORITIES for requests. Globally defined here. **/ /** PRIORITIES for requests. Globally defined here. **/
#define PAGEVIEW_PRIO 1 #define PAGEVIEW_PRIO 1
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include "ui/thumbnaillist.h" #include "ui/thumbnaillist.h"
#include "ui/searchwidget.h" #include "ui/searchwidget.h"
#include "ui/toc.h" #include "ui/toc.h"
#include "ui/minibar.h"
#include "ui/propertiesdialog.h" #include "ui/propertiesdialog.h"
#include "ui/presentationwidget.h" #include "ui/presentationwidget.h"
#include "conf/preferencesdialog.h" #include "conf/preferencesdialog.h"
...@@ -110,10 +111,15 @@ Part::Part(QWidget *parentWidget, const char *widgetName, ...@@ -110,10 +111,15 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
m_watchFile = new KToggleAction( i18n( "&Watch File" ), 0, this, SLOT( slotWatchFile() ), actionCollection(), "watch_file" ); m_watchFile = new KToggleAction( i18n( "&Watch File" ), 0, this, SLOT( slotWatchFile() ), actionCollection(), "watch_file" );
m_watchFile->setChecked( Settings::watchFile() ); m_watchFile->setChecked( Settings::watchFile() );
// widgets: [left toolbox] | [] // widgets: [left panel] | []
m_toolBox = new QToolBox( m_splitter ); QWidget * leftPanel = new QWidget( m_splitter );
m_toolBox->setMinimumWidth( 80 ); leftPanel->setMinimumWidth( 90 );
m_toolBox->setMaximumWidth( 300 ); leftPanel->setMaximumWidth( 300 );
QVBoxLayout * leftPanelLayout = new QVBoxLayout( leftPanel );
// widgets: [left toolbox/..] | []
m_toolBox = new QToolBox( leftPanel );
leftPanelLayout->addWidget( m_toolBox );
// [left toolbox: Table of Contents] | [] // [left toolbox: Table of Contents] | []
TOC * tocFrame = new TOC( m_toolBox, m_document ); TOC * tocFrame = new TOC( m_toolBox, m_document );
...@@ -127,6 +133,7 @@ Part::Part(QWidget *parentWidget, const char *widgetName, ...@@ -127,6 +133,7 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
m_thumbnailList = new ThumbnailList( thumbsBox, m_document ); m_thumbnailList = new ThumbnailList( thumbsBox, m_document );
// ThumbnailController * m_tc = new ThumbnailController( thumbsBox, m_thumbnailList ); // ThumbnailController * m_tc = new ThumbnailController( thumbsBox, m_thumbnailList );
connect( m_thumbnailList, SIGNAL( urlDropped( const KURL& ) ), SLOT( openURL( const KURL & )) ); connect( m_thumbnailList, SIGNAL( urlDropped( const KURL& ) ), SLOT( openURL( const KURL & )) );
connect( m_thumbnailList, SIGNAL( rightClick(const KPDFPage *, const QPoint &) ), this, SLOT( slotShowMenu(const KPDFPage *, const QPoint &) ) );
// shrink the bottom toolbar (todo: find a less hackish way) // shrink the bottom toolbar (todo: find a less hackish way)
thumbsBox->setStretchFactor( m_searchWidget, 100 ); thumbsBox->setStretchFactor( m_searchWidget, 100 );
thumbsBox->setStretchFactor( m_thumbnailList, 100 ); thumbsBox->setStretchFactor( m_thumbnailList, 100 );
...@@ -139,6 +146,18 @@ Part::Part(QWidget *parentWidget, const char *widgetName, ...@@ -139,6 +146,18 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
int iIdx = m_toolBox->addItem( editFrame, QIconSet(SmallIcon("pencil")), i18n("Annotations") ); int iIdx = m_toolBox->addItem( editFrame, QIconSet(SmallIcon("pencil")), i18n("Annotations") );
m_toolBox->setItemEnabled( iIdx, false );*/ m_toolBox->setItemEnabled( iIdx, false );*/
// widgets: [../miniBarContainer] | []
QWidget * miniBarContainer = new QWidget( leftPanel );
leftPanelLayout->addWidget( miniBarContainer );
QVBoxLayout * miniBarLayout = new QVBoxLayout( miniBarContainer );
// widgets: [../[spacer/..]] | []
QWidget * miniSpacer = new QWidget( miniBarContainer );
miniSpacer->setFixedHeight( 6 );
miniBarLayout->addWidget( miniSpacer );
// widgets: [../[../MiniBar]] | []
MiniBar * miniBar = new MiniBar( miniBarContainer, m_document );
miniBarLayout->addWidget( miniBar );
// widgets: [] | [right 'pageView'] // widgets: [] | [right 'pageView']
m_pageView = new PageView( m_splitter, m_document ); m_pageView = new PageView( m_splitter, m_document );
m_pageView->setFocus(); //usability setting m_pageView->setFocus(); //usability setting
...@@ -150,6 +169,7 @@ Part::Part(QWidget *parentWidget, const char *widgetName, ...@@ -150,6 +169,7 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
m_document->addObserver( m_thumbnailList ); m_document->addObserver( m_thumbnailList );
m_document->addObserver( m_pageView ); m_document->addObserver( m_pageView );
m_document->addObserver( tocFrame ); m_document->addObserver( tocFrame );
m_document->addObserver( miniBar );
// ACTIONS // ACTIONS
KActionCollection * ac = actionCollection(); KActionCollection * ac = actionCollection();
...@@ -157,14 +177,20 @@ Part::Part(QWidget *parentWidget, const char *widgetName, ...@@ -157,14 +177,20 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
// Page Traversal actions // Page Traversal actions
m_gotoPage = KStdAction::gotoPage( this, SLOT( slotGoToPage() ), ac, "goto_page" ); m_gotoPage = KStdAction::gotoPage( this, SLOT( slotGoToPage() ), ac, "goto_page" );
m_gotoPage->setShortcut( "CTRL+G" ); m_gotoPage->setShortcut( "CTRL+G" );
// dirty way to activate gotopage when pressing miniBar's button
connect( miniBar, SIGNAL( gotoPage() ), m_gotoPage, SLOT( activate() ) );
m_prevPage = KStdAction::prior(this, SLOT(slotPreviousPage()), ac, "previous_page"); m_prevPage = KStdAction::prior(this, SLOT(slotPreviousPage()), ac, "previous_page");
m_prevPage->setWhatsThis( i18n( "Moves to the previous page of the document" ) ); m_prevPage->setWhatsThis( i18n( "Moves to the previous page of the document" ) );
m_prevPage->setShortcut( "Backspace" ); m_prevPage->setShortcut( "Backspace" );
// dirty way to activate prev page when pressing miniBar's button
connect( miniBar, SIGNAL( prevPage() ), m_prevPage, SLOT( activate() ) );
m_nextPage = KStdAction::next(this, SLOT(slotNextPage()), ac, "next_page" ); m_nextPage = KStdAction::next(this, SLOT(slotNextPage()), ac, "next_page" );
m_nextPage->setWhatsThis( i18n( "Moves to the next page of the document" ) ); m_nextPage->setWhatsThis( i18n( "Moves to the next page of the document" ) );
m_nextPage->setShortcut( "Space" ); m_nextPage->setShortcut( "Space" );
// dirty way to activate next page when pressing miniBar's button
connect( miniBar, SIGNAL( nextPage() ), m_nextPage, SLOT( activate() ) );
m_firstPage = KStdAction::firstPage( this, SLOT( slotGotoFirst() ), ac, "first_page" ); m_firstPage = KStdAction::firstPage( this, SLOT( slotGotoFirst() ), ac, "first_page" );
m_firstPage->setWhatsThis( i18n( "Moves to the first page of the document" ) ); m_firstPage->setWhatsThis( i18n( "Moves to the first page of the document" ) );
...@@ -189,7 +215,7 @@ Part::Part(QWidget *parentWidget, const char *widgetName, ...@@ -189,7 +215,7 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
m_showPresentation = new KAction( i18n("P&resentation"), "kpresenter_kpr", "Ctrl+Shift+P", this, SLOT(slotShowPresentation()), ac, "presentation"); m_showPresentation = new KAction( i18n("P&resentation"), "kpresenter_kpr", "Ctrl+Shift+P", this, SLOT(slotShowPresentation()), ac, "presentation");
m_showPresentation->setEnabled( false ); m_showPresentation->setEnabled( false );
// attach the actions of the 2 children widgets too // attach the actions of the children widgets too
m_pageView->setupActions( ac ); m_pageView->setupActions( ac );
// apply configuration (both internal settings and GUI configured items) // apply configuration (both internal settings and GUI configured items)
......
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="kpdf_part" version="14"> <kpartgui name="kpdf_part" version="15">
<MenuBar> <MenuBar>
<Menu name="file"><text>&amp;File</text> <Menu name="file"><text>&amp;File</text>
<Action name="save" group="file_save"/> <Action name="save" group="file_save"/>
...@@ -42,9 +42,6 @@ ...@@ -42,9 +42,6 @@
</Menu> </Menu>
</MenuBar> </MenuBar>
<ToolBar name="mainToolBar"><text>Main Toolbar</text> <ToolBar name="mainToolBar"><text>Main Toolbar</text>
<Separator/>
<Action name="previous_page"/>
<Action name="next_page"/>
<Separator/> <Separator/>
<Action name="zoom_in"/> <Action name="zoom_in"/>
<Action name="zoom_to" /> <Action name="zoom_to" />
......
...@@ -145,6 +145,8 @@ void Shell::setupActions() ...@@ -145,6 +145,8 @@ void Shell::setupActions()
KAction * openAction = KStdAction::open(this, SLOT(fileOpen()), actionCollection()); KAction * openAction = KStdAction::open(this, SLOT(fileOpen()), actionCollection());
m_recent = KStdAction::openRecent( this, SLOT( openURL( const KURL& ) ), actionCollection() ); m_recent = KStdAction::openRecent( this, SLOT( openURL( const KURL& ) ), actionCollection() );
connect( m_recent, SIGNAL( activated() ), openAction, SLOT( activate() ) ); connect( m_recent, SIGNAL( activated() ), openAction, SLOT( activate() ) );
// the following line doesn't work! don't know why... -enrico
//m_recent->setToolTip( i18n("Click to open a file\nClick and hold to open a recent file") );
KStdAction::print(m_part, SLOT(slotPrint()), actionCollection()); KStdAction::print(m_part, SLOT(slotPrint()), actionCollection());
KStdAction::quit(this, SLOT(slotQuit()), actionCollection()); KStdAction::quit(this, SLOT(slotQuit()), actionCollection());
......
...@@ -4,7 +4,8 @@ METASOURCES = AUTO ...@@ -4,7 +4,8 @@ METASOURCES = AUTO
libkpdfui_la_SOURCES = pageview.cpp pageviewutils.cpp thumbnaillist.cpp \ libkpdfui_la_SOURCES = pageview.cpp pageviewutils.cpp thumbnaillist.cpp \
toc.cpp searchwidget.cpp \ toc.cpp searchwidget.cpp \
propertiesdialog.cpp presentationwidget.cpp propertiesdialog.cpp presentationwidget.cpp \
minibar.cpp
noinst_LTLIBRARIES = libkpdfui.la noinst_LTLIBRARIES = libkpdfui.la
......
/***************************************************************************
* Copyright (C) 2005 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 <qvariant.h>
#include <qpushbutton.h>
#include <qframe.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qvalidator.h>
#include <qpainter.h>
#include <kiconloader.h>
#include <kaccelmanager.h>
// local includes
#include "core/document.h"
#include "minibar.h"
// [private widget] show progress
class ProgressWidget : public QWidget
{
public:
ProgressWidget( MiniBar * parent );
void setProgress( float percentage );
protected:
void mouseMoveEvent( QMouseEvent * e );
void mousePressEvent( QMouseEvent * e );
void wheelEvent( QWheelEvent * e );
void paintEvent( QPaintEvent * e );
private:
MiniBar * m_miniBar;
float m_progressPercentage;
};
// [private widget] lineEdit for entering/validating page numbers
class PagesEdit : public QLineEdit
{
public:
PagesEdit( MiniBar * parent );
void setPagesNumber( int pages );
void setText( const QString & );
protected:
void focusInEvent( QFocusEvent * e );
void focusOutEvent( QFocusEvent * e );
void mousePressEvent( QMouseEvent * e );
void wheelEvent( QWheelEvent * e );
private:
MiniBar * m_miniBar;
bool m_eatClick;
QString backString;
QIntValidator * m_validator;
};
// [private widget] a flat qpushbutton that enlights on hover
class HoverButton : public QPushButton
{
public:
HoverButton( QWidget * parent );
protected:
void mouseMoveEvent( QMouseEvent * e );
void mouseReleaseEvent( QMouseEvent * e );
void paintEvent( QPaintEvent * e );
private:
bool m_hovering;
};
/** MiniBar **/
MiniBar::MiniBar( QWidget * parent, KPDFDocument * document )
: QFrame( parent, "miniBar" ), m_document( document ),
m_currentPage( -1 )
{
// left spacer
QHBoxLayout * horLayout = new QHBoxLayout( this );
QSpacerItem * spacerL = new QSpacerItem( 20, 10, QSizePolicy::Expanding );
horLayout->addItem( spacerL );
// central 2r by 3c grid layout that contains all components
QGridLayout * gridLayout = new QGridLayout( 0, 3,5, 2,1 );
// top spacer 6x6 px
// QSpacerItem * spacerTop = new QSpacerItem( 6, 6, QSizePolicy::Fixed, QSizePolicy::Fixed );
// gridLayout->addMultiCell( spacerTop, 0, 0, 0, 4 );
// center progress widget
m_progressWidget = new ProgressWidget( this );
gridLayout->addMultiCellWidget( m_progressWidget, 0, 0, 0, 4 );
// bottom: left prev_page button
m_prevButton = new HoverButton( this );
m_prevButton->setPixmap( SmallIcon("1leftarrow") );
gridLayout->addWidget( m_prevButton, 1, 0 );
// bottom: left lineEdit (current page box)
m_pagesEdit = new PagesEdit( this );
gridLayout->addWidget( m_pagesEdit, 1, 1 );
// bottom: central '/' label
gridLayout->addWidget( new QLabel( "/", this ), 1, 2 );
// bottom: right button
m_pagesButton = new HoverButton( this );
gridLayout->addWidget( m_pagesButton, 1, 3 );
// bottom: right next_page button
m_nextButton = new HoverButton( this );
m_nextButton->setPixmap( SmallIcon("1rightarrow") );
gridLayout->addWidget( m_nextButton, 1, 4 );
horLayout->addLayout( gridLayout );
// right spacer
QSpacerItem * spacerR = new QSpacerItem( 20, 10, QSizePolicy::Expanding );
horLayout->addItem( spacerR );
// customize own look
setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
// connect signals from child widgets to internal handlers / signals bouncers
connect( m_pagesEdit, SIGNAL( returnPressed() ), this, SLOT( slotChangePage() ) );
connect( m_pagesButton, SIGNAL( clicked() ), this, SIGNAL( gotoPage() ) );
connect( m_prevButton, SIGNAL( clicked() ), this, SIGNAL( prevPage() ) );
connect( m_nextButton, SIGNAL( clicked() ), this, SIGNAL( nextPage() ) );
// widget starts hidden (will be shown after opening a document)
parent->hide();
}
void MiniBar::notifySetup( const QValueVector< KPDFPage * > & pageVector, bool changed )
{
// only process data when document changes
if ( !changed )
return;
// if document is closed or has no pages, hide widget
int pages = pageVector.count();
if ( pages < 1 )
{
m_currentPage = -1;
static_cast<QWidget*>( parent() )->hide();
return;
}
// resize width of widgets
int numberWidth = 10 + fontMetrics().width( QString::number( pages ) );
m_pagesEdit->setMinimumWidth( numberWidth );
m_pagesEdit->setMaximumWidth( 2 * numberWidth );
m_pagesButton->setMinimumWidth( numberWidth );
m_pagesButton->setMaximumWidth( 2 * numberWidth );
// resize height of widgets
int fixedHeight = fontMetrics().height() + 2;
if ( fixedHeight < 18 )
fixedHeight = 18;
m_pagesEdit->setFixedHeight( fixedHeight );
m_pagesButton->setFixedHeight( fixedHeight );
m_prevButton->setFixedHeight( fixedHeight );
m_nextButton->setFixedHeight( fixedHeight );
// update child widgets
m_pagesEdit->setText( "" );
m_pagesEdit->setPagesNumber( pages );
m_pagesButton->setText( QString::number( pages ) );
m_prevButton->setEnabled( false );
m_nextButton->setEnabled( false );
static_cast<QWidget*>( parent() )->show();
}
void MiniBar::notifyViewportChanged()
{
// get current page number
int page = m_document->viewport().pageNumber;
int pages = m_document->pages();
// if the document is opened and page is changed
if ( page != m_currentPage && pages > 0 )
{
// update percentage
m_currentPage = page;
float percentage = pages < 2 ? 1.0 : (float)page / (float)(pages - 1);
m_progressWidget->setProgress( percentage );
// update prev/next button state
m_prevButton->setEnabled( page > 0 );
m_nextButton->setEnabled( page < ( pages - 1 ) );
// update text on widgets
m_pagesEdit->setText( QString::number( page + 1 ) );
}
}
void MiniBar::resizeEvent( QResizeEvent * e )
{
// auto-hide 'prev' and 'next' buttons if not enough space
const QSize & myHint = minimumSizeHint();
bool shown = m_prevButton->isVisible() && m_nextButton->isVisible();
if ( shown && e->size().width() < myHint.width() )
{
m_prevButton->hide();
m_nextButton->hide();
updateGeometry();
}
else if ( !shown )
{
int histeresis = m_prevButton->sizeHint().width() * 2 + 2;
if ( e->size().width() > (myHint.width() + histeresis) )
{
m_prevButton->show();
m_nextButton->show();
updateGeometry();
}
}
}
void MiniBar::slotChangePage()
{
// get text from the lineEdit
QString pageNumber = m_pagesEdit->text();
// convert it to page number and go to that page
bool ok;
int number = pageNumber.toInt( &ok ) - 1;
if ( ok && number >= 0 && number < (int)m_document->pages() &&
number != m_currentPage )
{
m_document->setViewportPage( number );
m_pagesEdit->clearFocus();
}
}
void MiniBar::slotGotoNormalizedPage( float index )
{
// figure out page number and go to that page
int number = (int)( index * (float)m_document->pages() );
if ( number >= 0 && number < (int)m_document->pages() &&
number != m_currentPage )
m_document->setViewportPage( number );
}
void MiniBar::slotEmitNextPage()
{
// emit signal
nextPage();
}
void MiniBar::slotEmitPrevPage()
{
// emit signal
prevPage();
}
/** ProgressWidget **/
ProgressWidget::ProgressWidget( MiniBar * parent )
: QWidget( parent, "progress", WNoAutoErase ),
m_miniBar( parent ), m_progressPercentage( -1 )
{
setFixedHeight( 4 );
setMouseTracking( true );
}
void ProgressWidget::setProgress( float percentage )
{
m_progressPercentage = percentage;
update();
}
void ProgressWidget::mouseMoveEvent( QMouseEvent * e )
{
if ( e->state() == Qt::LeftButton && width() > 0 )
m_miniBar->slotGotoNormalizedPage( (float)e->x() / (float)width() );
}
void ProgressWidget::mousePressEvent( QMouseEvent * e )
{
if ( e->button() == Qt::LeftButton && width() > 0 )
m_miniBar->slotGotoNormalizedPage( (float)e->x() / (float)width() );
}
void ProgressWidget::wheelEvent( QWheelEvent * e )