kviewshell
pageView.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023
00024 #include <kdebug.h>
00025 #include <qcursor.h>
00026 #include <qpainter.h>
00027 #include <qrect.h>
00028 #include <math.h>
00029
00030 #include "pageView.h"
00031 #include "pageNumber.h"
00032
00033 PageView::PageView( QWidget* parent, const char* name )
00034 : QScrollView( parent, name, WStaticContents | WNoAutoErase)
00035 {
00036 moveTool = true;
00037
00038 widgetList = 0;
00039 viewport()->setFocusPolicy(QWidget::StrongFocus);
00040
00041 setResizePolicy(QScrollView::Manual);
00042
00043 setVScrollBarMode(QScrollView::Auto);
00044 setHScrollBarMode(QScrollView::Auto);
00045
00046 viewport()->setBackgroundMode(Qt::NoBackground);
00047
00048 setResizePolicy(Manual);
00049 setDragAutoScroll(false);
00050
00051 enableClipper(true);
00052 nrCols = 1;
00053 nrRows = 1;
00054 continuousViewmode = true;
00055 fullScreen = false;
00056
00057 connect(this, SIGNAL(contentsMoving(int, int)), this, SLOT(calculateCurrentPageNumber(int, int)));
00058 }
00059
00060
00061 void PageView::addChild( QPtrVector<DocumentWidget> *wdgList )
00062 {
00063 if( wdgList == 0 ) {
00064 kdError(1223) << "PageView::addChild(...) called with invalid arguments" << endl;
00065 return;
00066 }
00067
00068 widgetList = wdgList;
00069 layoutPages();
00070 }
00071
00072
00073 bool PageView::atTop() const
00074 {
00075 return verticalScrollBar()->value() == verticalScrollBar()->minValue();
00076 }
00077
00078
00079 bool PageView::atBottom() const
00080 {
00081 return verticalScrollBar()->value() == verticalScrollBar()->maxValue();
00082 }
00083
00084
00085 bool PageView::readUp()
00086 {
00087 if( atTop() )
00088 return false;
00089 else {
00090
00091 int top = contentsY();
00092
00093 DocumentWidget* widget = 0;
00094
00095
00096 for(Q_UINT16 i=0; i<widgetList->size(); i++)
00097 {
00098 widget = widgetList->at(i);
00099 if (childY(widget) < top && childY(widget) + widget->height() > top)
00100 {
00101
00102 widget->drawScrollGuide(top - childY(widget));
00103 }
00104 }
00105
00106 int newValue = QMAX( verticalScrollBar()->value() - (int)(height() * 0.9),
00107 verticalScrollBar()->minValue() );
00108 verticalScrollBar()->setValue( newValue );
00109 return true;
00110 }
00111 }
00112
00113
00114 bool PageView::readDown()
00115 {
00116 if( atBottom() )
00117 return false;
00118 else {
00119
00120 int bottom = contentsY() + visibleHeight();
00121
00122 DocumentWidget* widget = 0;
00123
00124
00125 for(Q_UINT16 i=0; i<widgetList->size(); i++)
00126 {
00127 widget = widgetList->at(i);
00128 if (childY(widget) < bottom && childY(widget) + widget->height() > bottom)
00129 {
00130
00131 widget->drawScrollGuide(bottom - childY(widget));
00132 }
00133 }
00134
00135 int newValue = QMIN( verticalScrollBar()->value() + (int)(height() * 0.9),
00136 verticalScrollBar()->maxValue() );
00137 verticalScrollBar()->setValue( newValue );
00138
00139 return true;
00140 }
00141 }
00142
00143
00144 void PageView::scrollRight()
00145 {
00146 horizontalScrollBar()->addLine();
00147 }
00148
00149 void PageView::scrollLeft()
00150 {
00151 horizontalScrollBar()->subtractLine();
00152 }
00153
00154 void PageView::scrollDown()
00155 {
00156 verticalScrollBar()->addLine();
00157 }
00158
00159 void PageView::scrollUp()
00160 {
00161 verticalScrollBar()->subtractLine();
00162 }
00163
00164 void PageView::scrollBottom()
00165 {
00166 verticalScrollBar()->setValue( verticalScrollBar()->maxValue() );
00167 }
00168
00169 void PageView::scrollTop()
00170 {
00171 verticalScrollBar()->setValue( verticalScrollBar()->minValue() );
00172 }
00173
00174 void PageView::keyPressEvent( QKeyEvent* e )
00175 {
00176 switch ( e->key() ) {
00177 case Key_Up:
00178 scrollUp();
00179 break;
00180 case Key_Down:
00181 scrollDown();
00182 break;
00183 case Key_Left:
00184 scrollLeft();
00185 break;
00186 case Key_Right:
00187 scrollRight();
00188 break;
00189 default:
00190 e->ignore();
00191 return;
00192 }
00193 e->accept();
00194 }
00195
00196 void PageView::contentsMousePressEvent( QMouseEvent* e )
00197 {
00198 if (e->button() == LeftButton)
00199 {
00200 if (moveTool)
00201 {
00202 setCursor(Qt::SizeAllCursor);
00203 dragGrabPos = e->globalPos();
00204 }
00205 else
00206 {
00207
00208 }
00209 }
00210 else
00211 {
00212 setCursor(Qt::arrowCursor);
00213 }
00214 }
00215
00216 void PageView::contentsMouseReleaseEvent( QMouseEvent* )
00217 {
00218 setCursor(Qt::arrowCursor);
00219 }
00220
00221 void PageView::contentsMouseMoveEvent( QMouseEvent* e )
00222 {
00223 QPoint newPos = e->globalPos();
00224
00225 if (e->state() == LeftButton && moveTool)
00226 {
00227 QPoint delta = dragGrabPos - newPos;
00228 scrollBy(delta.x(), delta.y());
00229 }
00230 dragGrabPos = newPos;
00231 }
00232
00233 void PageView::viewportResizeEvent( QResizeEvent* e )
00234 {
00235 QScrollView::viewportResizeEvent( e );
00236
00237 if (!widgetList)
00238 return;
00239
00240 layoutPages();
00241
00242 emit viewSizeChanged( viewport()->size() );
00243 }
00244
00245 void PageView::setNrColumns( Q_UINT8 cols )
00246 {
00247 nrCols = cols;
00248 }
00249
00250 void PageView::setNrRows( Q_UINT8 rows )
00251 {
00252 nrRows = rows;
00253 }
00254
00255 void PageView::setContinuousViewMode(bool continuous)
00256 {
00257 continuousViewmode = continuous;
00258 }
00259
00260 bool PageView::singlePageFullScreenMode()
00261 {
00262 return (nrCols == 1 && nrRows == 1 && !continuousViewmode && fullScreen);
00263 }
00264
00265 void PageView::slotShowScrollbars(bool status)
00266 {
00267 if (status == true) {
00268 setVScrollBarMode(QScrollView::Auto);
00269 setHScrollBarMode(QScrollView::Auto);
00270 } else {
00271 setVScrollBarMode(QScrollView::AlwaysOff);
00272 setHScrollBarMode(QScrollView::AlwaysOff);
00273 }
00274 }
00275
00276 void PageView::setFullScreenMode(bool fullScreen)
00277 {
00278 this -> fullScreen = fullScreen;
00279 if (fullScreen == true)
00280 {
00281 setVScrollBarMode(QScrollView::AlwaysOff);
00282 setHScrollBarMode(QScrollView::AlwaysOff);
00283 oldFrameStyle = frameStyle();
00284 setFrameStyle(QFrame::NoFrame);
00285 backgroundColor = viewport()->paletteBackgroundColor();
00286 if (singlePageFullScreenMode())
00287 {
00288 viewport()->setPaletteBackgroundColor( Qt::black ) ;
00289 }
00290 }
00291 else
00292 {
00293 viewport()->setPaletteBackgroundColor( backgroundColor ) ;
00294 setFrameStyle(oldFrameStyle);
00295 }
00296 }
00297
00298 void PageView::layoutPages(bool zoomChanged)
00299 {
00300
00301 if (widgetList == 0)
00302 return;
00303
00304
00305
00306
00307
00308 if (widgetList->isEmpty()) {
00309 if ((contentsWidth() != 0) || (contentsHeight() != 0)) {
00310 QScrollView::resizeContents(0,0);
00311 }
00312 return;
00313 }
00314
00315
00316
00317 int distance = distanceBetweenWidgets;
00318 if (singlePageFullScreenMode())
00319 {
00320
00321 distance = 0;
00322 }
00323
00324 QMemArray<Q_UINT32> colWidth(nrCols);
00325 for(Q_UINT8 i=0; i<colWidth.size(); i++)
00326 colWidth[i] = 0;
00327
00328 Q_UINT16 numRows;
00329 if(nrCols <= 2)
00330 {
00331 numRows = (widgetList->size()+2*nrCols-2) / nrCols;
00332 }
00333 else
00334 {
00335 numRows = (Q_INT16)ceil(((double)widgetList->size()) / nrCols);
00336 }
00337
00338 QMemArray<Q_UINT32> rowHeight(numRows);
00339 for(Q_UINT16 i=0; i<rowHeight.size(); i++)
00340 rowHeight[i] = 0;
00341
00342
00343 for(Q_UINT16 i=0; i<widgetList->size(); i++)
00344 {
00345 Q_UINT8 col;
00346 Q_UINT16 row;
00347
00348 if (nrCols == 2) {
00349
00350 col = (i+1+nrCols) % nrCols;
00351 row = (i+1+nrCols) / nrCols - 1;
00352 } else {
00353 col = (i+nrCols) % nrCols;
00354 row = (i+nrCols) / nrCols - 1;
00355 }
00356
00357 colWidth[col] = QMAX(colWidth[col], (Q_UINT32)widgetList->at(i)->pageSize().width());
00358 rowHeight[row] = QMAX(rowHeight[row], (Q_UINT32)widgetList->at(i)->pageSize().height());
00359 }
00360
00361
00362 Q_UINT32 totalHeight = 0;
00363 for(Q_UINT16 i=0; i<rowHeight.size(); i++)
00364 totalHeight += rowHeight[i];
00365
00366 totalHeight += (numRows+1)*distance;
00367 Q_UINT32 totalWidth = 0;
00368 for(Q_UINT8 i=0; i<colWidth.size(); i++)
00369 totalWidth += colWidth[i];
00370
00371 totalWidth += (nrCols+1)*distance;
00372 QSize newViewportSize = viewportSize( totalWidth, totalHeight );
00373 Q_UINT32 centeringLeft = 0;
00374 if( (Q_UINT32)newViewportSize.width() > totalWidth )
00375 centeringLeft = ( newViewportSize.width() - totalWidth )/2;
00376 Q_UINT32 centeringTop = 0;
00377 if( (Q_UINT32)newViewportSize.height() > totalHeight )
00378 centeringTop = ( newViewportSize.height() - totalHeight)/2;
00379
00380
00381 if (((Q_UINT32)contentsWidth() != totalWidth) || ((Q_UINT32)contentsHeight() != totalHeight))
00382 {
00383
00384 QPoint midPoint = QPoint(visibleWidth() / 2 + contentsX(), visibleHeight() / 2 + contentsY());
00385 double midPointRatioX = (double)(midPoint.x()) / contentsWidth();
00386 double midPointRatioY = (double)(midPoint.y()) / contentsHeight();
00387
00388 resizeContents(totalWidth,totalHeight);
00389
00390
00391 if (zoomChanged)
00392 center((int)(contentsWidth() * midPointRatioX), (int)(contentsHeight() * midPointRatioY));
00393 }
00394
00395
00396
00397 QMemArray<Q_UINT32> colLeft(nrCols);
00398 colLeft[0] = distance;
00399 for(Q_UINT8 i=1; i<colLeft.size(); i++)
00400 colLeft[i] = colLeft[i-1]+colWidth[i-1]+distance;
00401
00402 QMemArray<Q_UINT32> rowTop(numRows);
00403 rowTop[0] = distance;
00404 for(Q_UINT16 i=1; i<rowTop.size(); i++)
00405 rowTop[i] = rowTop[i-1]+rowHeight[i-1]+distance;
00406
00407 for(Q_UINT16 i=0; i<widgetList->size(); i++)
00408 {
00409 Q_UINT8 col;
00410 Q_UINT16 row;
00411 if (nrCols == 2)
00412 {
00413
00414 col = (i+nrCols-1) % nrCols;
00415 row = (i+nrCols-1) / nrCols;
00416 }
00417 else
00418 {
00419 col = (i+nrCols) % nrCols;
00420 row = i / nrCols;
00421 }
00422 if (nrCols == 2)
00423 {
00424
00425 int width = widgetList->at(i)->width();
00426 int left;
00427 if (col == 0)
00428 left = centeringLeft + colLeft[col] + colWidth[col]-width + distance/2;
00429 else
00430 left = centeringLeft + colLeft[col];
00431 moveChild( widgetList->at(i), left, centeringTop+rowTop[row]);
00432 }
00433 else
00434 {
00435
00436 int widgetWidth = widgetList->at(i)->width();
00437 int left = centeringLeft + colLeft[col] + ((int)colWidth[col]-widgetWidth)/2;
00438 moveChild(widgetList->at(i), left, centeringTop+rowTop[row]);
00439 }
00440 }
00441 calculateCurrentPageNumber();
00442 }
00443
00444
00445 void PageView::contentsWheelEvent ( QWheelEvent * e )
00446 {
00447 emit(wheelEventReceived(e));
00448 }
00449
00450
00451 void PageView::moveViewportToWidget(QWidget* widget, int y)
00452 {
00453 int verticalPos = 0;
00454 int verticalPosTop = 0;
00455
00456 if (y != 0)
00457 {
00458 verticalPosTop = childY(widget) + y - visibleHeight()/2;
00459 verticalPos = childY(widget) + y;
00460 }
00461 else
00462 {
00463 verticalPos = childY(widget) - distanceBetweenWidgets;
00464 verticalPosTop = verticalPos;
00465 }
00466
00467 if (nrCols == 1)
00468 {
00469
00470
00471
00472 int top = (int)(contentsY() + 0.1 * visibleHeight());
00473 int bottom = (int)(contentsY() + 0.9 * visibleHeight());
00474
00475
00476
00477
00478 if (verticalPos < top || verticalPos > bottom || y == 0)
00479 {
00480 setContentsPos(contentsX(), verticalPosTop);
00481 }
00482 }
00483 else
00484 {
00485 setContentsPos(childX(widget) - distanceBetweenWidgets, verticalPosTop);
00486 }
00487 }
00488
00489
00490 void PageView::viewportPaintEvent(QPaintEvent* e)
00491 {
00492
00493 QRegion backgroundArea(e->rect());
00494
00495 if (widgetList != 0)
00496 {
00497 for (unsigned int i = 0; i < widgetList->count(); i++)
00498 {
00499 DocumentWidget* item = widgetList->at(i);
00500
00501
00502 if (!item->geometry().intersects(e->rect()))
00503 continue;
00504
00505 QRect widgetGeometry = item->geometry();
00506
00507
00508 if (e->rect().intersects(widgetGeometry))
00509 {
00510 QRect widgetRect = e->rect().intersect(widgetGeometry);
00511 widgetRect.moveBy(-widgetGeometry.left(), -widgetGeometry.top());
00512
00513 item->update(widgetRect);
00514 }
00515
00516
00517 backgroundArea -= widgetGeometry.intersect(e->rect());
00518 }
00519 }
00520
00521
00522 QPainter p(viewport());
00523
00524 QMemArray<QRect> backgroundRects = backgroundArea.rects();
00525
00526 for (unsigned int i = 0; i < backgroundRects.count(); i++)
00527 p.fillRect(backgroundRects[i], colorGroup().mid());
00528 }
00529
00530
00531 void PageView::calculateCurrentPageNumber(int x, int y)
00532 {
00533
00534 if (widgetList == 0)
00535 return;
00536
00537 QRect viewportRect(x, y, visibleWidth(), visibleHeight());
00538
00539
00540
00541
00542 int maxVisiblePixels = 0;
00543 DocumentWidget* _currentWidget = 0;
00544
00545 for (Q_UINT16 i = 0; i < widgetList->size(); i++)
00546 {
00547 DocumentWidget* documentWidget = widgetList->at(i);
00548
00549 if (documentWidget == 0)
00550 continue;
00551
00552
00553 int cx = childX(documentWidget);
00554 int cy = childY(documentWidget);
00555 QRect widgetRect(cx, cy, documentWidget->width(), documentWidget->height());
00556 bool isVisible = widgetRect.intersects(viewportRect);
00557
00558 if (!isVisible)
00559 continue;
00560
00561
00562 QRect visibleRect = widgetRect.intersect(viewportRect);
00563 int visiblePixels = visibleRect.width() * visibleRect.height();
00564
00565
00566
00567
00568 if (maxVisiblePixels < visiblePixels)
00569 {
00570 maxVisiblePixels = visiblePixels;
00571 _currentWidget = documentWidget;
00572 }
00573 }
00574
00575
00576 if (_currentWidget == 0)
00577 return;
00578
00579
00580 emit currentPageChanged(_currentWidget->getPageNumber());
00581 }
00582
00583 void PageView::calculateCurrentPageNumber()
00584 {
00585 calculateCurrentPageNumber(contentsX(), contentsY());
00586 }
00587
00588 void PageView::slotEnableMoveTool(bool enable)
00589 {
00590 moveTool = enable;
00591 }
00592
00593 #include "pageView.moc"