QRect DocumentWidget::pageRect() const { QRect boundingRect = rect(); // Substract the shadow. boundingRect.addCoords(1,1,-5,-5); return boundingRect; }
void MultiLayer::mousePressEvent(QMouseEvent *e) { int margin = 5; QPoint pos = canvas->mapFromParent(e->pos()); // iterate backwards, so layers on top are preferred for selection QList<QWidget *>::iterator i = graphsList.end(); while (i != graphsList.begin()) { --i; QRect igeo = (*i)->frameGeometry(); igeo.addCoords(-margin, -margin, margin, margin); if (igeo.contains(pos)) { if (e->modifiers() & Qt::ShiftModifier) { if (d_layers_selector) d_layers_selector->add(*i); else { d_layers_selector = new SelectionMoveResizer(*i); connect(d_layers_selector, SIGNAL(targetsChanged()), this, SIGNAL(modifiedPlot())); } } else { setActiveGraph((Graph *)(*i)); active_graph->raise(); if (!d_layers_selector) { d_layers_selector = new SelectionMoveResizer(*i); connect(d_layers_selector, SIGNAL(targetsChanged()), this, SIGNAL(modifiedPlot())); } } return; } } if (d_layers_selector) delete d_layers_selector; }
bool ScalePicker::eventFilter(QObject *object, QEvent *e) { if ( object->inherits("QwtScale") && e->type() == QEvent::MouseButtonDblClick) { mouseDblClicked((const QwtScale *)object, ((QMouseEvent *)e)->pos()); return TRUE; } if ( object->inherits("QwtScale") && e->type() == QEvent::MouseButtonPress) { const QMouseEvent *me = (const QMouseEvent *)e; if (me->button()==QEvent::LeftButton) { emit clicked(); if (plot()->margin() < 2 && plot()->lineWidth() < 2) { QRect r = ((const QwtScale *)object)->rect(); r.addCoords(2, 2, -2, -2); if (!r.contains(me->pos())) emit highlightGraph(); } return TRUE; } else if (me->button() == QEvent::RightButton) { mouseRightClicked((const QwtScale *)object, me->pos()); return TRUE; } } if ( object->inherits("QwtScale") && e->type() == QEvent::MouseMove) { const QMouseEvent *me = (const QMouseEvent *)e; movedGraph=TRUE; emit moveGraph(me->pos()); return TRUE; } if ( object->inherits("QwtScale") && e->type() == QEvent::MouseButtonRelease) { if (movedGraph) { emit releasedGraph(); movedGraph=FALSE; } return TRUE; } return QObject::eventFilter(object, e); }
void DocumentWidget::flash(int fo) { if (timerIdent != 0) { killTimer(timerIdent); // Delete old flash rectangle animationCounter = 10; QRect flashRect = linkFlashRect(); flashRect.addCoords(-1, -1, 1, 1); repaint(flashRect, false); } animationCounter = 0; flashOffset = fo; timerIdent = startTimer(50); // Start the animation. The animation proceeds in 1/10s intervals }
void DocumentWidget::timerEvent( QTimerEvent *e ) { if (animationCounter == 0) { killTimer(e->timerId()); timerIdent = startTimer(50); // Proceed with the animation in 1/10s intervals } animationCounter++; QRect flashRect = linkFlashRect(); flashRect.addCoords(-1, -1, 1, 1); if (animationCounter >= 10) { killTimer(e->timerId()); timerIdent = 0; animationCounter = 0; } repaint(flashRect, false); }
void QFrame::paintEvent( QPaintEvent *event ) { const int m = margin(); if ( m && testWFlags( WNoAutoErase ) ) { QRect r = contentsRect(); r.addCoords( -m, -m, m, m ); erase( event->region().intersect( QRegion( r ) - contentsRect() ) ); } QPainter paint( this ); if ( !contentsRect().contains( event->rect() ) ) { paint.save(); paint.setClipRegion( event->region().intersect(frameRect()) ); drawFrame( &paint ); paint.restore(); } if ( event->rect().intersects( contentsRect() ) && (fstyle & MShape) != HLine && (fstyle & MShape) != VLine ) { paint.setClipRegion( event->region().intersect( contentsRect() ) ); drawContents( &paint ); } }
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 have no pixmap, draw blank page with gray cross and exit if ( !pixmap ) { QColor color = Qt::white; if ( KpdfSettings::changeColors() ) { switch ( KpdfSettings::renderMode() ) { case KpdfSettings::EnumRenderMode::Inverted: color = Qt::black; break; case KpdfSettings::EnumRenderMode::Paper: color = KpdfSettings::paperColor(); break; case KpdfSettings::EnumRenderMode::Recolor: color = KpdfSettings::recolorBackground(); break; default: ; } } destPainter->fillRect( limits, color ); // 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 ); // idea here: draw a hourglass (or kpdf icon :-) on top-left corner return; } // find out what to paint over the pixmap (manipulations / overlays) bool paintAccessibility = (flags & Accessibility) && KpdfSettings::changeColors() && (KpdfSettings::renderMode() != KpdfSettings::EnumRenderMode::Paper); bool paintHighlights = (flags & Highlights) && !page->m_highlights.isEmpty(); bool enhanceLinks = (flags & EnhanceLinks) && KpdfSettings::highlightLinks(); bool enhanceImages = (flags & EnhanceImages) && KpdfSettings::highlightImages(); // check if there are really some highlightRects to paint if ( paintHighlights ) { // precalc normalized 'limits rect' for intersection double nXMin = (double)limits.left() / (double)width, nXMax = (double)limits.right() / (double)width, nYMin = (double)limits.top() / (double)height, nYMax = (double)limits.bottom() / (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 ) { if ( (*hIt)->intersects( nXMin, nYMin, nXMax, nYMax ) ) { paintHighlights = true; break; } } } // 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() ); } // 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 (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(); } // 2. mangle pixmap: convert it to 32-bit qimage and perform pixel-level manipulations if ( backBuffer ) { QImage backImage = backPixmap->convertToImage(); // 2.1. modify pixmap following accessibility settings if ( paintAccessibility ) { switch ( KpdfSettings::renderMode() ) { case KpdfSettings::EnumRenderMode::Inverted: // Invert image pixels using QImage internal function backImage.invertPixels(false); break; case KpdfSettings::EnumRenderMode::Recolor: // Recolor image using KImageEffect::flatten with dither:0 KImageEffect::flatten( backImage, KpdfSettings::recolorForeground(), KpdfSettings::recolorBackground() ); break; case KpdfSettings::EnumRenderMode::BlackWhite: // Manual Gray and Contrast unsigned int * data = (unsigned int *)backImage.bits(); int val, pixels = backImage.width() * backImage.height(), con = KpdfSettings::bWContrast(), thr = 255 - KpdfSettings::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 = r->geometry( width, height ); if ( highlightRect.isValid() && highlightRect.intersects( limits ) ) { // 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 ) { 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(); } } } } backPixmap->convertFromImage( backImage ); } // 3. visually enchance links and images if requested if ( enhanceLinks || enhanceImages ) { 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< ObjectRect * >::const_iterator lIt = page->m_rects.begin(), lEnd = page->m_rects.end(); for ( ; lIt != lEnd; ++lIt ) { ObjectRect * rect = *lIt; if ( (enhanceLinks && rect->objectType() == ObjectRect::Link) || (enhanceImages && rect->objectType() == ObjectRect::Image) ) { QRect rectGeometry = rect->geometry( width, height ); 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 ); } } } } // 4. if was backbuffering, copy the backPixmap to destination if ( backBuffer ) { delete p; destPainter->drawPixmap( limits.left(), limits.top(), *backPixmap ); delete backPixmap; } }
void OSDWidget::renderOSDText( const QString &txt ) { // Escaped text QString text = Konversation::removeIrcMarkup(txt); static QBitmap mask; //This is various spacings and margins, based on the font to look "just right" const uint METRIC = fontMetrics().width( 'x' ); // Set a sensible maximum size, don't cover the whole desktop or cross the screen QSize max = QApplication::desktop()->screen( m_screen )->size() - QSize( MARGIN*2 + METRIC*2, 100 ); QFont titleFont( "Arial", 12, QFont::Bold ); QFontMetrics titleFm( titleFont ); // The title cannnot be taller than one line // AlignAuto = align Arabic to the right, etc. QRect titleRect = titleFm.boundingRect( 0, 0, max.width() - METRIC, titleFm.height(), AlignAuto, m_appName ); // The osd cannot be larger than the screen QRect textRect = fontMetrics().boundingRect( 0, 0, max.width(), max.height(), AlignAuto | WordBreak, text ); if ( textRect.width() < titleRect.width() ) textRect.setWidth( titleRect.width() ); //this should still be within the screen bounds textRect.addCoords( 0, 0, METRIC*2, titleRect.height() + METRIC ); osdBuffer.resize( textRect.size() ); mask.resize( textRect.size() ); // Start painting! QPainter bufferPainter( &osdBuffer ); QPainter maskPainter( &mask ); // Draw backing rectangle const uint xround = (METRIC * 200) / textRect.width(); const uint yround = (METRIC * 200) / textRect.height(); bufferPainter.setPen( Qt::black ); bufferPainter.setBrush( backgroundColor() ); bufferPainter.drawRoundRect( textRect, xround, yround ); bufferPainter.setFont( font() ); const uint w = textRect.width() - 1; const uint h = textRect.height() - 1; // Draw the text shadow if ( m_shadow ) { bufferPainter.setPen( backgroundColor().dark( 175 ) ); bufferPainter.drawText( METRIC + 3, (METRIC/2) + titleFm.height() + 1, w, h, AlignLeft | WordBreak, text ); } // Draw the text bufferPainter.setPen( foregroundColor() ); bufferPainter.drawText( METRIC, (METRIC/2) + titleFm.height() - 1, w, h, AlignLeft | WordBreak, text ); // Draw the title text bufferPainter.setFont( titleFont ); bufferPainter.drawText( METRIC * 2, (METRIC/2), w, h, AlignLeft, m_appName ); // Masking for transparency mask.fill( Qt::black ); maskPainter.setBrush( Qt::white ); maskPainter.drawRoundRect( textRect, xround, yround ); setMask( mask ); //do last to reduce noticeable change when showing multiple OSDs in succession reposition( textRect.size() ); m_currentText = text; m_dirty = false; update(); }
void KdmLayoutBox::update(const QRect &parentGeometry, bool force) { kdDebug() << this << " update " << parentGeometry << endl; // I can't layout children if the parent rectangle is not valid if(!parentGeometry.isValid() || parentGeometry.isEmpty()) return; // Check if box size was computed. If not compute it // TODO check if this prevents updating changing items // if (!hintedSize.isValid()) // sizeHint(); // kdDebug() << this << " hintedSize " << hintedSize << endl; // XXX why was this asymmetric? it broke things big time. QRect childrenRect = /*box.isVertical ? QRect( parentGeometry.topLeft(), hintedSize ) :*/ parentGeometry; // Begin cutting the parent rectangle to attach children on the right place childrenRect.addCoords(box.xpadding, box.ypadding, -box.xpadding, -box.ypadding); kdDebug() << this << " childrenRect " << childrenRect << endl; // For each child in list ... if(box.homogeneous) { int ccnt = 0; for(QValueList< KdmItem * >::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) if(!(*it)->isExplicitlyHidden()) ccnt++; int height = (childrenRect.height() - (ccnt - 1) * box.spacing) / ccnt; int width = (childrenRect.width() - (ccnt - 1) * box.spacing) / ccnt; for(QValueList< KdmItem * >::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { if((*it)->isExplicitlyHidden()) continue; if(box.isVertical) { QRect temp(childrenRect.left(), childrenRect.top(), childrenRect.width(), height); (*it)->setGeometry(temp, force); childrenRect.setTop(childrenRect.top() + height + box.spacing); } else { QRect temp(childrenRect.left(), childrenRect.top(), width, childrenRect.height()); kdDebug() << "placement " << *it << " " << temp << " " << (*it)->placementHint(temp) << endl; temp = (*it)->placementHint(temp); (*it)->setGeometry(temp, force); childrenRect.setLeft(childrenRect.left() + width + box.spacing); } } } else { for(QValueList< KdmItem * >::ConstIterator it = m_children.begin(); it != m_children.end(); ++it) { if((*it)->isExplicitlyHidden()) continue; QRect temp = childrenRect, itemRect; if(box.isVertical) { temp.setHeight(0); itemRect = (*it)->placementHint(temp); temp.setHeight(itemRect.height()); childrenRect.setTop(childrenRect.top() + itemRect.size().height() + box.spacing); } else { temp.setWidth(0); itemRect = (*it)->placementHint(temp); kdDebug() << this << " placementHint " << *it << " " << temp << " " << itemRect << endl; temp.setWidth(itemRect.width()); childrenRect.setLeft(childrenRect.left() + itemRect.size().width() + box.spacing); kdDebug() << "childrenRect after " << *it << " " << childrenRect << endl; } itemRect = (*it)->placementHint(temp); kdDebug() << this << " placementHint2 " << *it << " " << temp << " " << itemRect << endl; (*it)->setGeometry(itemRect, force); } } }
bool TitlePicker::eventFilter(QObject *object, QEvent *e) { if (object != (QObject *)title) return FALSE; if ( object->inherits("QLabel") && e->type() == QEvent::MouseButtonDblClick) { emit doubleClicked(); return TRUE; } if ( object->inherits("QLabel") && e->type() == QEvent::MouseButtonPress ) { emit clicked(); const QMouseEvent *me = (const QMouseEvent *)e; if (me->button()==QEvent::RightButton) emit showTitleMenu(); QwtPlot *plot = (QwtPlot *)title->parent(); if (plot->margin() < 2 && plot->lineWidth() < 2) { QRect r = title->rect(); r.addCoords(2, 2, -2, -2); if (!r.contains(me->pos())) emit highlightGraph(); } return TRUE; } if ( object->inherits("QLabel") && e->type() == QEvent::MouseMove) { const QMouseEvent *me = (const QMouseEvent *)e; movedGraph=TRUE; emit moveGraph(me->pos()); return TRUE; } if ( object->inherits("QLabel") && e->type() == QEvent::MouseButtonRelease) { const QMouseEvent *me = (const QMouseEvent *)e; if (me->button()== QEvent::LeftButton) { emit clicked(); if (movedGraph) { emit releasedGraph(); movedGraph=FALSE; } return TRUE; } } if ( object->inherits("QLabel") && e->type() == QEvent::KeyPress) { switch (((const QKeyEvent *)e)->key()) { case Qt::Key_Delete: emit removeTitle(); return TRUE; } } return QObject::eventFilter(object, e); }
void MultiLayer::printAllLayers(QPainter *painter) { if (!painter) return; QPrinter *printer = (QPrinter *)painter->device(); QRect paperRect = ((QPrinter *)painter->device())->paperRect(); QRect canvasRect = canvas->rect(); QRect pageRect = printer->pageRect(); QRect cr = canvasRect; // cropmarks rectangle if (d_scale_on_print) { int margin = (int)((1 / 2.54) * printer->logicalDpiY()); // 1 cm margins double scaleFactorX = (double)(paperRect.width() - 2 * margin) / (double)canvasRect.width(); double scaleFactorY = (double)(paperRect.height() - 2 * margin) / (double)canvasRect.height(); if (d_print_cropmarks) { cr.moveTo(QPoint(margin + int(cr.x() * scaleFactorX), margin + int(cr.y() * scaleFactorY))); cr.setWidth(int(cr.width() * scaleFactorX)); cr.setHeight(int(cr.height() * scaleFactorX)); } for (int i = 0; i < (int)graphsList.count(); i++) { Graph *gr = (Graph *)graphsList.at(i); Plot *myPlot = gr->plotWidget(); QPoint pos = gr->pos(); pos = QPoint(margin + int(pos.x() * scaleFactorX), margin + int(pos.y() * scaleFactorY)); int width = int(myPlot->frameGeometry().width() * scaleFactorX); int height = int(myPlot->frameGeometry().height() * scaleFactorY); gr->print(painter, QRect(pos, QSize(width, height))); } } else { int x_margin = (pageRect.width() - canvasRect.width()) / 2; int y_margin = (pageRect.height() - canvasRect.height()) / 2; if (d_print_cropmarks) cr.moveTo(x_margin, y_margin); for (int i = 0; i < (int)graphsList.count(); i++) { Graph *gr = (Graph *)graphsList.at(i); Plot *myPlot = (Plot *)gr->plotWidget(); QPoint pos = gr->pos(); pos = QPoint(x_margin + pos.x(), y_margin + pos.y()); gr->print(painter, QRect(pos, myPlot->size())); } } if (d_print_cropmarks) { cr.addCoords(-1, -1, 2, 2); painter->save(); painter->setPen(QPen(QColor(Qt::black), 0.5, Qt::DashLine)); painter->drawLine(paperRect.left(), cr.top(), paperRect.right(), cr.top()); painter->drawLine(paperRect.left(), cr.bottom(), paperRect.right(), cr.bottom()); painter->drawLine(cr.left(), paperRect.top(), cr.left(), paperRect.bottom()); painter->drawLine(cr.right(), paperRect.top(), cr.right(), paperRect.bottom()); painter->restore(); } }
void DocumentWidget::mouseMoveEvent ( QMouseEvent * e ) { #ifdef DEBUG_DOCUMENTWIDGET kdDebug(1223) << "DocumentWidget::mouseMoveEvent(...) called" << endl; #endif // pageNr == 0 indicated an invalid page (e.g. page number not yet // set) if (pageNr == 0) return; // Get a pointer to the page contents RenderedDocumentPage *pageData = documentCache->getPage(pageNr); if (pageData == 0) { kdDebug(1223) << "DocumentWidget::selectAll() pageData for page #" << pageNr << " is empty" << endl; return; } // If no mouse button pressed if (e->state() == 0) { // Remember the index of the underlined link. int lastUnderlinedLink = indexOfUnderlinedLink; // go through hyperlinks for(unsigned int i = 0; i < pageData->hyperLinkList.size(); i++) { if (pageData->hyperLinkList[i].box.contains(e->pos())) { clearStatusBarTimer.stop(); setCursor(pointingHandCursor); QString link = pageData->hyperLinkList[i].linkText; if ( link.startsWith("#") ) link = link.remove(0,1); emit setStatusBarText( i18n("Link to %1").arg(link) ); indexOfUnderlinedLink = i; if (KVSPrefs::underlineLinks() == KVSPrefs::EnumUnderlineLinks::OnlyOnHover && indexOfUnderlinedLink != lastUnderlinedLink) { QRect newUnderline = pageData->hyperLinkList[i].box; // Increase Rectangle so that the whole line really lines in it. newUnderline.addCoords(0, 0, 0, 2); // Redraw widget update(newUnderline); if (lastUnderlinedLink != -1 && lastUnderlinedLink < pageData->hyperLinkList.size()) { // Erase old underline QRect oldUnderline = pageData->hyperLinkList[lastUnderlinedLink].box; oldUnderline.addCoords(0, 0, 0, 2); update(oldUnderline); } } return; } } // Whenever we reach this the mouse hovers no link. indexOfUnderlinedLink = -1; if (KVSPrefs::underlineLinks() == KVSPrefs::EnumUnderlineLinks::OnlyOnHover && lastUnderlinedLink != -1 && lastUnderlinedLink < pageData->hyperLinkList.size()) { // Erase old underline QRect oldUnderline = pageData->hyperLinkList[lastUnderlinedLink].box; // Increase Rectangle so that the whole line really lines in it. oldUnderline.addCoords(0, 0, 0, 2); // Redraw widget update(oldUnderline); } // Cursor not over hyperlink? Then let the cursor be the usual arrow if we use the move tool, and // The textselection cursor if we use the selection tool. setStandardCursor(); } if (!clearStatusBarTimer.isActive()) clearStatusBarTimer.start(200, true); // clear the statusbar after 200 msec. // Left mouse button pressed -> Text scroll function if ((e->state() & LeftButton) != 0 && moveTool) { // Pass the mouse event on to the owner of this widget ---under // normal circumstances that is the centeringScrollView which will // then scroll the scrollview contents e->ignore(); } // Right mouse button pressed -> Text copy function if ((e->state() & RightButton) != 0 || (!moveTool && (e->state() & LeftButton != 0))) { if (selectedRectangle.isEmpty()) { firstSelectedPoint = e->pos(); selectedRectangle.setRect(e->pos().x(),e->pos().y(),1,1); } else { int lx = e->pos().x() < firstSelectedPoint.x() ? e->pos().x() : firstSelectedPoint.x(); int rx = e->pos().x() > firstSelectedPoint.x() ? e->pos().x() : firstSelectedPoint.x(); int ty = e->pos().y() < firstSelectedPoint.y() ? e->pos().y() : firstSelectedPoint.y(); int by = e->pos().y() > firstSelectedPoint.y() ? e->pos().y() : firstSelectedPoint.y(); selectedRectangle.setCoords(lx,ty,rx,by); } // Now that we know the rectangle, we have to find out which words // intersect it! TextSelection newTextSelection = pageData->select(selectedRectangle); updateSelection(newTextSelection); } }
void DocumentWidget::paintEvent(QPaintEvent *e) { #ifdef DEBUG_DOCUMENTWIDGET kdDebug(1223) << "DocumentWidget::paintEvent() called" << endl; #endif // Check if this widget is really visible to the user. If not, there // is nothing to do. Remark: if we don't do this, then under QT // 3.2.3 the following happens: when the user changes the zoom // value, all those widgets are updated which the user has EVER // seen, not just those that are visible at the moment. If the // document contains several thousand pages, it is easily possible // that this means that a few hundred of these are re-painted (which // takes substantial time) although perhaps only three widgets are // visible and *should* be updated. I believe this is some error in // QT, but I am not positive about that ---Stefan Kebekus. if (!isVisible()) { //kdDebug() << "widget of page " << pageNr << " is not visible. Abort rendering" << endl; kapp->processEvents(); return; } QPainter p(this); p.setClipRegion(e->region()); // Paint a black border around the widget p.setRasterOp(Qt::CopyROP); p.setBrush(NoBrush); p.setPen(Qt::black); QRect outlineRect = pageRect(); outlineRect.addCoords(-1, -1, 1, 1); p.drawRect(outlineRect); // Paint page shadow QColor backgroundColor = colorGroup().mid(); // (Re-)generate the Pixmaps for the shadow corners, if necessary if (backgroundColor != backgroundColorForCorners) { backgroundColorForCorners = backgroundColor; QImage tmp(4, 4, 32); for(int x=0; x<4; x++) for(int y=0; y<4; y++) tmp.setPixel(x, y, backgroundColor.light(bottom_right_corner[x+4*y]).rgb() ); BRShadow->convertFromImage(tmp); for(int x=0; x<4; x++) for(int y=0; y<4; y++) tmp.setPixel(x, y, backgroundColor.light(bottom_left_corner[x+4*y]).rgb() ); BLShadow->convertFromImage(tmp); URShadow->convertFromImage(tmp.mirror(true, true)); } // Draw right and bottom shadows for(int i=0; i<4; i++) { p.setPen(backgroundColor.light(shadow_strip[i])); // Right shadow p.drawLine(pageSize().width()+i+2, 8, pageSize().width()+i+2, pageSize().height()+2); // Bottom shadow p.drawLine(8, pageSize().height()+i+2, pageSize().width()+2, pageSize().height()+i+2); } // Draw shadow corners p.drawPixmap(pageSize().width()+2, pageSize().height()+2, *BRShadow); p.drawPixmap(4, pageSize().height()+2, *BLShadow); p.drawPixmap(pageSize().width()+2, 4, *URShadow); // Draw corners p.fillRect(0, pageSize().height()+2, 4, 4, backgroundColor); p.fillRect(pageSize().width()+2, 0, 4, 4, backgroundColor); if (!documentCache->isPageCached(pageNr, pageSize())) { QRect destRect = e->rect().intersect(pageRect()); if (KVSPrefs::changeColors() && KVSPrefs::renderMode() == KVSPrefs::EnumRenderMode::Paper) p.fillRect(destRect, KVSPrefs::paperColor()); else p.fillRect(destRect, Qt::white); // Draw busy indicator. // Im not really sure if this is a good idea. // While it is nice to see an indication that something is happening for pages which // take long to redraw, it gets quite annoing for fast redraws. // TODO: Disable or find something less distractiong. p.drawPixmap(10, 10, *busyIcon); if (!pixmapRequested) { // Request page pixmap. pixmapRequested = true; QTimer::singleShot(50, this, SLOT(delayedRequestPage())); } return; } RenderedDocumentPagePixmap *pageData = documentCache->getPage(pageNr); if (pageData == 0) { #ifdef DEBUG_DOCUMENTWIDGET kdDebug(1223) << "DocumentWidget::paintEvent: no documentPage generated" << endl; #endif return; } QMemArray<QRect> damagedRects = e->region().rects(); for (unsigned int i = 0; i < damagedRects.count(); i++) { // Paint the page where it intersects with the damaged area. QRect destRect = damagedRects[i].intersect(pageRect()); // The actual page starts at point (1,1) because of the outline. // Therefore we need to shift the destination rectangle. QRect pixmapRect = destRect; pixmapRect.moveBy(-1,-1); if (KVSPrefs::changeColors() && KVSPrefs::renderMode() != KVSPrefs::EnumRenderMode::Paper) { // Paint widget contents with accessibility changes. QPixmap pdpix = pageData->accessiblePixmap(); bitBlt ( this, destRect.topLeft(), &pdpix, pixmapRect, CopyROP); } else { // Paint widget contents bitBlt ( this, destRect.topLeft(), pageData, pixmapRect, CopyROP); } } // Underline hyperlinks if (KVSPrefs::underlineLinks() == KVSPrefs::EnumUnderlineLinks::Enabled || KVSPrefs::underlineLinks() == KVSPrefs::EnumUnderlineLinks::OnlyOnHover) { int h = 2; // Height of line. for(int i = 0; i < (int)pageData->hyperLinkList.size(); i++) { if (KVSPrefs::underlineLinks() == KVSPrefs::EnumUnderlineLinks::OnlyOnHover && i != indexOfUnderlinedLink) continue; int x = pageData->hyperLinkList[i].box.left(); int w = pageData->hyperLinkList[i].box.width(); int y = pageData->hyperLinkList[i].baseline; QRect hyperLinkRect(x, y, w, h); if (hyperLinkRect.intersects(e->rect())) { #ifdef DEBUG_DOCUMENTWIDGET kdDebug(1223) << "Underline hyperlink \"" << pageData->hyperLinkList[i].linkText << "\"" << endl; #endif p.fillRect(x, y, w, h, KGlobalSettings::linkColor()); } } } // Paint flashing frame, if appropriate if (animationCounter > 0 && animationCounter < 10) { int gbChannel = 255 - (9-animationCounter)*28; p.setPen(QPen(QColor(255, gbChannel, gbChannel), 3)); p.drawRect(linkFlashRect()); } // Mark selected text. TextSelection selection = documentCache->selectedText(); if ((selection.getPageNumber() != 0) && (selection.getPageNumber() == pageNr)) { if (selectionNeedsUpdating) { //The zoom value has changed, therefore we need to recalculate //the selected region. selectedRegion = pageData->selectedRegion(selection); selectionNeedsUpdating = false; } p.setPen(NoPen); p.setBrush(white); p.setRasterOp(Qt::XorROP); QMemArray<QRect> selectionRects = selectedRegion.rects(); for (unsigned int i = 0; i < selectionRects.count(); i++) p.drawRect(selectionRects[i]); } // Draw scroll Guide if (scrollGuide >= 0) { // Don't draw over the page shadow p.setClipRegion(e->region().intersect(pageRect())); p.setRasterOp(Qt::CopyROP); p.setPen(Qt::red); p.drawLine(1, scrollGuide, pageSize().width(), scrollGuide); } }