[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: koffice/krita/ui
From: Cyrille Berger <cyb () lepi ! org>
Date: 2010-11-11 23:02:30
Message-ID: 20101111230230.4B10EAC89E () svn ! kde ! org
[Download RAW message or body]
SVN commit 1195758 by berger:
Compute preview of filters in threads. This fix UI blocking issues.
BUG: 243691
M +41 -3 kis_bookmarked_filter_configurations_model.cc
M +3 -0 kis_bookmarked_filter_configurations_model.h
M +39 -9 kis_filters_model.cc
M +3 -0 kis_filters_model.h
--- trunk/koffice/krita/ui/kis_bookmarked_filter_configurations_model.cc \
#1195757:1195758 @@ -17,7 +17,11 @@
*/
#include "kis_bookmarked_filter_configurations_model.h"
+
+#include <QFutureWatcher>
#include <QPixmap>
+#include <QSignalMapper>
+#include <QtConcurrentRun>
#include <filter/kis_filter.h>
#include <filter/kis_filter_configuration.h>
@@ -27,6 +31,8 @@
KisPaintDeviceSP thumb;
KisFilterSP filter;
QHash<int, QImage> previewCache;
+ QSignalMapper* previewCacheWatcher;
+ QHash<int, QFutureWatcher<QImage>*> previewCacheFutureWatcher;
};
KisBookmarkedFilterConfigurationsModel::KisBookmarkedFilterConfigurationsModel(KisPaintDeviceSP \
thumb, KisFilterSP filter) @@ -34,23 +40,45 @@
{
d->thumb = thumb;
d->filter = filter;
+ d->previewCacheWatcher = new QSignalMapper(this);
+ connect(d->previewCacheWatcher, SIGNAL(mapped(int)), SLOT(previewUpdated(int)));
}
KisBookmarkedFilterConfigurationsModel::~KisBookmarkedFilterConfigurationsModel()
{
+ foreach(QFutureWatcher<QImage>* watcher, d->previewCacheFutureWatcher)
+ {
+ watcher->cancel();
+ delete watcher;
+ }
delete d;
}
+QImage generatePreview(const KisFilter* filter, KisPaintDeviceSP thumb, \
KisFilterConfiguration* config) +{
+ KisPaintDeviceSP target = new KisPaintDevice(*thumb);
+ filter->process(target, QRect(0, 0, 100, 100), config);
+ return target->convertToQImage(0);
+}
+
QVariant KisBookmarkedFilterConfigurationsModel::data(const QModelIndex &index, int \
role) const {
if (!index.isValid()) {
return QVariant();
}
if (role == Qt::DecorationRole) {
+ if (!flags(index).testFlag(Qt::ItemIsEnabled)) return QVariant();
if (!d->previewCache.contains(index.row())) {
- KisPaintDeviceSP target = new KisPaintDevice(*d->thumb);
- d->filter->process(target, QRect(0, 0, 100, 100), configuration(index));
- d->previewCache[index.row()] = target->convertToQImage(0);
+
+ QFutureWatcher<QImage>* watcher = new QFutureWatcher<QImage>();
+ connect(watcher, SIGNAL(finished()), d->previewCacheWatcher, \
SLOT(map())); + watcher->setFuture(QtConcurrent::run(generatePreview, \
d->filter, d->thumb, configuration(index))); +
+ d->previewCacheWatcher->setMapping(watcher, index.row());
+
+ d->previewCacheFutureWatcher[index.row()] = watcher;
+
+ d->previewCache[index.row()] = QImage();
}
return d->previewCache[index.row()];
} else {
@@ -64,3 +92,13 @@
if (config) return config;
return d->filter->defaultConfiguration(d->thumb);
}
+
+void KisBookmarkedFilterConfigurationsModel::previewUpdated(int i)
+{
+ d->previewCache[i] = d->previewCacheFutureWatcher[i]->result();
+ delete d->previewCacheFutureWatcher[i];
+ d->previewCacheFutureWatcher.remove(i);
+ emit dataChanged(createIndex(i,0), createIndex(i,0));
+}
+
+#include "kis_bookmarked_filter_configurations_model.moc"
--- trunk/koffice/krita/ui/kis_bookmarked_filter_configurations_model.h \
#1195757:1195758 @@ -30,6 +30,7 @@
*/
class KisBookmarkedFilterConfigurationsModel : public \
KisBookmarkedConfigurationsModel {
+ Q_OBJECT
public:
/**
* @param thumb a 100x100 thumbnail used to preview the filters
@@ -46,6 +47,8 @@
* @return the filter configuration
*/
KisFilterConfiguration* configuration(const QModelIndex &index) const;
+private slots:
+ void previewUpdated(int i);
private:
struct Private;
Private* const d;
--- trunk/koffice/krita/ui/kis_filters_model.cc #1195757:1195758
@@ -20,7 +20,11 @@
*/
#include "kis_filters_model.h"
+
+#include <QFutureWatcher>
#include <QPixmap>
+#include <QSignalMapper>
+#include <QtConcurrentRun>
#include <filter/kis_filter.h>
#include <filter/kis_filter_registry.h>
@@ -66,6 +70,9 @@
QList<QString> categoriesKeys;
KisPaintDeviceSP thumb;
QHash<const KisFilter*, QImage> previewCache;
+ QSignalMapper* previewCacheWatcher;
+ QHash<int, QFutureWatcher<QImage>*> previewCacheFutureWatcher;
+ QHash<int, const KisFilter*> filterToWatcher;
};
KisFiltersModel::KisFiltersModel(KisPaintDeviceSP thumb) : d(new Private)
@@ -88,6 +95,8 @@
d->categories[ filter->menuCategory().id()].filters.append(filt);
}
qSort(d->categoriesKeys);
+ d->previewCacheWatcher = new QSignalMapper(this);
+ connect(d->previewCacheWatcher, SIGNAL(mapped(int)), SLOT(previewUpdated(int)));
}
KisFiltersModel::~KisFiltersModel()
@@ -159,6 +168,13 @@
return QModelIndex(); // categories don't have parents
}
+QImage generatePreview(const KisFilter* filter, KisPaintDeviceSP thumb)
+{
+ KisPaintDeviceSP target = new KisPaintDevice(*thumb);
+ filter->process(target, QRect(0, 0, 100, 100), \
filter->defaultConfiguration(thumb)); + return target->convertToQImage(0);
+}
+
QVariant KisFiltersModel::data(const QModelIndex &index, int role) const
{
if (index.isValid()) {
@@ -167,17 +183,20 @@
Private::Filter* filter = dynamic_cast<Private::Filter*>(node);
if (filter) {
if (!d->previewCache.contains(filter->filter)) {
- KisPaintDeviceSP target = new KisPaintDevice(*d->thumb);
- QRect rc = target->exactBounds();
- dbgUI << "Previewing " << filter->name << " on: " << rc;
- KisConstProcessingInformation cpi(d->thumb, rc.topLeft());
- KisProcessingInformation cp(target, rc.topLeft());
+ QFutureWatcher<QImage>* watcher = new QFutureWatcher<QImage>();
+ connect(watcher, SIGNAL(finished()), d->previewCacheWatcher, \
SLOT(map())); + \
watcher->setFuture(QtConcurrent::run(generatePreview, filter->filter, d->thumb));
- filter->filter->process(cpi, cp, rc.size()/*QSize(100, 100)*/, \
filter->filter->defaultConfiguration(d->thumb));
- dbgUI << "Resulting in: " << target->exactBounds();
- d->previewCache[ filter->filter ] = target->convertToQImage(0);
- dbgUI << "And in a qimage of size: " << d->previewCache[ \
filter->filter ].rect(); + int filterToWatcherId = \
d->filterToWatcher.count(); +
+ d->filterToWatcher[filterToWatcherId] = filter->filter;
+
+ d->previewCacheWatcher->setMapping(watcher, filterToWatcherId);
+
+ d->previewCacheFutureWatcher[filterToWatcherId] = watcher;
+
+ d->previewCache[filter->filter] = QImage();
}
return d->previewCache[ filter->filter ];
} else {
@@ -203,3 +222,14 @@
return Qt::ItemIsEnabled;
}
}
+
+void KisFiltersModel::previewUpdated(int i)
+{
+ const KisFilter* filter = d->filterToWatcher[i];
+ d->previewCache[filter] = d->previewCacheFutureWatcher[i]->result();
+ delete d->previewCacheFutureWatcher[i];
+ d->previewCacheFutureWatcher.remove(i);
+ emit dataChanged(indexForFilter(filter->id()), indexForFilter(filter->id()));
+}
+
+#include "kis_filters_model.moc"
--- trunk/koffice/krita/ui/kis_filters_model.h #1195757:1195758
@@ -33,6 +33,7 @@
*/
class KisFiltersModel : public QAbstractItemModel
{
+ Q_OBJECT
public:
KisFiltersModel(KisPaintDeviceSP thumb);
~KisFiltersModel();
@@ -44,6 +45,8 @@
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) \
const; virtual Qt::ItemFlags flags(const QModelIndex & index) const;
+private slots:
+ void previewUpdated(int i);
private:
struct Private;
Private* const d;
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic