[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: branches/work/kviewshell-0.7/kviewshell/shell
From: Wilfried Huss <Wilfried.Huss () gmx ! at>
Date: 2006-11-06 20:00:23
Message-ID: 1162843223.221000.19024.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 602778 by whuss:
Fix regressions caused by my last commit.
Add a widget cache that holds MarkListWidgets that are currently not in use,
to minimize Widget creation and destruction. This gives a significant performance
boost during scrolling.
Also enable prerendering of thumbnail widgets. In most cases the widgets
should now be already calculated when the widget comes into view.
Some cleanups.
M +5 -3 kviewpart.cpp
M +84 -18 marklist.cpp
M +10 -5 marklist.h
--- branches/work/kviewshell-0.7/kviewshell/shell/kviewpart.cpp #602777:602778
@@ -604,6 +604,8 @@
bool KViewPart::openFile()
{
+ closeURL();
+
KURL tmpFileURL;
// We try to be error-tolerant about filenames. If the user calls us
@@ -1814,7 +1816,7 @@
// Update widget sizes immediately
pageView()->resizeWidgets();
}
- markList()->repaintThumbnails();
+ markList()->rebuildThumbnailWidgets();
// return to the privious position in the document
dataModel->setCurrentPageNumber(_currentPage);
@@ -1853,7 +1855,7 @@
// Update widget sizes immediately
pageView()->resizeWidgets();
}
- markList()->repaintThumbnails();
+ markList()->rebuildThumbnailWidgets();
// return to the privious position in the document
dataModel->setCurrentPageNumber(_currentPage);
@@ -1867,7 +1869,7 @@
pageCache->clear();
pageView()->repaintPages();
- markList()->repaintThumbnails();
+ markList()->rebuildThumbnailWidgets();
}
//TODO: split into several functions
--- branches/work/kviewshell-0.7/kviewshell/shell/marklist.cpp #602777:602778
@@ -44,6 +44,9 @@
#include "marklist.moc"
+// Maximal number of MarkListWidgets we keep in the cache,
+// to reuse for future use.
+#define WIDGET_CACHE_SIZE 100
namespace {
@@ -448,6 +451,8 @@
MarkList::~MarkList()
{
+ clear();
+
delete testWidget;
delete contextMenu;
}
@@ -475,6 +480,9 @@
void MarkList::slotCreateWidgets(int x, int y)
{
+ if (!isVisible())
+ return;
+
Q_UNUSED(x);
unsigned int ytop = y;
@@ -513,10 +521,37 @@
{
MarkListWidget* item = widgetMap[pages[i]];
widgetMap.remove(pages[i]);
- delete item;
+
+ // Since deleteing QWidgets is an expensive operation, we only do
+ // it if we already have enough in the widget cache.
+ if (widgetCache.size() <= WIDGET_CACHE_SIZE)
+ {
+ widgetCache.push_back(item);
+ item->disconnect();
+ }
+ else
+ {
+ delete item;
+ }
}
}
+ // Prerender the pages right before and after the visible ones.
+ if (dataModel->preferences()->showThumbnails())
+ {
+ //TODO: find a less ugly way to do this.
+ if (startIndex - 1 > 0)
+ {
+ testWidget->setPageNumber(startIndex - 1);
+ pageCache->getThumbnail(startIndex - 1, testWidget->thumbnailWidth());
+ }
+ if (stopIndex + 1 <= dataModel->numberOfPages())
+ {
+ testWidget->setPageNumber(stopIndex + 1);
+ pageCache->getThumbnail(stopIndex + 1, testWidget->thumbnailWidth());
+ }
+ }
+
for (int i = startIndex; i <= stopIndex; i++)
{
QWidget* widget = createWidget(i);
@@ -575,9 +610,22 @@
return widgetMap[pageNumber];
}
- MarkListWidget* item = new MarkListWidget(viewport(), this, pageNumber, pageCache, \
dataModel->preferences()->showThumbnails());
- item->setupObservers(dataModel);
+ MarkListWidget* item;
+ // If we have a widget in the widget cache use it,
+ // otherwise we really need to create a new MarkListWidget
+ if (!widgetCache.isEmpty())
+ {
+ item = widgetCache.back();
+ item->setPageNumber(pageNumber);
+ widgetCache.pop_back();
+ }
+ else
+ {
+ item = new MarkListWidget(viewport(), this, pageNumber, pageCache, \
dataModel->preferences()->showThumbnails()); + item->setupObservers(dataModel);
+ }
+
connect(item, SIGNAL(selected(const PageNumber&)), this, \
SLOT(thumbnailSelected(const PageNumber&))); connect(item, \
SIGNAL(showPopupMenu(const PageNumber&, const QPoint&)), this, \
SLOT(showPopupMenu(const PageNumber&, const QPoint&))); connect(item, \
SIGNAL(selectionToggled(const PageNumber&, bool)), this, SLOT(selectionToggled(const \
PageNumber&, bool))); @@ -618,11 +666,16 @@
}
resizeContents(visibleWidth(), y);
+
+ if (contentsY() > y)
+ setContentsPos(0, 0);
}
void MarkList::rebuildThumbnailWidgets()
{
+ clear();
+
// We need to recreate the testWidget everytime, because
// we currently cannot enable/disable the the ThumbnailWidget
// for an already created MarkListWidget.
@@ -725,14 +778,11 @@
}
-void MarkList::setNumberOfPages()
+void MarkList::clear()
{
- clear();
- rebuildThumbnailWidgets();
-}
+ resizeContents(0, 0);
+ setContentsPos(0, 0);
-void MarkList::clear()
-{
currentPage = PageNumber::invalidPage;
widgetPositionList.clear();
@@ -744,6 +794,12 @@
widgetMap.remove(pages[i]);
delete item;
}
+
+ for (unsigned int i = 0; i < widgetCache.count(); i++)
+ {
+ delete widgetCache[i];
+ }
+ widgetCache.clear();
}
@@ -882,6 +938,24 @@
}
+void MarkList::showEvent(QShowEvent*)
+{
+ slotCreateWidgets();
+
+ // We need to realign the widgets, as their positions
+ // might have been messed up while the thumbnaillist was
+ // invisible.
+ QMap<PageNumber, MarkListWidget*>::Iterator it;
+ for (it = widgetMap.begin(); it != widgetMap.end(); ++it)
+ {
+ MarkListWidget* item = *it;
+ item->setNewWidth(visibleWidth());
+ moveChild(item, 0, widgetPositionList[item->getPageNumber() - 1]);
+ }
+
+ viewport()->update();
+}
+
void MarkList::slotShowThumbnails()
{
if (dataModel->numberOfPages() == 0)
@@ -892,20 +966,12 @@
dataModel->preferences()->setSmoothScrolling(false);
// Rebuild thumbnail widgets.
- clear();
rebuildThumbnailWidgets();
dataModel->preferences()->setSmoothScrolling(smooth);
}
-void MarkList::repaintThumbnails()
-{
- // Rebuild thumbnail widgets.
- rebuildThumbnailWidgets();
-}
-
-
void MarkList::showPopupMenu(const PageNumber& pageNumber, const QPoint& position)
{
if (contextMenu == 0)
@@ -1063,7 +1129,7 @@
{
SmoothScrollView::setupObservers(_dataModel);
connect(dataModel, SIGNAL(currentPageNumberChanged()), this, \
SLOT(setCurrentPage()));
- connect(dataModel, SIGNAL(numberOfPagesChanged()), this, \
SLOT(setNumberOfPages())); + connect(dataModel, SIGNAL(numberOfPagesChanged()), \
this, SLOT(rebuildThumbnailWidgets()));
/*
QValueList<PageNumber> keys = dataModel->bookmarks();
--- branches/work/kviewshell-0.7/kviewshell/shell/marklist.h #602777:602778
@@ -57,11 +57,11 @@
void setPageNumber(const PageNumber&);
+ int thumbnailWidth();
+
private:
virtual void paintEvent(QPaintEvent*);
- int thumbnailWidth();
-
private:
PageNumber pageNumber;
@@ -93,6 +93,8 @@
virtual void setupObservers(DataModel*);
+ int thumbnailWidth() { if (thumbnailWidget) return \
thumbnailWidget->thumbnailWidth(); else return 0; } +
public slots:
void toggle();
@@ -176,21 +178,19 @@
void clear();
void slotShowThumbnails();
- void repaintThumbnails();
/** @brief Called whenever the rendering of a thumbnail has been finished. */
void slotSetThumbnail(const PageNumber&);
protected:
virtual void viewportResizeEvent(QResizeEvent*);
-
+ virtual void showEvent(QShowEvent*);
virtual void mousePressEvent(QMouseEvent*);
virtual bool isSmoothScrollDistance(double scrollDistance);
private slots:
void setCurrentPage();
- void setNumberOfPages();
void selectionToggled(const PageNumber& page, bool on);
@@ -274,6 +274,11 @@
// for a given size. It is hidden. TODO: find a better way to do this.
MarkListWidget* testWidget;
+ // The widgets in this list are currently not in use.
+ // Because creating and deleting MarkListWidgets is slow
+ // we use this to hold widgets that are temporarely not needed.
+ QValueVector<MarkListWidget*> widgetCache;
+
QValueVector<unsigned int> widgetPositionList;
QMap<PageNumber, MarkListWidget*> widgetMap;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic