changeset 226:2ccd02015530

* Add basics of an Export Image File function
author Chris Cannam
date Mon, 12 Mar 2007 15:36:31 +0000
parents 6f46179086c0
children 6dab3ac2fe73
files layer/Layer.h view/View.cpp view/View.h
diffstat 3 files changed, 137 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Layer.h	Fri Mar 09 18:18:30 2007 +0000
+++ b/layer/Layer.h	Mon Mar 12 15:36:31 2007 +0000
@@ -226,7 +226,7 @@
      * Return the proportion of background work complete in drawing
      * this view, as a percentage -- in most cases this will be the
      * value returned by pointer from a call to the underlying model's
-     * isReady(int *) call.  The widget may choose to show a progress
+     * isReady(int *) call.  The view may choose to show a progress
      * meter if it finds that this returns < 100 at any given moment.
      */
     virtual int getCompletion(View *) const { return 100; }
--- a/view/View.cpp	Fri Mar 09 18:18:30 2007 +0000
+++ b/view/View.cpp	Mon Mar 12 15:36:31 2007 +0000
@@ -26,6 +26,7 @@
 #include <QPaintEvent>
 #include <QRect>
 #include <QApplication>
+#include <QProgressDialog>
 
 #include <iostream>
 #include <cassert>
@@ -1465,6 +1466,135 @@
     QFrame::paintEvent(e);
 }
 
+bool
+View::render(QPainter &paint, QRect rect)
+{
+    size_t f0 = getModelsStartFrame();
+    size_t f1 = getModelsEndFrame();
+
+    size_t x0 = f0 / m_zoomLevel;
+    size_t x1 = f1 / m_zoomLevel;
+
+    size_t w = x1 - x0;
+
+    size_t origCentreFrame = m_centreFrame;
+
+    bool someLayersIncomplete = false;
+
+    for (LayerList::iterator i = m_layers.begin();
+         i != m_layers.end(); ++i) {
+
+        int c = (*i)->getCompletion(this);
+        if (c < 100) {
+            someLayersIncomplete = true;
+            break;
+        }
+    }
+
+    if (someLayersIncomplete) {
+
+        QProgressDialog progress(tr("Waiting for layers to be ready..."),
+                                 tr("Cancel"), 0, 100, this);
+        
+        int layerCompletion = 0;
+
+        while (layerCompletion < 100) {
+
+            for (LayerList::iterator i = m_layers.begin();
+                 i != m_layers.end(); ++i) {
+
+                int c = (*i)->getCompletion(this);
+                if (i == m_layers.begin() || c < layerCompletion) {
+                    layerCompletion = c;
+                }
+            }
+
+            if (layerCompletion >= 100) break;
+
+            progress.setValue(layerCompletion);
+            qApp->processEvents();
+            if (progress.wasCanceled()) {
+                update();
+                return false;
+            }
+
+            usleep(50000);
+        }
+    }
+
+    QProgressDialog progress(tr("Rendering image..."),
+                             tr("Cancel"), 0, w / width(), this);
+
+    for (size_t x = 0; x < w; x += width()) {
+
+        progress.setValue(x / width());
+        qApp->processEvents();
+        if (progress.wasCanceled()) {
+            m_centreFrame = origCentreFrame;
+            update();
+            return false;
+        }
+
+        m_centreFrame = (x + width()/2) * m_zoomLevel;
+        
+        QRect chunk(0, 0, width(), height());
+
+	if (hasLightBackground()) {
+	    paint.setPen(Qt::white);
+	    paint.setBrush(Qt::white);
+	} else {
+	    paint.setPen(Qt::black);
+	    paint.setBrush(Qt::black);
+	}
+
+	paint.drawRect(QRect(rect.x() + x, rect.y(), width(), height()));
+
+	paint.setPen(Qt::black);
+	paint.setBrush(Qt::NoBrush);
+
+	for (LayerList::iterator i = m_layers.begin();
+             i != m_layers.end(); ++i) {
+
+	    paint.setRenderHint(QPainter::Antialiasing, false);
+
+	    paint.save();
+            paint.translate(rect.x() + x, rect.y());
+
+//            std::cerr << "Centre frame now: " << m_centreFrame << " drawing to " << chunk.x() << ", " << chunk.width() << std::endl;
+
+	    (*i)->paint(this, paint, chunk);
+
+	    paint.restore();
+	}
+    }
+
+    m_centreFrame = origCentreFrame;
+    update();
+    return true;
+}
+
+QImage *
+View::toNewImage()
+{
+    size_t f0 = getModelsStartFrame();
+    size_t f1 = getModelsEndFrame();
+
+    size_t x0 = f0 / getZoomLevel();
+    size_t x1 = f1 / getZoomLevel();
+    
+    QImage *image = new QImage(x1 - x0, height(), QImage::Format_RGB32);
+
+    QPainter *paint = new QPainter(image);
+    if (!render(*paint, image->rect())) {
+        delete paint;
+        delete image;
+        return 0;
+    } else {
+        delete paint;
+        return image;
+    }
+}
+
 void
 View::drawSelections(QPainter &paint)
 {
--- a/view/View.h	Fri Mar 09 18:18:30 2007 +0000
+++ b/view/View.h	Mon Mar 12 15:36:31 2007 +0000
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _CANVAS_H_
-#define _CANVAS_H_
+#ifndef _VIEW_H_
+#define _VIEW_H_
 
 #include <QFrame>
 #include <QProgressBar>
@@ -215,6 +215,10 @@
     virtual const PropertyContainer *getPropertyContainer(size_t i) const;
     virtual PropertyContainer *getPropertyContainer(size_t i);
 
+    // Render the entire contents on a wide canvas
+    virtual bool render(QPainter &paint, QRect rect);
+    virtual QImage *toNewImage();
+
     virtual int getTextLabelHeight(const Layer *layer, QPainter &) const;
 
     virtual bool getValueExtents(QString unit, float &min, float &max,