📄 document.cpp.svn-base
字号:
/* REFERENCE IMPLEMENTATION: better calling setViewport from other codevoid KPDFDocument::setNextPage(){ // advance page and set viewport on observers if ( (*d->viewportIterator).pageNumber < (int)pages_vector.count() - 1 ) setViewport( DocumentViewport( (*d->viewportIterator).pageNumber + 1 ) );}void KPDFDocument::setPrevPage(){ // go to previous page and set viewport on observers if ( (*d->viewportIterator).pageNumber > 0 ) setViewport( DocumentViewport( (*d->viewportIterator).pageNumber - 1 ) );}*/void KPDFDocument::setViewportPage( int page, int excludeId, bool smoothMove ){ // clamp page in range [0 ... numPages-1] if ( page < 0 ) page = 0; else if ( page > (int)pages_vector.count() ) page = pages_vector.count() - 1; // make a viewport from the page and broadcast it setViewport( DocumentViewport( page ), excludeId, smoothMove );}void KPDFDocument::setViewport( const DocumentViewport & viewport, int excludeId, bool smoothMove ){ // if already broadcasted, don't redo it DocumentViewport & oldViewport = *d->viewportIterator; // disabled by enrico on 2005-03-18 (less debug output) //if ( viewport == oldViewport ) // kDebug() << "setViewport with the same viewport." << endl; // set internal viewport taking care of history if ( oldViewport.pageNumber == viewport.pageNumber || oldViewport.pageNumber == -1 ) { // if page is unchanged save the viewport at current position in queue oldViewport = viewport; } else { // remove elements after viewportIterator in queue d->viewportHistory.erase( ++d->viewportIterator, d->viewportHistory.end() ); // keep the list to a reasonable size by removing head when needed if ( d->viewportHistory.count() >= 100 ) d->viewportHistory.pop_front(); // add the item at the end of the queue d->viewportIterator = d->viewportHistory.insert( d->viewportHistory.end(), viewport ); } // notify change to all other (different from id) observers QMap< int, DocumentObserver * >::iterator it = d->observers.begin(), end = d->observers.end(); for ( ; it != end ; ++ it ) if ( it.key() != excludeId ) (*it)->notifyViewportChanged( smoothMove ); // [MEM] raise position of currently viewed page in allocation queue if ( d->allocatedPixmapsFifo.count() > 1 ) { const int page = viewport.pageNumber; QLinkedList< AllocatedPixmap * > viewportPixmaps; QLinkedList< AllocatedPixmap * >::iterator aIt = d->allocatedPixmapsFifo.begin(); QLinkedList< AllocatedPixmap * >::iterator aEnd = d->allocatedPixmapsFifo.end(); while ( aIt != aEnd ) { if ( (*aIt)->page == page ) { viewportPixmaps.append( *aIt ); aIt = d->allocatedPixmapsFifo.erase( aIt ); continue; } ++aIt; } if ( !viewportPixmaps.isEmpty() ) d->allocatedPixmapsFifo += viewportPixmaps; }}void KPDFDocument::setPrevViewport()// restore viewport from the history{ if ( d->viewportIterator != d->viewportHistory.begin() ) { // restore previous viewport and notify it to observers --d->viewportIterator; foreachObserver( notifyViewportChanged( true ) ); }}void KPDFDocument::setNextViewport()// restore next viewport from the history{ QLinkedList< DocumentViewport >::iterator nextIterator = d->viewportIterator; ++nextIterator; if ( nextIterator != d->viewportHistory.end() ) { // restore next viewport and notify it to observers ++d->viewportIterator; foreachObserver( notifyViewportChanged( true ) ); }}bool KPDFDocument::searchText( int searchID, const QString & text, bool fromStart, bool caseSensitive, SearchType type, bool moveViewport, const QColor & color, bool noDialogs ){ // safety checks: don't perform searches on empty or unsearchable docs if ( !generator || !generator->supportsSearching() || pages_vector.isEmpty() ) return false; // if searchID search not recorded, create new descriptor and init params if ( !d->searches.contains( searchID ) ) { RunningSearch * search = new RunningSearch(); search->continueOnPage = -1; d->searches[ searchID ] = search; } if (d->m_lastSearchID != searchID) { resetSearch(d->m_lastSearchID); } d->m_lastSearchID = searchID; RunningSearch * s = d->searches[ searchID ]; // update search stucture bool newText = text != s->cachedString; s->cachedString = text; s->cachedType = type; s->cachedCaseSensitive = caseSensitive; s->cachedViewportMove = moveViewport; s->cachedNoDialogs = noDialogs; s->cachedColor = color; // global data for search bool foundAMatch = false; QLinkedList< int > pagesToNotify; // remove highlights from pages and queue them for notifying changes pagesToNotify += s->highlightedPages; QLinkedList< int >::iterator it = s->highlightedPages.begin(), end = s->highlightedPages.end(); for ( ; it != end; ++it ) pages_vector[ *it ]->deleteHighlights( searchID ); s->highlightedPages.clear(); // set hourglass cursor QApplication::setOverrideCursor( Qt::WaitCursor ); // 1. ALLDOC - proces all document marking pages if ( type == AllDoc ) { // search and highlight 'text' (as a solid phrase) on all pages QVector< 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 addedHighlights = false; RegularAreaRect * lastMatch = 0; while ( 1 ) { if ( lastMatch ) lastMatch = page->findText( searchID, text, NextRes, caseSensitive, lastMatch ); else lastMatch = page->findText( searchID, text, FromTop, caseSensitive ); if ( !lastMatch ) break; // add highligh rect to the page page->setHighlight( searchID, lastMatch, color ); addedHighlights = true; } // if added highlights, udpate internals and queue page for notify if ( addedHighlights ) { foundAMatch = true; s->highlightedPages.append( pageNumber ); if ( !pagesToNotify.contains( pageNumber ) ) pagesToNotify.append( pageNumber ); } } // reset cursor to previous shape QApplication::restoreOverrideCursor(); // send page lists if found anything new //if ( foundAMatch ) ?maybe? foreachObserver( notifySetup( pages_vector, false ) ); } // 2. NEXTMATCH - find next matching item (or start from top) else if ( type == NextMatch ) { // find out from where to start/resume search from int viewportPage = (*d->viewportIterator).pageNumber; int currentPage = fromStart ? 0 : ((s->continueOnPage != -1) ? s->continueOnPage : viewportPage); KPDFPage * lastPage = fromStart ? 0 : pages_vector[ currentPage ]; // continue checking last SearchPage first (if it is the current page) RegularAreaRect * match = 0; if ( lastPage && lastPage->number() == s->continueOnPage ) { if ( newText ) match = lastPage->findText( searchID, text, FromTop, caseSensitive ); else match = lastPage->findText( searchID, text, NextRes, caseSensitive, &s->continueOnMatch ); if ( !match ) currentPage++; } // if no match found, loop through the whole doc, starting from currentPage if ( !match ) { const int pageCount = pages_vector.count(); for ( int i = 0; i < pageCount; i++ ) { if ( currentPage >= pageCount ) { if ( noDialogs || KMessageBox::questionYesNo(0, i18n("End of document reached.\nContinue from the beginning?"), QString::null, KStdGuiItem::cont(), KStdGuiItem::cancel()) == KMessageBox::Yes ) currentPage = 0; else break; } // get page KPDFPage * page = pages_vector[ currentPage ]; // request search page if needed if ( !page->hasSearchPage() ) requestTextPage( page->number() ); // if found a match on the current page, end the loop if ( ( match = page->findText( searchID, text, FromTop, caseSensitive ) ) ) break; currentPage++; } } // reset cursor to previous shape QApplication::restoreOverrideCursor(); // if a match has been found.. if ( match ) { // update the RunningSearch structure adding this match.. foundAMatch = true; s->continueOnPage = currentPage; s->continueOnMatch = *match; s->highlightedPages.append( currentPage ); // ..add highlight to the page.. pages_vector[ currentPage ]->setHighlight( searchID, match, color ); // ..queue page for notifying changes.. if ( !pagesToNotify.contains( currentPage ) ) pagesToNotify.append( currentPage ); // ..move the viewport to show the first of the searched word sequence centered if ( moveViewport ) { DocumentViewport searchViewport( currentPage ); searchViewport.rePos.enabled = true; searchViewport.rePos.normalizedX = (match->first()->left + match->first()->right) / 2.0; searchViewport.rePos.normalizedY = (match->first()->top + match->first()->bottom) / 2.0; setViewport( searchViewport, -1, true ); } } else if ( !noDialogs ) KMessageBox::information( 0, i18n( "No matches found for '%1'.", text ) ); } // 3. PREVMATCH //TODO else if ( type == PrevMatch ) { } // 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 = text.split( " ", QString::SkipEmptyParts ); int wordsCount = words.count(), hueStep = (wordsCount > 1) ? (60 / (wordsCount - 1)) : 60, baseHue, baseSat, baseVal; color.getHsv( &baseHue, &baseSat, &baseVal ); QVector< 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::fromHsv( newHue, baseSat, baseVal ); RegularAreaRect * lastMatch = 0; // add all highlights for current word bool wordMatched = false; while ( 1 ) { if ( lastMatch ) lastMatch = page->findText( searchID, word, NextRes, caseSensitive, lastMatch ); else lastMatch = page->findText( searchID, word, FromTop, 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 QLinkedList< int >::iterator nIt = pagesToNotify.begin(), nEnd = pagesToNotify.end(); for ( ; nIt != nEnd; ++nIt ) foreachObserver( notifyPageChanged( *nIt, DocumentObserver::Highlights ) ); // return if search has found one or more matches return foundAMatch;}bool KPDFDocument::continueSearch( int searchID ){ // check if searchID is present in runningSearches if ( !d->searches.contains( searchID ) ) return false; // start search with cached parameters from last search by searchID RunningSearch * p = d->searches[ searchID ]; return searchText( searchID, p->cachedString, false, p->cachedCaseSensitive, p->cachedType, p->cachedViewportMove, p->cachedColor, p->cachedNoDialogs );}void KPDFDocument::resetSearch( int searchID )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -