changeset 706:97ea68f62c1f imaf_enc

Merge from default branch
author Chris Cannam
date Thu, 05 Dec 2013 09:47:02 +0000
parents 26c5f7fd4807 (current diff) b81f21f2c4c3 (diff)
children 282f4be8f058
files layer/TimeInstantLayer.cpp layer/WaveformLayer.cpp view/Pane.cpp widgets/ModelDataTableDialog.cpp widgets/PropertyBox.cpp
diffstat 60 files changed, 1467 insertions(+), 635 deletions(-) [+]
line wrap: on
line diff
--- a/layer/Colour3DPlotLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/Colour3DPlotLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -689,7 +689,7 @@
 
     float value = m_model->getValueAt(sx0, sy);
 
-//    std::cerr << "bin value (" << sx0 << "," << sy << ") is " << value << std::endl;
+//    cerr << "bin value (" << sx0 << "," << sy << ") is " << value << endl;
     
     QString binName = m_model->getBinName(sy);
     if (binName == "") binName = QString("[%1]").arg(sy + 1);
@@ -786,7 +786,7 @@
                 paint.setPen(QColor(qRed(c), qGreen(c), qBlue(c)));
                 paint.drawLine(5, 11 + y, cw - 5, 11 + y);
             } else {
-                std::cerr << "WARNING: Colour3DPlotLayer::paintVerticalScale: value " << value << ", mmin " << mmin << ", mmax " << mmax << " leads to invalid pixel " << pixel << std::endl;
+                cerr << "WARNING: Colour3DPlotLayer::paintVerticalScale: value " << value << ", mmin " << mmin << ", mmax " << mmax << " leads to invalid pixel " << pixel << endl;
             }
         }
 
@@ -970,7 +970,7 @@
 
     if (m_cacheValidStart <= firstBin && m_cacheValidEnd >= lastBin) {
 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
-        std::cerr << "Cache is valid in this region already" << std::endl;
+        cerr << "Cache is valid in this region already" << endl;
 #endif
         return;
     }
@@ -1006,7 +1006,7 @@
     }
 
 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
-    std::cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << std::endl;
+    cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << endl;
 #endif
 
     DenseThreeDimensionalModel::Column values;
@@ -1229,7 +1229,7 @@
 
 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
     SVDEBUG << "Colour3DPlotLayer::paint: w " << x1-x0 << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sx1-sx0 << ", sh " << sh << endl;
-    std::cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << std::endl;
+    cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << endl;
 #endif
 
     QPoint illuminatePos;
@@ -1289,8 +1289,8 @@
 	    }
             
 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
-//            std::cerr << "rect " << r.x() << "," << r.y() << " "
-//                      << r.width() << "x" << r.height() << std::endl;
+//            cerr << "rect " << r.x() << "," << r.y() << " "
+//                      << r.width() << "x" << r.height() << endl;
 #endif
 
 	    paint.drawRect(r);
@@ -1350,11 +1350,11 @@
     
     QImage *source = m_cache;
     
-    std::cerr << "modelResolution " << modelResolution << ", srRatio "
+    SVDEBUG << "modelResolution " << modelResolution << ", srRatio "
               << srRatio << ", m_peakResolution " << m_peakResolution
               << ", zoomLevel " << zoomLevel << ", result "
               << ((modelResolution * srRatio * m_peakResolution) / zoomLevel)
-              << std::endl;
+              << endl;
 
     if (m_peaksCache) {
         if (((modelResolution * srRatio * m_peakResolution) / zoomLevel) < 1) {
@@ -1362,10 +1362,10 @@
             source = m_peaksCache;
             modelResolution *= m_peakResolution;
         } else {
-            std::cerr << "not using peaks cache" << std::endl;
+            SVDEBUG << "not using peaks cache" << endl;
         }
     } else {
-        std::cerr << "have no peaks cache" << std::endl;
+        SVDEBUG << "have no peaks cache" << endl;
     }
 
     int psy1i = -1;
--- a/layer/ColourMapper.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/ColourMapper.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -19,6 +19,8 @@
 
 #include <cmath>
 
+#include "base/Debug.h"
+
 ColourMapper::ColourMapper(int map, float min, float max) :
     QObject(),
     m_map(map),
@@ -26,8 +28,8 @@
     m_max(max)
 {
     if (m_min == m_max) {
-        std::cerr << "WARNING: ColourMapper: min == max (== " << m_min
-                  << "), adjusting" << std::endl;
+        cerr << "WARNING: ColourMapper: min == max (== " << m_min
+                  << "), adjusting" << endl;
         m_max = m_min + 1;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/ColourScaleLayer.h	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,30 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef COLOUR_SCALE_LAYER_H
+#define COLOUR_SCALE_LAYER_H
+
+#include <QString>
+#include <QColor>
+
+class ColourScaleLayer
+{
+public:
+    virtual QString getScaleUnits() const = 0;
+    virtual QColor getColourForValue(View *v, float value) const = 0;
+};
+
+#endif
+
--- a/layer/ImageLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/ImageLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -163,7 +163,7 @@
         }
     }
 
-//    std::cerr << rv.size() << " point(s)" << std::endl;
+//    cerr << rv.size() << " point(s)" << endl;
 
     return rv;
 }
@@ -500,15 +500,15 @@
 bool
 ImageLayer::getImageOriginalSize(QString name, QSize &size) const
 {
-//    std::cerr << "getImageOriginalSize: \"" << name << "\"" << std::endl;
+//    cerr << "getImageOriginalSize: \"" << name << "\"" << endl;
 
     QMutexLocker locker(&m_imageMapMutex);
     if (m_images.find(name) == m_images.end()) {
-//        std::cerr << "don't have, trying to open local" << std::endl;
+//        cerr << "don't have, trying to open local" << endl;
         m_images[name] = QImage(getLocalFilename(name));
     }
     if (m_images[name].isNull()) {
-//        std::cerr << "null image" << std::endl;
+//        cerr << "null image" << endl;
         return false;
     } else {
         size = m_images[name].size();
@@ -529,7 +529,7 @@
           m_scaled[v][name].height() <= maxSize.height()) ||
          (m_scaled[v][name].width()  <= maxSize.width() &&
           m_scaled[v][name].height() == maxSize.height()))) {
-//        std::cerr << "cache hit" << std::endl;
+//        cerr << "cache hit" << endl;
         return m_scaled[v][name];
     }
 
