Author: JirkaH Date: 2010-02-16 19:01:22 +0100 (Tue, 16 Feb 2010) New Revision: 1744 Modified: branches/client/pdf-presentation-branch/elvys-client/src/Makefile branches/client/pdf-presentation-branch/elvys-client/src/pdfdocument.cpp branches/client/pdf-presentation-branch/elvys-client/src/pdffiller.cpp branches/client/pdf-presentation-branch/elvys-client/src/pdfviewer.cpp branches/client/pdf-presentation-branch/elvys-client/src/pdfviewer.h branches/client/pdf-presentation-branch/elvys-client/src/pdfzoomed.cpp branches/client/pdf-presentation-branch/elvys-client/src/pdfzoomed.h Log: zoomed pdfs are now displayed ok even if more than two of them are displayed + scrolling by pages works ok now. Modified: branches/client/pdf-presentation-branch/elvys-client/src/Makefile =================================================================== --- branches/client/pdf-presentation-branch/elvys-client/src/Makefile 2010-02-16 17:35:39 UTC (rev 1743) +++ branches/client/pdf-presentation-branch/elvys-client/src/Makefile 2010-02-16 18:01:22 UTC (rev 1744) @@ -1,6 +1,6 @@ ############################################################################# # Makefile for building: ../bin/elvys-client -# Generated by qmake (2.01a) (Qt 4.5.3) on: Tue Feb 16 12:42:10 2010 +# Generated by qmake (2.01a) (Qt 4.5.3) on: Tue Feb 16 17:09:36 2010 # Project: src.pro # Template: app # Command: /usr/bin/qmake -spec /usr/share/qt4/mkspecs/linux-g++ -unix CONFIG+=debug_and_release -o Makefile src.pro Modified: branches/client/pdf-presentation-branch/elvys-client/src/pdfdocument.cpp =================================================================== --- branches/client/pdf-presentation-branch/elvys-client/src/pdfdocument.cpp 2010-02-16 17:35:39 UTC (rev 1743) +++ branches/client/pdf-presentation-branch/elvys-client/src/pdfdocument.cpp 2010-02-16 18:01:22 UTC (rev 1744) @@ -47,6 +47,7 @@ connect(pdfZoomed, SIGNAL(getPage(int, QSize, QString)), pdfFiller, SLOT(loadPage(int, QSize, QString))); connect(pdfFiller, SIGNAL(pageLoaded(PageSelector , PDFPage *)), pdfZoomed, SLOT(pageReady(PageSelector , PDFPage *))); connect(pdfFiller, SIGNAL(pageDimension(int,int,int)), pdfZoomed, SLOT(setPageDimension(int, int, int))); + connect(pdfFiller, SIGNAL(pageDimension(int,int,int)), pdfViewer, SLOT(setPageDimension(int, int, int))); // event oriented connects connect(pdfViewer, SIGNAL(zoomEvent()), this, SLOT(zoomEventHandler())); @@ -82,7 +83,8 @@ bool retval; retval = pdfFiller->setPages(pages, mainPage); - pdfZoomed->setPages(pages); + pdfViewer->setPages(pages); + pdfZoomed->setPages(pages); if ( retval) { Modified: branches/client/pdf-presentation-branch/elvys-client/src/pdffiller.cpp =================================================================== --- branches/client/pdf-presentation-branch/elvys-client/src/pdffiller.cpp 2010-02-16 17:35:39 UTC (rev 1743) +++ branches/client/pdf-presentation-branch/elvys-client/src/pdffiller.cpp 2010-02-16 18:01:22 UTC (rev 1744) @@ -40,6 +40,7 @@ /** * Class desctructor. Waits for all threads to die. */ + PDFFiller::~PDFFiller() { quit = true; condition.wakeAll(); Modified: branches/client/pdf-presentation-branch/elvys-client/src/pdfviewer.cpp =================================================================== --- branches/client/pdf-presentation-branch/elvys-client/src/pdfviewer.cpp 2010-02-16 17:35:39 UTC (rev 1743) +++ branches/client/pdf-presentation-branch/elvys-client/src/pdfviewer.cpp 2010-02-16 18:01:22 UTC (rev 1744) @@ -28,10 +28,6 @@ pageKeyBase = "PDFVIEWER"; } -QString PDFViewer::getPageKey(const QSize & size, const QString & identifier) { - return pageKeyBase + identifier + QString::number(size.width()) + KEY_SEPERATOR + QString::number(size.height()); -} - void PDFViewer::getFirstPageBig() { QSize zoomSize(zoomW, zoomH); @@ -54,7 +50,7 @@ //qDebug() << Q_FUNC_INFO << selector.desc << selector.desSize << selector.pageNum; emit imageGenerationStarted(); - myPixmap = QPixmap::fromImage(*page->getImage()); ///< @todo better observe this place, as it fails here + myPixmap = QPixmap::fromImage(*page->getImage()); emit imageGenerationFinished(); emit imageGenerated(selector); @@ -213,23 +209,23 @@ break; case Qt::Key_Left: if ( scaled == 0 ) { - scroll->verticalScrollBar()->setValue(value - scroll->verticalScrollBar()->pageStep() - SEP_HEIGHT); + scrollByOnePage(ElvysNs::Up); } else { scroll->horizontalScrollBar()->triggerAction(QScrollBar::SliderSingleStepSub); } break; case Qt::Key_PageUp: - scroll->verticalScrollBar()->setValue(value - scroll->verticalScrollBar()->pageStep() - SEP_HEIGHT); + scrollByOnePage(ElvysNs::Up); break; case Qt::Key_Right: if ( scaled == 0 ) { - scroll->verticalScrollBar()->setValue(value + scroll->verticalScrollBar()->pageStep() + SEP_HEIGHT); + scrollByOnePage(ElvysNs::Down); } else { scroll->horizontalScrollBar()->triggerAction(QScrollBar::SliderSingleStepAdd); } break; case Qt::Key_PageDown: - scroll->verticalScrollBar()->setValue(value + scroll->verticalScrollBar()->pageStep() + SEP_HEIGHT); + scrollByOnePage(ElvysNs::Down); break; case Qt::Key_Return: zoom(); @@ -244,6 +240,61 @@ } } + +/** Scrolls down in such a way that a next page will be in the top of the zoomed area. It does nothing + if not zoomed. + + @arg direction direction in which scrolling should occur. Only left and right are applicable. + */ + +void PDFViewer::scrollByOnePage(ElvysNs::Direction direction) { + int curY; + int curPage; + + if ( ! zoomed || scroll == NULL) { + return; + } + + curY = scroll->verticalScrollBar()->value(); + curPage = pdfZoomed->whichPage(curY); + + mtx.lock(); + + if ( lengths.size() == curPage + 1 && direction == ElvysNs::Down) { // I am already at the last page + scroll->verticalScrollBar()->setValue(lengths[curPage] - pages[curPage].h); + mtx.unlock(); + return; + } + + if ( curPage == 0 && direction == ElvysNs::Up) { // I am on already at the first page + scroll->verticalScrollBar()->setValue(lengths[curPage] - pages[curPage].h); + mtx.unlock(); + return; + } + + if ( lengths.size() <= curPage ) { + qWarning() << "Cannot properly scroll the zoomed area as I am not aware of page" << curPage << "dimensions. Falling back to default."; + + if (direction == ElvysNs::Up) { + scroll->verticalScrollBar()->triggerAction(QScrollBar::SliderPageStepSub); + } else if ( direction == ElvysNs::Down ) { + scroll->verticalScrollBar()->triggerAction(QScrollBar::SliderPageStepAdd); + } + + mtx.unlock(); + return; + } + + if (direction == ElvysNs::Up) { + scroll->verticalScrollBar()->setValue(lengths[curPage - 1] - pages[curPage - 1].h); + } else if ( direction == ElvysNs::Down) { + + scroll->verticalScrollBar()->setValue(lengths[curPage + 1] - pages[curPage + 1].h); + } + + mtx.unlock(); +} + void PDFViewer::adjustScrollBar(QScrollBar * scrollBar, double factor) { scrollBar->setValue(int(factor * scrollBar->value() + ((factor - 1) * scrollBar->pageStep()/2))); } @@ -359,6 +410,98 @@ } } +/** Sets list of pages to display. + * @param _pageNumbers list of pages + */ + +void PDFViewer::setPages(QList<int> & _pageNumbers) { + bool same = true; + Page page; + + // do we have the same list, so no change is needed? + if (pages.size() < _pageNumbers.size()) { + same = false; + } else { + for (int i = 0; i < _pageNumbers.size(); ++i) { + if ( pages.at(i).num != _pageNumbers[i]) { + same = false; + //qDebug() << "Nestejne cisla stranek"; + break; + } + } + } + + if (same) { + //qDebug() << "Stejne cisla stranek"; + return; + } + + pages.clear(); + + page.h = 0; + page.w = 0; + + for (int i = 0; i < _pageNumbers.size(); ++i) { + page.num = _pageNumbers[i]; + pages.insert(i,page); + } +} + + +/** Updates lenghts array. This function doesnt NOT lock anything, it is up to caller to handle it. + * This function can potentionally fail due to the lack of information (you cannot determine y position of + * end of page no.i if you don't have same information for all pages before). + * @param page number + * @return true if updated successfully, or false if not + */ + +bool PDFViewer::updateLengths(int page) { + while (page >= lengths.size()) { //make sure our array is long enough so we can use [] operator to assign + if (lengths.size() != 0 ) { + lengths.resize(2*lengths.size()); + } else { + lengths.resize(100); + } + } + + if (page < 0 ) { + return false; + } else if ( page == 0) { + lengths[0] = pages[page].h; + return true; + } + + + if (lengths.value(page-1, 0) == 0) { + if ( ! updateLengths(page-1)) { + return false; + } + } else { + lengths[page] = (lengths[page-1] + SEP_HEIGHT + pages[page].h); + return true; + } + return true; +} + + +/** Sets dimension of page. + @param page page number + @param w width of page + @param h height of page + */ + +void PDFViewer::setPageDimension(int page, int w, int h) { + mtx.lock(); + + Q_ASSERT (page < pages.size()); //make sure that we are not out of bounds, ie. pages was set before this call + + pages[page].w = w; + pages[page].h = h; + updateLengths(page); + mtx.unlock(); +} + + void PDFViewer::paintEvent(QPaintEvent * event) { Q_UNUSED(event); Modified: branches/client/pdf-presentation-branch/elvys-client/src/pdfviewer.h =================================================================== --- branches/client/pdf-presentation-branch/elvys-client/src/pdfviewer.h 2010-02-16 17:35:39 UTC (rev 1743) +++ branches/client/pdf-presentation-branch/elvys-client/src/pdfviewer.h 2010-02-16 18:01:22 UTC (rev 1744) @@ -14,6 +14,10 @@ #define SMALL_PAGE_IDENTIFIER "smallPAGE" #define BIG_PAGE_IDENTIFIER "bigPAGE" +namespace ElvysNs { + enum Direction{ Left, Right, Up, Down}; +} + /** Trida zodpovedna za spravne zobrazeni pdfdokumentu..... */ @@ -25,10 +29,12 @@ public slots: virtual void pageReady(PageSelector selector, PDFPage * page); + void setPageDimension(int page, int w, int h); public: PDFViewer(QWidget * parent, const QRect & rect); //inicializuju dedene promene void setPDFZoomed(PDFZoomed * _pdfZoomed); + void setPages(QList <int> & _pageNumbers); virtual ~PDFViewer(); protected: @@ -40,15 +46,16 @@ virtual void focusOutEvent ( QFocusEvent * event ); private: + bool updateLengths(int page); virtual void stopFadeEffect(); void getFirstPageBig(); void getFirstPageSmall(); - QRect getScrollGeometry(); - virtual QString getPageKey(const QSize & size, const QString & identifier = ""); + QRect getScrollGeometry(); virtual void zoom(); virtual void unzoom(); virtual void showPDF(); void adjustScrollBar(QScrollBar * scrollBar, double factor); + void scrollByOnePage(ElvysNs::Direction); int pageW; //velikost prvni zvetsene stranky int pageH; @@ -60,6 +67,9 @@ QPixmap pixmapOpac; QScrollArea * scroll; QPixmap myPixmap; + QMutex mtx; + QVector<Page> pages; + QVector<int> lengths; ///< vector of y-point of page's ends }; #endif Modified: branches/client/pdf-presentation-branch/elvys-client/src/pdfzoomed.cpp =================================================================== --- branches/client/pdf-presentation-branch/elvys-client/src/pdfzoomed.cpp 2010-02-16 17:35:39 UTC (rev 1743) +++ branches/client/pdf-presentation-branch/elvys-client/src/pdfzoomed.cpp 2010-02-16 18:01:22 UTC (rev 1744) @@ -70,7 +70,7 @@ this->setGeometry(0,0, width, height); } -/** Computes which ould lay at point y. +/** Computes which page lay at point y. * * @param y point at which page should lay * @return page number or zero if conversion fails @@ -169,15 +169,6 @@ return geometry().size(); } -/** Handles resize event of the widget - @param event class containing event description - */ - -void PDFZoomed::resizeEvent(QResizeEvent * event) { - //pageKeyBase.append(geometry().width()); -} - - /** Paints zoomed area. This function is reimplementation of QWidget's paintEvent. It paints already rendered pages and emit signals in * advance, when page image is not available (pre-rendering). While the page is not ready, it displays transparent rect instead. * @param event Event structure containg rect to display. @@ -186,7 +177,7 @@ void PDFZoomed::paintEvent(QPaintEvent * event) { QPainter painter; QPixmap pixmap; - int x, y; + int x, y, eventHeight; QRect rect; int pageTop, pageBottom; @@ -194,17 +185,20 @@ QRect eventRect = event->rect(); y = eventRect.y(); x = eventRect.x(); + eventHeight = eventRect.height(); + painter.begin(this); pageTop = whichPage(y); - pageBottom = whichPage(y + eventRect.height()); + pageBottom = whichPage(y + eventHeight); for (int i = 0; i < pages.size(); ++i) { - if ( i != pageTop && i != pageBottom ) { + if ( i < pageTop || i > pageBottom ) { continue; } + mtx.lock(); // we have to protect lenghts and pages... rect = getPageRect(i); Modified: branches/client/pdf-presentation-branch/elvys-client/src/pdfzoomed.h =================================================================== --- branches/client/pdf-presentation-branch/elvys-client/src/pdfzoomed.h 2010-02-16 17:35:39 UTC (rev 1743) +++ branches/client/pdf-presentation-branch/elvys-client/src/pdfzoomed.h 2010-02-16 18:01:22 UTC (rev 1744) @@ -26,25 +26,28 @@ void setPageDimension(int page, int w, int h); void scale(double scaleFactor); // void clearPages(); + signals: void getPage(int pageNum, QSize size, QString desc); + public: PDFZoomed(); ~PDFZoomed(); void setKeyBase(QString & _key); void setPages(QList <int> & _pageNumbers); - protected: + int whichPage(int y); + + protected: void paintEvent(QPaintEvent * event); - void resizeEvent(QResizeEvent * event); + private: QString getPageKey(int pageNumber, const QSize & size, const QString & identifier = ""); QSize getPageBoundingRect(); QRect getPageRect(int page); - bool updateLengths(int page); - int whichPage(int y); + bool updateLengths(int page); QVector<Page> pages; - QVector<int> lengths; ///< vector of y-point of page's ends + QVector<int> lengths; ///< vector of y-point of pages' ends QMutex mtx; QString keyBase; int scaleI;