On Saturday 09 July 2011 18:20:35 Sebastian Sauer wrote: > Hi, > > please find attached a patch that introduces the possibility to provide > progress updates for shapes so they are able to give feedback on long > running tasks. > > The patch also extends the vectorshape to use the functionality during > parsing an EMF file. > > What you think?
Attached a modified version of the patch that only reports progress for emf- files that are >3MB size. Follows a suggested by ingwa.
diff --git a/libs/flake/KoShapeFactoryBase.h b/libs/flake/KoShapeFactoryBase.h index 79a893d..a251369 100644 --- a/libs/flake/KoShapeFactoryBase.h +++ b/libs/flake/KoShapeFactoryBase.h @@ -232,6 +232,13 @@ public: */ virtual KoShape *createShape(const KoProperties *params, KoResourceManager *documentResources = 0) const; +signals: + /** + * This signal is emitted during a longer running task to provide status updates. This + * allows feedback during for example loading a document to an user-interface. + */ + void progressUpdated( int percent ); + protected: /** diff --git a/libs/flake/KoShapeRegistry.cpp b/libs/flake/KoShapeRegistry.cpp index 06e4c7c..653499b 100644 --- a/libs/flake/KoShapeRegistry.cpp +++ b/libs/flake/KoShapeRegistry.cpp @@ -49,18 +49,20 @@ class KoShapeRegistry::Private { public: + explicit Private(KoShapeRegistry *qq) : q(qq) {} + void insertFactory(KoShapeFactoryBase *factory); - void init(KoShapeRegistry *q); + void init(); KoShape *createShapeInternal(const KoXmlElement &fullElement, KoShapeLoadingContext &context, const KoXmlElement &element) const; - + KoShapeRegistry *q; // Map namespace,tagname to priority:factory QHash<QPair<QString, QString>, QMultiMap<int, KoShapeFactoryBase*> > factoryMap; }; KoShapeRegistry::KoShapeRegistry() - : d(new Private()) + : d(new Private(this)) { } @@ -71,7 +73,7 @@ KoShapeRegistry::~KoShapeRegistry() delete d; } -void KoShapeRegistry::Private::init(KoShapeRegistry *q) +void KoShapeRegistry::Private::init() { KoPluginLoader::PluginsConfig config; config.whiteList = "FlakePlugins"; @@ -104,7 +106,7 @@ KoShapeRegistry* KoShapeRegistry::instance() { K_GLOBAL_STATIC(KoShapeRegistry, s_instance) if (!s_instance.exists()) { - s_instance->d->init(s_instance); + s_instance->d->init(); } return s_instance; } @@ -132,6 +134,8 @@ void KoShapeRegistry::Private::insertFactory(KoShapeFactoryBase *factory) priorityMap.insert(priority, factory); + QObject::connect(factory, SIGNAL(progressUpdated(int)), q, SIGNAL(progressUpdated(int))); + kDebug(30006) << "Inserting factory" << factory->id() << " for" << p << " with priority " << priority << " into factoryMap making " diff --git a/libs/flake/KoShapeRegistry.h b/libs/flake/KoShapeRegistry.h index 593e61a..6b5c5e4 100644 --- a/libs/flake/KoShapeRegistry.h +++ b/libs/flake/KoShapeRegistry.h @@ -39,8 +39,9 @@ class KoShapeLoadingContext; * or rather, of the factories that applications can use to create flake * shape objects. */ -class FLAKE_EXPORT KoShapeRegistry : public KoGenericRegistry<KoShapeFactoryBase*> +class FLAKE_EXPORT KoShapeRegistry : public QObject, public KoGenericRegistry<KoShapeFactoryBase*> { + Q_OBJECT public: ~KoShapeRegistry(); @@ -69,6 +70,13 @@ public: */ KoShape *createShapeFromOdf(const KoXmlElement &element, KoShapeLoadingContext &context) const; +signals: + /** + * This signal is emitted during a longer running task to provide status updates. This + * allows feedback during for example loading a document to an user-interface. + */ + void progressUpdated( int percent ); + private: KoShapeRegistry(); KoShapeRegistry(const KoShapeRegistry&); diff --git a/libs/main/KoDocument.cpp b/libs/main/KoDocument.cpp index 515911a..4dead60 100644 --- a/libs/main/KoDocument.cpp +++ b/libs/main/KoDocument.cpp @@ -46,6 +46,7 @@ #include <KoProgressProxy.h> #include <KoProgressUpdater.h> #include <KoUpdater.h> +#include <KoShapeRegistry.h> #include <KoDpi.h> #include <KoXmlWriter.h> @@ -389,6 +390,8 @@ KoDocument::KoDocument(QWidget *parentWidget, QObject *parent, bool singleViewMo // A way to 'fix' the job's window, since we have no widget known to KParts if (!singleViewMode) connect(this, SIGNAL(started(KIO::Job*)), SLOT(slotStarted(KIO::Job*))); + + connect(KoShapeRegistry::instance(), SIGNAL(progressUpdated(int)), this, SLOT(shapeProgressUpdated(int))); } KoDocument::~KoDocument() @@ -418,6 +421,14 @@ KoDocument::~KoDocument() } } +void KoDocument::shapeProgressUpdated(int percent) +{ + if (KoMainWindow *mainWindow = currentShell()) { + mainWindow->slotProgress(percent); + } +// emit sigProgress(percent); +} + bool KoDocument::isSingleViewMode() const { return d->bSingleViewMode; diff --git a/libs/main/KoDocument.h b/libs/main/KoDocument.h index 63e4ebf..e4f233b 100644 --- a/libs/main/KoDocument.h +++ b/libs/main/KoDocument.h @@ -1031,7 +1031,7 @@ private slots: void slotAutoSave(); void slotStarted(KIO::Job*); void startCustomDocument(); - + void shapeProgressUpdated(int); private: bool saveToStream(QIODevice *dev); diff --git a/plugins/vectorshape/VectorShape.cpp b/plugins/vectorshape/VectorShape.cpp index 3e2cbc8..04dc983 100644 --- a/plugins/vectorshape/VectorShape.cpp +++ b/plugins/vectorshape/VectorShape.cpp @@ -22,6 +22,7 @@ // Own #include "VectorShape.h" +#include "VectorShapeFactory.h" // Posix #include <math.h> @@ -46,6 +47,8 @@ #include <KoOdfLoadingContext.h> #include <KoShapeSavingContext.h> #include <KoViewConverter.h> +#include <KoUpdater.h> +#include <KoDocument.h> // Wmf support #include "WmfPainterBackend.h" @@ -58,8 +61,9 @@ #include "libsvm/SvmPainterBackend.h" -VectorShape::VectorShape() +VectorShape::VectorShape(const VectorShapeFactory *const factory) : KoFrameShape( KoXmlNS::draw, "image" ) + , m_factory(factory) , m_type(VectorTypeNone) { setShapeId(VectorShape_SHAPEID); @@ -213,6 +217,7 @@ void VectorShape::drawEmf(QPainter &painter) const // FIXME: Make it static to save time? Libemf::Parser emfParser; + QObject::connect(&emfParser, SIGNAL(progressUpdated(int)), m_factory, SIGNAL(progressUpdated(int))); #if 1 // Set to 0 to get debug output // Create a new painter output strategy. Last param = true means keep aspect ratio. diff --git a/plugins/vectorshape/VectorShape.h b/plugins/vectorshape/VectorShape.h index 4229842..c54ddaf 100644 --- a/plugins/vectorshape/VectorShape.h +++ b/plugins/vectorshape/VectorShape.h @@ -28,6 +28,7 @@ #include <QByteArray> #include <QCache> #include <QSize> +#include <QPointer> // Calligra #include <KoShape.h> @@ -38,6 +39,8 @@ class QPainter; +class KoUpdater; +class VectorShapeFactory; #define VectorShape_SHAPEID "VectorShapeID" @@ -54,7 +57,7 @@ public: // ... more here later }; - VectorShape(); + VectorShape(const VectorShapeFactory *const factory); virtual ~VectorShape(); // reimplemented methods. @@ -86,10 +89,11 @@ private: static bool isSvm(const QByteArray &bytes); // Member variables - + const VectorShapeFactory *const m_factory; VectorType m_type; QByteArray m_contents; QCache<int, QImage> m_cache; + QPointer<KoUpdater> m_updater; }; #endif diff --git a/plugins/vectorshape/VectorShapeFactory.cpp b/plugins/vectorshape/VectorShapeFactory.cpp index eeb1674..c5022f7 100644 --- a/plugins/vectorshape/VectorShapeFactory.cpp +++ b/plugins/vectorshape/VectorShapeFactory.cpp @@ -46,7 +46,7 @@ VectorShapeFactory::VectorShapeFactory() KoShape *VectorShapeFactory::createDefaultShape(KoResourceManager */*documentResources*/) const { - VectorShape *shape = new VectorShape(); + VectorShape *shape = new VectorShape(this); shape->setShapeId(VectorShape_SHAPEID); return shape; diff --git a/plugins/vectorshape/libemf/EmfParser.cpp b/plugins/vectorshape/libemf/EmfParser.cpp index ff84d8c..3d6f0eb 100644 --- a/plugins/vectorshape/libemf/EmfParser.cpp +++ b/plugins/vectorshape/libemf/EmfParser.cpp @@ -118,8 +118,21 @@ bool Parser::loadFromStream( QDataStream &stream ) #endif int numRecords = header->recordCount(); + bool reportProgress = stream.device()->size() > 3000; // only report progress if the operation is expected to take longer + int lastPercent = -1; + qint64 size = stream.device()->size(); + for ( int i = 1; i < numRecords; ++i ) { // kDebug(33100) << "Record" << i << "of" << numRecords; + + if (reportProgress) { + int percent = int(i / qreal(numRecords) * 100.); + if (percent != lastPercent) { + lastPercent = percent; + emit progressUpdated( percent ); + } + } + if ( ! readRecord( stream ) ) { break; } @@ -129,6 +142,9 @@ bool Parser::loadFromStream( QDataStream &stream ) delete header; + if (reportProgress) + emit progressUpdated( -1 ); + return true; } diff --git a/plugins/vectorshape/libemf/EmfParser.h b/plugins/vectorshape/libemf/EmfParser.h index f376dc2..bafaf12 100644 --- a/plugins/vectorshape/libemf/EmfParser.h +++ b/plugins/vectorshape/libemf/EmfParser.h @@ -23,6 +23,7 @@ #include "EmfOutput.h" +#include <QObject> #include <QString> #include <QRect> // also provides QSize @@ -41,8 +42,9 @@ namespace Libemf /** %Parser for an EMF format file */ -class EMF_EXPORT Parser +class EMF_EXPORT Parser : public QObject { + Q_OBJECT public: Parser(); ~Parser(); @@ -81,6 +83,13 @@ public: */ void setOutput( AbstractOutput *output ); +Q_SIGNALS: + /** + * This signal is emitted on parsing to provide progress updates to + * a properly long running task like parsing. + */ + void progressUpdated( int percent ); + private: // read a single EMF record bool readRecord( QDataStream &stream );
_______________________________________________ calligra-devel mailing list calligra-devel@kde.org https://mail.kde.org/mailman/listinfo/calligra-devel