@@ -540,7 +540,7 @@
     }
 
     if (m_images[name].isNull()) {
-//        std::cerr << "null image" << std::endl;
+//        cerr << "null image" << endl;
         m_scaled[v][name] = QImage();
     } else if (m_images[name].width() <= maxSize.width() &&
                m_images[name].height() <= maxSize.height()) {
@@ -627,7 +627,7 @@
 {
     QImage image(getLocalFilename(url));
     if (image.isNull()) {
-        std::cerr << "Failed to open image from url \"" << url << "\" (local filename \"" << getLocalFilename(url) << "\"" << std::endl;
+        cerr << "Failed to open image from url \"" << url << "\" (local filename \"" << getLocalFilename(url) << "\"" << endl;
         delete m_fileSources[url];
         m_fileSources.erase(url);
         return false;
@@ -915,7 +915,7 @@
     ProgressDialog dialog(tr("Opening image URL..."), true, 2000);
     FileSource *rf = new FileSource(img, &dialog);
     if (rf->isOK()) {
-        std::cerr << "ok, adding it (local filename = " << rf->getLocalFilename() << ")" << std::endl;
+        cerr << "ok, adding it (local filename = " << rf->getLocalFilename() << ")" << endl;
         m_fileSources[img] = rf;
         connect(rf, SIGNAL(ready()), this, SLOT(fileSourceReady()));
     } else {
@@ -948,7 +948,7 @@
          i != m_fileSources.end(); ++i) {
         if (i->second == rf) {
             img = i->first;
-//            std::cerr << "it's image \"" << img << "\"" << std::endl;
+//            cerr << "it's image \"" << img << "\"" << endl;
             break;
         }
     }
--- a/layer/ImageRegionFinder.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/ImageRegionFinder.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -118,7 +118,7 @@
     float db = float(qBlue(a) - qBlue(b)) / 255.f;
     float dist = sqrtf(dr * dr + dg * dg + db * db);
 
-//    std::cerr << "thresh=" << thresh << ", dist=" << dist << std::endl;
+//    cerr << "thresh=" << thresh << ", dist=" << dist << endl;
 
     return (dist < thresh);
 }
--- a/layer/Layer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/Layer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -106,7 +106,7 @@
 PlayParameters *
 Layer::getPlayParameters() 
 {
-//    std::cerr << "Layer (" << this << ", " << objectName() << ")::getPlayParameters: model is "<< getModel() << std::endl;
+//    cerr << "Layer (" << this << ", " << objectName() << ")::getPlayParameters: model is "<< getModel() << endl;
     const Model *model = getModel();
     if (model) {
 	return PlayParameterRepository::getInstance()->getPlayParameters(model);
@@ -257,7 +257,7 @@
         }
         long myMappedFrame = alignToReference(v, sourceFrame);
 
-//        std::cerr << "sourceFrame = " << sourceFrame << ", referenceFrame = " << referenceFrame << " (have = " << i->haveReferenceFrame() << "), myMappedFrame = " << myMappedFrame << std::endl;
+//        cerr << "sourceFrame = " << sourceFrame << ", referenceFrame = " << referenceFrame << " (have = " << i->haveReferenceFrame() << "), myMappedFrame = " << myMappedFrame << endl;
 
         if (myMappedFrame != referenceFrame) return true;
     }
--- a/layer/LayerFactory.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/LayerFactory.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -464,7 +464,7 @@
     QString defaults = settings.value(getLayerTypeName(type), "").toString();
     if (defaults == "") return;
 
-//    std::cerr << "defaults=\"" << defaults << "\"" << std::endl;
+//    cerr << "defaults=\"" << defaults << "\"" << endl;
 
     QString xml = layer->toXmlString();
     QDomDocument docOld, docNew;
@@ -480,9 +480,9 @@
         for (unsigned int i = 0; i < attrNodes.length(); ++i) {
             QDomAttr attr = attrNodes.item(i).toAttr();
             if (attr.isNull()) continue;
-//            std::cerr << "append \"" << attr.name().toStdString()
+//            cerr << "append \"" << attr.name()
 //                      << "\" -> \"" << attr.value() << "\""
-//                      << std::endl;
+//                      << endl;
             attrs.append(attr.name(), "", "", attr.value());
         }
         
@@ -492,9 +492,9 @@
             QDomAttr attr = attrNodes.item(i).toAttr();
             if (attr.isNull()) continue;
             if (attrs.value(attr.name()) == "") {
-//                std::cerr << "append \"" << attr.name().toStdString()
+//                cerr << "append \"" << attr.name()
 //                          << "\" -> \"" << attr.value() << "\""
-//                          << std::endl;
+//                          << endl;
                 attrs.append(attr.name(), "", "", attr.value());
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/LinearColourScale.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,97 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "LinearColourScale.h"
+#include "ColourScaleLayer.h"
+
+#include <QPainter>
+
+#include <cmath>
+
+#include "view/View.h"
+
+int
+LinearColourScale::getWidth(View *v,
+			    QPainter &paint)
+{
+    return paint.fontMetrics().width("-000.00") + 15;
+}
+
+void
+LinearColourScale::paintVertical(View *v,
+				 const ColourScaleLayer *layer,
+				 QPainter &paint,
+				 int x0,
+				 float min,
+				 float max)
+{
+    int h = v->height();
+
+    int n = 10;
+
+    float val = min;
+    float inc = (max - val) / n;
+
+    char buffer[40];
+
+    int w = getWidth(v, paint) + x0;
+
+    int boxx = 5, boxy = 5;
+    if (layer->getScaleUnits() != "") {
+        boxy += paint.fontMetrics().height();
+    }
+    int boxw = 10, boxh = h - boxy - 5;
+
+    int tx = 5 + boxx + boxw;
+    paint.drawRect(boxx, boxy, boxw, boxh);
+
+    paint.save();
+    for (int y = 0; y < boxh; ++y) {
+	float val = ((boxh - y) * (max - min)) / boxh + min;
+	paint.setPen(layer->getColourForValue(v, val));
+	paint.drawLine(boxx + 1, y + boxy + 1, boxx + boxw, y + boxy + 1);
+    }
+    paint.restore();
+
+    float round = 1.f;
+    int dp = 0;
+    if (inc > 0) {
+        int prec = trunc(log10f(inc));
+        prec -= 1;
+        if (prec < 0) dp = -prec;
+        round = powf(10.f, prec);
+#ifdef DEBUG_TIME_VALUE_LAYER
+        cerr << "inc = " << inc << ", round = " << round << ", dp = " << dp << endl;
+#endif
+    }
+
+    for (int i = 0; i < n; ++i) {
+
+	int y, ty;
+
+	y = boxy + int(boxh - ((val - min) * boxh) / (max - min));
+
+	ty = y - paint.fontMetrics().height() +
+	    paint.fontMetrics().ascent() + 2;
+
+	sprintf(buffer, "%.*f", dp, val);
+	QString label = QString(buffer);
+
+	paint.drawLine(boxx + boxw - boxw/3, y, boxx + boxw, y);
+	paint.drawText(tx, ty, label);
+
+	val += inc;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/LinearColourScale.h	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,36 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef LINEAR_COLOUR_SCALE_H
+#define LINEAR_COLOUR_SCALE_H
+
+#include <QRect>
+
+class QPainter;
+class View;
+class ColourScaleLayer;
+
+class LinearColourScale
+{
+public:
+    int getWidth(View *v, QPainter &paint);
+
+    void paintVertical
+    (View *v, const ColourScaleLayer *layer, QPainter &paint, int x0,
+     float minf, float maxf);
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/LinearNumericalScale.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,105 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "LinearNumericalScale.h"
+#include "VerticalScaleLayer.h"
+
+#include <QPainter>
+
+#include <cmath>
+
+#include "view/View.h"
+
+int
+LinearNumericalScale::getWidth(View *v,
+			       QPainter &paint)
+{
+    return paint.fontMetrics().width("-000.00") + 10;
+}
+
+void
+LinearNumericalScale::paintVertical(View *v,
+				    const VerticalScaleLayer *layer,
+				    QPainter &paint,
+				    int x0,
+				    float minf,
+				    float maxf)
+{
+    int h = v->height();
+
+    int n = 10;
+
+    float val = minf;
+    float inc = (maxf - val) / n;
+
+    char buffer[40];
+
+    int w = getWidth(v, paint) + x0;
+
+    float round = 1.f;
+    int dp = 0;
+    if (inc > 0) {
+        int prec = trunc(log10f(inc));
+        prec -= 1;
+        if (prec < 0) dp = -prec;
+        round = powf(10.f, prec);
+#ifdef DEBUG_TIME_VALUE_LAYER
+        cerr << "inc = " << inc << ", round = " << round << ", dp = " << dp << endl;
+#endif
+    }
+
+    int prevy = -1;
+                
+    for (int i = 0; i < n; ++i) {
+
+	int y, ty;
+        bool drawText = true;
+
+        float dispval = val;
+
+	if (i == n-1 &&
+	    v->height() < paint.fontMetrics().height() * (n*2)) {
+	    if (layer->getScaleUnits() != "") drawText = false;
+	}
+	dispval = lrintf(val / round) * round;
+
+#ifdef DEBUG_TIME_VALUE_LAYER
+	cerr << "val = " << val << ", dispval = " << dispval << endl;
+#endif
+
+	y = layer->getYForValue(v, dispval);
+
+	ty = y - paint.fontMetrics().height() + paint.fontMetrics().ascent() + 2;
+	
+	if (prevy >= 0 && (prevy - y) < paint.fontMetrics().height()) {
+	    val += inc;
+	    continue;
+        }
+
+	sprintf(buffer, "%.*f", dp, dispval);
+
+	QString label = QString(buffer);
+
+	paint.drawLine(w - 5, y, w, y);
+
+        if (drawText) {
+	    paint.drawText(w - paint.fontMetrics().width(label) - 6,
+			   ty, label);
+        }
+
+        prevy = y;
+	val += inc;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/LinearNumericalScale.h	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,36 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef LINEAR_NUMERICAL_SCALE_H
+#define LINEAR_NUMERICAL_SCALE_H
+
+#include <QRect>
+
+class QPainter;
+class View;
+class VerticalScaleLayer;
+
+class LinearNumericalScale
+{
+public:
+    int getWidth(View *v, QPainter &paint);
+
+    void paintVertical
+    (View *v, const VerticalScaleLayer *layer, QPainter &paint, int x0,
+     float minf, float maxf);
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/LogColourScale.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,99 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "LogColourScale.h"
+#include "ColourScaleLayer.h"
+
+#include "base/LogRange.h"
+
+#include <QPainter>
+
+#include <cmath>
+
+#include "view/View.h"
+
+int
+LogColourScale::getWidth(View *v,
+			    QPainter &paint)
+{
+    return paint.fontMetrics().width("-000.00") + 15;
+}
+
+void
+LogColourScale::paintVertical(View *v,
+			      const ColourScaleLayer *layer,
+			      QPainter &paint,
+			      int x0,
+			      float minlog,
+			      float maxlog)
+{
+    int h = v->height();
+
+    int n = 10;
+
+    float val = minlog;
+    float inc = (maxlog - val) / n;
+
+    char buffer[40];
+
+    int w = getWidth(v, paint) + x0;
+
+    int boxx = 5, boxy = 5;
+    if (layer->getScaleUnits() != "") {
+        boxy += paint.fontMetrics().height();
+    }
+    int boxw = 10, boxh = h - boxy - 5;
+
+    int tx = 5 + boxx + boxw;
+    paint.drawRect(boxx, boxy, boxw, boxh);
+
+    paint.save();
+    for (int y = 0; y < boxh; ++y) {
+	float val = ((boxh - y) * (maxlog - minlog)) / boxh + minlog;
+	paint.setPen(layer->getColourForValue(v, LogRange::unmap(val)));
+	paint.drawLine(boxx + 1, y + boxy + 1, boxx + boxw, y + boxy + 1);
+    }
+    paint.restore();
+
+    int dp = 0;
+    if (inc > 0) {
+        int prec = trunc(log10f(inc));
+        prec -= 1;
+        if (prec < 0) dp = -prec;
+    }
+
+    for (int i = 0; i < n; ++i) {
+
+	int y, ty;
+
+	y = boxy + int(boxh - ((val - minlog) * boxh) / (maxlog - minlog));
+
+	ty = y - paint.fontMetrics().height() +
+	    paint.fontMetrics().ascent() + 2;
+
+	double dv = LogRange::unmap(val);
+	int digits = trunc(log10f(dv));
+	int sf = dp + (digits > 0 ? digits : 0);
+	if (sf < 2) sf = 2;
+	sprintf(buffer, "%.*g", sf, dv);
+
+	QString label = QString(buffer);
+
+	paint.drawLine(boxx + boxw - boxw/3, y, boxx + boxw, y);
+	paint.drawText(tx, ty, label);
+
+	val += inc;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/LogColourScale.h	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,36 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef LOG_COLOUR_SCALE_H
+#define LOG_COLOUR_SCALE_H
+
+#include <QRect>
+
+class QPainter;
+class View;
+class ColourScaleLayer;
+
+class LogColourScale
+{
+public:
+    int getWidth(View *v, QPainter &paint);
+
+    void paintVertical
+    (View *v, const ColourScaleLayer *layer, QPainter &paint, int x0,
+     float minf, float maxf);
+};
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/LogNumericalScale.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,121 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "LogNumericalScale.h"
+#include "VerticalScaleLayer.h"
+
+#include "base/LogRange.h"
+
+#include <QPainter>
+
+#include <cmath>
+
+#include "view/View.h"
+
+//#define DEBUG_TIME_VALUE_LAYER 1
+
+int
+LogNumericalScale::getWidth(View *,
+			    QPainter &paint)
+{
+    return paint.fontMetrics().width("-000.00") + 10;
+}
+
+void
+LogNumericalScale::paintVertical(View *v,
+				 const VerticalScaleLayer *layer,
+				 QPainter &paint,
+				 int x0,
+				 float minlog,
+				 float maxlog)
+{
+    int w = getWidth(v, paint) + x0;
+
+    int n = 10;
+
+    float val = minlog;
+    float inc = (maxlog - val) / n; // even increments of log scale
+
+    // smallest increment as displayed
+    float minDispInc = LogRange::unmap(minlog + inc) - LogRange::unmap(minlog);
+
+#ifdef DEBUG_TIME_VALUE_LAYER
+    cerr << "min = " << minlog << ", max = " << maxlog << ", inc = " << inc << ", minDispInc = " << minDispInc << endl;
+#endif
+
+    char buffer[40];
+
+    float round = 1.f;
+    int dp = 0;
+
+    if (minDispInc > 0) {
+        int prec = trunc(log10f(minDispInc));
+        if (prec < 0) dp = -prec;
+        round = powf(10.f, prec);
+        if (dp > 4) dp = 4;
+#ifdef DEBUG_TIME_VALUE_LAYER
+        cerr << "round = " << round << ", prec = " << prec << ", dp = " << dp << endl;
+#endif
+    }
+
+    int prevy = -1;
+                
+    for (int i = 0; i < n; ++i) {
+
+	int y, ty;
+        bool drawText = true;
+
+	if (i == n-1 &&
+	    v->height() < paint.fontMetrics().height() * (n*2)) {
+	    if (layer->getScaleUnits() != "") drawText = false;
+	}
+
+        float dispval = LogRange::unmap(val);
+	dispval = floor(dispval / round) * round;
+
+#ifdef DEBUG_TIME_VALUE_LAYER
+	cerr << "val = " << val << ", dispval = " << dispval << endl;
+#endif
+
+	y = layer->getYForValue(v, dispval);
+
+	ty = y - paint.fontMetrics().height() + paint.fontMetrics().ascent() + 2;
+	
+	if (prevy >= 0 && (prevy - y) < paint.fontMetrics().height()) {
+	    val += inc;
+	    continue;
+        }
+
+	int digits = trunc(log10f(dispval));
+	int sf = dp + (digits > 0 ? digits : 0);
+	if (sf < 4) sf = 4;
+#ifdef DEBUG_TIME_VALUE_LAYER
+        cerr << "sf = " << sf << endl;
+#endif
+	sprintf(buffer, "%.*g", sf, dispval);
+
+	QString label = QString(buffer);
+
+	paint.drawLine(w - 5, y, w, y);
+
+        if (drawText) {
+	    paint.drawText(w - paint.fontMetrics().width(label) - 6,
+			   ty, label);
+        }
+
+        prevy = y;
+	val += inc;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/LogNumericalScale.h	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,36 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef LOG_NUMERICAL_SCALE_H
+#define LOG_NUMERICAL_SCALE_H
+
+#include <QRect>
+
+class QPainter;
+class View;
+class VerticalScaleLayer;
+
+class LogNumericalScale
+{
+public:
+    int getWidth(View *v, QPainter &paint);
+
+    void paintVertical
+    (View *v, const VerticalScaleLayer *layer, QPainter &paint, int x0,
+     float minlog, float maxlog);
+};
+
+#endif
+
--- a/layer/NoteLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/NoteLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -24,9 +24,14 @@
 #include "ColourDatabase.h"
 #include "view/View.h"
 
+#include "PianoScale.h"
+#include "LinearNumericalScale.h"
+#include "LogNumericalScale.h"
+
 #include "data/model/NoteModel.h"
 
 #include "widgets/ItemEditDialog.h"
+#include "widgets/TextAbbrev.h"
 
 #include <QPainter>
 #include <QPainterPath>
@@ -104,6 +109,13 @@
     return SingleColourLayer::getPropertyGroupName(name);
 }
 
+QString
+NoteLayer::getScaleUnits() const
+{
+    if (m_model) return m_model->getScaleUnits();
+    else return "";
+}
+
 int
 NoteLayer::getPropertyRangeAndValue(const PropertyName &name,
                                     int *min, int *max, int *deflt) const
@@ -123,7 +135,7 @@
         if (deflt) *deflt = 0;
         if (m_model) {
             val = UnitDatabase::getInstance()->getUnitId
-                (m_model->getScaleUnits());
+                (getScaleUnits());
         }
 
     } else {
@@ -184,7 +196,7 @@
 bool
 NoteLayer::shouldConvertMIDIToHz() const
 {
-    QString unit = m_model->getScaleUnits();
+    QString unit = getScaleUnits();
     return (unit != "Hz");
 //    if (unit == "" ||
 //        unit.startsWith("MIDI") ||
@@ -204,7 +216,7 @@
         unit = "Hz";
         min = Pitch::getFrequencyForPitch(lrintf(min));
         max = Pitch::getFrequencyForPitch(lrintf(max + 1));
-    } else unit = m_model->getScaleUnits();
+    } else unit = getScaleUnits();
 
     if (m_verticalScale == MIDIRangeScale ||
         m_verticalScale == LogScale) logarithmic = true;
@@ -237,7 +249,7 @@
     }
 
 #ifdef DEBUG_NOTE_LAYER
-    std::cerr << "NoteLayer::getDisplayExtents: min = " << min << ", max = " << max << " (m_scaleMinimum = " << m_scaleMinimum << ", m_scaleMaximum = " << m_scaleMaximum << ")" << std::endl;
+    cerr << "NoteLayer::getDisplayExtents: min = " << min << ", max = " << max << " (m_scaleMinimum = " << m_scaleMinimum << ", m_scaleMaximum = " << m_scaleMaximum << ")" << endl;
 #endif
 
     return true;
@@ -260,7 +272,7 @@
     m_scaleMaximum = max;
 
 #ifdef DEBUG_NOTE_LAYER
-    std::cerr << "NoteLayer::setDisplayExtents: min = " << min << ", max = " << max << std::endl;
+    cerr << "NoteLayer::setDisplayExtents: min = " << min << ", max = " << max << endl;
 #endif
     
     emit layerParametersChanged();
@@ -326,7 +338,7 @@
         newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2;
         newmin = newmax - newdist;
 
-//        std::cerr << "newmin = " << newmin << ", newmax = " << newmax << std::endl;
+//        cerr << "newmin = " << newmin << ", newmax = " << newmax << endl;
 
     } else {
         float dmid = (dmax + dmin) / 2;
@@ -343,7 +355,7 @@
     }
     
 #ifdef DEBUG_NOTE_LAYER
-    std::cerr << "NoteLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << std::endl;
+    cerr << "NoteLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << endl;
 #endif
 
     setDisplayExtents(newmin, newmax);
@@ -425,7 +437,7 @@
     NoteModel::PointList onPoints = m_model->getPoints(frame);
     if (onPoints.empty()) return false;
 
-//    std::cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << std::endl;
+//    cerr << "frame " << frame << ": " << onPoints.size() << " candidate points" << endl;
 
     int nearestDistance = -1;
 
@@ -498,7 +510,7 @@
             .arg(mnote)
             .arg(freq);
 
-    } else if (m_model->getScaleUnits() == "Hz") {
+    } else if (getScaleUnits() == "Hz") {
 
         pitchText = tr("%1 Hz (%2, %3)")
             .arg(note.value)
@@ -507,7 +519,7 @@
 
     } else {
         pitchText = tr("%1 %2")
-            .arg(note.value).arg(m_model->getScaleUnits());
+            .arg(note.value).arg(getScaleUnits());
     }
 
     QString text;
@@ -611,7 +623,7 @@
 
     QString queryUnits;
     if (shouldConvertMIDIToHz()) queryUnits = "Hz";
-    else queryUnits = m_model->getScaleUnits();
+    else queryUnits = getScaleUnits();
 
     if (shouldAutoAlign()) {
 
@@ -626,7 +638,7 @@
             }
 
 #ifdef DEBUG_NOTE_LAYER
-            std::cerr << "NoteLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << std::endl;
+            cerr << "NoteLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << endl;
 #endif
 
         } else if (log) {
@@ -634,7 +646,7 @@
             LogRange::mapRange(min, max);
 
 #ifdef DEBUG_NOTE_LAYER
-            std::cerr << "NoteLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << std::endl;
+            cerr << "NoteLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << endl;
 #endif
 
         }
@@ -670,27 +682,27 @@
     getScaleExtents(v, min, max, logarithmic);
 
 #ifdef DEBUG_NOTE_LAYER
-    std::cerr << "NoteLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << std::endl;
+    cerr << "NoteLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << endl;
 #endif
 
     if (shouldConvertMIDIToHz()) {
         val = Pitch::getFrequencyForPitch(lrintf(val),
                                           lrintf((val - lrintf(val)) * 100));
 #ifdef DEBUG_NOTE_LAYER
-        std::cerr << "shouldConvertMIDIToHz true, val now = " << val << std::endl;
+        cerr << "shouldConvertMIDIToHz true, val now = " << val << endl;
 #endif
     }
 
     if (logarithmic) {
         val = LogRange::map(val);
 #ifdef DEBUG_NOTE_LAYER
-        std::cerr << "logarithmic true, val now = " << val << std::endl;
+        cerr << "logarithmic true, val now = " << val << endl;
 #endif
     }
 
     int y = int(h - ((val - min) * h) / (max - min)) - 1;
 #ifdef DEBUG_NOTE_LAYER
-    std::cerr << "y = " << y << std::endl;
+    cerr << "y = " << y << endl;
 #endif
     return y;
 }
@@ -792,7 +804,7 @@
             paint.setPen(v->getForeground());
             paint.setBrush(v->getForeground());
 
-            QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits());
+            QString vlabel = QString("%1%2").arg(p.value).arg(getScaleUnits());
             v->drawVisibleText(paint, 
                                x - paint.fontMetrics().width(vlabel) - 2,
                                y + paint.fontMetrics().height()/2
@@ -813,6 +825,58 @@
     paint.restore();
 }
 
+int
+NoteLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const
+{
+    if (!m_model || shouldAutoAlign()) {
+        return 0;
+    } else  {
+        if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) {
+            return LogNumericalScale().getWidth(v, paint) + 10; // for piano
+        } else {
+            return LinearNumericalScale().getWidth(v, paint);
+        }
+    }
+}
+
+void
+NoteLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const
+{
+    if (!m_model) return;
+
+    QString unit;
+    float min, max;
+    bool logarithmic;
+
+    int w = getVerticalScaleWidth(v, false, paint);
+    int h = v->height();
+
+    getScaleExtents(v, min, max, logarithmic);
+
+    if (logarithmic) {
+        LogNumericalScale().paintVertical(v, this, paint, 0, min, max);
+    } else {
+        LinearNumericalScale().paintVertical(v, this, paint, 0, min, max);
+    }
+    
+    if (logarithmic && (getScaleUnits() == "Hz")) {
+        PianoScale().paintPianoVertical
+            (v, paint, QRect(w - 10, 0, 10, h), 
+             LogRange::unmap(min), 
+             LogRange::unmap(max));
+        paint.drawLine(w, 0, w, h);
+    }
+        
+    if (getScaleUnits() != "") {
+        int mw = w - 5;
+        paint.drawText(5,
+                       5 + paint.fontMetrics().ascent(),
+                       TextAbbrev::abbreviate(getScaleUnits(),
+                                              paint.fontMetrics(),
+                                              mw));
+    }
+}
+
 void
 NoteLayer::drawStart(View *v, QMouseEvent *e)
 {
@@ -1012,7 +1076,7 @@
          ItemEditDialog::ShowDuration |
          ItemEditDialog::ShowValue |
          ItemEditDialog::ShowText,
-         m_model->getScaleUnits());
+         getScaleUnits());
 
     dialog->setFrameTime(note.frame);
     dialog->setValue(note.value);
--- a/layer/NoteLayer.h	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/NoteLayer.h	Thu Dec 05 09:47:02 2013 +0000
@@ -17,6 +17,8 @@
 #define _NOTE_LAYER_H_
 
 #include "SingleColourLayer.h"
+#include "VerticalScaleLayer.h"
+
 #include "data/model/NoteModel.h"
 
 #include <QObject>
@@ -25,7 +27,8 @@
 class View;
 class QPainter;
 
-class NoteLayer : public SingleColourLayer
+class NoteLayer : public SingleColourLayer,
+                  public VerticalScaleLayer
 {
     Q_OBJECT
 
@@ -34,6 +37,9 @@
 
     virtual void paint(View *v, QPainter &paint, QRect rect) const;
 
+    virtual int getVerticalScaleWidth(View *v, bool, QPainter &) const;
+    virtual void paintVerticalScale(View *v, bool, QPainter &paint, QRect rect) const;
+
     virtual QString getFeatureDescription(View *v, QPoint &) const;
 
     virtual bool snapToFeatureFrame(View *v, int &frame,
@@ -102,8 +108,6 @@
     virtual void setVerticalZoomStep(int);
     virtual RangeMapper *getNewVerticalZoomRangeMapper() const;
 
-    virtual int getVerticalScaleWidth(View *, bool, QPainter &) const { return 0; }
-
     /**
      * Add a note-on.  Used when recording MIDI "live".  The note will
      * not be finally added to the layer until the corresponding
@@ -127,10 +131,13 @@
 
     void setProperties(const QXmlAttributes &attributes);
 
+    /// VerticalScaleLayer methods
+    virtual int getYForValue(View *v, float value) const;
+    virtual float getValueForY(View *v, int y) const;
+    virtual QString getScaleUnits() const;
+
 protected:
     void getScaleExtents(View *, float &min, float &max, bool &log) const;
-    int getYForValue(View *v, float value) const;
-    float getValueForY(View *v, int y) const;
     bool shouldConvertMIDIToHz() const;
 
     virtual int getDefaultColourHint(bool dark, bool &impose);
--- a/layer/PaintAssistant.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/PaintAssistant.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -52,13 +52,13 @@
         } while (!round && mult < limit);
         if (round) {
             mult /= 10;
-//            std::cerr << "\n\nstep goes from " << step;
+//            cerr << "\n\nstep goes from " << step;
             step = float(round) / mult;
             n = lrintf((maxVal - minVal) / step);
             if (mult > 1) {
                 mult /= 10;
             }
-//            std::cerr << " to " << step << " (n = " << n << ")" << std::endl;
+//            cerr << " to " << step << " (n = " << n << ")" << endl;
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/PianoScale.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,85 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "PianoScale.h"
+
+#include <QPainter>
+
+#include <cmath>
+
+#include "base/Pitch.h"
+
+#include "view/View.h"
+
+void
+PianoScale::paintPianoVertical(View *v,
+			       QPainter &paint,
+			       QRect r,
+			       float minf,
+			       float maxf)
+{
+    int x0 = r.x(), y0 = r.y(), x1 = r.x() + r.width(), y1 = r.y() + r.height();
+
+    paint.drawLine(x0, y0, x0, y1);
+
+    int py = y1, ppy = y1;
+    paint.setBrush(paint.pen().color());
+
+    for (int i = 0; i < 128; ++i) {
+
+	float f = Pitch::getFrequencyForPitch(i);
+	int y = lrintf(v->getYForFrequency(f, minf, maxf, true));
+
+	if (y < y0 - 2) break;
+	if (y > y1 + 2) {
+	    continue;
+	}
+	
+	int n = (i % 12);
+	
+	if (n == 1) {
+	    // C# -- fill the C from here
+	    QColor col = Qt::gray;
+	    if (i == 61) { // filling middle C
+		col = Qt::blue;
+		col = col.light(150);
+	    }
+	    if (ppy - y > 2) {
+		paint.fillRect(x0 + 1,
+			       y,
+			       x1 - x0,
+			       (py + ppy) / 2 - y,
+			       col);
+	    }
+	}
+	
+	if (n == 1 || n == 3 || n == 6 || n == 8 || n == 10) {
+	    // black notes
+	    paint.drawLine(x0 + 1, y, x1, y);
+	    int rh = ((py - y) / 4) * 2;
+	    if (rh < 2) rh = 2;
+	    paint.drawRect(x0 + 1, y - (py-y)/4, (x1 - x0) / 2, rh);
+	} else if (n == 0 || n == 5) {
+	    // C, F
+	    if (py < y1) {
+		paint.drawLine(x0 + 1, (y + py) / 2, x1, (y + py) / 2);
+	    }
+	}
+	
+	ppy = py;
+	py = y;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/PianoScale.h	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,34 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef PIANO_SCALE_H
+#define PIANO_SCALE_H
+
+#include <QRect>
+
+class QPainter;
+class View;
+
+class PianoScale
+{
+public:
+    void paintPianoVertical
+    (View *v, QPainter &paint, QRect rect, float minf, float maxf);
+};
+
+#endif
+
+
+    
--- a/layer/RegionLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/RegionLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -20,12 +20,19 @@
 #include "base/Profiler.h"
 #include "base/LogRange.h"
 #include "ColourDatabase.h"
+
 #include "ColourMapper.h"
+#include "LinearNumericalScale.h"
+#include "LogNumericalScale.h"
+#include "LinearColourScale.h"
+#include "LogColourScale.h"
+
 #include "view/View.h"
 
 #include "data/model/RegionModel.h"
 
 #include "widgets/ItemEditDialog.h"
+#include "widgets/TextAbbrev.h"
 
 #include <QPainter>
 #include <QPainterPath>
@@ -146,7 +153,7 @@
         if (deflt) *deflt = 0;
         if (m_model) {
             val = UnitDatabase::getInstance()->getUnitId
-                (m_model->getScaleUnits());
+                (getScaleUnits());
         }
 
     } else {
@@ -270,7 +277,7 @@
     if (!m_model) return false;
     min = m_model->getValueMinimum();
     max = m_model->getValueMaximum();
-    unit = m_model->getScaleUnits();
+    unit = getScaleUnits();
 
     if (m_verticalScale == LogScale) logarithmic = true;
 
@@ -419,7 +426,7 @@
     
     QString valueText;
 
-    valueText = tr("%1 %2").arg(region.value).arg(m_model->getScaleUnits());
+    valueText = tr("%1 %2").arg(region.value).arg(getScaleUnits());
 
     QString text;
 
@@ -597,6 +604,13 @@
     return found;
 }
 
+QString
+RegionLayer::getScaleUnits() const
+{
+    if (m_model) return m_model->getScaleUnits();
+    else return "";
+}
+
 void
 RegionLayer::getScaleExtents(View *v, float &min, float &max, bool &log) const
 {
@@ -605,7 +619,7 @@
     log = false;
 
     QString queryUnits;
-    queryUnits = m_model->getScaleUnits();
+    queryUnits = getScaleUnits();
 
     if (m_verticalScale == AutoAlignScale) {
 
@@ -614,13 +628,13 @@
             min = m_model->getValueMinimum();
             max = m_model->getValueMaximum();
 
-//            std::cerr << "RegionLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << std::endl;
+//            cerr << "RegionLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << endl;
 
         } else if (log) {
 
             LogRange::mapRange(min, max);
 
-//            std::cerr << "RegionLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << std::endl;
+//            cerr << "RegionLayer[" << this << "]::getScaleExtents: min = " << min << ", max = " << max << ", log = " << log << endl;
 
         }
 
@@ -632,7 +646,7 @@
             i = m_spacingMap.end();
             --i;
             max = i->second;
-//            std::cerr << "RegionLayer[" << this << "]::getScaleExtents: equal spaced; min = " << min << ", max = " << max << ", log = " << log << std::endl;
+//            cerr << "RegionLayer[" << this << "]::getScaleExtents: equal spaced; min = " << min << ", max = " << max << ", log = " << log << endl;
         }
 
     } else {
@@ -695,8 +709,8 @@
 
         getScaleExtents(v, min, max, logarithmic);
 
-//    std::cerr << "RegionLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << std::endl;
-//    std::cerr << "h = " << h << ", margin = " << margin << std::endl;
+//    cerr << "RegionLayer[" << this << "]::getYForValue(" << val << "): min = " << min << ", max = " << max << ", log = " << logarithmic << endl;
+//    cerr << "h = " << h << ", margin = " << margin << endl;
 
         if (logarithmic) {
             val = LogRange::map(val);
@@ -707,6 +721,12 @@
 }
 
 float
+RegionLayer::getValueForY(View *v, int y) const
+{
+    return getValueForY(v, y, -1);
+}
+
+float
 RegionLayer::getValueForY(View *v, int y, int avoid) const
 {
     float min = 0.0, max = 0.0;
@@ -740,7 +760,7 @@
         int dist = iy - y;
         int gap = h / n; // between region lines
 
-//        std::cerr << "getValueForY: y = " << y << ", vh = " << vh << ", ivh = " << ivh << " of " << n << ", iy = " << iy << ", dist = " << dist << ", gap = " << gap << std::endl;
+//        cerr << "getValueForY: y = " << y << ", vh = " << vh << ", ivh = " << ivh << " of " << n << ", iy = " << iy << ", dist = " << dist << ", gap = " << gap << endl;
 
         SpacingMap::const_iterator i = m_spacingMap.begin();
         while (i != m_spacingMap.end()) {
@@ -749,11 +769,11 @@
         }
         if (i == m_spacingMap.end()) i = m_spacingMap.begin();
 
-//        std::cerr << "nearest existing value = " << i->first << " at " << iy << std::endl;
+//        cerr << "nearest existing value = " << i->first << " at " << iy << endl;
 
         float val = 0;
 
-//        std::cerr << "note: avoid = " << avoid << ", i->second = " << i->second << std::endl;
+//        cerr << "note: avoid = " << avoid << ", i->second = " << i->second << endl;
 
         if (dist < -gap/3 &&
             ((avoid == -1) ||
@@ -761,12 +781,12 @@
             // bisect gap to prior
             if (i == m_spacingMap.begin()) {
                 val = i->first - 1.f;
-//                std::cerr << "extended down to " << val << std::endl;
+//                cerr << "extended down to " << val << endl;
             } else {
                 SpacingMap::const_iterator j = i;
                 --j;
                 val = (i->first + j->first) / 2;
-//                std::cerr << "bisected down to " << val << std::endl;
+//                cerr << "bisected down to " << val << endl;
             }
         } else if (dist > gap/3 &&
                    ((avoid == -1) ||
@@ -776,15 +796,15 @@
             ++j;
             if (j == m_spacingMap.end()) {
                 val = i->first + 1.f;
-//                std::cerr << "extended up to " << val << std::endl;
+//                cerr << "extended up to " << val << endl;
             } else {
                 val = (i->first + j->first) / 2;
-//                std::cerr << "bisected up to " << val << std::endl;
+//                cerr << "bisected up to " << val << endl;
             }
         } else {
             // snap
             val = i->first;
-//            std::cerr << "snapped to " << val << std::endl;
+//            cerr << "snapped to " << val << endl;
         }            
 
         return val;
@@ -947,7 +967,7 @@
                 paint.setPen(v->getForeground());
                 paint.setBrush(v->getForeground());
 
-                QString vlabel = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits());
+                QString vlabel = QString("%1%2").arg(p.value).arg(getScaleUnits());
                 v->drawVisibleText(paint, 
                                    x - paint.fontMetrics().width(vlabel) - 2,
                                    y + paint.fontMetrics().height()/2
@@ -996,7 +1016,7 @@
         if (!illuminated) {
             QString label = p.label;
             if (label == "") {
-                label = QString("%1%2").arg(p.value).arg(m_model->getScaleUnits());
+                label = QString("%1%2").arg(p.value).arg(getScaleUnits());
             }
 
             int labelX, labelY;
@@ -1024,6 +1044,72 @@
     paint.restore();
 }
 
+int
+RegionLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const
+{
+    if (!m_model || 
+        m_verticalScale == AutoAlignScale || 
+        m_verticalScale == EqualSpaced) {
+        return 0;
+    } else if (m_plotStyle == PlotSegmentation) {
+        if (m_verticalScale == LogScale) {
+            return LogColourScale().getWidth(v, paint);
+        } else {
+            return LinearColourScale().getWidth(v, paint);
+        }
+    } else {
+        if (m_verticalScale == LogScale) {
+            return LogNumericalScale().getWidth(v, paint);
+        } else {
+            return LinearNumericalScale().getWidth(v, paint);
+        }
+    }
+}
+
+void
+RegionLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const
+{
+    if (!m_model) return;
+
+    QString unit;
+    float min, max;
+    bool logarithmic;
+
+    int w = getVerticalScaleWidth(v, false, paint);
+    int h = v->height();
+
+    if (m_plotStyle == PlotSegmentation) {
+
+        getValueExtents(min, max, logarithmic, unit);
+
+        if (logarithmic) {
+            LogRange::mapRange(min, max);
+            LogColourScale().paintVertical(v, this, paint, 0, min, max);
+        } else {
+            LinearColourScale().paintVertical(v, this, paint, 0, min, max);
+        }
+
+    } else {
+
+        getScaleExtents(v, min, max, logarithmic);
+
+        if (logarithmic) {
+            LogNumericalScale().paintVertical(v, this, paint, 0, min, max);
+        } else {
+            LinearNumericalScale().paintVertical(v, this, paint, 0, min, max);
+        }
+    }
+        
+    if (getScaleUnits() != "") {
+        int mw = w - 5;
+        paint.drawText(5,
+                       5 + paint.fontMetrics().ascent(),
+                       TextAbbrev::abbreviate(getScaleUnits(),
+                                              paint.fontMetrics(),
+                                              mw));
+    }
+}
+
 void
 RegionLayer::drawStart(View *v, QMouseEvent *e)
 {
@@ -1234,7 +1320,7 @@
          ItemEditDialog::ShowDuration |
          ItemEditDialog::ShowValue |
          ItemEditDialog::ShowText,
-         m_model->getScaleUnits());
+         getScaleUnits());
 
     dialog->setFrameTime(region.frame);
     dialog->setValue(region.value);
--- a/layer/RegionLayer.h	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/RegionLayer.h	Thu Dec 05 09:47:02 2013 +0000
@@ -17,6 +17,9 @@
 #define _REGION_LAYER_H_
 
 #include "SingleColourLayer.h"
+#include "VerticalScaleLayer.h"
+#include "ColourScaleLayer.h"
+
 #include "data/model/RegionModel.h"
 
 #include <QObject>
@@ -27,7 +30,9 @@
 class View;
 class QPainter;
 
-class RegionLayer : public SingleColourLayer
+class RegionLayer : public SingleColourLayer,
+                    public VerticalScaleLayer,
+                    public ColourScaleLayer
 {
     Q_OBJECT
 
@@ -36,6 +41,9 @@
 
     virtual void paint(View *v, QPainter &paint, QRect rect) const;
 
+    virtual int getVerticalScaleWidth(View *v, bool, QPainter &) const;
+    virtual void paintVerticalScale(View *v, bool, QPainter &paint, QRect rect) const;
+
     virtual QString getFeatureDescription(View *v, QPoint &) const;
     virtual QString getLabelPreceding(size_t) const;
 
@@ -116,18 +124,20 @@
     virtual void toXml(QTextStream &stream, QString indent = "",
                        QString extraAttributes = "") const;
 
-    virtual int getVerticalScaleWidth(View *, bool, QPainter &) const { return 0; }
+    void setProperties(const QXmlAttributes &attributes);
 
-    void setProperties(const QXmlAttributes &attributes);
+    /// VerticalScaleLayer and ColourScaleLayer methods
+    int getYForValue(View *v, float value) const;
+    float getValueForY(View *v, int y) const;
+    virtual QString getScaleUnits() const;
+    QColor getColourForValue(View *v, float value) const;
 
 protected slots:
     void recalcSpacing();
 
 protected:
+    float getValueForY(View *v, int y, int avoid) const;
     void getScaleExtents(View *, float &min, float &max, bool &log) const;
-    int getYForValue(View *v, float value) const;
-    float getValueForY(View *v, int y, int avoid = -1) const;
-    QColor getColourForValue(View *v, float value) const;
 
     virtual int getDefaultColourHint(bool dark, bool &impose);
 
--- a/layer/SingleColourLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/SingleColourLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -161,11 +161,11 @@
         // a virtual function
         hint = getDefaultColourHint(dark, impose);
 #ifdef DEBUG_COLOUR_SELECTION
-        std::cerr << "hint = " << hint << ", impose = " << impose << std::endl;
+        cerr << "hint = " << hint << ", impose = " << impose << endl;
 #endif
     } else {
 #ifdef DEBUG_COLOUR_SELECTION
-        std::cerr << "(from ctor)" << std::endl;
+        cerr << "(from ctor)" << endl;
 #endif
     }
 
@@ -188,19 +188,19 @@
         }
 
 #ifdef DEBUG_COLOUR_SELECTION
-        std::cerr << "index = " << index << ", count = " << count;
+        cerr << "index = " << index << ", count = " << count;
 #endif
 
         if (bestColour < 0 || count < bestCount) {
             bestColour = index;
             bestCount = count;
 #ifdef DEBUG_COLOUR_SELECTION
-            std::cerr << " *";
+            cerr << " *";
 #endif
         }
 
 #ifdef DEBUG_COLOUR_SELECTION
-        std::cerr << std::endl;
+        cerr << endl;
 #endif
     }
     
--- a/layer/SliceLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/SliceLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -57,8 +57,8 @@
         dynamic_cast<const DenseThreeDimensionalModel *>(model);
 
     if (model && !sliceable) {
-        std::cerr << "WARNING: SliceLayer::setSliceableModel(" << model
-                  << "): model is not a DenseThreeDimensionalModel" << std::endl;
+        cerr << "WARNING: SliceLayer::setSliceableModel(" << model
+                  << "): model is not a DenseThreeDimensionalModel" << endl;
     }
 
     if (m_sliceableModel == sliceable) return;
@@ -360,7 +360,7 @@
     size_t f1 = v->getFrameForX(f0x + 1);
     if (f1 > f0) --f1;
 
-//    std::cerr << "centre frame " << v->getCentreFrame() << ", x " << f0x << ", f0 " << f0 << ", f1 " << f1 << std::endl;
+//    cerr << "centre frame " << v->getCentreFrame() << ", x " << f0x << ", f0 " << f0 << ", f1 " << f1 << endl;
 
     size_t res = m_sliceableModel->getResolution();
     size_t col0 = f0 / res;
@@ -369,7 +369,7 @@
     f0 = col0 * res;
     f1 = (col1 + 1) * res - 1;
 
-//    std::cerr << "resolution " << res << ", col0 " << col0 << ", col1 " << col1 << ", f0 " << f0 << ", f1 " << f1 << std::endl;
+//    cerr << "resolution " << res << ", col0 " << col0 << ", col1 " << col1 << ", f0 " << f0 << ", f1 " << f1 << endl;
 
     m_currentf0 = f0;
     m_currentf1 = f1;
@@ -622,7 +622,7 @@
 	*max = 50;
         *deflt = 0;
 
-        std::cerr << "gain is " << m_gain << ", mode is " << m_samplingMode << std::endl;
+        cerr << "gain is " << m_gain << ", mode is " << m_samplingMode << endl;
 
 	val = lrint(log10(m_gain) * 20.0);
 	if (val < *min) val = *min;
--- a/layer/SpectrogramLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/SpectrogramLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -27,6 +27,7 @@
 #include "ColourMapper.h"
 #include "ImageRegionFinder.h"
 #include "data/model/Dense3DModelPeakCache.h"
+#include "PianoScale.h"
 
 #include <QPainter>
 #include <QImage>
@@ -40,8 +41,8 @@
 
 #include <iostream>
 
-using std::cerr;
-using std::endl;
+
+
 #include <cassert>
 #include <cmath>
 
@@ -127,7 +128,7 @@
 void
 SpectrogramLayer::setModel(const DenseTimeValueModel *model)
 {
-//    std::cerr << "SpectrogramLayer(" << this << "): setModel(" << model << ")" << std::endl;
+//    cerr << "SpectrogramLayer(" << this << "): setModel(" << model << ")" << endl;
 
     if (model == m_model) return;
 
@@ -584,16 +585,16 @@
                   << v->getStartFrame() << ", " << v->getEndFrame()
                   << endl;
 
-        std::cerr << "Valid area was: " << i->second.validArea.x() << ", "
+        cerr << "Valid area was: " << i->second.validArea.x() << ", "
                   << i->second.validArea.y() << " "
                   << i->second.validArea.width() << "x"
-                  << i->second.validArea.height() << std::endl;
+                  << i->second.validArea.height() << endl;
 #endif
 
         if (long(startFrame) > v->getStartFrame()) {
             if (startFrame >= v->getEndFrame()) {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-                std::cerr << "Modified start frame is off right of view" << std::endl;
+                cerr << "Modified start frame is off right of view" << endl;
 #endif
                 return;
             }
@@ -610,7 +611,7 @@
         } else {
             if (long(endFrame) < v->getStartFrame()) {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-                std::cerr << "Modified end frame is off left of view" << std::endl;
+                cerr << "Modified end frame is off left of view" << endl;
 #endif
                 return;
             }
@@ -628,10 +629,10 @@
         }
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-        std::cerr << "Valid area is now: " << i->second.validArea.x() << ", "
+        cerr << "Valid area is now: " << i->second.validArea.x() << ", "
                   << i->second.validArea.y() << " "
                   << i->second.validArea.width() << "x"
-                  << i->second.validArea.height() << std::endl;
+                  << i->second.validArea.height() << endl;
 #endif
     }
 }
@@ -1067,7 +1068,7 @@
             if (fill >= lastFill) {
                 if (fill >= m_model->getEndFrame() && lastFill > 0) {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-                    std::cerr << "complete!" << std::endl;
+                    cerr << "complete!" << endl;
 #endif
                     invalidateImageCaches();
                     i->second.second = -1;
@@ -1075,8 +1076,8 @@
 
                 } else if (fill > lastFill) {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-                    std::cerr << "SpectrogramLayer: emitting modelChanged("
-                              << lastFill << "," << fill << ")" << std::endl;
+                    cerr << "SpectrogramLayer: emitting modelChanged("
+                              << lastFill << "," << fill << ")" << endl;
 #endif
                     invalidateImageCaches(lastFill, fill);
                     i->second.second = fill;
@@ -1084,8 +1085,8 @@
                 }
             } else {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-                std::cerr << "SpectrogramLayer: going backwards, emitting modelChanged("
-                          << m_model->getStartFrame() << "," << m_model->getEndFrame() << ")" << std::endl;
+                cerr << "SpectrogramLayer: going backwards, emitting modelChanged("
+                          << m_model->getStartFrame() << "," << m_model->getEndFrame() << ")" << endl;
 #endif
                 invalidateImageCaches();
                 i->second.second = fill;
@@ -1100,7 +1101,7 @@
 
     if (allDone) {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-        std::cerr << "SpectrogramLayer: all complete!" << std::endl;
+        cerr << "SpectrogramLayer: all complete!" << endl;
 #endif
         delete m_updateTimer;
         m_updateTimer = 0;
@@ -1674,7 +1675,7 @@
 
         if (!m_sliceableModel) {
 #ifdef DEBUG_SPECTROGRAM
-            std::cerr << "SpectrogramLayer: emitting sliceableModelReplaced(0, " << model << ")" << std::endl;
+            cerr << "SpectrogramLayer: emitting sliceableModelReplaced(0, " << model << ")" << endl;
 #endif
             ((SpectrogramLayer *)this)->sliceableModelReplaced(0, model);
             m_sliceableModel = model;
@@ -1730,7 +1731,7 @@
     m_peakCaches.clear();
 
     if (m_sliceableModel) {
-        std::cerr << "SpectrogramLayer: emitting sliceableModelReplaced(" << m_sliceableModel << ", 0)" << std::endl;
+        cerr << "SpectrogramLayer: emitting sliceableModelReplaced(" << m_sliceableModel << ", 0)" << endl;
         emit sliceableModelReplaced(m_sliceableModel, 0);
         m_sliceableModel = 0;
     }
@@ -1805,7 +1806,7 @@
 #ifdef DEBUG_SPECTROGRAM_REPAINT
     SVDEBUG << "SpectrogramLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", m_updateTimer " << m_updateTimer << endl;
     
-    std::cerr << "rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << std::endl;
+    cerr << "rect is " << rect.x() << "," << rect.y() << " " << rect.width() << "x" << rect.height() << endl;
 #endif
 
     long startFrame = v->getStartFrame();
@@ -1831,7 +1832,7 @@
 /*
     FFTModel *fft = getFFTModel(v);
     if (!fft) {
-	std::cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << std::endl;
+	cerr << "ERROR: SpectrogramLayer::paint(): No FFT model, returning" << endl;
 	return;
     }
 */
@@ -1859,7 +1860,7 @@
     x1 = rect.right() + 1;
 /*
     float xPixelRatio = float(fft->getResolution()) / float(zoomLevel);
-    std::cerr << "xPixelRatio = " << xPixelRatio << std::endl;
+    cerr << "xPixelRatio = " << xPixelRatio << endl;
     if (xPixelRatio < 1.f) xPixelRatio = 1.f;
 */
     if (cache.validArea.width() > 0) {
@@ -1877,7 +1878,7 @@
                 cache.validArea.x() + cache.validArea.width() >= x1) {
 	    
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-		std::cerr << "SpectrogramLayer: image cache good" << std::endl;
+		cerr << "SpectrogramLayer: image cache good" << endl;
 #endif
 
 		paint.drawImage(rect, cache.image, rect);
@@ -1891,7 +1892,7 @@
 	    } else {
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-		std::cerr << "SpectrogramLayer: image cache partially OK" << std::endl;
+		cerr << "SpectrogramLayer: image cache partially OK" << endl;
 #endif
 
 		recreateWholeImageCache = false;
@@ -1900,7 +1901,7 @@
 		         v->getXForFrame(startFrame);
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-		std::cerr << "SpectrogramLayer: dx = " << dx << " (image cache " << cw << "x" << ch << ")" << std::endl;
+		cerr << "SpectrogramLayer: dx = " << dx << " (image cache " << cw << "x" << ch << ")" << endl;
 #endif
 
 		if (dx != 0 &&
@@ -1946,10 +1947,10 @@
                               pw, cache.validArea.height());
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-                    std::cerr << "valid area now "
+                    cerr << "valid area now "
                               << px << "," << cache.validArea.y()
                               << " " << pw << "x" << cache.validArea.height()
-                              << std::endl;
+                              << endl;
 #endif
 /*
 		    paint.drawImage(rect & cache.validArea,
@@ -1961,7 +1962,7 @@
                     // we scrolled too far to be of use
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-                    std::cerr << "dx == " << dx << ": scrolled too far for cache to be useful" << std::endl;
+                    cerr << "dx == " << dx << ": scrolled too far for cache to be useful" << endl;
 #endif
 
                     cache.validArea = QRect();
@@ -1970,17 +1971,17 @@
 	    }
 	} else {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-	    std::cerr << "SpectrogramLayer: image cache useless" << std::endl;
+	    cerr << "SpectrogramLayer: image cache useless" << endl;
             if (int(cache.zoomLevel) != zoomLevel) {
-                std::cerr << "(cache zoomLevel " << cache.zoomLevel
-                          << " != " << zoomLevel << ")" << std::endl;
+                cerr << "(cache zoomLevel " << cache.zoomLevel
+                          << " != " << zoomLevel << ")" << endl;
             }
             if (cw != v->width()) {
-                std::cerr << "(cache width " << cw
+                cerr << "(cache width " << cw
                           << " != " << v->width();
             }
             if (ch != v->height()) {
-                std::cerr << "(cache height " << ch
+                cerr << "(cache height " << ch
                           << " != " << v->height();
             }
 #endif
@@ -1991,7 +1992,7 @@
 
     if (updateViewMagnitudes(v)) {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-        std::cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl;
+        cerr << "SpectrogramLayer: magnitude range changed to [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl;
 #endif
         if (m_normalizeVisibleArea) {
             cache.validArea = QRect();
@@ -1999,7 +2000,7 @@
         }
     } else {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-        std::cerr << "No change in magnitude range [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl;
+        cerr << "No change in magnitude range [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl;
 #endif
     }
 
@@ -2040,7 +2041,7 @@
     }
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-    std::cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << std::endl;
+    cerr << "[" << this << "]: last paint width: " << m_lastPaintBlockWidth << ", last paint time: " << m_lastPaintTime << ", new paint width: " << paintBlockWidth << endl;
 #endif
 
     // We always paint the full height when refreshing the cache.
@@ -2065,7 +2066,7 @@
         vx1 = cache.validArea.x() + cache.validArea.width();
         
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-        std::cerr << "x0 " << x0 << ", x1 " << x1 << ", vx0 " << vx0 << ", vx1 " << vx1 << ", paintBlockWidth " << paintBlockWidth << std::endl;
+        cerr << "x0 " << x0 << ", x1 " << x1 << ", vx0 " << vx0 << ", vx1 " << vx1 << ", paintBlockWidth " << paintBlockWidth << endl;
 #endif         
         if (x0 < vx0) {
             if (x0 + paintBlockWidth < vx0) {
@@ -2096,10 +2097,10 @@
              cache.validArea.height());
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-        std::cerr << "Valid area becomes " << cache.validArea.x()
+        cerr << "Valid area becomes " << cache.validArea.x()
                   << ", " << cache.validArea.y() << ", "
                   << cache.validArea.width() << "x"
-                  << cache.validArea.height() << std::endl;
+                  << cache.validArea.height() << endl;
 #endif
             
     } else {
@@ -2116,8 +2117,8 @@
             }
         }
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-        std::cerr << "Valid area becomes " << x0 << ", 0, " << (x1-x0)
-                  << "x" << h << std::endl;
+        cerr << "Valid area becomes " << x0 << ", 0, " << (x1-x0)
+                  << "x" << h << endl;
 #endif
         cache.validArea = QRect(x0, 0, x1 - x0, h);
     }
@@ -2131,7 +2132,7 @@
     int w = x1 - x0;
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-    std::cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << std::endl;
+    cerr << "x0 " << x0 << ", x1 " << x1 << ", w " << w << ", h " << h << endl;
 #endif
 
     int sr = m_model->getSampleRate();
@@ -2156,7 +2157,7 @@
     size_t minbin = 1;
     if (m_minFrequency > 0) {
 	minbin = int((double(m_minFrequency) * m_fftSize) / sr + 0.001);
-//        std::cerr << "m_minFrequency = " << m_minFrequency << " -> minbin = " << minbin << std::endl;
+//        cerr << "m_minFrequency = " << m_minFrequency << " -> minbin = " << minbin << endl;
 	if (minbin < 1) minbin = 1;
 	if (minbin >= maxbin) minbin = maxbin - 1;
     }
@@ -2176,7 +2177,7 @@
         displayMaxFreq = getEffectiveMaxFrequency();
     }
 
-//    std::cerr << "(giving actual minFreq " << minFreq << " and display minFreq " << displayMinFreq << ")" << std::endl;
+//    cerr << "(giving actual minFreq " << minFreq << " and display minFreq " << displayMinFreq << ")" << endl;
 
     int increment = getWindowIncrement();
     
@@ -2197,7 +2198,7 @@
     bool fftSuspended = false;
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-    std::cerr << ((float(v->getFrameForX(1) - v->getFrameForX(0))) / increment) << " bin(s) per pixel" << std::endl;
+    cerr << ((float(v->getFrameForX(1) - v->getFrameForX(0))) / increment) << " bin(s) per pixel" << endl;
 #endif
 
     bool runOutOfData = false;
@@ -2337,24 +2338,24 @@
 
         if (runOutOfData) {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-            std::cerr << "Run out of data -- dropping out of loop" << std::endl;
+            cerr << "Run out of data -- dropping out of loop" << endl;
 #endif
             break;
         }
     }
 */
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-//    std::cerr << pixels << " pixels drawn" << std::endl;
+//    cerr << pixels << " pixels drawn" << endl;
 #endif
 
     if (overallMagChanged) {
         m_viewMags[v] = overallMag;
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-        std::cerr << "Overall mag is now [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "] - will be updating" << std::endl;
+        cerr << "Overall mag is now [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "] - will be updating" << endl;
 #endif
     } else {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-        std::cerr << "Overall mag unchanged at [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << std::endl;
+        cerr << "Overall mag unchanged at [" << m_viewMags[v].getMin() << "->" << m_viewMags[v].getMax() << "]" << endl;
 #endif
     }
 
@@ -2464,7 +2465,7 @@
             }
         } else {
             // overallMagChanged
-            std::cerr << "\noverallMagChanged - updating all\n" << std::endl;
+            cerr << "\noverallMagChanged - updating all\n" << endl;
             cache.validArea = QRect();
             v->update();
         }
@@ -2540,7 +2541,7 @@
             if (!m_synchronous) {
                 if (!fft->isColumnAvailable(sx)) {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-                    std::cerr << "Met unavailable column at col " << sx << std::endl;
+                    cerr << "Met unavailable column at col " << sx << endl;
 #endif
                     return false;
                 }
@@ -2592,10 +2593,10 @@
             if (mag.isSet()) {
                 if (sx >= int(m_columnMags.size())) {
 #ifdef DEBUG_SPECTROGRAM
-                    std::cerr << "INTERNAL ERROR: " << sx << " >= "
+                    cerr << "INTERNAL ERROR: " << sx << " >= "
                               << m_columnMags.size()
                               << " at SpectrogramLayer.cpp::paintDrawBuffer"
-                              << std::endl;
+                              << endl;
 #endif
                 } else {
                     m_columnMags[sx].sample(mag);
@@ -2689,7 +2690,7 @@
         for (int sx = sx0; sx < sx1; ++sx) {
 
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-//            std::cerr << "sx = " << sx << std::endl;
+//            cerr << "sx = " << sx << endl;
 #endif
 
             if (sx < 0 || sx >= int(sourceModel->getWidth())) continue;
@@ -2697,7 +2698,7 @@
             if (!m_synchronous) {
                 if (!sourceModel->isColumnAvailable(sx)) {
 #ifdef DEBUG_SPECTROGRAM_REPAINT
-                    std::cerr << "Met unavailable column at col " << sx << std::endl;
+                    cerr << "Met unavailable column at col " << sx << endl;
 #endif
                     return false;
                 }
@@ -2805,10 +2806,10 @@
             if (mag.isSet()) {
                 if (sx >= int(m_columnMags.size())) {
 #ifdef DEBUG_SPECTROGRAM
-                    std::cerr << "INTERNAL ERROR: " << sx << " >= "
+                    cerr << "INTERNAL ERROR: " << sx << " >= "
                               << m_columnMags.size()
                               << " at SpectrogramLayer.cpp::paintDrawBuffer"
-                              << std::endl;
+                              << endl;
 #endif
                 } else {
                     m_columnMags[sx].sample(mag);
@@ -2846,8 +2847,8 @@
         return;
     }
 
-//    std::cerr << "SpectrogramLayer: illuminateLocalFeatures("
-//              << localPos.x() << "," << localPos.y() << ")" << std::endl;
+//    cerr << "SpectrogramLayer: illuminateLocalFeatures("
+//              << localPos.x() << "," << localPos.y() << ")" << endl;
 
     float s0, s1;
     float f0, f1;
@@ -2864,8 +2865,8 @@
         int y1 = int(getYForFrequency(v, f1));
         int y0 = int(getYForFrequency(v, f0));
         
-//        std::cerr << "SpectrogramLayer: illuminate "
-//                  << x0 << "," << y1 << " -> " << x1 << "," << y0 << std::endl;
+//        cerr << "SpectrogramLayer: illuminate "
+//                  << x0 << "," << y1 << " -> " << x1 << "," << y0 << endl;
         
         paint.setPen(v->getForeground());
 
@@ -3006,8 +3007,8 @@
 {
     ImageCache &cache = m_imageCaches[v];
 
-    std::cerr << "cache width: " << cache.image.width() << ", height: "
-              << cache.image.height() << std::endl;
+    cerr << "cache width: " << cache.image.width() << ", height: "
+              << cache.image.height() << endl;
 
     QImage image = cache.image;
 
@@ -3435,58 +3436,9 @@
 
         // piano keyboard
 
-	paint.drawLine(w - pkw - 1, 0, w - pkw - 1, h);
-
-	float minf = getEffectiveMinFrequency();
-	float maxf = getEffectiveMaxFrequency();
-
-	int py = h, ppy = h;
-	paint.setBrush(paint.pen().color());
-
-	for (int i = 0; i < 128; ++i) {
-
-	    float f = Pitch::getFrequencyForPitch(i);
-	    int y = lrintf(v->getYForFrequency(f, minf, maxf, true));
-
-            if (y < -2) break;
-            if (y > h + 2) {
-                continue;
-            }
-
-	    int n = (i % 12);
-
-            if (n == 1) {
-                // C# -- fill the C from here
-                QColor col = Qt::gray;
-                if (i == 61) { // filling middle C
-                    col = Qt::blue;
-                    col = col.light(150);
-                }
-                if (ppy - y > 2) {
-                    paint.fillRect(w - pkw,
-                                   y,
-                                   pkw,
-                                   (py + ppy) / 2 - y,
-                                   col);
-                }
-            }
-
-	    if (n == 1 || n == 3 || n == 6 || n == 8 || n == 10) {
-		// black notes
-		paint.drawLine(w - pkw, y, w, y);
-		int rh = ((py - y) / 4) * 2;
-		if (rh < 2) rh = 2;
-		paint.drawRect(w - pkw, y - (py-y)/4, pkw/2, rh);
-	    } else if (n == 0 || n == 5) {
-		// C, F
-		if (py < h) {
-		    paint.drawLine(w - pkw, (y + py) / 2, w, (y + py) / 2);
-		}
-	    }
-
-            ppy = py;
-	    py = y;
-	}
+        PianoScale().paintPianoVertical
+            (v, paint, QRect(w - pkw - 1, 0, pkw, h),
+             getEffectiveMinFrequency(), getEffectiveMaxFrequency());
     }
 
     m_haveDetailedScale = detailed;
@@ -3584,7 +3536,7 @@
     float dmin = m_minFrequency, dmax = m_maxFrequency;
 //    getDisplayExtents(dmin, dmax);
 
-//    std::cerr << "current range " << dmin << " -> " << dmax << ", range " << dmax-dmin << ", mid " << (dmax + dmin)/2 << std::endl;
+//    cerr << "current range " << dmin << " -> " << dmax << ", range " << dmax-dmin << ", mid " << (dmax + dmin)/2 << endl;
     
     int sr = m_model->getSampleRate();
     SpectrogramRangeMapper mapper(sr, m_fftSize);
@@ -3618,7 +3570,7 @@
         newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2;
         newmin = newmax - newdist;
 
-//        std::cerr << "newmin = " << newmin << ", newmax = " << newmax << std::endl;
+//        cerr << "newmin = " << newmin << ", newmax = " << newmax << endl;
 
     } else {
         float dmid = (dmax + dmin) / 2;
--- a/layer/SpectrumLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/SpectrumLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -717,7 +717,7 @@
 
             size_t bin = i->first;
             
-//            std::cerr << "bin = " << bin << ", thresh = " << thresh << ", value = " << fft->getMagnitudeAt(col, bin) << std::endl;
+//            cerr << "bin = " << bin << ", thresh = " << thresh << ", value = " << fft->getMagnitudeAt(col, bin) << endl;
 
             if (!fft->isOverThreshold(col, bin, thresh)) continue;
             
--- a/layer/TimeInstantLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/TimeInstantLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -60,7 +60,7 @@
     connectSignals(m_model);
 
 #ifdef DEBUG_TIME_INSTANT_LAYER
-    std::cerr << "TimeInstantLayer::setModel(" << model << ")" << std::endl;
+    cerr << "TimeInstantLayer::setModel(" << model << ")" << endl;
 #endif
 
     if (m_model && m_model->getRDFTypeURI().endsWith("Segment")) {
@@ -469,7 +469,7 @@
 TimeInstantLayer::drawStart(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_INSTANT_LAYER
-    std::cerr << "TimeInstantLayer::drawStart(" << e->x() << ")" << std::endl;
+    cerr << "TimeInstantLayer::drawStart(" << e->x() << ")" << endl;
 #endif
 
     if (!m_model) return;
@@ -492,7 +492,7 @@
 TimeInstantLayer::drawDrag(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_INSTANT_LAYER
-    std::cerr << "TimeInstantLayer::drawDrag(" << e->x() << ")" << std::endl;
+    cerr << "TimeInstantLayer::drawDrag(" << e->x() << ")" << endl;
 #endif
 
     if (!m_model || !m_editing) return;
@@ -509,7 +509,7 @@
 TimeInstantLayer::drawEnd(View *, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_INSTANT_LAYER
-    std::cerr << "TimeInstantLayer::drawEnd(" << e->x() << ")" << std::endl;
+    cerr << "TimeInstantLayer::drawEnd(" << e->x() << ")" << endl;
 #endif
     if (!m_model || !m_editing) return;
     QString newName = tr("Add Point at %1 s")
@@ -570,7 +570,7 @@
 TimeInstantLayer::editStart(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_INSTANT_LAYER
-    std::cerr << "TimeInstantLayer::editStart(" << e->x() << ")" << std::endl;
+    cerr << "TimeInstantLayer::editStart(" << e->x() << ")" << endl;
 #endif
 
     if (!m_model) return;
@@ -592,7 +592,7 @@
 TimeInstantLayer::editDrag(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_INSTANT_LAYER
-    std::cerr << "TimeInstantLayer::editDrag(" << e->x() << ")" << std::endl;
+    cerr << "TimeInstantLayer::editDrag(" << e->x() << ")" << endl;
 #endif
 
     if (!m_model || !m_editing) return;
@@ -615,7 +615,7 @@
 TimeInstantLayer::editEnd(View *, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_INSTANT_LAYER
-    std::cerr << "TimeInstantLayer::editEnd(" << e->x() << ")" << std::endl;
+    cerr << "TimeInstantLayer::editEnd(" << e->x() << ")" << endl;
 #endif
     if (!m_model || !m_editing) return;
     if (m_editingCommand) {
--- a/layer/TimeRulerLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/TimeRulerLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -29,8 +29,8 @@
 
 //#define DEBUG_TIME_RULER_LAYER 1
 
-using std::cerr;
-using std::endl;
+
+
 
 TimeRulerLayer::TimeRulerLayer() :
     SingleColourLayer(),
@@ -207,7 +207,7 @@
     long startFrame = v->getFrameForX(rect.x() - 50);
 
 #ifdef DEBUG_TIME_RULER_LAYER
-    std::cerr << "start frame = " << startFrame << std::endl;
+    cerr << "start frame = " << startFrame << endl;
 #endif
 
     bool quarter = false;
@@ -217,7 +217,7 @@
     ms = (ms / incms) * incms - incms;
 
 #ifdef DEBUG_TIME_RULER_LAYER
-    std::cerr << "start ms = " << ms << " at step " << incms << std::endl;
+    cerr << "start ms = " << ms << " at step " << incms << endl;
 #endif
 
     // Calculate the number of ticks per increment -- approximate
@@ -257,7 +257,7 @@
 
         if (x >= rect.x() + rect.width() + 50) {
 #ifdef DEBUG_TIME_RULER_LAYER
-            std::cerr << "X well out of range, ending here" << std::endl;
+            cerr << "X well out of range, ending here" << endl;
 #endif
             break;
         }
@@ -267,7 +267,7 @@
             RealTime rt = RealTime::fromMilliseconds(ms);
 
 #ifdef DEBUG_TIME_RULER_LAYER
-            std::cerr << "X in range, drawing line here for time " << rt.toText() << std::endl;
+            cerr << "X in range, drawing line here for time " << rt.toText() << endl;
 #endif
 
             QString text(QString::fromStdString(rt.toText()));
@@ -278,7 +278,7 @@
                 (x < rect.x() - tw/2 ||
                  x >= rect.x() + rect.width() + tw/2)) {
 #ifdef DEBUG_TIME_RULER_LAYER
-                std::cerr << "hm, maybe X isn't in range after all (x = " << x << ", tw = " << tw << ", rect.x() = " << rect.x() << ", rect.width() = " << rect.width() << ")" << std::endl;
+                cerr << "hm, maybe X isn't in range after all (x = " << x << ", tw = " << tw << ", rect.x() = " << rect.x() << ", rect.width() = " << rect.width() << ")" << endl;
 #endif
             }
 
@@ -327,13 +327,13 @@
 
             if (x < rect.x() || x >= rect.x() + rect.width()) {
 #ifdef DEBUG_TIME_RULER_LAYER
-//                std::cerr << "tick " << i << ": X out of range, going on to next tick" << std::endl;
+//                cerr << "tick " << i << ": X out of range, going on to next tick" << endl;
 #endif
                 continue;
             }
 
 #ifdef DEBUG_TIME_RULER_LAYER
-            std::cerr << "tick " << i << " in range, drawing at " << x << std::endl;
+            cerr << "tick " << i << " in range, drawing at " << x << endl;
 #endif
 
 	    int sz = 5;
--- a/layer/TimeValueLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/TimeValueLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -28,8 +28,14 @@
 
 #include "widgets/ItemEditDialog.h"
 #include "widgets/ListInputDialog.h"
+#include "widgets/TextAbbrev.h"
 
 #include "ColourMapper.h"
+#include "PianoScale.h"
+#include "LinearNumericalScale.h"
+#include "LogNumericalScale.h"
+#include "LinearColourScale.h"
+#include "LogColourScale.h"
 
 #include <QPainter>
 #include <QPainterPath>
@@ -81,7 +87,7 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::setModel(" << model << ")" << std::endl;
+    cerr << "TimeValueLayer::setModel(" << model << ")" << endl;
 #endif
 
     emit modelReplaced();
@@ -143,6 +149,13 @@
     return SingleColourLayer::getPropertyGroupName(name);
 }
 
+QString
+TimeValueLayer::getScaleUnits() const
+{
+    if (m_model) return m_model->getScaleUnits();
+    else return "";
+}
+
 int
 TimeValueLayer::getPropertyRangeAndValue(const PropertyName &name,
 					 int *min, int *max, int *deflt) const
@@ -178,7 +191,7 @@
         if (deflt) *deflt = 0;
         if (m_model) {
             val = UnitDatabase::getInstance()->getUnitId
-                (m_model->getScaleUnits());
+                (getScaleUnits());
         }
 
     } else if (name == "Draw Segment Division Lines") {
@@ -326,7 +339,7 @@
 
     logarithmic = (m_verticalScale == LogScale);
 
-    unit = m_model->getScaleUnits();
+    unit = getScaleUnits();
 
     if (m_derivative) {
         max = std::max(fabsf(min), fabsf(max));
@@ -334,7 +347,7 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getValueExtents: min = " << min << ", max = " << max << std::endl;
+    cerr << "TimeValueLayer::getValueExtents: min = " << min << ", max = " << max << endl;
 #endif
 
     if (!shouldAutoAlign() && !logarithmic && !m_derivative) {
@@ -349,7 +362,7 @@
         }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-        std::cerr << "TimeValueLayer::getValueExtents: min = " << min << ", max = " << max << " (after adjustment)" << std::endl;
+        cerr << "TimeValueLayer::getValueExtents: min = " << min << ", max = " << max << " (after adjustment)" << endl;
 #endif
     }
 
@@ -376,7 +389,7 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getDisplayExtents: min = " << min << ", max = " << max << std::endl;
+    cerr << "TimeValueLayer::getDisplayExtents: min = " << min << ", max = " << max << endl;
 #endif
 
     return true;
@@ -399,7 +412,7 @@
     m_scaleMaximum = max;
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::setDisplayExtents: min = " << min << ", max = " << max << std::endl;
+    cerr << "TimeValueLayer::setDisplayExtents: min = " << min << ", max = " << max << endl;
 #endif
     
     emit layerParametersChanged();
@@ -431,7 +444,7 @@
     int nr = mapper->getPositionForValue(dmax - dmin);
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getCurrentVerticalZoomStep: dmin = " << dmin << ", dmax = " << dmax << ", nr = " << nr << std::endl;
+    cerr << "TimeValueLayer::getCurrentVerticalZoomStep: dmin = " << dmin << ", dmax = " << dmax << ", nr = " << nr << endl;
 #endif
 
     delete mapper;
@@ -468,7 +481,7 @@
         newmin = newmax - newdist;
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-        std::cerr << "newmin = " << newmin << ", newmax = " << newmax << std::endl;
+        cerr << "newmin = " << newmin << ", newmax = " << newmax << endl;
 #endif
 
     } else {
@@ -486,7 +499,7 @@
     }
     
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << std::endl;
+    cerr << "TimeValueLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << endl;
 #endif
 
     setDisplayExtents(newmin, newmax);
@@ -594,7 +607,7 @@
     RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
     
     QString text;
-    QString unit = m_model->getScaleUnits();
+    QString unit = getScaleUnits();
     if (unit != "") unit = " " + unit;
 
     if (points.begin()->label == "") {
@@ -769,7 +782,7 @@
 
     if (shouldAutoAlign()) {
 
-        if (!v->getValueExtents(m_model->getScaleUnits(), min, max, log)) {
+        if (!v->getValueExtents(getScaleUnits(), min, max, log)) {
             min = m_model->getValueMinimum();
             max = m_model->getValueMaximum();
         } else if (log) {
@@ -792,7 +805,7 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getScaleExtents: min = " << min << ", max = " << max << std::endl;
+    cerr << "TimeValueLayer::getScaleExtents: min = " << min << ", max = " << max << endl;
 #endif
 }
 
@@ -806,8 +819,8 @@
     getScaleExtents(v, min, max, logarithmic);
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "getYForValue(" << val << "): min " << min << ", max "
-              << max << ", log " << logarithmic << std::endl;
+    cerr << "getYForValue(" << val << "): min " << min << ", max "
+              << max << ", log " << logarithmic << endl;
 #endif
 
     if (logarithmic) {
@@ -839,7 +852,7 @@
 TimeValueLayer::shouldAutoAlign() const
 {
     if (!m_model) return false;
-    QString unit = m_model->getScaleUnits();
+    QString unit = getScaleUnits();
     return (m_verticalScale == AutoAlignScale && unit != "");
 }
 
@@ -858,8 +871,8 @@
     }
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::getColourForValue: min " << min << ", max "
-              << max << ", log " << log << ", value " << val << std::endl;
+    cerr << "TimeValueLayer::getColourForValue: min " << min << ", max "
+              << max << ", log " << log << ", value " << val << endl;
 #endif
 
     QColor solid = ColourMapper(m_colourMap, min, max).map(val);
@@ -902,8 +915,8 @@
     paint.setBrush(brushColour);
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::paint: resolution is "
-	      << m_model->getResolution() << " frames" << std::endl;
+    cerr << "TimeValueLayer::paint: resolution is "
+	      << m_model->getResolution() << " frames" << endl;
 #endif
 
     float min = m_model->getValueMinimum();
@@ -920,7 +933,7 @@
 	SparseTimeValueModel::PointList localPoints =
 	    getLocalPoints(v, localPos.x());
 #ifdef DEBUG_TIME_VALUE_LAYER
-        std::cerr << "TimeValueLayer: " << localPoints.size() << " local points" << std::endl;
+        cerr << "TimeValueLayer: " << localPoints.size() << " local points" << endl;
 #endif
 	if (!localPoints.empty()) illuminateFrame = localPoints.begin()->frame;
     }
@@ -1004,8 +1017,8 @@
 	    haveNext = true;
         }
 
-//        std::cout << "frame = " << p.frame << ", x = " << x << ", haveNext = " << haveNext 
-//                  << ", nx = " << nx << std::endl;
+//        cout << "frame = " << p.frame << ", x = " << x << ", haveNext = " << haveNext 
+//                  << ", nx = " << nx << endl;
 
         if (m_plotStyle == PlotDiscreteCurves) {
             paint.setPen(QPen(getBaseQColor(), 3));
@@ -1132,7 +1145,7 @@
 	if (m_plotStyle == PlotSegmentation) {
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "drawing rect" << std::endl;
+            cerr << "drawing rect" << endl;
 #endif
 	    
 	    if (nx <= x) continue;
@@ -1179,9 +1192,11 @@
         ++pointCount;
     }
 
-    if ((m_plotStyle == PlotCurve || m_plotStyle == PlotDiscreteCurves ||
-         m_plotStyle == PlotLines)
-        && !path.isEmpty()) {
+    if (m_plotStyle == PlotDiscreteCurves) {
+        paint.setRenderHint(QPainter::Antialiasing, true);
+	paint.drawPath(path);
+    } else if ((m_plotStyle == PlotCurve || m_plotStyle == PlotLines)
+               && !path.isEmpty()) {
 	paint.setRenderHint(QPainter::Antialiasing, pointCount <= v->width());
 	paint.drawPath(path);
     }
@@ -1193,11 +1208,23 @@
 }
 
 int
-TimeValueLayer::getVerticalScaleWidth(View *, bool, QPainter &paint) const
+TimeValueLayer::getVerticalScaleWidth(View *v, bool, QPainter &paint) const
 {
-    int w = paint.fontMetrics().width("-000.000");
-    if (m_plotStyle == PlotSegmentation) return w + 20;
-    else return w + 10;
+    if (!m_model || shouldAutoAlign()) {
+        return 0;
+    } else if (m_plotStyle == PlotSegmentation) {
+        if (m_verticalScale == LogScale) {
+            return LogColourScale().getWidth(v, paint);
+        } else {
+            return LinearColourScale().getWidth(v, paint);
+        }
+    } else {
+        if (m_verticalScale == LogScale) {
+            return LogNumericalScale().getWidth(v, paint) + 10; // for piano
+        } else {
+            return LinearNumericalScale().getWidth(v, paint);
+        }
+    }
 }
 
 void
@@ -1205,136 +1232,50 @@
 {
     if (!m_model) return;
 
+    QString unit;
+    float min, max;
+    bool logarithmic;
+
+    int w = getVerticalScaleWidth(v, false, paint);
     int h = v->height();
 
-    int n = 10;
+    if (m_plotStyle == PlotSegmentation) {
 
-    float min, max;
-    bool logarithmic;
-    getScaleExtents(v, min, max, logarithmic);
+        getValueExtents(min, max, logarithmic, unit);
 
-    if (m_plotStyle == PlotSegmentation) {
-        QString unit;
-        getValueExtents(min, max, logarithmic, unit);
         if (logarithmic) {
             LogRange::mapRange(min, max);
+            LogColourScale().paintVertical(v, this, paint, 0, min, max);
+        } else {
+            LinearColourScale().paintVertical(v, this, paint, 0, min, max);
+        }
+
+    } else {
+
+        getScaleExtents(v, min, max, logarithmic);
+
+        if (logarithmic) {
+            LogNumericalScale().paintVertical(v, this, paint, 0, min, max);
+        } else {
+            LinearNumericalScale().paintVertical(v, this, paint, 0, min, max);
+        }
+
+        if (logarithmic && (getScaleUnits() == "Hz")) {
+            PianoScale().paintPianoVertical
+                (v, paint, QRect(w - 10, 0, 10, h), 
+                 LogRange::unmap(min), 
+                 LogRange::unmap(max));
+            paint.drawLine(w, 0, w, h);
         }
     }
-
-    float val = min;
-    float inc = (max - val) / n;
-
-    char buffer[40];
-
-    int w = getVerticalScaleWidth(v, false, paint);
-
-    int tx = 5;
-
-    int boxx = 5, boxy = 5;
-    if (m_model->getScaleUnits() != "") {
-        boxy += paint.fontMetrics().height();
-    }
-    int boxw = 10, boxh = h - boxy - 5;
-
-    if (m_plotStyle == PlotSegmentation) {
-        tx += boxx + boxw;
-        paint.drawRect(boxx, boxy, boxw, boxh);
-    }
-
-    if (m_plotStyle == PlotSegmentation) {
-        paint.save();
-        for (int y = 0; y < boxh; ++y) {
-            float val = ((boxh - y) * (max - min)) / boxh + min;
-            if (logarithmic) {
-                paint.setPen(getColourForValue(v, LogRange::unmap(val)));
-            } else {
-                paint.setPen(getColourForValue(v, val));
-            }
-            paint.drawLine(boxx + 1, y + boxy + 1, boxx + boxw, y + boxy + 1);
-        }
-        paint.restore();
-    }
-    
-    float round = 1.f;
-    int dp = 0;
-    if (inc > 0) {
-        int prec = trunc(log10f(inc));
-        prec -= 1;
-        if (prec < 0) dp = -prec;
-        round = powf(10.f, prec);
-#ifdef DEBUG_TIME_VALUE_LAYER
-        std::cerr << "inc = " << inc << ", round = " << round << ", dp = " << dp << std::endl;
-#endif
-    }
-
-    int prevy = -1;
-                
-    for (int i = 0; i < n; ++i) {
-
-	int y, ty;
-        bool drawText = true;
-
-        float dispval = val;
-
-        if (m_plotStyle == PlotSegmentation) {
-            y = boxy + int(boxh - ((val - min) * boxh) / (max - min));
-            ty = y;
-        } else {
-            if (i == n-1 &&
-                v->height() < paint.fontMetrics().height() * (n*2)) {
-                if (m_model->getScaleUnits() != "") drawText = false;
-            }
-            dispval = lrintf(val / round) * round;
-#ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "val = " << val << ", dispval = " << dispval << std::endl;
-#endif
-            if (logarithmic) {
-                y = getYForValue(v, LogRange::unmap(dispval));
-            } else {
-                y = getYForValue(v, dispval);
-            }                
-            ty = y - paint.fontMetrics().height() +
-                     paint.fontMetrics().ascent() + 2;
-
-            if (prevy >= 0 && (prevy - y) < paint.fontMetrics().height()) {
-                val += inc;
-                continue;
-            }
-        }
-
-        if (logarithmic) {
-            double dv = LogRange::unmap(dispval);
-            int digits = trunc(log10f(dv));
-            int sf = dp + (digits > 0 ? digits : 0);
-            if (sf < 2) sf = 2;
-            sprintf(buffer, "%.*g", sf, dv);
-        } else {
-            sprintf(buffer, "%.*f", dp, dispval);
-        }            
-	QString label = QString(buffer);
-
-        if (m_plotStyle != PlotSegmentation) {
-            paint.drawLine(w - 5, y, w, y);
-        } else {
-            paint.drawLine(boxx + boxw - boxw/3, y, boxx + boxw, y);
-        }
-
-        if (drawText) {
-            if (m_plotStyle != PlotSegmentation) {
-                paint.drawText(tx + w - paint.fontMetrics().width(label) - 8,
-                               ty, label);
-            } else {
-                paint.drawText(tx, ty, label);
-            }
-        }
-
-        prevy = y;
-	val += inc;
-    }
-    
-    if (m_model->getScaleUnits() != "") {
-        paint.drawText(5, 5 + paint.fontMetrics().ascent(),
-                       m_model->getScaleUnits());
+        
+    if (getScaleUnits() != "") {
+        int mw = w - 5;
+        paint.drawText(5,
+                       5 + paint.fontMetrics().ascent(),
+                       TextAbbrev::abbreviate(getScaleUnits(),
+                                              paint.fontMetrics(),
+                                              mw));
     }
 }
 
@@ -1342,7 +1283,7 @@
 TimeValueLayer::drawStart(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::drawStart(" << e->x() << "," << e->y() << ")" << std::endl;
+    cerr << "TimeValueLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl;
 #endif
 
     if (!m_model) return;
@@ -1362,7 +1303,7 @@
              i != points.end(); ++i) {
             if (((i->frame / resolution) * resolution) != frame) {
 #ifdef DEBUG_TIME_VALUE_LAYER
-                std::cerr << "ignoring out-of-range frame at " << i->frame << std::endl;
+                cerr << "ignoring out-of-range frame at " << i->frame << endl;
 #endif
                 continue;
             }
@@ -1392,7 +1333,7 @@
 TimeValueLayer::drawDrag(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::drawDrag(" << e->x() << "," << e->y() << ")" << std::endl;
+    cerr << "TimeValueLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl;
 #endif
 
     if (!m_model || !m_editing) return;
@@ -1407,7 +1348,7 @@
     SparseTimeValueModel::PointList points = getLocalPoints(v, e->x());
 
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << points.size() << " points" << std::endl;
+    cerr << points.size() << " points" << endl;
 #endif
 
     bool havePoint = false;
@@ -1418,18 +1359,18 @@
             if (i->frame == m_editingPoint.frame &&
                 i->value == m_editingPoint.value) {
 #ifdef DEBUG_TIME_VALUE_LAYER
-                std::cerr << "ignoring current editing point at " << i->frame << ", " << i->value << std::endl;
+                cerr << "ignoring current editing point at " << i->frame << ", " << i->value << endl;
 #endif
                 continue;
             }
             if (((i->frame / resolution) * resolution) != frame) {
 #ifdef DEBUG_TIME_VALUE_LAYER
-                std::cerr << "ignoring out-of-range frame at " << i->frame << std::endl;
+                cerr << "ignoring out-of-range frame at " << i->frame << endl;
 #endif
                 continue;
             }
 #ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "adjusting to new point at " << i->frame << ", " << i->value << std::endl;
+            cerr << "adjusting to new point at " << i->frame << ", " << i->value << endl;
 #endif
             m_editingPoint = *i;
             m_originalPoint = m_editingPoint;
@@ -1454,7 +1395,7 @@
 TimeValueLayer::drawEnd(View *, QMouseEvent *)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::drawEnd" << std::endl;
+    cerr << "TimeValueLayer::drawEnd" << endl;
 #endif
     if (!m_model || !m_editing) return;
     finish(m_editingCommand);
@@ -1511,7 +1452,7 @@
 TimeValueLayer::editStart(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl;
+    cerr << "TimeValueLayer::editStart(" << e->x() << "," << e->y() << ")" << endl;
 #endif
 
     if (!m_model) return;
@@ -1534,7 +1475,7 @@
 TimeValueLayer::editDrag(View *v, QMouseEvent *e)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl;
+    cerr << "TimeValueLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl;
 #endif
 
     if (!m_model || !m_editing) return;
@@ -1560,7 +1501,7 @@
 TimeValueLayer::editEnd(View *, QMouseEvent *)
 {
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "TimeValueLayer::editEnd" << std::endl;
+    cerr << "TimeValueLayer::editEnd" << endl;
 #endif
     if (!m_model || !m_editing) return;
 
@@ -1601,7 +1542,7 @@
          ItemEditDialog::ShowTime |
          ItemEditDialog::ShowValue |
          ItemEditDialog::ShowText,
-         m_model->getScaleUnits());
+         getScaleUnits());
 
     dialog->setFrameTime(point.frame);
     dialog->setValue(point.value);
@@ -1900,17 +1841,17 @@
             newPoint.value = i->getValue();
         } else {
 #ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "Setting value on point at " << newPoint.frame << " from labeller";
+            cerr << "Setting value on point at " << newPoint.frame << " from labeller";
             if (i == points.begin()) {
-                std::cerr << ", no prev point" << std::endl;
+                cerr << ", no prev point" << endl;
             } else {
-                std::cerr << ", prev point is at " << prevPoint.frame << std::endl;
+                cerr << ", prev point is at " << prevPoint.frame << endl;
             }
 #endif
             labeller.setValue<SparseTimeValueModel::Point>
                 (newPoint, (i == points.begin()) ? 0 : &prevPoint);
 #ifdef DEBUG_TIME_VALUE_LAYER
-            std::cerr << "New point value = " << newPoint.value << std::endl;
+            cerr << "New point value = " << newPoint.value << endl;
 #endif
             if (labeller.actingOnPrevPoint() && i != points.begin()) {
                 usePrev = true;
@@ -1973,7 +1914,7 @@
     float min = attributes.value("scaleMinimum").toFloat(&ok);
     float max = attributes.value("scaleMaximum").toFloat(&alsoOk);
 #ifdef DEBUG_TIME_VALUE_LAYER
-    std::cerr << "from properties: min = " << min << ", max = " << max << std::endl;
+    cerr << "from properties: min = " << min << ", max = " << max << endl;
 #endif
     if (ok && alsoOk && min != max) setDisplayExtents(min, max);
 }
--- a/layer/TimeValueLayer.h	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/TimeValueLayer.h	Thu Dec 05 09:47:02 2013 +0000
@@ -17,6 +17,9 @@
 #define _TIME_VALUE_LAYER_H_
 
 #include "SingleColourLayer.h"
+#include "VerticalScaleLayer.h"
+#include "ColourScaleLayer.h"
+
 #include "data/model/SparseTimeValueModel.h"
 
 #include <QObject>
@@ -25,7 +28,9 @@
 class View;
 class QPainter;
 
-class TimeValueLayer : public SingleColourLayer
+class TimeValueLayer : public SingleColourLayer, 
+                       public VerticalScaleLayer, 
+                       public ColourScaleLayer
 {
     Q_OBJECT
 
@@ -149,11 +154,14 @@
         }
     }
 
+    /// VerticalScaleLayer and ColourScaleLayer methods
+    virtual int getYForValue(View *, float value) const;
+    virtual float getValueForY(View *, int y) const;
+    virtual QString getScaleUnits() const;
+    virtual QColor getColourForValue(View *v, float value) const;
+
 protected:
     void getScaleExtents(View *, float &min, float &max, bool &log) const;
-    int getYForValue(View *, float value) const;
-    float getValueForY(View *, int y) const;
-    QColor getColourForValue(View *v, float value) const;
     bool shouldAutoAlign() const;
 
     SparseTimeValueModel::PointList getLocalPoints(View *v, int) const;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/layer/VerticalScaleLayer.h	Thu Dec 05 09:47:02 2013 +0000
@@ -0,0 +1,28 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006-2013 Chris Cannam and QMUL.
+    
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License as
+    published by the Free Software Foundation; either version 2 of the
+    License, or (at your option) any later version.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef VERTICAL_SCALE_LAYER_H
+#define VERTICAL_SCALE_LAYER_H
+
+class VerticalScaleLayer
+{
+public:
+    virtual int getYForValue(View *, float value) const = 0;
+    virtual float getValueForY(View *, int y) const = 0;
+    virtual QString getScaleUnits() const = 0;
+};
+
+#endif
+
--- a/layer/WaveformLayer.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/layer/WaveformLayer.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -30,8 +30,8 @@
 
 //#define DEBUG_WAVEFORM_PAINT 1
 
-using std::cerr;
-using std::endl;
+
+
 
 WaveformLayer::WaveformLayer() :
     SingleColourLayer(),
@@ -474,7 +474,7 @@
 
 #ifdef DEBUG_WAVEFORM_PAINT
     Profiler profiler("WaveformLayer::paint", true);
-    std::cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y()
+    cerr << "WaveformLayer::paint (" << rect.x() << "," << rect.y()
 	      << ") [" << rect.width() << "x" << rect.height() << "]: zoom " << zoomLevel << endl;
 #endif
 
@@ -494,7 +494,7 @@
     if (m_aggressive) {
 
 #ifdef DEBUG_WAVEFORM_PAINT
-        std::cerr << "WaveformLayer::paint: aggressive is true" << endl;
+        cerr << "WaveformLayer::paint: aggressive is true" << endl;
 #endif
 
 	if (m_cacheValid && (zoomLevel != m_cacheZoomLevel)) {
@@ -504,7 +504,7 @@
 	if (!m_cache || m_cache->width() != w || m_cache->height() != h) {
 #ifdef DEBUG_WAVEFORM_PAINT
             if (m_cache) {
-                std::cerr << "WaveformLayer::paint: cache size " << m_cache->width() << "x" << m_cache->height() << " differs from view size " << w << "x" << h << ": regenerating aggressive cache" << endl;
+                cerr << "WaveformLayer::paint: cache size " << m_cache->width() << "x" << m_cache->height() << " differs from view size " << w << "x" << h << ": regenerating aggressive cache" << endl;
             }
 #endif
 	    delete m_cache;
@@ -562,7 +562,7 @@
     getSourceFramesForX(v, x1, modelZoomLevel, spare, frame1);
     
 #ifdef DEBUG_WAVEFORM_PAINT
-    std::cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << " and model zoom " << modelZoomLevel << ")" <<  std::endl;
+    cerr << "Painting waveform from " << frame0 << " to " << frame1 << " (" << (x1-x0+1) << " pixels at zoom " << zoomLevel << " and model zoom " << modelZoomLevel << ")" <<  endl;
 #endif
 
     RangeSummarisableTimeValueModel::RangeBlock *ranges = 
@@ -604,7 +604,7 @@
 	int my = m + (((ch - minChannel) * h) / channels);
 
 #ifdef DEBUG_WAVEFORM_PAINT	
-	std::cerr << "ch = " << ch << ", channels = " << channels << ", m = " << m << ", my = " << my << ", h = " << h << std::endl;
+	cerr << "ch = " << ch << ", channels = " << channels << ", m = " << m << ", my = " << my << ", h = " << h << endl;
 #endif
 
 	if (my - m > y1 || my + m < y0) continue;
@@ -670,7 +670,7 @@
                               *ranges, modelZoomLevel);
 
 #ifdef DEBUG_WAVEFORM_PAINT
-        std::cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << modelZoomLevel << std::endl;
+        cerr << "channel " << ch << ": " << ranges->size() << " ranges from " << frame0 << " to " << frame1 << " at zoom level " << modelZoomLevel << endl;
 #endif
 
 	if (mergingChannels || mixingChannels) {
@@ -697,7 +697,7 @@
             f1 = f1 - 1;
 
             if (f0 < frame0) {
-                std::cerr << "ERROR: WaveformLayer::paint: pixel " << x << " has f0 = " << f0 << " which is less than range frame0 " << frame0 << " for x0 = " << x0 << std::endl;
+                cerr << "ERROR: WaveformLayer::paint: pixel " << x << " has f0 = " << f0 << " which is less than range frame0 " << frame0 << " for x0 = " << x0 << endl;
                 continue;
             }
 
@@ -705,11 +705,11 @@
             size_t i1 = (f1 - frame0) / modelZoomLevel;
 
 #ifdef DEBUG_WAVEFORM_PAINT
-            std::cerr << "WaveformLayer::paint: pixel " << x << ": i0 " << i0 << " (f " << f0 << "), i1 " << i1 << " (f " << f1 << ")" << std::endl;
+            cerr << "WaveformLayer::paint: pixel " << x << ": i0 " << i0 << " (f " << f0 << "), i1 " << i1 << " (f " << f1 << ")" << endl;
 #endif
 
             if (i1 > i0 + 1) {
-                std::cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << zoomLevel << ", model zoom = " << modelZoomLevel << ")" << std::endl;
+                cerr << "WaveformLayer::paint: ERROR: i1 " << i1 << " > i0 " << i0 << " plus one (zoom = " << zoomLevel << ", model zoom = " << modelZoomLevel << ")" << endl;
             }
 
 	    if (ranges && i0 < ranges->size()) {
@@ -724,7 +724,7 @@
 
 	    } else {
 #ifdef DEBUG_WAVEFORM_PAINT
-                std::cerr << "No (or not enough) ranges for i0 = " << i0 << std::endl;
+                cerr << "No (or not enough) ranges for i0 = " << i0 << endl;
 #endif
 		continue;
 	    }
@@ -874,7 +874,7 @@
 	    }
 
 #ifdef DEBUG_WAVEFORM_PAINT
-            std::cerr << "range " << rangeBottom << " -> " << rangeTop << ", means " << meanBottom << " -> " << meanTop << ", raw range " << range.min() << " -> " << range.max() << std::endl;
+            cerr << "range " << rangeBottom << " -> " << rangeTop << ", means " << meanBottom << " -> " << meanTop << ", raw range " << range.min() << " -> " << range.max() << endl;
 #endif
 
             if (rangeTop == rangeBottom) {
@@ -1051,7 +1051,7 @@
         break;
     }
 
-//    std::cerr << "mergingChannels= " << mergingChannels << ", channel  = " << channel << ", value = " << value << ", vy = " << vy << std::endl;
+//    cerr << "mergingChannels= " << mergingChannels << ", channel  = " << channel << ", value = " << value << ", vy = " << vy << endl;
 
     return my - vy;
 }
--- a/svgui.pro	Mon Nov 04 17:12:32 2013 +0000
+++ b/svgui.pro	Thu Dec 05 09:47:02 2013 +0000
@@ -30,12 +30,18 @@
 HEADERS += layer/Colour3DPlotLayer.h \
 	   layer/ColourDatabase.h \
 	   layer/ColourMapper.h \
+           layer/ColourScaleLayer.h \
            layer/ImageLayer.h \
            layer/ImageRegionFinder.h \
            layer/Layer.h \
            layer/LayerFactory.h \
+           layer/LinearNumericalScale.h \
+           layer/LogNumericalScale.h \
+           layer/LinearColourScale.h \
+           layer/LogColourScale.h \
            layer/NoteLayer.h \
            layer/PaintAssistant.h \
+           layer/PianoScale.h \
            layer/RegionLayer.h \
            layer/SingleColourLayer.h \
            layer/SliceableLayer.h \
@@ -46,6 +52,7 @@
            layer/TimeInstantLayer.h \
            layer/TimeRulerLayer.h \
            layer/TimeValueLayer.h \
+           layer/VerticalScaleLayer.h \
            layer/WaveformLayer.h
 SOURCES += layer/Colour3DPlotLayer.cpp \
 	   layer/ColourDatabase.cpp \
@@ -54,8 +61,13 @@
            layer/ImageRegionFinder.cpp \
            layer/Layer.cpp \
            layer/LayerFactory.cpp \
+           layer/LinearNumericalScale.cpp \
+           layer/LogNumericalScale.cpp \
+           layer/LinearColourScale.cpp \
+           layer/LogColourScale.cpp \
            layer/NoteLayer.cpp \
            layer/PaintAssistant.cpp \
+           layer/PianoScale.cpp \
            layer/RegionLayer.cpp \
            layer/SingleColourLayer.cpp \
            layer/SliceLayer.cpp \
--- a/view/Overview.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/view/Overview.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -24,8 +24,8 @@
 
 //#define DEBUG_OVERVIEW 1
 
-using std::cerr;
-using std::endl;
+
+
 
 Overview::Overview(QWidget *w) :
     View(w, false),
@@ -95,7 +95,7 @@
 Overview::globalCentreFrameChanged(unsigned long f)
 {
 #ifdef DEBUG_OVERVIEW
-    std::cerr << "Overview::globalCentreFrameChanged: " << f << std::endl;
+    cerr << "Overview::globalCentreFrameChanged: " << f << endl;
 #endif
     update();
 }
@@ -104,7 +104,7 @@
 Overview::viewCentreFrameChanged(View *v, unsigned long f)
 {
 #ifdef DEBUG_OVERVIEW
-    std::cerr << "Overview[" << this << "]::viewCentreFrameChanged(" << v << "): " << f << std::endl;
+    cerr << "Overview[" << this << "]::viewCentreFrameChanged(" << v << "): " << f << endl;
 #endif
     if (m_views.find(v) != m_views.end()) {
 	update();
@@ -124,7 +124,7 @@
 Overview::viewManagerPlaybackFrameChanged(unsigned long f)
 {
 #ifdef DEBUG_OVERVIEW
-    std::cerr << "Overview[" << this << "]::viewManagerPlaybackFrameChanged(" << f << "): " << f << std::endl;
+    cerr << "Overview[" << this << "]::viewManagerPlaybackFrameChanged(" << f << "): " << f << endl;
 #endif
 
     bool changed = false;
@@ -143,7 +143,7 @@
     // Recalculate zoom in case the size of the widget has changed.
 
 #ifdef DEBUG_OVERVIEW
-    std::cerr << "Overview::paintEvent: width is " << width() << ", centre frame " << m_centreFrame << std::endl;
+    cerr << "Overview::paintEvent: width is " << width() << ", centre frame " << m_centreFrame << endl;
 #endif
 
     size_t startFrame = getModelsStartFrame();
@@ -163,12 +163,12 @@
     }
     if (centreFrame != m_centreFrame) {
 #ifdef DEBUG_OVERVIEW
-        std::cerr << "Overview::paintEvent: Centre frame changed from "
+        cerr << "Overview::paintEvent: Centre frame changed from "
                   << m_centreFrame << " to " << centreFrame << " and thus start frame from " << getStartFrame();
 #endif
 	m_centreFrame = centreFrame;
 #ifdef DEBUG_OVERVIEW
-        std::cerr << " to " << getStartFrame() << std::endl;
+        cerr << " to " << getStartFrame() << endl;
 #endif
 	emit centreFrameChanged(m_centreFrame, false, PlaybackIgnore);
     }
@@ -278,7 +278,7 @@
 	std::min(m_centreFrame, newCentreFrame) > size_t(m_zoomLevel)) {
         size_t rf = alignToReference(newCentreFrame);
 #ifdef DEBUG_OVERVIEW
-        std::cerr << "Overview::mouseMoveEvent: x " << e->x() << " and click x " << m_clickPos.x() << " -> frame " << newCentreFrame << " -> rf " << rf << std::endl;
+        cerr << "Overview::mouseMoveEvent: x " << e->x() << " and click x " << m_clickPos.x() << " -> frame " << newCentreFrame << " -> rf " << rf << endl;
 #endif
 	emit centreFrameChanged(rf, true, PlaybackScrollContinuous);
     }
@@ -291,7 +291,7 @@
     size_t rf = 0;
     if (frame > 0) rf = alignToReference(frame);
 #ifdef DEBUG_OVERVIEW
-    std::cerr << "Overview::mouseDoubleClickEvent: frame " << frame << " -> rf " << rf << std::endl;
+    cerr << "Overview::mouseDoubleClickEvent: frame " << frame << " -> rf " << rf << endl;
 #endif
     m_clickedInRange = false; // we're not starting a drag with the second click
     emit centreFrameChanged(rf, true, PlaybackScrollContinuous);
--- a/view/Pane.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/view/Pane.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -53,8 +53,8 @@
 
 //#define DEBUG_PANE
 
-using std::cerr;
-using std::endl;
+
+
 
 QCursor *Pane::m_measureCursor1 = 0;
 QCursor *Pane::m_measureCursor2 = 0;
@@ -110,7 +110,7 @@
         ++count;
     }
 
-    std::cerr << "Have " << count+1 << " zoom levels" << std::endl;
+    cerr << "Have " << count+1 << " zoom levels" << endl;
 */
 
     Layer *layer = 0;
@@ -223,25 +223,25 @@
                 step *= 2;
                 --pwr;
             }
-//            std::cerr << level << std::endl;
+//            cerr << level << endl;
             level += step;
             if (++count == 100 || level > 262144) break;
         }
     }
 
-//    std::cerr << "Have " << count << " zoom levels" << std::endl;
+//    cerr << "Have " << count << " zoom levels" << endl;
 
     m_hthumb->setMinimumValue(0);
     m_hthumb->setMaximumValue(count);
     m_hthumb->setValue(count - current);
 
-//    std::cerr << "set value to " << count-current << std::endl;
-
-//    std::cerr << "default value is " << m_hthumb->getDefaultValue() << std::endl;
+//    cerr << "set value to " << count-current << endl;
+
+//    cerr << "default value is " << m_hthumb->getDefaultValue() << endl;
 
     if (count != 50 && m_hthumb->getDefaultValue() == 0) {
         m_hthumb->setDefaultValue(count - current);
-//        std::cerr << "set default value to " << m_hthumb->getDefaultValue() << std::endl;
+//        cerr << "set default value to " << m_hthumb->getDefaultValue() << endl;
     }
 
     bool haveVThumb = false;
@@ -261,9 +261,9 @@
             m_vthumb->setValue(layer->getCurrentVerticalZoomStep());
             m_vthumb->blockSignals(false);
 
-//            std::cerr << "Vertical thumbwheel: min 0, max " << max
+//            cerr << "Vertical thumbwheel: min 0, max " << max
 //                      << ", default " << defaultStep << ", value "
-//                      << m_vthumb->getValue() << std::endl;
+//                      << m_vthumb->getValue() << endl;
 
         }
     }
@@ -774,11 +774,11 @@
     const Model *reference = model->getAlignmentReference();
 /*
     if (!reference) {
-        std::cerr << "Pane[" << this << "]::drawAlignmentStatus: No reference" << std::endl;
+        cerr << "Pane[" << this << "]::drawAlignmentStatus: No reference" << endl;
     } else if (reference == model) {
-        std::cerr << "Pane[" << this << "]::drawAlignmentStatus: This is the reference model" << std::endl;
+        cerr << "Pane[" << this << "]::drawAlignmentStatus: This is the reference model" << endl;
     } else {
-        std::cerr << "Pane[" << this << "]::drawAlignmentStatus: This is not the reference" << std::endl;
+        cerr << "Pane[" << this << "]::drawAlignmentStatus: This is not the reference" << endl;
     }
 */
     QString text;
@@ -878,8 +878,8 @@
     std::vector<QPixmap> pixmaps;
     for (LayerList::iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
         texts.push_back((*i)->getLayerPresentationName());
-//        std::cerr << "Pane " << this << ": Layer presentation name for " << *i << ": "
-//                  << texts[texts.size()-1] << std::endl;
+//        cerr << "Pane " << this << ": Layer presentation name for " << *i << ": "
+//                  << texts[texts.size()-1] << endl;
         pixmaps.push_back((*i)->getLayerPresentationPixmap
                           (QSize(fontAscent, fontAscent)));
     }
@@ -896,7 +896,7 @@
 	
         for (size_t i = 0; i < texts.size(); ++i) {
 
-//            std::cerr << "Pane "<< this << ": text " << i << ": " << texts[i] << std::endl;
+//            cerr << "Pane "<< this << ": text " << i << ": " << texts[i] << endl;
             
             if (i + 1 == texts.size()) {
                 paint.setPen(getForeground());
@@ -1278,7 +1278,7 @@
         return;
     }
 
-//    std::cerr << "mousePressEvent" << std::endl;
+//    cerr << "mousePressEvent" << endl;
 
     m_clickPos = e->pos();
     m_mousePos = m_clickPos;
@@ -1398,7 +1398,7 @@
         return;
     }
 
-//    std::cerr << "mouseReleaseEvent" << std::endl;
+//    cerr << "mouseReleaseEvent" << endl;
 
     ViewManager::ToolMode mode = ViewManager::NavigateMode;
     if (m_manager) mode = m_manager->getToolMode();
@@ -1506,7 +1506,7 @@
         return;
     }
 
-//    std::cerr << "mouseMoveEvent" << std::endl;
+//    cerr << "mouseMoveEvent" << endl;
 
     QPoint pos = e->pos();
     updateContextHelp(&pos);
@@ -1703,11 +1703,11 @@
     }
 	    
     float ratio = float(w) / float(width());
-//	std::cerr << "ratio: " << ratio << std::endl;
+//	cerr << "ratio: " << ratio << endl;
     size_t newZoomLevel = (size_t)nearbyint(m_zoomLevel * ratio);
     if (newZoomLevel < 1) newZoomLevel = 1;
 
-//	std::cerr << "start: " << m_startFrame << ", level " << m_zoomLevel << std::endl;
+//	cerr << "start: " << m_startFrame << ", level " << m_zoomLevel << endl;
     setZoomLevel(getZoomConstraintBlockSize(newZoomLevel));
     setStartFrame(newStartFrame);
 
@@ -1731,12 +1731,12 @@
         }
         float rmin = min + ((max - min) * (height() - y1)) / height();
         float rmax = min + ((max - min) * (height() - y0)) / height();
-        std::cerr << "min: " << min << ", max: " << max << ", y0: " << y0 << ", y1: " << y1 << ", h: " << height() << ", rmin: " << rmin << ", rmax: " << rmax << std::endl;
+        cerr << "min: " << min << ", max: " << max << ", y0: " << y0 << ", y1: " << y1 << ", h: " << height() << ", rmin: " << rmin << ", rmax: " << rmax << endl;
         if (log) {
             rmin = powf(10, rmin);
             rmax = powf(10, rmax);
         }
-        std::cerr << "finally: rmin: " << rmin << ", rmax: " << rmax << " " << unit << std::endl;
+        cerr << "finally: rmin: " << rmin << ", rmax: " << rmax << " " << unit << endl;
 
         layer->setDisplayExtents(rmin, rmax);
         updateVerticalPanner();
@@ -1818,12 +1818,12 @@
 
         if (getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) {
 
-//            std::cerr << "ydiff = " << ydiff << std::endl;
+//            cerr << "ydiff = " << ydiff << endl;
 
             int ydiff = e->y() - m_clickPos.y();
             float perpix = (dmax - dmin) / height();
             float valdiff = ydiff * perpix;
-//            std::cerr << "valdiff = " << valdiff << std::endl;
+//            cerr << "valdiff = " << valdiff << endl;
 
             if (m_dragMode == UnresolvedDrag && ydiff != 0) {
                 m_dragMode = VerticalDrag;
@@ -1839,8 +1839,8 @@
                 newmin -= newmax - vmax;
                 newmax -= newmax - vmax;
             }
-//            std::cerr << "(" << dmin << ", " << dmax << ") -> ("
-//                      << newmin << ", " << newmax << ") (drag start " << m_dragStartMinValue << ")" << std::endl;
+//            cerr << "(" << dmin << ", " << dmax << ") -> ("
+//                      << newmin << ", " << newmax << ") (drag start " << m_dragStartMinValue << ")" << endl;
 
             setTopLayerDisplayExtents(newmin, newmax);
             updateVerticalPanner();
@@ -1923,7 +1923,7 @@
                                   resolution, Layer::SnapRight);
     }
 	
-//	std::cerr << "snap: frame = " << mouseFrame << ", start frame = " << m_selectionStartFrame << ", left = " << snapFrameLeft << ", right = " << snapFrameRight << std::endl;
+//	cerr << "snap: frame = " << mouseFrame << ", start frame = " << m_selectionStartFrame << ", left = " << snapFrameLeft << ", right = " << snapFrameRight << endl;
 
     if (snapFrameLeft < 0) snapFrameLeft = 0;
     if (snapFrameRight < 0) snapFrameRight = 0;
@@ -1986,7 +1986,7 @@
         return;
     }
 
-//    std::cerr << "mouseDoubleClickEvent" << std::endl;
+//    cerr << "mouseDoubleClickEvent" << endl;
 
     m_clickPos = e->pos();
     m_clickedInRange = true;
@@ -2059,7 +2059,7 @@
 void
 Pane::wheelEvent(QWheelEvent *e)
 {
-    //std::cerr << "wheelEvent, delta " << e->delta() << std::endl;
+    //cerr << "wheelEvent, delta " << e->delta() << endl;
 
     int count = e->delta();
 
@@ -2178,13 +2178,13 @@
                 step *= 2;
                 --pwr;
             }
-//            std::cerr << level << std::endl;
+//            cerr << level << endl;
             level += step;
             if (++count == 100 || level > 262144) break;
         }
     }
         
-//    std::cerr << "new level is " << level << std::endl;
+//    cerr << "new level is " << level << endl;
     setZoomLevel(level);
 }    
 
@@ -2216,8 +2216,8 @@
     float y1 = y0 + h;
     float newmax = vmin + ((1.0 - y0) * (vmax - vmin));
     float newmin = vmin + ((1.0 - y1) * (vmax - vmin));
-//    std::cerr << "verticalPannerMoved: (" << x0 << "," << y0 << "," << w
-//              << "," << h << ") -> (" << newmin << "," << newmax << ")" << std::endl;
+//    cerr << "verticalPannerMoved: (" << x0 << "," << y0 << "," << w
+//              << "," << h << ") -> (" << newmin << "," << newmax << ")" << endl;
     setTopLayerDisplayExtents(newmin, newmax);
 }
 
@@ -2257,10 +2257,10 @@
 Pane::dragEnterEvent(QDragEnterEvent *e)
 {
     QStringList formats(e->mimeData()->formats());
-    std::cerr << "dragEnterEvent: format: "
-              << formats.join(",").toStdString()
+    cerr << "dragEnterEvent: format: "
+              << formats.join(",")
               << ", possibleActions: " << e->possibleActions()
-              << ", proposedAction: " << e->proposedAction() << std::endl;
+              << ", proposedAction: " << e->proposedAction() << endl;
     
     if (e->mimeData()->hasFormat("text/uri-list") ||
         e->mimeData()->hasFormat("text/plain")) {
@@ -2277,8 +2277,8 @@
 void
 Pane::dropEvent(QDropEvent *e)
 {
-    std::cerr << "dropEvent: text: \"" << e->mimeData()->text().toStdString()
-              << "\"" << std::endl;
+    cerr << "dropEvent: text: \"" << e->mimeData()->text()
+              << "\"" << endl;
 
     if (e->mimeData()->hasFormat("text/uri-list") || 
         e->mimeData()->hasFormat("text/plain")) {
@@ -2442,8 +2442,8 @@
 void
 Pane::viewZoomLevelChanged(View *v, unsigned long z, bool locked)
 {
-//    std::cerr << "Pane[" << this << "]::zoomLevelChanged (global now "
-//              << (m_manager ? m_manager->getGlobalZoom() : 0) << ")" << std::endl;
+//    cerr << "Pane[" << this << "]::zoomLevelChanged (global now "
+//              << (m_manager ? m_manager->getGlobalZoom() : 0) << ")" << endl;
 
     View::viewZoomLevelChanged(v, z, locked);
 
--- a/view/PaneStack.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/view/PaneStack.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -258,7 +258,7 @@
 	}
 
 	if (!found) {
-	    std::cerr << "WARNING: PaneStack::deletePane(" << pane << "): Pane not found in visible or hidden panes, not deleting" << std::endl;
+	    cerr << "WARNING: PaneStack::deletePane(" << pane << "): Pane not found in visible or hidden panes, not deleting" << endl;
 	    return;
 	}
     }
@@ -283,7 +283,7 @@
 void
 PaneStack::showOrHidePaneAccessories()
 {
-    std::cerr << "PaneStack::showOrHidePaneAccessories: count == " << getPaneCount() << std::endl;
+    cerr << "PaneStack::showOrHidePaneAccessories: count == " << getPaneCount() << endl;
 
     bool multi = (getPaneCount() > 1);
     for (std::vector<PaneRec>::iterator i = m_panes.begin();
@@ -335,7 +335,7 @@
 	++i;
     }
 
-    std::cerr << "WARNING: PaneStack::hidePane(" << pane << "): Pane not found in visible panes" << std::endl;
+    cerr << "WARNING: PaneStack::hidePane(" << pane << "): Pane not found in visible panes" << endl;
 }
 
 void
@@ -359,7 +359,7 @@
 	++i;
     }
 
-    std::cerr << "WARNING: PaneStack::showPane(" << pane << "): Pane not found in hidden panes" << std::endl;
+    cerr << "WARNING: PaneStack::showPane(" << pane << "): Pane not found in hidden panes" << endl;
 }
 
 void
@@ -398,7 +398,7 @@
 	m_currentPane = pane;
 	emit currentPaneChanged(m_currentPane);
     } else {
-	std::cerr << "WARNING: PaneStack::setCurrentPane(" << pane << "): pane is not a visible pane in this stack" << std::endl;
+	cerr << "WARNING: PaneStack::setCurrentPane(" << pane << "): pane is not a visible pane in this stack" << endl;
     }
 }
 
@@ -602,11 +602,11 @@
     }
 
 /*
-    std::cerr << "sizes: ";
+    cerr << "sizes: ";
     for (int i = 0; i < sizes.size(); ++i) {
-        std::cerr << sizes[i] << " ";
+        cerr << sizes[i] << " ";
     }
-    std::cerr << std::endl;
+    cerr << endl;
 */
 
     m_splitter->setSizes(sizes);
--- a/view/View.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/view/View.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -43,8 +43,8 @@
 
 //#define DEBUG_VIEW_WIDGET_PAINT 1
 
-using std::cerr;
-using std::endl;
+
+
 
 View::View(QWidget *w, bool showProgress) :
     QFrame(w),
@@ -325,7 +325,7 @@
 	if (newPixel != formerPixel) {
 
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-	    std::cout << "View(" << this << ")::setCentreFrame: newPixel " << newPixel << ", formerPixel " << formerPixel << std::endl;
+	    cout << "View(" << this << ")::setCentreFrame: newPixel " << newPixel << ", formerPixel " << formerPixel << endl;
 #endif
 	    update();
 
@@ -335,9 +335,9 @@
 	if (e) {
             size_t rf = alignToReference(f);
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-            std::cerr << "View[" << this << "]::setCentreFrame(" << f
+            cerr << "View[" << this << "]::setCentreFrame(" << f
                       << "): emitting centreFrameChanged("
-                      << rf << ")" << std::endl;
+                      << rf << ")" << endl;
 #endif
             emit centreFrameChanged(rf, m_followPan, m_followPlay);
         }
@@ -436,7 +436,7 @@
 View::getZoomLevel() const
 {
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-//	std::cout << "zoom level: " << m_zoomLevel << std::endl;
+//	cout << "zoom level: " << m_zoomLevel << endl;
 #endif
     return m_zoomLevel;
 }
@@ -753,7 +753,7 @@
         
         QRect r = paint.fontMetrics().boundingRect(text);
         r.translate(QPoint(x, y));
-//        std::cerr << "drawVisibleText: r = " << r.x() << "," <<r.y() << " " << r.width() << "x" << r.height() << std::endl;
+//        cerr << "drawVisibleText: r = " << r.x() << "," <<r.y() << " " << r.width() << "x" << r.height() << endl;
         paint.drawRect(r);
         paint.setBrush(Qt::NoBrush);
 
@@ -774,7 +774,7 @@
 
     } else {
 
-	std::cerr << "ERROR: View::drawVisibleText: Boxed style not yet implemented!" << std::endl;
+	cerr << "ERROR: View::drawVisibleText: Boxed style not yet implemented!" << endl;
     }
 }
 
@@ -791,7 +791,7 @@
     QObject *obj = sender();
 
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-    std::cerr << "View(" << this << ")::modelChanged()" << std::endl;
+    cerr << "View(" << this << ")::modelChanged()" << endl;
 #endif
     
     // If the model that has changed is not used by any of the cached
@@ -830,7 +830,7 @@
     size_t myEndFrame = getEndFrame();
 
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-    std::cerr << "View(" << this << ")::modelChanged(" << startFrame << "," << endFrame << ") [me " << myStartFrame << "," << myEndFrame << "]" << std::endl;
+    cerr << "View(" << this << ")::modelChanged(" << startFrame << "," << endFrame << ") [me " << myStartFrame << "," << myEndFrame << "]" << endl;
 #endif
 
     if (myStartFrame > 0 && endFrame < size_t(myStartFrame)) {
@@ -873,7 +873,7 @@
 void
 View::modelCompletionChanged()
 {
-//    std::cerr << "View(" << this << ")::modelCompletionChanged()" << std::endl;
+//    cerr << "View(" << this << ")::modelCompletionChanged()" << endl;
 
     QObject *obj = sender();
     checkProgress(obj);
@@ -882,7 +882,7 @@
 void
 View::modelAlignmentCompletionChanged()
 {
-//    std::cerr << "View(" << this << ")::modelAlignmentCompletionChanged()" << std::endl;
+//    cerr << "View(" << this << ")::modelAlignmentCompletionChanged()" << endl;
 
     QObject *obj = sender();
     checkProgress(obj);
@@ -892,7 +892,7 @@
 View::modelReplaced()
 {
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-    std::cerr << "View(" << this << ")::modelReplaced()" << std::endl;
+    cerr << "View(" << this << ")::modelReplaced()" << endl;
 #endif
     delete m_cache;
     m_cache = 0;
@@ -945,8 +945,8 @@
     if (m_followPan) {
         size_t f = alignFromReference(rf);
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-        std::cerr << "View[" << this << "]::globalCentreFrameChanged(" << rf
-                  << "): setting centre frame to " << f << std::endl;
+        cerr << "View[" << this << "]::globalCentreFrameChanged(" << rf
+                  << "): setting centre frame to " << f << endl;
 #endif
         setCentreFrame(f, false);
     }
@@ -1014,8 +1014,8 @@
 	}
 
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-	std::cerr << "PlaybackScrollPage: f = " << m_playPointerFrame << ", sf = " << sf << ", start frame "
-		  << getStartFrame() << std::endl;
+	cerr << "PlaybackScrollPage: f = " << m_playPointerFrame << ", sf = " << sf << ", start frame "
+		  << getStartFrame() << endl;
 #endif
 
 	// We don't consider scrolling unless the pointer is outside
@@ -1024,7 +1024,7 @@
 	int xnew = getXForFrame(m_playPointerFrame);
 
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-	std::cerr << "xnew = " << xnew << ", width = " << width() << std::endl;
+	cerr << "xnew = " << xnew << ", width = " << width() << endl;
 #endif
 
 	if (xnew < width()/8 || xnew > (width()*7)/8) {
@@ -1057,7 +1057,7 @@
 View::viewZoomLevelChanged(View *p, unsigned long z, bool locked)
 {
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-    std::cerr  << "View[" << this << "]: viewZoomLevelChanged(" << p << ", " << z << ", " << locked << ")" << std::endl;
+    cerr  << "View[" << this << "]: viewZoomLevelChanged(" << p << ", " << z << ", " << locked << ")" << endl;
 #endif
     if (m_followZoom && p != this && locked) {
         setZoomLevel(z);
@@ -1245,16 +1245,16 @@
 /*
     Model *pm = m_manager->getPlaybackModel();
 
-//    std::cerr << "View[" << this << "]::getAlignedPlaybackFrame: pf = " << pf;
+//    cerr << "View[" << this << "]::getAlignedPlaybackFrame: pf = " << pf;
 
     if (pm) {
         pf = pm->alignToReference(pf);
-//        std::cerr << " -> " << pf;
+//        cerr << " -> " << pf;
     }
 */
     int af = aligningModel->alignFromReference(pf);
 
-//    std::cerr << ", aligned = " << af << std::endl;
+//    cerr << ", aligned = " << af << endl;
     return af;
 }
 
@@ -1281,8 +1281,8 @@
 
     for (LayerList::const_iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
 //        SVDEBUG << "View::getScrollableBackLayers: calling isLayerDormant on layer " << *i << endl;
-//        std::cerr << "(name is " << (*i)->objectName() << ")"
-//                  << std::endl;
+//        cerr << "(name is " << (*i)->objectName() << ")"
+//                  << endl;
 //        SVDEBUG << "View::getScrollableBackLayers: I am " << this << endl;
 	if ((*i)->isLayerDormant(this)) continue;
 	if ((*i)->isLayerOpaque()) {
@@ -1485,7 +1485,7 @@
 
 	    } else {
 
-//                std::cerr << "progress = " << completion << std::endl;
+//                cerr << "progress = " << completion << endl;
 
                 if (!pb->isVisible()) {
                     i->second.lastCheck = 0;
@@ -1578,8 +1578,8 @@
     if (e) {
 	cacheRect &= e->rect();
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-	std::cerr << "paint rect " << cacheRect.width() << "x" << cacheRect.height()
-		  << ", my rect " << width() << "x" << height() << std::endl;
+	cerr << "paint rect " << cacheRect.width() << "x" << cacheRect.height()
+		  << ", my rect " << width() << "x" << height() << endl;
 #endif
     }
 
@@ -1619,11 +1619,11 @@
     }
 
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-    std::cerr << "View(" << this << ")::paintEvent: have " << scrollables.size()
+    cerr << "View(" << this << ")::paintEvent: have " << scrollables.size()
 	      << " scrollable back layers and " << nonScrollables.size()
-	      << " non-scrollable front layers" << std::endl;
-    std::cerr << "haveSelections " << haveSelections << ", selectionCacheable "
-	      << selectionCacheable << ", m_selectionCached " << m_selectionCached << std::endl;
+	      << " non-scrollable front layers" << endl;
+    cerr << "haveSelections " << haveSelections << ", selectionCacheable "
+	      << selectionCacheable << ", m_selectionCached " << m_selectionCached << endl;
 #endif
 
     if (layersChanged || scrollables.empty() ||
@@ -1636,8 +1636,8 @@
     if (!scrollables.empty()) {
 
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-        std::cerr << "View(" << this << "): cache " << m_cache << ", cache zoom "
-                  << m_cacheZoomLevel << ", zoom " << m_zoomLevel << std::endl;
+        cerr << "View(" << this << "): cache " << m_cache << ", cache zoom "
+                  << m_cacheZoomLevel << ", zoom " << m_zoomLevel << endl;
 #endif
 
 	if (!m_cache ||
@@ -1651,13 +1651,13 @@
 		delete m_cache;
                 m_cache = 0;
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-		std::cerr << "View(" << this << ")::paintEvent: small repaint, not bothering to recreate cache" << std::endl;
+		cerr << "View(" << this << ")::paintEvent: small repaint, not bothering to recreate cache" << endl;
 #endif
 	    } else {
 		delete m_cache;
 		m_cache = new QPixmap(width(), height());
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-		std::cerr << "View(" << this << ")::paintEvent: recreated cache" << std::endl;
+		cerr << "View(" << this << ")::paintEvent: recreated cache" << endl;
 #endif
 		cacheRect = rect();
 		repaintCache = true;
@@ -1702,19 +1702,19 @@
 		    cacheRect = QRect(0, 0, dx, height());
 		}
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-		std::cerr << "View(" << this << ")::paintEvent: scrolled cache by " << dx << std::endl;
+		cerr << "View(" << this << ")::paintEvent: scrolled cache by " << dx << endl;
 #endif
 	    } else {
 		cacheRect = rect();
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-		std::cerr << "View(" << this << ")::paintEvent: scrolling too far" << std::endl;
+		cerr << "View(" << this << ")::paintEvent: scrolling too far" << endl;
 #endif
 	    }
 	    repaintCache = true;
 
 	} else {
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-	    std::cerr << "View(" << this << ")::paintEvent: cache is good" << std::endl;
+	    cerr << "View(" << this << ")::paintEvent: cache is good" << endl;
 #endif
 	    paint.begin(this);
 	    paint.drawPixmap(cacheRect, *m_cache, cacheRect);
@@ -1728,7 +1728,7 @@
     }
 
 #ifdef DEBUG_VIEW_WIDGET_PAINT
-//    std::cerr << "View(" << this << ")::paintEvent: cacheRect " << cacheRect << ", nonCacheRect " << (nonCacheRect | cacheRect) << ", repaintCache " << repaintCache << ", paintedCacheRect " << paintedCacheRect << std::endl;
+//    cerr << "View(" << this << ")::paintEvent: cacheRect " << cacheRect << ", nonCacheRect " << (nonCacheRect | cacheRect) << ", repaintCache " << repaintCache << ", paintedCacheRect " << paintedCacheRect << endl;
 #endif
 
     // Scrollable (cacheable) items first
@@ -2309,7 +2309,7 @@
 		    paint.save();
 	            paint.translate(xorigin + x, 0);
 
-	            std::cerr << "Centre frame now: " << m_centreFrame << " drawing to " << chunk.x() + x + xorigin << ", " << chunk.width() << std::endl;
+	            cerr << "Centre frame now: " << m_centreFrame << " drawing to " << chunk.x() + x + xorigin << ", " << chunk.width() << endl;
 
 	            (*i)->setSynchronousPainting(true);
 
--- a/view/ViewManager.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/view/ViewManager.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -70,18 +70,18 @@
 
     if (getGlobalDarkBackground()) {
 /*
-        std::cerr << "dark palette:" << std::endl;
-        std::cerr << "window = " << QApplication::palette().color(QPalette::Window).name() << std::endl;
-        std::cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name() << std::endl;
-        std::cerr << "base = " << QApplication::palette().color(QPalette::Base).name() << std::endl;
-        std::cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name() << std::endl;
-        std::cerr << "text = " << QApplication::palette().color(QPalette::Text).name() << std::endl;
-        std::cerr << "button = " << QApplication::palette().color(QPalette::Button).name() << std::endl;
-        std::cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name() << std::endl;
-        std::cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name() << std::endl;
-        std::cerr << "light = " << QApplication::palette().color(QPalette::Light).name() << std::endl;
-        std::cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name() << std::endl;
-        std::cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name() << std::endl;
+        cerr << "dark palette:" << endl;
+        cerr << "window = " << QApplication::palette().color(QPalette::Window).name() << endl;
+        cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name() << endl;
+        cerr << "base = " << QApplication::palette().color(QPalette::Base).name() << endl;
+        cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name() << endl;
+        cerr << "text = " << QApplication::palette().color(QPalette::Text).name() << endl;
+        cerr << "button = " << QApplication::palette().color(QPalette::Button).name() << endl;
+        cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name() << endl;
+        cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name() << endl;
+        cerr << "light = " << QApplication::palette().color(QPalette::Light).name() << endl;
+        cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name() << endl;
+        cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name() << endl;
 */
         m_lightPalette = QPalette(QColor("#000000"),  // WindowText
                                   QColor("#dddfe4"),  // Button
@@ -96,18 +96,18 @@
 
     } else {
 /*
-        std::cerr << "light palette:" << std::endl;
-        std::cerr << "window = " << QApplication::palette().color(QPalette::Window).name() << std::endl;
-        std::cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name() << std::endl;
-        std::cerr << "base = " << QApplication::palette().color(QPalette::Base).name() << std::endl;
-        std::cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name() << std::endl;
-        std::cerr << "text = " << QApplication::palette().color(QPalette::Text).name() << std::endl;
-        std::cerr << "button = " << QApplication::palette().color(QPalette::Button).name() << std::endl;
-        std::cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name() << std::endl;
-        std::cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name() << std::endl;
-        std::cerr << "light = " << QApplication::palette().color(QPalette::Light).name() << std::endl;
-        std::cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name() << std::endl;
-        std::cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name() << std::endl;
+        cerr << "light palette:" << endl;
+        cerr << "window = " << QApplication::palette().color(QPalette::Window).name() << endl;
+        cerr << "windowtext = " << QApplication::palette().color(QPalette::WindowText).name() << endl;
+        cerr << "base = " << QApplication::palette().color(QPalette::Base).name() << endl;
+        cerr << "alternatebase = " << QApplication::palette().color(QPalette::AlternateBase).name() << endl;
+        cerr << "text = " << QApplication::palette().color(QPalette::Text).name() << endl;
+        cerr << "button = " << QApplication::palette().color(QPalette::Button).name() << endl;
+        cerr << "buttontext = " << QApplication::palette().color(QPalette::ButtonText).name() << endl;
+        cerr << "brighttext = " << QApplication::palette().color(QPalette::BrightText).name() << endl;
+        cerr << "light = " << QApplication::palette().color(QPalette::Light).name() << endl;
+        cerr << "dark = " << QApplication::palette().color(QPalette::Dark).name() << endl;
+        cerr << "mid = " << QApplication::palette().color(QPalette::Mid).name() << endl;
 */
         m_darkPalette = QPalette(QColor("#ffffff"),  // WindowText
                                  QColor("#3e3e3e"),  // Button
@@ -129,7 +129,7 @@
 ViewManager::getGlobalCentreFrame() const
 {
 #ifdef DEBUG_VIEW_MANAGER
-    std::cerr << "ViewManager::getGlobalCentreFrame: returning " << m_globalCentreFrame << std::endl;
+    cerr << "ViewManager::getGlobalCentreFrame: returning " << m_globalCentreFrame << endl;
 #endif
     return m_globalCentreFrame;
 }
@@ -138,7 +138,7 @@
 ViewManager::setGlobalCentreFrame(unsigned long f)
 {
 #ifdef DEBUG_VIEW_MANAGER
-    std::cerr << "ViewManager::setGlobalCentreFrame to " << f << std::endl;
+    cerr << "ViewManager::setGlobalCentreFrame to " << f << endl;
 #endif
     m_globalCentreFrame = f;
     emit globalCentreFrameChanged(f);
@@ -148,7 +148,7 @@
 ViewManager::getGlobalZoom() const
 {
 #ifdef DEBUG_VIEW_MANAGER
-    std::cerr << "ViewManager::getGlobalZoom: returning " << m_globalZoom << std::endl;
+    cerr << "ViewManager::getGlobalZoom: returning " << m_globalZoom << endl;
 #endif
     return m_globalZoom;
 }
@@ -453,6 +453,9 @@
 void
 ViewManager::playStatusChanged(bool /* playing */)
 {
+#ifdef DEBUG_VIEW_MANAGER
+    cerr << "ViewManager::playStatusChanged" << endl;
+#endif
     checkPlayStatus();
 }
 
@@ -473,7 +476,7 @@
 	m_playbackFrame = m_playSource->getCurrentPlayingFrame();
 
 #ifdef DEBUG_VIEW_MANAGER
-	std::cerr << "ViewManager::checkPlayStatus: Playing, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << std::endl;
+	cerr << "ViewManager::checkPlayStatus: Playing, frame " << m_playbackFrame << ", levels " << m_lastLeft << "," << m_lastRight << endl;
 #endif
 
 	emit playbackFrameChanged(m_playbackFrame);
@@ -482,8 +485,6 @@
 
     } else {
 
-	QTimer::singleShot(100, this, SLOT(checkPlayStatus()));
-	
 	if (m_lastLeft != 0.0 || m_lastRight != 0.0) {
 	    emit outputLevelsChanged(0.0, 0.0);
 	    m_lastLeft = 0.0;
@@ -491,7 +492,7 @@
 	}
 
 #ifdef DEBUG_VIEW_MANAGER
-//	std::cerr << "ViewManager::checkPlayStatus: Not playing" << std::endl;
+	cerr << "ViewManager::checkPlayStatus: Not playing" << endl;
 #endif
     }
 }
@@ -509,7 +510,7 @@
     View *v = dynamic_cast<View *>(sender());
 
 #ifdef DEBUG_VIEW_MANAGER
-    std::cerr << "ViewManager::viewCentreFrameChanged(" << f << ", " << locked << ", " << mode << "), view is " << v << std::endl;
+    cerr << "ViewManager::viewCentreFrameChanged(" << f << ", " << locked << ", " << mode << "), view is " << v << endl;
 #endif
 
     if (locked) {
@@ -538,7 +539,7 @@
 ViewManager::seek(unsigned long f)
 {
 #ifdef DEBUG_VIEW_MANAGER 
-    std::cerr << "ViewManager::seek(" << f << ")" << std::endl;
+    cerr << "ViewManager::seek(" << f << ")" << endl;
 #endif
 
     if (m_playSource && m_playSource->isPlaying()) {
@@ -548,7 +549,7 @@
 	    m_playbackFrame = f;
 	    m_playSource->play(f);
 #ifdef DEBUG_VIEW_MANAGER 
-	    std::cerr << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << std::endl;
+	    cerr << "ViewManager::considerSeek: reseeking from " << playFrame << " to " << f << endl;
 #endif
             emit playbackFrameChanged(f);
 	}
@@ -577,7 +578,7 @@
     }
 
 #ifdef DEBUG_VIEW_MANAGER 
-    std::cerr << "ViewManager::viewZoomLevelChanged(" << v << ", " << z << ", " << locked << ")" << std::endl;
+    cerr << "ViewManager::viewZoomLevelChanged(" << v << ", " << z << ", " << locked << ")" << endl;
 #endif
 
     emit viewZoomLevelChanged(v, z, locked);
--- a/view/ViewManager.h	Mon Nov 04 17:12:32 2013 +0000
+++ b/view/ViewManager.h	Thu Dec 05 09:47:02 2013 +0000
@@ -248,10 +248,10 @@
     void viewZoomLevelChanged(unsigned long, bool);
     void setGlobalCentreFrame(unsigned long);
     void setPlaybackFrame(unsigned long);
+    void playStatusChanged(bool playing);
 
 protected slots:
     void checkPlayStatus();
-    void playStatusChanged(bool playing);
     void seek(unsigned long);
 //!!!    void considerZoomChange(void *, unsigned long, bool);
 
--- a/widgets/ActivityLog.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/ActivityLog.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -55,7 +55,7 @@
     name = name.replace("&", "");
 //    SVDEBUG << "ActivityLog::activityHappened(" << name << ")" << endl;
     if (name == m_prevName) {
-//        std::cerr << "(ignoring duplicate)" << std::endl;
+//        cerr << "(ignoring duplicate)" << endl;
         return;
     }
     m_prevName = name;
--- a/widgets/AudioDial.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/AudioDial.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -52,8 +52,8 @@
 
 #include "base/Profiler.h"
 
-using std::endl;
-using std::cerr;
+
+
 
 
 //!!! Pedro updated his version to use my up/down response code from RG -- need to grab that code in preference to this version from Rui
@@ -99,7 +99,7 @@
 
 void AudioDial::setRangeMapper(RangeMapper *mapper)
 {
-//    std::cerr << "AudioDial[" << this << "][\"" << objectName() << "\"::setRangeMapper(" << mapper << ") [current is " << m_rangeMapper << "] (have " << dialsExtant << " dials extant)" << std::endl;
+//    cerr << "AudioDial[" << this << "][\"" << objectName() << "\"::setRangeMapper(" << mapper << ") [current is " << m_rangeMapper << "] (have " << dialsExtant << " dials extant)" << endl;
 
     if (m_rangeMapper == mapper) return;
 
@@ -183,7 +183,7 @@
     // Tick notches...
 
     if ( notchesVisible() ) {
-//	std::cerr << "Notches visible" << std::endl;
+//	cerr << "Notches visible" << endl;
 	pen.setColor(palette().dark().color());
 	pen.setWidth(scale);
 	paint.setPen(pen);
@@ -202,7 +202,7 @@
     pen.setWidth(indent);
     paint.setPen(pen);
 
-//    std::cerr << "degrees " << degrees << ", gives us " << -(degrees - 45) * 16 << std::endl;
+//    cerr << "degrees " << degrees << ", gives us " << -(degrees - 45) * 16 << endl;
 
     int arcLen = -(degrees - 45) * 16;
     if (arcLen == 0) arcLen = -16;
--- a/widgets/CSVFormatDialog.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/CSVFormatDialog.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -31,6 +31,8 @@
 
 #include <iostream>
 
+#include "base/Debug.h"
+
 CSVFormatDialog::CSVFormatDialog(QWidget *parent, CSVFormat format,
                                  int maxDisplayCols) :
     QDialog(parent),
@@ -290,8 +292,8 @@
         
         if (thisChanged) {
 
-            std::cerr << "i == " << i << ", fuzzy == " << m_fuzzyColumn
-                      << ", p == " << p << std::endl;
+            cerr << "i == " << i << ", fuzzy == " << m_fuzzyColumn
+                      << ", p == " << p << endl;
 
             if (i == m_fuzzyColumn) {
                 for (int j = i; j < m_format.getColumnCount(); ++j) {
--- a/widgets/CommandHistory.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/CommandHistory.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -143,7 +143,7 @@
     if (!command) return;
 
 #ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::addCommand: " << command->getName().toLocal8Bit().data() << " of type " << typeid(*command).name() << " at " << command << ": execute = " << execute << ", bundle = " << bundle << " (m_currentCompound = " << m_currentCompound << ", m_currentBundle = " << m_currentBundle << ")" << endl;
+    SVDEBUG << "CommandHistory::addCommand: " << command->getName() << " of type " << typeid(*command).name() << " at " << command << ": execute = " << execute << ", bundle = " << bundle << " (m_currentCompound = " << m_currentCompound << ", m_currentBundle = " << m_currentBundle << ")" << endl;
 #endif
 
     if (m_currentCompound) {
@@ -265,7 +265,7 @@
 CommandHistory::addToCompound(Command *command, bool execute)
 {
 #ifdef DEBUG_COMMAND_HISTORY
-    SVDEBUG << "CommandHistory::addToCompound: " << command->getName().toLocal8Bit().data() << endl;
+    SVDEBUG << "CommandHistory::addToCompound: " << command->getName() << endl;
 #endif
     if (!m_currentCompound) {
 	SVDEBUG << "CommandHistory::addToCompound: ERROR: no compound operation in progress!" << endl;
@@ -281,7 +281,7 @@
 {
     if (m_currentCompound) {
 	SVDEBUG << "CommandHistory::startCompoundOperation: ERROR: compound operation already in progress!" << endl;
-	std::cerr << "(name is " << m_currentCompound->getName().toLocal8Bit().data() << ")" << std::endl;
+	cerr << "(name is " << m_currentCompound->getName() << ")" << endl;
         return;
     }
  
@@ -436,7 +436,7 @@
 	for (i = 0; i < limit; ++i) {
 #ifdef DEBUG_COMMAND_HISTORY
 	    Command *command = stack.top();
-	    SVDEBUG << "CommandHistory::clipStack: Saving recent command: " << command->getName().toLocal8Bit().data() << " at " << command << endl;
+	    SVDEBUG << "CommandHistory::clipStack: Saving recent command: " << command->getName() << " at " << command << endl;
 #endif
 	    tempStack.push(stack.top());
 	    stack.pop();
--- a/widgets/Fader.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/Fader.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -57,25 +57,25 @@
     QString background_path = ":/icons/fader_background.png";
     bool ok = m_back.load(background_path);
     if (ok == false) {
-	std::cerr << "Fader: Error loading pixmap" << std::endl;
+	cerr << "Fader: Error loading pixmap" << endl;
     }
 
     QString leds_path = ":/icons/fader_leds.png";
     ok = m_leds.load(leds_path);
     if (ok == false) {
-	std::cerr <<  "Error loading pixmap" << std::endl;
+	cerr <<  "Error loading pixmap" << endl;
     }
 
     QString knob_path = ":/icons/fader_knob.png";
     ok = m_knob.load(knob_path);
     if (ok == false) {
-	std::cerr <<  "Error loading pixmap" << std::endl;
+	cerr <<  "Error loading pixmap" << endl;
     }
 
     QString clip_path = ":/icons/fader_knob_red.png";
     ok = m_clip.load(clip_path);
     if (ok == false) {
-	std::cerr <<  "Error loading pixmap" << std::endl;
+	cerr <<  "Error loading pixmap" << endl;
     }
 }
 
@@ -222,7 +222,7 @@
                 .arg(abs(int(db * 10.0) % 10))
                 .arg(abs(int(db * 100.0) % 10));
 	}
-        std::cerr << "Fader: setting tooltip to \"" << text << "\"" << std::endl;
+        cerr << "Fader: setting tooltip to \"" << text << "\"" << endl;
         QWidget::setToolTip(text);
 	update();
     }
--- a/widgets/ImageDialog.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/ImageDialog.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -204,7 +204,7 @@
             }
         }
         
-//        std::cerr << "image filename: \"" << fileName << "\"" << std::endl;
+//        cerr << "image filename: \"" << fileName << "\"" << endl;
 
         m_loadedImage = QPixmap(fileName);
         m_loadedImageFile = img;
--- a/widgets/InteractiveFileFinder.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/InteractiveFileFinder.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -225,7 +225,7 @@
         break;
 
     case SessionOrAudioFile:
-        std::cerr << "ERROR: Internal error: InteractiveFileFinder::getSaveFileName: SessionOrAudioFile cannot be used here" << std::endl;
+        cerr << "ERROR: Internal error: InteractiveFileFinder::getSaveFileName: SessionOrAudioFile cannot be used here" << endl;
         abort();
 
     case ImageFile:
@@ -241,7 +241,7 @@
         break;
 
     case AnyFile:
-        std::cerr << "ERROR: Internal error: InteractiveFileFinder::getSaveFileName: AnyFile cannot be used here" << std::endl;
+        cerr << "ERROR: Internal error: InteractiveFileFinder::getSaveFileName: AnyFile cannot be used here" << endl;
         abort();
     };
 
@@ -297,7 +297,7 @@
         
         QFileInfo fi(path);
 
-        std::cerr << "type = " << type << ", suffix = " << fi.suffix() << std::endl;
+        cerr << "type = " << type << ", suffix = " << fi.suffix() << endl;
         
         if ((type == LayerFile || type == LayerFileNoMidi)
             && fi.suffix() == "") {
@@ -314,7 +314,7 @@
             } else if (selectedFilter.contains(".ttl")) {
                 expectedExtension = "ttl";
             }
-            std::cerr << "expected extension = " << expectedExtension << std::endl;
+            cerr << "expected extension = " << expectedExtension << endl;
             if (expectedExtension != "") {
                 path = QString("%1.%2").arg(path).arg(expectedExtension);
                 fi = QFileInfo(path);
@@ -444,7 +444,7 @@
     if (FileSource::isRemote(relativeTo)) {
         resolved = QUrl(relativeTo).resolved(fileName).toString();
         if (!FileSource(resolved).isAvailable()) resolved = "";
-        std::cerr << "resolved: " << resolved << std::endl;
+        cerr << "resolved: " << resolved << endl;
     } else {
         if (QUrl(relativeTo).scheme() == "file") {
             relativeTo = QUrl(relativeTo).toLocalFile();
--- a/widgets/ItemEditDialog.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/ItemEditDialog.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -147,8 +147,8 @@
         m_valueSpinBox = new QDoubleSpinBox;
         m_valueSpinBox->setSuffix(QString(" %1").arg(valueUnits));
         m_valueSpinBox->setDecimals(10);
-        m_valueSpinBox->setMinimum(-1e100);
-        m_valueSpinBox->setMaximum(1e100);
+        m_valueSpinBox->setMinimum(-1e10);
+        m_valueSpinBox->setMaximum(1e10);
         connect(m_valueSpinBox, SIGNAL(valueChanged(double)),
                 this, SLOT(valueChanged(double)));
         subgrid->addWidget(m_valueSpinBox, subrow, 1);
--- a/widgets/LEDButton.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/LEDButton.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -94,7 +94,7 @@
 void
 LEDButton::mousePressEvent(QMouseEvent *e)
 {
-    std::cerr << "LEDButton(" << this << ")::mousePressEvent" << std::endl;
+    cerr << "LEDButton(" << this << ")::mousePressEvent" << endl;
 
     if (e->buttons() & Qt::LeftButton) {
 	toggle();
--- a/widgets/LayerTree.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/LayerTree.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -319,7 +319,7 @@
 void
 LayerTreeModel::paneAboutToBeDeleted(Pane *pane)
 {
-    std::cerr << "paneDeleted: " << pane << std::endl;
+    cerr << "paneDeleted: " << pane << endl;
     m_deletedPanes.insert(pane);
     emit layoutChanged();
 }
--- a/widgets/ModelDataTableDialog.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/ModelDataTableDialog.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -215,8 +215,8 @@
 
     // should only select if no part of the desired row is currently selected
 
-//    std::cerr << "rh = " << rh << ", row = " << row << ", scrolling to "
-//              << topRow << std::endl;
+//    cerr << "rh = " << rh << ", row = " << row << ", scrolling to "
+//              << topRow << endl;
 
     int pos = m_tableView->rowViewportPosition(row);
 
--- a/widgets/PluginParameterBox.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/PluginParameterBox.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -109,8 +109,8 @@
         float qtz = 0.0;
         if (params[i].isQuantized) qtz = params[i].quantizeStep;
 
-//        std::cerr << "PluginParameterBox: hint = " << hint << ", min = " << min << ", max = "
-//                  << max << ", qtz = " << qtz << std::endl;
+//        cerr << "PluginParameterBox: hint = " << hint << ", min = " << min << ", max = "
+//                  << max << ", qtz = " << qtz << endl;
 
         std::vector<std::string> valueNames = params[i].valueNames;
 
@@ -225,7 +225,7 @@
     }
 
     if (m_params.find(identifier) == m_params.end()) {
-        std::cerr << "WARNING: PluginParameterBox::dialChanged: Unknown parameter \"" << identifier << "\"" << std::endl;
+        cerr << "WARNING: PluginParameterBox::dialChanged: Unknown parameter \"" << identifier << "\"" << endl;
         return;
     }
 
@@ -288,7 +288,7 @@
     }
 
     if (m_params.find(identifier) == m_params.end()) {
-        std::cerr << "WARNING: PluginParameterBox::checkBoxChanged: Unknown parameter \"" << identifier << "\"" << std::endl;
+        cerr << "WARNING: PluginParameterBox::checkBoxChanged: Unknown parameter \"" << identifier << "\"" << endl;
         return;
     }
 
@@ -314,7 +314,7 @@
     }
 
     if (m_params.find(identifier) == m_params.end()) {
-        std::cerr << "WARNING: PluginParameterBox::spinBoxChanged: Unknown parameter \"" << identifier << "\"" << std::endl;
+        cerr << "WARNING: PluginParameterBox::spinBoxChanged: Unknown parameter \"" << identifier << "\"" << endl;
         return;
     }
 
--- a/widgets/PluginParameterDialog.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/PluginParameterDialog.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -40,6 +40,8 @@
 #include <QDesktopServices>
 #include <QUrl>
 
+#include "base/Debug.h"
+
 PluginParameterDialog::PluginParameterDialog(Vamp::PluginBase *plugin,
 					     QWidget *parent) :
     QDialog(parent),
@@ -327,7 +329,7 @@
         } else {
 
             if (m_haveChannelBoxData) {
-                std::cerr << "WARNING: PluginParameterDialog::setChannelArrangement: Calling more than once on same dialog is not currently implemented" << std::endl;
+                cerr << "WARNING: PluginParameterDialog::setChannelArrangement: Calling more than once on same dialog is not currently implemented" << endl;
                 return;
             }
             
@@ -372,7 +374,7 @@
                                                 bool showFrequencyDomainOptions)
 {
     if (m_haveWindowBoxData) {
-        std::cerr << "WARNING: PluginParameterDialog::setShowProcessingOptions: Calling more than once on same dialog is not currently implemented" << std::endl;
+        cerr << "WARNING: PluginParameterDialog::setShowProcessingOptions: Calling more than once on same dialog is not currently implemented" << endl;
         return;
     }
 
@@ -385,7 +387,7 @@
         int increment = 1024;
         if (fePlugin) {
             size = fePlugin->getPreferredBlockSize();
-            std::cerr << "Feature extraction plugin \"" << fePlugin->getName() << "\" reports preferred block size as " << size << std::endl;
+            cerr << "Feature extraction plugin \"" << fePlugin->getName() << "\" reports preferred block size as " << size << endl;
             if (size == 0) size = 1024;
             increment = fePlugin->getPreferredStepSize();
             if (increment == 0) {
@@ -406,7 +408,7 @@
             windowLayout->addWidget(new QLabel(tr("Audio frames per block:")), 0, 0);
         }
 
-        std::cerr << "size: " << size << ", increment: " << increment << std::endl;
+        cerr << "size: " << size << ", increment: " << increment << endl;
 
         QComboBox *blockSizeCombo = new QComboBox;
         blockSizeCombo->setEditable(true);
@@ -559,7 +561,7 @@
 PluginParameterDialog::blockSizeComboChanged(const QString &text)
 {
     m_blockSize = text.toInt();
-    std::cerr << "Block size changed to " << m_blockSize << std::endl;
+    cerr << "Block size changed to " << m_blockSize << endl;
 }
 
 void
@@ -567,7 +569,7 @@
 {
     m_stepSize = text.toInt();
     //!!! rename increment to step size throughout
-    std::cerr << "Increment changed to " << m_stepSize << std::endl;
+    cerr << "Increment changed to " << m_stepSize << endl;
 }
 
 void
@@ -605,7 +607,7 @@
         m_advancedButton->setChecked(false);
     }
 
-//    std::cerr << "resize to " << sizeHint().width() << " x " << sizeHint().height() << std::endl;
+//    cerr << "resize to " << sizeHint().width() << " x " << sizeHint().height() << endl;
 
 //    setMinimumHeight(sizeHint().height());
     adjustSize();
--- a/widgets/PropertyBox.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/PropertyBox.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -64,8 +64,8 @@
     m_playButton(0)
 {
 #ifdef DEBUG_PROPERTY_BOX
-    std::cerr << "PropertyBox[" << this << "(\"" <<
-	container->getPropertyContainerName() << "\" at " << container << ")]::PropertyBox" << std::endl;
+    cerr << "PropertyBox[" << this << "(\"" <<
+	container->getPropertyContainerName() << "\" at " << container << ")]::PropertyBox" << endl;
 #endif
 
     m_mainBox = new QVBoxLayout;
@@ -107,14 +107,14 @@
             this, SLOT(colourDatabaseChanged()));
 
 #ifdef DEBUG_PROPERTY_BOX
-    std::cerr << "PropertyBox[" << this << "]::PropertyBox returning" << std::endl;
+    cerr << "PropertyBox[" << this << "]::PropertyBox returning" << endl;
 #endif
 }
 
 PropertyBox::~PropertyBox()
 {
 #ifdef DEBUG_PROPERTY_BOX
-    std::cerr << "PropertyBox[" << this << "]::~PropertyBox" << std::endl;
+    cerr << "PropertyBox[" << this << "]::~PropertyBox" << endl;
 #endif
 }
 
@@ -123,7 +123,7 @@
 PropertyBox::populateViewPlayFrame()
 {
 #ifdef DEBUG_PROPERTY_BOX
-    std::cerr << "PropertyBox(" << m_container << ")::populateViewPlayFrame" << std::endl;
+    cerr << "PropertyBox(" << m_container << ")::populateViewPlayFrame" << endl;
 #endif
 
     if (m_viewPlayFrame) {
@@ -334,12 +334,12 @@
     QString iconName = m_container->getPropertyIconName(name);
 
 #ifdef DEBUG_PROPERTY_BOX
-    std::cerr << "PropertyBox[" << this
-	      << "(\"" << m_container->getPropertyContainerName().toStdString()
+    cerr << "PropertyBox[" << this
+	      << "(\"" << m_container->getPropertyContainerName()
 	      << "\")]";
-    std::cerr << "::updatePropertyEditor(\"" << name << "\"):";
-    std::cerr << " value " << value << ", have " << have << ", group \""
-	      << groupName << "\"" << std::endl;
+    cerr << "::updatePropertyEditor(\"" << name << "\"):";
+    cerr << " value " << value << ", have " << have << ", group \""
+	      << groupName << "\"" << endl;
 #endif
 
     bool inGroup = (groupName != QString());
@@ -348,7 +348,7 @@
 	if (inGroup) {
 	    if (m_groupLayouts.find(groupName) == m_groupLayouts.end()) {
 #ifdef DEBUG_PROPERTY_BOX
-		std::cerr << "PropertyBox: adding label \"" << groupName << "\" and frame for group for \"" << name << "\"" << std::endl;
+		cerr << "PropertyBox: adding label \"" << groupName << "\" and frame for group for \"" << name << "\"" << endl;
 #endif
 		m_layout->addWidget(new QLabel(groupName, m_mainWidget), row, 0);
 		QFrame *frame = new QFrame(m_mainWidget);
@@ -359,7 +359,7 @@
 	    }
 	} else {
 #ifdef DEBUG_PROPERTY_BOX 
-	    std::cerr << "PropertyBox: adding label \"" << propertyLabel << "\"" << std::endl;
+	    cerr << "PropertyBox: adding label \"" << propertyLabel << "\"" << endl;
 #endif
 	    m_layout->addWidget(new QLabel(propertyLabel, m_mainWidget), row, 0);
 	}
@@ -376,7 +376,7 @@
             assert(button);
 	} else {
 #ifdef DEBUG_PROPERTY_BOX 
-	    std::cerr << "PropertyBox: creating new checkbox" << std::endl;
+	    cerr << "PropertyBox: creating new checkbox" << endl;
 #endif
             if (iconName != "") {
                 button = new NotifyingPushButton();
@@ -430,7 +430,7 @@
                 
 	} else {
 #ifdef DEBUG_PROPERTY_BOX 
-	    std::cerr << "PropertyBox: creating new dial" << std::endl;
+	    cerr << "PropertyBox: creating new dial" << endl;
 #endif
 	    dial = new AudioDial();
 	    dial->setObjectName(name);
@@ -486,7 +486,7 @@
 	    assert(cb);
 	} else {
 #ifdef DEBUG_PROPERTY_BOX 
-	    std::cerr << "PropertyBox: creating new combobox" << std::endl;
+	    cerr << "PropertyBox: creating new combobox" << endl;
 #endif
 
 	    cb = new NotifyingComboBox();
@@ -571,7 +571,7 @@
         }
         cb->blockSignals(false);
 
-#ifdef Q_WS_MAC
+#ifdef Q_OS_MAC
 	// Crashes on startup without this, for some reason
 	cb->setMinimumSize(QSize(10, 10));
 #endif
@@ -621,12 +621,12 @@
 void
 PropertyBox::unitDatabaseChanged()
 {
-    std::cerr << "PropertyBox[" << this << "]: unitDatabaseChanged" << std::endl;
+    cerr << "PropertyBox[" << this << "]: unitDatabaseChanged" << endl;
     blockSignals(true);
 
-//    std::cerr << "my container is " << m_container << std::endl;
-//    std::cerr << "my container's name is... " << std::endl;
-//    std::cerr << m_container->objectName() << std::endl;
+//    cerr << "my container is " << m_container << endl;
+//    cerr << "my container's name is... " << endl;
+//    cerr << m_container->objectName() << endl;
 
     PropertyContainer::PropertyList properties = m_container->getProperties();
     for (size_t i = 0; i < properties.size(); ++i) {
--- a/widgets/SelectableLabel.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/SelectableLabel.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -131,7 +131,7 @@
 void
 SelectableLabel::enterEvent(QEvent *)
 {
-//    std::cerr << "enterEvent" << std::endl;
+//    cerr << "enterEvent" << endl;
 //    QPalette palette = QApplication::palette();
 //    palette.setColor(QPalette::Window, Qt::gray);
 //    setStyleSheet("background: gray");
@@ -141,7 +141,7 @@
 void
 SelectableLabel::leaveEvent(QEvent *)
 {
-//    std::cerr << "leaveEvent" << std::endl;
+//    cerr << "leaveEvent" << endl;
 //    setStyleSheet("background: white");
 //    QPalette palette = QApplication::palette();
 //    palette.setColor(QPalette::Window, Qt::gray);
--- a/widgets/SubdividingMenu.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/SubdividingMenu.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -17,6 +17,8 @@
 
 #include <iostream>
 
+#include "base/Debug.h"
+
 using std::set;
 using std::map;
 
@@ -81,7 +83,7 @@
             firstInitialInChunk = initial;
         }
 
-//        std::cerr << "count = "<< count << ", upper limit = " << m_upperLimit << std::endl;
+//        cerr << "count = "<< count << ", upper limit = " << m_upperLimit << endl;
 
         bool lastInChunk = (k == entries.end() ||
                             (count >= m_lowerLimit-1 &&
@@ -134,7 +136,7 @@
 SubdividingMenu::entriesAdded()
 {
     if (m_entriesSet) {
-        std::cerr << "ERROR: SubdividingMenu::entriesAdded: setEntries was also called -- should use one mechanism or the other, but not both" << std::endl;
+        cerr << "ERROR: SubdividingMenu::entriesAdded: setEntries was also called -- should use one mechanism or the other, but not both" << endl;
         return;
     }
     
--- a/widgets/TextAbbrev.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/TextAbbrev.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -263,7 +263,7 @@
 
 //    SVDEBUG << "TextAbbrev::getPrefixLength: prefix length is " << candidate << endl;
 //    for (int i = 0; i < texts.size(); ++i) {
-//        std::cerr << texts[i].left(candidate) << "|" << texts[i].right(texts[i].length() - candidate) << std::endl;
+//        cerr << texts[i].left(candidate) << "|" << texts[i].right(texts[i].length() - candidate) << endl;
 //    }
 
     return candidate;
--- a/widgets/Thumbwheel.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/Thumbwheel.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -506,7 +506,7 @@
 
     float radians = m_rotation * 1.5f * M_PI;
 
-//    std::cerr << "value = " << m_value << ", min = " << m_min << ", max = " << m_max << ", rotation = " << rotation << std::endl;
+//    cerr << "value = " << m_value << ", min = " << m_min << ", max = " << m_max << ", rotation = " << rotation << endl;
 
     w = (m_orientation == Qt::Horizontal ? width() : height()) - bw*2;
 
--- a/widgets/TipDialog.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/TipDialog.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -146,7 +146,7 @@
 TipDialog::showTip()
 {
     if (m_tipNumber < int(m_tips.size())) {
-        std::cerr << "Tip " << m_tipNumber << " is: " << m_tips[m_tipNumber] << std::endl;
+        cerr << "Tip " << m_tipNumber << " is: " << m_tips[m_tipNumber] << endl;
         m_label->setText(m_tips[m_tipNumber]);
     } else {
         accept();
@@ -196,24 +196,24 @@
         if (caption != "") m_dialog->m_caption = caption;
     } else if (name == "tip") {
         if (m_inTip) {
-            std::cerr << "WARNING: TipFileParser: nested <tip> elements" << std::endl;
+            cerr << "WARNING: TipFileParser: nested <tip> elements" << endl;
         }
         m_inTip = true;
     } else if (name == "text") {
         if (m_inTip) {
             m_inText = true;
-            std::cerr << "TipFileParser: adding new tip" << std::endl;
+            cerr << "TipFileParser: adding new tip" << endl;
             m_dialog->m_tips.push_back("");
         } else {
-            std::cerr << "WARNING: TipFileParser: <text> outside <tip> element" << std::endl;
+            cerr << "WARNING: TipFileParser: <text> outside <tip> element" << endl;
         }
     } else if (name == "html") {
         if (m_inTip) {
             m_inHtml = true;
-            std::cerr << "TipFileParser: adding new tip" << std::endl;
+            cerr << "TipFileParser: adding new tip" << endl;
             m_dialog->m_tips.push_back("");
         } else {
-            std::cerr << "WARNING: TipFileParser: <html> outside <tip> element" << std::endl;
+            cerr << "WARNING: TipFileParser: <html> outside <tip> element" << endl;
         }
     } else if (m_inHtml) {
         m_dialog->m_tips[m_dialog->m_tips.size()-1] += "<" + qName;
@@ -236,21 +236,21 @@
 
     if (name == "text") {
         if (!m_inText) {
-            std::cerr << "WARNING: TipFileParser: </text> without <text>" << std::endl;
+            cerr << "WARNING: TipFileParser: </text> without <text>" << endl;
         }
         m_inText = false;
     } else if (name == "html") {
         if (!m_inHtml) {
-            std::cerr << "WARNING: TipFileParser: </html> without <html>" << std::endl;
+            cerr << "WARNING: TipFileParser: </html> without <html>" << endl;
         }
         m_inHtml = false;
     } else if (name == "tip") {
         if (m_inText) {
-            std::cerr << "WARNING: TipFileParser: <text> without </text>" << std::endl;
+            cerr << "WARNING: TipFileParser: <text> without </text>" << endl;
         } else if (m_inHtml) {
-            std::cerr << "WARNING: TipFileParser: <html> without </html>" << std::endl;
+            cerr << "WARNING: TipFileParser: <html> without </html>" << endl;
         } else if (!m_inTip) {
-            std::cerr << "WARNING: TipFileParser: </tip> without <tip>" << std::endl;
+            cerr << "WARNING: TipFileParser: </tip> without <tip>" << endl;
         }
         m_inTip = false;
     } else if (m_inHtml) {
@@ -280,7 +280,7 @@
 	.arg(exception.message())
 	.arg(exception.lineNumber())
 	.arg(exception.columnNumber());
-    std::cerr << errorString << std::endl;
+    cerr << errorString << endl;
     return QXmlDefaultHandler::error(exception);
 }
 
@@ -292,6 +292,6 @@
 	.arg(exception.message())
 	.arg(exception.lineNumber())
 	.arg(exception.columnNumber());
-    std::cerr << errorString << std::endl;
+    cerr << errorString << endl;
     return QXmlDefaultHandler::fatalError(exception);
 }
--- a/widgets/TransformFinder.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/TransformFinder.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -169,7 +169,7 @@
 void
 TransformFinder::searchTextChanged(const QString &text)
 {
-//    std::cerr << "text is " << text << std::endl;
+//    cerr << "text is " << text << endl;
     m_newSearchText = text;
 }
 
@@ -187,7 +187,7 @@
         TransformFactory::SearchResults results =
             TransformFactory::getInstance()->search(keywords);
         
-//        std::cerr << results.size() << " result(s)..." << std::endl;
+//        cerr << results.size() << " result(s)..." << endl;
         
         std::set<TextMatcher::Match> sorted;
         sorted.clear();
@@ -241,7 +241,7 @@
 
         int i = m_upToDateCount;
 
-//        std::cerr << "sorted size = " << m_sortedResults.size() << std::endl;
+//        cerr << "sorted size = " << m_sortedResults.size() << endl;
 
         TransformDescription desc;
         TransformId tid = m_sortedResults[i].key;
@@ -318,7 +318,7 @@
         m_labels[i]->setFixedWidth(this->width() - 40);
         m_labels[i]->setUnselectedText(labelText);
 
-//        std::cerr << "selected text: " << selectedText << std::endl;
+//        cerr << "selected text: " << selectedText << endl;
         m_labels[i]->setSelectedText(selectedText);
 
         m_labels[i]->setSelected(m_selectedTransform == desc.identifier);
@@ -350,8 +350,8 @@
             }
         }
     }
-    std::cerr << "selectedLabelChanged: selected transform is now \""
-              << m_selectedTransform << "\"" << std::endl;
+    cerr << "selectedLabelChanged: selected transform is now \""
+              << m_selectedTransform << "\"" << endl;
 }
 
 void
--- a/widgets/WindowShapePreview.cpp	Mon Nov 04 17:12:32 2013 +0000
+++ b/widgets/WindowShapePreview.cpp	Thu Dec 05 09:47:02 2013 +0000
@@ -177,7 +177,7 @@
     path = QPainterPath();
     freqPainter.setPen(Qt::black);
 
-//    std::cerr << "maxdb = " << maxdb << ", mindb = " << mindb << ", maxval = " <<maxval << std::endl;
+//    cerr << "maxdb = " << maxdb << ", mindb = " << mindb << ", maxval = " <<maxval << endl;
 
     for (int i = 0; i < fftsize/2; ++i) {
         float power = output[i][0] * output[i][0] + output[i][1] * output[i][1];