Branchport fuzzy search (google like) and kwallet support for storing passwords from kpdf_annotations branch to HEAD.

Enrico can you check that i have ported all the necessary bits?

svn path=/trunk/kdegraphics/kpdf/; revision=395089
remotes/origin/kpdf-kde4
Albert Astals Cid 21 years ago
parent 620d54f9d4
commit 39f8e14d23
  1. 4
      TODO
  2. 72
      core/document.cpp
  3. 3
      core/document.h
  4. 57
      core/generator_pdf/generator_pdf.cpp
  5. 74
      ui/searchwidget.cpp
  6. 5
      ui/searchwidget.h

@ -9,7 +9,6 @@ In progress:
-- 2005-Feb-26: Merge from 'kpdf_annotations' branch --
More items (first items will enter 'In progress list' first):
-> search: google search in the page
-> pageview: add scrollbar marks for bookmarks (like kate)
-> screen editing (annotations): framework (BR67300,BR62793)
-> screen editing (annotations): tools (BR67300), yellow notes 'post-it' like
@ -65,7 +64,6 @@ More items (first items will enter 'In progress list' first):
-> investigate 'Splash' lack of smoothness at low resolutions (see lines in thumbnails)
-> add search on the toc widget (a 'prune on type' lineedit like in thumbnails widget)
-> goto 'logical' page (usually differs from pdf's page) (req. by Luca Burrelli)
-> use wallet for storing passwords of encrypted files
-> use shortcuts for next and prev page even in presenatation mode (by Tobias Koenig)
-> move some document related features from part to the document (see find, goto dialog, ...)
-> Albert: Read pdf specification and see if paths with length = 1 are allowed, in case they are allowed see how to fix 97131 without skipping paths with length = 1
@ -75,6 +73,8 @@ More items (first items will enter 'In progress list' first):
Done (newest features come first):
-- merging from kdpf_annotations branch --
-> ADD: google-like search on thumbnails
-> ADD: use kde wallet for storing passwords of protected files
-> ADD: Obey DRM is now a configuration option
-> FIX: leakfix when closing document while thread was running (no more leaks now)
-> FIX: direct hi-performance pixels manipulation for highlighting (instead of the obsoleted setRasterOp)

@ -735,9 +735,77 @@ bool KPDFDocument::searchText( int searchID, const QString & text, bool fromStar
else if ( type == PrevMatch )
{
}
// 4. GOOGLELIKE //TODO
else if ( type == GoogleLike )
// 4. GOOGLE* - process all document marking pages
else if ( type == GoogleAll || type == GoogleAny )
{
// search and highlight every word in 'text' on all pages
bool matchAll = type == GoogleAll;
QStringList words = QStringList::split( " ", text );
int wordsCount = words.count(),
hueStep = (wordsCount > 1) ? (60 / (wordsCount - 1)) : 60,
baseHue, baseSat, baseVal;
color.getHsv( &baseHue, &baseSat, &baseVal );
QValueVector< KPDFPage * >::iterator it = pages_vector.begin(), end = pages_vector.end();
for ( ; it != end; ++it )
{
// get page (from the first to the last)
KPDFPage * page = *it;
int pageNumber = page->number();
// request search page if needed
if ( !page->hasSearchPage() )
requestTextPage( pageNumber );
// loop on a page adding highlights for all found items
bool allMatched = wordsCount > 0,
anyMatched = false;
for ( int w = 0; w < wordsCount; w++ )
{
QString word = words[ w ];
int newHue = baseHue - w * hueStep;
if ( newHue < 0 )
newHue += 360;
QColor wordColor = QColor( newHue, baseSat, baseVal, QColor::Hsv );
NormalizedRect * lastMatch = 0;
// add all highlights for current word
bool wordMatched = false;
while ( 1 )
{
if ( lastMatch )
lastMatch = page->findText( word, caseSensitive, lastMatch );
else
lastMatch = page->findText( word, caseSensitive );
if ( !lastMatch )
break;
// add highligh rect to the page
page->setHighlight( searchID, lastMatch, wordColor );
wordMatched = true;
}
allMatched = allMatched && wordMatched;
anyMatched = anyMatched || wordMatched;
}
// if not all words are present in page, remove partial highlights
if ( !allMatched && matchAll )
page->deleteHighlights( searchID );
// if page contains all words, udpate internals and queue page for notify
if ( (allMatched && matchAll) || (anyMatched && !matchAll) )
{
foundAMatch = true;
s->highlightedPages.append( pageNumber );
if ( !pagesToNotify.contains( pageNumber ) )
pagesToNotify.append( pageNumber );
}
}
// reset cursor to previous shape
QApplication::restoreOverrideCursor();
// send page lists to update observers (since some filter on bookmarks)
foreachObserver( notifySetup( pages_vector, false ) );
}
// notify observers about highlights changes

@ -62,7 +62,6 @@ class KPDFDocument : public QObject
// enum definitions
enum Permission { AllowModify = 1, AllowCopy = 2, AllowPrint = 4, AllowNotes = 8 };
enum SearchType { NextMatch, PrevMatch, AllDoc, GoogleLike };
// query methods (const ones)
bool isOpened() const;
@ -84,6 +83,8 @@ class KPDFDocument : public QObject
void setNextViewport();
void requestPixmaps( const QValueList< PixmapRequest * > & requests );
void requestTextPage( uint page );
enum SearchType { NextMatch, PrevMatch, AllDoc, GoogleAll, GoogleAny };
bool searchText( int searchID, const QString & text, bool fromStart, bool caseSensitive,
SearchType type, bool moveViewport, const QColor & color, bool noDialogs = false );
bool continueSearch( int searchID );

@ -18,6 +18,7 @@
#include <kapplication.h>
#include <klocale.h>
#include <kpassdlg.h>
#include <kwallet.h>
#include <kprinter.h>
#include <ktempfile.h>
#include <kmessagebox.h>
@ -87,7 +88,7 @@ PDFGenerator::~PDFGenerator()
//BEGIN Generator inherited functions
bool PDFGenerator::loadDocument( const QString & fileName, QValueVector<KPDFPage*> & pagesVector )
bool PDFGenerator::loadDocument( const QString & filePath, QValueVector<KPDFPage*> & pagesVector )
{
#ifndef NDEBUG
if ( pdfdoc )
@ -97,28 +98,62 @@ bool PDFGenerator::loadDocument( const QString & fileName, QValueVector<KPDFPage
}
#endif
// create PDFDoc for the given file
pdfdoc = new PDFDoc( new GString( QFile::encodeName( fileName ) ), 0, 0 );
pdfdoc = new PDFDoc( new GString( QFile::encodeName( filePath ) ), 0, 0 );
// if the file didn't open correctly it might be encrypted, so ask for a pass
bool firstTry = true;
bool firstInput = true;
bool triedWallet = false;
KWallet::Wallet * wallet = 0;
while ( !pdfdoc->isOk() && pdfdoc->getErrorCode() == errEncrypted )
{
QCString password;
// 1.A. try to retrieve the first password from the kde wallet system
if ( !triedWallet )
{
QString walletName = KWallet::Wallet::NetworkWallet();
wallet = KWallet::Wallet::openWallet( walletName );
if ( wallet )
{
// use the KPdf folder (and create if missing)
if ( !wallet->hasFolder( "KPdf" ) )
wallet->createFolder( "KPdf" );
wallet->setFolder( "KPdf" );
// look for the pass in that folder
QString retrievedPass;
if ( !wallet->readPassword( filePath.section('/', -1, -1), retrievedPass ) )
password = retrievedPass.local8Bit();
}
triedWallet = true;
}
// 1.B. if not retrieved, ask the password using the kde password dialog
if ( password.isNull() )
{
QString prompt;
if ( firstTry )
if ( firstInput )
prompt = i18n( "Please insert the password to read the document:" );
else
prompt = i18n( "Incorrect password. Try again:" );
firstTry = false;
firstInput = false;
QCString pwd;
if ( KPasswordDialog::getPassword( pwd, prompt ) != KPasswordDialog::Accepted )
// if the user presses cancel, abort opening
if ( KPasswordDialog::getPassword( password, prompt ) != KPasswordDialog::Accepted )
break;
else
{
GString * pwd2 = new GString( pwd.data() );
}
// 2. reopen the document using the password
GString * pwd2 = new GString( password.data() );
delete pdfdoc;
pdfdoc = new PDFDoc( new GString( QFile::encodeName( fileName ) ), pwd2, pwd2 );
pdfdoc = new PDFDoc( new GString( QFile::encodeName( filePath ) ), pwd2, pwd2 );
delete pwd2;
// 3. if the password is correct, store it to the wallet
if ( pdfdoc->isOk() && wallet && /*safety check*/ wallet->isOpen() )
{
QString goodPass = QString::fromLocal8Bit( password.data() );
wallet->writePassword( filePath.section('/', -1, -1), goodPass );
}
}
if ( !pdfdoc->isOk() )

@ -24,14 +24,13 @@
#include "core/document.h"
#include "conf/settings.h"
// uncomment following to enable the case switching button
//#define SW_ENABLE_CASE_BUTTON
#define CLEAR_ID 1
#define LEDIT_ID 2
#define FIND_ID 3
SearchWidget::SearchWidget( QWidget * parent, KPDFDocument * document )
: KToolBar( parent, "iSearchBar" ), m_document( document ), m_caseSensitive( false )
: KToolBar( parent, "iSearchBar" ), m_document( document ),
m_searchType( 0 ), m_caseSensitive( false )
{
// change toolbar appearance
setMargin( 3 );
@ -44,31 +43,31 @@ SearchWidget::SearchWidget( QWidget * parent, KPDFDocument * document )
connect( m_inputDelayTimer, SIGNAL( timeout() ),
this, SLOT( startSearch() ) );
// line edit
// 1. text line
insertLined( QString::null, LEDIT_ID, SIGNAL( textChanged(const QString &) ),
this, SLOT( slotTextChanged(const QString &) ), true,
i18n( "Enter at least 3 letters to filter pages" ), 0/*size*/, 1 );
// clear button (uses a lineEdit slot, so it must be created after)
// 2. clear button (uses a lineEdit slot, so it must be created after)
insertButton( QApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
CLEAR_ID, SIGNAL( clicked() ),
getLined( LEDIT_ID ), SLOT( clear() ), true,
i18n( "Clear filter" ), 0/*index*/ );
#ifdef SW_ENABLE_CASE_BUTTON
// create popup menu for change case button
m_caseMenu = new KPopupMenu( this );
m_caseMenu->insertItem( i18n("Case Insensitive"), 1 );
m_caseMenu->insertItem( i18n("Case Sensitive"), 2 );
m_caseMenu->setItemChecked( 1, true );
connect( m_caseMenu, SIGNAL( activated(int) ), SLOT( slotCaseChanged(int) ) );
// 3.1. create the popup menu for changing filtering features
m_menu = new KPopupMenu( this );
m_menu->insertItem( i18n("Case Sensitive"), 1 );
m_menu->insertSeparator( 2 );
m_menu->insertItem( i18n("Match Phrase"), 3 );
m_menu->insertItem( i18n("Match All Words"), 4 );
m_menu->insertItem( i18n("Match Any Word"), 5 );
m_menu->setItemChecked( 3, true );
connect( m_menu, SIGNAL( activated(int) ), SLOT( slotMenuChaged(int) ) );
// create the change case button
insertButton( "find", FIND_ID, m_caseMenu, true,
i18n( "Change Case" ), 2/*index*/ );
#endif
// 3.2. create the toolbar button that spawns the popup menu
insertButton( "kpdf", FIND_ID, m_menu, true, i18n( "Filter Options" ), 2/*index*/ );
// setStretchableWidget( lineEditWidget );
// always maximize the text line
setItemAutoSized( LEDIT_ID );
}
@ -88,13 +87,40 @@ void SearchWidget::slotTextChanged( const QString & text )
m_inputDelayTimer->start(333, true);
}
void SearchWidget::slotMenuChaged( int index )
{
// update internal variables and checked state
if ( index == 1 )
{
m_caseSensitive = !m_caseSensitive;
m_menu->setItemChecked( 1, m_caseSensitive );
}
else if ( index >= 3 && index <= 5 )
{
m_searchType = index - 3;
for ( int i = 0; i < 3; i++ )
m_menu->setItemChecked( i + 3, m_searchType == i );
}
else
return;
// update search
slotTextChanged( getLined( LEDIT_ID )->text() );
}
void SearchWidget::startSearch()
{
// search text if have more than 3 chars or else clear search
QString text = getLined( LEDIT_ID )->text();
bool ok = true;
if ( text.length() >= 3 )
ok = m_document->searchText( SW_SEARCH_ID, text, true, m_caseSensitive, KPDFDocument::AllDoc, false, qRgb( 0, 183, 255 ) );
{
KPDFDocument::SearchType type = !m_searchType ? KPDFDocument::AllDoc :
( (m_searchType > 1) ? KPDFDocument::GoogleAny :
KPDFDocument::GoogleAll );
ok = m_document->searchText( SW_SEARCH_ID, text, true, m_caseSensitive,
type, false, qRgb( 0, 183, 255 ) );
}
else
m_document->resetSearch( SW_SEARCH_ID );
// if not found, use warning colors
@ -106,16 +132,4 @@ void SearchWidget::startSearch()
}
}
void SearchWidget::slotCaseChanged( int index )
{
bool newState = (index == 2);
if ( newState != m_caseSensitive )
{
m_caseSensitive = newState;
m_caseMenu->setItemChecked( 1, !m_caseSensitive );
m_caseMenu->setItemChecked( 2, m_caseSensitive );
slotTextChanged( getLined( LEDIT_ID )->text() );
}
}
#include "searchwidget.moc"

@ -36,13 +36,14 @@ class SearchWidget : public KToolBar
private:
KPDFDocument * m_document;
KPopupMenu * m_caseMenu;
KPopupMenu * m_menu;
QTimer * m_inputDelayTimer;
int m_searchType;
bool m_caseSensitive;
private slots:
void slotTextChanged( const QString & text );
void slotCaseChanged( int index );
void slotMenuChaged( int index );
void startSearch();
};

Loading…
Cancel
Save