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

Reply via email to