Commit 93c1d384 authored by Enrico Ros's avatar Enrico Ros

Implemented history (implementation is inside Document. actions (2) are in

 Part). Implemented 'history (xpdf's LinkAction) links'. History depth is
 100 steps by default (this is enough for sure, clicking 100 times on a
 button is not an easy task :-).

Minor issues (removed half TODOs in code, all FIXMEs are already removed):
Invoke mailer on 'mailto:' links inst instead of konqueror.
Actions cleanup: disable actions like 'print', 'preview', 'save to..', etc
 when there isn't an active document. Added history actions to the toolbar
 in place of the 'prev_page' and 'next_page' ones. Fixed open+open_recent
 action tooltip and behavior.
Move definition and implementation of PagePainter class to ui/pagepainter
 from core/page.
Valgrinded and leakchecked (2 memory leaks spotted and fixed (missing
 contents deletion in KPDFGeneratorThread and missing deletion of
 PixmapRequests on cancel in Document::requestPixmaps())).

svn path=/trunk/kdegraphics/kpdf/; revision=382960
parent e65c7058
......@@ -6,16 +6,13 @@ Legend:
MRG - MeRGed (code from a branch or a patch)
Status:
-> 2005-01-20: Stable. Apart from a bad memory deallocation mechanism
the core is ready for a public release. Usability: needs testing.
next steps: empty the in-progress list and keep it empty until release.
-> 2005-01-27: Stable and leakchecked. Usability: needs testing.
-> 2005-01-20: Stable. Apart from a bad (but still safe) memory deallocation
mechanism the core is ready for a public release.
In progress:
In progress 3.4 features (deadline is 2k5-Feb-2):
-> save/restore history (partially committed)
-> 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):
- empty! -
More items (first items will enter 'In progress list' first):
-> go to next/previous bookmark actions (showing in thumbnailslist rmb popup too)
......@@ -28,9 +25,8 @@ More items (first items will enter 'In progress list' first):
-> show Viewport in ThumbnailsList (blended/contour)
-> history as a toolbox child (collecting Doc's viewport changes notifications)
-> Delay TOC (DocumentSynapsis) generation (and move it on thread)
-> refactor ThumbnailsList to do internal rendering as pageview does (way
faster than using QScrollView + inserted Widgets and saves 8% on document
loading)
-> refactor ThumbnailsList to do internal rendering as pageview does (way faster
than using QScrollView + inserted Widgets and saves 8% on document loading)
-> move toolbar view actions in the PageView instead of the part. maybe.. or not...
-> usability: layout 2PPV [1 2,3 4,5 6] -> [1,2 3,4 5]. add option for 'ebook' style alignment
-> usability: trigger redraw on 'filter text' on current page
......@@ -69,7 +65,7 @@ More items (first items will enter 'In progress list' first):
-> core: pdf forms support
-> add OCR for building TextPages out of pure graphical (aka scanned) pages
-> rotate the whole document / individual pages
-> presentation: implement transitions (6/11 done)
-> presentation: implement missing transitions (6/11 done)
-> presentation: add some gfx tools (like a red pencil)
-> presentation: save a flag (to the xml) to open a pdf in presentation mode
-> presentation: link following (difficult due to pagerects related to pageview pixmap only)
......@@ -85,6 +81,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)
Done (newest features come first):
-> FIX: complete valgrind check and leakfix (2 leaks were present) [27-Jan-04]
-> ADD: history (100 steps) and forward/back actions
-> 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
......
This diff is collapsed.
......@@ -68,11 +68,15 @@ class KPDFDocument : public QObject // only for a private slot..
uint currentPage() const;
uint pages() const;
bool okToPrint() const;
bool historyAtBegin() const;
bool historyAtEnd() const;
QString getMetaData( const QString & key, const QString & option = QString() ) const;
// perform actions on document / pages
void setViewportPage( int page, int id = -1 );
void setViewport( const DocumentViewport & viewport, int id = -1 );
void setViewportPage( int page, int excludeId = -1 );
void setViewport( const DocumentViewport & viewport, int excludeId = -1 );
void setPrevViewport();
void setNextViewport();
void requestPixmaps( const QValueList< PixmapRequest * > & requests );
void requestTextPage( uint page );
bool findText( const QString & text = "", bool caseSensitive = false, bool findAhead = false );
......
......@@ -22,6 +22,7 @@
// xpdf includes
#include "xpdf/PSOutputDev.h"
#include "xpdf/TextOutputDev.h"
#include "xpdf/Link.h"
#include "xpdf/ErrorCodes.h"
#include "xpdf/UnicodeMap.h"
......@@ -285,7 +286,6 @@ void PDFGenerator::generateSyncTextPage( KPDFPage * page )
bool PDFGenerator::print( KPrinter& printer )
{
//FIXME (if needed) TAKE CARE OF THREADING, READY STATE AND SIMILAR STUFF
KTempFile tf( QString::null, ".ps" );
PSOutputDev *psOut = new PSOutputDev(tf.name().latin1(), pdfdoc->getXRef(), pdfdoc->getCatalog(), 1, pdfdoc->getNumPages(), psModePS);
......@@ -532,7 +532,7 @@ void PDFGenerator::addSynopsisChildren( QDomNode * parent, GList * items )
pageNumber = pdfdoc->findPage( ref.num, ref.gen ) - 1;
}
// set page as attribute to node
// TODO add other attributes to the viewport
// TODO add other attributes to the viewport (taken from link)
item.setAttribute( "Viewport", DocumentViewport( pageNumber ).toString() );
}
}
......@@ -690,6 +690,7 @@ struct PPGThreadPrivate
QImage * m_image;
TextPage * m_textPage;
QValueList< KPDFPageRect * > m_rects;
bool m_rectsTaken;
};
PDFPixmapGeneratorThread::PDFPixmapGeneratorThread( PDFGenerator * gen )
......@@ -697,10 +698,24 @@ PDFPixmapGeneratorThread::PDFPixmapGeneratorThread( PDFGenerator * gen )
{
d->generator = gen;
d->currentRequest = 0;
d->m_image = 0;
d->m_textPage = 0;
d->m_rectsTaken = true;
}
PDFPixmapGeneratorThread::~PDFPixmapGeneratorThread()
{
// delete internal objects if the class is deleted before the gui thread
// takes the data
delete d->m_image;
delete d->m_textPage;
if ( !d->m_rectsTaken && d->m_rects.count() )
{
QValueList< KPDFPageRect * >::iterator it = d->m_rects.begin(), end = d->m_rects.end();
for ( ; it != end; ++it )
delete *it;
}
// delete internal storage structure
delete d;
}
......@@ -727,9 +742,7 @@ void PDFPixmapGeneratorThread::startGeneration( PixmapRequest * request )
#endif
// set generation parameters and run thread
d->currentRequest = request;
// TODO map priorities embedded in request
QThread::Priority prio = QThread::InheritPriority;
start( prio );
start( QThread::InheritPriority );
}
void PDFPixmapGeneratorThread::endGeneration()
......@@ -749,16 +762,21 @@ void PDFPixmapGeneratorThread::endGeneration()
QImage * PDFPixmapGeneratorThread::takeImage() const
{
return d->m_image;
QImage * img = d->m_image;
d->m_image = 0;
return img;
}
TextPage * PDFPixmapGeneratorThread::takeTextPage() const
{
return d->m_textPage;
TextPage * tp = d->m_textPage;
d->m_textPage = 0;
return tp;
}
QValueList< KPDFPageRect * > PDFPixmapGeneratorThread::takeRects() const
{
d->m_rectsTaken = true;
return d->m_rects;
}
......@@ -792,9 +810,16 @@ void PDFPixmapGeneratorThread::run()
fakeDpiX, fakeDpiY, 0, true, genPageRects );
// 2. grab data from the OutputDev and store it locally (note takeIMAGE)
#ifndef NDEBUG
if ( d->m_image )
kdDebug() << "PDFPixmapGeneratorThread: previous image not taken" << endl;
if ( d->m_textPage )
kdDebug() << "PDFPixmapGeneratorThread: previous textpage not taken" << endl;
#endif
d->m_image = d->generator->kpdfOutputDev->takeImage();
d->m_textPage = d->generator->kpdfOutputDev->takeTextPage();
d->m_rects = d->generator->kpdfOutputDev->takeRects();
d->m_rectsTaken = false;
// 3. [UNLOCK] mutex
d->generator->docLock.unlock();
......
......@@ -324,7 +324,7 @@ KPDFLink * KPDFOutputDev::generateLink( LinkAction * a )
break;
case actionMovie:
/* { TODO this
/* { TODO this (Movie link)
m_type = Movie;
LinkMovie * m = (LinkMovie *) a;
// copy Movie parameters (2 IDs and a const char *)
......@@ -364,7 +364,8 @@ DocumentViewport KPDFOutputDev::decodeViewport( GString * namedDest, LinkDest *
vp.pageNumber = m_doc->findPage( ref.num, ref.gen ) - 1;
}
// get destination position (fill remaining Viewport fields)
// get destination position
// TODO add other attributes to the viewport (taken from link)
switch ( dest->getKind() )
{
case destXYZ:
......
......@@ -103,7 +103,7 @@ class KPDFLinkAction : public KPDFLink
/** Movie: Not yet defined -> think renaming to 'Media' link **/
class KPDFLinkMovie : public KPDFLink
//TODO: this
// TODO this (Movie link)
{
public:
KPDFLinkMovie() {};
......
......@@ -8,18 +8,11 @@
***************************************************************************/
// qt/kde includes
#include <qapplication.h>
#include <qimage.h>
#include <qpixmap.h>
#include <qstring.h>
#include <qpainter.h>
#include <qmap.h>
#include <kimageeffect.h>
#include <kdebug.h>
// system includes
#include <string.h>
// local includes
#include "page.h"
#include "pagetransition.h"
......@@ -261,182 +254,3 @@ void KPDFPageRect::deletePointer()
kdDebug() << "Object deletion not implemented for type '"
<< m_pointerType << "' ." << endl;
}
/** class PagePainter **/
void PagePainter::paintPageOnPainter( const KPDFPage * page, int id, int flags,
QPainter * destPainter, const QRect & limits, int width, int height )
{
QPixmap * pixmap = 0;
// if a pixmap is present for given id, use it
if ( page->m_pixmaps.contains( id ) )
pixmap = page->m_pixmaps[ id ];
// else find the closest match using pixmaps of other IDs (great optim!)
else if ( !page->m_pixmaps.isEmpty() && width != -1 )
{
int minDistance = -1;
QMap< int,QPixmap * >::const_iterator it = page->m_pixmaps.begin(), end = page->m_pixmaps.end();
for ( ; it != end; ++it )
{
int pixWidth = (*it)->width(),
distance = pixWidth > width ? pixWidth - width : width - pixWidth;
if ( minDistance == -1 || distance < minDistance )
{
pixmap = *it;
minDistance = distance;
}
}
}
if ( !pixmap )
{
if ( Settings::changeColors() &&
Settings::renderMode() == Settings::EnumRenderMode::Paper )
destPainter->fillRect( limits, Settings::paperColor() );
else
destPainter->fillRect( limits, Qt::white );
// draw a cross (to that the pixmap as not yet been loaded)
// helps a lot on pages that take much to render
destPainter->setPen( Qt::gray );
destPainter->drawLine( 0, 0, width-1, height-1 );
destPainter->drawLine( 0, height-1, width-1, 0 );
return;
}
// we have a pixmap to paint, now let's paint it using a direct or buffered painter
bool backBuffer = Settings::changeColors() &&
Settings::renderMode() != Settings::EnumRenderMode::Paper;
// if PagePainter::Accessibility is not in 'flags', disable backBuffer
backBuffer = backBuffer && (flags & Accessibility);
QPixmap * backPixmap = 0;
QPainter * p = destPainter;
if ( backBuffer )
{
backPixmap = new QPixmap( limits.width(), limits.height() );
p = new QPainter( backPixmap );
p->translate( -limits.left(), -limits.top() );
}
// fast blit the pixmap if it has the right size..
if ( pixmap->width() == width && pixmap->height() == height )
p->drawPixmap( limits.topLeft(), *pixmap, limits );
// ..else set a scale matrix to the painter and paint a quick 'zoomed' pixmap
else
{
p->save();
// TODO paint only the needed part
p->scale( width / (double)pixmap->width(), height / (double)pixmap->height() );
p->drawPixmap( 0,0, *pixmap, 0,0, pixmap->width(), pixmap->height() );
p->restore();
/* Code disabled (after HEAD merge). The user can recognize a wrong sized
pixmap even without the grey cross..
// draw a cross (for telling that the pixmap has not the right size)
p->setPen( Qt::gray );
p->drawLine( 0, 0, width-1, height-1 );
p->drawLine( 0, height-1, width-1, 0 );
*/ }
// modify pixmap following accessibility settings
if ( (flags & Accessibility) && backBuffer )
{
QImage backImage = backPixmap->convertToImage();
switch ( Settings::renderMode() )
{
case Settings::EnumRenderMode::Inverted:
// Invert image pixels using QImage internal function
backImage.invertPixels(false);
break;
case Settings::EnumRenderMode::Recolor:
// Recolor image using KImageEffect::flatten with dither:0
KImageEffect::flatten( backImage, Settings::recolorForeground(), Settings::recolorBackground() );
break;
case Settings::EnumRenderMode::BlackWhite:
// Manual Gray and Contrast
unsigned int * data = (unsigned int *)backImage.bits();
int val, pixels = backImage.width() * backImage.height(),
con = Settings::bWContrast(), thr = 255 - Settings::bWThreshold();
for( int i = 0; i < pixels; ++i )
{
val = qGray( data[i] );
if ( val > thr )
val = 128 + (127 * (val - thr)) / (255 - thr);
else if ( val < thr )
val = (128 * val) / thr;
if ( con > 2 )
{
val = con * ( val - thr ) / 2 + thr;
if ( val > 255 )
val = 255;
else if ( val < 0 )
val = 0;
}
data[i] = qRgba( val, val, val, 255 );
}
break;
}
backPixmap->convertFromImage( backImage );
}
// visually enchance links and images if requested
bool hLinks = ( flags & EnhanceLinks ) && Settings::highlightLinks();
bool hImages = ( flags & EnhanceImages ) && Settings::highlightImages();
if ( hLinks || hImages )
{
QColor normalColor = QApplication::palette().active().highlight();
QColor lightColor = normalColor.light( 140 );
// enlarging limits for intersection is like growing the 'rectGeometry' below
QRect limitsEnlarged = limits;
limitsEnlarged.addCoords( -2, -2, 2, 2 );
// draw rects that are inside the 'limits' paint region as opaque rects
QValueList< KPDFPageRect * >::const_iterator lIt = page->m_rects.begin(), lEnd = page->m_rects.end();
for ( ; lIt != lEnd; ++lIt )
{
KPDFPageRect * rect = *lIt;
if ( (hLinks && rect->pointerType() == KPDFPageRect::Link) ||
(hImages && rect->pointerType() == KPDFPageRect::Image) )
{
QRect rectGeometry = rect->geometry();
if ( rectGeometry.intersects( limitsEnlarged ) )
{
// expand rect and draw inner border
rectGeometry.addCoords( -1,-1,1,1 );
p->setPen( lightColor );
p->drawRect( rectGeometry );
// expand rect to draw outer border
rectGeometry.addCoords( -1,-1,1,1 );
p->setPen( normalColor );
p->drawRect( rectGeometry );
}
}
}
}
// draw selection (note: it is rescaled since the text page is at 100% scale)
if ( ( flags & Highlight ) && ( page->attributes() & KPDFPage::Highlight ) )
{
int x = (int)( page->m_sLeft * width / page->m_width ),
y = (int)( page->m_sTop * height / page->m_height ),
w = (int)( page->m_sRight * width / page->m_width ) - x,
h = (int)( page->m_sBottom * height / page->m_height ) - y;
if ( w > 0 && h > 0 )
{
// TODO setRasterOp is no more on Qt4 find an alternative way of doing this
p->setBrush( Qt::SolidPattern );
p->setPen( QPen( Qt::black, 1 ) ); // should not be necessary bug a Qt bug makes it necessary
p->setRasterOp( Qt::NotROP );
p->drawRect( x, y, w, h );
}
}
// if was backbuffering, copy the backPixmap to destination
if ( backBuffer )
{
delete p;
destPainter->drawPixmap( limits.left(), limits.top(), *backPixmap );
delete backPixmap;
}
}
......@@ -13,7 +13,6 @@
#include <qmap.h>
#include <qvaluelist.h>
class QPainter;
class QPixmap;
class QRect;
class TextPage;
......@@ -123,26 +122,4 @@ class KPDFPageRect
void * m_pointer;
};
/**
* @short Paints a KPDFPage to an open painter using given flags.
* TODO: move definition and implementation to pagepainter.* (..maybe..)
*/
class PagePainter
{
public:
// list of flags passed to the painting function. by OR-ing those flags
// you can decide wether or not to permit drawing of a certain feature.
enum PagePainterFlags { Accessibility = 1, EnhanceLinks = 2,
EnhanceImages = 4, Highlight = 8 };
// draw (using painter 'p') the 'page' requested by 'id' using features
// in 'flags'. 'limits' is the bounding rect of the paint operation,
// 'width' and 'height' the expected size of page contents (used only
// to pick up an alternative pixmap if the pixmap of 'id' is missing.
static void paintPageOnPainter( const KPDFPage * page, int id, int flags,
QPainter * p, const QRect & limits, int width = -1, int height = -1 );
};
#endif
......@@ -134,7 +134,7 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
// ThumbnailController * m_tc = new ThumbnailController( thumbsBox, m_thumbnailList );
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 controller toolbar (too hackish..)
thumbsBox->setStretchFactor( m_searchWidget, 100 );
thumbsBox->setStretchFactor( m_thumbnailList, 100 );
// thumbsBox->setStretchFactor( m_tc, 1 );
......@@ -198,16 +198,24 @@ Part::Part(QWidget *parentWidget, const char *widgetName,
m_lastPage = KStdAction::lastPage( this, SLOT( slotGotoLast() ), ac, "last_page" );
m_lastPage->setWhatsThis( i18n( "Moves to the last page of the document" ) );
m_historyBack = KStdAction::back( this, SLOT( slotHistoryBack() ), ac, "history_back" );
m_historyBack->setWhatsThis( i18n( "Go to the place you were before" ) );
m_historyNext = KStdAction::forward( this, SLOT( slotHistoryNext() ), ac, "history_forward" );
m_historyNext->setWhatsThis( i18n( "Go to the place you were after" ) );
// Find and other actions
m_find = KStdAction::find( this, SLOT( slotFind() ), ac, "find" );
m_find->setEnabled(false);
m_find->setEnabled( false );
m_findNext = KStdAction::findNext( this, SLOT( slotFindNext() ), ac, "find_next" );
m_findNext->setEnabled(false);
m_findNext->setEnabled( false );
KStdAction::saveAs( this, SLOT( slotSaveFileAs() ), ac, "save" );
m_saveAs = KStdAction::saveAs( this, SLOT( slotSaveFileAs() ), ac, "save" );
m_saveAs->setEnabled( false );
KStdAction::preferences( this, SLOT( slotPreferences() ), ac, "preferences" );
KStdAction::printPreview( this, SLOT( slotPrintPreview() ), ac );
m_printPreview = KStdAction::printPreview( this, SLOT( slotPrintPreview() ), ac );
m_printPreview->setEnabled( false );
m_showProperties = new KAction(i18n("&Properties"), "info", 0, this, SLOT(slotShowProperties()), ac, "properties");
m_showProperties->setEnabled( false );
......@@ -215,19 +223,19 @@ 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->setEnabled( false );
// attach the actions of the children widgets too
m_pageView->setupActions( ac );
// attach the actions of the children widgets too
m_pageView->setupActions( ac );
// apply configuration (both internal settings and GUI configured items)
QValueList<int> splitterSizes = Settings::splitterSizes();
if ( !splitterSizes.count() )
{
// the first time use 1/10 for the panel and 9/10 for the pageView
splitterSizes.push_back( 50 );
splitterSizes.push_back( 500 );
}
m_splitter->setSizes( splitterSizes );
slotNewConfig();
// apply configuration (both internal settings and GUI configured items)
QValueList<int> splitterSizes = Settings::splitterSizes();
if ( !splitterSizes.count() )
{
// the first time use 1/10 for the panel and 9/10 for the pageView
splitterSizes.push_back( 50 );
splitterSizes.push_back( 500 );
}
m_splitter->setSizes( splitterSizes );
slotNewConfig();
m_watcher = new KDirWatch( this );
connect( m_watcher, SIGNAL( dirty( const QString& ) ), this, SLOT( slotFileDirty( const QString& ) ) );
......@@ -294,30 +302,43 @@ KAboutData* Part::createAboutData()
bool Part::openFile()
{
bool ok = m_document->openDocument( m_file );
if ( ok && !m_watcher->contains(m_file)) m_watcher->addFile(m_file);
// update one-time actions
m_saveAs->setEnabled( ok );
m_printPreview->setEnabled( ok );
// update viewing actions
updateActions();
if ( ok && m_document->getMetaData( "StartFullScreen" ) == "yes" )
if ( !ok )
{
// if can't open document, update windows so they display blank contents
m_pageView->updateContents();
m_thumbnailList->updateContents();
return false;
}
// set the file to the fileWatcher
if ( !m_watcher->contains(m_file) )
m_watcher->addFile(m_file);
// if the 'StartFullScreen' flag is set, start presentation
if ( m_document->getMetaData( "StartFullScreen" ) == "yes" )
slotShowPresentation();
return ok;
return true;
}
bool Part::openURL(const KURL &url)
{
// this calls the above 'openURL' method
bool b = KParts::ReadOnlyPart::openURL(url);
// if can't open document, update windows so they display blank contents
if ( !b )
{
m_pageView->updateContents();
m_thumbnailList->updateContents();
KMessageBox::error( widget(), i18n("Could not open %1").arg(url.prettyURL()) );
}
KMessageBox::error( widget(), i18n("Could not open %1").arg( url.prettyURL() ) );
return b;
}
void
Part::slotWatchFile()
void Part::slotWatchFile()
{
Settings::setWatchFile(m_watchFile->isChecked());
if( m_watchFile->isChecked() )
......@@ -329,8 +350,7 @@ Part::slotWatchFile()
}
}
void
Part::slotFileDirty( const QString& fileName )
void Part::slotFileDirty( const QString& fileName )
{
// The beauty of this is that each start cancels the previous one.
// This means that timeout() is only fired when there have
......@@ -343,8 +363,7 @@ Part::slotFileDirty( const QString& fileName )
}
}
void
Part::slotDoFileDirty()
void Part::slotDoFileDirty()
{
uint p = m_document->currentPage() + 1;
if (openFile())
......@@ -356,6 +375,8 @@ Part::slotDoFileDirty()
bool Part::closeURL()
{
m_saveAs->setEnabled( false );
m_printPreview->setEnabled( false );
if (!m_file.isEmpty()) m_watcher->removeFile(m_file);
m_document->closeDocument();
return KParts::ReadOnlyPart::closeURL();
......@@ -373,6 +394,8 @@ void Part::updateActions()
m_prevPage->setEnabled( !atBegin );
m_lastPage->setEnabled( !atEnd );
m_nextPage->setEnabled( !atEnd );
m_historyBack->setEnabled( !m_document->historyAtBegin() );
m_historyNext->setEnabled( !m_document->historyAtEnd() );
}
else
{
......@@ -381,6 +404,8 @@ void Part::updateActions()
m_lastPage->setEnabled( false );
m_prevPage->setEnabled( false );
m_nextPage->setEnabled( false );
m_historyBack->setEnabled( false );
m_historyNext->setEnabled( false );
}
m_find->setEnabled( ok );
m_showProperties->setEnabled( ok );
......@@ -451,6 +476,16 @@ void Part::slotGotoLast()
m_document->setViewportPage( m_document->pages() - 1 );
}
void Part::slotHistoryBack()
{
m_document->setPrevViewport();
}
void Part::slotHistoryNext()
{
m_document->setNextViewport();
}
void Part::slotFind()
{
KFindDialog dlg( widget() );
......@@ -635,7 +670,7 @@ void Part::slotShowMenu(const KPDFPage *page, const QPoint &point)
case 2:
m_pageView->fitPageWidth( page->number() );
break;
// case 3: // ToDO switch to edit mode
// case 3: // switch to edit mode
// m_pageView->slotSetMouseDraw();
// break;
}
......
......@@ -87,15 +87,17 @@ protected slots:
void slotNextPage();
void slotGotoFirst();
void slotGotoLast();
void slotHistoryBack();
void slotHistoryNext();
void slotFind();
void slotFindNext();
void slotSaveFileAs();
void slotPreferences();
void slotNewConfig();
void slotPrintPreview();
void slotSaveFileAs();
void slotPreferences();
void slotNewConfig();
void slotPrintPreview();
void slotShowMenu(const KPDFPage *page, const QPoint &point);
void slotShowProperties();
void slotShowPresentation();
void slotShowPresentation();
// can be connected to widget elements
void updateActions();
void enableTOC(bool enable);
......@@ -134,8 +136,12 @@ private:
KAction *m_nextPage;
KAction *m_firstPage;
KAction *m_lastPage;
KAction *m_historyBack;
KAction *m_historyNext;
KAction *m_find;
KAction *m_findNext;
KAction *m_saveAs;
KAction *m_printPreview;
KAction *m_showProperties;
KAction *m_showPresentation;
KToggleAction* m_watchFile;
......
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
<kpartgui name="kpdf_part" version="15">
<kpartgui name="kpdf_part" version="16">
<MenuBar>
<Menu name="file"><text>&amp;File</text>
<Action name="save" group="file_save"/>
......@@ -34,6 +34,9 @@
<Action name="next_page"/>
<Action name="last_page"/>
<Separator/>
<Action name="history_back"/>
<Action name="history_forward" />
<Separator/>
<Action name="goto_page"/>
</Menu>
<Menu name="settings"><text>&amp;Settings</text>
......@@ -42,6 +45,9 @@
</Menu>
</MenuBar>
<ToolBar name="mainToolBar"><text>Main Toolbar</text>
<Separator/>
<Action name="history_back"/>
<Action name="history_forward" />
<Separator/>
<Action name="zoom_in"/>
<Action name="zoom_to" />
......
......@@ -93,18 +93,26 @@ Shell::~Shell()
void Shell::openURL( const KURL & url )
{
if ( m_part && m_part->openURL( url ) ) m_recent->addURL (url);
else m_recent->removeURL(url);
if ( m_part )
{
bool openOk = m_part->openURL( url );
if ( openOk ) m_recent->addURL( url );
else m_recent->removeURL( url );
m_printAction->setEnabled( openOk );
}
}
void Shell::readSettings()
{
m_recent->loadEntries( KGlobal::config() );
m_recent->setEnabled( true ); // force enabling
m_recent->setToolTip( i18n("Click to open a file\nClick and hold to open a recent file") );
KGlobal::config()->setDesktopGroup();
bool fullScreen = KGlobal::config()->readBoolEntry( "FullScreen", false );
setFullScreen( fullScreen );
// necessary to make fullscreen mode obey the last showmenubar / showtoolbarsettings
KGlobal::config()->setGroup("MainWindow");
if (KGlobal::config()->readBoolEntry( "MenuBar", true ))
......@@ -145,9 +153,9 @@ void Shell::setupActions()
KAction * openAction = KStdAction::open(this, SLOT(fileOpen()), actionCollection());
m_recent = KStdAction::openRecent( this, SLOT( openURL( const KURL& ) ), actionCollection() );
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());