[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdegraphics/kviewshell/shell
From: Wilfried Huss <Wilfried.Huss () gmx ! at>
Date: 2006-11-12 16:47:25
Message-ID: 1163350045.266152.22825.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 604368 by whuss:
port of commit 602778:
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 +87 -19 marklist.cpp
M +10 -5 marklist.h
--- trunk/KDE/kdegraphics/kviewshell/shell/kviewpart.cpp #604367:604368
@@ -671,6 +671,8 @@
bool KViewPart::openFile()
{
+ closeUrl();
+
KUrl tmpFileURL;
// We try to be error-tolerant about filenames. If the user calls us
@@ -1899,7 +1901,7 @@
// Update widget sizes immediately
pageView()->resizeWidgets();
}
- markList()->repaintThumbnails();
+ markList()->rebuildThumbnailWidgets();
// return to the privious position in the document
dataModel->setCurrentPageNumber(_currentPage);
@@ -1938,7 +1940,7 @@
// Update widget sizes immediately
pageView()->resizeWidgets();
}
- markList()->repaintThumbnails();
+ markList()->rebuildThumbnailWidgets();
// return to the privious position in the document
dataModel->setCurrentPageNumber(_currentPage);
@@ -1952,7 +1954,7 @@
pageCache->clear();
pageView()->repaintPages();
- markList()->repaintThumbnails();
+ markList()->rebuildThumbnailWidgets();
}
//TODO: split into several functions
--- trunk/KDE/kdegraphics/kviewshell/shell/marklist.cpp #604367:604368
@@ -44,6 +44,10 @@
#include "marklist.moc"
+// Maximal number of MarkListWidgets we keep in the cache,
+// to reuse for future use.
+#define WIDGET_CACHE_SIZE 100
+
namespace {
/** Holds the icon used as a overlay on pages which are not drawn yet. */
@@ -465,6 +469,8 @@
MarkList::~MarkList()
{
+ clear();
+
delete testWidget;
delete contextMenu;
}
@@ -493,6 +499,9 @@
void MarkList::slotCreateWidgets(int x, int y)
{
+ if (!isVisible())
+ return;
+
Q_UNUSED(x);
unsigned int ytop = y;
@@ -531,10 +540,39 @@
{
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)
+ {
+ item->setSelected(false);
+ item->setChecked(false);
+ 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);
@@ -593,9 +631,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))); @@ -636,11 +687,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.
@@ -743,15 +799,11 @@
}
-void MarkList::setNumberOfPages()
+void MarkList::clear()
{
- clear();
- rebuildThumbnailWidgets();
-}
+ resizeContents(0, 0);
+ setContentsPos(0, 0);
-
-void MarkList::clear()
-{
currentPage = PageNumber::invalidPage;
widgetPositionList.clear();
@@ -763,6 +815,12 @@
widgetMap.remove(pages[i]);
delete item;
}
+
+ for (unsigned int i = 0; i < widgetCache.count(); i++)
+ {
+ delete widgetCache[i];
+ }
+ widgetCache.clear();
}
@@ -900,6 +958,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)
@@ -910,20 +986,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)
@@ -1091,7 +1159,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()));
/*
QList<PageNumber> keys = dataModel->bookmarks();
--- trunk/KDE/kdegraphics/kviewshell/shell/marklist.h #604367:604368
@@ -55,11 +55,11 @@
void setPageNumber(const PageNumber&);
+ int thumbnailWidth();
+
private:
virtual void paintEvent(QPaintEvent*);
- int thumbnailWidth();
-
private:
PageNumber pageNumber;
@@ -91,6 +91,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(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.
+ QVector<MarkListWidget*> widgetCache;
+
QVector<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