From 519892521fe2b6fdc18a71cf0739617be1a49bc3 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Thu, 3 Feb 2005 17:09:33 +0000 Subject: [PATCH] Fix the last CRASH (on search) and fix a memleak before BETA2 tagging. Removed old code, reworked bad code. I have no more reported crashes now. No plans for additions or code changes till 3.4 release. Thank you all kpdf users, Have Fun! svn path=/trunk/kdegraphics/kpdf/; revision=385897 --- TODO | 33 +++-- core/document.cpp | 32 +---- core/document.h | 1 - core/generator_pdf/generator_pdf.cpp | 1 + core/page.cpp | 18 ++- core/page.h | 10 +- part.cpp | 4 +- ui/pagepainter.cpp | 205 +++++++++++++-------------- ui/pageview.cpp | 4 +- ui/searchwidget.cpp | 24 ++-- ui/searchwidget.h | 4 + ui/thumbnaillist.cpp | 5 +- 12 files changed, 171 insertions(+), 170 deletions(-) diff --git a/TODO b/TODO index c7b00f322..1ba7d2eaa 100644 --- a/TODO +++ b/TODO @@ -5,32 +5,33 @@ Legend: FIX - FIXed (bug or regression) MRG - MeRGed (code from a branch or a patch) -Status: +Status (last 3 updates): +-> 2005-02-03+: Fixing bugs until 3.4 release.. reports are welcome!!! -> 2005-02-02: Features for 3.4 done. Ready for bugfixes. -> 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. More items (first items will enter 'In progress list' first): + -- THIS LIST IS FROZEN FOR 3.4 RELEASE -- +-> 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 -> 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: save the page width setting between runs (save/restore zoom factor) -> presentation: provide a pageX/totalPages indicator in addition to the circle one --> add scrollbar marks for bookmarks (like kate) --> search: google search in the page -> cleanup code and update README.png -> search: use shortcut for 'find next' action (not the default one) in find-ahead -> show Viewport in ThumbnailsList (blended/contour) -> Delay TOC (DocumentSynapsis) generation (and move it on thread) +-> add a way to handle "named xpdf links" in KPDFLink instead of resolving all destinations + when displaying a page (speedups a lot generation of page with many links) -> 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 (need new highligh engine first) -> abstract TextPage generation (the last xpdf dependant class!). then go dancing in the streets. --> better boomark rendering (tested a 'clip overlay' but looks bad actually) - maybe gray out other pages? -> Dom framework to cache document metadata. It should archive those types of data: (NOTE: already Dom'ed object is marked with 'X') - Synopsis will go there after 1st generation (so we can edit it too) @@ -48,14 +49,13 @@ More items (first items will enter 'In progress list' first): this visually explains basic usage, mouse buttons functions & more.. -> take care of TODOs in code -> ADD: click over image allows "save image" [60% done (activerect of type image)] --> screen editing (annotations): framework (BR67300,BR62793) --> screen editing (annotations): tools (BR67300), yellow notes 'post-it' like -> export all text in plain_text/html -> extract(export?) images (have a look at ImageOutputDev.cc and pdfimages.cc from xpdf (not in our xpdf sources)) -> text selection in wordprocessor style (very hard) -> zoom: fit text (with configurable margin) +-> bookview: 3d opengl widget for viewing the document as a real book (turning pages, etc..) -> open gzipped (.pdf.gz?) files --> kspeech TTS interface. speech {document / page / selection} +-> kspeech TTS interface. speech {document / page / selection(done)} -> automatic online dictionaries / translators (BR80338) -> core: pdf forms support -> add OCR for building TextPages out of pure graphical (aka scanned) pages @@ -65,9 +65,8 @@ More items (first items will enter 'In progress list' first): -> 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) -> presentation: wheel not visible on black. gradient appreciated on lighter backgrounds. --> history as a toolbox child (collecting Doc's viewport changes notifications) -> 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) +-> 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) @@ -75,9 +74,14 @@ More items (first items will enter 'In progress list' first): -> 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 -> tools: ruler, measure: distance, perimeter, ?area?, color picker -> export: export to other formats keeping formatting (a dream.. except for PNG :-) (PS is easy, we just have PSOutputDev that does it :-D) +-> history as a toolbox child (collecting Doc's viewport changes notifications) Done (newest features come first): --> FIX: memleaks, bugfixes (1,..) +-> 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) +-> CHG: new search api. supports multiple searches at once, multiple highlighs per page +-> ADD: pageView moves smoothly when searching / moving in history +-> ADD: better bookmark rendering in thumbnailslist (show 'clip overlay') -> CHG: changes and cleanups in pageView's mouse handling functions -> ADD: KTTSD simple support: speech selection using kspeech api via pure dcop (don't break compatibiltiy) -> CHG: right click and drag while in 'normal' mode changes to 'selection' mode and selects @@ -164,3 +168,4 @@ Done (newest features come first): -> The branch 'kpdf_experiments' was created at this point. Code refactoring started. -> ADD: Completely use xpdf code for rendering that solves most font problems (Albert) -> MRG: Replace xpdf version with lastest one (3.00) that supports PDF 1.5 (Albert) +-> newest added features are at the top of the list diff --git a/core/document.cpp b/core/document.cpp index 61bc2adbe..bef87572d 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -157,7 +157,7 @@ bool KPDFDocument::openDocument( const QString & docFile ) loadDocumentInfo(); // 3. setup observers inernal lists and data - processPageList( true ); + foreachObserver( notifySetup( pages_vector, true ) ); // 4. set initial page (restoring the page saved in xml if loaded) DocumentViewport loadedViewport = (*d->viewportIterator); @@ -554,6 +554,10 @@ void KPDFDocument::setNextViewport() bool KPDFDocument::searchText( int searchID, const QString & text, bool fromStart, bool caseSensitive, SearchType type, bool moveViewport, const QColor & color, bool noDialogs ) { + // don't perform searches on empty docs + if ( !generator || pages_vector.isEmpty() ) + return false; + // if searchID search not recorded, create new descriptor and init params if ( !d->searches.contains( searchID ) ) { @@ -1213,32 +1217,6 @@ bool KPDFDocument::openRelativeFile( const QString & fileName ) return openDocument( absFileName ); } -void KPDFDocument::processPageList( bool documentChanged ) -{ - /* FIXME - if ( d->filterText.length() < 3 ) - unHilightPages(); - else - { - uint pageCount = pages_vector.count(); - for ( uint i = 0; i < pageCount ; i++ ) - { - KPDFPage * page = pages_vector[ i ]; - //page->clearAttribute( KPDFPage::Highlight ); - if ( d->filterText.length() > 2 ) - { - if ( !page->hasSearchPage() ) - requestTextPage( i ); - if ( page->hasText( d->filterText, d->filterCase, true ) ) - page->setAttribute( KPDFPage::Highlight ); - } - } - } - */ - // send the list to observers - foreachObserver( notifySetup( pages_vector, documentChanged ) ); -} - void KPDFDocument::saveDocumentInfo() const { diff --git a/core/document.h b/core/document.h index cf4ee96c1..d679502f1 100644 --- a/core/document.h +++ b/core/document.h @@ -107,7 +107,6 @@ class KPDFDocument : public QObject void loadDocumentInfo(); QString giveAbsolutePath( const QString & fileName ); bool openRelativeFile( const QString & fileName ); - void processPageList( bool documentChanged ); Generator * generator; QValueVector< KPDFPage * > pages_vector; diff --git a/core/generator_pdf/generator_pdf.cpp b/core/generator_pdf/generator_pdf.cpp index ee2ed99ba..415048034 100644 --- a/core/generator_pdf/generator_pdf.cpp +++ b/core/generator_pdf/generator_pdf.cpp @@ -720,6 +720,7 @@ PDFPixmapGeneratorThread::~PDFPixmapGeneratorThread() for ( ; it != end; ++it ) delete *it; } + delete d->currentRequest; // delete internal storage structure delete d; } diff --git a/core/page.cpp b/core/page.cpp index 7e9b048f1..30ed7028b 100644 --- a/core/page.cpp +++ b/core/page.cpp @@ -49,6 +49,22 @@ KPDFPage::~KPDFPage() } +bool KPDFPage::hasHighlights( int id ) const +{ + // simple case: have no highlights + if ( m_highlights.isEmpty() ) + return false; + // simple case: we have highlights and no id to match + if ( id == -1 ) + return true; + // iterate on the highlights list to find an entry by id + QValueList< HighlightRect * >::const_iterator it = m_highlights.begin(), end = m_highlights.end(); + for ( ; it != end; ++it ) + if ( (*it)->id == id ) + return true; + return false; +} + bool KPDFPage::hasPixmap( int id, int width, int height ) const { if ( !m_pixmaps.contains( id ) ) @@ -143,7 +159,7 @@ HighlightRect * KPDFPage::searchText( const QString & text, bool strictCase, Hig else if ( dir == NextMatch ) found = m_text->findText( u, len, gFalse, gTrue, gTrue, gFalse, &sLeft, &sTop, &sRight, &sBottom ); else if ( dir == PrevMatch ) - // FIXME: this doesn't work as expected + // FIXME: this doesn't work as expected (luckily backward search isn't yet used) found = m_text->findText( u, len, gTrue, gFalse, gFalse, gTrue, &sLeft, &sTop, &sRight, &sBottom ); // if not found (even in case unsensitive search), terminate diff --git a/core/page.h b/core/page.h index 0d60201eb..01acefe53 100644 --- a/core/page.h +++ b/core/page.h @@ -44,17 +44,13 @@ class KPDFPage inline float height() const { return m_height; } inline float ratio() const { return m_height / m_width; } inline bool hasBookmark() const { return m_bookmarked; } - inline bool hasHighlights() const { return !m_highlights.isEmpty(); } - + bool hasHighlights( int id = -1 ) const; bool hasPixmap( int id, int width = -1, int height = -1 ) const; bool hasSearchPage() const; bool hasRect( int mouseX, int mouseY ) const; bool hasLink( int mouseX, int mouseY ) const; - const KPDFPageRect * getRect( int mouseX, int mouseY ) const; - // - HL? .. - const KPDFPageTransition * getTransition() const; - const QString getTextInRect( const QRect & rect, double zoom /*= 1.0*/ ) const; // operations (by KPDFDocument) @@ -128,7 +124,9 @@ class KPDFPageRect void * m_pointer; }; -// TODO: comment this +/** + * @short A normalized and colored highlight on the page. + */ struct HighlightRect { // publicly accessed fields diff --git a/part.cpp b/part.cpp index 58b6bc6d3..a5fb6eaec 100644 --- a/part.cpp +++ b/part.cpp @@ -373,6 +373,7 @@ bool Part::closeURL() m_searchStarted = false; if (!m_file.isEmpty()) m_watcher->removeFile(m_file); m_document->closeDocument(); + m_searchWidget->clearText(); return KParts::ReadOnlyPart::closeURL(); } @@ -524,8 +525,9 @@ void Part::slotFind() if ( dlg.exec() == QDialog::Accepted ) { m_searchStarted = true; + m_document->resetSearch( PART_SEARCH_ID ); m_document->searchText( PART_SEARCH_ID, dlg.pattern(), false, dlg.options() & KFindDialog::CaseSensitive, - KPDFDocument::NextMatch, true, Qt::red ); + KPDFDocument::NextMatch, true, qRgb( 255, 255, 64 ) ); } } diff --git a/ui/pagepainter.cpp b/ui/pagepainter.cpp index 2484bc474..1de28873a 100644 --- a/ui/pagepainter.cpp +++ b/ui/pagepainter.cpp @@ -60,23 +60,25 @@ void PagePainter::paintPageOnPainter( const KPDFPage * page, int id, int flags, destPainter->setPen( Qt::gray ); destPainter->drawLine( 0, 0, width-1, height-1 ); destPainter->drawLine( 0, height-1, width-1, 0 ); + // idea here: draw a hourglass (or kpdf icon :-) on top-left corner return; } - // clear accessibility flag if not really needed - if ( !Settings::changeColors() || Settings::renderMode() == Settings::EnumRenderMode::Paper ) - flags &= ~Accessibility; - // use backBuffer if accessiblity (page color processing) is needed - bool backBuffer = flags & Accessibility; - // use backBuffer even if we have to render highlights - if ( !backBuffer && (flags & Highlights) && !page->m_highlights.isEmpty() ) + // find out what to paint over the pixmap (manipulations / overlays) + bool paintAccessibility = (flags & Accessibility) && Settings::changeColors() && (Settings::renderMode() != Settings::EnumRenderMode::Paper); + bool paintHighlights = (flags & Highlights) && !page->m_highlights.isEmpty(); + bool enhanceLinks = (flags & EnhanceLinks) && Settings::highlightLinks(); + bool enhanceImages = (flags & EnhanceImages) && Settings::highlightImages(); + // check if there are really some highlightRects to paint + if ( paintHighlights ) { - // precalc normalized limits rect for intersection + // precalc normalized 'limits rect' for intersection double nXMin = (double)limits.left() / (double)width, - nXMax = (double)(limits.right() + 1) / (double)width, + nXMax = (double)(limits.right() + 0) / (double)width, nYMin = (double)limits.top() / (double)height, - nYMax = (double)(limits.bottom() + 1) / (double)height; - // if an highlightRect intersects limits, use backBuffer for painting + nYMax = (double)(limits.bottom() + 0) / (double)height; + // if no rect intersects limits, disable paintHighlights + paintHighlights = false; QValueList< HighlightRect * >::const_iterator hIt = page->m_highlights.begin(), hEnd = page->m_highlights.end(); for ( ; hIt != hEnd; ++hIt ) { @@ -84,86 +86,122 @@ void PagePainter::paintPageOnPainter( const KPDFPage * page, int id, int flags, // intersection: A) highlightRect, B) normalized limits if ( (r->left < nXMax) && (r->right > nXMin) && (r->top < nYMax) && (r->bottom > nYMin) ) { - backBuffer = true; + paintHighlights = true; break; } } } - // we have a pixmap to paint, now let's paint it using a direct or buffered painter + // use backBuffer if 'pixmap direct manipulation' is needed + bool backBuffer = paintAccessibility || paintHighlights; QPixmap * backPixmap = 0; QPainter * p = destPainter; if ( backBuffer ) { + // let's paint using a buffered painter 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.. + // 1. 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 + // TODO paint only the needed part (note: hope that Qt4 transforms are faster) 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 ) + // 2. mangle pixmap: convert it to 32-bit qimage and perform pixel-level manipulations + if ( backBuffer ) { QImage backImage = backPixmap->convertToImage(); - switch ( Settings::renderMode() ) + // 2.1. modify pixmap following accessibility settings + if ( paintAccessibility ) { - 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 ) + 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; + } + } + // 2.2. highlight rects in page + if ( paintHighlights ) + { + // draw highlights that are inside the 'limits' paint region + QValueList< HighlightRect * >::const_iterator hIt = page->m_highlights.begin(), hEnd = page->m_highlights.end(); + for ( ; hIt != hEnd; ++hIt ) + { + HighlightRect * r = *hIt; + QRect highlightRect( (int)(r->left * width), (int)(r->top * height), + (int)((r->right - r->left) * width) + 1, (int)((r->bottom - r->top) * height) + 1 ); + if ( highlightRect.isValid() && highlightRect.intersects( limits ) ) { - 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 ) + // find out the rect to highlight on pixmap + highlightRect = highlightRect.intersect( limits ); + highlightRect.moveBy( -limits.left(), -limits.top() ); + + // highlight composition (product: highlight color * destcolor) + unsigned int * data = (unsigned int *)backImage.bits(); + int val, newR, newG, newB, + rh = r->color.red(), + gh = r->color.green(), + bh = r->color.blue(), + offset = highlightRect.top() * backImage.width(); + for( int y = highlightRect.top(); y <= highlightRect.bottom(); ++y ) { - val = con * ( val - thr ) / 2 + thr; - if ( val > 255 ) - val = 255; - else if ( val < 0 ) - val = 0; + for( int x = highlightRect.left(); x <= highlightRect.right(); ++x ) + { + val = data[ x + offset ]; + newR = (qRed(val) * rh) / 255; + newG = (qGreen(val) * gh) / 255; + newB = (qBlue(val) * bh) / 255; + data[ x + offset ] = qRgba( newR, newG, newB, 255 ); + } + offset += backImage.width(); } - 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 ) + // 3. visually enchance links and images if requested + if ( enhanceLinks || enhanceImages ) { QColor normalColor = QApplication::palette().active().highlight(); QColor lightColor = normalColor.light( 140 ); @@ -175,8 +213,8 @@ void PagePainter::paintPageOnPainter( const KPDFPage * page, int id, int flags, for ( ; lIt != lEnd; ++lIt ) { KPDFPageRect * rect = *lIt; - if ( (hLinks && rect->pointerType() == KPDFPageRect::Link) || - (hImages && rect->pointerType() == KPDFPageRect::Image) ) + if ( (enhanceLinks && rect->pointerType() == KPDFPageRect::Link) || + (enhanceImages && rect->pointerType() == KPDFPageRect::Image) ) { QRect rectGeometry = rect->geometry(); if ( rectGeometry.intersects( limitsEnlarged ) ) @@ -194,56 +232,7 @@ void PagePainter::paintPageOnPainter( const KPDFPage * page, int id, int flags, } } - // draw selection (note: it is rescaled since the text page is at 100% scale) - if ( backBuffer && ( flags & Highlights ) && !page->m_highlights.isEmpty() ) - { - QImage backImage = backPixmap->convertToImage(); - // draw highlights that are inside the 'limits' paint region - QValueList< HighlightRect * >::const_iterator hIt = page->m_highlights.begin(), hEnd = page->m_highlights.end(); - for ( ; hIt != hEnd; ++hIt ) - { - HighlightRect * r = *hIt; - QRect highlightRect( (int)(r->left * width), (int)(r->top * height), - (int)((r->right - r->left) * width) + 1, (int)((r->bottom - r->top) * height) + 1 ); - if ( highlightRect.isValid() && highlightRect.intersects( limits ) ) - { -#if 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( highlightRect ); -#else - // TODO this is the other way - // find out the rect to highlight on pixmap - highlightRect = highlightRect.intersect( limits ); - highlightRect.moveBy( -limits.left(), -limits.top() ); - - // Manual yellow highlight - unsigned int * data = (unsigned int *)backImage.bits(); - int val, - rh = r->color.red(), - gh = r->color.green(), - bh = r->color.blue(); - for( int y = highlightRect.top(); y < highlightRect.bottom(); ++y ) - { - int offset = y * backImage.width(); - for( int x = highlightRect.left(); x < highlightRect.right(); ++x ) - { - val = data[x + offset]; - int newR = (qRed(val) * rh) / 255, - newG = (qGreen(val) * gh) / 255, - newB = (qBlue(val) * bh) / 255; - data[x + offset] = qRgba( newR, newG, newB, 255 ); - } - } -#endif - } - } - backPixmap->convertFromImage( backImage ); - } - - // if was backbuffering, copy the backPixmap to destination + // 4. if was backbuffering, copy the backPixmap to destination if ( backBuffer ) { delete p; diff --git a/ui/pageview.cpp b/ui/pageview.cpp index 7d02c3d85..9ca7c3a18 100644 --- a/ui/pageview.cpp +++ b/ui/pageview.cpp @@ -565,7 +565,7 @@ void PageView::keyPressEvent( QKeyEvent * e ) { d->typeAheadString = d->typeAheadString.left( d->typeAheadString.length() - 1 ); bool found = d->document->searchText( PAGEVIEW_SEARCH_ID, d->typeAheadString, true, false, - KPDFDocument::NextMatch, true, Qt::yellow, true ); + KPDFDocument::NextMatch, true, qRgb( 128, 255, 128 ), true ); QString status = found ? i18n("Text found: \"%1\".") : i18n("Text not found: \"%1\"."); d->messageWindow->display( status.arg(d->typeAheadString.lower()), found ? PageViewMessage::Find : PageViewMessage::Warning, 4000 ); @@ -599,7 +599,7 @@ void PageView::keyPressEvent( QKeyEvent * e ) { d->typeAheadString += e->text(); bool found = d->document->searchText( PAGEVIEW_SEARCH_ID, d->typeAheadString, false, false, - KPDFDocument::NextMatch, true, Qt::yellow, true ); + KPDFDocument::NextMatch, true, qRgb( 128, 255, 128 ), true ); QString status = found ? i18n("Text found: \"%1\".") : i18n("Text not found: \"%1\"."); d->messageWindow->display( status.arg(d->typeAheadString.lower()), found ? PageViewMessage::Find : PageViewMessage::Warning, 4000 ); diff --git a/ui/searchwidget.cpp b/ui/searchwidget.cpp index 61652d33d..d510b8778 100644 --- a/ui/searchwidget.cpp +++ b/ui/searchwidget.cpp @@ -24,9 +24,6 @@ #include "core/document.h" #include "conf/settings.h" -// definition of searchID for this class -#define SW_SEARCH_ID 3 - // uncomment following to enable the case switching button //#define SW_ENABLE_CASE_BUTTON #define CLEAR_ID 1 @@ -75,11 +72,18 @@ SearchWidget::SearchWidget( QWidget * parent, KPDFDocument * document ) setItemAutoSized( LEDIT_ID ); } +void SearchWidget::clearText() +{ + getLined( LEDIT_ID )->clear(); +} + void SearchWidget::slotTextChanged( const QString & text ) { // if length<3 set 'red' text and send a blank string to document QColor color = text.length() < 3 ? Qt::darkRed : palette().active().text(); - getLined( LEDIT_ID )->setPaletteForegroundColor( color ); + KLineEdit * lineEdit = getLined( LEDIT_ID ); + lineEdit->setPaletteForegroundColor( color ); + lineEdit->setPaletteBackgroundColor( palette().active().base() ); m_inputDelayTimer->stop(); m_inputDelayTimer->start(333, true); } @@ -90,12 +94,16 @@ void SearchWidget::startSearch() 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, Qt::green ); + ok = m_document->searchText( SW_SEARCH_ID, text, true, m_caseSensitive, KPDFDocument::AllDoc, false, qRgb( 0, 183, 255 ) ); else m_document->resetSearch( SW_SEARCH_ID ); - // change color to red if text not found - QColor color = ok ? palette().active().text() : Qt::red; - getLined( LEDIT_ID )->setPaletteForegroundColor( color ); + // if not found, use warning colors + if ( !ok ) + { + KLineEdit * lineEdit = getLined( LEDIT_ID ); + lineEdit->setPaletteForegroundColor( Qt::white ); + lineEdit->setPaletteBackgroundColor( Qt::red ); + } } void SearchWidget::slotCaseChanged( int index ) diff --git a/ui/searchwidget.h b/ui/searchwidget.h index 2a5447364..3bc192a3b 100644 --- a/ui/searchwidget.h +++ b/ui/searchwidget.h @@ -16,6 +16,9 @@ class KPopupMenu; class KPDFDocument; class m_inputDelayTimer; +// definition of searchID for this class (publicly available to ThumbnailsList) +#define SW_SEARCH_ID 3 + /** * @short A widget for find-as-you-type search. Outputs to the Document. * @@ -29,6 +32,7 @@ class SearchWidget : public KToolBar Q_OBJECT public: SearchWidget( QWidget *parent, KPDFDocument *document ); + void clearText(); private: KPDFDocument * m_document; diff --git a/ui/thumbnaillist.cpp b/ui/thumbnaillist.cpp index e9d38037b..7c8443706 100644 --- a/ui/thumbnaillist.cpp +++ b/ui/thumbnaillist.cpp @@ -20,6 +20,7 @@ // local includes #include "thumbnaillist.h" #include "pagepainter.h" +#include "searchwidget.h" // for SW_SEARCH_ID #include "core/document.h" #include "core/generator.h" #include "core/page.h" @@ -114,7 +115,7 @@ void ThumbnailList::notifySetup( const QValueVector< KPDFPage * > & pages, bool bool skipCheck = true; for ( ; pIt != pEnd ; ++pIt ) //if ( (*pIt)->attributes() & flags ) - if ( (*pIt)->hasHighlights() ) + if ( (*pIt)->hasHighlights( SW_SEARCH_ID ) ) skipCheck = false; // generate Thumbnails for the given set of pages @@ -122,7 +123,7 @@ void ThumbnailList::notifySetup( const QValueVector< KPDFPage * > & pages, bool totalHeight = 0; for ( pIt = pages.begin(); pIt != pEnd ; ++pIt ) //if ( skipCheck || (*pIt)->attributes() & flags ) - if ( skipCheck || (*pIt)->hasHighlights() ) + if ( skipCheck || (*pIt)->hasHighlights( SW_SEARCH_ID ) ) { ThumbnailWidget * t = new ThumbnailWidget( viewport(), *pIt, this ); t->setFocusProxy( this );