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?
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..becfe21 100644
--- a/plugins/vectorshape/libemf/EmfParser.cpp
+++ b/plugins/vectorshape/libemf/EmfParser.cpp
@@ -111,6 +111,8 @@ bool Parser::loadFromStream( QDataStream &stream )
         return false;
     }
 
+    emit progressUpdated( 0 );
+
     mOutput->init( header );
 
 #if DEBUG_EMFPARSER
@@ -118,17 +120,26 @@ bool Parser::loadFromStream( QDataStream &stream )
 #endif
 
     int numRecords = header->recordCount();
+    int lastPercent = -1;
     for ( int i = 1; i < numRecords; ++i ) {
         // kDebug(33100) << "Record" << i << "of" << numRecords;
         if ( ! readRecord( stream ) ) {
             break;
         }
+
+        int percent = int(i / qreal(numRecords) * 100.);
+        if (percent != lastPercent) {
+            lastPercent = percent;
+            emit progressUpdated( percent );
+        }
     }
 
     mOutput->cleanup( header );
 
     delete header;
 
+    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

Reply via email to