Findahead - as in khtml.

svn path=/trunk/kdegraphics/kpdf/; revision=378583
This commit is contained in:
Jakub Stachowski 2005-01-14 23:19:04 +00:00
parent 6d12abbcff
commit cc5f8bb689
5 changed files with 103 additions and 10 deletions

2
TODO
View file

@ -29,7 +29,6 @@ More items (first items will enter 'In progress list' first):
-> refactor ThumbnailsList to do internal rendering as pageview does (way
faster than using QScrollView + inserted Widgets and saves 8% on document
loading)
-> type ahead search in pageview (type '/' then the word to search..) (ready: patch by JakobS)
-> 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. (by Mikolaj)
-> usability: trigger redraw on 'filter text' on current page (by Mikolaj)
@ -87,6 +86,7 @@ More items (first items will enter 'In progress list' first):
-> move some document related features from part to the document (see find, goto dialog, ...)
Done (newest features come first):
-> type ahead search in pageview (type '/' then the word to search..)
-> FIX: scroll page if the the searched string is not visible
-> FIX: use a global Viewport over the document (linked views, real link following, location restoring, etc)
-> FIX: wrong zoom buttons order (BR74248) (check consistancy with kdvi/kviewshell/kghostview/.. (not konq))

View file

@ -355,7 +355,7 @@ void KPDFDocument::setViewport( const DocumentViewport & viewport, int id )
(*it)->instance->notifyViewportChanged();
}
void KPDFDocument::findText( const QString & string, bool keepCase )
bool KPDFDocument::findText( const QString & string, bool keepCase, bool findAhead )
{
// turn selection drawing off on filtered pages
if ( !d->filterText.isEmpty() )
@ -374,7 +374,7 @@ void KPDFDocument::findText( const QString & string, bool keepCase )
KPDFPage * foundPage = 0,
* lastPage = (d->searchPage > -1) ? pages_vector[ d->searchPage ] : 0;
if ( lastPage && d->searchPage == currentPage )
if ( lastPage->hasText( d->searchText, d->searchCase, false ) )
if ( lastPage->hasText( d->searchText, d->searchCase, findAhead ) )
foundPage = lastPage;
else
{
@ -389,7 +389,7 @@ void KPDFDocument::findText( const QString & string, bool keepCase )
{
if ( currentPage >= pageCount )
{
if ( KMessageBox::questionYesNo(0, i18n("End of document reached.\nContinue from the beginning?")) == KMessageBox::Yes )
if ( !findAhead && KMessageBox::questionYesNo(0, i18n("End of document reached.\nContinue from the beginning?")) == KMessageBox::Yes )
currentPage = 0;
else
break;
@ -420,8 +420,9 @@ void KPDFDocument::findText( const QString & string, bool keepCase )
// notify all observers about hilighting chages
foreachObserver( notifyPageChanged( pageNumber, DocumentObserver::Highlights ) );
}
else
else if ( !findAhead )
KMessageBox::information( 0, i18n("No matches found for '%1'.").arg(d->searchText) );
return foundPage;
}
void KPDFDocument::findTextAll( const QString & pattern, bool keepCase )
@ -809,9 +810,9 @@ void KPDFDocument::processPageList( bool documentChanged )
foreachObserver( notifySetup( pages_vector, documentChanged ) );
}
void KPDFDocument::unHilightPages()
void KPDFDocument::unHilightPages(bool filteredOnly)
{
if ( d->filterText.isEmpty() )
if ( filteredOnly && d->filterText.isEmpty() )
return;
d->filterText = QString::null;

View file

@ -74,11 +74,12 @@ class KPDFDocument : public QObject // only for a private slot..
void setViewport( const DocumentViewport & viewport, int id = -1 );
void requestPixmaps( const QValueList< PixmapRequest * > & requests, bool asyncronous );
void requestTextPage( uint page );
void findText( const QString & text = "", bool caseSensitive = false );
bool findText( const QString & text = "", bool caseSensitive = false, bool findAhead = false );
void findTextAll( const QString & pattern, bool caseSensitive );
void toggleBookmark( int page );
void processLink( const KPDFLink * link );
bool print( KPrinter &printer );
void unHilightPages(bool filteredOnly = true);
signals:
void linkFind();
@ -94,7 +95,6 @@ class KPDFDocument : public QObject // only for a private slot..
QString giveAbsolutePath( const QString & fileName );
bool openRelativeFile( const QString & fileName );
void processPageList( bool documentChanged );
void unHilightPages();
Generator * generator;
QString documentFileName;

View file

@ -26,6 +26,7 @@
#include <kiconloader.h>
#include <kurldrag.h>
#include <kaction.h>
#include <kstdaccel.h>
#include <kactioncollection.h>
#include <kpopupmenu.h>
#include <klocale.h>
@ -71,8 +72,11 @@ public:
// other stuff
QTimer * delayTimer;
QTimer * scrollTimer;
QTimer * findTimer;
int scrollIncrement;
bool dirtyLayout;
bool typeAheadActivated;
QString findString;
bool blockViewport;
PageViewMessage * messageWindow; //in pageviewutils.h
@ -111,6 +115,8 @@ PageView::PageView( QWidget *parent, KPDFDocument *document )
d->mouseOnRect = false;
d->delayTimer = 0;
d->scrollTimer = 0;
d->typeAheadActivated = false;
d->findTimer = new QTimer(this);
d->scrollIncrement = 0;
d->dirtyLayout = false;
d->blockViewport = false;
@ -138,6 +144,11 @@ PageView::PageView( QWidget *parent, KPDFDocument *document )
// setCornerWidget( resizeButton );
// resizeButton->setEnabled( false );
// connect(...);
// find ahead timeout timer
connect(d->findTimer, SIGNAL(timeout()), this, SLOT(findTimeout()));
}
PageView::~PageView()
@ -493,6 +504,61 @@ void PageView::viewportResizeEvent( QResizeEvent * )
void PageView::keyPressEvent( QKeyEvent * e )
{
e->accept();
// based on khtml/khtmlview.cpp
if(d->typeAheadActivated)
{
// type-ahead find aka find-as-you-type
if(e->key() == Key_BackSpace)
{
d->findString = d->findString.left(d->findString.length() - 1);
if(!d->findString.isEmpty())
{
findAhead(false);
d->findTimer->start(3000, true);
}
else
{
findTimeout();
d->document->unHilightPages(false);
}
return;
}
else if(e->key() == KStdAccel::findNext())
{ // part doesn't get this key event because of the keyboard grab
d->findTimer->stop(); // restore normal operation during possible messagebox is displayed
releaseKeyboard();
if (d->document->findText())
d->messageWindow->display(i18n("Text found: \"%1\".").arg(d->findString.lower()),
PageViewMessage::Info, 3000);
d->findTimer->start(3000, true);
grabKeyboard();
return;
}
else if(e->key() == Key_Escape || e->key() == Key_Return)
{
findTimeout();
return;
}
else if(e->text().isEmpty() == false)
{
d->findString += e->text();
findAhead(true);
d->findTimer->start(3000, true);
return;
}
}
else if(e->key() == '/')
{
d->findString="";
d->messageWindow->display(i18n("Starting -- find text as you type"), PageViewMessage::Info, 3000);
d->typeAheadActivated = true;
d->findTimer->start(3000, true);
grabKeyboard();
return;
}
// move/scroll page by using keys
switch ( e->key() )
{
@ -564,6 +630,28 @@ void PageView::keyPressEvent( QKeyEvent * e )
}
}
void PageView::findTimeout()
{
d->typeAheadActivated = false;
d->findString = "";
d->messageWindow->display(i18n("Find stopped."),PageViewMessage::Info,1000);
releaseKeyboard();
}
void PageView::findAhead(bool increase)
{
if (!increase)
d->document->setViewportPage(0);
QString status;
d->document->unHilightPages(false);
if(d->document->findText(d->findString, false, true))
status = i18n("Text found: \"%1\".");
else
status = i18n("Text not found: \"%1\".");
d->messageWindow->display(status.arg(d->findString.lower()), PageViewMessage::Info, 4000);
}
void PageView::contentsMouseMoveEvent( QMouseEvent * e )
{
// if holding mouse mid button, perform zoom

View file

@ -103,6 +103,8 @@ class PageView : public QScrollView, public DocumentObserver
void updateZoomText();
// updates cursor
void updateCursor( const QPoint &p );
void findAhead(bool increase);
// don't want to expose classes in here
class PageViewPrivate * d;
@ -114,7 +116,9 @@ class PageView : public QScrollView, public DocumentObserver
void slotRequestVisiblePixmaps( int left = -1, int top = -1 );
// activated by the autoscroll timer (Shift+Up/Down keys)
void slotAutoScoll();
// type-ahead find timeout
void findTimeout();
// connected to local actions
void slotZoom();
void slotZoomIn();