Index: trunk/BNC/qwt/qwt.h
===================================================================
--- trunk/BNC/qwt/qwt.h	(revision 4271)
+++ trunk/BNC/qwt/qwt.h	(revision 4271)
@@ -0,0 +1,22 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_H
+#define QWT_H
+
+#include "qwt_global.h"
+
+/*!
+  Some constants for use within Qwt.
+*/
+namespace Qwt
+{
+};
+
+#endif
Index: trunk/BNC/qwt/qwt.pro
===================================================================
--- trunk/BNC/qwt/qwt.pro	(revision 4271)
+++ trunk/BNC/qwt/qwt.pro	(revision 4271)
@@ -0,0 +1,139 @@
+
+TEMPLATE  = lib
+TARGET    = qwt
+CONFIG   += staticlib
+
+DEFINES += QWT_NO_SVG
+
+HEADERS += \
+    qwt.h \
+    qwt_abstract_scale_draw.h \
+    qwt_interval_symbol.h \
+    qwt_clipper.h \
+    qwt_color_map.h \
+    qwt_compat.h \
+    qwt_column_symbol.h \
+    qwt_interval.h \
+    qwt_dyngrid_layout.h \
+    qwt_global.h \
+    qwt_math.h \
+    qwt_magnifier.h \
+    qwt_null_paintdevice.h \
+    qwt_painter.h \
+    qwt_panner.h \
+    qwt_picker.h \
+    qwt_picker_machine.h \
+    qwt_point_3d.h \
+    qwt_point_polar.h \
+    qwt_round_scale_draw.h \
+    qwt_scale_div.h \
+    qwt_scale_draw.h \
+    qwt_scale_engine.h \
+    qwt_scale_map.h \
+    qwt_spline.h \
+    qwt_symbol.h \
+    qwt_system_clock.h \
+    qwt_text_engine.h \
+    qwt_text_label.h \
+    qwt_text.h
+
+SOURCES += \
+    qwt_abstract_scale_draw.cpp \
+    qwt_interval_symbol.cpp \
+    qwt_clipper.cpp \
+    qwt_color_map.cpp \
+    qwt_column_symbol.cpp \
+    qwt_interval.cpp \
+    qwt_dyngrid_layout.cpp \
+    qwt_math.cpp \
+    qwt_magnifier.cpp \
+    qwt_panner.cpp \
+    qwt_null_paintdevice.cpp \
+    qwt_painter.cpp \
+    qwt_picker.cpp \
+    qwt_round_scale_draw.cpp \
+    qwt_scale_div.cpp \
+    qwt_scale_draw.cpp \
+    qwt_scale_map.cpp \
+    qwt_spline.cpp \
+    qwt_text_engine.cpp \
+    qwt_text_label.cpp \
+    qwt_text.cpp \
+    qwt_event_pattern.cpp \
+    qwt_picker_machine.cpp \
+    qwt_point_3d.cpp \
+    qwt_point_polar.cpp \
+    qwt_scale_engine.cpp \
+    qwt_symbol.cpp \
+    qwt_system_clock.cpp
+
+ 
+    HEADERS += \
+        qwt_curve_fitter.h \
+        qwt_event_pattern.h \
+        qwt_legend.h \
+        qwt_legend_item.h \
+        qwt_legend_itemmanager.h \
+        qwt_plot.h \
+        qwt_plot_renderer.h \
+        qwt_plot_curve.h \
+        qwt_plot_dict.h \
+        qwt_plot_directpainter.h \
+        qwt_plot_grid.h \
+        qwt_plot_histogram.h \
+        qwt_plot_item.h \
+        qwt_plot_intervalcurve.h \
+        qwt_plot_layout.h \
+        qwt_plot_marker.h \
+        qwt_plot_rasteritem.h \
+        qwt_plot_spectrogram.h \
+        qwt_plot_spectrocurve.h \
+        qwt_plot_scaleitem.h \
+        qwt_plot_seriesitem.h \
+        qwt_plot_canvas.h \
+        qwt_plot_panner.h \
+        qwt_plot_picker.h \
+        qwt_plot_zoomer.h \
+        qwt_plot_magnifier.h \
+        qwt_plot_rescaler.h \
+        qwt_raster_data.h \
+        qwt_matrix_raster_data.h \
+        qwt_sampling_thread.h \
+        qwt_series_data.h \
+        qwt_scale_widget.h 
+
+    SOURCES += \
+        qwt_curve_fitter.cpp \
+        qwt_legend.cpp \
+        qwt_legend_item.cpp \
+        qwt_plot.cpp \
+        qwt_plot_renderer.cpp \
+        qwt_plot_xml.cpp \
+        qwt_plot_axis.cpp \
+        qwt_plot_curve.cpp \
+        qwt_plot_dict.cpp \
+        qwt_plot_directpainter.cpp \
+        qwt_plot_grid.cpp \
+        qwt_plot_histogram.cpp \
+        qwt_plot_item.cpp \
+        qwt_plot_intervalcurve.cpp \
+        qwt_plot_spectrogram.cpp \
+        qwt_plot_spectrocurve.cpp \
+        qwt_plot_scaleitem.cpp \
+        qwt_plot_seriesitem.cpp \
+        qwt_plot_marker.cpp \
+        qwt_plot_layout.cpp \
+        qwt_plot_canvas.cpp \
+        qwt_plot_panner.cpp \
+        qwt_plot_rasteritem.cpp \
+        qwt_plot_picker.cpp \
+        qwt_plot_zoomer.cpp \
+        qwt_plot_magnifier.cpp \
+        qwt_plot_rescaler.cpp \
+        qwt_raster_data.cpp \
+        qwt_matrix_raster_data.cpp \
+        qwt_sampling_thread.cpp \
+        qwt_series_data.cpp \
+        qwt_scale_widget.cpp 
+
+
Index: trunk/BNC/qwt/qwt_abstract_scale_draw.cpp
===================================================================
--- trunk/BNC/qwt/qwt_abstract_scale_draw.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_abstract_scale_draw.cpp	(revision 4271)
@@ -0,0 +1,412 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_abstract_scale_draw.h"
+#include "qwt_math.h"
+#include "qwt_text.h"
+#include "qwt_painter.h"
+#include "qwt_scale_map.h"
+#include <qpainter.h>
+#include <qpalette.h>
+#include <qmap.h>
+#include <qlocale.h>
+
+class QwtAbstractScaleDraw::PrivateData
+{
+public:
+    PrivateData():
+        spacing( 4.0 ),
+        penWidth( 0 ),
+        minExtent( 0.0 )
+    {
+        components = QwtAbstractScaleDraw::Backbone 
+            | QwtAbstractScaleDraw::Ticks 
+            | QwtAbstractScaleDraw::Labels;
+
+        tickLength[QwtScaleDiv::MinorTick] = 4.0;
+        tickLength[QwtScaleDiv::MediumTick] = 6.0;
+        tickLength[QwtScaleDiv::MajorTick] = 8.0;
+    }
+
+    ScaleComponents components;
+
+    QwtScaleMap map;
+    QwtScaleDiv scldiv;
+
+    double spacing;
+    double tickLength[QwtScaleDiv::NTickTypes];
+    int penWidth;
+
+    double minExtent;
+
+    QMap<double, QwtText> labelCache;
+};
+
+/*!
+  \brief Constructor
+
+  The range of the scale is initialized to [0, 100],
+  The spacing (distance between ticks and labels) is
+  set to 4, the tick lengths are set to 4,6 and 8 pixels
+*/
+QwtAbstractScaleDraw::QwtAbstractScaleDraw()
+{
+    d_data = new QwtAbstractScaleDraw::PrivateData;
+}
+
+//! Destructor
+QwtAbstractScaleDraw::~QwtAbstractScaleDraw()
+{
+    delete d_data;
+}
+
+/*!
+  En/Disable a component of the scale
+
+  \param component Scale component
+  \param enable On/Off
+
+  \sa hasComponent()
+*/
+void QwtAbstractScaleDraw::enableComponent(
+    ScaleComponent component, bool enable )
+{
+    if ( enable )
+        d_data->components |= component;
+    else
+        d_data->components &= ~component;
+}
+
+/*!
+  Check if a component is enabled
+  \sa enableComponent()
+*/
+bool QwtAbstractScaleDraw::hasComponent( ScaleComponent component ) const
+{
+    return ( d_data->components & component );
+}
+
+/*!
+  Change the scale division
+  \param sd New scale division
+*/
+void QwtAbstractScaleDraw::setScaleDiv( const QwtScaleDiv &sd )
+{
+    d_data->scldiv = sd;
+    d_data->map.setScaleInterval( sd.lowerBound(), sd.upperBound() );
+    d_data->labelCache.clear();
+}
+
+/*!
+  Change the transformation of the scale
+  \param transformation New scale transformation
+*/
+void QwtAbstractScaleDraw::setTransformation(
+    QwtScaleTransformation *transformation )
+{
+    d_data->map.setTransformation( transformation );
+}
+
+//! \return Map how to translate between scale and pixel values
+const QwtScaleMap &QwtAbstractScaleDraw::scaleMap() const
+{
+    return d_data->map;
+}
+
+//! \return Map how to translate between scale and pixel values
+QwtScaleMap &QwtAbstractScaleDraw::scaleMap()
+{
+    return d_data->map;
+}
+
+//! \return scale division
+const QwtScaleDiv& QwtAbstractScaleDraw::scaleDiv() const
+{
+    return d_data->scldiv;
+}
+
+/*!
+  \brief Specify the width of the scale pen
+  \param width Pen width
+  \sa penWidth()
+*/
+void QwtAbstractScaleDraw::setPenWidth( int width )
+{
+    if ( width < 0 )
+        width = 0;
+
+    if ( width != d_data->penWidth )
+        d_data->penWidth = width;
+}
+
+/*!
+    \return Scale pen width
+    \sa setPenWidth()
+*/
+int QwtAbstractScaleDraw::penWidth() const
+{
+    return d_data->penWidth;
+}
+
+/*!
+  \brief Draw the scale
+
+  \param painter    The painter
+
+  \param palette    Palette, text color is used for the labels,
+                    foreground color for ticks and backbone
+*/
+void QwtAbstractScaleDraw::draw( QPainter *painter,
+    const QPalette& palette ) const
+{
+    painter->save();
+
+    QPen pen = painter->pen();
+    pen.setWidth( d_data->penWidth );
+    pen.setCosmetic( false );
+    painter->setPen( pen );
+
+    if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
+    {
+        painter->save();
+        painter->setPen( palette.color( QPalette::Text ) ); // ignore pen style
+
+        const QList<double> &majorTicks =
+            d_data->scldiv.ticks( QwtScaleDiv::MajorTick );
+
+        for ( int i = 0; i < majorTicks.count(); i++ )
+        {
+            const double v = majorTicks[i];
+            if ( d_data->scldiv.contains( v ) )
+                drawLabel( painter, majorTicks[i] );
+        }
+
+        painter->restore();
+    }
+
+    if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
+    {
+        painter->save();
+
+        QPen pen = painter->pen();
+        pen.setColor( palette.color( QPalette::WindowText ) );
+        pen.setCapStyle( Qt::FlatCap );
+
+        painter->setPen( pen );
+
+        for ( int tickType = QwtScaleDiv::MinorTick;
+            tickType < QwtScaleDiv::NTickTypes; tickType++ )
+        {
+            const QList<double> &ticks = d_data->scldiv.ticks( tickType );
+            for ( int i = 0; i < ticks.count(); i++ )
+            {
+                const double v = ticks[i];
+                if ( d_data->scldiv.contains( v ) )
+                    drawTick( painter, v, d_data->tickLength[tickType] );
+            }
+        }
+
+        painter->restore();
+    }
+
+    if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
+    {
+        painter->save();
+
+        QPen pen = painter->pen();
+        pen.setColor( palette.color( QPalette::WindowText ) );
+        pen.setCapStyle( Qt::FlatCap );
+
+        painter->setPen( pen );
+
+        drawBackbone( painter );
+
+        painter->restore();
+    }
+
+    painter->restore();
+}
+
+/*!
+  \brief Set the spacing between tick and labels
+
+  The spacing is the distance between ticks and labels.
+  The default spacing is 4 pixels.
+
+  \param spacing Spacing
+
+  \sa spacing()
+*/
+void QwtAbstractScaleDraw::setSpacing( double spacing )
+{
+    if ( spacing < 0 )
+        spacing = 0;
+
+    d_data->spacing = spacing;
+}
+
+/*!
+  \brief Get the spacing
+
+  The spacing is the distance between ticks and labels.
+  The default spacing is 4 pixels.
+
+  \sa setSpacing()
+*/
+double QwtAbstractScaleDraw::spacing() const
+{
+    return d_data->spacing;
+}
+
+/*!
+  \brief Set a minimum for the extent
+
+  The extent is calculated from the coomponents of the
+  scale draw. In situations, where the labels are
+  changing and the layout depends on the extent (f.e scrolling
+  a scale), setting an upper limit as minimum extent will
+  avoid jumps of the layout.
+
+  \param minExtent Minimum extent
+
+  \sa extent(), minimumExtent()
+*/
+void QwtAbstractScaleDraw::setMinimumExtent( double minExtent )
+{
+    if ( minExtent < 0.0 )
+        minExtent = 0.0;
+
+    d_data->minExtent = minExtent;
+}
+
+/*!
+  Get the minimum extent
+  \sa extent(), setMinimumExtent()
+*/
+double QwtAbstractScaleDraw::minimumExtent() const
+{
+    return d_data->minExtent;
+}
+
+/*!
+  Set the length of the ticks
+
+  \param tickType Tick type
+  \param length New length
+
+  \warning the length is limited to [0..1000]
+*/
+void QwtAbstractScaleDraw::setTickLength(
+    QwtScaleDiv::TickType tickType, double length )
+{
+    if ( tickType < QwtScaleDiv::MinorTick ||
+        tickType > QwtScaleDiv::MajorTick )
+    {
+        return;
+    }
+
+    if ( length < 0.0 )
+        length = 0.0;
+
+    const double maxTickLen = 1000.0;
+    if ( length > maxTickLen )
+        length = maxTickLen;
+
+    d_data->tickLength[tickType] = length;
+}
+
+/*!
+    Return the length of the ticks
+
+    \sa setTickLength(), maxTickLength()
+*/
+double QwtAbstractScaleDraw::tickLength( QwtScaleDiv::TickType tickType ) const
+{
+    if ( tickType < QwtScaleDiv::MinorTick ||
+        tickType > QwtScaleDiv::MajorTick )
+    {
+        return 0;
+    }
+
+    return d_data->tickLength[tickType];
+}
+
+/*!
+   \return Length of the longest tick
+
+   Useful for layout calculations
+   \sa tickLength(), setTickLength()
+*/
+double QwtAbstractScaleDraw::maxTickLength() const
+{
+    double length = 0.0;
+    for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
+        length = qMax( length, d_data->tickLength[i] );
+
+    return length;
+}
+
+/*!
+  \brief Convert a value into its representing label
+
+  The value is converted to a plain text using
+  QLocale::system().toString(value).
+  This method is often overloaded by applications to have individual
+  labels.
+
+  \param value Value
+  \return Label string.
+*/
+QwtText QwtAbstractScaleDraw::label( double value ) const
+{
+    return QLocale().toString( value );
+}
+
+/*!
+   \brief Convert a value into its representing label and cache it.
+
+   The conversion between value and label is called very often
+   in the layout and painting code. Unfortunately the
+   calculation of the label sizes might be slow (really slow
+   for rich text in Qt4), so it's necessary to cache the labels.
+
+   \param font Font
+   \param value Value
+
+   \return Tick label
+*/
+const QwtText &QwtAbstractScaleDraw::tickLabel(
+    const QFont &font, double value ) const
+{
+    QMap<double, QwtText>::const_iterator it = d_data->labelCache.find( value );
+    if ( it == d_data->labelCache.end() )
+    {
+        QwtText lbl = label( value );
+        lbl.setRenderFlags( 0 );
+        lbl.setLayoutAttribute( QwtText::MinimumLayout );
+
+        ( void )lbl.textSize( font ); // initialize the internal cache
+
+        it = d_data->labelCache.insert( value, lbl );
+    }
+
+    return ( *it );
+}
+
+/*!
+   Invalidate the cache used by QwtAbstractScaleDraw::tickLabel
+
+   The cache is invalidated, when a new QwtScaleDiv is set. If
+   the labels need to be changed. while the same QwtScaleDiv is set,
+   invalidateCache() needs to be called manually.
+*/
+void QwtAbstractScaleDraw::invalidateCache()
+{
+    d_data->labelCache.clear();
+}
Index: trunk/BNC/qwt/qwt_abstract_scale_draw.h
===================================================================
--- trunk/BNC/qwt/qwt_abstract_scale_draw.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_abstract_scale_draw.h	(revision 4271)
@@ -0,0 +1,139 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_ABSTRACT_SCALE_DRAW_H
+#define QWT_ABSTRACT_SCALE_DRAW_H
+
+#include "qwt_global.h"
+#include "qwt_scale_div.h"
+#include "qwt_text.h"
+
+class QPalette;
+class QPainter;
+class QFont;
+class QwtScaleTransformation;
+class QwtScaleMap;
+
+/*!
+  \brief A abstract base class for drawing scales
+
+  QwtAbstractScaleDraw can be used to draw linear or logarithmic scales.
+
+  After a scale division has been specified as a QwtScaleDiv object
+  using QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s),
+  the scale can be drawn with the QwtAbstractScaleDraw::draw() member.
+*/
+class QWT_EXPORT QwtAbstractScaleDraw
+{
+public:
+
+    /*!
+       Components of a scale
+       \sa enableComponent(), hasComponent
+    */
+    enum ScaleComponent
+    {
+        //! Backbone = the line where the ticks are located
+        Backbone = 0x01,
+
+        //! Ticks
+        Ticks = 0x02,
+
+        //! Labels
+        Labels = 0x04
+    };
+
+    //! Scale components
+    typedef QFlags<ScaleComponent> ScaleComponents;
+
+    QwtAbstractScaleDraw();
+    virtual ~QwtAbstractScaleDraw();
+
+    void setScaleDiv( const QwtScaleDiv &s );
+    const QwtScaleDiv& scaleDiv() const;
+
+    void setTransformation( QwtScaleTransformation * );
+    const QwtScaleMap &scaleMap() const;
+    QwtScaleMap &scaleMap();
+
+    void enableComponent( ScaleComponent, bool enable = true );
+    bool hasComponent( ScaleComponent ) const;
+
+    void setTickLength( QwtScaleDiv::TickType, double length );
+    double tickLength( QwtScaleDiv::TickType ) const;
+    double maxTickLength() const;
+
+    void setSpacing( double margin );
+    double spacing() const;
+
+    void setPenWidth( int width );
+    int penWidth() const;
+
+    virtual void draw( QPainter *, const QPalette & ) const;
+
+    virtual QwtText label( double ) const;
+
+    /*!
+      Calculate the extent
+
+      The extent is the distcance from the baseline to the outermost
+      pixel of the scale draw in opposite to its orientation.
+      It is at least minimumExtent() pixels.
+
+      \sa setMinimumExtent(), minimumExtent()
+    */
+    virtual double extent( const QFont & ) const = 0;
+
+    void setMinimumExtent( double );
+    double minimumExtent() const;
+
+protected:
+    /*!
+       Draw a tick
+
+       \param painter Painter
+       \param value Value of the tick
+       \param len Lenght of the tick
+
+       \sa drawBackbone(), drawLabel()
+    */
+    virtual void drawTick( QPainter *painter, double value, double len ) const = 0;
+
+    /*!
+      Draws the baseline of the scale
+      \param painter Painter
+
+      \sa drawTick(), drawLabel()
+    */
+    virtual void drawBackbone( QPainter *painter ) const = 0;
+
+    /*!
+        Draws the label for a major scale tick
+
+        \param painter Painter
+        \param value Value
+
+        \sa drawTick(), drawBackbone()
+    */
+    virtual void drawLabel( QPainter *painter, double value ) const = 0;
+
+    void invalidateCache();
+    const QwtText &tickLabel( const QFont &, double value ) const;
+
+private:
+    QwtAbstractScaleDraw( const QwtAbstractScaleDraw & );
+    QwtAbstractScaleDraw &operator=( const QwtAbstractScaleDraw & );
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtAbstractScaleDraw::ScaleComponents )
+
+#endif
Index: trunk/BNC/qwt/qwt_clipper.cpp
===================================================================
--- trunk/BNC/qwt/qwt_clipper.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_clipper.cpp	(revision 4271)
@@ -0,0 +1,486 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_clipper.h"
+#include "qwt_point_polar.h"
+#include <qrect.h>
+
+#if QT_VERSION < 0x040601
+#define qAtan(x) ::atan(x)
+#endif
+
+namespace QwtClip
+{
+    // some templates used for inlining
+    template <class Point, typename T> class LeftEdge;
+    template <class Point, typename T> class RightEdge;
+    template <class Point, typename T> class TopEdge;
+    template <class Point, typename T> class BottomEdge;
+
+    template <class Point> class PointBuffer;
+}
+
+template <class Point, typename Value>
+class QwtClip::LeftEdge
+{
+public:
+    inline LeftEdge( Value x1, Value, Value, Value ):
+        d_x1( x1 )
+    {
+    }
+
+    inline bool isInside( const Point &p  ) const
+    {
+        return p.x() >= d_x1;
+    }
+
+    inline Point intersection( const Point &p1, const Point &p2 ) const
+    {
+        double dy = ( p1.y() - p2.y() ) / double( p1.x() - p2.x() );
+        return Point( d_x1, ( Value ) ( p2.y() + ( d_x1 - p2.x() ) * dy ) );
+    }
+private:
+    const Value d_x1;
+};
+
+template <class Point, typename Value>
+class QwtClip::RightEdge
+{
+public:
+    inline RightEdge( Value, Value x2, Value, Value ):
+        d_x2( x2 )
+    {
+    }
+
+    inline bool isInside( const Point &p  ) const
+    {
+        return p.x() <= d_x2;
+    }
+
+    inline Point intersection( const Point &p1, const Point &p2 ) const
+    {
+        double dy = ( p1.y() - p2.y() ) / double( p1.x() - p2.x() );
+        return Point( d_x2, ( Value ) ( p2.y() + ( d_x2 - p2.x() ) * dy ) );
+    }
+
+private:
+    const Value d_x2;
+};
+
+template <class Point, typename Value>
+class QwtClip::TopEdge
+{
+public:
+    inline TopEdge( Value, Value, Value y1, Value ):
+        d_y1( y1 )
+    {
+    }
+
+    inline bool isInside( const Point &p  ) const
+    {
+        return p.y() >= d_y1;
+    }
+
+    inline Point intersection( const Point &p1, const Point &p2 ) const
+    {
+        double dx = ( p1.x() - p2.x() ) / double( p1.y() - p2.y() );
+        return Point( ( Value )( p2.x() + ( d_y1 - p2.y() ) * dx ), d_y1 );
+    }
+
+private:
+    const Value d_y1;
+};
+
+template <class Point, typename Value>
+class QwtClip::BottomEdge
+{
+public:
+    inline BottomEdge( Value, Value, Value, Value y2 ):
+        d_y2( y2 )
+    {
+    }
+
+    inline bool isInside( const Point &p ) const
+    {
+        return p.y() <= d_y2;
+    }
+
+    inline Point intersection( const Point &p1, const Point &p2 ) const
+    {
+        double dx = ( p1.x() - p2.x() ) / double( p1.y() - p2.y() );
+        return Point( ( Value )( p2.x() + ( d_y2 - p2.y() ) * dx ), d_y2 );
+    }
+
+private:
+    const Value d_y2;
+};
+
+template<class Point>
+class QwtClip::PointBuffer
+{
+public:
+    PointBuffer( int capacity = 0 ):
+        m_capacity( 0 ),
+        m_size( 0 ),
+        m_buffer( NULL )
+    {
+        if ( capacity > 0 )
+            reserve( capacity );
+    }
+
+    ~PointBuffer()
+    {
+        if ( m_buffer )
+            qFree( m_buffer );
+    }
+
+    inline void setPoints( int numPoints, const Point *points )
+    {
+        reserve( numPoints );
+
+        m_size = numPoints;
+        qMemCopy( m_buffer, points, m_size * sizeof( Point ) );
+    }
+
+    inline void reset() 
+    { 
+        m_size = 0; 
+    }
+
+    inline int size() const 
+    { 
+        return m_size; 
+    }
+
+    inline Point *data() const 
+    { 
+        return m_buffer; 
+    }
+
+    inline Point &operator[]( int i ) 
+    { 
+        return m_buffer[i]; 
+    }
+
+    inline const Point &operator[]( int i ) const 
+    { 
+        return m_buffer[i]; 
+    }
+
+    inline void add( const Point &point )
+    {
+        if ( m_capacity <= m_size )
+            reserve( m_size + 1 );
+
+        m_buffer[m_size++] = point;
+    }
+
+private:
+    inline void reserve( int size )
+    {
+        if ( m_capacity == 0 )
+            m_capacity = 1;
+
+        while ( m_capacity < size )
+            m_capacity *= 2;
+
+        m_buffer = ( Point * ) qRealloc( 
+            m_buffer, m_capacity * sizeof( Point ) );
+    }
+
+    int m_capacity;
+    int m_size;
+    Point *m_buffer;
+};
+
+using namespace QwtClip;
+
+template <class Polygon, class Rect, class Point, typename T>
+class QwtPolygonClipper
+{
+public:
+    QwtPolygonClipper( const Rect &clipRect ):
+        d_clipRect( clipRect )
+    {
+    }
+
+    Polygon clipPolygon( const Polygon &polygon, bool closePolygon ) const
+    {
+#if 0
+        if ( d_clipRect.contains( polygon.boundingRect() ) )
+            return polygon;
+#endif
+
+        PointBuffer<Point> points1;
+        PointBuffer<Point> points2( qMin( 256, polygon.size() ) );
+
+        points1.setPoints( polygon.size(), polygon.data() );
+
+        clipEdge< LeftEdge<Point, T> >( closePolygon, points1, points2 );
+        clipEdge< RightEdge<Point, T> >( closePolygon, points2, points1 );
+        clipEdge< TopEdge<Point, T> >( closePolygon, points1, points2 );
+        clipEdge< BottomEdge<Point, T> >( closePolygon, points2, points1 );
+
+        Polygon p;
+        p.resize( points1.size() );
+        qMemCopy( p.data(), points1.data(), points1.size() * sizeof( Point ) );
+
+        return p;
+    }
+
+private:
+    template <class Edge>
+    inline void clipEdge( bool closePolygon,
+        PointBuffer<Point> &points, PointBuffer<Point> &clippedPoints ) const
+    {
+        clippedPoints.reset();
+
+        if ( points.size() < 2 )
+        {
+            if ( points.size() == 1 )
+                clippedPoints.add( points[0] );
+            return;
+        }
+
+        const Edge edge( d_clipRect.x(), d_clipRect.x() + d_clipRect.width(),
+            d_clipRect.y(), d_clipRect.y() + d_clipRect.height() );
+
+        int lastPos, start;
+        if ( closePolygon )
+        {
+            start = 0;
+            lastPos = points.size() - 1;
+        }
+        else
+        {
+            start = 1;
+            lastPos = 0;
+
+            if ( edge.isInside( points[0] ) )
+                clippedPoints.add( points[0] );
+        }
+
+        const uint nPoints = points.size();
+        for ( uint i = start; i < nPoints; i++ )
+        {
+            const Point &p1 = points[i];
+            const Point &p2 = points[lastPos];
+
+            if ( edge.isInside( p1 ) )
+            {
+                if ( edge.isInside( p2 ) )
+                {
+                    clippedPoints.add( p1 );
+                }
+                else
+                {
+                    clippedPoints.add( edge.intersection( p1, p2 ) );
+                    clippedPoints.add( p1 );
+                }
+            }
+            else
+            {
+                if ( edge.isInside( p2 ) )
+                {
+                    clippedPoints.add( edge.intersection( p1, p2 ) );
+                }
+            }
+            lastPos = i;
+        }
+    }
+
+    const Rect d_clipRect;
+};
+
+class QwtCircleClipper
+{
+public:
+    QwtCircleClipper( const QRectF &r );
+    QVector<QwtInterval> clipCircle( const QPointF &, double radius ) const;
+
+private:
+    enum Edge
+    {
+        Left,
+        Top,
+        Right,
+        Bottom,
+
+        NEdges
+    };
+
+    QList<QPointF> cuttingPoints(
+        Edge, const QPointF &pos, double radius ) const;
+
+    double toAngle( const QPointF &, const QPointF & ) const;
+
+    const QRectF d_rect;
+};
+
+
+QwtCircleClipper::QwtCircleClipper( const QRectF &r ):
+    d_rect( r )
+{
+}
+
+QVector<QwtInterval> QwtCircleClipper::clipCircle(
+    const QPointF &pos, double radius ) const
+{
+    QList<QPointF> points;
+    for ( int edge = 0; edge < NEdges; edge++ )
+        points += cuttingPoints( ( Edge )edge, pos, radius );
+
+    QVector<QwtInterval> intv;
+    if ( points.size() <= 0 )
+    {
+        QRectF cRect( 0, 0, 2 * radius, 2 * radius );
+        cRect.moveCenter( pos );
+        if ( d_rect.contains( cRect ) )
+            intv += QwtInterval( 0.0, 2 * M_PI );
+    }
+    else
+    {
+        QList<double> angles;
+        for ( int i = 0; i < points.size(); i++ )
+            angles += toAngle( pos, points[i] );
+        qSort( angles );
+
+        const int in = d_rect.contains( qwtPolar2Pos( pos, radius,
+            angles[0] + ( angles[1] - angles[0] ) / 2 ) );
+
+        if ( in )
+        {
+            for ( int i = 0; i < angles.size() - 1; i += 2 )
+                intv += QwtInterval( angles[i], angles[i+1] );
+        }
+        else
+        {
+            for ( int i = 1; i < angles.size() - 1; i += 2 )
+                intv += QwtInterval( angles[i], angles[i+1] );
+            intv += QwtInterval( angles.last(), angles.first() );
+        }
+    }
+
+    return intv;
+}
+
+double QwtCircleClipper::toAngle(
+    const QPointF &from, const QPointF &to ) const
+{
+    if ( from.x() == to.x() )
+        return from.y() <= to.y() ? M_PI / 2.0 : 3 * M_PI / 2.0;
+
+    const double m = qAbs( ( to.y() - from.y() ) / ( to.x() - from.x() ) );
+
+    double angle = qAtan( m );
+    if ( to.x() > from.x() )
+    {
+        if ( to.y() > from.y() )
+            angle = 2 * M_PI - angle;
+    }
+    else
+    {
+        if ( to.y() > from.y() )
+            angle = M_PI + angle;
+        else
+            angle = M_PI - angle;
+    }
+
+    return angle;
+}
+
+QList<QPointF> QwtCircleClipper::cuttingPoints(
+    Edge edge, const QPointF &pos, double radius ) const
+{
+    QList<QPointF> points;
+
+    if ( edge == Left || edge == Right )
+    {
+        const double x = ( edge == Left ) ? d_rect.left() : d_rect.right();
+        if ( qAbs( pos.x() - x ) < radius )
+        {
+            const double off = qSqrt( qwtSqr( radius ) - qwtSqr( pos.x() - x ) );
+            const double m_y1 = pos.y() + off;
+            if ( m_y1 >= d_rect.top() && m_y1 <= d_rect.bottom() )
+                points += QPointF( x, m_y1 );
+
+            const double m_y2 = pos.y() - off;
+            if ( m_y2 >= d_rect.top() && m_y2 <= d_rect.bottom() )
+                points += QPointF( x, m_y2 );
+        }
+    }
+    else
+    {
+        const double y = ( edge == Top ) ? d_rect.top() : d_rect.bottom();
+        if ( qAbs( pos.y() - y ) < radius )
+        {
+            const double off = qSqrt( qwtSqr( radius ) - qwtSqr( pos.y() - y ) );
+            const double x1 = pos.x() + off;
+            if ( x1 >= d_rect.left() && x1 <= d_rect.right() )
+                points += QPointF( x1, y );
+
+            const double m_x2 = pos.x() - off;
+            if ( m_x2 >= d_rect.left() && m_x2 <= d_rect.right() )
+                points += QPointF( m_x2, y );
+        }
+    }
+    return points;
+}
+
+/*!
+   Sutherland-Hodgman polygon clipping
+
+   \param clipRect Clip rectangle
+   \param polygon Polygon
+   \param closePolygon True, when the polygon is closed
+
+   \return Clipped polygon
+*/
+QPolygon QwtClipper::clipPolygon(
+    const QRect &clipRect, const QPolygon &polygon, bool closePolygon )
+{
+    QwtPolygonClipper<QPolygon, QRect, QPoint, int> clipper( clipRect );
+    return clipper.clipPolygon( polygon, closePolygon );
+}
+
+/*!
+   Sutherland-Hodgman polygon clipping
+
+   \param clipRect Clip rectangle
+   \param polygon Polygon
+   \param closePolygon True, when the polygon is closed
+
+   \return Clipped polygon
+*/
+QPolygonF QwtClipper::clipPolygonF(
+    const QRectF &clipRect, const QPolygonF &polygon, bool closePolygon )
+{
+    QwtPolygonClipper<QPolygonF, QRectF, QPointF, double> clipper( clipRect );
+    return clipper.clipPolygon( polygon, closePolygon );
+}
+
+/*!
+   Circle clipping
+
+   clipCircle() devides a circle into intervals of angles representing arcs
+   of the circle. When the circle is completely inside the clip rectangle
+   an interval [0.0, 2 * M_PI] is returned.
+
+   \param clipRect Clip rectangle
+   \param center Center of the circle
+   \param radius Radius of the circle
+
+   \return Arcs of the circle
+*/
+QVector<QwtInterval> QwtClipper::clipCircle( const QRectF &clipRect,
+    const QPointF &center, double radius )
+{
+    QwtCircleClipper clipper( clipRect );
+    return clipper.clipCircle( center, radius );
+}
Index: trunk/BNC/qwt/qwt_clipper.h
===================================================================
--- trunk/BNC/qwt/qwt_clipper.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_clipper.h	(revision 4271)
@@ -0,0 +1,37 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_CLIPPER_H
+#define QWT_CLIPPER_H
+
+#include "qwt_global.h"
+#include "qwt_interval.h"
+#include <qpolygon.h>
+#include <qvector.h>
+
+class QRect;
+class QRectF;
+
+/*!
+  \brief Some clipping algos
+*/
+
+class QWT_EXPORT QwtClipper
+{
+public:
+    static QPolygon clipPolygon( const QRect &, 
+        const QPolygon &, bool closePolygon = false );
+    static QPolygonF clipPolygonF( const QRectF &, 
+        const QPolygonF &, bool closePolygon = false );
+
+    static QVector<QwtInterval> clipCircle(
+        const QRectF &, const QPointF &, double radius );
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_color_map.cpp
===================================================================
--- trunk/BNC/qwt/qwt_color_map.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_color_map.cpp	(revision 4271)
@@ -0,0 +1,440 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_color_map.h"
+#include "qwt_math.h"
+#include "qwt_interval.h"
+#include <qnumeric.h>
+
+class QwtLinearColorMap::ColorStops
+{
+public:
+    ColorStops()
+    {
+        _stops.reserve( 256 );
+    }
+
+    void insert( double pos, const QColor &color );
+    QRgb rgb( QwtLinearColorMap::Mode, double pos ) const;
+
+    QVector<double> stops() const;
+
+private:
+
+    class ColorStop
+    {
+    public:
+        ColorStop():
+            pos( 0.0 ),
+            rgb( 0 )
+        {
+        };
+
+        ColorStop( double p, const QColor &c ):
+            pos( p ),
+            rgb( c.rgb() )
+        {
+            r = qRed( rgb );
+            g = qGreen( rgb );
+            b = qBlue( rgb );
+        }
+
+        double pos;
+        QRgb rgb;
+        int r, g, b;
+    };
+
+    inline int findUpper( double pos ) const;
+    QVector<ColorStop> _stops;
+};
+
+void QwtLinearColorMap::ColorStops::insert( double pos, const QColor &color )
+{
+    // Lookups need to be very fast, insertions are not so important.
+    // Anyway, a balanced tree is what we need here. TODO ...
+
+    if ( pos < 0.0 || pos > 1.0 )
+        return;
+
+    int index;
+    if ( _stops.size() == 0 )
+    {
+        index = 0;
+        _stops.resize( 1 );
+    }
+    else
+    {
+        index = findUpper( pos );
+        if ( index == _stops.size() ||
+                qAbs( _stops[index].pos - pos ) >= 0.001 )
+        {
+            _stops.resize( _stops.size() + 1 );
+            for ( int i = _stops.size() - 1; i > index; i-- )
+                _stops[i] = _stops[i-1];
+        }
+    }
+
+    _stops[index] = ColorStop( pos, color );
+}
+
+inline QVector<double> QwtLinearColorMap::ColorStops::stops() const
+{
+    QVector<double> positions( _stops.size() );
+    for ( int i = 0; i < _stops.size(); i++ )
+        positions[i] = _stops[i].pos;
+    return positions;
+}
+
+inline int QwtLinearColorMap::ColorStops::findUpper( double pos ) const
+{
+    int index = 0;
+    int n = _stops.size();
+
+    const ColorStop *stops = _stops.data();
+
+    while ( n > 0 )
+    {
+        const int half = n >> 1;
+        const int middle = index + half;
+
+        if ( stops[middle].pos <= pos )
+        {
+            index = middle + 1;
+            n -= half + 1;
+        }
+        else
+            n = half;
+    }
+
+    return index;
+}
+
+inline QRgb QwtLinearColorMap::ColorStops::rgb(
+    QwtLinearColorMap::Mode mode, double pos ) const
+{
+    if ( pos <= 0.0 )
+        return _stops[0].rgb;
+    if ( pos >= 1.0 )
+        return _stops[ _stops.size() - 1 ].rgb;
+
+    const int index = findUpper( pos );
+    if ( mode == FixedColors )
+    {
+        return _stops[index-1].rgb;
+    }
+    else
+    {
+        const ColorStop &s1 = _stops[index-1];
+        const ColorStop &s2 = _stops[index];
+
+        const double ratio = ( pos - s1.pos ) / ( s2.pos - s1.pos );
+
+        const int r = s1.r + qRound( ratio * ( s2.r - s1.r ) );
+        const int g = s1.g + qRound( ratio * ( s2.g - s1.g ) );
+        const int b = s1.b + qRound( ratio * ( s2.b - s1.b ) );
+
+        return qRgb( r, g, b );
+    }
+}
+
+//! Constructor
+QwtColorMap::QwtColorMap( Format format ):
+    d_format( format )
+{
+}
+
+//! Destructor
+QwtColorMap::~QwtColorMap()
+{
+}
+
+/*!
+   Build and return a color map of 256 colors
+
+   The color table is needed for rendering indexed images in combination
+   with using colorIndex().
+
+   \param interval Range for the values
+   \return A color table, that can be used for a QImage
+*/
+QVector<QRgb> QwtColorMap::colorTable( const QwtInterval &interval ) const
+{
+    QVector<QRgb> table( 256 );
+
+    if ( interval.isValid() )
+    {
+        const double step = interval.width() / ( table.size() - 1 );
+        for ( int i = 0; i < table.size(); i++ )
+            table[i] = rgb( interval, interval.minValue() + step * i );
+    }
+
+    return table;
+}
+
+class QwtLinearColorMap::PrivateData
+{
+public:
+    ColorStops colorStops;
+    QwtLinearColorMap::Mode mode;
+};
+
+/*!
+   Build a color map with two stops at 0.0 and 1.0. The color
+   at 0.0 is Qt::blue, at 1.0 it is Qt::yellow.
+
+   \param format Preferred format of the color map
+*/
+QwtLinearColorMap::QwtLinearColorMap( QwtColorMap::Format format ):
+    QwtColorMap( format )
+{
+    d_data = new PrivateData;
+    d_data->mode = ScaledColors;
+
+    setColorInterval( Qt::blue, Qt::yellow );
+}
+
+/*!
+   Build a color map with two stops at 0.0 and 1.0.
+
+   \param color1 Color used for the minimum value of the value interval
+   \param color2 Color used for the maximum value of the value interval
+   \param format Preferred format of the coor map
+*/
+QwtLinearColorMap::QwtLinearColorMap( const QColor &color1,
+        const QColor &color2, QwtColorMap::Format format ):
+    QwtColorMap( format )
+{
+    d_data = new PrivateData;
+    d_data->mode = ScaledColors;
+    setColorInterval( color1, color2 );
+}
+
+//! Destructor
+QwtLinearColorMap::~QwtLinearColorMap()
+{
+    delete d_data;
+}
+
+/*!
+   \brief Set the mode of the color map
+
+   FixedColors means the color is calculated from the next lower
+   color stop. ScaledColors means the color is calculated
+   by interpolating the colors of the adjacent stops.
+
+   \sa mode()
+*/
+void QwtLinearColorMap::setMode( Mode mode )
+{
+    d_data->mode = mode;
+}
+
+/*!
+   \return Mode of the color map
+   \sa setMode()
+*/
+QwtLinearColorMap::Mode QwtLinearColorMap::mode() const
+{
+    return d_data->mode;
+}
+
+/*!
+   Set the color range
+
+   Add stops at 0.0 and 1.0.
+
+   \param color1 Color used for the minimum value of the value interval
+   \param color2 Color used for the maximum value of the value interval
+
+   \sa color1(), color2()
+*/
+void QwtLinearColorMap::setColorInterval(
+    const QColor &color1, const QColor &color2 )
+{
+    d_data->colorStops = ColorStops();
+    d_data->colorStops.insert( 0.0, color1 );
+    d_data->colorStops.insert( 1.0, color2 );
+}
+
+/*!
+   Add a color stop
+
+   The value has to be in the range [0.0, 1.0].
+   F.e. a stop at position 17.0 for a range [10.0,20.0] must be
+   passed as: (17.0 - 10.0) / (20.0 - 10.0)
+
+   \param value Value between [0.0, 1.0]
+   \param color Color stop
+*/
+void QwtLinearColorMap::addColorStop( double value, const QColor& color )
+{
+    if ( value >= 0.0 && value <= 1.0 )
+        d_data->colorStops.insert( value, color );
+}
+
+/*!
+   Return all positions of color stops in increasing order
+*/
+QVector<double> QwtLinearColorMap::colorStops() const
+{
+    return d_data->colorStops.stops();
+}
+
+/*!
+  \return the first color of the color range
+  \sa setColorInterval()
+*/
+QColor QwtLinearColorMap::color1() const
+{
+    return QColor( d_data->colorStops.rgb( d_data->mode, 0.0 ) );
+}
+
+/*!
+  \return the second color of the color range
+  \sa setColorInterval()
+*/
+QColor QwtLinearColorMap::color2() const
+{
+    return QColor( d_data->colorStops.rgb( d_data->mode, 1.0 ) );
+}
+
+/*!
+  Map a value of a given interval into a rgb value
+
+  \param interval Range for all values
+  \param value Value to map into a rgb value
+*/
+QRgb QwtLinearColorMap::rgb(
+    const QwtInterval &interval, double value ) const
+{
+    if ( qIsNaN(value) )
+        return qRgba(0, 0, 0, 0);
+
+    const double width = interval.width();
+
+    double ratio = 0.0;
+    if ( width > 0.0 )
+        ratio = ( value - interval.minValue() ) / width;
+
+    return d_data->colorStops.rgb( d_data->mode, ratio );
+}
+
+/*!
+  Map a value of a given interval into a color index, between 0 and 255
+
+  \param interval Range for all values
+  \param value Value to map into a color index
+*/
+unsigned char QwtLinearColorMap::colorIndex(
+    const QwtInterval &interval, double value ) const
+{
+    const double width = interval.width();
+
+    if ( qIsNaN(value) || width <= 0.0 || value <= interval.minValue() )
+        return 0;
+
+    if ( value >= interval.maxValue() )
+        return ( unsigned char )255;
+
+    const double ratio = ( value - interval.minValue() ) / width;
+
+    unsigned char index;
+    if ( d_data->mode == FixedColors )
+        index = ( unsigned char )( ratio * 255 ); // always floor
+    else
+        index = ( unsigned char )qRound( ratio * 255 );
+
+    return index;
+}
+
+class QwtAlphaColorMap::PrivateData
+{
+public:
+    QColor color;
+    QRgb rgb;
+};
+
+
+/*!
+   Constructor
+   \param color Color of the map
+*/
+QwtAlphaColorMap::QwtAlphaColorMap( const QColor &color ):
+    QwtColorMap( QwtColorMap::RGB )
+{
+    d_data = new PrivateData;
+    d_data->color = color;
+    d_data->rgb = color.rgb() & qRgba( 255, 255, 255, 0 );
+}
+
+//! Destructor
+QwtAlphaColorMap::~QwtAlphaColorMap()
+{
+    delete d_data;
+}
+
+/*!
+   Set the color
+
+   \param color Color
+   \sa color()
+*/
+void QwtAlphaColorMap::setColor( const QColor &color )
+{
+    d_data->color = color;
+    d_data->rgb = color.rgb();
+}
+
+/*!
+  \return the color
+  \sa setColor()
+*/
+QColor QwtAlphaColorMap::color() const
+{
+    return d_data->color;
+}
+
+/*!
+  \brief Map a value of a given interval into a alpha value
+
+  alpha := (value - interval.minValue()) / interval.width();
+
+  \param interval Range for all values
+  \param value Value to map into a rgb value
+  \return rgb value, with an alpha value
+*/
+QRgb QwtAlphaColorMap::rgb( const QwtInterval &interval, double value ) const
+{
+    const double width = interval.width();
+    if ( !qIsNaN(value) && width >= 0.0 )
+    {
+        const double ratio = ( value - interval.minValue() ) / width;
+        int alpha = qRound( 255 * ratio );
+        if ( alpha < 0 )
+            alpha = 0;
+        if ( alpha > 255 )
+            alpha = 255;
+
+        return d_data->rgb | ( alpha << 24 );
+    }
+    return d_data->rgb;
+}
+
+/*!
+  Dummy function, needed to be implemented as it is pure virtual
+  in QwtColorMap. Color indices make no sense in combination with
+  an alpha channel.
+
+  \return Always 0
+*/
+unsigned char QwtAlphaColorMap::colorIndex(
+    const QwtInterval &, double ) const
+{
+    return 0;
+}
Index: trunk/BNC/qwt/qwt_color_map.h
===================================================================
--- trunk/BNC/qwt/qwt_color_map.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_color_map.h	(revision 4271)
@@ -0,0 +1,198 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_COLOR_MAP_H
+#define QWT_COLOR_MAP_H
+
+#include "qwt_global.h"
+#include "qwt_interval.h"
+#include <qcolor.h>
+#include <qvector.h>
+
+/*!
+  \brief QwtColorMap is used to map values into colors.
+
+  For displaying 3D data on a 2D plane the 3rd dimension is often
+  displayed using colors, like f.e in a spectrogram.
+
+  Each color map is optimized to return colors for only one of the
+  following image formats:
+
+  - QImage::Format_Indexed8\n
+  - QImage::Format_ARGB32\n
+
+  \sa QwtPlotSpectrogram, QwtScaleWidget
+*/
+
+class QWT_EXPORT QwtColorMap
+{
+public:
+    /*!
+        Format for color mapping
+        \sa rgb(), colorIndex(), colorTable()
+    */
+
+    enum Format
+    {
+        //! The map is intended to map into QRgb values.
+        RGB,
+
+        /*!
+          The map is intended to map into 8 bit values, that
+          are indices into the color table.
+         */
+        Indexed
+    };
+
+    QwtColorMap( Format = QwtColorMap::RGB );
+    virtual ~QwtColorMap();
+
+    Format format() const;
+
+    /*!
+       Map a value of a given interval into a rgb value.
+       \param interval Range for the values
+       \param value Value
+       \return rgb value, corresponding to value
+    */
+    virtual QRgb rgb( const QwtInterval &interval,
+        double value ) const = 0;
+
+    /*!
+       Map a value of a given interval into a color index
+       \param interval Range for the values
+       \param value Value
+       \return color index, corresponding to value
+     */
+    virtual unsigned char colorIndex(
+        const QwtInterval &interval, double value ) const = 0;
+
+    QColor color( const QwtInterval &, double value ) const;
+    virtual QVector<QRgb> colorTable( const QwtInterval & ) const;
+
+private:
+    Format d_format;
+};
+
+/*!
+  \brief QwtLinearColorMap builds a color map from color stops.
+
+  A color stop is a color at a specific position. The valid
+  range for the positions is [0.0, 1.0]. When mapping a value
+  into a color it is translated into this interval according to mode().
+*/
+class QWT_EXPORT QwtLinearColorMap: public QwtColorMap
+{
+public:
+    /*!
+       Mode of color map
+       \sa setMode(), mode()
+    */
+    enum Mode
+    {
+        //! Return the color from the next lower color stop
+        FixedColors,
+
+        //! Interpolating the colors of the adjacent stops.
+        ScaledColors
+    };
+
+    QwtLinearColorMap( QwtColorMap::Format = QwtColorMap::RGB );
+    QwtLinearColorMap( const QColor &from, const QColor &to,
+        QwtColorMap::Format = QwtColorMap::RGB );
+
+    virtual ~QwtLinearColorMap();
+
+    void setMode( Mode );
+    Mode mode() const;
+
+    void setColorInterval( const QColor &color1, const QColor &color2 );
+    void addColorStop( double value, const QColor& );
+    QVector<double> colorStops() const;
+
+    QColor color1() const;
+    QColor color2() const;
+
+    virtual QRgb rgb( const QwtInterval &, double value ) const;
+    virtual unsigned char colorIndex(
+        const QwtInterval &, double value ) const;
+
+    class ColorStops;
+
+private:
+    // Disabled copy constructor and operator=
+    QwtLinearColorMap( const QwtLinearColorMap & );
+    QwtLinearColorMap &operator=( const QwtLinearColorMap & );
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+/*!
+  \brief QwtAlphaColorMap variies the alpha value of a color
+*/
+class QWT_EXPORT QwtAlphaColorMap: public QwtColorMap
+{
+public:
+    QwtAlphaColorMap( const QColor & = QColor( Qt::gray ) );
+    virtual ~QwtAlphaColorMap();
+
+    void setColor( const QColor & );
+    QColor color() const;
+
+    virtual QRgb rgb( const QwtInterval &, double value ) const;
+
+private:
+    QwtAlphaColorMap( const QwtAlphaColorMap & );
+    QwtAlphaColorMap &operator=( const QwtAlphaColorMap & );
+
+    virtual unsigned char colorIndex(
+        const QwtInterval &, double value ) const;
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+
+/*!
+   Map a value into a color
+
+   \param interval Valid interval for values
+   \param value Value
+
+   \return Color corresponding to value
+
+   \warning This method is slow for Indexed color maps. If it is
+            necessary to map many values, its better to get the
+            color table once and find the color using colorIndex().
+*/
+inline QColor QwtColorMap::color(
+    const QwtInterval &interval, double value ) const
+{
+    if ( d_format == RGB )
+    {
+        return QColor( rgb( interval, value ) );
+    }
+    else
+    {
+        const unsigned int index = colorIndex( interval, value );
+        return colorTable( interval )[index]; // slow
+    }
+}
+
+/*!
+   \return Intended format of the color map
+   \sa Format
+*/
+inline QwtColorMap::Format QwtColorMap::format() const
+{
+    return d_format;
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_column_symbol.cpp
===================================================================
--- trunk/BNC/qwt/qwt_column_symbol.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_column_symbol.cpp	(revision 4271)
@@ -0,0 +1,296 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_column_symbol.h"
+#include "qwt_math.h"
+#include "qwt_text.h"
+#include "qwt_painter.h"
+#include <qpainter.h>
+#include <qpalette.h>
+
+static void drawBox( QPainter *p, const QRectF &rect,
+    const QPalette &pal, double lw )
+{
+    if ( lw > 0.0 )
+    {
+        if ( rect.width() == 0.0 )
+        {
+            p->setPen( pal.dark().color() );
+            p->drawLine( rect.topLeft(), rect.bottomLeft() );
+            return;
+        }
+
+        if ( rect.height() == 0.0 )
+        {
+            p->setPen( pal.dark().color() );
+            p->drawLine( rect.topLeft(), rect.topRight() );
+            return;
+        }
+
+        lw = qMin( lw, rect.height() / 2.0 - 1.0 );
+        lw = qMin( lw, rect.width() / 2.0 - 1.0 );
+
+        const QRectF outerRect = rect.adjusted( 0, 0, 1, 1 );
+        QPolygonF polygon( outerRect );
+
+        if ( outerRect.width() > 2 * lw &&
+                outerRect.height() > 2 * lw )
+        {
+            const QRectF innerRect = outerRect.adjusted( lw, lw, -lw, -lw );
+            polygon = polygon.subtracted( innerRect );
+        }
+
+        p->setPen( Qt::NoPen );
+
+        p->setBrush( pal.dark() );
+        p->drawPolygon( polygon );
+    }
+
+    const QRectF windowRect = rect.adjusted( lw, lw, -lw + 1, -lw + 1 );
+    if ( windowRect.isValid() )
+        p->fillRect( windowRect, pal.window() );
+}
+
+static void drawPanel( QPainter *painter, const QRectF &rect,
+    const QPalette &pal, double lw )
+{
+    if ( lw > 0.0 )
+    {
+        if ( rect.width() == 0.0 )
+        {
+            painter->setPen( pal.window().color() );
+            painter->drawLine( rect.topLeft(), rect.bottomLeft() );
+            return;
+        }
+
+        if ( rect.height() == 0.0 )
+        {
+            painter->setPen( pal.window().color() );
+            painter->drawLine( rect.topLeft(), rect.topRight() );
+            return;
+        }
+
+        lw = qMin( lw, rect.height() / 2.0 - 1.0 );
+        lw = qMin( lw, rect.width() / 2.0 - 1.0 );
+
+        const QRectF outerRect = rect.adjusted( 0, 0, 1, 1 );
+        const QRectF innerRect = outerRect.adjusted( lw, lw, -lw, -lw );
+
+        QPolygonF lines[2];
+
+        lines[0] += outerRect.bottomLeft();
+        lines[0] += outerRect.topLeft();
+        lines[0] += outerRect.topRight();
+        lines[0] += innerRect.topRight();
+        lines[0] += innerRect.topLeft();
+        lines[0] += innerRect.bottomLeft();
+
+        lines[1] += outerRect.topRight();
+        lines[1] += outerRect.bottomRight();
+        lines[1] += outerRect.bottomLeft();
+        lines[1] += innerRect.bottomLeft();
+        lines[1] += innerRect.bottomRight();
+        lines[1] += innerRect.topRight();
+
+        painter->setPen( Qt::NoPen );
+
+        painter->setBrush( pal.light() );
+        painter->drawPolygon( lines[0] );
+        painter->setBrush( pal.dark() );
+        painter->drawPolygon( lines[1] );
+    }
+
+    painter->fillRect( rect.adjusted( lw, lw, -lw + 1, -lw + 1 ), pal.window() );
+}
+
+class QwtColumnSymbol::PrivateData
+{
+public:
+    PrivateData():
+        style( QwtColumnSymbol::Box ),
+        frameStyle( QwtColumnSymbol::Raised ),
+        lineWidth( 2 )
+    {
+        palette = QPalette( Qt::gray );
+    }
+
+    QwtColumnSymbol::Style style;
+    QwtColumnSymbol::FrameStyle frameStyle;
+
+    QPalette palette;
+    QwtText label;
+
+    int lineWidth;
+};
+
+/*!
+  Constructor
+
+  \param style Style of the symbol
+  \sa setStyle(), style(), Style
+*/
+QwtColumnSymbol::QwtColumnSymbol( Style style )
+{
+    d_data = new PrivateData();
+    d_data->style = style;
+}
+
+//! Destructor
+QwtColumnSymbol::~QwtColumnSymbol()
+{
+    delete d_data;
+}
+
+/*!
+  Specify the symbol style
+
+  \param style Style
+  \sa style(), setPalette()
+*/
+void QwtColumnSymbol::setStyle( Style style )
+{
+    d_data->style = style;
+}
+
+/*!
+  \return Current symbol style
+  \sa setStyle()
+*/
+QwtColumnSymbol::Style QwtColumnSymbol::style() const
+{
+    return d_data->style;
+}
+
+/*!
+  Assign a palette for the symbol
+
+  \param palette Palette
+  \sa palette(), setStyle()
+*/
+void QwtColumnSymbol::setPalette( const QPalette &palette )
+{
+    d_data->palette = palette;
+}
+
+/*!
+  \return Current palette
+  \sa setPalette()
+*/
+const QPalette& QwtColumnSymbol::palette() const
+{
+    return d_data->palette;
+}
+
+/*!
+   Set the frame, that is used for the Box style.
+
+   \param frameStyle Frame style
+   \sa frameStyle(), setLineWidth(), setStyle()
+*/
+void QwtColumnSymbol::setFrameStyle( FrameStyle frameStyle )
+{
+    d_data->frameStyle = frameStyle;
+}
+
+/*!
+  \return Current frame style, that is used for the Box style.
+  \sa setFrameStyle(), lineWidth(), setStyle()
+*/
+QwtColumnSymbol::FrameStyle QwtColumnSymbol::frameStyle() const
+{
+    return d_data->frameStyle;
+}
+
+/*!
+   Set the line width of the frame, that is used for the Box style.
+
+   \param width Width
+   \sa lineWidth(), setFrameStyle()
+*/
+void QwtColumnSymbol::setLineWidth( int width )
+{
+    if ( width < 0 )
+        width = 0;
+
+    d_data->lineWidth = width;
+}
+
+/*!
+  \return Line width of the frame, that is used for the Box style.
+  \sa setLineWidth(), frameStyle(), setStyle()
+*/
+int QwtColumnSymbol::lineWidth() const
+{
+    return d_data->lineWidth;
+}
+
+/*!
+  Draw the symbol depending on its style.
+
+  \param painter Painter
+  \param rect Directed rectangle
+
+  \sa drawBox()
+*/
+void QwtColumnSymbol::draw( QPainter *painter,
+    const QwtColumnRect &rect ) const
+{
+    painter->save();
+
+    switch ( d_data->style )
+    {
+        case QwtColumnSymbol::Box:
+        {
+            drawBox( painter, rect );
+            break;
+        }
+        default:;
+    }
+
+    painter->restore();
+}
+
+/*!
+  Draw the symbol when it is in Box style.
+
+  \param painter Painter
+  \param rect Directed rectangle
+
+  \sa draw()
+*/
+void QwtColumnSymbol::drawBox( QPainter *painter,
+    const QwtColumnRect &rect ) const
+{
+    QRectF r = rect.toRect();
+    if ( QwtPainter::roundingAlignment( painter ) )
+    {
+        r.setLeft( qRound( r.left() ) );
+        r.setRight( qRound( r.right() ) );
+        r.setTop( qRound( r.top() ) );
+        r.setBottom( qRound( r.bottom() ) );
+    }
+
+    switch ( d_data->frameStyle )
+    {
+        case QwtColumnSymbol::Raised:
+        {
+            ::drawPanel( painter, r, d_data->palette, d_data->lineWidth );
+            break;
+        }
+        case QwtColumnSymbol::Plain:
+        {
+            ::drawBox( painter, r, d_data->palette, d_data->lineWidth );
+            break;
+        }
+        default:
+        {
+            painter->fillRect( r, d_data->palette.window() );
+        }
+    }
+}
Index: trunk/BNC/qwt/qwt_column_symbol.h
===================================================================
--- trunk/BNC/qwt/qwt_column_symbol.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_column_symbol.h	(revision 4271)
@@ -0,0 +1,161 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_COLUMN_SYMBOL_H
+#define QWT_COLUMN_SYMBOL_H
+
+#include "qwt_global.h"
+#include "qwt_interval.h"
+#include <qpen.h>
+#include <qsize.h>
+#include <qrect.h>
+
+class QPainter;
+class QPalette;
+class QRect;
+class QwtText;
+
+/*!
+    \brief Directed rectangle representing bounding rectangle und orientation
+    of a column.
+*/
+class QWT_EXPORT QwtColumnRect
+{
+public:
+    //! Direction of the column
+    enum Direction
+    {
+        //! From left to right
+        LeftToRight,
+
+        //! From right to left
+        RightToLeft,
+
+        //! From bottom to top
+        BottomToTop,
+
+        //! From top to bottom
+        TopToBottom
+    };
+
+    //! Build an rectangle with invalid intervals directed BottomToTop.
+    QwtColumnRect():
+        direction( BottomToTop )
+    {
+    }
+
+    //! \return A normalized QRect built from the intervals
+    QRectF toRect() const
+    {
+        QRectF r( hInterval.minValue(), vInterval.minValue(),
+            hInterval.maxValue() - hInterval.minValue(),
+            vInterval.maxValue() - vInterval.minValue() );
+        r = r.normalized();
+
+        if ( hInterval.borderFlags() & QwtInterval::ExcludeMinimum )
+            r.adjust( 1, 0, 0, 0 );
+        if ( hInterval.borderFlags() & QwtInterval::ExcludeMaximum )
+            r.adjust( 0, 0, -1, 0 );
+        if ( vInterval.borderFlags() & QwtInterval::ExcludeMinimum )
+            r.adjust( 0, 1, 0, 0 );
+        if ( vInterval.borderFlags() & QwtInterval::ExcludeMaximum )
+            r.adjust( 0, 0, 0, -1 );
+
+        return r;
+    }
+
+    //! \return Orientation
+    Qt::Orientation orientation() const
+    {
+        if ( direction == LeftToRight || direction == RightToLeft )
+            return Qt::Horizontal;
+
+        return Qt::Vertical;
+    }
+
+    //! Interval for the horizontal coordinates
+    QwtInterval hInterval;
+
+    //! Interval for the vertical coordinates
+    QwtInterval vInterval;
+
+    //! Direction
+    Direction direction;
+};
+
+//! A drawing primitive for columns
+class QWT_EXPORT QwtColumnSymbol
+{
+public:
+    /*!
+      Style
+      \sa setStyle(), style()
+    */
+    enum Style
+    {
+        //! No Style, the symbol draws nothing
+        NoStyle = -1,
+
+        /*!
+          The column is painted with a frame depending on the frameStyle()
+          and lineWidth() using the palette().
+         */
+        Box,
+
+        /*!
+          Styles >= QwtColumnSymbol::UserStyle are reserved for derived
+          classes of QwtColumnSymbol that overload draw() with
+          additional application specific symbol types.
+         */
+        UserStyle = 1000
+    };
+
+    /*!
+      Frame Style used in Box style().
+      \sa Style, setFrameStyle(), frameStyle(), setStyle(), setPalette()
+     */
+    enum FrameStyle
+    {
+        //! No frame
+        NoFrame,
+
+        //! A plain frame style
+        Plain,
+
+        //! A raised frame style
+        Raised
+    };
+
+public:
+    QwtColumnSymbol( Style = NoStyle );
+    virtual ~QwtColumnSymbol();
+
+    void setFrameStyle( FrameStyle style );
+    FrameStyle frameStyle() const;
+
+    void setLineWidth( int width );
+    int lineWidth() const;
+
+    void setPalette( const QPalette & );
+    const QPalette &palette() const;
+
+    void setStyle( Style );
+    Style style() const;
+
+    virtual void draw( QPainter *, const QwtColumnRect & ) const;
+
+protected:
+    void drawBox( QPainter *, const QwtColumnRect & ) const;
+
+private:
+    class PrivateData;
+    PrivateData* d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_compat.h
===================================================================
--- trunk/BNC/qwt/qwt_compat.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_compat.h	(revision 4271)
@@ -0,0 +1,40 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef _QWT_COMPAT_H_
+#define _QWT_COMPAT_H_
+
+#include "qwt_global.h"
+#include <qlist.h>
+#include <qvector.h>
+#include <qpoint.h>
+#include <qsize.h>
+#include <qrect.h>
+#include <qpolygon.h>
+
+// A couple of definition for Qwt5 compatibility
+
+#define qwtMax qMax
+#define qwtMin qMin
+#define qwtAbs qAbs
+#define qwtRound qRound
+
+#define QwtArray QVector
+
+typedef QList<double> QwtValueList;
+typedef QPointF QwtDoublePoint;
+typedef QSizeF QwtDoubleSize;
+typedef QRectF QwtDoubleRect;
+
+typedef QPolygon QwtPolygon;
+typedef QPolygonF QwtPolygonF;
+typedef QwtInterval QwtDoubleInterval;
+typedef QwtPoint3D QwtDoublePoint3D;
+
+#endif
Index: trunk/BNC/qwt/qwt_curve_fitter.cpp
===================================================================
--- trunk/BNC/qwt/qwt_curve_fitter.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_curve_fitter.cpp	(revision 4271)
@@ -0,0 +1,405 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_curve_fitter.h"
+#include "qwt_math.h"
+#include "qwt_spline.h"
+#include <qstack.h>
+#include <qvector.h>
+
+#if QT_VERSION < 0x040601
+#define qFabs(x) ::fabs(x)
+#endif
+
+//! Constructor
+QwtCurveFitter::QwtCurveFitter()
+{
+}
+
+//! Destructor
+QwtCurveFitter::~QwtCurveFitter()
+{
+}
+
+class QwtSplineCurveFitter::PrivateData
+{
+public:
+    PrivateData():
+        fitMode( QwtSplineCurveFitter::Auto ),
+        splineSize( 250 )
+    {
+    }
+
+    QwtSpline spline;
+    QwtSplineCurveFitter::FitMode fitMode;
+    int splineSize;
+};
+
+//! Constructor
+QwtSplineCurveFitter::QwtSplineCurveFitter()
+{
+    d_data = new PrivateData;
+}
+
+//! Destructor
+QwtSplineCurveFitter::~QwtSplineCurveFitter()
+{
+    delete d_data;
+}
+
+/*!
+  Select the algorithm used for building the spline
+
+  \param mode Mode representing a spline algorithm
+  \sa fitMode()
+*/
+void QwtSplineCurveFitter::setFitMode( FitMode mode )
+{
+    d_data->fitMode = mode;
+}
+
+/*!
+  \return Mode representing a spline algorithm
+  \sa setFitMode()
+*/
+QwtSplineCurveFitter::FitMode QwtSplineCurveFitter::fitMode() const
+{
+    return d_data->fitMode;
+}
+
+/*!
+  Assign a spline
+
+  \param spline Spline
+  \sa spline()
+*/
+void QwtSplineCurveFitter::setSpline( const QwtSpline &spline )
+{
+    d_data->spline = spline;
+    d_data->spline.reset();
+}
+
+/*!
+  \return Spline
+  \sa setSpline()
+*/
+const QwtSpline &QwtSplineCurveFitter::spline() const
+{
+    return d_data->spline;
+}
+
+/*!
+  \return Spline
+  \sa setSpline()
+*/
+QwtSpline &QwtSplineCurveFitter::spline()
+{
+    return d_data->spline;
+}
+
+/*!
+   Assign a spline size ( has to be at least 10 points )
+
+   \param splineSize Spline size
+   \sa splineSize()
+*/
+void QwtSplineCurveFitter::setSplineSize( int splineSize )
+{
+    d_data->splineSize = qMax( splineSize, 10 );
+}
+
+/*!
+  \return Spline size
+  \sa setSplineSize()
+*/
+int QwtSplineCurveFitter::splineSize() const
+{
+    return d_data->splineSize;
+}
+
+/*!
+  Find a curve which has the best fit to a series of data points
+
+  \param points Series of data points
+  \return Curve points
+*/
+QPolygonF QwtSplineCurveFitter::fitCurve( const QPolygonF &points ) const
+{
+    const int size = points.size();
+    if ( size <= 2 )
+        return points;
+
+    FitMode fitMode = d_data->fitMode;
+    if ( fitMode == Auto )
+    {
+        fitMode = Spline;
+
+        const QPointF *p = points.data();
+        for ( int i = 1; i < size; i++ )
+        {
+            if ( p[i].x() <= p[i-1].x() )
+            {
+                fitMode = ParametricSpline;
+                break;
+            }
+        };
+    }
+
+    if ( fitMode == ParametricSpline )
+        return fitParametric( points );
+    else
+        return fitSpline( points );
+}
+
+QPolygonF QwtSplineCurveFitter::fitSpline( const QPolygonF &points ) const
+{
+    d_data->spline.setPoints( points );
+    if ( !d_data->spline.isValid() )
+        return points;
+
+    QPolygonF fittedPoints( d_data->splineSize );
+
+    const double x1 = points[0].x();
+    const double x2 = points[int( points.size() - 1 )].x();
+    const double dx = x2 - x1;
+    const double delta = dx / ( d_data->splineSize - 1 );
+
+    for ( int i = 0; i < d_data->splineSize; i++ )
+    {
+        QPointF &p = fittedPoints[i];
+
+        const double v = x1 + i * delta;
+        const double sv = d_data->spline.value( v );
+
+        p.setX( v );
+        p.setY( sv );
+    }
+    d_data->spline.reset();
+
+    return fittedPoints;
+}
+
+QPolygonF QwtSplineCurveFitter::fitParametric( const QPolygonF &points ) const
+{
+    int i;
+    const int size = points.size();
+
+    QPolygonF fittedPoints( d_data->splineSize );
+    QPolygonF splinePointsX( size );
+    QPolygonF splinePointsY( size );
+
+    const QPointF *p = points.data();
+    QPointF *spX = splinePointsX.data();
+    QPointF *spY = splinePointsY.data();
+
+    double param = 0.0;
+    for ( i = 0; i < size; i++ )
+    {
+        const double x = p[i].x();
+        const double y = p[i].y();
+        if ( i > 0 )
+        {
+            const double delta = qSqrt( qwtSqr( x - spX[i-1].y() )
+                      + qwtSqr( y - spY[i-1].y() ) );
+            param += qMax( delta, 1.0 );
+        }
+        spX[i].setX( param );
+        spX[i].setY( x );
+        spY[i].setX( param );
+        spY[i].setY( y );
+    }
+
+    d_data->spline.setPoints( splinePointsX );
+    if ( !d_data->spline.isValid() )
+        return points;
+
+    const double deltaX =
+        splinePointsX[size - 1].x() / ( d_data->splineSize - 1 );
+    for ( i = 0; i < d_data->splineSize; i++ )
+    {
+        const double dtmp = i * deltaX;
+        fittedPoints[i].setX( d_data->spline.value( dtmp ) );
+    }
+
+    d_data->spline.setPoints( splinePointsY );
+    if ( !d_data->spline.isValid() )
+        return points;
+
+    const double deltaY =
+        splinePointsY[size - 1].x() / ( d_data->splineSize - 1 );
+    for ( i = 0; i < d_data->splineSize; i++ )
+    {
+        const double dtmp = i * deltaY;
+        fittedPoints[i].setY( d_data->spline.value( dtmp ) );
+    }
+
+    return fittedPoints;
+}
+
+class QwtWeedingCurveFitter::PrivateData
+{
+public:
+    PrivateData():
+        tolerance( 1.0 )
+    {
+    }
+
+    double tolerance;
+};
+
+class QwtWeedingCurveFitter::Line
+{
+public:
+    Line( int i1 = 0, int i2 = 0 ):
+        from( i1 ),
+        to( i2 )
+    {
+    }
+
+    int from;
+    int to;
+};
+
+/*!
+   Constructor
+
+   \param tolerance Tolerance
+   \sa setTolerance(), tolerance()
+*/
+QwtWeedingCurveFitter::QwtWeedingCurveFitter( double tolerance )
+{
+    d_data = new PrivateData;
+    setTolerance( tolerance );
+}
+
+//! Destructor
+QwtWeedingCurveFitter::~QwtWeedingCurveFitter()
+{
+    delete d_data;
+}
+
+/*!
+ Assign the tolerance
+
+ The tolerance is the maximum distance, that is accaptable
+ between the original curve and the smoothed curve.
+
+ Increasing the tolerance will reduce the number of the
+ resulting points.
+
+ \param tolerance Tolerance
+
+ \sa tolerance()
+*/
+void QwtWeedingCurveFitter::setTolerance( double tolerance )
+{
+    d_data->tolerance = qMax( tolerance, 0.0 );
+}
+
+/*!
+  \return Tolerance
+  \sa setTolerance()
+*/
+double QwtWeedingCurveFitter::tolerance() const
+{
+    return d_data->tolerance;
+}
+
+/*!
+  \param points Series of data points
+  \return Curve points
+*/
+QPolygonF QwtWeedingCurveFitter::fitCurve( const QPolygonF &points ) const
+{
+    QStack<Line> stack;
+    stack.reserve( 500 );
+
+    const QPointF *p = points.data();
+    const int nPoints = points.size();
+
+    QVector<bool> usePoint( nPoints, false );
+
+    double distToSegment;
+
+    stack.push( Line( 0, nPoints - 1 ) );
+
+    while ( !stack.isEmpty() )
+    {
+        const Line r = stack.pop();
+
+        // initialize line segment
+        const double vecX = p[r.to].x() - p[r.from].x();
+        const double vecY = p[r.to].y() - p[r.from].y();
+
+        const double vecLength = qSqrt( vecX * vecX + vecY * vecY );
+
+        const double unitVecX = ( vecLength != 0.0 ) ? vecX / vecLength : 0.0;
+        const double unitVecY = ( vecLength != 0.0 ) ? vecY / vecLength : 0.0;
+
+        double maxDist = 0.0;
+        int nVertexIndexMaxDistance = r.from + 1;
+        for ( int i = r.from + 1; i < r.to; i++ )
+        {
+            //compare to anchor
+            const double fromVecX = p[i].x() - p[r.from].x();
+            const double fromVecY = p[i].y() - p[r.from].y();
+            const double fromVecLength =
+                qSqrt( fromVecX * fromVecX + fromVecY * fromVecY );
+
+            if ( fromVecX * unitVecX + fromVecY * unitVecY < 0.0 )
+            {
+                distToSegment = fromVecLength;
+            }
+            if ( fromVecX * unitVecX + fromVecY * unitVecY < 0.0 )
+            {
+                distToSegment = fromVecLength;
+            }
+            else
+            {
+                const double toVecX = p[i].x() - p[r.to].x();
+                const double toVecY = p[i].y() - p[r.to].y();
+                const double toVecLength = qSqrt( toVecX * toVecX + toVecY * toVecY );
+                const double s = toVecX * ( -unitVecX ) + toVecY * ( -unitVecY );
+                if ( s < 0.0 )
+                    distToSegment = toVecLength;
+                else
+                {
+                    distToSegment = qSqrt( qFabs( toVecLength * toVecLength - s * s ) );
+                }
+            }
+
+            if ( maxDist < distToSegment )
+            {
+                maxDist = distToSegment;
+                nVertexIndexMaxDistance = i;
+            }
+        }
+        if ( maxDist <= d_data->tolerance )
+        {
+            usePoint[r.from] = true;
+            usePoint[r.to] = true;
+        }
+        else
+        {
+            stack.push( Line( r.from, nVertexIndexMaxDistance ) );
+            stack.push( Line( nVertexIndexMaxDistance, r.to ) );
+        }
+    }
+
+    int cnt = 0;
+
+    QPolygonF stripped( nPoints );
+    for ( int i = 0; i < nPoints; i++ )
+    {
+        if ( usePoint[i] )
+            stripped[cnt++] = p[i];
+    }
+    stripped.resize( cnt );
+    return stripped;
+}
Index: trunk/BNC/qwt/qwt_curve_fitter.h
===================================================================
--- trunk/BNC/qwt/qwt_curve_fitter.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_curve_fitter.h	(revision 4271)
@@ -0,0 +1,128 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_CURVE_FITTER_H
+#define QWT_CURVE_FITTER_H
+
+#include "qwt_global.h"
+#include <qpolygon.h>
+#include <qrect.h>
+
+class QwtSpline;
+
+/*!
+  \brief Abstract base class for a curve fitter
+*/
+class QWT_EXPORT QwtCurveFitter
+{
+public:
+    virtual ~QwtCurveFitter();
+
+    /*!
+        Find a curve which has the best fit to a series of data points
+
+        \param polygon Series of data points
+        \return Curve points
+     */
+    virtual QPolygonF fitCurve( const QPolygonF &polygon ) const = 0;
+
+protected:
+    QwtCurveFitter();
+
+private:
+    QwtCurveFitter( const QwtCurveFitter & );
+    QwtCurveFitter &operator=( const QwtCurveFitter & );
+};
+
+/*!
+  \brief A curve fitter using cubic splines
+*/
+class QWT_EXPORT QwtSplineCurveFitter: public QwtCurveFitter
+{
+public:
+    /*!
+      Spline type
+      The default setting is Auto
+      \sa setFitMode(), FitMode()
+     */
+    enum FitMode
+    {
+        /*!
+          Use the default spline algorithm for polygons with
+          increasing x values ( p[i-1] < p[i] ), otherwise use
+          a parametric spline algorithm.
+         */
+        Auto,
+
+        //! Use a default spline algorithm
+        Spline,
+
+        //! Use a parametric spline algorithm
+        ParametricSpline
+    };
+
+    QwtSplineCurveFitter();
+    virtual ~QwtSplineCurveFitter();
+
+    void setFitMode( FitMode );
+    FitMode fitMode() const;
+
+    void setSpline( const QwtSpline& );
+    const QwtSpline &spline() const;
+    QwtSpline &spline();
+
+    void setSplineSize( int size );
+    int splineSize() const;
+
+    virtual QPolygonF fitCurve( const QPolygonF & ) const;
+
+private:
+    QPolygonF fitSpline( const QPolygonF & ) const;
+    QPolygonF fitParametric( const QPolygonF & ) const;
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+/*!
+  \brief A curve fitter implementing Douglas and Peucker algorithm
+
+  The purpose of the Douglas and Peucker algorithm is that given a 'curve'
+  composed of line segments to find a curve not too dissimilar but that
+  has fewer points. The algorithm defines 'too dissimilar' based on the
+  maximum distance (tolerance) between the original curve and the
+  smoothed curve.
+
+  The smoothed curve consists of a subset of the points that defined the
+  original curve.
+
+  In opposite to QwtSplineCurveFitter the Douglas and Peucker algorithm reduces
+  the number of points. By adjusting the tolerance parameter according to the
+  axis scales QwtSplineCurveFitter can be used to implement different
+  level of details to speed up painting of curves of many points.
+*/
+class QWT_EXPORT QwtWeedingCurveFitter: public QwtCurveFitter
+{
+public:
+    QwtWeedingCurveFitter( double tolerance = 1.0 );
+    virtual ~QwtWeedingCurveFitter();
+
+    void setTolerance( double );
+    double tolerance() const;
+
+    virtual QPolygonF fitCurve( const QPolygonF & ) const;
+
+private:
+    class Line;
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_dyngrid_layout.cpp
===================================================================
--- trunk/BNC/qwt/qwt_dyngrid_layout.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_dyngrid_layout.cpp	(revision 4271)
@@ -0,0 +1,571 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_dyngrid_layout.h"
+#include "qwt_math.h"
+#include <qwidget.h>
+#include <qlist.h>
+
+class QwtDynGridLayout::PrivateData
+{
+public:
+    PrivateData():
+        isDirty( true )
+    {
+    }
+
+    void updateLayoutCache();
+
+    mutable QList<QLayoutItem*> itemList;
+
+    uint maxCols;
+    uint numRows;
+    uint numCols;
+
+    Qt::Orientations expanding;
+
+    bool isDirty;
+    QVector<QSize> itemSizeHints;
+};
+
+void QwtDynGridLayout::PrivateData::updateLayoutCache()
+{
+    itemSizeHints.resize( itemList.count() );
+
+    int index = 0;
+
+    for ( QList<QLayoutItem*>::iterator it = itemList.begin();
+        it != itemList.end(); ++it, index++ )
+    {
+        itemSizeHints[ index ] = ( *it )->sizeHint();
+    }
+
+    isDirty = false;
+}
+
+/*!
+  \param parent Parent widget
+  \param margin Margin
+  \param spacing Spacing
+*/
+
+QwtDynGridLayout::QwtDynGridLayout( QWidget *parent,
+        int margin, int spacing ):
+    QLayout( parent )
+{
+    init();
+
+    setSpacing( spacing );
+    setMargin( margin );
+}
+
+/*!
+  \param spacing Spacing
+*/
+
+QwtDynGridLayout::QwtDynGridLayout( int spacing )
+{
+    init();
+    setSpacing( spacing );
+}
+
+/*!
+  Initialize the layout with default values.
+*/
+void QwtDynGridLayout::init()
+{
+    d_data = new QwtDynGridLayout::PrivateData;
+    d_data->maxCols = d_data->numRows = d_data->numCols = 0;
+    d_data->expanding = 0;
+}
+
+//! Destructor
+
+QwtDynGridLayout::~QwtDynGridLayout()
+{
+    for ( int i = 0; i < d_data->itemList.size(); i++ )
+        delete d_data->itemList[i];
+
+    delete d_data;
+}
+
+//! Invalidate all internal caches
+void QwtDynGridLayout::invalidate()
+{
+    d_data->isDirty = true;
+    QLayout::invalidate();
+}
+
+/*!
+  Limit the number of columns.
+  \param maxCols upper limit, 0 means unlimited
+  \sa maxCols()
+*/
+void QwtDynGridLayout::setMaxCols( uint maxCols )
+{
+    d_data->maxCols = maxCols;
+}
+
+/*!
+  Return the upper limit for the number of columns.
+  0 means unlimited, what is the default.
+  \sa setMaxCols()
+*/
+
+uint QwtDynGridLayout::maxCols() const
+{
+    return d_data->maxCols;
+}
+
+//! Adds item to the next free position.
+
+void QwtDynGridLayout::addItem( QLayoutItem *item )
+{
+    d_data->itemList.append( item );
+    invalidate();
+}
+
+/*!
+  \return true if this layout is empty.
+*/
+
+bool QwtDynGridLayout::isEmpty() const
+{
+    return d_data->itemList.isEmpty();
+}
+
+/*!
+  \return number of layout items
+*/
+
+uint QwtDynGridLayout::itemCount() const
+{
+    return d_data->itemList.count();
+}
+
+/*!
+  Find the item at a spcific index
+
+  \param index Index
+  \sa takeAt()
+*/
+QLayoutItem *QwtDynGridLayout::itemAt( int index ) const
+{
+    if ( index < 0 || index >= d_data->itemList.count() )
+        return NULL;
+
+    return d_data->itemList.at( index );
+}
+
+/*!
+  Find the item at a spcific index and remove it from the layout
+
+  \param index Index
+  \sa itemAt()
+*/
+QLayoutItem *QwtDynGridLayout::takeAt( int index )
+{
+    if ( index < 0 || index >= d_data->itemList.count() )
+        return NULL;
+
+    d_data->isDirty = true;
+    return d_data->itemList.takeAt( index );
+}
+
+//! \return Number of items in the layout
+int QwtDynGridLayout::count() const
+{
+    return d_data->itemList.count();
+}
+
+/*!
+  Set whether this layout can make use of more space than sizeHint().
+  A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only
+  one dimension, while Qt::Vertical | Qt::Horizontal means that it wants
+  to grow in both dimensions. The default value is 0.
+
+  \param expanding Or'd orientations
+  \sa expandingDirections()
+*/
+void QwtDynGridLayout::setExpandingDirections( Qt::Orientations expanding )
+{
+    d_data->expanding = expanding;
+}
+
+/*!
+  Returns whether this layout can make use of more space than sizeHint().
+  A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only
+  one dimension, while Qt::Vertical | Qt::Horizontal means that it wants
+  to grow in both dimensions.
+  \sa setExpandingDirections()
+*/
+Qt::Orientations QwtDynGridLayout::expandingDirections() const
+{
+    return d_data->expanding;
+}
+
+/*!
+  Reorganizes columns and rows and resizes managed widgets within
+  the rectangle rect.
+
+  \param rect Layout geometry
+*/
+void QwtDynGridLayout::setGeometry( const QRect &rect )
+{
+    QLayout::setGeometry( rect );
+
+    if ( isEmpty() )
+        return;
+
+    d_data->numCols = columnsForWidth( rect.width() );
+    d_data->numRows = itemCount() / d_data->numCols;
+    if ( itemCount() % d_data->numCols )
+        d_data->numRows++;
+
+    QList<QRect> itemGeometries = layoutItems( rect, d_data->numCols );
+
+    int index = 0;
+    for ( QList<QLayoutItem*>::iterator it = d_data->itemList.begin();
+        it != d_data->itemList.end(); ++it )
+    {
+        QWidget *w = ( *it )->widget();
+        if ( w )
+        {
+            w->setGeometry( itemGeometries[index] );
+            index++;
+        }
+    }
+}
+
+/*!
+  Calculate the number of columns for a given width. It tries to
+  use as many columns as possible (limited by maxCols())
+
+  \param width Available width for all columns
+  \sa maxCols(), setMaxCols()
+*/
+
+uint QwtDynGridLayout::columnsForWidth( int width ) const
+{
+    if ( isEmpty() )
+        return 0;
+
+    const int maxCols = ( d_data->maxCols > 0 ) ? d_data->maxCols : itemCount();
+    if ( maxRowWidth( maxCols ) <= width )
+        return maxCols;
+
+    for ( int numCols = 2; numCols <= maxCols; numCols++ )
+    {
+        const int rowWidth = maxRowWidth( numCols );
+        if ( rowWidth > width )
+            return numCols - 1;
+    }
+
+    return 1; // At least 1 column
+}
+
+/*!
+  Calculate the width of a layout for a given number of
+  columns.
+
+  \param numCols Given number of columns
+  \param itemWidth Array of the width hints for all items
+*/
+int QwtDynGridLayout::maxRowWidth( int numCols ) const
+{
+    int col;
+
+    QVector<int> colWidth( numCols );
+    for ( col = 0; col < numCols; col++ )
+        colWidth[col] = 0;
+
+    if ( d_data->isDirty )
+        d_data->updateLayoutCache();
+
+    for ( int index = 0;
+        index < d_data->itemSizeHints.count(); index++ )
+    {
+        col = index % numCols;
+        colWidth[col] = qMax( colWidth[col],
+            d_data->itemSizeHints[int( index )].width() );
+    }
+
+    int rowWidth = 2 * margin() + ( numCols - 1 ) * spacing();
+    for ( col = 0; col < numCols; col++ )
+        rowWidth += colWidth[col];
+
+    return rowWidth;
+}
+
+/*!
+  \return the maximum width of all layout items
+*/
+int QwtDynGridLayout::maxItemWidth() const
+{
+    if ( isEmpty() )
+        return 0;
+
+    if ( d_data->isDirty )
+        d_data->updateLayoutCache();
+
+    int w = 0;
+    for ( int i = 0; i < d_data->itemSizeHints.count(); i++ )
+    {
+        const int itemW = d_data->itemSizeHints[i].width();
+        if ( itemW > w )
+            w = itemW;
+    }
+
+    return w;
+}
+
+/*!
+  Calculate the geometries of the layout items for a layout
+  with numCols columns and a given rect.
+
+  \param rect Rect where to place the items
+  \param numCols Number of columns
+  \return item geometries
+*/
+
+QList<QRect> QwtDynGridLayout::layoutItems( const QRect &rect,
+    uint numCols ) const
+{
+    QList<QRect> itemGeometries;
+    if ( numCols == 0 || isEmpty() )
+        return itemGeometries;
+
+    uint numRows = itemCount() / numCols;
+    if ( numRows % itemCount() )
+        numRows++;
+
+    QVector<int> rowHeight( numRows );
+    QVector<int> colWidth( numCols );
+
+    layoutGrid( numCols, rowHeight, colWidth );
+
+    bool expandH, expandV;
+    expandH = expandingDirections() & Qt::Horizontal;
+    expandV = expandingDirections() & Qt::Vertical;
+
+    if ( expandH || expandV )
+        stretchGrid( rect, numCols, rowHeight, colWidth );
+
+    const int maxCols = d_data->maxCols;
+    d_data->maxCols = numCols;
+    const QRect alignedRect = alignmentRect( rect );
+    d_data->maxCols = maxCols;
+
+    const int xOffset = expandH ? 0 : alignedRect.x();
+    const int yOffset = expandV ? 0 : alignedRect.y();
+
+    QVector<int> colX( numCols );
+    QVector<int> rowY( numRows );
+
+    const int xySpace = spacing();
+
+    rowY[0] = yOffset + margin();
+    for ( int r = 1; r < ( int )numRows; r++ )
+        rowY[r] = rowY[r-1] + rowHeight[r-1] + xySpace;
+
+    colX[0] = xOffset + margin();
+    for ( int c = 1; c < ( int )numCols; c++ )
+        colX[c] = colX[c-1] + colWidth[c-1] + xySpace;
+
+    const int itemCount = d_data->itemList.size();
+    for ( int i = 0; i < itemCount; i++ )
+    {
+        const int row = i / numCols;
+        const int col = i % numCols;
+
+        QRect itemGeometry( colX[col], rowY[row],
+            colWidth[col], rowHeight[row] );
+        itemGeometries.append( itemGeometry );
+    }
+
+    return itemGeometries;
+}
+
+
+/*!
+  Calculate the dimensions for the columns and rows for a grid
+  of numCols columns.
+
+  \param numCols Number of columns.
+  \param rowHeight Array where to fill in the calculated row heights.
+  \param colWidth Array where to fill in the calculated column widths.
+*/
+
+void QwtDynGridLayout::layoutGrid( uint numCols,
+    QVector<int>& rowHeight, QVector<int>& colWidth ) const
+{
+    if ( numCols <= 0 )
+        return;
+
+    if ( d_data->isDirty )
+        d_data->updateLayoutCache();
+
+    for ( uint index = 0;
+        index < ( uint )d_data->itemSizeHints.count(); index++ )
+    {
+        const int row = index / numCols;
+        const int col = index % numCols;
+
+        const QSize &size = d_data->itemSizeHints[int( index )];
+
+        rowHeight[row] = ( col == 0 )
+            ? size.height() : qMax( rowHeight[row], size.height() );
+        colWidth[col] = ( row == 0 )
+            ? size.width() : qMax( colWidth[col], size.width() );
+    }
+}
+
+/*!
+  \return true: QwtDynGridLayout implements heightForWidth.
+  \sa heightForWidth()
+*/
+bool QwtDynGridLayout::hasHeightForWidth() const
+{
+    return true;
+}
+
+/*!
+  \return The preferred height for this layout, given the width w.
+  \sa hasHeightForWidth()
+*/
+int QwtDynGridLayout::heightForWidth( int width ) const
+{
+    if ( isEmpty() )
+        return 0;
+
+    const uint numCols = columnsForWidth( width );
+    uint numRows = itemCount() / numCols;
+    if ( itemCount() % numCols )
+        numRows++;
+
+    QVector<int> rowHeight( numRows );
+    QVector<int> colWidth( numCols );
+
+    layoutGrid( numCols, rowHeight, colWidth );
+
+    int h = 2 * margin() + ( numRows - 1 ) * spacing();
+    for ( int row = 0; row < ( int )numRows; row++ )
+        h += rowHeight[row];
+
+    return h;
+}
+
+/*!
+  Stretch columns in case of expanding() & QSizePolicy::Horizontal and
+  rows in case of expanding() & QSizePolicy::Vertical to fill the entire
+  rect. Rows and columns are stretched with the same factor.
+
+  \sa setExpanding(), expanding()
+*/
+void QwtDynGridLayout::stretchGrid( const QRect &rect,
+    uint numCols, QVector<int>& rowHeight, QVector<int>& colWidth ) const
+{
+    if ( numCols == 0 || isEmpty() )
+        return;
+
+    bool expandH, expandV;
+    expandH = expandingDirections() & Qt::Horizontal;
+    expandV = expandingDirections() & Qt::Vertical;
+
+    if ( expandH )
+    {
+        int xDelta = rect.width() - 2 * margin() - ( numCols - 1 ) * spacing();
+        for ( int col = 0; col < ( int )numCols; col++ )
+            xDelta -= colWidth[col];
+
+        if ( xDelta > 0 )
+        {
+            for ( int col = 0; col < ( int )numCols; col++ )
+            {
+                const int space = xDelta / ( numCols - col );
+                colWidth[col] += space;
+                xDelta -= space;
+            }
+        }
+    }
+
+    if ( expandV )
+    {
+        uint numRows = itemCount() / numCols;
+        if ( itemCount() % numCols )
+            numRows++;
+
+        int yDelta = rect.height() - 2 * margin() - ( numRows - 1 ) * spacing();
+        for ( int row = 0; row < ( int )numRows; row++ )
+            yDelta -= rowHeight[row];
+
+        if ( yDelta > 0 )
+        {
+            for ( int row = 0; row < ( int )numRows; row++ )
+            {
+                const int space = yDelta / ( numRows - row );
+                rowHeight[row] += space;
+                yDelta -= space;
+            }
+        }
+    }
+}
+
+/*!
+   Return the size hint. If maxCols() > 0 it is the size for
+   a grid with maxCols() columns, otherwise it is the size for
+   a grid with only one row.
+
+   \sa maxCols(), setMaxCols()
+*/
+QSize QwtDynGridLayout::sizeHint() const
+{
+    if ( isEmpty() )
+        return QSize();
+
+    const uint numCols = ( d_data->maxCols > 0 ) ? d_data->maxCols : itemCount();
+    uint numRows = itemCount() / numCols;
+    if ( itemCount() % numCols )
+        numRows++;
+
+    QVector<int> rowHeight( numRows );
+    QVector<int> colWidth( numCols );
+
+    layoutGrid( numCols, rowHeight, colWidth );
+
+    int h = 2 * margin() + ( numRows - 1 ) * spacing();
+    for ( int row = 0; row < ( int )numRows; row++ )
+        h += rowHeight[row];
+
+    int w = 2 * margin() + ( numCols - 1 ) * spacing();
+    for ( int col = 0; col < ( int )numCols; col++ )
+        w += colWidth[col];
+
+    return QSize( w, h );
+}
+
+/*!
+  \return Number of rows of the current layout.
+  \sa numCols()
+  \warning The number of rows might change whenever the geometry changes
+*/
+uint QwtDynGridLayout::numRows() const
+{
+    return d_data->numRows;
+}
+
+/*!
+  \return Number of columns of the current layout.
+  \sa numRows()
+  \warning The number of columns might change whenever the geometry changes
+*/
+uint QwtDynGridLayout::numCols() const
+{
+    return d_data->numCols;
+}
Index: trunk/BNC/qwt/qwt_dyngrid_layout.h
===================================================================
--- trunk/BNC/qwt/qwt_dyngrid_layout.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_dyngrid_layout.h	(revision 4271)
@@ -0,0 +1,83 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_DYNGRID_LAYOUT_H
+#define QWT_DYNGRID_LAYOUT_H
+
+#include "qwt_global.h"
+#include <qlayout.h>
+#include <qsize.h>
+#include <qlist.h>
+
+/*!
+  \brief The QwtDynGridLayout class lays out widgets in a grid,
+         adjusting the number of columns and rows to the current size.
+
+  QwtDynGridLayout takes the space it gets, divides it up into rows and
+  columns, and puts each of the widgets it manages into the correct cell(s).
+  It lays out as many number of columns as possible (limited by maxCols()).
+*/
+
+class QWT_EXPORT QwtDynGridLayout : public QLayout
+{
+    Q_OBJECT
+public:
+    explicit QwtDynGridLayout( QWidget *, int margin = 0, int space = -1 );
+    explicit QwtDynGridLayout( int space = -1 );
+
+    virtual ~QwtDynGridLayout();
+
+    virtual void invalidate();
+
+    void setMaxCols( uint maxCols );
+    uint maxCols() const;
+
+    uint numRows () const;
+    uint numCols () const;
+
+    virtual void addItem( QLayoutItem * );
+
+    virtual QLayoutItem *itemAt( int index ) const;
+    virtual QLayoutItem *takeAt( int index );
+    virtual int count() const;
+
+    void setExpandingDirections( Qt::Orientations );
+    virtual Qt::Orientations expandingDirections() const;
+    QList<QRect> layoutItems( const QRect &, uint numCols ) const;
+
+    virtual int maxItemWidth() const;
+
+    virtual void setGeometry( const QRect &rect );
+
+    virtual bool hasHeightForWidth() const;
+    virtual int heightForWidth( int ) const;
+
+    virtual QSize sizeHint() const;
+
+    virtual bool isEmpty() const;
+    uint itemCount() const;
+
+    virtual uint columnsForWidth( int width ) const;
+
+protected:
+
+    void layoutGrid( uint numCols,
+        QVector<int>& rowHeight, QVector<int>& colWidth ) const;
+    void stretchGrid( const QRect &rect, uint numCols,
+        QVector<int>& rowHeight, QVector<int>& colWidth ) const;
+
+private:
+    void init();
+    int maxRowWidth( int numCols ) const;
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_event_pattern.cpp
===================================================================
--- trunk/BNC/qwt/qwt_event_pattern.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_event_pattern.cpp	(revision 4271)
@@ -0,0 +1,274 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_event_pattern.h"
+#include <qevent.h>
+
+/*!
+  Constructor
+
+  \sa MousePatternCode, KeyPatternCode
+*/
+
+QwtEventPattern::QwtEventPattern():
+    d_mousePattern( MousePatternCount ),
+    d_keyPattern( KeyPatternCount )
+{
+    initKeyPattern();
+    initMousePattern( 3 );
+}
+
+//! Destructor
+QwtEventPattern::~QwtEventPattern()
+{
+}
+
+/*!
+  Set default mouse patterns, depending on the number of mouse buttons
+
+  \param numButtons Number of mouse buttons ( <= 3 )
+  \sa MousePatternCode
+*/
+void QwtEventPattern::initMousePattern( int numButtons )
+{
+    const int altButton = Qt::AltModifier;
+    const int controlButton = Qt::ControlModifier;
+    const int shiftButton = Qt::ShiftModifier;
+
+    d_mousePattern.resize( MousePatternCount );
+
+    switch ( numButtons )
+    {
+        case 1:
+        {
+            setMousePattern( MouseSelect1, Qt::LeftButton );
+            setMousePattern( MouseSelect2, Qt::LeftButton, controlButton );
+            setMousePattern( MouseSelect3, Qt::LeftButton, altButton );
+            break;
+        }
+        case 2:
+        {
+            setMousePattern( MouseSelect1, Qt::LeftButton );
+            setMousePattern( MouseSelect2, Qt::RightButton );
+            setMousePattern( MouseSelect3, Qt::LeftButton, altButton );
+            break;
+        }
+        default:
+        {
+            setMousePattern( MouseSelect1, Qt::LeftButton );
+            setMousePattern( MouseSelect2, Qt::RightButton );
+            setMousePattern( MouseSelect3, Qt::MidButton );
+        }
+    }
+    for ( int i = 0; i < 3; i++ )
+    {
+        setMousePattern( MouseSelect4 + i,
+                         d_mousePattern[MouseSelect1 + i].button,
+                         d_mousePattern[MouseSelect1 + i].state | shiftButton );
+    }
+}
+
+/*!
+  Set default mouse patterns.
+
+  \sa KeyPatternCode
+*/
+void QwtEventPattern::initKeyPattern()
+{
+    d_keyPattern.resize( KeyPatternCount );
+
+    setKeyPattern( KeySelect1, Qt::Key_Return );
+    setKeyPattern( KeySelect2, Qt::Key_Space );
+    setKeyPattern( KeyAbort, Qt::Key_Escape );
+
+    setKeyPattern( KeyLeft, Qt::Key_Left );
+    setKeyPattern( KeyRight, Qt::Key_Right );
+    setKeyPattern( KeyUp, Qt::Key_Up );
+    setKeyPattern( KeyDown, Qt::Key_Down );
+
+    setKeyPattern( KeyRedo, Qt::Key_Plus );
+    setKeyPattern( KeyUndo, Qt::Key_Minus );
+    setKeyPattern( KeyHome, Qt::Key_Escape );
+}
+
+/*!
+  Change one mouse pattern
+
+  \param pattern Index of the pattern
+  \param button Button
+  \param state State
+
+  \sa QMouseEvent
+*/
+void QwtEventPattern::setMousePattern( uint pattern, int button, int state )
+{
+    if ( pattern < ( uint )d_mousePattern.count() )
+    {
+        d_mousePattern[int( pattern )].button = button;
+        d_mousePattern[int( pattern )].state = state;
+    }
+}
+
+/*!
+  Change one key pattern
+
+  \param pattern Index of the pattern
+  \param key Key
+  \param state State
+
+  \sa QKeyEvent
+*/
+void QwtEventPattern::setKeyPattern( uint pattern, int key, int state )
+{
+    if ( pattern < ( uint )d_keyPattern.count() )
+    {
+        d_keyPattern[int( pattern )].key = key;
+        d_keyPattern[int( pattern )].state = state;
+    }
+}
+
+//! Change the mouse event patterns
+void QwtEventPattern::setMousePattern( const QVector<MousePattern> &pattern )
+{
+    d_mousePattern = pattern;
+}
+
+//! Change the key event patterns
+void QwtEventPattern::setKeyPattern( const QVector<KeyPattern> &pattern )
+{
+    d_keyPattern = pattern;
+}
+
+//! Return mouse patterns
+const QVector<QwtEventPattern::MousePattern> &
+QwtEventPattern::mousePattern() const
+{
+    return d_mousePattern;
+}
+
+//! Return key patterns
+const QVector<QwtEventPattern::KeyPattern> &
+QwtEventPattern::keyPattern() const
+{
+    return d_keyPattern;
+}
+
+//! Return ,ouse patterns
+QVector<QwtEventPattern::MousePattern> &QwtEventPattern::mousePattern()
+{
+    return d_mousePattern;
+}
+
+//! Return Key patterns
+QVector<QwtEventPattern::KeyPattern> &QwtEventPattern::keyPattern()
+{
+    return d_keyPattern;
+}
+
+/*!
+  \brief Compare a mouse event with an event pattern.
+
+  A mouse event matches the pattern when both have the same button
+  value and in the state value the same key flags(Qt::KeyButtonMask)
+  are set.
+
+  \param pattern Index of the event pattern
+  \param event Mouse event
+  \return true if matches
+
+  \sa keyMatch()
+*/
+bool QwtEventPattern::mouseMatch( uint pattern, 
+    const QMouseEvent *event ) const
+{
+    bool ok = false;
+
+    if ( event && pattern < ( uint )d_mousePattern.count() )
+        ok = mouseMatch( d_mousePattern[int( pattern )], event );
+
+    return ok;
+}
+
+/*!
+  \brief Compare a mouse event with an event pattern.
+
+  A mouse event matches the pattern when both have the same button
+  value and in the state value the same key flags(Qt::KeyButtonMask)
+  are set.
+
+  \param pattern Mouse event pattern
+  \param event Mouse event
+  \return true if matches
+
+  \sa keyMatch()
+*/
+
+bool QwtEventPattern::mouseMatch( const MousePattern &pattern,
+    const QMouseEvent *event ) const
+{
+    if ( event->button() != pattern.button )
+        return false;
+
+    const bool matched =
+        ( event->modifiers() & Qt::KeyboardModifierMask ) ==
+            ( int )( pattern.state & Qt::KeyboardModifierMask );
+
+    return matched;
+}
+
+/*!
+  \brief Compare a key event with an event pattern.
+
+  A key event matches the pattern when both have the same key
+  value and in the state value the same key flags (Qt::KeyButtonMask)
+  are set.
+
+  \param pattern Index of the event pattern
+  \param event Key event
+  \return true if matches
+
+  \sa mouseMatch()
+*/
+bool QwtEventPattern::keyMatch( uint pattern, 
+    const QKeyEvent *event ) const
+{
+    bool ok = false;
+
+    if ( event && pattern < ( uint )d_keyPattern.count() )
+        ok = keyMatch( d_keyPattern[int( pattern )], event );
+
+    return ok;
+}
+
+/*!
+  \brief Compare a key event with an event pattern.
+
+  A key event matches the pattern when both have the same key
+  value and in the state value the same key flags (Qt::KeyButtonMask)
+  are set.
+
+  \param pattern Key event pattern
+  \param event Key event
+  \return true if matches
+
+  \sa mouseMatch()
+*/
+
+bool QwtEventPattern::keyMatch(
+    const KeyPattern &pattern, const QKeyEvent *event ) const
+{
+    if ( event->key() != pattern.key )
+        return false;
+
+    const bool matched =
+        ( event->modifiers() & Qt::KeyboardModifierMask ) ==
+            ( int )( pattern.state & Qt::KeyboardModifierMask );
+
+    return matched;
+}
Index: trunk/BNC/qwt/qwt_event_pattern.h
===================================================================
--- trunk/BNC/qwt/qwt_event_pattern.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_event_pattern.h	(revision 4271)
@@ -0,0 +1,225 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_EVENT_PATTERN
+#define QWT_EVENT_PATTERN 1
+
+#include "qwt_global.h"
+#include <qnamespace.h>
+#include <qvector.h>
+
+class QMouseEvent;
+class QKeyEvent;
+
+/*!
+  \brief A collection of event patterns
+
+  QwtEventPattern introduces an level of indirection for mouse and
+  keyboard inputs. Those are represented by symbolic names, so
+  the application code can be configured by individual mappings.
+
+  \sa QwtPicker, QwtPickerMachine, QwtPlotZoomer
+*/
+class QWT_EXPORT QwtEventPattern
+{
+public:
+    /*!
+      \brief Symbolic mouse input codes
+
+      The default initialization for 3 button mice is:
+      - MouseSelect1\n
+        Qt::LeftButton
+      - MouseSelect2\n
+        Qt::RightButton
+      - MouseSelect3\n
+        Qt::MidButton
+      - MouseSelect4\n
+        Qt::LeftButton + Qt::ShiftButton
+      - MouseSelect5\n
+        Qt::RightButton + Qt::ShiftButton
+      - MouseSelect6\n
+        Qt::MidButton + Qt::ShiftButton
+
+      The default initialization for 2 button mice is:
+      - MouseSelect1\n
+        Qt::LeftButton
+      - MouseSelect2\n
+        Qt::RightButton
+      - MouseSelect3\n
+        Qt::LeftButton + Qt::AltButton
+      - MouseSelect4\n
+        Qt::LeftButton + Qt::ShiftButton
+      - MouseSelect5\n
+        Qt::RightButton + Qt::ShiftButton
+      - MouseSelect6\n
+        Qt::LeftButton + Qt::AltButton + Qt::ShiftButton
+
+      The default initialization for 1 button mice is:
+      - MouseSelect1\n
+        Qt::LeftButton
+      - MouseSelect2\n
+        Qt::LeftButton + Qt::ControlButton
+      - MouseSelect3\n
+        Qt::LeftButton + Qt::AltButton
+      - MouseSelect4\n
+        Qt::LeftButton + Qt::ShiftButton
+      - MouseSelect5\n
+        Qt::LeftButton + Qt::ControlButton + Qt::ShiftButton
+      - MouseSelect6\n
+        Qt::LeftButton + Qt::AltButton + Qt::ShiftButton
+
+      \sa initMousePattern()
+    */
+
+    enum MousePatternCode
+    {
+        MouseSelect1,
+        MouseSelect2,
+        MouseSelect3,
+        MouseSelect4,
+        MouseSelect5,
+        MouseSelect6,
+
+        MousePatternCount
+    };
+
+    /*!
+      \brief Symbolic keyboard input codes
+
+      Default initialization:
+      - KeySelect1\n
+        Qt::Key_Return
+      - KeySelect2\n
+        Qt::Key_Space
+      - KeyAbort\n
+        Qt::Key_Escape
+
+      - KeyLeft\n
+        Qt::Key_Left
+      - KeyRight\n
+        Qt::Key_Right
+      - KeyUp\n
+        Qt::Key_Up
+      - KeyDown\n
+        Qt::Key_Down
+
+      - KeyUndo\n
+        Qt::Key_Minus
+      - KeyRedo\n
+        Qt::Key_Plus
+      - KeyHome\n
+        Qt::Key_Escape
+    */
+    enum KeyPatternCode
+    {
+        KeySelect1,
+        KeySelect2,
+        KeyAbort,
+
+        KeyLeft,
+        KeyRight,
+        KeyUp,
+        KeyDown,
+
+        KeyRedo,
+        KeyUndo,
+        KeyHome,
+
+        KeyPatternCount
+    };
+
+    //! A pattern for mouse events
+    class MousePattern
+    {
+    public:
+        //! Constructor
+        MousePattern( int btn = Qt::NoButton, int st = Qt::NoButton )
+        {
+            button = btn;
+            state = st;
+        }
+
+        //! Button code
+        int button;
+
+        //! State
+        int state;
+    };
+
+    //! A pattern for key events
+    class KeyPattern
+    {
+    public:
+        //! Constructor
+        KeyPattern( int k = 0, int st = Qt::NoButton )
+        {
+            key = k;
+            state = st;
+        }
+
+        //! Key code
+        int key;
+
+        //! State
+        int state;
+    };
+
+    QwtEventPattern();
+    virtual ~QwtEventPattern();
+
+    void initMousePattern( int numButtons );
+    void initKeyPattern();
+
+    void setMousePattern( uint pattern, int button, int state = Qt::NoButton );
+    void setKeyPattern( uint pattern, int key, int state = Qt::NoButton );
+
+    void setMousePattern( const QVector<MousePattern> & );
+    void setKeyPattern( const QVector<KeyPattern> & );
+
+    const QVector<MousePattern> &mousePattern() const;
+    const QVector<KeyPattern> &keyPattern() const;
+
+    QVector<MousePattern> &mousePattern();
+    QVector<KeyPattern> &keyPattern();
+
+    bool mouseMatch( uint pattern, const QMouseEvent * ) const;
+    bool keyMatch( uint pattern, const QKeyEvent * ) const;
+
+protected:
+    virtual bool mouseMatch( const MousePattern &, const QMouseEvent * ) const;
+    virtual bool keyMatch( const KeyPattern &, const QKeyEvent * ) const;
+
+private:
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable: 4251)
+#endif
+    QVector<MousePattern> d_mousePattern;
+    QVector<KeyPattern> d_keyPattern;
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+};
+
+//! Compare operator
+inline bool operator==( QwtEventPattern::MousePattern b1,
+    QwtEventPattern::MousePattern  b2 )
+{
+    return b1.button == b2.button && b1.state == b2.state;
+}
+
+//! Compare operator
+inline bool operator==( QwtEventPattern::KeyPattern b1,
+   QwtEventPattern::KeyPattern  b2 )
+{
+    return b1.key == b2.key && b1.state == b2.state;
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_global.h
===================================================================
--- trunk/BNC/qwt/qwt_global.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_global.h	(revision 4271)
@@ -0,0 +1,46 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_GLOBAL_H
+#define QWT_GLOBAL_H
+
+#include <qglobal.h>
+
+// QWT_VERSION is (major << 16) + (minor << 8) + patch.
+
+#define QWT_VERSION       0x060001
+#define QWT_VERSION_STR   "6.0.1"
+
+#if defined(Q_WS_WIN) || defined(Q_WS_S60)
+
+#if defined(_MSC_VER) /* MSVC Compiler */
+/* template-class specialization 'identifier' is already instantiated */
+#pragma warning(disable: 4660)
+#endif // _MSC_VER
+
+#ifdef QWT_DLL
+
+#if defined(QWT_MAKEDLL)     // create a Qwt DLL library 
+#define QWT_EXPORT  __declspec(dllexport)
+#define QWT_TEMPLATEDLL
+#else                        // use a Qwt DLL library
+#define QWT_EXPORT  __declspec(dllimport)
+#endif
+
+#endif // QWT_DLL
+
+#endif // Q_WS_WIN || Q_WS_S60
+
+#ifndef QWT_EXPORT
+#define QWT_EXPORT
+#endif
+
+// #define QWT_NO_COMPAT 1 // disable withdrawn functionality
+
+#endif 
Index: trunk/BNC/qwt/qwt_interval.cpp
===================================================================
--- trunk/BNC/qwt/qwt_interval.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_interval.cpp	(revision 4271)
@@ -0,0 +1,334 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_interval.h"
+#include "qwt_math.h"
+#include <qalgorithms.h>
+
+/*!
+   \brief Normalize the limits of the interval
+
+   If maxValue() < minValue() the limits will be inverted.
+   \return Normalized interval
+
+   \sa isValid(), inverted()
+*/
+QwtInterval QwtInterval::normalized() const
+{
+    if ( d_minValue > d_maxValue )
+    {
+        return inverted();
+    }
+    if ( d_minValue == d_maxValue && d_borderFlags == ExcludeMinimum )
+    {
+        return inverted();
+    }
+
+    return *this;
+}
+
+/*!
+   Invert the limits of the interval
+   \return Inverted interval
+   \sa normalized()
+*/
+QwtInterval QwtInterval::inverted() const
+{
+    BorderFlags borderFlags = IncludeBorders;
+    if ( d_borderFlags & ExcludeMinimum )
+        borderFlags |= ExcludeMaximum;
+    if ( d_borderFlags & ExcludeMaximum )
+        borderFlags |= ExcludeMinimum;
+
+    return QwtInterval( d_maxValue, d_minValue, borderFlags );
+}
+
+/*!
+  Test if a value is inside an interval
+
+  \param value Value
+  \return true, if value >= minValue() && value <= maxValue()
+*/
+bool QwtInterval::contains( double value ) const
+{
+    if ( !isValid() )
+        return false;
+
+    if ( value < d_minValue || value > d_maxValue )
+        return false;
+
+    if ( value == d_minValue && d_borderFlags & ExcludeMinimum )
+        return false;
+
+    if ( value == d_maxValue && d_borderFlags & ExcludeMaximum )
+        return false;
+
+    return true;
+}
+
+//! Unite 2 intervals
+QwtInterval QwtInterval::unite( const QwtInterval &other ) const
+{
+    /*
+     If one of the intervals is invalid return the other one.
+     If both are invalid return an invalid default interval
+     */
+    if ( !isValid() )
+    {
+        if ( !other.isValid() )
+            return QwtInterval();
+        else
+            return other;
+    }
+    if ( !other.isValid() )
+        return *this;
+
+    QwtInterval united;
+    BorderFlags flags = IncludeBorders;
+
+    // minimum
+    if ( d_minValue < other.minValue() )
+    {
+        united.setMinValue( d_minValue );
+        flags &= d_borderFlags & ExcludeMinimum;
+    }
+    else if ( other.minValue() < d_minValue )
+    {
+        united.setMinValue( other.minValue() );
+        flags &= other.borderFlags() & ExcludeMinimum;
+    }
+    else // d_minValue == other.minValue()
+    {
+        united.setMinValue( d_minValue );
+        flags &= ( d_borderFlags & other.borderFlags() ) & ExcludeMinimum;
+    }
+
+    // maximum
+    if ( d_maxValue > other.maxValue() )
+    {
+        united.setMaxValue( d_maxValue );
+        flags &= d_borderFlags & ExcludeMaximum;
+    }
+    else if ( other.maxValue() > d_maxValue )
+    {
+        united.setMaxValue( other.maxValue() );
+        flags &= other.borderFlags() & ExcludeMaximum;
+    }
+    else // d_maxValue == other.maxValue() )
+    {
+        united.setMaxValue( d_maxValue );
+        flags &= d_borderFlags & other.borderFlags() & ExcludeMaximum;
+    }
+
+    united.setBorderFlags( flags );
+    return united;
+}
+
+//! Intersect 2 intervals
+QwtInterval QwtInterval::intersect( const QwtInterval &other ) const
+{
+    if ( !other.isValid() || !isValid() )
+        return QwtInterval();
+
+    QwtInterval i1 = *this;
+    QwtInterval i2 = other;
+
+    // swap i1/i2, so that the minimum of i1
+    // is smaller then the minimum of i2
+
+    if ( i1.minValue() > i2.minValue() )
+    {
+        qSwap( i1, i2 );
+    }
+    else if ( i1.minValue() == i2.minValue() )
+    {
+        if ( i1.borderFlags() & ExcludeMinimum )
+            qSwap( i1, i2 );
+    }
+
+    if ( i1.maxValue() < i2.minValue() )
+    {
+        return QwtInterval();
+    }
+
+    if ( i1.maxValue() == i2.minValue() )
+    {
+        if ( i1.borderFlags() & ExcludeMaximum ||
+            i2.borderFlags() & ExcludeMinimum )
+        {
+            return QwtInterval();
+        }
+    }
+
+    QwtInterval intersected;
+    BorderFlags flags = IncludeBorders;
+
+    intersected.setMinValue( i2.minValue() );
+    flags |= i2.borderFlags() & ExcludeMinimum;
+
+    if ( i1.maxValue() < i2.maxValue() )
+    {
+        intersected.setMaxValue( i1.maxValue() );
+        flags |= i1.borderFlags() & ExcludeMaximum;
+    }
+    else if ( i2.maxValue() < i1.maxValue() )
+    {
+        intersected.setMaxValue( i2.maxValue() );
+        flags |= i2.borderFlags() & ExcludeMaximum;
+    }
+    else // i1.maxValue() == i2.maxValue()
+    {
+        intersected.setMaxValue( i1.maxValue() );
+        flags |= i1.borderFlags() & i2.borderFlags() & ExcludeMaximum;
+    }
+
+    intersected.setBorderFlags( flags );
+    return intersected;
+}
+
+//! Unites this interval with the given interval.
+QwtInterval& QwtInterval::operator|=( const QwtInterval & interval )
+{
+    *this = *this | interval;
+    return *this;
+}
+
+//! Intersects this interval with the given interval.
+QwtInterval& QwtInterval::operator&=( const QwtInterval & interval )
+{
+    *this = *this & interval;
+    return *this;
+}
+
+/*!
+   Test if two intervals overlap
+*/
+bool QwtInterval::intersects( const QwtInterval &other ) const
+{
+    if ( !isValid() || !other.isValid() )
+        return false;
+
+    QwtInterval i1 = *this;
+    QwtInterval i2 = other;
+
+    // swap i1/i2, so that the minimum of i1
+    // is smaller then the minimum of i2
+
+    if ( i1.minValue() > i2.minValue() )
+    {
+        qSwap( i1, i2 );
+    }
+    else if ( i1.minValue() == i2.minValue() &&
+              i1.borderFlags() & ExcludeMinimum )
+    {
+        qSwap( i1, i2 );
+    }
+
+    if ( i1.maxValue() > i2.minValue() )
+    {
+        return true;
+    }
+    if ( i1.maxValue() == i2.minValue() )
+    {
+        return !( ( i1.borderFlags() & ExcludeMaximum ) ||
+            ( i2.borderFlags() & ExcludeMinimum ) );
+    }
+    return false;
+}
+
+/*!
+   Adjust the limit that is closer to value, so that value becomes
+   the center of the interval.
+
+   \param value Center
+   \return Interval with value as center
+*/
+QwtInterval QwtInterval::symmetrize( double value ) const
+{
+    if ( !isValid() )
+        return *this;
+
+    const double delta =
+        qMax( qAbs( value - d_maxValue ), qAbs( value - d_minValue ) );
+
+    return QwtInterval( value - delta, value + delta );
+}
+
+/*!
+   Limit the interval, keeping the border modes
+
+   \param lowerBound Lower limit
+   \param upperBound Upper limit
+
+   \return Limited interval
+*/
+QwtInterval QwtInterval::limited( double lowerBound, double upperBound ) const
+{
+    if ( !isValid() || lowerBound > upperBound )
+        return QwtInterval();
+
+    double minValue = qMax( d_minValue, lowerBound );
+    minValue = qMin( minValue, upperBound );
+
+    double maxValue = qMax( d_maxValue, lowerBound );
+    maxValue = qMin( maxValue, upperBound );
+
+    return QwtInterval( minValue, maxValue, d_borderFlags );
+}
+
+/*!
+   Extend the interval
+
+   If value is below minValue, value becomes the lower limit.
+   If value is above maxValue, value becomes the upper limit.
+
+   extend has no effect for invalid intervals
+
+   \param value Value
+   \sa isValid()
+*/
+QwtInterval QwtInterval::extend( double value ) const
+{
+    if ( !isValid() )
+        return *this;
+
+    return QwtInterval( qMin( value, d_minValue ),
+        qMax( value, d_maxValue ), d_borderFlags );
+}
+
+/*!
+   Extend an interval
+
+   \param value Value
+   \return Reference of the extended interval
+
+   \sa extend()
+*/
+QwtInterval& QwtInterval::operator|=( double value )
+{
+    *this = *this | value;
+    return *this;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+
+QDebug operator<<( QDebug debug, const QwtInterval &interval )
+{
+    const int flags = interval.borderFlags();
+
+    debug.nospace() << "QwtInterval("
+        << ( ( flags & QwtInterval::ExcludeMinimum ) ? "]" : "[" )
+        << interval.minValue() << "," << interval.maxValue()
+        << ( ( flags & QwtInterval::ExcludeMaximum ) ? "[" : "]" )
+        << ")";
+
+    return debug.space();
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_interval.h
===================================================================
--- trunk/BNC/qwt/qwt_interval.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_interval.h	(revision 4271)
@@ -0,0 +1,296 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_INTERVAL_H
+#define QWT_INTERVAL_H
+
+#include "qwt_global.h"
+#ifndef QT_NO_DEBUG_STREAM
+#include <qdebug.h>
+#endif
+
+/*!
+  \brief A class representing an interval
+
+  The interval is represented by 2 doubles, the lower and the upper limit.
+*/
+
+class QWT_EXPORT QwtInterval
+{
+public:
+    /*!
+      Flag indicating if a border is included or excluded 
+      \sa setBorderFlags(), borderFlags()
+    */
+    enum BorderFlag
+    {
+        //! Min/Max values are inside the interval
+        IncludeBorders = 0x00,
+
+        //! Min value is not included in the interval
+        ExcludeMinimum = 0x01,
+
+        //! Max value is not included in the interval
+        ExcludeMaximum = 0x02,
+
+        //! Min/Max values are not included in the interval
+        ExcludeBorders = ExcludeMinimum | ExcludeMaximum
+    };
+
+    //! Border flags
+    typedef QFlags<BorderFlag> BorderFlags;
+
+    QwtInterval();
+    QwtInterval( double minValue, double maxValue,
+        BorderFlags = IncludeBorders );
+
+    void setInterval( double minValue, double maxValue,
+        BorderFlags = IncludeBorders );
+
+    QwtInterval normalized() const;
+    QwtInterval inverted() const;
+    QwtInterval limited( double minValue, double maxValue ) const;
+
+    bool operator==( const QwtInterval & ) const;
+    bool operator!=( const QwtInterval & ) const;
+
+    void setBorderFlags( BorderFlags );
+    BorderFlags borderFlags() const;
+
+    double minValue() const;
+    double maxValue() const;
+
+    double width() const;
+
+    void setMinValue( double );
+    void setMaxValue( double );
+
+    bool contains( double value ) const;
+
+    bool intersects( const QwtInterval & ) const;
+    QwtInterval intersect( const QwtInterval & ) const;
+    QwtInterval unite( const QwtInterval & ) const;
+
+    QwtInterval operator|( const QwtInterval & ) const;
+    QwtInterval operator&( const QwtInterval & ) const;
+
+    QwtInterval &operator|=( const QwtInterval & );
+    QwtInterval &operator&=( const QwtInterval & );
+
+    QwtInterval extend( double value ) const;
+    QwtInterval operator|( double ) const;
+    QwtInterval &operator|=( double );
+
+    bool isValid() const;
+    bool isNull() const;
+    void invalidate();
+
+    QwtInterval symmetrize( double value ) const;
+
+private:
+    double d_minValue;
+    double d_maxValue;
+    BorderFlags d_borderFlags;
+};
+
+Q_DECLARE_TYPEINFO(QwtInterval, Q_MOVABLE_TYPE);
+
+/*!
+  \brief Default Constructor
+
+  Creates an invalid interval [0.0, -1.0]
+  \sa setInterval(), isValid()
+*/
+inline QwtInterval::QwtInterval():
+    d_minValue( 0.0 ),
+    d_maxValue( -1.0 ),
+    d_borderFlags( IncludeBorders )
+{
+}
+
+/*!
+   Constructor
+
+   Build an interval with from min/max values
+
+   \param minValue Minimum value
+   \param maxValue Maximum value
+   \param borderFlags Include/Exclude borders
+*/
+inline QwtInterval::QwtInterval(
+        double minValue, double maxValue, BorderFlags borderFlags ):
+    d_minValue( minValue ),
+    d_maxValue( maxValue ),
+    d_borderFlags( borderFlags )
+{
+}
+
+/*!
+   Assign the limits of the interval
+
+   \param minValue Minimum value
+   \param maxValue Maximum value
+   \param borderFlags Include/Exclude borders
+*/
+inline void QwtInterval::setInterval(
+    double minValue, double maxValue, BorderFlags borderFlags )
+{
+    d_minValue = minValue;
+    d_maxValue = maxValue;
+    d_borderFlags = borderFlags;
+}
+
+/*!
+   Change the border flags
+
+   \param borderFlags Or'd BorderMode flags
+   \sa borderFlags()
+*/
+inline void QwtInterval::setBorderFlags( BorderFlags borderFlags )
+{
+    d_borderFlags = borderFlags;
+}
+
+/*!
+   \return Border flags
+   \sa setBorderFlags()
+*/
+inline QwtInterval::BorderFlags QwtInterval::borderFlags() const
+{
+    return d_borderFlags;
+}
+
+/*!
+   Assign the lower limit of the interval
+
+   \param minValue Minimum value
+*/
+inline void QwtInterval::setMinValue( double minValue )
+{
+    d_minValue = minValue;
+}
+
+/*!
+   Assign the upper limit of the interval
+
+   \param maxValue Maximum value
+*/
+inline void QwtInterval::setMaxValue( double maxValue )
+{
+    d_maxValue = maxValue;
+}
+
+//! \return Lower limit of the interval
+inline double QwtInterval::minValue() const
+{
+    return d_minValue;
+}
+
+//! \return Upper limit of the interval
+inline double QwtInterval::maxValue() const
+{
+    return d_maxValue;
+}
+
+/*!
+   Return the width of an interval
+   The width of invalid intervals is 0.0, otherwise the result is
+   maxValue() - minValue().
+
+   \sa isValid()
+*/
+inline double QwtInterval::width() const
+{
+    return isValid() ? ( d_maxValue - d_minValue ) : 0.0;
+}
+
+/*!
+   Intersection of two intervals
+   \sa intersect()
+*/
+inline QwtInterval QwtInterval::operator&(
+    const QwtInterval &interval ) const
+{
+    return intersect( interval );
+}
+
+/*!
+   Union of two intervals
+   \sa unite()
+*/
+inline QwtInterval QwtInterval::operator|(
+    const QwtInterval &interval ) const
+{
+    return unite( interval );
+}
+
+//! Compare two intervals
+inline bool QwtInterval::operator==( const QwtInterval &other ) const
+{
+    return ( d_minValue == other.d_minValue ) &&
+           ( d_maxValue == other.d_maxValue ) &&
+           ( d_borderFlags == other.d_borderFlags );
+}
+
+//! Compare two intervals
+inline bool QwtInterval::operator!=( const QwtInterval &other ) const
+{
+    return ( !( *this == other ) );
+}
+
+/*!
+   Extend an interval
+
+   \param value Value
+   \return Extended interval
+   \sa extend()
+*/
+inline QwtInterval QwtInterval::operator|( double value ) const
+{
+    return extend( value );
+}
+
+//! \return true, if isValid() && (minValue() >= maxValue())
+inline bool QwtInterval::isNull() const
+{
+    return isValid() && d_minValue >= d_maxValue;
+}
+
+/*!
+   A interval is valid when minValue() <= maxValue().
+   In case of QwtInterval::ExcludeBorders it is true
+   when minValue() < maxValue()
+*/
+inline bool QwtInterval::isValid() const
+{
+    if ( ( d_borderFlags & ExcludeBorders ) == 0 )
+        return d_minValue <= d_maxValue;
+    else
+        return d_minValue < d_maxValue;
+}
+
+/*!
+  Invalidate the interval
+
+  The limits are set to interval [0.0, -1.0]
+  \sa isValid()
+*/
+inline void QwtInterval::invalidate()
+{
+    d_minValue = 0.0;
+    d_maxValue = -1.0;
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtInterval::BorderFlags )
+
+#ifndef QT_NO_DEBUG_STREAM
+QWT_EXPORT QDebug operator<<( QDebug, const QwtInterval & );
+#endif
+
+#endif
Index: trunk/BNC/qwt/qwt_interval_symbol.cpp
===================================================================
--- trunk/BNC/qwt/qwt_interval_symbol.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_interval_symbol.cpp	(revision 4271)
@@ -0,0 +1,298 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_interval_symbol.h"
+#include "qwt_painter.h"
+#include "qwt_math.h"
+#include <qpainter.h>
+
+#if QT_VERSION < 0x040601
+#define qAtan2(y, x) ::atan2(y, x)
+#endif
+
+class QwtIntervalSymbol::PrivateData
+{
+public:
+    PrivateData():
+        style( QwtIntervalSymbol::NoSymbol ),
+        width( 6 )
+    {
+    }
+
+    bool operator==( const PrivateData &other ) const
+    {
+        return ( style == other.style )
+            && ( width == other.width )
+            && ( brush == other.brush )
+            && ( pen == other.pen );
+    }
+
+    QwtIntervalSymbol::Style style;
+    int width;
+
+    QPen pen;
+    QBrush brush;
+};
+
+/*!
+  Constructor
+
+  \param style Style of the symbol
+  \sa setStyle(), style(), Style
+*/
+QwtIntervalSymbol::QwtIntervalSymbol( Style style )
+{
+    d_data = new PrivateData();
+    d_data->style = style;
+}
+
+//! Copy constructor
+QwtIntervalSymbol::QwtIntervalSymbol( const QwtIntervalSymbol &other )
+{
+    d_data = new PrivateData();
+    *d_data = *other.d_data;
+}
+
+//! Destructor
+QwtIntervalSymbol::~QwtIntervalSymbol()
+{
+    delete d_data;
+}
+
+//! \brief Assignment operator
+QwtIntervalSymbol &QwtIntervalSymbol::operator=( 
+    const QwtIntervalSymbol &other )
+{
+    *d_data = *other.d_data;
+    return *this;
+}
+
+//! \brief Compare two symbols
+bool QwtIntervalSymbol::operator==( 
+    const QwtIntervalSymbol &other ) const
+{
+    return *d_data == *other.d_data;
+}
+
+//! \brief Compare two symbols
+bool QwtIntervalSymbol::operator!=( 
+    const QwtIntervalSymbol &other ) const
+{
+    return !( *d_data == *other.d_data );
+}
+
+/*!
+  Specify the symbol style
+
+  \param style Style
+  \sa style(), Style
+*/
+void QwtIntervalSymbol::setStyle( Style style )
+{
+    d_data->style = style;
+}
+
+/*!
+  \return Current symbol style
+  \sa setStyle()
+*/
+QwtIntervalSymbol::Style QwtIntervalSymbol::style() const
+{
+    return d_data->style;
+}
+
+/*!
+  Specify the width of the symbol
+  It is used depending on the style.
+
+  \param width Width
+  \sa width(), setStyle()
+*/
+void QwtIntervalSymbol::setWidth( int width )
+{
+    d_data->width = width;
+}
+
+/*!
+  \return Width of the symbol.
+  \sa setWidth(), setStyle()
+*/
+int QwtIntervalSymbol::width() const
+{
+    return d_data->width;
+}
+
+/*!
+  \brief Assign a brush
+
+  The brush is used for the Box style.
+
+  \param brush Brush
+  \sa brush()
+*/
+void QwtIntervalSymbol::setBrush( const QBrush &brush )
+{
+    d_data->brush = brush;
+}
+
+/*!
+  \return Brush
+  \sa setBrush()
+*/
+const QBrush& QwtIntervalSymbol::brush() const
+{
+    return d_data->brush;
+}
+
+/*!
+  Assign a pen
+
+  \param pen Pen
+  \sa pen(), setBrush()
+*/
+void QwtIntervalSymbol::setPen( const QPen &pen )
+{
+    d_data->pen = pen;
+}
+
+/*!
+  \return Pen
+  \sa setPen(), brush()
+*/
+const QPen& QwtIntervalSymbol::pen() const
+{
+    return d_data->pen;
+}
+
+/*!
+  Draw a symbol depending on its style
+
+  \param painter Painter
+  \param orientation Orientation
+  \param from Start point of the interval in target device coordinates
+  \param to End point of the interval in target device coordinates
+
+  \sa setStyle()
+*/
+void QwtIntervalSymbol::draw( QPainter *painter, Qt::Orientation orientation,
+    const QPointF &from, const QPointF &to ) const
+{
+    const qreal pw = qMax( painter->pen().widthF(), qreal( 1.0 ) );
+
+    QPointF p1 = from;
+    QPointF p2 = to;
+    if ( QwtPainter::roundingAlignment( painter ) )
+    {
+        p1 = p1.toPoint();
+        p2 = p2.toPoint();
+    }
+
+    switch ( d_data->style )
+    {
+        case QwtIntervalSymbol::Bar:
+        {
+            QwtPainter::drawLine( painter, p1, p2 );
+            if ( d_data->width > pw )
+            {
+                if ( ( orientation == Qt::Horizontal ) 
+                    && ( p1.y() == p2.y() ) )
+                {
+                    const double sw = d_data->width;
+
+                    const double y = p1.y() - sw / 2;
+                    QwtPainter::drawLine( painter,
+                        p1.x(), y, p1.x(), y + sw );
+                    QwtPainter::drawLine( painter,
+                        p2.x(), y, p2.x(), y + sw );
+                }
+                else if ( ( orientation == Qt::Vertical ) 
+                    && ( p1.x() == p2.x() ) )
+                {
+                    const double sw = d_data->width;
+
+                    const double x = p1.x() - sw / 2;
+                    QwtPainter::drawLine( painter,
+                        x, p1.y(), x + sw, p1.y() );
+                    QwtPainter::drawLine( painter,
+                        x, p2.y(), x + sw, p2.y() );
+                }
+                else
+                {
+                    const double sw = d_data->width;
+
+                    const double dx = p2.x() - p1.x();
+                    const double dy = p2.y() - p1.y();
+                    const double angle = qAtan2( dy, dx ) + M_PI_2;
+                    double dw2 = sw / 2.0;
+
+                    const double cx = qCos( angle ) * dw2;
+                    const double sy = qSin( angle ) * dw2;
+
+                    QwtPainter::drawLine( painter,
+                        p1.x() - cx, p1.y() - sy,
+                        p1.x() + cx, p1.y() + sy );
+                    QwtPainter::drawLine( painter,
+                        p2.x() - cx, p2.y() - sy,
+                        p2.x() + cx, p2.y() + sy );
+                }
+            }
+            break;
+        }
+        case QwtIntervalSymbol::Box:
+        {
+            if ( d_data->width <= pw )
+            {
+                QwtPainter::drawLine( painter, p1, p2 );
+            }
+            else
+            {
+                if ( ( orientation == Qt::Horizontal ) 
+                    && ( p1.y() == p2.y() ) )
+                {
+                    const double sw = d_data->width;
+
+                    const double y = p1.y() - d_data->width / 2;
+                    QwtPainter::drawRect( painter,
+                        p1.x(), y, p2.x() - p1.x(),  sw );
+                }
+                else if ( ( orientation == Qt::Vertical )
+                    && ( p1.x() == p2.x() ) )
+                {
+                    const double sw = d_data->width;
+
+                    const double x = p1.x() - d_data->width / 2;
+                    QwtPainter::drawRect( painter,
+                        x, p1.y(), sw, p2.y() - p1.y() );
+                }
+                else
+                {
+                    const double sw = d_data->width;
+
+                    const double dx = p2.x() - p1.x();
+                    const double dy = p2.y() - p1.y();
+                    const double angle = qAtan2( dy, dx ) + M_PI_2;
+                    double dw2 = sw / 2.0;
+
+                    const int cx = qCos( angle ) * dw2;
+                    const int sy = qSin( angle ) * dw2;
+
+                    QPolygonF polygon;
+                    polygon += QPointF( p1.x() - cx, p1.y() - sy );
+                    polygon += QPointF( p1.x() + cx, p1.y() + sy );
+                    polygon += QPointF( p2.x() + cx, p2.y() + sy );
+                    polygon += QPointF( p2.x() - cx, p2.y() - sy );
+
+                    QwtPainter::drawPolygon( painter, polygon );
+                }
+            }
+            break;
+        }
+        default:;
+    }
+}
Index: trunk/BNC/qwt/qwt_interval_symbol.h
===================================================================
--- trunk/BNC/qwt/qwt_interval_symbol.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_interval_symbol.h	(revision 4271)
@@ -0,0 +1,86 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_INTERVAL_SYMBOL_H
+#define QWT_INTERVAL_SYMBOL_H
+
+#include "qwt_global.h"
+#include <qpen.h>
+#include <qsize.h>
+
+class QPainter;
+class QRect;
+class QPointF;
+
+/*!
+  \brief A drawing primitive for displaying an interval like an error bar
+
+  \sa QwtPlotIntervalCurve
+*/
+class QWT_EXPORT QwtIntervalSymbol
+{
+public:
+    //! Symbol style
+    enum Style
+    {
+        //! No Style. The symbol cannot be drawn.
+        NoSymbol = -1,
+
+        /*!
+          The symbol displays a line with caps at the beginning/end.
+          The size of the caps depends on the symbol width().
+         */
+        Bar,
+
+        /*!
+          The symbol displays a plain rectangle using pen() and brush().
+          The size of the rectangle depends on the translated interval and
+          the width(),
+         */
+        Box,
+
+        /*!
+          Styles >= UserSymbol are reserved for derived
+          classes of QwtIntervalSymbol that overload draw() with
+          additional application specific symbol types.
+         */
+        UserSymbol = 1000
+    };
+
+public:
+    QwtIntervalSymbol( Style = NoSymbol );
+    QwtIntervalSymbol( const QwtIntervalSymbol & );
+    virtual ~QwtIntervalSymbol();
+
+    QwtIntervalSymbol &operator=( const QwtIntervalSymbol & );
+    bool operator==( const QwtIntervalSymbol & ) const;
+    bool operator!=( const QwtIntervalSymbol & ) const;
+
+    void setWidth( int );
+    int width() const;
+
+    void setBrush( const QBrush& b );
+    const QBrush& brush() const;
+
+    void setPen( const QPen & );
+    const QPen& pen() const;
+
+    void setStyle( Style );
+    Style style() const;
+
+    virtual void draw( QPainter *, Qt::Orientation,
+        const QPointF& from, const QPointF& to ) const;
+
+private:
+
+    class PrivateData;
+    PrivateData* d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_legend.cpp
===================================================================
--- trunk/BNC/qwt/qwt_legend.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_legend.cpp	(revision 4271)
@@ -0,0 +1,519 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_legend.h"
+#include "qwt_legend_itemmanager.h"
+#include "qwt_legend_item.h"
+#include "qwt_dyngrid_layout.h"
+#include "qwt_math.h"
+#include <qapplication.h>
+#include <qmap.h>
+#include <qscrollbar.h>
+#include <qscrollarea.h>
+
+class QwtLegend::PrivateData
+{
+public:
+    class LegendMap
+    {
+    public:
+        void insert( const QwtLegendItemManager *, QWidget * );
+
+        void remove( const QwtLegendItemManager * );
+        void remove( QWidget * );
+
+        void clear();
+
+        uint count() const;
+
+        inline const QWidget *find( const QwtLegendItemManager * ) const;
+        inline QWidget *find( const QwtLegendItemManager * );
+
+        inline const QwtLegendItemManager *find( const QWidget * ) const;
+        inline QwtLegendItemManager *find( const QWidget * );
+
+        const QMap<QWidget *, const QwtLegendItemManager *> &widgetMap() const;
+        QMap<QWidget *, const QwtLegendItemManager *> &widgetMap();
+
+    private:
+        QMap<QWidget *, const QwtLegendItemManager *> d_widgetMap;
+        QMap<const QwtLegendItemManager *, QWidget *> d_itemMap;
+    };
+
+    QwtLegend::LegendItemMode itemMode;
+
+    LegendMap map;
+
+    class LegendView;
+    LegendView *view;
+};
+
+class QwtLegend::PrivateData::LegendView: public QScrollArea
+{
+public:
+    LegendView( QWidget *parent ):
+        QScrollArea( parent )
+    {
+        setFocusPolicy( Qt::NoFocus );
+
+        contentsWidget = new QWidget( this );
+        contentsWidget->setObjectName( "QwtLegendViewContents" );
+
+        setWidget( contentsWidget );
+        setWidgetResizable( false );
+
+        viewport()->setObjectName( "QwtLegendViewport" );
+
+        // QScrollArea::setWidget internally sets autoFillBackground to true
+        // But we don't want a background.
+        contentsWidget->setAutoFillBackground( false );
+        viewport()->setAutoFillBackground( false );
+    }
+
+    virtual bool viewportEvent( QEvent *e )
+    {
+        bool ok = QScrollArea::viewportEvent( e );
+
+        if ( e->type() == QEvent::Resize )
+        {
+            QEvent event( QEvent::LayoutRequest );
+            QApplication::sendEvent( contentsWidget, &event );
+        }
+        return ok;
+    }
+
+    QSize viewportSize( int w, int h ) const
+    {
+        const int sbHeight = horizontalScrollBar()->sizeHint().height();
+        const int sbWidth = verticalScrollBar()->sizeHint().width();
+
+        const int cw = contentsRect().width();
+        const int ch = contentsRect().height();
+
+        int vw = cw;
+        int vh = ch;
+
+        if ( w > vw )
+            vh -= sbHeight;
+
+        if ( h > vh )
+        {
+            vw -= sbWidth;
+            if ( w > vw && vh == ch )
+                vh -= sbHeight;
+        }
+        return QSize( vw, vh );
+    }
+
+    QWidget *contentsWidget;
+};
+
+void QwtLegend::PrivateData::LegendMap::insert(
+    const QwtLegendItemManager *item, QWidget *widget )
+{
+    d_itemMap.insert( item, widget );
+    d_widgetMap.insert( widget, item );
+}
+
+void QwtLegend::PrivateData::LegendMap::remove( const QwtLegendItemManager *item )
+{
+    QWidget *widget = d_itemMap[item];
+    d_itemMap.remove( item );
+    d_widgetMap.remove( widget );
+}
+
+void QwtLegend::PrivateData::LegendMap::remove( QWidget *widget )
+{
+    const QwtLegendItemManager *item = d_widgetMap[widget];
+    d_itemMap.remove( item );
+    d_widgetMap.remove( widget );
+}
+
+void QwtLegend::PrivateData::LegendMap::clear()
+{
+
+    /*
+       We can't delete the widgets in the following loop, because
+       we would get ChildRemoved events, changing d_itemMap, while
+       we are iterating.
+     */
+
+    QList<const QWidget *> widgets;
+
+    QMap<const QwtLegendItemManager *, QWidget *>::const_iterator it;
+    for ( it = d_itemMap.begin(); it != d_itemMap.end(); ++it )
+        widgets.append( it.value() );
+
+    d_itemMap.clear();
+    d_widgetMap.clear();
+
+    for ( int i = 0; i < widgets.size(); i++ )
+        delete widgets[i];
+}
+
+uint QwtLegend::PrivateData::LegendMap::count() const
+{
+    return d_itemMap.count();
+}
+
+inline const QWidget *QwtLegend::PrivateData::LegendMap::find( 
+    const QwtLegendItemManager *item ) const
+{
+    if ( !d_itemMap.contains( item ) )
+        return NULL;
+
+    return d_itemMap[item];
+}
+
+inline QWidget *QwtLegend::PrivateData::LegendMap::find( 
+    const QwtLegendItemManager *item )
+{
+    if ( !d_itemMap.contains( item ) )
+        return NULL;
+
+    return d_itemMap[item];
+}
+
+inline const QwtLegendItemManager *QwtLegend::PrivateData::LegendMap::find(
+    const QWidget *widget ) const
+{
+    QWidget *w = const_cast<QWidget *>( widget );
+    if ( !d_widgetMap.contains( w ) )
+        return NULL;
+
+    return d_widgetMap[w];
+}
+
+inline QwtLegendItemManager *QwtLegend::PrivateData::LegendMap::find(
+    const QWidget *widget )
+{
+    QWidget *w = const_cast<QWidget *>( widget );
+    if ( !d_widgetMap.contains( w ) )
+        return NULL;
+
+    return const_cast<QwtLegendItemManager *>( d_widgetMap[w] );
+}
+
+inline const QMap<QWidget *, const QwtLegendItemManager *> &
+QwtLegend::PrivateData::LegendMap::widgetMap() const
+{
+    return d_widgetMap;
+}
+
+inline QMap<QWidget *, const QwtLegendItemManager *> &
+QwtLegend::PrivateData::LegendMap::widgetMap()
+{
+    return d_widgetMap;
+}
+
+/*!
+  Constructor
+
+  \param parent Parent widget
+*/
+QwtLegend::QwtLegend( QWidget *parent ):
+    QFrame( parent )
+{
+    setFrameStyle( NoFrame );
+
+    d_data = new QwtLegend::PrivateData;
+    d_data->itemMode = QwtLegend::ReadOnlyItem;
+
+    d_data->view = new QwtLegend::PrivateData::LegendView( this );
+    d_data->view->setObjectName( "QwtLegendView" );
+    d_data->view->setFrameStyle( NoFrame );
+
+    QwtDynGridLayout *gridLayout = new QwtDynGridLayout(
+        d_data->view->contentsWidget );
+    gridLayout->setAlignment( Qt::AlignHCenter | Qt::AlignTop );
+
+    d_data->view->contentsWidget->installEventFilter( this );
+
+    QVBoxLayout *layout = new QVBoxLayout( this );
+    layout->setContentsMargins( 0, 0, 0, 0 );
+    layout->addWidget( d_data->view );
+}
+
+//! Destructor
+QwtLegend::~QwtLegend()
+{
+    delete d_data;
+}
+
+//! \sa LegendItemMode
+void QwtLegend::setItemMode( LegendItemMode mode )
+{
+    d_data->itemMode = mode;
+}
+
+//! \sa LegendItemMode
+QwtLegend::LegendItemMode QwtLegend::itemMode() const
+{
+    return d_data->itemMode;
+}
+
+/*!
+  The contents widget is the only child of the viewport of 
+  the internal QScrollArea  and the parent widget of all legend items.
+
+  \return Container widget of the legend items
+*/
+QWidget *QwtLegend::contentsWidget()
+{
+    return d_data->view->contentsWidget;
+}
+
+/*!
+  \return Horizontal scrollbar
+  \sa verticalScrollBar()
+*/
+QScrollBar *QwtLegend::horizontalScrollBar() const
+{
+    return d_data->view->horizontalScrollBar();
+}
+
+/*!
+  \return Vertical scrollbar
+  \sa horizontalScrollBar()
+*/
+QScrollBar *QwtLegend::verticalScrollBar() const
+{
+    return d_data->view->verticalScrollBar();
+}
+
+/*!
+  The contents widget is the only child of the viewport of 
+  the internal QScrollArea  and the parent widget of all legend items.
+
+  \return Container widget of the legend items
+
+*/
+const QWidget *QwtLegend::contentsWidget() const
+{
+    return d_data->view->contentsWidget;
+}
+
+/*!
+  Insert a new item for a plot item
+  \param plotItem Plot item
+  \param legendItem New legend item
+  \note The parent of item will be changed to contentsWidget()
+*/
+void QwtLegend::insert( const QwtLegendItemManager *plotItem, QWidget *legendItem )
+{
+    if ( legendItem == NULL || plotItem == NULL )
+        return;
+
+    QWidget *contentsWidget = d_data->view->contentsWidget;
+
+    if ( legendItem->parent() != contentsWidget )
+        legendItem->setParent( contentsWidget );
+
+    legendItem->show();
+
+    d_data->map.insert( plotItem, legendItem );
+
+    layoutContents();
+
+    if ( contentsWidget->layout() )
+    {
+        contentsWidget->layout()->addWidget( legendItem );
+
+        // set tab focus chain
+
+        QWidget *w = NULL;
+
+        for ( int i = 0; i < contentsWidget->layout()->count(); i++ )
+        {
+            QLayoutItem *item = contentsWidget->layout()->itemAt( i );
+            if ( w && item->widget() )
+                QWidget::setTabOrder( w, item->widget() );
+
+            w = item->widget();
+        }
+    }
+    if ( parentWidget() && parentWidget()->layout() == NULL )
+    {
+        /*
+           updateGeometry() doesn't post LayoutRequest in certain
+           situations, like when we are hidden. But we want the
+           parent widget notified, so it can show/hide the legend
+           depending on its items.
+         */
+        QApplication::postEvent( parentWidget(),
+            new QEvent( QEvent::LayoutRequest ) );
+    }
+}
+
+/*!
+  Find the widget that represents a plot item
+
+  \param plotItem Plot item
+  \return Widget on the legend, or NULL
+*/
+QWidget *QwtLegend::find( const QwtLegendItemManager *plotItem ) const
+{
+    return d_data->map.find( plotItem );
+}
+
+/*!
+  Find the widget that represents a plot item
+
+  \param legendItem Legend item
+  \return Widget on the legend, or NULL
+*/
+QwtLegendItemManager *QwtLegend::find( const QWidget *legendItem ) const
+{
+    return d_data->map.find( legendItem );
+}
+
+/*!
+   Find the corresponding item for a plotItem and remove it
+   from the item list.
+
+   \param plotItem Plot item
+*/
+void QwtLegend::remove( const QwtLegendItemManager *plotItem )
+{
+    QWidget *legendItem = d_data->map.find( plotItem );
+    d_data->map.remove( legendItem );
+    delete legendItem;
+}
+
+//! Remove all items.
+void QwtLegend::clear()
+{
+    bool doUpdate = updatesEnabled();
+    if ( doUpdate )
+        setUpdatesEnabled( false );
+
+    d_data->map.clear();
+
+    if ( doUpdate )
+        setUpdatesEnabled( true );
+
+    update();
+}
+
+//! Return a size hint.
+QSize QwtLegend::sizeHint() const
+{
+    QSize hint = d_data->view->contentsWidget->sizeHint();
+    hint += QSize( 2 * frameWidth(), 2 * frameWidth() );
+
+    return hint;
+}
+
+/*!
+  \return The preferred height, for the width w.
+  \param width Width
+*/
+int QwtLegend::heightForWidth( int width ) const
+{
+    width -= 2 * frameWidth();
+
+    int h = d_data->view->contentsWidget->heightForWidth( width );
+    if ( h >= 0 )
+        h += 2 * frameWidth();
+
+    return h;
+}
+
+/*!
+  Adjust contents widget and item layout to the size of the viewport().
+*/
+void QwtLegend::layoutContents()
+{
+    const QSize visibleSize = 
+        d_data->view->viewport()->contentsRect().size();
+
+    const QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>(
+        d_data->view->contentsWidget->layout() );
+    if ( tl )
+    {
+        const int minW = int( tl->maxItemWidth() ) + 2 * tl->margin();
+
+        int w = qMax( visibleSize.width(), minW );
+        int h = qMax( tl->heightForWidth( w ), visibleSize.height() );
+
+        const int vpWidth = d_data->view->viewportSize( w, h ).width();
+        if ( w > vpWidth )
+        {
+            w = qMax( vpWidth, minW );
+            h = qMax( tl->heightForWidth( w ), visibleSize.height() );
+        }
+
+        d_data->view->contentsWidget->resize( w, h );
+    }
+}
+
+/*!
+  Handle QEvent::ChildRemoved andQEvent::LayoutRequest events 
+  for the contentsWidget().
+
+  \param object Object to be filtered
+  \param event Event
+*/
+bool QwtLegend::eventFilter( QObject *object, QEvent *event )
+{
+    if ( object == d_data->view->contentsWidget )
+    {
+        switch ( event->type() )
+        {
+            case QEvent::ChildRemoved:
+            {
+                const QChildEvent *ce = 
+                    static_cast<const QChildEvent *>(event);
+                if ( ce->child()->isWidgetType() )
+                {
+                    QWidget *w = static_cast< QWidget * >( ce->child() );
+                    d_data->map.remove( w );
+                }
+                break;
+            }
+            case QEvent::LayoutRequest:
+            {
+                layoutContents();
+                break;
+            }
+            default:
+                break;
+        }
+    }
+
+    return QFrame::eventFilter( object, event );
+}
+
+
+//! Return true, if there are no legend items.
+bool QwtLegend::isEmpty() const
+{
+    return d_data->map.count() == 0;
+}
+
+//! Return the number of legend items.
+uint QwtLegend::itemCount() const
+{
+    return d_data->map.count();
+}
+
+//! Return a list of all legend items
+QList<QWidget *> QwtLegend::legendItems() const
+{
+    const QMap<QWidget *, const QwtLegendItemManager *> &map =
+        d_data->map.widgetMap();
+
+    QList<QWidget *> list;
+
+    QMap<QWidget *, const QwtLegendItemManager *>::const_iterator it;
+    for ( it = map.begin(); it != map.end(); ++it )
+        list += it.key();
+
+    return list;
+}
Index: trunk/BNC/qwt/qwt_legend.h
===================================================================
--- trunk/BNC/qwt/qwt_legend.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_legend.h	(revision 4271)
@@ -0,0 +1,95 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_LEGEND_H
+#define QWT_LEGEND_H
+
+#include "qwt_global.h"
+#include <qframe.h>
+#include <qlist.h>
+
+class QScrollBar;
+class QwtLegendItemManager;
+
+/*!
+  \brief The legend widget
+
+  The QwtLegend widget is a tabular arrangement of legend items. Legend
+  items might be any type of widget, but in general they will be
+  a QwtLegendItem.
+
+  \sa QwtLegendItem, QwtLegendItemManager QwtPlot
+*/
+
+class QWT_EXPORT QwtLegend : public QFrame
+{
+    Q_OBJECT
+
+public:
+    /*!
+      \brief Interaction mode for the legend items
+
+       The default is QwtLegend::ReadOnlyItem.
+
+       \sa setItemMode(), itemMode(), QwtLegendItem::IdentifierMode
+           QwtLegendItem::clicked(), QwtLegendItem::checked(),
+           QwtPlot::legendClicked(), QwtPlot::legendChecked()
+     */
+
+    enum LegendItemMode
+    {
+        //! The legend item is not interactive, like a label
+        ReadOnlyItem,
+
+        //! The legend item is clickable, like a push button
+        ClickableItem,
+
+        //! The legend item is checkable, like a checkable button
+        CheckableItem
+    };
+
+    explicit QwtLegend( QWidget *parent = NULL );
+    virtual ~QwtLegend();
+
+    void setItemMode( LegendItemMode );
+    LegendItemMode itemMode() const;
+
+    QWidget *contentsWidget();
+    const QWidget *contentsWidget() const;
+
+    void insert( const QwtLegendItemManager *, QWidget * );
+    void remove( const QwtLegendItemManager * );
+
+    QWidget *find( const QwtLegendItemManager * ) const;
+    QwtLegendItemManager *find( const QWidget * ) const;
+
+    virtual QList<QWidget *> legendItems() const;
+
+    void clear();
+
+    bool isEmpty() const;
+    uint itemCount() const;
+
+    virtual bool eventFilter( QObject *, QEvent * );
+
+    virtual QSize sizeHint() const;
+    virtual int heightForWidth( int w ) const;
+
+    QScrollBar *horizontalScrollBar() const;
+    QScrollBar *verticalScrollBar() const;
+
+protected:
+    virtual void layoutContents();
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif 
Index: trunk/BNC/qwt/qwt_legend_item.cpp
===================================================================
--- trunk/BNC/qwt/qwt_legend_item.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_legend_item.cpp	(revision 4271)
@@ -0,0 +1,405 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_legend_item.h"
+#include "qwt_math.h"
+#include "qwt_painter.h"
+#include "qwt_symbol.h"
+#include <qpainter.h>
+#include <qdrawutil.h>
+#include <qstyle.h>
+#include <qpen.h>
+#include <qevent.h>
+#include <qstyleoption.h>
+#include <qapplication.h>
+
+static const int ButtonFrame = 2;
+static const int Margin = 2;
+
+static QSize buttonShift( const QwtLegendItem *w )
+{
+    QStyleOption option;
+    option.init( w );
+
+    const int ph = w->style()->pixelMetric(
+        QStyle::PM_ButtonShiftHorizontal, &option, w );
+    const int pv = w->style()->pixelMetric(
+        QStyle::PM_ButtonShiftVertical, &option, w );
+    return QSize( ph, pv );
+}
+
+class QwtLegendItem::PrivateData
+{
+public:
+    PrivateData():
+        itemMode( QwtLegend::ReadOnlyItem ),
+        isDown( false ),
+        identifierSize( 8, 8 ),
+        spacing( Margin )
+    {
+    }
+
+    QwtLegend::LegendItemMode itemMode;
+    bool isDown;
+
+    QSize identifierSize;
+    QPixmap identifier;
+
+    int spacing;
+};
+
+/*!
+  \param parent Parent widget
+*/
+QwtLegendItem::QwtLegendItem( QWidget *parent ):
+    QwtTextLabel( parent )
+{
+    d_data = new PrivateData;
+    setMargin( Margin );
+    setIndent( Margin + d_data->identifierSize.width() + 2 * d_data->spacing );
+}
+
+//! Destructor
+QwtLegendItem::~QwtLegendItem()
+{
+    delete d_data;
+    d_data = NULL;
+}
+
+/*!
+   Set the text to the legend item
+
+   \param text Text label
+    \sa QwtTextLabel::text()
+*/
+void QwtLegendItem::setText( const QwtText &text )
+{
+    const int flags = Qt::AlignLeft | Qt::AlignVCenter
+        | Qt::TextExpandTabs | Qt::TextWordWrap;
+
+    QwtText txt = text;
+    txt.setRenderFlags( flags );
+
+    QwtTextLabel::setText( txt );
+}
+
+/*!
+   Set the item mode
+   The default is QwtLegend::ReadOnlyItem
+
+   \param mode Item mode
+   \sa itemMode()
+*/
+void QwtLegendItem::setItemMode( QwtLegend::LegendItemMode mode )
+{
+    if ( mode != d_data->itemMode )
+    {
+        d_data->itemMode = mode;
+        d_data->isDown = false;
+
+        setFocusPolicy( mode != QwtLegend::ReadOnlyItem ? Qt::TabFocus : Qt::NoFocus );
+        setMargin( ButtonFrame + Margin );
+
+        updateGeometry();
+    }
+}
+
+/*!
+   Return the item mode
+
+   \sa setItemMode()
+*/
+QwtLegend::LegendItemMode QwtLegendItem::itemMode() const
+{
+    return d_data->itemMode;
+}
+
+/*!
+  Assign the identifier
+  The identifier needs to be created according to the identifierWidth()
+
+  \param identifier Pixmap representing a plot item
+
+  \sa identifier(), identifierWidth()
+*/
+void QwtLegendItem::setIdentifier( const QPixmap &identifier )
+{
+    d_data->identifier = identifier;
+    update();
+}
+
+/*!
+  \return pixmap representing a plot item
+  \sa setIdentifier()
+*/
+QPixmap QwtLegendItem::identifier() const
+{
+    return d_data->identifier;
+}
+
+/*!
+  Set the size for the identifier
+  Default is 8x8 pixels
+
+  \param size New size
+
+  \sa identifierSize()
+*/
+void QwtLegendItem::setIdentifierSize( const QSize &size )
+{
+    QSize sz = size.expandedTo( QSize( 0, 0 ) );
+    if ( sz != d_data->identifierSize )
+    {
+        d_data->identifierSize = sz;
+        setIndent( margin() + d_data->identifierSize.width()
+            + 2 * d_data->spacing );
+        updateGeometry();
+    }
+}
+/*!
+   Return the width of the identifier
+
+   \sa setIdentifierSize()
+*/
+QSize QwtLegendItem::identifierSize() const
+{
+    return d_data->identifierSize;
+}
+
+/*!
+   Change the spacing
+   \param spacing Spacing
+   \sa spacing(), identifierWidth(), QwtTextLabel::margin()
+*/
+void QwtLegendItem::setSpacing( int spacing )
+{
+    spacing = qMax( spacing, 0 );
+    if ( spacing != d_data->spacing )
+    {
+        d_data->spacing = spacing;
+        setIndent( margin() + d_data->identifierSize.width()
+            + 2 * d_data->spacing );
+    }
+}
+
+/*!
+   Return the spacing
+   \sa setSpacing(), identifierWidth(), QwtTextLabel::margin()
+*/
+int QwtLegendItem::spacing() const
+{
+    return d_data->spacing;
+}
+
+/*!
+    Check/Uncheck a the item
+
+    \param on check/uncheck
+    \sa setItemMode()
+*/
+void QwtLegendItem::setChecked( bool on )
+{
+    if ( d_data->itemMode == QwtLegend::CheckableItem )
+    {
+        const bool isBlocked = signalsBlocked();
+        blockSignals( true );
+
+        setDown( on );
+
+        blockSignals( isBlocked );
+    }
+}
+
+//! Return true, if the item is checked
+bool QwtLegendItem::isChecked() const
+{
+    return d_data->itemMode == QwtLegend::CheckableItem && isDown();
+}
+
+//! Set the item being down
+void QwtLegendItem::setDown( bool down )
+{
+    if ( down == d_data->isDown )
+        return;
+
+    d_data->isDown = down;
+    update();
+
+    if ( d_data->itemMode == QwtLegend::ClickableItem )
+    {
+        if ( d_data->isDown )
+            Q_EMIT pressed();
+        else
+        {
+            Q_EMIT released();
+            Q_EMIT clicked();
+        }
+    }
+
+    if ( d_data->itemMode == QwtLegend::CheckableItem )
+        Q_EMIT checked( d_data->isDown );
+}
+
+//! Return true, if the item is down
+bool QwtLegendItem::isDown() const
+{
+    return d_data->isDown;
+}
+
+//! Return a size hint
+QSize QwtLegendItem::sizeHint() const
+{
+    QSize sz = QwtTextLabel::sizeHint();
+    sz.setHeight( qMax( sz.height(), d_data->identifier.height() + 4 ) );
+
+    if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
+    {
+        sz += buttonShift( this );
+        sz = sz.expandedTo( QApplication::globalStrut() );
+    }
+
+    return sz;
+}
+
+//! Paint event
+void QwtLegendItem::paintEvent( QPaintEvent *e )
+{
+    const QRect cr = contentsRect();
+
+    QPainter painter( this );
+    painter.setClipRegion( e->region() );
+
+    if ( d_data->isDown )
+    {
+        qDrawWinButton( &painter, 0, 0, width(), height(),
+            palette(), true );
+    }
+
+    painter.save();
+
+    if ( d_data->isDown )
+    {
+        const QSize shiftSize = buttonShift( this );
+        painter.translate( shiftSize.width(), shiftSize.height() );
+    }
+
+    painter.setClipRect( cr );
+
+    drawContents( &painter );
+
+    if ( !d_data->identifier.isNull() )
+    {
+        QRect identRect = cr;
+        identRect.setX( identRect.x() + margin() );
+        if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
+            identRect.setX( identRect.x() + ButtonFrame );
+
+        identRect.setSize( d_data->identifier.size() );
+        identRect.moveCenter( QPoint( identRect.center().x(), cr.center().y() ) );
+
+        painter.drawPixmap( identRect, d_data->identifier );
+    }
+
+    painter.restore();
+}
+
+//! Handle mouse press events
+void QwtLegendItem::mousePressEvent( QMouseEvent *e )
+{
+    if ( e->button() == Qt::LeftButton )
+    {
+        switch ( d_data->itemMode )
+        {
+            case QwtLegend::ClickableItem:
+            {
+                setDown( true );
+                return;
+            }
+            case QwtLegend::CheckableItem:
+            {
+                setDown( !isDown() );
+                return;
+            }
+            default:;
+        }
+    }
+    QwtTextLabel::mousePressEvent( e );
+}
+
+//! Handle mouse release events
+void QwtLegendItem::mouseReleaseEvent( QMouseEvent *e )
+{
+    if ( e->button() == Qt::LeftButton )
+    {
+        switch ( d_data->itemMode )
+        {
+            case QwtLegend::ClickableItem:
+            {
+                setDown( false );
+                return;
+            }
+            case QwtLegend::CheckableItem:
+            {
+                return; // do nothing, but accept
+            }
+            default:;
+        }
+    }
+    QwtTextLabel::mouseReleaseEvent( e );
+}
+
+//! Handle key press events
+void QwtLegendItem::keyPressEvent( QKeyEvent *e )
+{
+    if ( e->key() == Qt::Key_Space )
+    {
+        switch ( d_data->itemMode )
+        {
+            case QwtLegend::ClickableItem:
+            {
+                if ( !e->isAutoRepeat() )
+                    setDown( true );
+                return;
+            }
+            case QwtLegend::CheckableItem:
+            {
+                if ( !e->isAutoRepeat() )
+                    setDown( !isDown() );
+                return;
+            }
+            default:;
+        }
+    }
+
+    QwtTextLabel::keyPressEvent( e );
+}
+
+//! Handle key release events
+void QwtLegendItem::keyReleaseEvent( QKeyEvent *e )
+{
+    if ( e->key() == Qt::Key_Space )
+    {
+        switch ( d_data->itemMode )
+        {
+            case QwtLegend::ClickableItem:
+            {
+                if ( !e->isAutoRepeat() )
+                    setDown( false );
+                return;
+            }
+            case QwtLegend::CheckableItem:
+            {
+                return; // do nothing, but accept
+            }
+            default:;
+        }
+    }
+
+    QwtTextLabel::keyReleaseEvent( e );
+}
Index: trunk/BNC/qwt/qwt_legend_item.h
===================================================================
--- trunk/BNC/qwt/qwt_legend_item.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_legend_item.h	(revision 4271)
@@ -0,0 +1,78 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_LEGEND_ITEM_H
+#define QWT_LEGEND_ITEM_H
+
+#include "qwt_global.h"
+#include "qwt_legend.h"
+#include "qwt_text.h"
+#include "qwt_text_label.h"
+#include <qpixmap.h>
+
+/*!
+  \brief A widget representing something on a QwtLegend().
+*/
+class QWT_EXPORT QwtLegendItem: public QwtTextLabel
+{
+    Q_OBJECT
+public:
+    explicit QwtLegendItem( QWidget *parent = 0 );
+    virtual ~QwtLegendItem();
+
+    void setItemMode( QwtLegend::LegendItemMode );
+    QwtLegend::LegendItemMode itemMode() const;
+
+    void setSpacing( int spacing );
+    int spacing() const;
+
+    virtual void setText( const QwtText & );
+
+    void setIdentifier( const QPixmap & );
+    QPixmap identifier() const;
+
+    void setIdentifierSize( const QSize & );
+    QSize identifierSize() const;
+
+    virtual QSize sizeHint() const;
+
+    bool isChecked() const;
+
+public Q_SLOTS:
+    void setChecked( bool on );
+
+Q_SIGNALS:
+    //! Signal, when the legend item has been clicked
+    void clicked();
+
+    //! Signal, when the legend item has been pressed
+    void pressed();
+
+    //! Signal, when the legend item has been relased
+    void released();
+
+    //! Signal, when the legend item has been toggled
+    void checked( bool );
+
+protected:
+    void setDown( bool );
+    bool isDown() const;
+
+    virtual void paintEvent( QPaintEvent * );
+    virtual void mousePressEvent( QMouseEvent * );
+    virtual void mouseReleaseEvent( QMouseEvent * );
+    virtual void keyPressEvent( QKeyEvent * );
+    virtual void keyReleaseEvent( QKeyEvent * );
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif 
Index: trunk/BNC/qwt/qwt_legend_itemmanager.h
===================================================================
--- trunk/BNC/qwt/qwt_legend_itemmanager.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_legend_itemmanager.h	(revision 4271)
@@ -0,0 +1,66 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_LEGEND_ITEM_MANAGER_H
+#define QWT_LEGEND_ITEM_MANAGER_H
+
+#include "qwt_global.h"
+
+class QwtLegend;
+class QWidget;
+class QRectF;
+class QPainter;
+
+/*!
+  \brief Abstract API to bind plot items to the legend
+*/
+
+class QWT_EXPORT QwtLegendItemManager
+{
+public:
+    //! Constructor
+    QwtLegendItemManager()
+    {
+    }
+
+    //! Destructor
+    virtual ~QwtLegendItemManager()
+    {
+    }
+
+    /*!
+      Update the widget that represents the item on the legend
+      \param legend Legend
+      \sa legendItem()
+     */
+    virtual void updateLegend( QwtLegend *legend ) const = 0;
+
+    /*!
+      Allocate the widget that represents the item on the legend
+      \return Allocated widget
+      \sa updateLegend() QwtLegend()
+     */
+
+    virtual QWidget *legendItem() const = 0;
+
+    /*!
+      QwtLegendItem can display an icon-identifier followed
+      by a text. The icon helps to identify a plot item on
+      the plot canvas and depends on the type of information,
+      that is displayed.
+
+      The default implementation paints nothing.
+     */
+    virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const
+    {
+    }
+};
+
+#endif
+
Index: trunk/BNC/qwt/qwt_magnifier.cpp
===================================================================
--- trunk/BNC/qwt/qwt_magnifier.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_magnifier.cpp	(revision 4271)
@@ -0,0 +1,473 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_magnifier.h"
+#include "qwt_math.h"
+#include <qevent.h>
+#include <qwidget.h>
+
+class QwtMagnifier::PrivateData
+{
+public:
+    PrivateData():
+        isEnabled( false ),
+        wheelFactor( 0.9 ),
+        wheelButtonState( Qt::NoButton ),
+        mouseFactor( 0.95 ),
+        mouseButton( Qt::RightButton ),
+        mouseButtonState( Qt::NoButton ),
+        keyFactor( 0.9 ),
+        zoomInKey( Qt::Key_Plus ),
+        zoomOutKey( Qt::Key_Minus ),
+        zoomInKeyModifiers( Qt::NoModifier ),
+        zoomOutKeyModifiers( Qt::NoModifier ),
+        mousePressed( false )
+    {
+    }
+
+    bool isEnabled;
+
+    double wheelFactor;
+    int wheelButtonState;
+
+    double mouseFactor;
+    int mouseButton;
+    int mouseButtonState;
+
+    double keyFactor;
+    int zoomInKey;
+    int zoomOutKey;
+    int zoomInKeyModifiers;
+    int zoomOutKeyModifiers;
+
+    bool mousePressed;
+    bool hasMouseTracking;
+    QPoint mousePos;
+};
+
+/*!
+   Constructor
+   \param parent Widget to be magnified
+*/
+QwtMagnifier::QwtMagnifier( QWidget *parent ):
+    QObject( parent )
+{
+    d_data = new PrivateData();
+    setEnabled( true );
+}
+
+//! Destructor
+QwtMagnifier::~QwtMagnifier()
+{
+    delete d_data;
+}
+
+/*!
+  \brief En/disable the magnifier
+
+  When enabled is true an event filter is installed for
+  the observed widget, otherwise the event filter is removed.
+
+  \param on true or false
+  \sa isEnabled(), eventFilter()
+*/
+void QwtMagnifier::setEnabled( bool on )
+{
+    if ( d_data->isEnabled != on )
+    {
+        d_data->isEnabled = on;
+
+        QObject *o = parent();
+        if ( o )
+        {
+            if ( d_data->isEnabled )
+                o->installEventFilter( this );
+            else
+                o->removeEventFilter( this );
+        }
+    }
+}
+
+/*!
+  \return true when enabled, false otherwise
+  \sa setEnabled(), eventFilter()
+*/
+bool QwtMagnifier::isEnabled() const
+{
+    return d_data->isEnabled;
+}
+
+/*!
+   \brief Change the wheel factor
+
+   The wheel factor defines the ratio between the current range
+   on the parent widget and the zoomed range for each step of the wheel.
+   The default value is 0.9.
+
+   \param factor Wheel factor
+   \sa wheelFactor(), setWheelButtonState(),
+       setMouseFactor(), setKeyFactor()
+*/
+void QwtMagnifier::setWheelFactor( double factor )
+{
+    d_data->wheelFactor = factor;
+}
+
+/*!
+   \return Wheel factor
+   \sa setWheelFactor()
+*/
+double QwtMagnifier::wheelFactor() const
+{
+    return d_data->wheelFactor;
+}
+
+/*!
+   Assign a mandatory button state for zooming in/out using the wheel.
+   The default button state is Qt::NoButton.
+
+   \param buttonState Button state
+   \sa wheelButtonState()
+*/
+void QwtMagnifier::setWheelButtonState( int buttonState )
+{
+    d_data->wheelButtonState = buttonState;
+}
+
+/*!
+   \return Wheel button state
+   \sa setWheelButtonState()
+*/
+int QwtMagnifier::wheelButtonState() const
+{
+    return d_data->wheelButtonState;
+}
+
+/*!
+   \brief Change the mouse factor
+
+   The mouse factor defines the ratio between the current range
+   on the parent widget and the zoomed range for each vertical mouse movement.
+   The default value is 0.95.
+
+   \param factor Wheel factor
+   \sa mouseFactor(), setMouseButton(), setWheelFactor(), setKeyFactor()
+*/
+void QwtMagnifier::setMouseFactor( double factor )
+{
+    d_data->mouseFactor = factor;
+}
+
+/*!
+   \return Mouse factor
+   \sa setMouseFactor()
+*/
+double QwtMagnifier::mouseFactor() const
+{
+    return d_data->mouseFactor;
+}
+
+/*!
+   Assign the mouse button, that is used for zooming in/out.
+   The default value is Qt::RightButton.
+
+   \param button Button
+   \param buttonState Button state
+   \sa getMouseButton()
+*/
+void QwtMagnifier::setMouseButton( int button, int buttonState )
+{
+    d_data->mouseButton = button;
+    d_data->mouseButtonState = buttonState;
+}
+
+//! \sa setMouseButton()
+void QwtMagnifier::getMouseButton(
+    int &button, int &buttonState ) const
+{
+    button = d_data->mouseButton;
+    buttonState = d_data->mouseButtonState;
+}
+
+/*!
+   \brief Change the key factor
+
+   The key factor defines the ratio between the current range
+   on the parent widget and the zoomed range for each key press of
+   the zoom in/out keys. The default value is 0.9.
+
+   \param factor Key factor
+   \sa keyFactor(), setZoomInKey(), setZoomOutKey(),
+       setWheelFactor, setMouseFactor()
+*/
+void QwtMagnifier::setKeyFactor( double factor )
+{
+    d_data->keyFactor = factor;
+}
+
+/*!
+   \return Key factor
+   \sa setKeyFactor()
+*/
+double QwtMagnifier::keyFactor() const
+{
+    return d_data->keyFactor;
+}
+
+/*!
+   Assign the key, that is used for zooming in.
+   The default combination is Qt::Key_Plus + Qt::NoModifier.
+
+   \param key
+   \param modifiers
+   \sa getZoomInKey(), setZoomOutKey()
+*/
+void QwtMagnifier::setZoomInKey( int key, int modifiers )
+{
+    d_data->zoomInKey = key;
+    d_data->zoomInKeyModifiers = modifiers;
+}
+
+//! \sa setZoomInKey()
+void QwtMagnifier::getZoomInKey( int &key, int &modifiers ) const
+{
+    key = d_data->zoomInKey;
+    modifiers = d_data->zoomInKeyModifiers;
+}
+
+/*!
+   Assign the key, that is used for zooming out.
+   The default combination is Qt::Key_Minus + Qt::NoModifier.
+
+   \param key
+   \param modifiers
+   \sa getZoomOutKey(), setZoomOutKey()
+*/
+void QwtMagnifier::setZoomOutKey( int key, int modifiers )
+{
+    d_data->zoomOutKey = key;
+    d_data->zoomOutKeyModifiers = modifiers;
+}
+
+//! \sa setZoomOutKey()
+void QwtMagnifier::getZoomOutKey( int &key, int &modifiers ) const
+{
+    key = d_data->zoomOutKey;
+    modifiers = d_data->zoomOutKeyModifiers;
+}
+
+/*!
+  \brief Event filter
+
+  When isEnabled() the mouse events of the observed widget are filtered.
+
+  \param object Object to be filtered
+  \param event Event
+
+  \sa widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseMoveEvent(), widgetWheelEvent(), widgetKeyPressEvent()
+      widgetKeyReleaseEvent()
+*/
+bool QwtMagnifier::eventFilter( QObject *object, QEvent *event )
+{
+    if ( object && object == parent() )
+    {
+        switch ( event->type() )
+        {
+            case QEvent::MouseButtonPress:
+            {
+                widgetMousePressEvent( ( QMouseEvent * )event );
+                break;
+            }
+            case QEvent::MouseMove:
+            {
+                widgetMouseMoveEvent( ( QMouseEvent * )event );
+                break;
+            }
+            case QEvent::MouseButtonRelease:
+            {
+                widgetMouseReleaseEvent( ( QMouseEvent * )event );
+                break;
+            }
+            case QEvent::Wheel:
+            {
+                widgetWheelEvent( ( QWheelEvent * )event );
+                break;
+            }
+            case QEvent::KeyPress:
+            {
+                widgetKeyPressEvent( ( QKeyEvent * )event );
+                break;
+            }
+            case QEvent::KeyRelease:
+            {
+                widgetKeyReleaseEvent( ( QKeyEvent * )event );
+                break;
+            }
+            default:;
+        }
+    }
+    return QObject::eventFilter( object, event );
+}
+
+/*!
+  Handle a mouse press event for the observed widget.
+
+  \param mouseEvent Mouse event
+  \sa eventFilter(), widgetMouseReleaseEvent(), widgetMouseMoveEvent()
+*/
+void QwtMagnifier::widgetMousePressEvent( QMouseEvent *mouseEvent )
+{
+    if ( ( mouseEvent->button() != d_data->mouseButton) 
+        || parentWidget() == NULL )
+    {
+        return;
+    }
+
+    if ( ( mouseEvent->modifiers() & Qt::KeyboardModifierMask ) !=
+        ( int )( d_data->mouseButtonState & Qt::KeyboardModifierMask ) )
+    {
+        return;
+    }
+
+    d_data->hasMouseTracking = parentWidget()->hasMouseTracking();
+    parentWidget()->setMouseTracking( true );
+    d_data->mousePos = mouseEvent->pos();
+    d_data->mousePressed = true;
+}
+
+/*!
+  Handle a mouse release event for the observed widget.
+
+  \param mouseEvent Mouse event
+
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseMoveEvent(),
+*/
+void QwtMagnifier::widgetMouseReleaseEvent( QMouseEvent *mouseEvent )
+{
+    Q_UNUSED( mouseEvent );
+
+    if ( d_data->mousePressed && parentWidget() )
+    {
+        d_data->mousePressed = false;
+        parentWidget()->setMouseTracking( d_data->hasMouseTracking );
+    }
+}
+
+/*!
+  Handle a mouse move event for the observed widget.
+
+  \param mouseEvent Mouse event
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
+*/
+void QwtMagnifier::widgetMouseMoveEvent( QMouseEvent *mouseEvent )
+{
+    if ( !d_data->mousePressed )
+        return;
+
+    const int dy = mouseEvent->pos().y() - d_data->mousePos.y();
+    if ( dy != 0 )
+    {
+        double f = d_data->mouseFactor;
+        if ( dy < 0 )
+            f = 1 / f;
+
+        rescale( f );
+    }
+
+    d_data->mousePos = mouseEvent->pos();
+}
+
+/*!
+  Handle a wheel event for the observed widget.
+
+  \param wheelEvent Wheel event
+  \sa eventFilter()
+*/
+void QwtMagnifier::widgetWheelEvent( QWheelEvent *wheelEvent )
+{
+    if ( ( wheelEvent->modifiers() & Qt::KeyboardModifierMask ) !=
+        ( int )( d_data->wheelButtonState & Qt::KeyboardModifierMask ) )
+    {
+        return;
+    }
+
+    if ( d_data->wheelFactor != 0.0 )
+    {
+        /*
+            A positive delta indicates that the wheel was
+            rotated forwards away from the user; a negative
+            value indicates that the wheel was rotated
+            backwards toward the user.
+            Most mouse types work in steps of 15 degrees,
+            in which case the delta value is a multiple
+            of 120 (== 15 * 8).
+         */
+        double f = qPow( d_data->wheelFactor, 
+            qAbs( wheelEvent->delta() / 120 ) );
+
+        if ( wheelEvent->delta() > 0 )
+            f = 1 / f;
+
+        rescale( f );
+    }
+}
+
+/*!
+  Handle a key press event for the observed widget.
+
+  \param keyEvent Key event
+  \sa eventFilter(), widgetKeyReleaseEvent()
+*/
+void QwtMagnifier::widgetKeyPressEvent( QKeyEvent *keyEvent )
+{
+    const int key = keyEvent->key();
+    const int state = keyEvent->modifiers();
+
+    if ( key == d_data->zoomInKey &&
+        state == d_data->zoomInKeyModifiers )
+    {
+        rescale( d_data->keyFactor );
+    }
+    else if ( key == d_data->zoomOutKey &&
+        state == d_data->zoomOutKeyModifiers )
+    {
+        rescale( 1.0 / d_data->keyFactor );
+    }
+}
+
+/*!
+  Handle a key release event for the observed widget.
+
+  \param keyEvent Key event
+  \sa eventFilter(), widgetKeyReleaseEvent()
+*/
+void QwtMagnifier::widgetKeyReleaseEvent( QKeyEvent *keyEvent )
+{
+    Q_UNUSED( keyEvent );
+}
+
+//! \return Parent widget, where the rescaling happens
+QWidget *QwtMagnifier::parentWidget()
+{
+    if ( parent()->inherits( "QWidget" ) )
+        return ( QWidget * )parent();
+
+    return NULL;
+}
+
+//! \return Parent widget, where the rescaling happens
+const QWidget *QwtMagnifier::parentWidget() const
+{
+    if ( parent()->inherits( "QWidget" ) )
+        return ( const QWidget * )parent();
+
+    return NULL;
+}
+
Index: trunk/BNC/qwt/qwt_magnifier.h
===================================================================
--- trunk/BNC/qwt/qwt_magnifier.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_magnifier.h	(revision 4271)
@@ -0,0 +1,86 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_MAGNIFIER_H
+#define QWT_MAGNIFIER_H 1
+
+#include "qwt_global.h"
+#include <qobject.h>
+
+class QWidget;
+class QMouseEvent;
+class QWheelEvent;
+class QKeyEvent;
+
+/*!
+  \brief QwtMagnifier provides zooming, by magnifying in steps.
+
+  Using QwtMagnifier a plot can be zoomed in/out in steps using
+  keys, the mouse wheel or moving a mouse button in vertical direction.
+*/
+class QWT_EXPORT QwtMagnifier: public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit QwtMagnifier( QWidget * );
+    virtual ~QwtMagnifier();
+
+    QWidget *parentWidget();
+    const QWidget *parentWidget() const;
+
+    void setEnabled( bool );
+    bool isEnabled() const;
+
+    // mouse
+    void setMouseFactor( double );
+    double mouseFactor() const;
+
+    void setMouseButton( int button, int buttonState = Qt::NoButton );
+    void getMouseButton( int &button, int &buttonState ) const;
+
+    // mouse wheel
+    void setWheelFactor( double );
+    double wheelFactor() const;
+
+    void setWheelButtonState( int buttonState );
+    int wheelButtonState() const;
+
+    // keyboard
+    void setKeyFactor( double );
+    double keyFactor() const;
+
+    void setZoomInKey( int key, int modifiers );
+    void getZoomInKey( int &key, int &modifiers ) const;
+
+    void setZoomOutKey( int key, int modifiers );
+    void getZoomOutKey( int &key, int &modifiers ) const;
+
+    virtual bool eventFilter( QObject *, QEvent * );
+
+protected:
+    /*!
+       Rescale the parent widget
+       \param factor Scale factor
+     */
+    virtual void rescale( double factor ) = 0;
+
+    virtual void widgetMousePressEvent( QMouseEvent * );
+    virtual void widgetMouseReleaseEvent( QMouseEvent * );
+    virtual void widgetMouseMoveEvent( QMouseEvent * );
+    virtual void widgetWheelEvent( QWheelEvent * );
+    virtual void widgetKeyPressEvent( QKeyEvent * );
+    virtual void widgetKeyReleaseEvent( QKeyEvent * );
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_math.cpp
===================================================================
--- trunk/BNC/qwt/qwt_math.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_math.cpp	(revision 4271)
@@ -0,0 +1,45 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_math.h"
+
+/*!
+  \brief Find the smallest value in an array
+  \param array Pointer to an array
+  \param size Array size
+*/
+double qwtGetMin( const double *array, int size )
+{
+    if ( size <= 0 )
+        return 0.0;
+
+    double rv = array[0];
+    for ( int i = 1; i < size; i++ )
+        rv = qMin( rv, array[i] );
+
+    return rv;
+}
+
+
+/*!
+  \brief Find the largest value in an array
+  \param array Pointer to an array
+  \param size Array size
+*/
+double qwtGetMax( const double *array, int size )
+{
+    if ( size <= 0 )
+        return 0.0;
+
+    double rv = array[0];
+    for ( int i = 1; i < size; i++ )
+        rv = qMax( rv, array[i] );
+
+    return rv;
+}
Index: trunk/BNC/qwt/qwt_math.h
===================================================================
--- trunk/BNC/qwt/qwt_math.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_math.h	(revision 4271)
@@ -0,0 +1,182 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_MATH_H
+#define QWT_MATH_H
+
+#include "qwt_global.h"
+
+#if defined(_MSC_VER)
+/*
+  Microsoft says:
+
+  Define _USE_MATH_DEFINES before including math.h to expose these macro
+  definitions for common math constants.  These are placed under an #ifdef
+  since these commonly-defined names are not part of the C/C++ standards.
+*/
+#define _USE_MATH_DEFINES 1
+#endif
+
+#include <qpoint.h>
+#include <qmath.h>
+#include "qwt_global.h"
+
+#ifndef LOG10_2
+#define LOG10_2     0.30102999566398119802  /* log10(2) */
+#endif
+
+#ifndef LOG10_3
+#define LOG10_3     0.47712125471966243540  /* log10(3) */
+#endif
+
+#ifndef LOG10_5
+#define LOG10_5     0.69897000433601885749  /* log10(5) */
+#endif
+
+#ifndef M_2PI
+#define M_2PI       6.28318530717958623200  /* 2 pi */
+#endif
+
+#ifndef LOG_MIN
+//! Mininum value for logarithmic scales
+#define LOG_MIN 1.0e-100
+#endif
+
+#ifndef LOG_MAX
+//! Maximum value for logarithmic scales
+#define LOG_MAX 1.0e100
+#endif
+
+#ifndef M_E
+#define M_E            2.7182818284590452354   /* e */
+#endif
+
+#ifndef M_LOG2E
+#define M_LOG2E 1.4426950408889634074   /* log_2 e */
+#endif
+
+#ifndef M_LOG10E
+#define M_LOG10E    0.43429448190325182765  /* log_10 e */
+#endif
+
+#ifndef M_LN2
+#define M_LN2       0.69314718055994530942  /* log_e 2 */
+#endif
+
+#ifndef M_LN10
+#define M_LN10         2.30258509299404568402  /* log_e 10 */
+#endif
+
+#ifndef M_PI
+#define M_PI        3.14159265358979323846  /* pi */
+#endif
+
+#ifndef M_PI_2
+#define M_PI_2      1.57079632679489661923  /* pi/2 */
+#endif
+
+#ifndef M_PI_4
+#define M_PI_4      0.78539816339744830962  /* pi/4 */
+#endif
+
+#ifndef M_1_PI
+#define M_1_PI      0.31830988618379067154  /* 1/pi */
+#endif
+
+#ifndef M_2_PI
+#define M_2_PI      0.63661977236758134308  /* 2/pi */
+#endif
+
+#ifndef M_2_SQRTPI
+#define M_2_SQRTPI  1.12837916709551257390  /* 2/sqrt(pi) */
+#endif
+
+#ifndef M_SQRT2
+#define M_SQRT2 1.41421356237309504880  /* sqrt(2) */
+#endif
+
+#ifndef M_SQRT1_2
+#define M_SQRT1_2   0.70710678118654752440  /* 1/sqrt(2) */
+#endif
+
+QWT_EXPORT double qwtGetMin( const double *array, int size );
+QWT_EXPORT double qwtGetMax( const double *array, int size );
+
+/*!
+  \brief Compare 2 values, relative to an interval
+
+  Values are "equal", when :
+  \f$\cdot value2 - value1 <= abs(intervalSize * 10e^{-6})\f$
+
+  \param value1 First value to compare
+  \param value2 Second value to compare
+  \param intervalSize interval size
+
+  \return 0: if equal, -1: if value2 > value1, 1: if value1 > value2
+*/
+inline int qwtFuzzyCompare( double value1, double value2, double intervalSize )
+{
+    const double eps = qAbs( 1.0e-6 * intervalSize );
+
+    if ( value2 - value1 > eps )
+        return -1;
+
+    if ( value1 - value2 > eps )
+        return 1;
+
+    return 0;
+}
+
+
+inline bool qwtFuzzyGreaterOrEqual( double d1, double d2 )
+{
+    return ( d1 >= d2 ) || qFuzzyCompare( d1, d2 );
+}
+
+inline bool qwtFuzzyLessOrEqual( double d1, double d2 )
+{
+    return ( d1 <= d2 ) || qFuzzyCompare( d1, d2 );
+}
+
+//! Return the sign
+inline int qwtSign( double x )
+{
+    if ( x > 0.0 )
+        return 1;
+    else if ( x < 0.0 )
+        return ( -1 );
+    else
+        return 0;
+}
+
+//! Return the square of a number
+inline double qwtSqr( double x )
+{
+    return x * x;
+}
+
+//! Like qRound, but without converting the result to an int
+inline double qwtRoundF(double d)
+{ 
+    return ::floor( d + 0.5 );
+}
+
+//! Like qFloor, but without converting the result to an int
+inline double qwtFloorF(double d)
+{ 
+    return ::floor( d );
+}
+
+//! Like qCeil, but without converting the result to an int
+inline double qwtCeilF(double d)
+{ 
+    return ::ceil( d );
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_matrix_raster_data.cpp
===================================================================
--- trunk/BNC/qwt/qwt_matrix_raster_data.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_matrix_raster_data.cpp	(revision 4271)
@@ -0,0 +1,270 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_matrix_raster_data.h"
+#include <qnumeric.h>
+#include <qmath.h>
+
+class QwtMatrixRasterData::PrivateData
+{
+public:
+    PrivateData():
+        resampleMode(QwtMatrixRasterData::NearestNeighbour),
+        numColumns(0)
+    {
+    }
+
+    inline double value(size_t row, size_t col) const
+    {
+        return values.data()[ row * numColumns + col ];
+    }
+
+    QwtMatrixRasterData::ResampleMode resampleMode;
+
+    QVector<double> values;
+    size_t numColumns;
+    size_t numRows;
+
+    double dx;
+    double dy;
+};
+
+//! Constructor
+QwtMatrixRasterData::QwtMatrixRasterData()
+{
+    d_data = new PrivateData();
+    update();
+}
+
+//! Destructor
+QwtMatrixRasterData::~QwtMatrixRasterData()
+{
+    delete d_data;
+}
+
+/*!
+   \brief Set the resampling algorithm
+
+   \param mode Resampling mode
+   \sa resampleMode(), value()
+*/
+void QwtMatrixRasterData::setResampleMode(ResampleMode mode)
+{
+    d_data->resampleMode = mode;
+}
+
+/*!
+   \return resampling algorithm
+   \sa setResampleMode(), value()
+*/
+QwtMatrixRasterData::ResampleMode QwtMatrixRasterData::resampleMode() const
+{
+    return d_data->resampleMode;
+}
+
+/*!
+   \brief Assign the bounding interval for an axis
+
+   Setting the bounding intervals for the X/Y axis is mandatory
+   to define the positions for the values of the value matrix.
+   The interval in Z direction defines the possible range for
+   the values in the matrix, what is f.e used by QwtPlotSpectrogram
+   to map values to colors. The Z-interval might be the bounding
+   interval of the values in the matrix, but usually it isn't.
+   ( f.e a interval of 0.0-100.0 for values in percentage )
+
+   \param axis X, Y or Z axis
+   \param interval Interval
+   
+   \sa QwtRasterData::interval(), setValueMatrix()
+*/
+void QwtMatrixRasterData::setInterval( 
+    Qt::Axis axis, const QwtInterval &interval )
+{
+    QwtRasterData::setInterval( axis, interval );
+    update();
+}
+
+/*!
+   \brief Assign a value matrix
+
+   The positions of the values are calculated by dividing
+   the bounding rectangle of the X/Y intervals into equidistant
+   rectangles ( pixels ). Each value corresponds to the center of 
+   a pixel.
+
+   \param values Vector of values
+   \param numColumns Number of columns
+
+   \sa valueMatrix(), numColumns(), numRows(), setInterval()()
+*/
+void QwtMatrixRasterData::setValueMatrix( 
+    const QVector<double> &values, size_t numColumns )
+{
+    d_data->values = values;
+    d_data->numColumns = numColumns;
+    update();
+}
+
+/*!
+   \return Value matrix
+   \sa setValueMatrix(), numColumns(), numRows(), setInterval()
+*/
+const QVector<double> QwtMatrixRasterData::valueMatrix() const
+{
+    return d_data->values;
+}
+
+/*!
+   \return Number of columns of the value matrix
+   \sa valueMatrix(), numRows(), setValueMatrix()
+*/
+size_t QwtMatrixRasterData::numColumns() const
+{
+    return d_data->numColumns;
+}
+
+/*!
+   \return Number of rows of the value matrix
+   \sa valueMatrix(), numColumns(), setValueMatrix()
+*/
+size_t QwtMatrixRasterData::numRows() const
+{
+    return d_data->numRows;
+}
+
+/*!
+   \brief Pixel hint
+
+   - NearestNeighbour\n
+     pixelHint() returns the surrounding pixel of the top left value 
+     in the matrix.
+
+   - BilinearInterpolation\n
+     Returns an empty rectangle recommending
+     to render in target device ( f.e. screen ) resolution. 
+
+   \sa ResampleMode, setMatrix(), setInterval()
+*/
+QRectF QwtMatrixRasterData::pixelHint( const QRectF & ) const
+{
+    QRectF rect;
+    if ( d_data->resampleMode == NearestNeighbour )
+    {
+        const QwtInterval intervalX = interval( Qt::XAxis );
+        const QwtInterval intervalY = interval( Qt::YAxis );
+        if ( intervalX.isValid() && intervalY.isValid() )
+        {
+            rect = QRectF( intervalX.minValue(), intervalY.minValue(),
+                d_data->dx, d_data->dy );
+        }
+    }
+
+    return rect;
+}
+
+/*!
+   \return the value at a raster position
+
+   \param x X value in plot coordinates
+   \param y Y value in plot coordinates
+
+   \sa ResampleMode
+*/
+double QwtMatrixRasterData::value( double x, double y ) const
+{
+    const QwtInterval xInterval = interval( Qt::XAxis );
+    const QwtInterval yInterval = interval( Qt::YAxis );
+
+    if ( !( xInterval.contains(x) && yInterval.contains(y) ) )
+        return qQNaN();
+
+    double value;
+
+    switch( d_data->resampleMode )
+    {
+        case BilinearInterpolation:
+        {
+            int col1 = qRound( (x - xInterval.minValue() ) / d_data->dx ) - 1;
+            int row1 = qRound( (y - yInterval.minValue() ) / d_data->dy ) - 1;
+            int col2 = col1 + 1;
+            int row2 = row1 + 1;
+
+            if ( col1 < 0 )
+                col1 = col2;
+            else if ( col2 >= (int)d_data->numColumns )
+                col2 = col1;
+
+            if ( row1 < 0 )
+                row1 = row2;
+            else if ( row2 >= (int)d_data->numRows )
+                row2 = row1;
+
+            const double v11 = d_data->value( row1, col1 );
+            const double v21 = d_data->value( row1, col2 );
+            const double v12 = d_data->value( row2, col1 );
+            const double v22 = d_data->value( row2, col2 );
+
+            const double x2 = xInterval.minValue() + 
+                ( col2 + 0.5 ) * d_data->dx;
+            const double y2 = yInterval.minValue() + 
+                ( row2 + 0.5 ) * d_data->dy;
+                
+            const double rx = ( x2 - x ) / d_data->dx;
+            const double ry = ( y2 - y ) / d_data->dy;
+
+            const double vr1 = rx * v11 + ( 1.0 - rx ) * v21;
+            const double vr2 = rx * v12 + ( 1.0 - rx ) * v22;
+
+            value = ry * vr1 + ( 1.0 - ry ) * vr2;
+
+            break;
+        }
+        case NearestNeighbour:
+        default:
+        {
+            uint row = uint( (y - yInterval.minValue() ) / d_data->dy );
+            uint col = uint( (x - xInterval.minValue() ) / d_data->dx );
+
+            // In case of intervals, where the maximum is included
+            // we get out of bound for row/col, when the value for the
+            // maximum is requested. Instead we return the value
+            // from the last row/col
+
+            if ( row >= d_data->numRows )
+                row = d_data->numRows - 1;
+
+            if ( col >= d_data->numColumns )
+                col = d_data->numColumns - 1;
+
+            value = d_data->value( row, col );
+        }
+    }
+
+    return value;
+}
+
+void QwtMatrixRasterData::update()
+{
+    d_data->numRows = 0;
+    d_data->dx = 0.0;
+    d_data->dy = 0.0;
+
+    if ( d_data->numColumns > 0 )
+    {
+        d_data->numRows = d_data->values.size() / d_data->numColumns;
+
+        const QwtInterval xInterval = interval( Qt::XAxis );
+        const QwtInterval yInterval = interval( Qt::YAxis );
+        if ( xInterval.isValid() )
+            d_data->dx = xInterval.width() / d_data->numColumns;
+        if ( yInterval.isValid() )
+            d_data->dy = yInterval.width() / d_data->numRows;
+    }
+}
Index: trunk/BNC/qwt/qwt_matrix_raster_data.h
===================================================================
--- trunk/BNC/qwt/qwt_matrix_raster_data.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_matrix_raster_data.h	(revision 4271)
@@ -0,0 +1,71 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_MATRIX_RASTER_DATA_H
+#define QWT_MATRIX_RASTER_DATA_H 1
+
+#include "qwt_global.h"
+#include "qwt_raster_data.h"
+#include <qvector.h>
+
+/*!
+  \brief A class representing a matrix of values as raster data
+
+  QwtMatrixRasterData implements an interface for a matrix of
+  equidistant values, that can be used by a QwtPlotRasterItem. 
+  It implements a couple of resampling algorithms, to provide
+  values for positions, that or not on the value matrix.
+*/
+class QWT_EXPORT QwtMatrixRasterData: public QwtRasterData
+{
+public:
+    /*!
+      \brief Resampling algorithm
+      The default setting is NearestNeighbour;
+    */
+    enum ResampleMode
+    {
+        /*!
+          Return the value from the matrix, that is nearest to the
+          the requested position.
+         */
+        NearestNeighbour,
+
+        /*!
+          Interpolate the value from the distances and values of the 
+          4 surrounding values in the matrix,
+         */
+        BilinearInterpolation
+    };
+
+    QwtMatrixRasterData();
+    virtual ~QwtMatrixRasterData();
+
+    void setResampleMode(ResampleMode mode);
+    ResampleMode resampleMode() const;
+
+    virtual void setInterval( Qt::Axis, const QwtInterval & );
+    void setValueMatrix( const QVector<double> &values, size_t numColumns );
+    
+    const QVector<double> valueMatrix() const;
+    size_t numColumns() const;
+    size_t numRows() const;
+
+    virtual QRectF pixelHint( const QRectF & ) const;
+
+    virtual double value( double x, double y ) const;
+
+private:
+    void update();
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_null_paintdevice.cpp
===================================================================
--- trunk/BNC/qwt/qwt_null_paintdevice.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_null_paintdevice.cpp	(revision 4271)
@@ -0,0 +1,428 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_null_paintdevice.h"
+#include <qpaintengine.h>
+#include <qpixmap.h>
+
+class QwtNullPaintDevice::PrivateData
+{
+public:
+    PrivateData():
+        size( 0, 0 )
+    {
+    }
+
+    QSize size;
+};
+
+class QwtNullPaintDevice::PaintEngine: public QPaintEngine
+{
+public:
+    PaintEngine( QPaintEngine::PaintEngineFeatures );
+
+    virtual bool begin( QPaintDevice * );
+    virtual bool end();
+
+    virtual Type type () const;
+    virtual void updateState(const QPaintEngineState &);
+
+    virtual void drawRects(const QRect *, int );
+    virtual void drawRects(const QRectF *, int );
+
+    virtual void drawLines(const QLine *, int );
+    virtual void drawLines(const QLineF *, int );
+
+    virtual void drawEllipse(const QRectF &);
+    virtual void drawEllipse(const QRect &);
+
+    virtual void drawPath(const QPainterPath &);
+
+    virtual void drawPoints(const QPointF *, int );
+    virtual void drawPoints(const QPoint *, int );
+
+    virtual void drawPolygon(const QPointF *, int , PolygonDrawMode );
+    virtual void drawPolygon(const QPoint *, int , PolygonDrawMode );
+
+    virtual void drawPixmap(const QRectF &, 
+        const QPixmap &, const QRectF &);
+
+    virtual void drawTextItem(const QPointF &, const QTextItem &);
+    virtual void drawTiledPixmap(const QRectF &, 
+        const QPixmap &, const QPointF &s);
+    virtual void drawImage(const QRectF &, 
+        const QImage &, const QRectF &, Qt::ImageConversionFlags );
+
+private:
+    QwtNullPaintDevice *d_device;
+};
+    
+QwtNullPaintDevice::PaintEngine::PaintEngine( 
+        QPaintEngine::PaintEngineFeatures features ):
+    QPaintEngine( features ),
+    d_device(NULL)
+{
+}
+
+bool QwtNullPaintDevice::PaintEngine::begin( 
+    QPaintDevice *device )
+{
+    d_device = static_cast<QwtNullPaintDevice *>( device );
+    return true;
+}
+
+bool QwtNullPaintDevice::PaintEngine::end()
+{
+    d_device = NULL;
+    return true;
+}
+
+QPaintEngine::Type 
+QwtNullPaintDevice::PaintEngine::type () const
+{
+    return QPaintEngine::User;
+}
+
+void QwtNullPaintDevice::PaintEngine::drawRects(
+    const QRect *rects, int rectCount)
+{
+    if ( d_device )
+        d_device->drawRects( rects, rectCount );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawRects(
+    const QRectF *rects, int rectCount)
+{
+    if ( d_device )
+        d_device->drawRects( rects, rectCount );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawLines(
+    const QLine *lines, int lineCount)
+{
+    if ( d_device )
+        d_device->drawLines( lines, lineCount );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawLines(
+    const QLineF *lines, int lineCount)
+{
+    if ( d_device )
+        d_device->drawLines( lines, lineCount );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawEllipse(
+    const QRectF &rect)
+{
+    if ( d_device )
+        d_device->drawEllipse( rect );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawEllipse(
+    const QRect &rect)
+{
+    if ( d_device )
+        d_device->drawEllipse( rect );
+}
+
+
+void QwtNullPaintDevice::PaintEngine::drawPath(
+    const QPainterPath &path)
+{
+    if ( d_device )
+        d_device->drawPath( path );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawPoints(
+    const QPointF *points, int pointCount)
+{
+    if ( d_device )
+        d_device->drawPoints( points, pointCount );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawPoints(
+    const QPoint *points, int pointCount)
+{
+    if ( d_device )
+        d_device->drawPoints( points, pointCount );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawPolygon(
+    const QPointF *points, int pointCount, PolygonDrawMode mode)
+{
+    if ( d_device )
+        d_device->drawPolygon( points, pointCount, mode );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawPolygon(
+    const QPoint *points, int pointCount, PolygonDrawMode mode)
+{
+    if ( d_device )
+        d_device->drawPolygon( points, pointCount, mode );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawPixmap( 
+    const QRectF &rect, const QPixmap &pm, const QRectF &subRect )
+{
+    if ( d_device )
+        d_device->drawPixmap( rect, pm, subRect );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawTextItem(
+    const QPointF &pos, const QTextItem &textItem)
+{
+    if ( d_device )
+        d_device->drawTextItem( pos, textItem );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawTiledPixmap(
+    const QRectF &rect, const QPixmap &pixmap, 
+    const QPointF &subRect)
+{
+    if ( d_device )
+        d_device->drawTiledPixmap( rect, pixmap, subRect );
+}
+
+void QwtNullPaintDevice::PaintEngine::drawImage(
+    const QRectF &rect, const QImage &image, 
+    const QRectF &subRect, Qt::ImageConversionFlags flags)
+{
+    if ( d_device )
+        d_device->drawImage( rect, image, subRect, flags );
+}
+
+void QwtNullPaintDevice::PaintEngine::updateState(
+    const QPaintEngineState &state)
+{
+    if ( d_device )
+        d_device->updateState( state );
+}
+
+//! Constructor
+QwtNullPaintDevice::QwtNullPaintDevice( 
+    QPaintEngine::PaintEngineFeatures features )
+{
+    init( features );
+}
+
+//! Constructor
+QwtNullPaintDevice::QwtNullPaintDevice( const QSize &size,
+    QPaintEngine::PaintEngineFeatures features )
+{
+    init( features );
+    d_data->size = size;
+}
+
+void QwtNullPaintDevice::init( 
+    QPaintEngine::PaintEngineFeatures features )
+{
+    d_engine = new PaintEngine( features );
+    d_data = new PrivateData;
+}
+
+//! Destructor
+QwtNullPaintDevice::~QwtNullPaintDevice()
+{
+    delete d_engine;
+    delete d_data;
+}
+
+/*!
+   Set the size of the paint device
+
+   \param size Size
+   \sa size()
+*/
+void QwtNullPaintDevice::setSize( const QSize & size )
+{
+    d_data->size = size;
+}
+
+/*! 
+    \return Size of the paint device
+    \sa setSize()
+*/
+QSize QwtNullPaintDevice::size() const
+{
+    return d_data->size;
+}
+
+//! See QPaintDevice::paintEngine()
+QPaintEngine *QwtNullPaintDevice::paintEngine() const
+{
+    return d_engine;
+}
+
+/*! 
+    See QPaintDevice::metric()
+    \sa setSize()
+*/
+int QwtNullPaintDevice::metric( PaintDeviceMetric metric ) const
+{
+    static QPixmap pm;
+
+    int value;
+
+    switch ( metric ) 
+    {
+        case PdmWidth:
+            value = qMax( d_data->size.width(), 0 );
+            break;
+        case PdmHeight:
+            value = qMax( d_data->size.height(), 0 );
+            break;
+        case PdmNumColors:
+            value = 16777216;
+            break;
+        case PdmDepth:
+            value = 24;
+            break;
+        case PdmPhysicalDpiX:
+        case PdmDpiY:
+        case PdmPhysicalDpiY:
+        case PdmWidthMM:
+        case PdmHeightMM:
+        case PdmDpiX:
+        default:
+            value = 0;
+    }
+    return value;
+
+}
+
+//! See QPaintEngine::drawRects()
+void QwtNullPaintDevice::drawRects(
+    const QRect *rects, int rectCount)
+{
+    Q_UNUSED(rects);
+    Q_UNUSED(rectCount);
+}
+
+//! See QPaintEngine::drawRects()
+void QwtNullPaintDevice::drawRects(
+    const QRectF *rects, int rectCount)
+{
+    Q_UNUSED(rects);
+    Q_UNUSED(rectCount);
+}
+
+//! See QPaintEngine::drawLines()
+void QwtNullPaintDevice::drawLines(
+    const QLine *lines, int lineCount)
+{
+    Q_UNUSED(lines);
+    Q_UNUSED(lineCount);
+}
+
+//! See QPaintEngine::drawLines()
+void QwtNullPaintDevice::drawLines(
+    const QLineF *lines, int lineCount)
+{
+    Q_UNUSED(lines);
+    Q_UNUSED(lineCount);
+}
+
+//! See QPaintEngine::drawEllipse()
+void QwtNullPaintDevice::drawEllipse( const QRectF &rect )
+{
+    Q_UNUSED(rect);
+}
+
+//! See QPaintEngine::drawEllipse()
+void QwtNullPaintDevice::drawEllipse( const QRect &rect )
+{
+    Q_UNUSED(rect);
+}
+
+//! See QPaintEngine::drawPath()
+void QwtNullPaintDevice::drawPath( const QPainterPath &path )
+{
+    Q_UNUSED(path);
+}
+
+//! See QPaintEngine::drawPoints()
+void QwtNullPaintDevice::drawPoints(
+    const QPointF *points, int pointCount)
+{
+    Q_UNUSED(points);
+    Q_UNUSED(pointCount);
+}
+
+//! See QPaintEngine::drawPoints()
+void QwtNullPaintDevice::drawPoints(
+    const QPoint *points, int pointCount)
+{
+    Q_UNUSED(points);
+    Q_UNUSED(pointCount);
+}
+
+//! See QPaintEngine::drawPolygon()
+void QwtNullPaintDevice::drawPolygon(
+    const QPointF *points, int pointCount, 
+    QPaintEngine::PolygonDrawMode mode)
+{
+    Q_UNUSED(points);
+    Q_UNUSED(pointCount);
+    Q_UNUSED(mode);
+}
+
+//! See QPaintEngine::drawPolygon()
+void QwtNullPaintDevice::drawPolygon(
+    const QPoint *points, int pointCount, 
+    QPaintEngine::PolygonDrawMode mode)
+{
+    Q_UNUSED(points);
+    Q_UNUSED(pointCount);
+    Q_UNUSED(mode);
+}
+
+//! See QPaintEngine::drawPixmap()
+void QwtNullPaintDevice::drawPixmap( const QRectF &rect, 
+    const QPixmap &pm, const QRectF &subRect )
+{
+    Q_UNUSED(rect);
+    Q_UNUSED(pm);
+    Q_UNUSED(subRect);
+}
+
+//! See QPaintEngine::drawTextItem()
+void QwtNullPaintDevice::drawTextItem(
+    const QPointF &pos, const QTextItem &textItem)
+{
+    Q_UNUSED(pos);
+    Q_UNUSED(textItem);
+}
+
+//! See QPaintEngine::drawTiledPixmap()
+void QwtNullPaintDevice::drawTiledPixmap(
+    const QRectF &rect, const QPixmap &pixmap, 
+    const QPointF &subRect)
+{
+    Q_UNUSED(rect);
+    Q_UNUSED(pixmap);
+    Q_UNUSED(subRect);
+}
+
+//! See QPaintEngine::drawImage()
+void QwtNullPaintDevice::drawImage(
+    const QRectF &rect, const QImage &image, 
+    const QRectF &subRect, Qt::ImageConversionFlags flags)
+{
+    Q_UNUSED(rect);
+    Q_UNUSED(image);
+    Q_UNUSED(subRect);
+    Q_UNUSED(flags);
+}
+
+//! See QPaintEngine::updateState()
+void QwtNullPaintDevice::updateState( 
+    const QPaintEngineState &state )
+{
+    Q_UNUSED(state);
+}
Index: trunk/BNC/qwt/qwt_null_paintdevice.h
===================================================================
--- trunk/BNC/qwt/qwt_null_paintdevice.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_null_paintdevice.h	(revision 4271)
@@ -0,0 +1,89 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_NULL_PAINT_DEVICE_H
+#define QWT_NULL_PAINT_DEVICE_H 1
+
+#include "qwt_global.h"
+#include <qpaintdevice.h>
+#include <qpaintengine.h>
+
+/*!
+  \brief A null paint device doing nothing
+
+  Sometimes important layout/rendering geometries are not 
+  available or changable from the public Qt class interface. 
+  ( f.e hidden in the style implementation ).
+
+  QwtNullPaintDevice can be used to manipulate or filter out 
+  these informations by analyzing the stream of paint primitives.
+
+  F.e. QwtNullPaintDevice is used by QwtPlotCanvas to identify
+  styled backgrounds with rounded corners.
+*/
+
+class QWT_EXPORT QwtNullPaintDevice: public QPaintDevice
+{
+public:
+    QwtNullPaintDevice( QPaintEngine::PaintEngineFeatures );
+    QwtNullPaintDevice( const QSize &size,
+        QPaintEngine::PaintEngineFeatures );
+
+    virtual ~QwtNullPaintDevice();
+
+    void setSize( const QSize &);
+    QSize size() const;
+
+    virtual QPaintEngine *paintEngine() const;
+    virtual int metric( PaintDeviceMetric metric ) const;
+
+    virtual void drawRects(const QRect *, int );
+    virtual void drawRects(const QRectF *, int );
+
+    virtual void drawLines(const QLine *, int );
+    virtual void drawLines(const QLineF *, int );
+
+    virtual void drawEllipse(const QRectF &);
+    virtual void drawEllipse(const QRect &);
+
+    virtual void drawPath(const QPainterPath &);
+
+    virtual void drawPoints(const QPointF *, int );
+    virtual void drawPoints(const QPoint *, int );
+
+    virtual void drawPolygon(
+        const QPointF *, int , QPaintEngine::PolygonDrawMode );
+
+    virtual void drawPolygon(
+        const QPoint *, int , QPaintEngine::PolygonDrawMode );
+
+    virtual void drawPixmap(const QRectF &,
+        const QPixmap &, const QRectF &);
+
+    virtual void drawTextItem(const QPointF &, const QTextItem &);
+
+    virtual void drawTiledPixmap(const QRectF &,
+        const QPixmap &, const QPointF &s);
+
+    virtual void drawImage(const QRectF &,
+        const QImage &, const QRectF &, Qt::ImageConversionFlags );
+
+    virtual void updateState( const QPaintEngineState &state );
+
+private:
+    void init( QPaintEngine::PaintEngineFeatures );
+
+    class PaintEngine;
+    PaintEngine *d_engine;
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_painter.cpp
===================================================================
--- trunk/BNC/qwt/qwt_painter.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_painter.cpp	(revision 4271)
@@ -0,0 +1,704 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_painter.h"
+#include "qwt_math.h"
+#include "qwt_clipper.h"
+#include "qwt_color_map.h"
+#include "qwt_scale_map.h"
+#include <qwindowdefs.h>
+#include <qwidget.h>
+#include <qframe.h>
+#include <qrect.h>
+#include <qpainter.h>
+#include <qpalette.h>
+#include <qpaintdevice.h>
+#include <qpixmap.h>
+#include <qstyle.h>
+#include <qtextdocument.h>
+#include <qabstracttextdocumentlayout.h>
+#include <qstyleoption.h>
+#include <qpaintengine.h>
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+
+bool QwtPainter::d_polylineSplitting = true;
+bool QwtPainter::d_roundingAlignment = true;
+
+static inline bool isClippingNeeded( const QPainter *painter, QRectF &clipRect )
+{
+    bool doClipping = false;
+    const QPaintEngine *pe = painter->paintEngine();
+    if ( pe && pe->type() == QPaintEngine::SVG )
+    {
+        // The SVG paint engine ignores any clipping,
+
+        if ( painter->hasClipping() )
+        {
+            doClipping = true;
+            clipRect = painter->clipRegion().boundingRect();
+        }
+    }
+
+    return doClipping;
+}
+
+static inline void drawPolyline( QPainter *painter,
+    const QPointF *points, int pointCount, bool polylineSplitting )
+{
+    bool doSplit = false;
+    if ( polylineSplitting )
+    {
+        const QPaintEngine *pe = painter->paintEngine();
+        if ( pe && pe->type() == QPaintEngine::Raster )
+        {
+            /*
+                The raster paint engine seems to use some algo with O(n*n).
+                ( Qt 4.3 is better than Qt 4.2, but remains unacceptable)
+                To work around this problem, we have to split the polygon into
+                smaller pieces.
+             */
+            doSplit = true;
+        }
+    }
+
+    if ( doSplit )
+    {
+        const int splitSize = 20;
+        for ( int i = 0; i < pointCount; i += splitSize )
+        {
+            const int n = qMin( splitSize + 1, pointCount - i );
+            painter->drawPolyline( points + i, n );
+        }
+    }
+    else
+        painter->drawPolyline( points, pointCount );
+}
+
+static inline void unscaleFont( QPainter *painter )
+{
+    if ( painter->font().pixelSize() >= 0 )
+        return;
+
+    static QSize screenResolution;
+    if ( !screenResolution.isValid() )
+    {
+        QDesktopWidget *desktop = QApplication::desktop();
+        if ( desktop )
+        {
+            screenResolution.setWidth( desktop->logicalDpiX() );
+            screenResolution.setHeight( desktop->logicalDpiY() );
+        }
+    }
+
+    const QPaintDevice *pd = painter->device();
+    if ( pd->logicalDpiX() != screenResolution.width() ||
+        pd->logicalDpiY() != screenResolution.height() )
+    {
+        QFont pixelFont( painter->font(), QApplication::desktop() );
+        pixelFont.setPixelSize( QFontInfo( pixelFont ).pixelSize() );
+
+        painter->setFont( pixelFont );
+    }
+}
+
+/*!
+  Check if the painter is using a paint engine, that aligns
+  coordinates to integers. Today these are all paint engines
+  beside QPaintEngine::Pdf and QPaintEngine::SVG.
+
+  \param  painter Painter
+  \return true, when the paint engine is aligning
+
+  \sa setRoundingAlignment()
+*/
+bool QwtPainter::isAligning( QPainter *painter )
+{
+    if ( painter && painter->isActive() )
+    {
+        switch ( painter->paintEngine()->type() )
+        {
+            case QPaintEngine::Pdf:
+            case QPaintEngine::SVG:
+                return false;
+
+            default:;
+        }
+    }
+
+    return true;
+}
+
+/*!
+  Enable whether coordinates should be rounded, before they are painted
+  to a paint engine that floors to integer values. For other paint engines
+  this ( Pdf, SVG ), this flag has no effect.
+  QwtPainter stores this flag only, the rounding itsself is done in 
+  the painting code ( f.e the plot items ).
+
+  The default setting is true. 
+
+  \sa roundingAlignment(), isAligning()
+*/
+void QwtPainter::setRoundingAlignment( bool enable )
+{
+    d_roundingAlignment = enable;
+}
+
+/*!
+  \brief En/Disable line splitting for the raster paint engine
+
+  The raster paint engine paints polylines of many points
+  much faster when they are splitted in smaller chunks.
+
+  \sa polylineSplitting()
+*/
+void QwtPainter::setPolylineSplitting( bool enable )
+{
+    d_polylineSplitting = enable;
+}
+
+//! Wrapper for QPainter::drawPath()
+void QwtPainter::drawPath( QPainter *painter, const QPainterPath &path )
+{
+    painter->drawPath( path );
+}
+
+//! Wrapper for QPainter::drawRect()
+void QwtPainter::drawRect( QPainter *painter, double x, double y, double w, double h )
+{
+    drawRect( painter, QRectF( x, y, w, h ) );
+}
+
+//! Wrapper for QPainter::drawRect()
+void QwtPainter::drawRect( QPainter *painter, const QRectF &rect )
+{
+    const QRectF r = rect;
+
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+
+    if ( deviceClipping )
+    {
+        if ( !clipRect.intersects( r ) )
+            return;
+
+        if ( !clipRect.contains( r ) )
+        {
+            fillRect( painter, r & clipRect, painter->brush() );
+
+            painter->save();
+            painter->setBrush( Qt::NoBrush );
+            drawPolyline( painter, QPolygonF( r ) );
+            painter->restore();
+
+            return;
+        }
+    }
+
+    painter->drawRect( r );
+}
+
+//! Wrapper for QPainter::fillRect()
+void QwtPainter::fillRect( QPainter *painter,
+    const QRectF &rect, const QBrush &brush )
+{
+    if ( !rect.isValid() )
+        return;
+
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+
+    /*
+      Performance of Qt4 is horrible for non trivial brushs. Without
+      clipping expect minutes or hours for repainting large rects
+      (might result from zooming)
+    */
+
+    if ( deviceClipping )
+        clipRect &= painter->window();
+    else
+        clipRect = painter->window();
+
+    if ( painter->hasClipping() )
+        clipRect &= painter->clipRegion().boundingRect();
+
+    QRectF r = rect;
+    if ( deviceClipping )
+        r = r.intersect( clipRect );
+
+    if ( r.isValid() )
+        painter->fillRect( r, brush );
+}
+
+//! Wrapper for QPainter::drawPie()
+void QwtPainter::drawPie( QPainter *painter, const QRectF &rect,
+    int a, int alen )
+{
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+    if ( deviceClipping && !clipRect.contains( rect ) )
+        return;
+
+    painter->drawPie( rect, a, alen );
+}
+
+//! Wrapper for QPainter::drawEllipse()
+void QwtPainter::drawEllipse( QPainter *painter, const QRectF &rect )
+{
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+
+    if ( deviceClipping && !clipRect.contains( rect ) )
+        return;
+
+    painter->drawEllipse( rect );
+}
+
+//! Wrapper for QPainter::drawText()
+void QwtPainter::drawText( QPainter *painter, double x, double y,
+        const QString &text )
+{
+    drawText( painter, QPointF( x, y ), text );
+}
+
+//! Wrapper for QPainter::drawText()
+void QwtPainter::drawText( QPainter *painter, const QPointF &pos,
+        const QString &text )
+{
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+
+    if ( deviceClipping && !clipRect.contains( pos ) )
+        return;
+
+
+    painter->save();
+    unscaleFont( painter );
+    painter->drawText( pos, text );
+    painter->restore();
+}
+
+//! Wrapper for QPainter::drawText()
+void QwtPainter::drawText( QPainter *painter,
+    double x, double y, double w, double h,
+    int flags, const QString &text )
+{
+    drawText( painter, QRectF( x, y, w, h ), flags, text );
+}
+
+//! Wrapper for QPainter::drawText()
+void QwtPainter::drawText( QPainter *painter, const QRectF &rect,
+        int flags, const QString &text )
+{
+    painter->save();
+    unscaleFont( painter );
+    painter->drawText( rect, flags, text );
+    painter->restore();
+}
+
+#ifndef QT_NO_RICHTEXT
+
+/*!
+  Draw a text document into a rectangle
+
+  \param painter Painter
+  \param rect Traget rectangle
+  \param flags Alignments/Text flags, see QPainter::drawText()
+  \param text Text document
+*/
+void QwtPainter::drawSimpleRichText( QPainter *painter, const QRectF &rect,
+    int flags, const QTextDocument &text )
+{
+    QTextDocument *txt = text.clone();
+
+    painter->save();
+
+    painter->setFont( txt->defaultFont() );
+    unscaleFont( painter );
+
+    txt->setDefaultFont( painter->font() );
+    txt->setPageSize( QSizeF( rect.width(), QWIDGETSIZE_MAX ) );
+
+    QAbstractTextDocumentLayout* layout = txt->documentLayout();
+
+    const double height = layout->documentSize().height();
+    double y = rect.y();
+    if ( flags & Qt::AlignBottom )
+        y += ( rect.height() - height );
+    else if ( flags & Qt::AlignVCenter )
+        y += ( rect.height() - height ) / 2;
+
+    QAbstractTextDocumentLayout::PaintContext context;
+    context.palette.setColor( QPalette::Text, painter->pen().color() );
+
+    painter->translate( rect.x(), y );
+    layout->draw( painter, context );
+
+    painter->restore();
+    delete txt;
+}
+
+#endif // !QT_NO_RICHTEXT
+
+
+//! Wrapper for QPainter::drawLine()
+void QwtPainter::drawLine( QPainter *painter,
+    const QPointF &p1, const QPointF &p2 )
+{
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+
+    if ( deviceClipping &&
+        !( clipRect.contains( p1 ) && clipRect.contains( p2 ) ) )
+    {
+        QPolygonF polygon;
+        polygon += p1;
+        polygon += p2;
+        drawPolyline( painter, polygon );
+        return;
+    }
+
+    painter->drawLine( p1, p2 );
+}
+
+//! Wrapper for QPainter::drawPolygon()
+void QwtPainter::drawPolygon( QPainter *painter, const QPolygonF &polygon )
+{
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+
+    QPolygonF cpa = polygon;
+    if ( deviceClipping )
+        cpa = QwtClipper::clipPolygonF( clipRect, polygon );
+
+    painter->drawPolygon( cpa );
+}
+
+//! Wrapper for QPainter::drawPolyline()
+void QwtPainter::drawPolyline( QPainter *painter, const QPolygonF &polygon )
+{
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+
+    QPolygonF cpa = polygon;
+    if ( deviceClipping )
+        cpa = QwtClipper::clipPolygonF( clipRect, cpa );
+
+    ::drawPolyline( painter,
+        cpa.constData(), cpa.size(), d_polylineSplitting );
+}
+
+//! Wrapper for QPainter::drawPolyline()
+void QwtPainter::drawPolyline( QPainter *painter,
+    const QPointF *points, int pointCount )
+{
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+
+    if ( deviceClipping )
+    {
+        QPolygonF polygon( pointCount );
+        qMemCopy( polygon.data(), points, pointCount * sizeof( QPointF ) );
+
+        polygon = QwtClipper::clipPolygonF( clipRect, polygon );
+        ::drawPolyline( painter,
+            polygon.constData(), polygon.size(), d_polylineSplitting );
+    }
+    else
+        ::drawPolyline( painter, points, pointCount, d_polylineSplitting );
+}
+
+//! Wrapper for QPainter::drawPoint()
+void QwtPainter::drawPoint( QPainter *painter, const QPointF &pos )
+{
+    QRectF clipRect;
+    const bool deviceClipping = isClippingNeeded( painter, clipRect );
+
+    if ( deviceClipping && !clipRect.contains( pos ) )
+        return;
+
+    painter->drawPoint( pos );
+}
+
+//! Wrapper for QPainter::drawImage()
+void QwtPainter::drawImage( QPainter *painter,
+    const QRectF &rect, const QImage &image )
+{
+    const QRect alignedRect = rect.toAlignedRect();
+
+    if ( alignedRect != rect )
+    {
+        const QRectF clipRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
+
+        painter->save();
+        painter->setClipRect( clipRect, Qt::IntersectClip );
+        painter->drawImage( alignedRect, image );
+        painter->restore();
+    }
+    else
+    {
+        painter->drawImage( alignedRect, image );
+    }
+}
+
+//! Wrapper for QPainter::drawPixmap()
+void QwtPainter::drawPixmap( QPainter *painter,
+    const QRectF &rect, const QPixmap &pixmap )
+{
+    const QRect alignedRect = rect.toAlignedRect();
+
+    if ( alignedRect != rect )
+    {
+        const QRectF clipRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
+
+        painter->save();
+        painter->setClipRect( clipRect, Qt::IntersectClip );
+        painter->drawPixmap( alignedRect, pixmap );
+        painter->restore();
+    }
+    else
+    {
+        painter->drawPixmap( alignedRect, pixmap );
+    }
+}
+
+//! Draw a focus rectangle on a widget using its style.
+void QwtPainter::drawFocusRect( QPainter *painter, QWidget *widget )
+{
+    drawFocusRect( painter, widget, widget->rect() );
+}
+
+//! Draw a focus rectangle on a widget using its style.
+void QwtPainter::drawFocusRect( QPainter *painter, QWidget *widget,
+    const QRect &rect )
+{
+    QStyleOptionFocusRect opt;
+    opt.init( widget );
+    opt.rect = rect;
+    opt.state |= QStyle::State_HasFocus;
+
+    widget->style()->drawPrimitive( QStyle::PE_FrameFocusRect,
+        &opt, painter, widget );
+}
+
+/*!
+  Draw a frame with rounded borders
+
+  \param painter Painter
+  \param rect Frame rectangle
+  \param xRadius x-radius of the ellipses defining the corners
+  \param yRadius y-radius of the ellipses defining the corners
+  \param palette QPalette::WindowText is used for plain borders
+                 QPalette::Dark and QPalette::Light for raised
+                 or sunken borders
+  \param lineWidth Line width
+  \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow
+*/
+
+void QwtPainter::drawRoundedFrame( QPainter *painter, 
+    const QRectF &rect, double xRadius, double yRadius, 
+    const QPalette &palette, int lineWidth, int frameStyle )
+{
+    painter->save();
+    painter->setRenderHint( QPainter::Antialiasing, true );
+    painter->setBrush( Qt::NoBrush );
+
+    double lw2 = lineWidth * 0.5;
+    QRectF r = rect.adjusted( lw2, lw2, -lw2, -lw2 );
+
+    QPainterPath path;
+    path.addRoundedRect( r, xRadius, yRadius );
+
+    enum Style
+    {
+        Plain,
+        Sunken,
+        Raised
+    };
+
+    Style style = Plain;
+    if ( (frameStyle & QFrame::Sunken) == QFrame::Sunken )
+        style = Sunken;
+    else if ( (frameStyle & QFrame::Raised) == QFrame::Raised )
+        style = Raised;
+
+    if ( style != Plain && path.elementCount() == 17 )
+    {
+        // move + 4 * ( cubicTo + lineTo )
+        QPainterPath pathList[8];
+        
+        for ( int i = 0; i < 4; i++ )
+        {
+            const int j = i * 4 + 1;
+            
+            pathList[ 2 * i ].moveTo(
+                path.elementAt(j - 1).x, path.elementAt( j - 1 ).y
+            );  
+            
+            pathList[ 2 * i ].cubicTo(
+                path.elementAt(j + 0).x, path.elementAt(j + 0).y,
+                path.elementAt(j + 1).x, path.elementAt(j + 1).y,
+                path.elementAt(j + 2).x, path.elementAt(j + 2).y );
+                
+            pathList[ 2 * i + 1 ].moveTo(
+                path.elementAt(j + 2).x, path.elementAt(j + 2).y
+            );  
+            pathList[ 2 * i + 1 ].lineTo(
+                path.elementAt(j + 3).x, path.elementAt(j + 3).y
+            );  
+        }   
+
+        QColor c1( palette.color( QPalette::Dark ) );
+        QColor c2( palette.color( QPalette::Light ) );
+
+        if ( style == Raised )
+            qSwap( c1, c2 );
+
+        for ( int i = 0; i < 4; i++ )
+        {
+            QRectF r = pathList[2 * i].controlPointRect();
+
+            QPen arcPen;
+            arcPen.setWidth( lineWidth );
+
+            QPen linePen;
+            linePen.setWidth( lineWidth );
+
+            switch( i )
+            {
+                case 0:
+                {
+                    arcPen.setColor( c1 );
+                    linePen.setColor( c1 );
+                    break;
+                }
+                case 1:
+                {
+                    QLinearGradient gradient;
+                    gradient.setStart( r.topLeft() );
+                    gradient.setFinalStop( r.bottomRight() );
+                    gradient.setColorAt( 0.0, c1 );
+                    gradient.setColorAt( 1.0, c2 );
+
+                    arcPen.setBrush( gradient );
+                    linePen.setColor( c2 );
+                    break;
+                }
+                case 2:
+                {
+                    arcPen.setColor( c2 );
+                    linePen.setColor( c2 );
+                    break;
+                }
+                case 3:
+                {
+                    QLinearGradient gradient;
+
+                    gradient.setStart( r.bottomRight() );
+                    gradient.setFinalStop( r.topLeft() );
+                    gradient.setColorAt( 0.0, c2 );
+                    gradient.setColorAt( 1.0, c1 );
+
+                    arcPen.setBrush( gradient );
+                    linePen.setColor( c1 );
+                    break;
+                }
+            }
+
+
+            painter->setPen( arcPen );
+            painter->drawPath( pathList[ 2 * i] );
+
+            painter->setPen( linePen );
+            painter->drawPath( pathList[ 2 * i + 1] );
+        }
+    }
+    else
+    {
+        QPen pen( palette.color( QPalette::WindowText ), lineWidth );
+        painter->setPen( pen );
+        painter->drawPath( path );
+    }
+
+    painter->restore();
+}
+
+/*!
+  Draw a color bar into a rectangle
+
+  \param painter Painter
+  \param colorMap Color map
+  \param interval Value range
+  \param scaleMap Scale map
+  \param orientation Orientation
+  \param rect Traget rectangle
+*/
+void QwtPainter::drawColorBar( QPainter *painter,
+        const QwtColorMap &colorMap, const QwtInterval &interval,
+        const QwtScaleMap &scaleMap, Qt::Orientation orientation,
+        const QRectF &rect )
+{
+    QVector<QRgb> colorTable;
+    if ( colorMap.format() == QwtColorMap::Indexed )
+        colorTable = colorMap.colorTable( interval );
+
+    QColor c;
+
+    const QRect devRect = rect.toAlignedRect();
+
+    /*
+      We paint to a pixmap first to have something scalable for printing
+      ( f.e. in a Pdf document )
+     */
+
+    QPixmap pixmap( devRect.size() );
+    QPainter pmPainter( &pixmap );
+    pmPainter.translate( -devRect.x(), -devRect.y() );
+
+    if ( orientation == Qt::Horizontal )
+    {
+        QwtScaleMap sMap = scaleMap;
+        sMap.setPaintInterval( rect.left(), rect.right() );
+
+        for ( int x = devRect.left(); x <= devRect.right(); x++ )
+        {
+            const double value = sMap.invTransform( x );
+
+            if ( colorMap.format() == QwtColorMap::RGB )
+                c.setRgb( colorMap.rgb( interval, value ) );
+            else
+                c = colorTable[colorMap.colorIndex( interval, value )];
+
+            pmPainter.setPen( c );
+            pmPainter.drawLine( x, devRect.top(), x, devRect.bottom() );
+        }
+    }
+    else // Vertical
+    {
+        QwtScaleMap sMap = scaleMap;
+        sMap.setPaintInterval( rect.bottom(), rect.top() );
+
+        for ( int y = devRect.top(); y <= devRect.bottom(); y++ )
+        {
+            const double value = sMap.invTransform( y );
+
+            if ( colorMap.format() == QwtColorMap::RGB )
+                c.setRgb( colorMap.rgb( interval, value ) );
+            else
+                c = colorTable[colorMap.colorIndex( interval, value )];
+
+            pmPainter.setPen( c );
+            pmPainter.drawLine( devRect.left(), y, devRect.right(), y );
+        }
+    }
+    pmPainter.end();
+
+    drawPixmap( painter, rect, pixmap );
+}
Index: trunk/BNC/qwt/qwt_painter.h
===================================================================
--- trunk/BNC/qwt/qwt_painter.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_painter.h	(revision 4271)
@@ -0,0 +1,149 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PAINTER_H
+#define QWT_PAINTER_H
+
+#include "qwt_global.h"
+
+#include <qpoint.h>
+#include <qrect.h>
+#include <qpen.h>
+#include <qline.h>
+
+class QPainter;
+class QBrush;
+class QColor;
+class QWidget;
+class QPolygonF;
+class QRectF;
+class QImage;
+class QPixmap;
+class QwtScaleMap;
+class QwtColorMap;
+class QwtInterval;
+
+class QPalette;
+class QTextDocument;
+class QPainterPath;
+
+/*!
+  \brief A collection of QPainter workarounds
+*/
+class QWT_EXPORT QwtPainter
+{
+public:
+    static void setPolylineSplitting( bool );
+    static bool polylineSplitting();
+
+    static void setRoundingAlignment( bool );
+    static bool roundingAlignment();
+    static bool roundingAlignment(QPainter *);
+
+    static void drawText( QPainter *, double x, double y, const QString & );
+    static void drawText( QPainter *, const QPointF &, const QString & );
+    static void drawText( QPainter *, double x, double y, double w, double h,
+        int flags, const QString & );
+    static void drawText( QPainter *, const QRectF &, 
+        int flags, const QString & );
+
+#ifndef QT_NO_RICHTEXT
+    static void drawSimpleRichText( QPainter *, const QRectF &,
+        int flags, const QTextDocument & );
+#endif
+
+    static void drawRect( QPainter *, double x, double y, double w, double h );
+    static void drawRect( QPainter *, const QRectF &rect );
+    static void fillRect( QPainter *, const QRectF &, const QBrush & );
+
+    static void drawEllipse( QPainter *, const QRectF & );
+    static void drawPie( QPainter *, const QRectF & r, int a, int alen );
+
+    static void drawLine( QPainter *, double x1, double y1, double x2, double y2 );
+    static void drawLine( QPainter *, const QPointF &p1, const QPointF &p2 );
+    static void drawLine( QPainter *, const QLineF & );
+
+    static void drawPolygon( QPainter *, const QPolygonF &pa );
+    static void drawPolyline( QPainter *, const QPolygonF &pa );
+    static void drawPolyline( QPainter *, const QPointF *, int pointCount );
+
+    static void drawPoint( QPainter *, double x, double y );
+    static void drawPoint( QPainter *, const QPointF & );
+
+    static void drawPath( QPainter *, const QPainterPath & );
+    static void drawImage( QPainter *, const QRectF &, const QImage & );
+    static void drawPixmap( QPainter *, const QRectF &, const QPixmap & );
+
+    static void drawRoundedFrame( QPainter *, 
+        const QRectF &, double xRadius, double yRadius,
+        const QPalette &, int lineWidth, int frameStyle );
+
+    static void drawFocusRect( QPainter *, QWidget * );
+    static void drawFocusRect( QPainter *, QWidget *, const QRect & );
+
+    static void drawColorBar( QPainter *painter,
+        const QwtColorMap &, const QwtInterval &,
+        const QwtScaleMap &, Qt::Orientation, const QRectF & );
+
+    static bool isAligning( QPainter *painter );
+
+private:
+    static bool d_polylineSplitting;
+    static bool d_roundingAlignment;
+};
+
+//!  Wrapper for QPainter::drawPoint()
+inline void QwtPainter::drawPoint( QPainter *painter, double x, double y )
+{
+    QwtPainter::drawPoint( painter, QPointF( x, y ) );
+}
+
+//!  Wrapper for QPainter::drawLine()
+inline void QwtPainter::drawLine( QPainter *painter,
+    double x1, double y1, double x2, double y2 )
+{
+    QwtPainter::drawLine( painter, QPointF( x1, y1 ), QPointF( x2, y2 ) );
+}
+
+//!  Wrapper for QPainter::drawLine()
+inline void QwtPainter::drawLine( QPainter *painter, const QLineF &line )
+{
+    QwtPainter::drawLine( painter, line.p1(), line.p2() );
+}
+
+/*!
+  Returns whether line splitting for the raster paint engine is enabled.
+  \sa setPolylineSplitting()
+*/
+inline bool QwtPainter::polylineSplitting()
+{
+    return d_polylineSplitting;
+}
+
+/*!
+  Returns whether coordinates should be rounded, before they are painted
+  to a paint engine that floors to integer values.  For other paint engines
+  this ( Pdf, SVG ), this flag has no effect.
+
+  \sa setRoundingAlignment(), isAligning()
+*/
+inline bool QwtPainter::roundingAlignment()
+{
+    return d_roundingAlignment;
+}
+
+/*!
+  \return roundingAlignment() && isAligning(painter);
+  \param painter Painter
+*/
+inline bool QwtPainter::roundingAlignment(QPainter *painter)
+{
+    return d_roundingAlignment && isAligning(painter);
+}
+#endif
Index: trunk/BNC/qwt/qwt_panner.cpp
===================================================================
--- trunk/BNC/qwt/qwt_panner.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_panner.cpp	(revision 4271)
@@ -0,0 +1,534 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_panner.h"
+#include "qwt_picker.h"
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qevent.h>
+#include <qcursor.h>
+#include <qbitmap.h>
+
+static QVector<QwtPicker *> qwtActivePickers( QWidget *w )
+{
+    QVector<QwtPicker *> pickers;
+
+    QObjectList children = w->children();
+    for ( int i = 0; i < children.size(); i++ )
+    {
+        QObject *obj = children[i];
+        if ( obj->inherits( "QwtPicker" ) )
+        {
+            QwtPicker *picker = ( QwtPicker * )obj;
+            if ( picker->isEnabled() )
+                pickers += picker;
+        }
+    }
+
+    return pickers;
+}
+
+class QwtPanner::PrivateData
+{
+public:
+    PrivateData():
+        button( Qt::LeftButton ),
+        buttonState( Qt::NoButton ),
+        abortKey( Qt::Key_Escape ),
+        abortKeyState( Qt::NoButton ),
+#ifndef QT_NO_CURSOR
+        cursor( NULL ),
+        restoreCursor( NULL ),
+        hasCursor( false ),
+#endif
+        isEnabled( false )
+    {
+        orientations = Qt::Vertical | Qt::Horizontal;
+    }
+
+    ~PrivateData()
+    {
+#ifndef QT_NO_CURSOR
+        delete cursor;
+        delete restoreCursor;
+#endif
+    }
+
+    int button;
+    int buttonState;
+    int abortKey;
+    int abortKeyState;
+
+    QPoint initialPos;
+    QPoint pos;
+
+    QPixmap pixmap;
+    QBitmap contentsMask;
+
+#ifndef QT_NO_CURSOR
+    QCursor *cursor;
+    QCursor *restoreCursor;
+    bool hasCursor;
+#endif
+    bool isEnabled;
+    Qt::Orientations orientations;
+};
+
+/*!
+  Creates an panner that is enabled for the left mouse button.
+
+  \param parent Parent widget to be panned
+*/
+QwtPanner::QwtPanner( QWidget *parent ):
+    QWidget( parent )
+{
+    d_data = new PrivateData();
+
+    setAttribute( Qt::WA_TransparentForMouseEvents );
+    setAttribute( Qt::WA_NoSystemBackground );
+    setFocusPolicy( Qt::NoFocus );
+    hide();
+
+    setEnabled( true );
+}
+
+//! Destructor
+QwtPanner::~QwtPanner()
+{
+    delete d_data;
+}
+
+/*!
+   Change the mouse button
+   The defaults are Qt::LeftButton and Qt::NoButton
+*/
+void QwtPanner::setMouseButton( int button, int buttonState )
+{
+    d_data->button = button;
+    d_data->buttonState = buttonState;
+}
+
+//! Get the mouse button
+void QwtPanner::getMouseButton( int &button, int &buttonState ) const
+{
+    button = d_data->button;
+    buttonState = d_data->buttonState;
+}
+
+/*!
+   Change the abort key
+   The defaults are Qt::Key_Escape and Qt::NoButton
+
+   \param key Key ( See Qt::Keycode )
+   \param state State
+*/
+void QwtPanner::setAbortKey( int key, int state )
+{
+    d_data->abortKey = key;
+    d_data->abortKeyState = state;
+}
+
+//! Get the abort key
+void QwtPanner::getAbortKey( int &key, int &state ) const
+{
+    key = d_data->abortKey;
+    state = d_data->abortKeyState;
+}
+
+/*!
+   Change the cursor, that is active while panning
+   The default is the cursor of the parent widget.
+
+   \param cursor New cursor
+
+   \sa setCursor()
+*/
+#ifndef QT_NO_CURSOR
+void QwtPanner::setCursor( const QCursor &cursor )
+{
+    d_data->cursor = new QCursor( cursor );
+}
+#endif
+
+/*!
+   \return Cursor that is active while panning
+   \sa setCursor()
+*/
+#ifndef QT_NO_CURSOR
+const QCursor QwtPanner::cursor() const
+{
+    if ( d_data->cursor )
+        return *d_data->cursor;
+
+    if ( parentWidget() )
+        return parentWidget()->cursor();
+
+    return QCursor();
+}
+#endif
+
+/*!
+  \brief En/disable the panner
+
+  When enabled is true an event filter is installed for
+  the observed widget, otherwise the event filter is removed.
+
+  \param on true or false
+  \sa isEnabled(), eventFilter()
+*/
+void QwtPanner::setEnabled( bool on )
+{
+    if ( d_data->isEnabled != on )
+    {
+        d_data->isEnabled = on;
+
+        QWidget *w = parentWidget();
+        if ( w )
+        {
+            if ( d_data->isEnabled )
+            {
+                w->installEventFilter( this );
+            }
+            else
+            {
+                w->removeEventFilter( this );
+                hide();
+            }
+        }
+    }
+}
+
+/*!
+   Set the orientations, where panning is enabled
+   The default value is in both directions: Qt::Horizontal | Qt::Vertical
+
+   /param o Orientation
+*/
+void QwtPanner::setOrientations( Qt::Orientations o )
+{
+    d_data->orientations = o;
+}
+
+//! Return the orientation, where paning is enabled
+Qt::Orientations QwtPanner::orientations() const
+{
+    return d_data->orientations;
+}
+
+/*!
+   Return true if a orientatio is enabled
+   \sa orientations(), setOrientations()
+*/
+bool QwtPanner::isOrientationEnabled( Qt::Orientation o ) const
+{
+    return d_data->orientations & o;
+}
+
+/*!
+  \return true when enabled, false otherwise
+  \sa setEnabled, eventFilter()
+*/
+bool QwtPanner::isEnabled() const
+{
+    return d_data->isEnabled;
+}
+
+/*!
+   \brief Paint event
+
+   Repaint the grabbed pixmap on its current position and
+   fill the empty spaces by the background of the parent widget.
+
+   \param pe Paint event
+*/
+void QwtPanner::paintEvent( QPaintEvent *pe )
+{
+    int dx = d_data->pos.x() - d_data->initialPos.x();
+    int dy = d_data->pos.y() - d_data->initialPos.y();
+
+    QRect r( 0, 0, d_data->pixmap.width(), d_data->pixmap.height() );
+    r.moveCenter( QPoint( r.center().x() + dx, r.center().y() + dy ) );
+
+    QPixmap pm( size() );
+    pm.fill( parentWidget(), 0, 0 );
+
+    QPainter painter( &pm );
+
+    if ( !d_data->contentsMask.isNull() )
+    {
+        QPixmap masked = d_data->pixmap;
+        masked.setMask( d_data->contentsMask );
+        painter.drawPixmap( r, masked );
+    }
+    else
+    {
+        painter.drawPixmap( r, d_data->pixmap );
+    }
+
+    painter.end();
+
+    if ( !d_data->contentsMask.isNull() )
+        pm.setMask( d_data->contentsMask );
+
+    painter.begin( this );
+    painter.setClipRegion( pe->region() );
+    painter.drawPixmap( 0, 0, pm );
+}
+
+/*!
+  \brief Calculate a mask for the contents of the panned widget
+
+  Sometimes only parts of the contents of a widget should be
+  panned. F.e. for a widget with a styled background with rounded borders
+  only the area inside of the border should be panned.
+
+  \return An empty bitmap, indicating no mask
+*/
+QBitmap QwtPanner::contentsMask() const
+{
+    return QBitmap();
+}
+
+/*!
+  Grab the widget into a pixmap.
+*/
+QPixmap QwtPanner::grab() const
+{
+    return QPixmap::grabWidget( parentWidget() );
+}
+
+/*!
+  \brief Event filter
+
+  When isEnabled() the mouse events of the observed widget are filtered.
+
+  \param object Object to be filtered
+  \param event Event
+
+  \sa widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseMoveEvent()
+*/
+bool QwtPanner::eventFilter( QObject *object, QEvent *event )
+{
+    if ( object == NULL || object != parentWidget() )
+        return false;
+
+    switch ( event->type() )
+    {
+        case QEvent::MouseButtonPress:
+        {
+            widgetMousePressEvent( ( QMouseEvent * )event );
+            break;
+        }
+        case QEvent::MouseMove:
+        {
+            widgetMouseMoveEvent( ( QMouseEvent * )event );
+            break;
+        }
+        case QEvent::MouseButtonRelease:
+        {
+            widgetMouseReleaseEvent( ( QMouseEvent * )event );
+            break;
+        }
+        case QEvent::KeyPress:
+        {
+            widgetKeyPressEvent( ( QKeyEvent * )event );
+            break;
+        }
+        case QEvent::KeyRelease:
+        {
+            widgetKeyReleaseEvent( ( QKeyEvent * )event );
+            break;
+        }
+        case QEvent::Paint:
+        {
+            if ( isVisible() )
+                return true;
+            break;
+        }
+        default:;
+    }
+
+    return false;
+}
+
+/*!
+  Handle a mouse press event for the observed widget.
+
+  \param mouseEvent Mouse event
+  \sa eventFilter(), widgetMouseReleaseEvent(),
+      widgetMouseMoveEvent(),
+*/
+void QwtPanner::widgetMousePressEvent( QMouseEvent *mouseEvent )
+{
+    if ( mouseEvent->button() != d_data->button )
+        return;
+
+    QWidget *w = parentWidget();
+    if ( w == NULL )
+        return;
+
+    if ( ( mouseEvent->modifiers() & Qt::KeyboardModifierMask ) !=
+        ( int )( d_data->buttonState & Qt::KeyboardModifierMask ) )
+    {
+        return;
+    }
+
+#ifndef QT_NO_CURSOR
+    showCursor( true );
+#endif
+
+    d_data->initialPos = d_data->pos = mouseEvent->pos();
+
+    setGeometry( parentWidget()->rect() );
+
+    // We don't want to grab the picker !
+    QVector<QwtPicker *> pickers = qwtActivePickers( parentWidget() );
+    for ( int i = 0; i < ( int )pickers.size(); i++ )
+        pickers[i]->setEnabled( false );
+
+    d_data->pixmap = grab();
+    d_data->contentsMask = contentsMask();
+
+    for ( int i = 0; i < ( int )pickers.size(); i++ )
+        pickers[i]->setEnabled( true );
+
+    show();
+}
+
+/*!
+  Handle a mouse move event for the observed widget.
+
+  \param mouseEvent Mouse event
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent()
+*/
+void QwtPanner::widgetMouseMoveEvent( QMouseEvent *mouseEvent )
+{
+    if ( !isVisible() )
+        return;
+
+    QPoint pos = mouseEvent->pos();
+    if ( !isOrientationEnabled( Qt::Horizontal ) )
+        pos.setX( d_data->initialPos.x() );
+    if ( !isOrientationEnabled( Qt::Vertical ) )
+        pos.setY( d_data->initialPos.y() );
+
+    if ( pos != d_data->pos && rect().contains( pos ) )
+    {
+        d_data->pos = pos;
+        update();
+
+        Q_EMIT moved( d_data->pos.x() - d_data->initialPos.x(),
+            d_data->pos.y() - d_data->initialPos.y() );
+    }
+}
+
+/*!
+  Handle a mouse release event for the observed widget.
+
+  \param mouseEvent Mouse event
+  \sa eventFilter(), widgetMousePressEvent(),
+      widgetMouseMoveEvent(),
+*/
+void QwtPanner::widgetMouseReleaseEvent( QMouseEvent *mouseEvent )
+{
+    if ( isVisible() )
+    {
+        hide();
+#ifndef QT_NO_CURSOR
+        showCursor( false );
+#endif
+
+        QPoint pos = mouseEvent->pos();
+        if ( !isOrientationEnabled( Qt::Horizontal ) )
+            pos.setX( d_data->initialPos.x() );
+        if ( !isOrientationEnabled( Qt::Vertical ) )
+            pos.setY( d_data->initialPos.y() );
+
+        d_data->pixmap = QPixmap();
+        d_data->contentsMask = QBitmap();
+        d_data->pos = pos;
+
+        if ( d_data->pos != d_data->initialPos )
+        {
+            Q_EMIT panned( d_data->pos.x() - d_data->initialPos.x(),
+                d_data->pos.y() - d_data->initialPos.y() );
+        }
+    }
+}
+
+/*!
+  Handle a key press event for the observed widget.
+
+  \param keyEvent Key event
+  \sa eventFilter(), widgetKeyReleaseEvent()
+*/
+void QwtPanner::widgetKeyPressEvent( QKeyEvent *keyEvent )
+{
+    if ( keyEvent->key() == d_data->abortKey )
+    {
+        const bool matched =
+            ( keyEvent->modifiers() & Qt::KeyboardModifierMask ) ==
+                ( int )( d_data->abortKeyState & Qt::KeyboardModifierMask );
+        if ( matched )
+        {
+            hide();
+#ifndef QT_NO_CURSOR
+            showCursor( false );
+#endif
+            d_data->pixmap = QPixmap();
+        }
+    }
+}
+
+/*!
+  Handle a key release event for the observed widget.
+
+  \param keyEvent Key event
+  \sa eventFilter(), widgetKeyReleaseEvent()
+*/
+void QwtPanner::widgetKeyReleaseEvent( QKeyEvent *keyEvent )
+{
+    Q_UNUSED( keyEvent );
+}
+
+#ifndef QT_NO_CURSOR
+void QwtPanner::showCursor( bool on )
+{
+    if ( on == d_data->hasCursor )
+        return;
+
+    QWidget *w = parentWidget();
+    if ( w == NULL || d_data->cursor == NULL )
+        return;
+
+    d_data->hasCursor = on;
+
+    if ( on )
+    {
+        if ( w->testAttribute( Qt::WA_SetCursor ) )
+        {
+            delete d_data->restoreCursor;
+            d_data->restoreCursor = new QCursor( w->cursor() );
+        }
+        w->setCursor( *d_data->cursor );
+    }
+    else
+    {
+        if ( d_data->restoreCursor )
+        {
+            w->setCursor( *d_data->restoreCursor );
+            delete d_data->restoreCursor;
+            d_data->restoreCursor = NULL;
+        }
+        else
+            w->unsetCursor();
+    }
+}
+#endif
Index: trunk/BNC/qwt/qwt_panner.h
===================================================================
--- trunk/BNC/qwt/qwt_panner.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_panner.h	(revision 4271)
@@ -0,0 +1,100 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PANNER_H
+#define QWT_PANNER_H 1
+
+#include "qwt_global.h"
+#include <qwidget.h>
+#include <qpixmap.h>
+
+class QCursor;
+
+/*!
+  \brief QwtPanner provides panning of a widget
+
+  QwtPanner grabs the contents of a widget, that can be dragged
+  in all directions. The offset between the start and the end position
+  is emitted by the panned signal.
+
+  QwtPanner grabs the content of the widget into a pixmap and moves
+  the pixmap around, without initiating any repaint events for the widget.
+  Areas, that are not part of content are not painted  while panning.
+  This makes panning fast enough for widgets, where
+  repaints are too slow for mouse movements.
+
+  For widgets, where repaints are very fast it might be better to
+  implement panning manually by mapping mouse events into paint events.
+*/
+class QWT_EXPORT QwtPanner: public QWidget
+{
+    Q_OBJECT
+
+public:
+    QwtPanner( QWidget* parent );
+    virtual ~QwtPanner();
+
+    void setEnabled( bool );
+    bool isEnabled() const;
+
+    void setMouseButton( int button, int buttonState = Qt::NoButton );
+    void getMouseButton( int &button, int &buttonState ) const;
+    void setAbortKey( int key, int state = Qt::NoButton );
+    void getAbortKey( int &key, int &state ) const;
+
+    void setCursor( const QCursor & );
+    const QCursor cursor() const;
+
+    void setOrientations( Qt::Orientations );
+    Qt::Orientations orientations() const;
+
+    bool isOrientationEnabled( Qt::Orientation ) const;
+
+    virtual bool eventFilter( QObject *, QEvent * );
+
+Q_SIGNALS:
+    /*!
+      Signal emitted, when panning is done
+
+      \param dx Offset in horizontal direction
+      \param dy Offset in vertical direction
+    */
+    void panned( int dx, int dy );
+
+    /*!
+      Signal emitted, while the widget moved, but panning
+      is not finished.
+
+      \param dx Offset in horizontal direction
+      \param dy Offset in vertical direction
+    */
+    void moved( int dx, int dy );
+
+protected:
+    virtual void widgetMousePressEvent( QMouseEvent * );
+    virtual void widgetMouseReleaseEvent( QMouseEvent * );
+    virtual void widgetMouseMoveEvent( QMouseEvent * );
+    virtual void widgetKeyPressEvent( QKeyEvent * );
+    virtual void widgetKeyReleaseEvent( QKeyEvent * );
+
+    virtual void paintEvent( QPaintEvent * );
+
+    virtual QBitmap contentsMask() const;
+    virtual QPixmap grab() const;
+
+private:
+#ifndef QT_NO_CURSOR
+    void showCursor( bool );
+#endif
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_picker.cpp
===================================================================
--- trunk/BNC/qwt/qwt_picker.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_picker.cpp	(revision 4271)
@@ -0,0 +1,1434 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_picker.h"
+#include "qwt_picker_machine.h"
+#include "qwt_painter.h"
+#include "qwt_math.h"
+#include <qapplication.h>
+#include <qevent.h>
+#include <qpainter.h>
+#include <qframe.h>
+#include <qcursor.h>
+#include <qbitmap.h>
+#include <qpointer.h>
+#include <qpaintengine.h>
+#include <qmath.h>
+
+class QwtPicker::PickerWidget: public QWidget
+{
+public:
+    enum Type
+    {
+        RubberBand,
+        Text
+    };
+
+    PickerWidget( QwtPicker *, QWidget *, Type );
+    void updateMask();
+
+    /*
+       For a tracker text with a background we can use the background
+       rect as mask. Also for "regular" Qt widgets >= 4.3.0 we
+       don't need to mask the text anymore.
+     */
+    bool d_hasTextMask;
+
+protected:
+    virtual void paintEvent( QPaintEvent * );
+
+    QwtPicker *d_picker;
+    Type d_type;
+};
+
+class QwtPicker::PrivateData
+{
+public:
+    bool enabled;
+
+    QwtPickerMachine *stateMachine;
+
+    QwtPicker::ResizeMode resizeMode;
+
+    QwtPicker::RubberBand rubberBand;
+    QPen rubberBandPen;
+
+    QwtPicker::DisplayMode trackerMode;
+    QPen trackerPen;
+    QFont trackerFont;
+
+    QPolygon pickedPoints;
+    bool isActive;
+    QPoint trackerPosition;
+
+    bool mouseTracking; // used to save previous value
+
+    /*
+      On X11 the widget below the picker widgets gets paint events
+      with a region that is the bounding rect of the mask, if it is complex.
+      In case of (f.e) a CrossRubberBand and a text this creates complete
+      repaints of the widget. So we better use two different widgets.
+     */
+
+    QPointer<PickerWidget> rubberBandWidget;
+    QPointer<PickerWidget> trackerWidget;
+};
+
+QwtPicker::PickerWidget::PickerWidget(
+        QwtPicker *picker, QWidget *parent, Type type ):
+    QWidget( parent ),
+    d_hasTextMask( false ),
+    d_picker( picker ),
+    d_type( type )
+{
+    setAttribute( Qt::WA_TransparentForMouseEvents );
+    setAttribute( Qt::WA_NoSystemBackground );
+    setFocusPolicy( Qt::NoFocus );
+}
+
+void QwtPicker::PickerWidget::updateMask()
+{
+    QRegion mask;
+
+    if ( d_type == RubberBand )
+    {
+        QBitmap bm( width(), height() );
+        bm.fill( Qt::color0 );
+
+        QPainter painter( &bm );
+        QPen pen = d_picker->rubberBandPen();
+        pen.setColor( Qt::color1 );
+        painter.setPen( pen );
+
+        d_picker->drawRubberBand( &painter );
+
+        mask = QRegion( bm );
+    }
+    if ( d_type == Text )
+    {
+        d_hasTextMask = parentWidget()->testAttribute( Qt::WA_PaintOnScreen );
+
+        if ( d_hasTextMask )
+        {
+            const QwtText label = d_picker->trackerText(
+                d_picker->trackerPosition() );
+
+            if ( label.testPaintAttribute( QwtText::PaintBackground )
+                && label.backgroundBrush().style() != Qt::NoBrush )
+            {
+                if ( label.backgroundBrush().color().alpha() > 0 )
+                {
+                    // We don't need a text mask, when we have a background
+                    d_hasTextMask = false;
+                }
+            }
+        }
+
+        if ( d_hasTextMask )
+        {
+            QBitmap bm( width(), height() );
+            bm.fill( Qt::color0 );
+
+            QPainter painter( &bm );
+            painter.setFont( font() );
+
+            QPen pen = d_picker->trackerPen();
+            pen.setColor( Qt::color1 );
+            painter.setPen( pen );
+
+            d_picker->drawTracker( &painter );
+
+            mask = QRegion( bm );
+        }
+        else
+        {
+            mask = d_picker->trackerRect( font() );
+        }
+    }
+
+    QWidget *w = parentWidget();
+    if ( w && !w->testAttribute( Qt::WA_PaintOnScreen ) )
+    {
+        // The parent widget gets an update for its complete rectangle
+        // when the mask is changed in visible state.
+        // With this hide/show we only get an update for the
+        // previous mask.
+
+        hide();
+    }
+    setMask( mask );
+    setVisible( !mask.isEmpty() );
+}
+
+void QwtPicker::PickerWidget::paintEvent( QPaintEvent *e )
+{
+    QPainter painter( this );
+    painter.setClipRegion( e->region() );
+
+    if ( d_type == RubberBand )
+    {
+        painter.setPen( d_picker->rubberBandPen() );
+        d_picker->drawRubberBand( &painter );
+    }
+
+    if ( d_type == Text )
+    {
+        /*
+           If we have a text mask we simply fill the region of
+           the mask. This gives better results for antialiased fonts.
+         */
+        if ( d_hasTextMask )
+        {
+            painter.fillRect( e->rect(), 
+                QBrush( d_picker->trackerPen().color() ) );
+        }
+        else
+        {
+            painter.setPen( d_picker->trackerPen() );
+            d_picker->drawTracker( &painter );
+        }
+    }
+}
+
+/*!
+  Constructor
+
+  Creates an picker that is enabled, but without a state machine.
+  rubberband and tracker are disabled.
+
+  \param parent Parent widget, that will be observed
+ */
+
+QwtPicker::QwtPicker( QWidget *parent ):
+    QObject( parent )
+{
+    init( parent, NoRubberBand, AlwaysOff );
+}
+
+/*!
+  Constructor
+
+  \param rubberBand Rubberband style
+  \param trackerMode Tracker mode
+  \param parent Parent widget, that will be observed
+ */
+QwtPicker::QwtPicker( RubberBand rubberBand,
+        DisplayMode trackerMode, QWidget *parent ):
+    QObject( parent )
+{
+    init( parent, rubberBand, trackerMode );
+}
+
+//! Destructor
+QwtPicker::~QwtPicker()
+{
+    setMouseTracking( false );
+    delete d_data->stateMachine;
+    delete d_data->rubberBandWidget;
+    delete d_data->trackerWidget;
+    delete d_data;
+}
+
+//! Init the picker, used by the constructors
+void QwtPicker::init( QWidget *parent,
+    RubberBand rubberBand, DisplayMode trackerMode )
+{
+    d_data = new PrivateData;
+
+    d_data->rubberBandWidget = NULL;
+    d_data->trackerWidget = NULL;
+
+    d_data->rubberBand = rubberBand;
+    d_data->enabled = false;
+    d_data->resizeMode = Stretch;
+    d_data->trackerMode = AlwaysOff;
+    d_data->isActive = false;
+    d_data->trackerPosition = QPoint( -1, -1 );
+    d_data->mouseTracking = false;
+
+    d_data->stateMachine = NULL;
+
+    if ( parent )
+    {
+        if ( parent->focusPolicy() == Qt::NoFocus )
+            parent->setFocusPolicy( Qt::WheelFocus );
+
+        d_data->trackerFont = parent->font();
+        d_data->mouseTracking = parent->hasMouseTracking();
+        setEnabled( true );
+    }
+    setTrackerMode( trackerMode );
+}
+
+/*!
+  Set a state machine and delete the previous one
+
+  \param stateMachine State machine
+  \sa stateMachine()
+*/
+void QwtPicker::setStateMachine( QwtPickerMachine *stateMachine )
+{
+    if ( d_data->stateMachine != stateMachine )
+    {
+        reset();
+
+        delete d_data->stateMachine;
+        d_data->stateMachine = stateMachine;
+
+        if ( d_data->stateMachine )
+            d_data->stateMachine->reset();
+    }
+}
+
+/*!
+  \return Assigned state machine
+  \sa setStateMachine()
+*/
+QwtPickerMachine *QwtPicker::stateMachine()
+{
+    return d_data->stateMachine;
+}
+
+/*!
+  \return Assigned state machine
+  \sa setStateMachine()
+*/
+const QwtPickerMachine *QwtPicker::stateMachine() const
+{
+    return d_data->stateMachine;
+}
+
+//! Return the parent widget, where the selection happens
+QWidget *QwtPicker::parentWidget()
+{
+    QObject *obj = parent();
+    if ( obj && obj->isWidgetType() )
+        return static_cast<QWidget *>( obj );
+
+    return NULL;
+}
+
+//! Return the parent widget, where the selection happens
+const QWidget *QwtPicker::parentWidget() const
+{
+    QObject *obj = parent();
+    if ( obj && obj->isWidgetType() )
+        return static_cast< const QWidget *>( obj );
+
+    return NULL;
+}
+
+/*!
+  Set the rubberband style
+
+  \param rubberBand Rubberband style
+         The default value is NoRubberBand.
+
+  \sa rubberBand(), RubberBand, setRubberBandPen()
+*/
+void QwtPicker::setRubberBand( RubberBand rubberBand )
+{
+    d_data->rubberBand = rubberBand;
+}
+
+/*!
+  \return Rubberband style
+  \sa setRubberBand(), RubberBand, rubberBandPen()
+*/
+QwtPicker::RubberBand QwtPicker::rubberBand() const
+{
+    return d_data->rubberBand;
+}
+
+/*!
+  \brief Set the display mode of the tracker.
+
+  A tracker displays information about current position of
+  the cursor as a string. The display mode controls
+  if the tracker has to be displayed whenever the observed
+  widget has focus and cursor (AlwaysOn), never (AlwaysOff), or
+  only when the selection is active (ActiveOnly).
+
+  \param mode Tracker display mode
+
+  \warning In case of AlwaysOn, mouseTracking will be enabled
+           for the observed widget.
+  \sa trackerMode(), DisplayMode
+*/
+
+void QwtPicker::setTrackerMode( DisplayMode mode )
+{
+    if ( d_data->trackerMode != mode )
+    {
+        d_data->trackerMode = mode;
+        setMouseTracking( d_data->trackerMode == AlwaysOn );
+    }
+}
+
+/*!
+  \return Tracker display mode
+  \sa setTrackerMode(), DisplayMode
+*/
+QwtPicker::DisplayMode QwtPicker::trackerMode() const
+{
+    return d_data->trackerMode;
+}
+
+/*!
+  \brief Set the resize mode.
+
+  The resize mode controls what to do with the selected points of an active
+  selection when the observed widget is resized.
+
+  Stretch means the points are scaled according to the new
+  size, KeepSize means the points remain unchanged.
+
+  The default mode is Stretch.
+
+  \param mode Resize mode
+  \sa resizeMode(), ResizeMode
+*/
+void QwtPicker::setResizeMode( ResizeMode mode )
+{
+    d_data->resizeMode = mode;
+}
+
+/*!
+  \return Resize mode
+  \sa setResizeMode(), ResizeMode
+*/
+
+QwtPicker::ResizeMode QwtPicker::resizeMode() const
+{
+    return d_data->resizeMode;
+}
+
+/*!
+  \brief En/disable the picker
+
+  When enabled is true an event filter is installed for
+  the observed widget, otherwise the event filter is removed.
+
+  \param enabled true or false
+  \sa isEnabled(), eventFilter()
+*/
+void QwtPicker::setEnabled( bool enabled )
+{
+    if ( d_data->enabled != enabled )
+    {
+        d_data->enabled = enabled;
+
+        QWidget *w = parentWidget();
+        if ( w )
+        {
+            if ( enabled )
+                w->installEventFilter( this );
+            else
+                w->removeEventFilter( this );
+        }
+
+        updateDisplay();
+    }
+}
+
+/*!
+  \return true when enabled, false otherwise
+  \sa setEnabled(), eventFilter()
+*/
+
+bool QwtPicker::isEnabled() const
+{
+    return d_data->enabled;
+}
+
+/*!
+  Set the font for the tracker
+
+  \param font Tracker font
+  \sa trackerFont(), setTrackerMode(), setTrackerPen()
+*/
+void QwtPicker::setTrackerFont( const QFont &font )
+{
+    if ( font != d_data->trackerFont )
+    {
+        d_data->trackerFont = font;
+        updateDisplay();
+    }
+}
+
+/*!
+  \return Tracker font
+  \sa setTrackerFont(), trackerMode(), trackerPen()
+*/
+
+QFont QwtPicker::trackerFont() const
+{
+    return d_data->trackerFont;
+}
+
+/*!
+  Set the pen for the tracker
+
+  \param pen Tracker pen
+  \sa trackerPen(), setTrackerMode(), setTrackerFont()
+*/
+void QwtPicker::setTrackerPen( const QPen &pen )
+{
+    if ( pen != d_data->trackerPen )
+    {
+        d_data->trackerPen = pen;
+        updateDisplay();
+    }
+}
+
+/*!
+  \return Tracker pen
+  \sa setTrackerPen(), trackerMode(), trackerFont()
+*/
+QPen QwtPicker::trackerPen() const
+{
+    return d_data->trackerPen;
+}
+
+/*!
+  Set the pen for the rubberband
+
+  \param pen Rubberband pen
+  \sa rubberBandPen(), setRubberBand()
+*/
+void QwtPicker::setRubberBandPen( const QPen &pen )
+{
+    if ( pen != d_data->rubberBandPen )
+    {
+        d_data->rubberBandPen = pen;
+        updateDisplay();
+    }
+}
+
+/*!
+  \return Rubberband pen
+  \sa setRubberBandPen(), rubberBand()
+*/
+QPen QwtPicker::rubberBandPen() const
+{
+    return d_data->rubberBandPen;
+}
+
+/*!
+   \brief Return the label for a position
+
+   In case of HLineRubberBand the label is the value of the
+   y position, in case of VLineRubberBand the value of the x position.
+   Otherwise the label contains x and y position separated by a ',' .
+
+   The format for the string conversion is "%d".
+
+   \param pos Position
+   \return Converted position as string
+*/
+
+QwtText QwtPicker::trackerText( const QPoint &pos ) const
+{
+    QString label;
+
+    switch ( rubberBand() )
+    {
+        case HLineRubberBand:
+            label.sprintf( "%d", pos.y() );
+            break;
+        case VLineRubberBand:
+            label.sprintf( "%d", pos.x() );
+            break;
+        default:
+            label.sprintf( "%d, %d", pos.x(), pos.y() );
+    }
+    return label;
+}
+
+/*!
+   Draw a rubberband, depending on rubberBand()
+
+   \param painter Painter, initialized with clip rect
+
+   \sa rubberBand(), RubberBand
+*/
+
+void QwtPicker::drawRubberBand( QPainter *painter ) const
+{
+    if ( !isActive() || rubberBand() == NoRubberBand ||
+        rubberBandPen().style() == Qt::NoPen )
+    {
+        return;
+    }
+
+    const QRect &pRect = pickRect();
+    const QPolygon pa = adjustedPoints( d_data->pickedPoints );
+
+    QwtPickerMachine::SelectionType selectionType =
+        QwtPickerMachine::NoSelection;
+
+    if ( d_data->stateMachine )
+        selectionType = d_data->stateMachine->selectionType();
+
+    switch ( selectionType )
+    {
+        case QwtPickerMachine::NoSelection:
+        case QwtPickerMachine::PointSelection:
+        {
+            if ( pa.count() < 1 )
+                return;
+
+            const QPoint pos = pa[0];
+
+            switch ( rubberBand() )
+            {
+                case VLineRubberBand:
+                    QwtPainter::drawLine( painter, pos.x(),
+                        pRect.top(), pos.x(), pRect.bottom() );
+                    break;
+
+                case HLineRubberBand:
+                    QwtPainter::drawLine( painter, pRect.left(),
+                        pos.y(), pRect.right(), pos.y() );
+                    break;
+
+                case CrossRubberBand:
+                    QwtPainter::drawLine( painter, pos.x(),
+                        pRect.top(), pos.x(), pRect.bottom() );
+                    QwtPainter::drawLine( painter, pRect.left(),
+                        pos.y(), pRect.right(), pos.y() );
+                    break;
+                default:
+                    break;
+            }
+            break;
+        }
+        case QwtPickerMachine::RectSelection:
+        {
+            if ( pa.count() < 2 )
+                return;
+
+            const QPoint p1 = pa[0];
+            const QPoint p2 = pa[int( pa.count() - 1 )];
+
+            const QRect rect = QRect( p1, p2 ).normalized();
+            switch ( rubberBand() )
+            {
+                case EllipseRubberBand:
+                    QwtPainter::drawEllipse( painter, rect );
+                    break;
+                case RectRubberBand:
+                    QwtPainter::drawRect( painter, rect );
+                    break;
+                default:
+                    break;
+            }
+            break;
+        }
+        case QwtPickerMachine::PolygonSelection:
+        {
+            if ( rubberBand() == PolygonRubberBand )
+                painter->drawPolyline( pa );
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+/*!
+   Draw the tracker
+
+   \param painter Painter
+   \sa trackerRect(), trackerText()
+*/
+
+void QwtPicker::drawTracker( QPainter *painter ) const
+{
+    const QRect textRect = trackerRect( painter->font() );
+    if ( !textRect.isEmpty() )
+    {
+        const QwtText label = trackerText( d_data->trackerPosition );
+        if ( !label.isEmpty() )
+            label.draw( painter, textRect );
+    }
+}
+
+/*!
+   \brief Map the pickedPoints() into a selection()
+
+   adjustedPoints() maps the points, that have been collected on
+   the parentWidget() into a selection(). The default implementation
+   simply returns the points unmodified.
+
+   The reason, why a selection() differs from the picked points
+   depends on the application requirements. F.e. :
+
+   - A rectangular selection might need to have a specific aspect ratio only.\n
+   - A selection could accept non intersecting polygons only.\n
+   - ...\n
+
+   The example below is for a rectangular selection, where the first
+   point is the center of the selected rectangle.
+  \par Example
+  \verbatim QPolygon MyPicker::adjustedPoints(const QPolygon &points) const
+{
+    QPolygon adjusted;
+    if ( points.size() == 2 )
+    {
+        const int width = qAbs(points[1].x() - points[0].x());
+        const int height = qAbs(points[1].y() - points[0].y());
+
+        QRect rect(0, 0, 2 * width, 2 * height);
+        rect.moveCenter(points[0]);
+
+        adjusted += rect.topLeft();
+        adjusted += rect.bottomRight();
+    }
+    return adjusted;
+}\endverbatim\n
+*/
+QPolygon QwtPicker::adjustedPoints( const QPolygon &points ) const
+{
+    return points;
+}
+
+/*!
+  \return Selected points
+  \sa pickedPoints(), adjustedPoints()
+*/
+QPolygon QwtPicker::selection() const
+{
+    return adjustedPoints( d_data->pickedPoints );
+}
+
+//! \return Current position of the tracker
+QPoint QwtPicker::trackerPosition() const
+{
+    return d_data->trackerPosition;
+}
+
+/*!
+   Calculate the bounding rectangle for the tracker text
+   from the current position of the tracker
+
+   \param font Font of the tracker text
+   \return Bounding rectangle of the tracker text
+
+   \sa trackerPosition()
+*/
+QRect QwtPicker::trackerRect( const QFont &font ) const
+{
+    if ( trackerMode() == AlwaysOff ||
+        ( trackerMode() == ActiveOnly && !isActive() ) )
+    {
+        return QRect();
+    }
+
+    if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
+        return QRect();
+
+    QwtText text = trackerText( d_data->trackerPosition );
+    if ( text.isEmpty() )
+        return QRect();
+
+    const QSizeF textSize = text.textSize( font );
+    QRect textRect( 0, 0, qCeil( textSize.width() ), qCeil( textSize.height() ) );
+
+    const QPoint &pos = d_data->trackerPosition;
+
+    int alignment = 0;
+    if ( isActive() && d_data->pickedPoints.count() > 1
+        && rubberBand() != NoRubberBand )
+    {
+        const QPoint last =
+            d_data->pickedPoints[int( d_data->pickedPoints.count() ) - 2];
+
+        alignment |= ( pos.x() >= last.x() ) ? Qt::AlignRight : Qt::AlignLeft;
+        alignment |= ( pos.y() > last.y() ) ? Qt::AlignBottom : Qt::AlignTop;
+    }
+    else
+        alignment = Qt::AlignTop | Qt::AlignRight;
+
+    const int margin = 5;
+
+    int x = pos.x();
+    if ( alignment & Qt::AlignLeft )
+        x -= textRect.width() + margin;
+    else if ( alignment & Qt::AlignRight )
+        x += margin;
+
+    int y = pos.y();
+    if ( alignment & Qt::AlignBottom )
+        y += margin;
+    else if ( alignment & Qt::AlignTop )
+        y -= textRect.height() + margin;
+
+    textRect.moveTopLeft( QPoint( x, y ) );
+
+    int right = qMin( textRect.right(), pickRect().right() - margin );
+    int bottom = qMin( textRect.bottom(), pickRect().bottom() - margin );
+    textRect.moveBottomRight( QPoint( right, bottom ) );
+
+    int left = qMax( textRect.left(), pickRect().left() + margin );
+    int top = qMax( textRect.top(), pickRect().top() + margin );
+    textRect.moveTopLeft( QPoint( left, top ) );
+
+    return textRect;
+}
+
+/*!
+  \brief Event filter
+
+  When isEnabled() == true all events of the observed widget are filtered.
+  Mouse and keyboard events are translated into widgetMouse- and widgetKey-
+  and widgetWheel-events. Paint and Resize events are handled to keep
+  rubberband and tracker up to date.
+
+  \param object Object to be filtered
+  \param event Event
+
+  \sa widgetEnterEvent(), widgetLeaveEvent(),
+      widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
+      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent(),
+      QObject::installEventFilter(), QObject::event()
+*/
+bool QwtPicker::eventFilter( QObject *object, QEvent *event )
+{
+    if ( object && object == parentWidget() )
+    {
+        switch ( event->type() )
+        {
+            case QEvent::Resize:
+            {
+                const QResizeEvent *re = ( QResizeEvent * )event;
+                if ( d_data->resizeMode == Stretch )
+                    stretchSelection( re->oldSize(), re->size() );
+
+                if ( d_data->rubberBandWidget )
+                    d_data->rubberBandWidget->resize( re->size() );
+
+                if ( d_data->trackerWidget )
+                    d_data->trackerWidget->resize( re->size() );
+                break;
+            }
+            case QEvent::Enter:
+                widgetEnterEvent( event );
+                break;
+            case QEvent::Leave:
+                widgetLeaveEvent( event );
+                break;
+            case QEvent::MouseButtonPress:
+                widgetMousePressEvent( ( QMouseEvent * )event );
+                break;
+            case QEvent::MouseButtonRelease:
+                widgetMouseReleaseEvent( ( QMouseEvent * )event );
+                break;
+            case QEvent::MouseButtonDblClick:
+                widgetMouseDoubleClickEvent( ( QMouseEvent * )event );
+                break;
+            case QEvent::MouseMove:
+                widgetMouseMoveEvent( ( QMouseEvent * )event );
+                break;
+            case QEvent::KeyPress:
+                widgetKeyPressEvent( ( QKeyEvent * )event );
+                break;
+            case QEvent::KeyRelease:
+                widgetKeyReleaseEvent( ( QKeyEvent * )event );
+                break;
+            case QEvent::Wheel:
+                widgetWheelEvent( ( QWheelEvent * )event );
+                break;
+            default:
+                break;
+        }
+    }
+    return false;
+}
+
+/*!
+  Handle a mouse press event for the observed widget.
+
+  \param mouseEvent Mouse event
+
+  \sa eventFilter(), widgetMouseReleaseEvent(),
+      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
+      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+*/
+void QwtPicker::widgetMousePressEvent( QMouseEvent *mouseEvent )
+{
+    transition( mouseEvent );
+}
+
+/*!
+  Handle a mouse move event for the observed widget.
+
+  \param mouseEvent Mouse event
+
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseDoubleClickEvent(),
+      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+*/
+void QwtPicker::widgetMouseMoveEvent( QMouseEvent *mouseEvent )
+{
+    if ( pickRect().contains( mouseEvent->pos() ) )
+        d_data->trackerPosition = mouseEvent->pos();
+    else
+        d_data->trackerPosition = QPoint( -1, -1 );
+
+    if ( !isActive() )
+        updateDisplay();
+
+    transition( mouseEvent );
+}
+
+/*!
+  Handle a enter event for the observed widget.
+
+  \param event Qt event
+
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseDoubleClickEvent(),
+      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+*/
+void QwtPicker::widgetEnterEvent( QEvent *event )
+{
+    transition( event );
+}
+
+/*!
+  Handle a leave event for the observed widget.
+
+  \param event Qt event
+
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseDoubleClickEvent(),
+      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+*/
+void QwtPicker::widgetLeaveEvent( QEvent *event )
+{
+    transition( event );
+
+    d_data->trackerPosition = QPoint( -1, -1 );
+    if ( !isActive() )
+        updateDisplay();
+}
+
+/*!
+  Handle a mouse relase event for the observed widget.
+
+  \param mouseEvent Mouse event
+
+  \sa eventFilter(), widgetMousePressEvent(),
+      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
+      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+*/
+void QwtPicker::widgetMouseReleaseEvent( QMouseEvent *mouseEvent )
+{
+    transition( mouseEvent );
+}
+
+/*!
+  Handle mouse double click event for the observed widget.
+
+  \param mouseEvent Mouse event
+
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseMoveEvent(),
+      widgetWheelEvent(), widgetKeyPressEvent(), widgetKeyReleaseEvent()
+*/
+void QwtPicker::widgetMouseDoubleClickEvent( QMouseEvent *mouseEvent )
+{
+    transition( mouseEvent );
+}
+
+
+/*!
+  Handle a wheel event for the observed widget.
+
+  Move the last point of the selection in case of isActive() == true
+
+  \param wheelEvent Wheel event
+
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
+      widgetKeyPressEvent(), widgetKeyReleaseEvent()
+*/
+void QwtPicker::widgetWheelEvent( QWheelEvent *wheelEvent )
+{
+    if ( pickRect().contains( wheelEvent->pos() ) )
+        d_data->trackerPosition = wheelEvent->pos();
+    else
+        d_data->trackerPosition = QPoint( -1, -1 );
+
+    updateDisplay();
+
+    transition( wheelEvent );
+}
+
+/*!
+  Handle a key press event for the observed widget.
+
+  Selections can be completely done by the keyboard. The arrow keys
+  move the cursor, the abort key aborts a selection. All other keys
+  are handled by the current state machine.
+
+  \param keyEvent Key event
+
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
+      widgetWheelEvent(), widgetKeyReleaseEvent(), stateMachine(),
+      QwtEventPattern::KeyPatternCode
+*/
+void QwtPicker::widgetKeyPressEvent( QKeyEvent *keyEvent )
+{
+    int dx = 0;
+    int dy = 0;
+
+    int offset = 1;
+    if ( keyEvent->isAutoRepeat() )
+        offset = 5;
+
+    if ( keyMatch( KeyLeft, keyEvent ) )
+        dx = -offset;
+    else if ( keyMatch( KeyRight, keyEvent ) )
+        dx = offset;
+    else if ( keyMatch( KeyUp, keyEvent ) )
+        dy = -offset;
+    else if ( keyMatch( KeyDown, keyEvent ) )
+        dy = offset;
+    else if ( keyMatch( KeyAbort, keyEvent ) )
+    {
+        reset();
+    }
+    else
+        transition( keyEvent );
+
+    if ( dx != 0 || dy != 0 )
+    {
+        const QRect rect = pickRect();
+        const QPoint pos = parentWidget()->mapFromGlobal( QCursor::pos() );
+
+        int x = pos.x() + dx;
+        x = qMax( rect.left(), x );
+        x = qMin( rect.right(), x );
+
+        int y = pos.y() + dy;
+        y = qMax( rect.top(), y );
+        y = qMin( rect.bottom(), y );
+
+        QCursor::setPos( parentWidget()->mapToGlobal( QPoint( x, y ) ) );
+    }
+}
+
+/*!
+  Handle a key release event for the observed widget.
+
+  Passes the event to the state machine.
+
+  \param keyEvent Key event
+
+  \sa eventFilter(), widgetMousePressEvent(), widgetMouseReleaseEvent(),
+      widgetMouseDoubleClickEvent(), widgetMouseMoveEvent(),
+      widgetWheelEvent(), widgetKeyPressEvent(), stateMachine()
+*/
+void QwtPicker::widgetKeyReleaseEvent( QKeyEvent *keyEvent )
+{
+    transition( keyEvent );
+}
+
+/*!
+  Passes an event to the state machine and executes the resulting
+  commands. Append and Move commands use the current position
+  of the cursor (QCursor::pos()).
+
+  \param event Event
+*/
+void QwtPicker::transition( const QEvent *event )
+{
+    if ( !d_data->stateMachine )
+        return;
+
+    const QList<QwtPickerMachine::Command> commandList =
+        d_data->stateMachine->transition( *this, event );
+
+    QPoint pos;
+    switch ( event->type() )
+    {
+        case QEvent::MouseButtonDblClick:
+        case QEvent::MouseButtonPress:
+        case QEvent::MouseButtonRelease:
+        case QEvent::MouseMove:
+        {
+            const QMouseEvent *me = 
+                static_cast< const QMouseEvent * >( event );
+            pos = me->pos();
+            break;
+        }
+        default:
+            pos = parentWidget()->mapFromGlobal( QCursor::pos() );
+    }
+
+    for ( int i = 0; i < commandList.count(); i++ )
+    {
+        switch ( commandList[i] )
+        {
+            case QwtPickerMachine::Begin:
+            {
+                begin();
+                break;
+            }
+            case QwtPickerMachine::Append:
+            {
+                append( pos );
+                break;
+            }
+            case QwtPickerMachine::Move:
+            {
+                move( pos );
+                break;
+            }
+            case QwtPickerMachine::Remove:
+            {
+                remove();
+                break;
+            }
+            case QwtPickerMachine::End:
+            {
+                end();
+                break;
+            }
+        }
+    }
+}
+
+/*!
+  Open a selection setting the state to active
+
+  \sa isActive(), end(), append(), move()
+*/
+void QwtPicker::begin()
+{
+    if ( d_data->isActive )
+        return;
+
+    d_data->pickedPoints.resize( 0 );
+    d_data->isActive = true;
+    Q_EMIT activated( true );
+
+    if ( trackerMode() != AlwaysOff )
+    {
+        if ( d_data->trackerPosition.x() < 0 || d_data->trackerPosition.y() < 0 )
+        {
+            QWidget *w = parentWidget();
+            if ( w )
+                d_data->trackerPosition = w->mapFromGlobal( QCursor::pos() );
+        }
+    }
+
+    updateDisplay();
+    setMouseTracking( true );
+}
+
+/*!
+  \brief Close a selection setting the state to inactive.
+
+  The selection is validated and maybe fixed by accept().
+
+  \param ok If true, complete the selection and emit a selected signal
+            otherwise discard the selection.
+  \return true if the selection is accepted, false otherwise
+  \sa isActive(), begin(), append(), move(), selected(), accept()
+*/
+bool QwtPicker::end( bool ok )
+{
+    if ( d_data->isActive )
+    {
+        setMouseTracking( false );
+
+        d_data->isActive = false;
+        Q_EMIT activated( false );
+
+        if ( trackerMode() == ActiveOnly )
+            d_data->trackerPosition = QPoint( -1, -1 );
+
+        if ( ok )
+            ok = accept( d_data->pickedPoints );
+
+        if ( ok )
+            Q_EMIT selected( d_data->pickedPoints );
+        else
+            d_data->pickedPoints.resize( 0 );
+
+        updateDisplay();
+    }
+    else
+        ok = false;
+
+    return ok;
+}
+
+/*!
+   Reset the state machine and terminate (end(false)) the selection
+*/
+void QwtPicker::reset()
+{
+    if ( d_data->stateMachine )
+        d_data->stateMachine->reset();
+
+    if ( isActive() )
+        end( false );
+}
+
+/*!
+  Append a point to the selection and update rubberband and tracker.
+  The appended() signal is emitted.
+
+  \param pos Additional point
+
+  \sa isActive(), begin(), end(), move(), appended()
+*/
+void QwtPicker::append( const QPoint &pos )
+{
+    if ( d_data->isActive )
+    {
+        const int idx = d_data->pickedPoints.count();
+        d_data->pickedPoints.resize( idx + 1 );
+        d_data->pickedPoints[idx] = pos;
+
+        updateDisplay();
+        Q_EMIT appended( pos );
+    }
+}
+
+/*!
+  Move the last point of the selection
+  The moved() signal is emitted.
+
+  \param pos New position
+  \sa isActive(), begin(), end(), append()
+*/
+void QwtPicker::move( const QPoint &pos )
+{
+    if ( d_data->isActive )
+    {
+        const int idx = d_data->pickedPoints.count() - 1;
+        if ( idx >= 0 )
+        {
+            if ( d_data->pickedPoints[idx] != pos )
+            {
+                d_data->pickedPoints[idx] = pos;
+
+                updateDisplay();
+                Q_EMIT moved( pos );
+            }
+        }
+    }
+}
+
+/*!
+  Remove the last point of the selection
+  The removed() signal is emitted.
+
+  \sa isActive(), begin(), end(), append(), move()
+*/
+void QwtPicker::remove()
+{
+    if ( d_data->isActive )
+    {
+        const int idx = d_data->pickedPoints.count() - 1;
+        if ( idx > 0 )
+        {
+            const int idx = d_data->pickedPoints.count();
+
+            const QPoint pos = d_data->pickedPoints[idx - 1];
+            d_data->pickedPoints.resize( idx - 1 );
+
+            updateDisplay();
+            Q_EMIT removed( pos );
+        }
+    }
+}
+
+/*!
+  \brief Validate and fixup the selection
+
+  Accepts all selections unmodified
+
+  \param selection Selection to validate and fixup
+  \return true, when accepted, false otherwise
+*/
+bool QwtPicker::accept( QPolygon &selection ) const
+{
+    Q_UNUSED( selection );
+    return true;
+}
+
+/*!
+  A picker is active between begin() and end().
+  \return true if the selection is active.
+*/
+bool QwtPicker::isActive() const
+{
+    return d_data->isActive;
+}
+
+/*!
+  Return the points, that have been collected so far. The selection()
+  is calculated from the pickedPoints() in adjustedPoints().
+  \return Picked points
+*/
+const QPolygon &QwtPicker::pickedPoints() const
+{
+    return d_data->pickedPoints;
+}
+
+/*!
+  Scale the selection by the ratios of oldSize and newSize
+  The changed() signal is emitted.
+
+  \param oldSize Previous size
+  \param newSize Current size
+
+  \sa ResizeMode, setResizeMode(), resizeMode()
+*/
+void QwtPicker::stretchSelection( const QSize &oldSize, const QSize &newSize )
+{
+    if ( oldSize.isEmpty() )
+    {
+        // avoid division by zero. But scaling for small sizes also
+        // doesn't make much sense, because of rounding losses. TODO ...
+        return;
+    }
+
+    const double xRatio =
+        double( newSize.width() ) / double( oldSize.width() );
+    const double yRatio =
+        double( newSize.height() ) / double( oldSize.height() );
+
+    for ( int i = 0; i < int( d_data->pickedPoints.count() ); i++ )
+    {
+        QPoint &p = d_data->pickedPoints[i];
+        p.setX( qRound( p.x() * xRatio ) );
+        p.setY( qRound( p.y() * yRatio ) );
+
+        Q_EMIT changed( d_data->pickedPoints );
+    }
+}
+
+/*!
+  Set mouse tracking for the observed widget.
+
+  In case of enable is true, the previous value
+  is saved, that is restored when enable is false.
+
+  \warning Even when enable is false, mouse tracking might be restored
+           to true. When mouseTracking for the observed widget
+           has been changed directly by QWidget::setMouseTracking
+           while mouse tracking has been set to true, this value can't
+           be restored.
+*/
+
+void QwtPicker::setMouseTracking( bool enable )
+{
+    QWidget *widget = parentWidget();
+    if ( !widget )
+        return;
+
+    if ( enable )
+    {
+        d_data->mouseTracking = widget->hasMouseTracking();
+        widget->setMouseTracking( true );
+    }
+    else
+    {
+        widget->setMouseTracking( d_data->mouseTracking );
+    }
+}
+
+/*!
+  Find the area of the observed widget, where selection might happen.
+
+  \return parentWidget()->contentsRect() 
+*/
+QRect QwtPicker::pickRect() const
+{
+    const QWidget *widget = parentWidget();
+    if ( widget )
+        return widget->contentsRect();
+
+    return QRect();
+}
+
+//! Update the state of rubberband and tracker label
+void QwtPicker::updateDisplay()
+{
+    QWidget *w = parentWidget();
+
+    bool showRubberband = false;
+    bool showTracker = false;
+    if ( w && w->isVisible() && d_data->enabled )
+    {
+        if ( rubberBand() != NoRubberBand && isActive() &&
+            rubberBandPen().style() != Qt::NoPen )
+        {
+            showRubberband = true;
+        }
+
+        if ( trackerMode() == AlwaysOn ||
+            ( trackerMode() == ActiveOnly && isActive() ) )
+        {
+            if ( trackerPen() != Qt::NoPen )
+                showTracker = true;
+        }
+    }
+
+    QPointer<PickerWidget> &rw = d_data->rubberBandWidget;
+    if ( showRubberband )
+    {
+        if ( rw.isNull() )
+        {
+            rw = new PickerWidget( this, w, PickerWidget::RubberBand );
+            rw->resize( w->size() );
+        }
+        rw->updateMask();
+        rw->update(); // Needed, when the mask doesn't change
+    }
+    else
+        delete rw;
+
+    QPointer<PickerWidget> &tw = d_data->trackerWidget;
+    if ( showTracker )
+    {
+        if ( tw.isNull() )
+        {
+            tw = new PickerWidget( this, w, PickerWidget::Text );
+            tw->resize( w->size() );
+        }
+        tw->setFont( d_data->trackerFont );
+        tw->updateMask();
+        tw->update(); // Needed, when the mask doesn't change
+    }
+    else
+        delete tw;
+}
+
+//! \return Widget displaying the rubberband
+const QWidget *QwtPicker::rubberBandWidget() const
+{
+    return d_data->rubberBandWidget;
+}
+
+//! \return Widget displaying the tracker text
+const QWidget *QwtPicker::trackerWidget() const
+{
+    return d_data->trackerWidget;
+}
+
Index: trunk/BNC/qwt/qwt_picker.h
===================================================================
--- trunk/BNC/qwt/qwt_picker.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_picker.h	(revision 4271)
@@ -0,0 +1,327 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PICKER
+#define QWT_PICKER 1
+
+#include "qwt_global.h"
+#include "qwt_text.h"
+#include "qwt_event_pattern.h"
+#include <qobject.h>
+#include <qpen.h>
+#include <qfont.h>
+#include <qrect.h>
+
+class QWidget;
+class QMouseEvent;
+class QWheelEvent;
+class QKeyEvent;
+class QwtPickerMachine;
+
+/*!
+  \brief QwtPicker provides selections on a widget
+
+  QwtPicker filters all enter, leave, mouse and keyboard events of a widget
+  and translates them into an array of selected points.
+
+  The way how the points are collected depends on type of state machine
+  that is connected to the picker. Qwt offers a couple of predefined
+  state machines for selecting:
+
+  - Nothing\n
+    QwtPickerTrackerMachine
+  - Single points\n
+    QwtPickerClickPointMachine, QwtPickerDragPointMachine
+  - Rectangles\n
+    QwtPickerClickRectMachine, QwtPickerDragRectMachine
+  - Polygons\n
+    QwtPickerPolygonMachine
+
+  While these state machines cover the most common ways to collect points
+  it is also possible to implement individual machines as well.
+
+  QwtPicker translates the picked points into a selection using the
+  adjustedPoints method. adjustedPoints is intended to be reimplemented
+  to fixup the selection according to application specific requirements.
+  (F.e. when an application accepts rectangles of a fixed aspect ratio only.)
+
+  Optionally QwtPicker support the process of collecting points by a
+  rubberband and tracker displaying a text for the current mouse
+  position.
+
+  \par Example
+  \verbatim #include <qwt_picker.h>
+#include <qwt_picker_machine.h>
+
+QwtPicker *picker = new QwtPicker(widget);
+picker->setStateMachine(new QwtPickerDragRectMachine);
+picker->setTrackerMode(QwtPicker::ActiveOnly);
+picker->setRubberBand(QwtPicker::RectRubberBand); \endverbatim\n
+
+  The state machine triggers the following commands:
+
+  - begin()\n
+    Activate/Initialize the selection.
+  - append()\n
+    Add a new point
+  - move() \n
+    Change the position of the last point.
+  - remove()\n
+    Remove the last point.
+  - end()\n
+    Terminate the selection and call accept to validate the picked points.
+
+  The picker is active (isActive()), between begin() and end().
+  In active state the rubberband is displayed, and the tracker is visible
+  in case of trackerMode is ActiveOnly or AlwaysOn.
+
+  The cursor can be moved using the arrow keys. All selections can be aborted
+  using the abort key. (QwtEventPattern::KeyPatternCode)
+
+  \warning In case of QWidget::NoFocus the focus policy of the observed
+           widget is set to QWidget::WheelFocus and mouse tracking
+           will be manipulated while the picker is active,
+           or if trackerMode() is AlwayOn.
+*/
+
+class QWT_EXPORT QwtPicker: public QObject, public QwtEventPattern
+{
+    Q_OBJECT
+
+    Q_ENUMS( RubberBand )
+    Q_ENUMS( DisplayMode )
+    Q_ENUMS( ResizeMode )
+
+    Q_PROPERTY( bool isEnabled READ isEnabled WRITE setEnabled )
+    Q_PROPERTY( ResizeMode resizeMode READ resizeMode WRITE setResizeMode )
+
+    Q_PROPERTY( DisplayMode trackerMode READ trackerMode WRITE setTrackerMode )
+    Q_PROPERTY( QPen trackerPen READ trackerPen WRITE setTrackerPen )
+    Q_PROPERTY( QFont trackerFont READ trackerFont WRITE setTrackerFont )
+
+    Q_PROPERTY( RubberBand rubberBand READ rubberBand WRITE setRubberBand )
+    Q_PROPERTY( QPen rubberBandPen READ rubberBandPen WRITE setRubberBandPen )
+
+public:
+    /*!
+      Rubberband style
+
+      The default value is QwtPicker::NoRubberBand.
+      \sa setRubberBand(), rubberBand()
+    */
+
+    enum RubberBand
+    {
+        //! No rubberband.
+        NoRubberBand = 0,
+
+        //! A horizontal line ( only for QwtPicker::PointSelection )
+        HLineRubberBand,
+
+        //! A vertical line ( only for QwtPicker::PointSelection )
+        VLineRubberBand,
+
+        //! A crosshair ( only for QwtPicker::PointSelection )
+        CrossRubberBand,
+
+        //! A rectangle ( only for QwtPicker::RectSelection )
+        RectRubberBand,
+
+        //! An ellipse ( only for QwtPicker::RectSelection )
+        EllipseRubberBand,
+
+        //! A polygon ( only for QwtPicker::&PolygonSelection )
+        PolygonRubberBand,
+
+        /*!
+          Values >= UserRubberBand can be used to define additional
+          rubber bands.
+         */
+        UserRubberBand = 100
+    };
+
+    /*!
+      \brief Display mode
+      \sa setTrackerMode(), trackerMode(), isActive()
+    */
+    enum DisplayMode
+    {
+        //! Display never
+        AlwaysOff,
+
+        //! Display always
+        AlwaysOn,
+
+        //! Display only when the selection is active
+        ActiveOnly
+    };
+
+    /*!
+      Controls what to do with the selected points of an active
+         selection when the observed widget is resized.
+
+      The default value is QwtPicker::Stretch.
+      \sa setResizeMode()
+    */
+
+    enum ResizeMode
+    {
+        //! All points are scaled according to the new size,
+        Stretch,
+
+        //! All points remain unchanged.
+        KeepSize
+    };
+
+    explicit QwtPicker( QWidget *parent );
+    explicit QwtPicker( RubberBand rubberBand,
+                        DisplayMode trackerMode, QWidget * );
+
+    virtual ~QwtPicker();
+
+    void setStateMachine( QwtPickerMachine * );
+    const QwtPickerMachine *stateMachine() const;
+    QwtPickerMachine *stateMachine();
+
+    void setRubberBand( RubberBand );
+    RubberBand rubberBand() const;
+
+    void setTrackerMode( DisplayMode );
+    DisplayMode trackerMode() const;
+
+    void setResizeMode( ResizeMode );
+    ResizeMode resizeMode() const;
+
+    void setRubberBandPen( const QPen & );
+    QPen rubberBandPen() const;
+
+    void setTrackerPen( const QPen & );
+    QPen trackerPen() const;
+
+    void setTrackerFont( const QFont & );
+    QFont trackerFont() const;
+
+    bool isEnabled() const;
+    bool isActive() const;
+
+    virtual bool eventFilter( QObject *, QEvent * );
+
+    QWidget *parentWidget();
+    const QWidget *parentWidget() const;
+
+    virtual QRect pickRect() const;
+
+    virtual void drawRubberBand( QPainter * ) const;
+    virtual void drawTracker( QPainter * ) const;
+
+    virtual QwtText trackerText( const QPoint &pos ) const;
+    QPoint trackerPosition() const;
+    virtual QRect trackerRect( const QFont & ) const;
+
+    QPolygon selection() const;
+
+public Q_SLOTS:
+    void setEnabled( bool );
+
+Q_SIGNALS:
+    /*!
+      A signal indicating, when the picker has been activated.
+      Together with setEnabled() it can be used to implement
+      selections with more than one picker.
+
+      \param on True, when the picker has been activated
+    */
+    void activated( bool on );
+
+    /*!
+      A signal emitting the selected points,
+      at the end of a selection.
+
+      \param polygon Selected points
+    */
+    void selected( const QPolygon &polygon );
+
+    /*!
+      A signal emitted when a point has been appended to the selection
+
+      \param pos Position of the appended point.
+      \sa append(). moved()
+    */
+    void appended( const QPoint &pos );
+
+    /*!
+      A signal emitted whenever the last appended point of the
+      selection has been moved.
+
+      \param pos Position of the moved last point of the selection.
+      \sa move(), appended()
+    */
+    void moved( const QPoint &pos );
+
+    /*!
+      A signal emitted whenever the last appended point of the
+      selection has been removed.
+
+      \sa remove(), appended()
+    */
+    void removed( const QPoint &pos );
+    /*!
+      A signal emitted when the active selection has been changed.
+      This might happen when the observed widget is resized.
+
+      \param selection Changed selection
+      \sa stretchSelection()
+    */
+    void changed( const QPolygon &selection );
+
+protected:
+    virtual QPolygon adjustedPoints( const QPolygon & ) const;
+
+    virtual void transition( const QEvent * );
+
+    virtual void begin();
+    virtual void append( const QPoint & );
+    virtual void move( const QPoint & );
+    virtual void remove();
+    virtual bool end( bool ok = true );
+
+    virtual bool accept( QPolygon & ) const;
+    virtual void reset();
+
+    virtual void widgetMousePressEvent( QMouseEvent * );
+    virtual void widgetMouseReleaseEvent( QMouseEvent * );
+    virtual void widgetMouseDoubleClickEvent( QMouseEvent * );
+    virtual void widgetMouseMoveEvent( QMouseEvent * );
+    virtual void widgetWheelEvent( QWheelEvent * );
+    virtual void widgetKeyPressEvent( QKeyEvent * );
+    virtual void widgetKeyReleaseEvent( QKeyEvent * );
+    virtual void widgetEnterEvent( QEvent * );
+    virtual void widgetLeaveEvent( QEvent * );
+
+    virtual void stretchSelection( const QSize &oldSize,
+                                   const QSize &newSize );
+
+    virtual void updateDisplay();
+
+    const QWidget *rubberBandWidget() const;
+    const QWidget *trackerWidget() const;
+
+    const QPolygon &pickedPoints() const;
+
+private:
+    void init( QWidget *, RubberBand rubberBand, DisplayMode trackerMode );
+
+    void setMouseTracking( bool );
+
+    class PickerWidget;
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_picker_machine.cpp
===================================================================
--- trunk/BNC/qwt/qwt_picker_machine.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_picker_machine.cpp	(revision 4271)
@@ -0,0 +1,450 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_picker_machine.h"
+#include "qwt_event_pattern.h"
+#include <qevent.h>
+
+//! Constructor
+QwtPickerMachine::QwtPickerMachine( SelectionType type ):
+    d_selectionType( type ),
+    d_state( 0 )
+{
+}
+
+//! Destructor
+QwtPickerMachine::~QwtPickerMachine()
+{
+}
+
+//! Return the selection type
+QwtPickerMachine::SelectionType QwtPickerMachine::selectionType() const
+{
+    return d_selectionType;
+}
+
+//! Return the current state
+int QwtPickerMachine::state() const
+{
+    return d_state;
+}
+
+//! Change the current state
+void QwtPickerMachine::setState( int state )
+{
+    d_state = state;
+}
+
+//! Set the current state to 0.
+void QwtPickerMachine::reset()
+{
+    setState( 0 );
+}
+
+//! Constructor
+QwtPickerTrackerMachine::QwtPickerTrackerMachine():
+    QwtPickerMachine( NoSelection )
+{
+}
+
+//! Transition
+QList<QwtPickerMachine::Command> QwtPickerTrackerMachine::transition(
+    const QwtEventPattern &, const QEvent *e )
+{
+    QList<QwtPickerMachine::Command> cmdList;
+
+    switch ( e->type() )
+    {
+        case QEvent::Enter:
+        case QEvent::MouseMove:
+        {
+            if ( state() == 0 )
+            {
+                cmdList += Begin;
+                cmdList += Append;
+                setState( 1 );
+            }
+            else
+            {
+                cmdList += Move;
+            }
+            break;
+        }
+        case QEvent::Leave:
+        {
+            cmdList += Remove;
+            cmdList += End;
+            setState( 0 );
+        }
+        default:
+            break;
+    }
+
+    return cmdList;
+}
+
+//! Constructor
+QwtPickerClickPointMachine::QwtPickerClickPointMachine():
+    QwtPickerMachine( PointSelection )
+{
+}
+
+//! Transition
+QList<QwtPickerMachine::Command> QwtPickerClickPointMachine::transition(
+    const QwtEventPattern &eventPattern, const QEvent *e )
+{
+    QList<QwtPickerMachine::Command> cmdList;
+
+    switch ( e->type() )
+    {
+        case QEvent::MouseButtonPress:
+        {
+            if ( eventPattern.mouseMatch(
+                QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
+            {
+                cmdList += Begin;
+                cmdList += Append;
+                cmdList += End;
+            }
+            break;
+        }
+        case QEvent::KeyPress:
+        {
+            if ( eventPattern.keyMatch(
+                QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
+            {
+                cmdList += Begin;
+                cmdList += Append;
+                cmdList += End;
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    return cmdList;
+}
+
+//! Constructor
+QwtPickerDragPointMachine::QwtPickerDragPointMachine():
+    QwtPickerMachine( PointSelection )
+{
+}
+
+//! Transition
+QList<QwtPickerMachine::Command> QwtPickerDragPointMachine::transition(
+    const QwtEventPattern &eventPattern, const QEvent *e )
+{
+    QList<QwtPickerMachine::Command> cmdList;
+
+    switch ( e->type() )
+    {
+        case QEvent::MouseButtonPress:
+        {
+            if ( eventPattern.mouseMatch(
+                QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
+            {
+                if ( state() == 0 )
+                {
+                    cmdList += Begin;
+                    cmdList += Append;
+                    setState( 1 );
+                }
+            }
+            break;
+        }
+        case QEvent::MouseMove:
+        case QEvent::Wheel:
+        {
+            if ( state() != 0 )
+                cmdList += Move;
+            break;
+        }
+        case QEvent::MouseButtonRelease:
+        {
+            if ( state() != 0 )
+            {
+                cmdList += End;
+                setState( 0 );
+            }
+            break;
+        }
+        case QEvent::KeyPress:
+        {
+            if ( eventPattern.keyMatch(
+                QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
+            {
+                if ( state() == 0 )
+                {
+                    cmdList += Begin;
+                    cmdList += Append;
+                    setState( 1 );
+                }
+                else
+                {
+                    cmdList += End;
+                    setState( 0 );
+                }
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    return cmdList;
+}
+
+//! Constructor
+QwtPickerClickRectMachine::QwtPickerClickRectMachine():
+    QwtPickerMachine( RectSelection )
+{
+}
+
+//! Transition
+QList<QwtPickerMachine::Command> QwtPickerClickRectMachine::transition(
+    const QwtEventPattern &eventPattern, const QEvent *e )
+{
+    QList<QwtPickerMachine::Command> cmdList;
+
+    switch ( e->type() )
+    {
+        case QEvent::MouseButtonPress:
+        {
+            if ( eventPattern.mouseMatch(
+                QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
+            {
+                switch ( state() )
+                {
+                    case 0:
+                    {
+                        cmdList += Begin;
+                        cmdList += Append;
+                        setState( 1 );
+                        break;
+                    }
+                    case 1:
+                    {
+                        // Uh, strange we missed the MouseButtonRelease
+                        break;
+                    }
+                    default:
+                    {
+                        cmdList += End;
+                        setState( 0 );
+                    }
+                }
+            }
+        }
+        case QEvent::MouseMove:
+        case QEvent::Wheel:
+        {
+            if ( state() != 0 )
+                cmdList += Move;
+            break;
+        }
+        case QEvent::MouseButtonRelease:
+        {
+            if ( eventPattern.mouseMatch(
+                QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
+            {
+                if ( state() == 1 )
+                {
+                    cmdList += Append;
+                    setState( 2 );
+                }
+            }
+            break;
+        }
+        case QEvent::KeyPress:
+        {
+            if ( eventPattern.keyMatch(
+                QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
+            {
+                if ( state() == 0 )
+                {
+                    cmdList += Begin;
+                    cmdList += Append;
+                    setState( 1 );
+                }
+                else
+                {
+                    if ( state() == 1 )
+                    {
+                        cmdList += Append;
+                        setState( 2 );
+                    }
+                    else if ( state() == 2 )
+                    {
+                        cmdList += End;
+                        setState( 0 );
+                    }
+                }
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    return cmdList;
+}
+
+//! Constructor
+QwtPickerDragRectMachine::QwtPickerDragRectMachine():
+    QwtPickerMachine( RectSelection )
+{
+}
+
+//! Transition
+QList<QwtPickerMachine::Command> QwtPickerDragRectMachine::transition(
+    const QwtEventPattern &eventPattern, const QEvent *e )
+{
+    QList<QwtPickerMachine::Command> cmdList;
+
+    switch ( e->type() )
+    {
+        case QEvent::MouseButtonPress:
+        {
+            if ( eventPattern.mouseMatch(
+                QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
+            {
+                if ( state() == 0 )
+                {
+                    cmdList += Begin;
+                    cmdList += Append;
+                    cmdList += Append;
+                    setState( 2 );
+                }
+            }
+            break;
+        }
+        case QEvent::MouseMove:
+        case QEvent::Wheel:
+        {
+            if ( state() != 0 )
+                cmdList += Move;
+            break;
+        }
+        case QEvent::MouseButtonRelease:
+        {
+            if ( state() == 2 )
+            {
+                cmdList += End;
+                setState( 0 );
+            }
+            break;
+        }
+        case QEvent::KeyPress:
+        {
+            if ( eventPattern.keyMatch(
+                QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
+            {
+                if ( state() == 0 )
+                {
+                    cmdList += Begin;
+                    cmdList += Append;
+                    cmdList += Append;
+                    setState( 2 );
+                }
+                else
+                {
+                    cmdList += End;
+                    setState( 0 );
+                }
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    return cmdList;
+}
+
+//! Constructor
+QwtPickerPolygonMachine::QwtPickerPolygonMachine():
+    QwtPickerMachine( PolygonSelection )
+{
+}
+
+//! Transition
+QList<QwtPickerMachine::Command> QwtPickerPolygonMachine::transition(
+    const QwtEventPattern &eventPattern, const QEvent *e )
+{
+    QList<QwtPickerMachine::Command> cmdList;
+
+    switch ( e->type() )
+    {
+        case QEvent::MouseButtonPress:
+        {
+            if ( eventPattern.mouseMatch(
+                QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
+            {
+                if ( state() == 0 )
+                {
+                    cmdList += Begin;
+                    cmdList += Append;
+                    cmdList += Append;
+                    setState( 1 );
+                }
+                else
+                {
+                    cmdList += End;
+                    setState( 0 );
+                }
+            }
+            if ( eventPattern.mouseMatch(
+                QwtEventPattern::MouseSelect2, ( const QMouseEvent * )e ) )
+            {
+                if ( state() == 1 )
+                    cmdList += Append;
+            }
+            break;
+        }
+        case QEvent::MouseMove:
+        case QEvent::Wheel:
+        {
+            if ( state() != 0 )
+                cmdList += Move;
+            break;
+        }
+        case QEvent::KeyPress:
+        {
+            if ( eventPattern.keyMatch(
+                QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
+            {
+                if ( state() == 0 )
+                {
+                    cmdList += Begin;
+                    cmdList += Append;
+                    cmdList += Append;
+                    setState( 1 );
+                }
+                else
+                {
+                    cmdList += End;
+                    setState( 0 );
+                }
+            }
+            else if ( eventPattern.keyMatch(
+                QwtEventPattern::KeySelect2, ( const QKeyEvent * )e ) )
+            {
+                if ( state() == 1 )
+                    cmdList += Append;
+            }
+            break;
+        }
+        default:
+            break;
+    }
+
+    return cmdList;
+}
Index: trunk/BNC/qwt/qwt_picker_machine.h
===================================================================
--- trunk/BNC/qwt/qwt_picker_machine.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_picker_machine.h	(revision 4271)
@@ -0,0 +1,190 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PICKER_MACHINE
+#define QWT_PICKER_MACHINE 1
+
+#include "qwt_global.h"
+#include <qlist.h>
+
+class QEvent;
+class QwtEventPattern;
+
+/*!
+  \brief A state machine for QwtPicker selections
+
+  QwtPickerMachine accepts key and mouse events and translates them
+  into selection commands.
+
+  \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+*/
+
+class QWT_EXPORT QwtPickerMachine
+{
+public:
+    /*!
+      Type of a selection.
+      \sa selectionType()
+    */
+    enum SelectionType
+    {
+        //! The state machine not usable for any type of selection.
+        NoSelection = -1,
+
+        //! The state machine is for selecting a single point.
+        PointSelection,
+
+        //! The state machine is for selecting a rectangle (2 points).
+        RectSelection,
+
+        //! The state machine is for selecting a polygon (many points).
+        PolygonSelection
+    };
+
+    //! Commands - the output of a state machine
+    enum Command
+    {
+        Begin,
+        Append,
+        Move,
+        Remove,
+        End
+    };
+
+    QwtPickerMachine( SelectionType );
+    virtual ~QwtPickerMachine();
+
+    //! Transition
+    virtual QList<Command> transition(
+        const QwtEventPattern &, const QEvent * ) = 0;
+    void reset();
+
+    int state() const;
+    void setState( int );
+
+    SelectionType selectionType() const;
+
+private:
+    const SelectionType d_selectionType;
+    int d_state;
+};
+
+/*!
+  \brief A state machine for indicating mouse movements
+
+  QwtPickerTrackerMachine supports displaying information
+  corresponding to mouse movements, but is not intended for
+  selecting anything. Begin/End are related to Enter/Leave events.
+*/
+class QWT_EXPORT QwtPickerTrackerMachine: public QwtPickerMachine
+{
+public:
+    QwtPickerTrackerMachine();
+
+    virtual QList<Command> transition(
+        const QwtEventPattern &, const QEvent * );
+};
+
+/*!
+  \brief A state machine for point selections
+
+  Pressing QwtEventPattern::MouseSelect1 or
+  QwtEventPattern::KeySelect1 selects a point.
+
+  \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+*/
+class QWT_EXPORT QwtPickerClickPointMachine: public QwtPickerMachine
+{
+public:
+    QwtPickerClickPointMachine();
+
+    virtual QList<Command> transition(
+        const QwtEventPattern &, const QEvent * );
+};
+
+/*!
+  \brief A state machine for point selections
+
+  Pressing QwtEventPattern::MouseSelect1 or QwtEventPattern::KeySelect1
+  starts the selection, releasing QwtEventPattern::MouseSelect1 or
+  a second press of QwtEventPattern::KeySelect1 terminates it.
+*/
+class QWT_EXPORT QwtPickerDragPointMachine: public QwtPickerMachine
+{
+public:
+    QwtPickerDragPointMachine();
+
+    virtual QList<Command> transition(
+        const QwtEventPattern &, const QEvent * );
+};
+
+/*!
+  \brief A state machine for rectangle selections
+
+  Pressing QwtEventPattern::MouseSelect1 starts
+  the selection, releasing it selects the first point. Pressing it
+  again selects the second point and terminates the selection.
+  Pressing QwtEventPattern::KeySelect1 also starts the
+  selection, a second press selects the first point. A third one selects
+  the second point and terminates the selection.
+
+  \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+*/
+
+class QWT_EXPORT QwtPickerClickRectMachine: public QwtPickerMachine
+{
+public:
+    QwtPickerClickRectMachine();
+
+    virtual QList<Command> transition(
+        const QwtEventPattern &, const QEvent * );
+};
+
+/*!
+  \brief A state machine for rectangle selections
+
+  Pressing QwtEventPattern::MouseSelect1 selects
+  the first point, releasing it the second point.
+  Pressing QwtEventPattern::KeySelect1 also selects the
+  first point, a second press selects the second point and terminates
+  the selection.
+
+  \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+*/
+
+class QWT_EXPORT QwtPickerDragRectMachine: public QwtPickerMachine
+{
+public:
+    QwtPickerDragRectMachine();
+
+    virtual QList<Command> transition(
+        const QwtEventPattern &, const QEvent * );
+};
+
+/*!
+  \brief A state machine for polygon selections
+
+  Pressing QwtEventPattern::MouseSelect1 or QwtEventPattern::KeySelect1
+  starts the selection and selects the first point, or appends a point.
+  Pressing QwtEventPattern::MouseSelect2 or QwtEventPattern::KeySelect2
+  appends the last point and terminates the selection.
+
+  \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
+*/
+
+class QWT_EXPORT QwtPickerPolygonMachine: public QwtPickerMachine
+{
+public:
+    QwtPickerPolygonMachine();
+
+    virtual QList<Command> transition(
+        const QwtEventPattern &, const QEvent * );
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot.cpp	(revision 4271)
@@ -0,0 +1,748 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot.h"
+#include "qwt_plot_dict.h"
+#include "qwt_plot_layout.h"
+#include "qwt_scale_widget.h"
+#include "qwt_scale_engine.h"
+#include "qwt_text_label.h"
+#include "qwt_legend.h"
+#include "qwt_dyngrid_layout.h"
+#include "qwt_plot_canvas.h"
+#include <qpainter.h>
+#include <qpointer.h>
+#include <qpaintengine.h>
+#include <qapplication.h>
+#include <qevent.h>
+
+class QwtPlot::PrivateData
+{
+public:
+    QPointer<QwtTextLabel> lblTitle;
+    QPointer<QwtPlotCanvas> canvas;
+    QPointer<QwtLegend> legend;
+    QwtPlotLayout *layout;
+
+    bool autoReplot;
+};
+
+/*!
+  \brief Constructor
+  \param parent Parent widget
+ */
+QwtPlot::QwtPlot( QWidget *parent ):
+    QFrame( parent )
+{
+    initPlot( QwtText() );
+}
+
+/*!
+  \brief Constructor
+  \param title Title text
+  \param parent Parent widget
+ */
+QwtPlot::QwtPlot( const QwtText &title, QWidget *parent ):
+    QFrame( parent )
+{
+    initPlot( title );
+}
+
+//! Destructor
+QwtPlot::~QwtPlot()
+{
+    detachItems( QwtPlotItem::Rtti_PlotItem, autoDelete() );
+
+    delete d_data->layout;
+    deleteAxesData();
+    delete d_data;
+}
+
+/*!
+  \brief Initializes a QwtPlot instance
+  \param title Title text
+ */
+void QwtPlot::initPlot( const QwtText &title )
+{
+    d_data = new PrivateData;
+
+    d_data->layout = new QwtPlotLayout;
+    d_data->autoReplot = false;
+
+    d_data->lblTitle = new QwtTextLabel( title, this );
+    d_data->lblTitle->setObjectName( "QwtPlotTitle" );
+
+    d_data->lblTitle->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) );
+
+    QwtText text( title );
+    text.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap );
+    d_data->lblTitle->setText( text );
+
+    d_data->legend = NULL;
+
+    initAxesData();
+
+    d_data->canvas = new QwtPlotCanvas( this );
+    d_data->canvas->setObjectName( "QwtPlotCanvas" );
+    d_data->canvas->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+    d_data->canvas->setLineWidth( 2 );
+
+    updateTabOrder();
+
+    setSizePolicy( QSizePolicy::MinimumExpanding,
+        QSizePolicy::MinimumExpanding );
+
+    resize( 200, 200 );
+}
+
+/*!
+  \brief Adds handling of layout requests
+  \param event Event
+*/
+bool QwtPlot::event( QEvent *event )
+{
+    bool ok = QFrame::event( event );
+    switch ( event->type() )
+    {
+        case QEvent::LayoutRequest:
+            updateLayout();
+            break;
+        case QEvent::PolishRequest:
+            replot();
+            break;
+        default:;
+    }
+    return ok;
+}
+
+//! Replots the plot if autoReplot() is \c true.
+void QwtPlot::autoRefresh()
+{
+    if ( d_data->autoReplot )
+        replot();
+}
+
+/*!
+  \brief Set or reset the autoReplot option
+
+  If the autoReplot option is set, the plot will be
+  updated implicitly by manipulating member functions.
+  Since this may be time-consuming, it is recommended
+  to leave this option switched off and call replot()
+  explicitly if necessary.
+
+  The autoReplot option is set to false by default, which
+  means that the user has to call replot() in order to make
+  changes visible.
+  \param tf \c true or \c false. Defaults to \c true.
+  \sa replot()
+*/
+void QwtPlot::setAutoReplot( bool tf )
+{
+    d_data->autoReplot = tf;
+}
+
+/*! 
+  \return true if the autoReplot option is set.
+  \sa setAutoReplot()
+*/
+bool QwtPlot::autoReplot() const
+{
+    return d_data->autoReplot;
+}
+
+/*!
+  Change the plot's title
+  \param title New title
+*/
+void QwtPlot::setTitle( const QString &title )
+{
+    if ( title != d_data->lblTitle->text().text() )
+    {
+        d_data->lblTitle->setText( title );
+        updateLayout();
+    }
+}
+
+/*!
+  Change the plot's title
+  \param title New title
+*/
+void QwtPlot::setTitle( const QwtText &title )
+{
+    if ( title != d_data->lblTitle->text() )
+    {
+        d_data->lblTitle->setText( title );
+        updateLayout();
+    }
+}
+
+//! \return the plot's title
+QwtText QwtPlot::title() const
+{
+    return d_data->lblTitle->text();
+}
+
+//! \return the plot's title
+QwtPlotLayout *QwtPlot::plotLayout()
+{
+    return d_data->layout;
+}
+
+//! \return the plot's titel label.
+const QwtPlotLayout *QwtPlot::plotLayout() const
+{
+    return d_data->layout;
+}
+
+//! \return the plot's titel label.
+QwtTextLabel *QwtPlot::titleLabel()
+{
+    return d_data->lblTitle;
+}
+
+/*!
+  \return the plot's titel label.
+*/
+const QwtTextLabel *QwtPlot::titleLabel() const
+{
+    return d_data->lblTitle;
+}
+
+/*!
+  \return the plot's legend
+  \sa insertLegend()
+*/
+QwtLegend *QwtPlot::legend()
+{
+    return d_data->legend;
+}
+
+/*!
+  \return the plot's legend
+  \sa insertLegend()
+*/
+const QwtLegend *QwtPlot::legend() const
+{
+    return d_data->legend;
+}
+
+
+/*!
+  \return the plot's canvas
+*/
+QwtPlotCanvas *QwtPlot::canvas()
+{
+    return d_data->canvas;
+}
+
+/*!
+  \return the plot's canvas
+*/
+const QwtPlotCanvas *QwtPlot::canvas() const
+{
+    return d_data->canvas;
+}
+
+/*!
+  Return sizeHint
+  \sa minimumSizeHint()
+*/
+
+QSize QwtPlot::sizeHint() const
+{
+    int dw = 0;
+    int dh = 0;
+    for ( int axisId = 0; axisId < axisCnt; axisId++ )
+    {
+        if ( axisEnabled( axisId ) )
+        {
+            const int niceDist = 40;
+            const QwtScaleWidget *scaleWidget = axisWidget( axisId );
+            const QwtScaleDiv &scaleDiv = scaleWidget->scaleDraw()->scaleDiv();
+            const int majCnt = scaleDiv.ticks( QwtScaleDiv::MajorTick ).count();
+
+            if ( axisId == yLeft || axisId == yRight )
+            {
+                int hDiff = ( majCnt - 1 ) * niceDist
+                    - scaleWidget->minimumSizeHint().height();
+                if ( hDiff > dh )
+                    dh = hDiff;
+            }
+            else
+            {
+                int wDiff = ( majCnt - 1 ) * niceDist
+                    - scaleWidget->minimumSizeHint().width();
+                if ( wDiff > dw )
+                    dw = wDiff;
+            }
+        }
+    }
+    return minimumSizeHint() + QSize( dw, dh );
+}
+
+/*!
+  \brief Return a minimum size hint
+*/
+QSize QwtPlot::minimumSizeHint() const
+{
+    QSize hint = d_data->layout->minimumSizeHint( this );
+    hint += QSize( 2 * frameWidth(), 2 * frameWidth() );
+
+    return hint;
+}
+
+/*!
+  Resize and update internal layout
+  \param e Resize event
+*/
+void QwtPlot::resizeEvent( QResizeEvent *e )
+{
+    QFrame::resizeEvent( e );
+    updateLayout();
+}
+
+/*!
+  \brief Redraw the plot
+
+  If the autoReplot option is not set (which is the default)
+  or if any curves are attached to raw data, the plot has to
+  be refreshed explicitly in order to make changes visible.
+
+  \sa setAutoReplot()
+  \warning Calls canvas()->repaint, take care of infinite recursions
+*/
+void QwtPlot::replot()
+{
+    bool doAutoReplot = autoReplot();
+    setAutoReplot( false );
+
+    updateAxes();
+
+    /*
+      Maybe the layout needs to be updated, because of changed
+      axes labels. We need to process them here before painting
+      to avoid that scales and canvas get out of sync.
+     */
+    QApplication::sendPostedEvents( this, QEvent::LayoutRequest );
+
+    d_data->canvas->replot();
+
+    setAutoReplot( doAutoReplot );
+}
+
+/*!
+  \brief Adjust plot content to its current size.
+  \sa resizeEvent()
+*/
+void QwtPlot::updateLayout()
+{
+    d_data->layout->activate( this, contentsRect() );
+
+    QRect titleRect = d_data->layout->titleRect().toRect();
+    QRect scaleRect[QwtPlot::axisCnt];
+    for ( int axisId = 0; axisId < axisCnt; axisId++ )
+        scaleRect[axisId] = d_data->layout->scaleRect( axisId ).toRect();
+    QRect legendRect = d_data->layout->legendRect().toRect();
+    QRect canvasRect = d_data->layout->canvasRect().toRect();
+
+    //
+    // resize and show the visible widgets
+    //
+    if ( !d_data->lblTitle->text().isEmpty() )
+    {
+        d_data->lblTitle->setGeometry( titleRect );
+        if ( !d_data->lblTitle->isVisibleTo( this ) )
+            d_data->lblTitle->show();
+    }
+    else
+        d_data->lblTitle->hide();
+
+    for ( int axisId = 0; axisId < axisCnt; axisId++ )
+    {
+        if ( axisEnabled( axisId ) )
+        {
+            axisWidget( axisId )->setGeometry( scaleRect[axisId] );
+
+            if ( axisId == xBottom || axisId == xTop )
+            {
+                QRegion r( scaleRect[axisId] );
+                if ( axisEnabled( yLeft ) )
+                    r = r.subtract( QRegion( scaleRect[yLeft] ) );
+                if ( axisEnabled( yRight ) )
+                    r = r.subtract( QRegion( scaleRect[yRight] ) );
+                r.translate( -d_data->layout->scaleRect( axisId ).x(),
+                    -scaleRect[axisId].y() );
+
+                axisWidget( axisId )->setMask( r );
+            }
+            if ( !axisWidget( axisId )->isVisibleTo( this ) )
+                axisWidget( axisId )->show();
+        }
+        else
+            axisWidget( axisId )->hide();
+    }
+
+    if ( d_data->legend &&
+        d_data->layout->legendPosition() != ExternalLegend )
+    {
+        if ( d_data->legend->itemCount() > 0 )
+        {
+            d_data->legend->setGeometry( legendRect );
+            d_data->legend->show();
+        }
+        else
+            d_data->legend->hide();
+    }
+
+    d_data->canvas->setGeometry( canvasRect );
+}
+
+/*!
+   Update the focus tab order
+
+   The order is changed so that the canvas will be in front of the
+   first legend item, or behind the last legend item - depending
+   on the position of the legend.
+*/
+
+void QwtPlot::updateTabOrder()
+{
+    if ( d_data->canvas->focusPolicy() == Qt::NoFocus )
+        return;
+    if ( d_data->legend.isNull()
+        || d_data->layout->legendPosition() == ExternalLegend
+        || d_data->legend->legendItems().count() == 0 )
+    {
+        return;
+    }
+
+    // Depending on the position of the legend the
+    // tab order will be changed that the canvas is
+    // next to the last legend item, or before
+    // the first one.
+
+    const bool canvasFirst =
+        d_data->layout->legendPosition() == QwtPlot::BottomLegend ||
+        d_data->layout->legendPosition() == QwtPlot::RightLegend;
+
+    QWidget *previous = NULL;
+
+    QWidget *w = d_data->canvas;
+    while ( ( w = w->nextInFocusChain() ) != d_data->canvas )
+    {
+        bool isLegendItem = false;
+        if ( w->focusPolicy() != Qt::NoFocus
+            && w->parent() && w->parent() == d_data->legend->contentsWidget() )
+        {
+            isLegendItem = true;
+        }
+
+        if ( canvasFirst )
+        {
+            if ( isLegendItem )
+                break;
+
+            previous = w;
+        }
+        else
+        {
+            if ( isLegendItem )
+                previous = w;
+            else
+            {
+                if ( previous )
+                    break;
+            }
+        }
+    }
+
+    if ( previous && previous != d_data->canvas )
+        setTabOrder( previous, d_data->canvas );
+}
+
+/*!
+  Redraw the canvas.
+  \param painter Painter used for drawing
+
+  \warning drawCanvas calls drawItems what is also used
+           for printing. Applications that like to add individual
+           plot items better overload drawItems()
+  \sa drawItems()
+*/
+void QwtPlot::drawCanvas( QPainter *painter )
+{
+    QwtScaleMap maps[axisCnt];
+    for ( int axisId = 0; axisId < axisCnt; axisId++ )
+        maps[axisId] = canvasMap( axisId );
+
+    drawItems( painter, d_data->canvas->contentsRect(), maps );
+}
+
+/*!
+  Redraw the canvas items.
+  \param painter Painter used for drawing
+  \param canvasRect Bounding rectangle where to paint
+  \param map QwtPlot::axisCnt maps, mapping between plot and paint device coordinates
+*/
+
+void QwtPlot::drawItems( QPainter *painter, const QRectF &canvasRect,
+        const QwtScaleMap map[axisCnt] ) const
+{
+    const QwtPlotItemList& itmList = itemList();
+    for ( QwtPlotItemIterator it = itmList.begin();
+        it != itmList.end(); ++it )
+    {
+        QwtPlotItem *item = *it;
+        if ( item && item->isVisible() )
+        {
+            painter->save();
+
+            painter->setRenderHint( QPainter::Antialiasing,
+                item->testRenderHint( QwtPlotItem::RenderAntialiased ) );
+
+            item->draw( painter,
+                map[item->xAxis()], map[item->yAxis()],
+                canvasRect );
+
+            painter->restore();
+        }
+    }
+}
+
+/*!
+  \param axisId Axis
+  \return Map for the axis on the canvas. With this map pixel coordinates can
+          translated to plot coordinates and vice versa.
+  \sa QwtScaleMap, transform(), invTransform()
+
+*/
+QwtScaleMap QwtPlot::canvasMap( int axisId ) const
+{
+    QwtScaleMap map;
+    if ( !d_data->canvas )
+        return map;
+
+    map.setTransformation( axisScaleEngine( axisId )->transformation() );
+
+    const QwtScaleDiv *sd = axisScaleDiv( axisId );
+    map.setScaleInterval( sd->lowerBound(), sd->upperBound() );
+
+    if ( axisEnabled( axisId ) )
+    {
+        const QwtScaleWidget *s = axisWidget( axisId );
+        if ( axisId == yLeft || axisId == yRight )
+        {
+            double y = s->y() + s->startBorderDist() - d_data->canvas->y();
+            double h = s->height() - s->startBorderDist() - s->endBorderDist();
+            map.setPaintInterval( y + h, y );
+        }
+        else
+        {
+            double x = s->x() + s->startBorderDist() - d_data->canvas->x();
+            double w = s->width() - s->startBorderDist() - s->endBorderDist();
+            map.setPaintInterval( x, x + w );
+        }
+    }
+    else
+    {
+        int margin = 0;
+        if ( !plotLayout()->alignCanvasToScales() )
+            margin = plotLayout()->canvasMargin( axisId );
+
+        const QRect &canvasRect = d_data->canvas->contentsRect();
+        if ( axisId == yLeft || axisId == yRight )
+        {
+            map.setPaintInterval( canvasRect.bottom() - margin,
+                canvasRect.top() + margin );
+        }
+        else
+        {
+            map.setPaintInterval( canvasRect.left() + margin,
+                canvasRect.right() - margin );
+        }
+    }
+    return map;
+}
+
+/*!
+  \brief Change the background of the plotting area
+
+  Sets brush to QPalette::Window of all colorgroups of
+  the palette of the canvas. Using canvas()->setPalette()
+  is a more powerful way to set these colors.
+
+  \param brush New background brush
+  \sa canvasBackground()
+*/
+void QwtPlot::setCanvasBackground( const QBrush &brush )
+{
+    QPalette pal = d_data->canvas->palette();
+
+    for ( int i = 0; i < QPalette::NColorGroups; i++ )
+        pal.setBrush( ( QPalette::ColorGroup )i, QPalette::Window, brush );
+
+    canvas()->setPalette( pal );
+}
+
+/*!
+  Nothing else than: canvas()->palette().brush(
+        QPalette::Normal, QPalette::Window);
+
+  \return Background brush of the plotting area.
+  \sa setCanvasBackground()
+*/
+QBrush QwtPlot::canvasBackground() const
+{
+    return canvas()->palette().brush(
+        QPalette::Normal, QPalette::Window );
+}
+
+/*!
+  \brief Change the border width of the plotting area
+
+  Nothing else than canvas()->setLineWidth(w),
+  left for compatibility only.
+
+  \param width New border width
+*/
+void QwtPlot::setCanvasLineWidth( int width )
+{
+    canvas()->setLineWidth( width );
+    updateLayout();
+}
+
+/*!
+  Nothing else than: canvas()->lineWidth(),
+  left for compatibility only.
+
+  \return the border width of the plotting area
+*/
+int QwtPlot::canvasLineWidth() const
+{
+    return canvas()->lineWidth();
+}
+
+/*!
+  \return \c true if the specified axis exists, otherwise \c false
+  \param axisId axis index
+ */
+bool QwtPlot::axisValid( int axisId )
+{
+    return ( ( axisId >= QwtPlot::yLeft ) && ( axisId < QwtPlot::axisCnt ) );
+}
+
+/*!
+  Called internally when the legend has been clicked on.
+  Emits a legendClicked() signal.
+*/
+void QwtPlot::legendItemClicked()
+{
+    if ( d_data->legend && sender()->isWidgetType() )
+    {
+        QwtPlotItem *plotItem =
+            ( QwtPlotItem* )d_data->legend->find( ( QWidget * )sender() );
+        if ( plotItem )
+            Q_EMIT legendClicked( plotItem );
+    }
+}
+
+/*!
+  Called internally when the legend has been checked
+  Emits a legendClicked() signal.
+*/
+void QwtPlot::legendItemChecked( bool on )
+{
+    if ( d_data->legend && sender()->isWidgetType() )
+    {
+        QwtPlotItem *plotItem =
+            ( QwtPlotItem* )d_data->legend->find( ( QWidget * )sender() );
+        if ( plotItem )
+            Q_EMIT legendChecked( plotItem, on );
+    }
+}
+
+/*!
+  \brief Insert a legend
+
+  If the position legend is \c QwtPlot::LeftLegend or \c QwtPlot::RightLegend
+  the legend will be organized in one column from top to down.
+  Otherwise the legend items will be placed in a table
+  with a best fit number of columns from left to right.
+
+  If pos != QwtPlot::ExternalLegend the plot widget will become
+  parent of the legend. It will be deleted when the plot is deleted,
+  or another legend is set with insertLegend().
+
+  \param legend Legend
+  \param pos The legend's position. For top/left position the number
+             of colums will be limited to 1, otherwise it will be set to
+             unlimited.
+
+  \param ratio Ratio between legend and the bounding rect
+               of title, canvas and axes. The legend will be shrinked
+               if it would need more space than the given ratio.
+               The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
+               it will be reset to the default ratio.
+               The default vertical/horizontal ratio is 0.33/0.5.
+
+  \sa legend(), QwtPlotLayout::legendPosition(),
+      QwtPlotLayout::setLegendPosition()
+*/
+void QwtPlot::insertLegend( QwtLegend *legend,
+    QwtPlot::LegendPosition pos, double ratio )
+{
+    d_data->layout->setLegendPosition( pos, ratio );
+
+    if ( legend != d_data->legend )
+    {
+        if ( d_data->legend && d_data->legend->parent() == this )
+            delete d_data->legend;
+
+        d_data->legend = legend;
+
+        if ( d_data->legend )
+        {
+            if ( pos != ExternalLegend )
+            {
+                if ( d_data->legend->parent() != this )
+                    d_data->legend->setParent( this );
+            }
+
+            const QwtPlotItemList& itmList = itemList();
+            for ( QwtPlotItemIterator it = itmList.begin();
+                it != itmList.end(); ++it )
+            {
+                ( *it )->updateLegend( d_data->legend );
+            }
+
+            QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>(
+                d_data->legend->contentsWidget()->layout() );
+            if ( tl )
+            {
+                switch ( d_data->layout->legendPosition() )
+                {
+                    case LeftLegend:
+                    case RightLegend:
+                        tl->setMaxCols( 1 ); // 1 column: align vertical
+                        break;
+                    case TopLegend:
+                    case BottomLegend:
+                        tl->setMaxCols( 0 ); // unlimited
+                        break;
+                    case ExternalLegend:
+                        break;
+                }
+            }
+        }
+        updateTabOrder();
+    }
+
+    updateLayout();
+}
Index: trunk/BNC/qwt/qwt_plot.h
===================================================================
--- trunk/BNC/qwt/qwt_plot.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot.h	(revision 4271)
@@ -0,0 +1,290 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_H
+#define QWT_PLOT_H
+
+#include "qwt_global.h"
+#include "qwt_text.h"
+#include "qwt_plot_dict.h"
+#include "qwt_scale_map.h"
+#include "qwt_interval.h"
+#include <qframe.h>
+
+class QwtPlotLayout;
+class QwtLegend;
+class QwtScaleWidget;
+class QwtScaleEngine;
+class QwtScaleDiv;
+class QwtScaleDraw;
+class QwtTextLabel;
+class QwtPlotCanvas;
+
+/*!
+  \brief A 2-D plotting widget
+
+  QwtPlot is a widget for plotting two-dimensional graphs.
+  An unlimited number of plot items can be displayed on
+  its canvas. Plot items might be curves (QwtPlotCurve), markers
+  (QwtPlotMarker), the grid (QwtPlotGrid), or anything else derived
+  from QwtPlotItem.
+  A plot can have up to four axes, with each plot item attached to an x- and
+  a y axis. The scales at the axes can be explicitely set (QwtScaleDiv), or
+  are calculated from the plot items, using algorithms (QwtScaleEngine) which
+  can be configured separately for each axis.
+
+  \image html plot.png
+
+  \par Example
+  The following example shows (schematically) the most simple
+  way to use QwtPlot. By default, only the left and bottom axes are
+  visible and their scales are computed automatically.
+  \verbatim
+#include <qwt_plot.h>
+#include <qwt_plot_curve.h>
+
+QwtPlot *myPlot = new QwtPlot("Two Curves", parent);
+
+// add curves
+QwtPlotCurve *curve1 = new QwtPlotCurve("Curve 1");
+QwtPlotCurve *curve2 = new QwtPlotCurve("Curve 2");
+
+// copy the data into the curves
+curve1->setData(...);
+curve2->setData(...);
+
+curve1->attach(myPlot);
+curve2->attach(myPlot);
+
+// finally, refresh the plot
+myPlot->replot();
+\endverbatim
+*/
+
+class QWT_EXPORT QwtPlot: public QFrame, public QwtPlotDict
+{
+    Q_OBJECT
+    Q_PROPERTY( QString propertiesDocument
+        READ grabProperties WRITE applyProperties )
+
+public:
+    //! \brief Axis index
+    enum Axis
+    {
+        //! Y axis left of the canvas
+        yLeft,
+
+        //! Y axis right of the canvas
+        yRight,
+
+        //! X axis below the canvas
+        xBottom,
+
+        //! X axis above the canvas
+        xTop,
+
+        //! Number of axes
+        axisCnt
+    };
+
+    /*!
+        Position of the legend, relative to the canvas.
+
+        \sa insertLegend()
+        \note In case of ExternalLegend, the legend is not
+              handled by QwtPlotRenderer
+     */
+    enum LegendPosition
+    {
+        //! The legend will be left from the QwtPlot::yLeft axis.
+        LeftLegend,
+
+        //! The legend will be right from the QwtPlot::yRight axis.
+        RightLegend,
+
+        //! The legend will be below QwtPlot::xBottom axis.
+        BottomLegend,
+
+        //! The legend will be between QwtPlot::xTop axis and the title.
+        TopLegend,
+
+        /*!
+          External means that only the content of the legend
+          will be handled by QwtPlot, but not its geometry.
+          This type can be used to have a legend in an 
+          external window ( or on the canvas ).
+         */
+        ExternalLegend
+    };
+
+    explicit QwtPlot( QWidget * = NULL );
+    explicit QwtPlot( const QwtText &title, QWidget *p = NULL );
+
+    virtual ~QwtPlot();
+
+    void applyProperties( const QString & );
+    QString grabProperties() const;
+
+    void setAutoReplot( bool tf = true );
+    bool autoReplot() const;
+
+    // Layout
+
+    QwtPlotLayout *plotLayout();
+    const QwtPlotLayout *plotLayout() const;
+
+    // Title
+
+    void setTitle( const QString & );
+    void setTitle( const QwtText &t );
+    QwtText title() const;
+
+    QwtTextLabel *titleLabel();
+    const QwtTextLabel *titleLabel() const;
+
+    // Canvas
+
+    QwtPlotCanvas *canvas();
+    const QwtPlotCanvas *canvas() const;
+
+    void setCanvasBackground( const QBrush & );
+    QBrush canvasBackground() const;
+
+    void setCanvasLineWidth( int w );
+    int canvasLineWidth() const;
+
+    virtual QwtScaleMap canvasMap( int axisId ) const;
+
+    double invTransform( int axisId, int pos ) const;
+    double transform( int axisId, double value ) const;
+
+    // Axes
+
+    QwtScaleEngine *axisScaleEngine( int axisId );
+    const QwtScaleEngine *axisScaleEngine( int axisId ) const;
+    void setAxisScaleEngine( int axisId, QwtScaleEngine * );
+
+    void setAxisAutoScale( int axisId, bool on = true );
+    bool axisAutoScale( int axisId ) const;
+
+    void enableAxis( int axisId, bool tf = true );
+    bool axisEnabled( int axisId ) const;
+
+    void setAxisFont( int axisId, const QFont &f );
+    QFont axisFont( int axisId ) const;
+
+    void setAxisScale( int axisId, double min, double max, double step = 0 );
+    void setAxisScaleDiv( int axisId, const QwtScaleDiv & );
+    void setAxisScaleDraw( int axisId, QwtScaleDraw * );
+
+    double axisStepSize( int axisId ) const;
+    QwtInterval axisInterval( int axisId ) const;
+
+    const QwtScaleDiv *axisScaleDiv( int axisId ) const;
+    QwtScaleDiv *axisScaleDiv( int axisId );
+
+    const QwtScaleDraw *axisScaleDraw( int axisId ) const;
+    QwtScaleDraw *axisScaleDraw( int axisId );
+
+    const QwtScaleWidget *axisWidget( int axisId ) const;
+    QwtScaleWidget *axisWidget( int axisId );
+
+    void setAxisLabelAlignment( int axisId, Qt::Alignment );
+    void setAxisLabelRotation( int axisId, double rotation );
+
+    void setAxisTitle( int axisId, const QString & );
+    void setAxisTitle( int axisId, const QwtText & );
+    QwtText axisTitle( int axisId ) const;
+
+    void setAxisMaxMinor( int axisId, int maxMinor );
+    int axisMaxMinor( int axisId ) const;
+
+    void setAxisMaxMajor( int axisId, int maxMajor );
+    int axisMaxMajor( int axisId ) const;
+
+    // Legend
+
+    void insertLegend( QwtLegend *, LegendPosition = QwtPlot::RightLegend,
+        double ratio = -1.0 );
+
+    QwtLegend *legend();
+    const QwtLegend *legend() const;
+
+    // Misc
+
+    virtual QSize sizeHint() const;
+    virtual QSize minimumSizeHint() const;
+
+    virtual void updateLayout();
+    virtual void drawCanvas( QPainter * );
+
+    void updateAxes();
+
+    virtual bool event( QEvent * );
+
+    virtual void drawItems( QPainter *, const QRectF &,
+        const QwtScaleMap maps[axisCnt] ) const;
+
+Q_SIGNALS:
+    /*!
+      A signal which is emitted when the user has clicked on
+      a legend item, which is in QwtLegend::ClickableItem mode.
+
+      \param plotItem Corresponding plot item of the
+                 selected legend item
+
+      \note clicks are disabled as default
+      \sa QwtLegend::setItemMode(), QwtLegend::itemMode()
+     */
+    void legendClicked( QwtPlotItem *plotItem );
+
+    /*!
+      A signal which is emitted when the user has clicked on
+      a legend item, which is in QwtLegend::CheckableItem mode
+
+      \param plotItem Corresponding plot item of the
+                 selected legend item
+      \param on True when the legen item is checked
+
+      \note clicks are disabled as default
+      \sa QwtLegend::setItemMode(), QwtLegend::itemMode()
+     */
+
+    void legendChecked( QwtPlotItem *plotItem, bool on );
+
+public Q_SLOTS:
+    virtual void replot();
+    void autoRefresh();
+
+protected Q_SLOTS:
+    virtual void legendItemClicked();
+    virtual void legendItemChecked( bool );
+
+protected:
+    static bool axisValid( int axisId );
+
+    virtual void updateTabOrder();
+
+    virtual void resizeEvent( QResizeEvent *e );
+
+private:
+    void initAxesData();
+    void deleteAxesData();
+    void updateScaleDiv();
+
+    void initPlot( const QwtText &title );
+
+    class AxisData;
+    AxisData *d_axisData[axisCnt];
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_axis.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_axis.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_axis.cpp	(revision 4271)
@@ -0,0 +1,670 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot.h"
+#include "qwt_math.h"
+#include "qwt_scale_widget.h"
+#include "qwt_scale_div.h"
+#include "qwt_scale_engine.h"
+
+class QwtPlot::AxisData
+{
+public:
+    bool isEnabled;
+    bool doAutoScale;
+
+    double minValue;
+    double maxValue;
+    double stepSize;
+
+    int maxMajor;
+    int maxMinor;
+
+    QwtScaleDiv scaleDiv;
+    QwtScaleEngine *scaleEngine;
+    QwtScaleWidget *scaleWidget;
+};
+
+//! Initialize axes
+void QwtPlot::initAxesData()
+{
+    int axisId;
+
+    for ( axisId = 0; axisId < axisCnt; axisId++ )
+        d_axisData[axisId] = new AxisData;
+
+    d_axisData[yLeft]->scaleWidget =
+        new QwtScaleWidget( QwtScaleDraw::LeftScale, this );
+    d_axisData[yRight]->scaleWidget =
+        new QwtScaleWidget( QwtScaleDraw::RightScale, this );
+    d_axisData[xTop]->scaleWidget =
+        new QwtScaleWidget( QwtScaleDraw::TopScale, this );
+    d_axisData[xBottom]->scaleWidget =
+        new QwtScaleWidget( QwtScaleDraw::BottomScale, this );
+
+    d_axisData[yLeft]->scaleWidget->setObjectName( "QwtPlotAxisYLeft" );
+    d_axisData[yRight]->scaleWidget->setObjectName( "QwtPlotAxisYRight" );
+    d_axisData[xTop]->scaleWidget->setObjectName( "QwtPlotAxisXTop" );
+    d_axisData[xBottom]->scaleWidget->setObjectName( "QwtPlotAxisXBottom" );
+
+    QFont fscl( fontInfo().family(), 10 );
+    QFont fttl( fontInfo().family(), 12, QFont::Bold );
+
+    for ( axisId = 0; axisId < axisCnt; axisId++ )
+    {
+        AxisData &d = *d_axisData[axisId];
+
+        d.scaleWidget->setFont( fscl );
+        d.scaleWidget->setMargin( 2 );
+
+        QwtText text = d.scaleWidget->title();
+        text.setFont( fttl );
+        d.scaleWidget->setTitle( text );
+
+        d.doAutoScale = true;
+
+        d.minValue = 0.0;
+        d.maxValue = 1000.0;
+        d.stepSize = 0.0;
+
+        d.maxMinor = 5;
+        d.maxMajor = 8;
+
+        d.scaleEngine = new QwtLinearScaleEngine;
+
+        d.scaleDiv.invalidate();
+    }
+
+    d_axisData[yLeft]->isEnabled = true;
+    d_axisData[yRight]->isEnabled = false;
+    d_axisData[xBottom]->isEnabled = true;
+    d_axisData[xTop]->isEnabled = false;
+}
+
+void QwtPlot::deleteAxesData()
+{
+    for ( int axisId = 0; axisId < axisCnt; axisId++ )
+    {
+        delete d_axisData[axisId]->scaleEngine;
+        delete d_axisData[axisId];
+        d_axisData[axisId] = NULL;
+    }
+}
+
+/*!
+  \return specified axis, or NULL if axisId is invalid.
+  \param axisId axis index
+*/
+const QwtScaleWidget *QwtPlot::axisWidget( int axisId ) const
+{
+    if ( axisValid( axisId ) )
+        return d_axisData[axisId]->scaleWidget;
+
+    return NULL;
+}
+
+/*!
+  \return specified axis, or NULL if axisId is invalid.
+  \param axisId axis index
+*/
+QwtScaleWidget *QwtPlot::axisWidget( int axisId )
+{
+    if ( axisValid( axisId ) )
+        return d_axisData[axisId]->scaleWidget;
+
+    return NULL;
+}
+
+/*!
+   Change the scale engine for an axis
+
+  \param axisId axis index
+  \param scaleEngine Scale engine
+
+  \sa axisScaleEngine()
+*/
+void QwtPlot::setAxisScaleEngine( int axisId, QwtScaleEngine *scaleEngine )
+{
+    if ( axisValid( axisId ) && scaleEngine != NULL )
+    {
+        AxisData &d = *d_axisData[axisId];
+
+        delete d.scaleEngine;
+        d.scaleEngine = scaleEngine;
+
+        d.scaleDiv.invalidate();
+
+        autoRefresh();
+    }
+}
+
+/*!
+  \param axisId axis index
+  \return Scale engine for a specific axis
+*/
+QwtScaleEngine *QwtPlot::axisScaleEngine( int axisId )
+{
+    if ( axisValid( axisId ) )
+        return d_axisData[axisId]->scaleEngine;
+    else
+        return NULL;
+}
+
+/*!
+  \param axisId axis index
+  \return Scale engine for a specific axis
+*/
+const QwtScaleEngine *QwtPlot::axisScaleEngine( int axisId ) const
+{
+    if ( axisValid( axisId ) )
+        return d_axisData[axisId]->scaleEngine;
+    else
+        return NULL;
+}
+/*!
+  \return \c true if autoscaling is enabled
+  \param axisId axis index
+*/
+bool QwtPlot::axisAutoScale( int axisId ) const
+{
+    if ( axisValid( axisId ) )
+        return d_axisData[axisId]->doAutoScale;
+    else
+        return false;
+
+}
+
+/*!
+  \return \c true if a specified axis is enabled
+  \param axisId axis index
+*/
+bool QwtPlot::axisEnabled( int axisId ) const
+{
+    if ( axisValid( axisId ) )
+        return d_axisData[axisId]->isEnabled;
+    else
+        return false;
+}
+
+/*!
+  \return the font of the scale labels for a specified axis
+  \param axisId axis index
+*/
+QFont QwtPlot::axisFont( int axisId ) const
+{
+    if ( axisValid( axisId ) )
+        return axisWidget( axisId )->font();
+    else
+        return QFont();
+
+}
+
+/*!
+  \return the maximum number of major ticks for a specified axis
+  \param axisId axis index
+  \sa setAxisMaxMajor()
+*/
+int QwtPlot::axisMaxMajor( int axisId ) const
+{
+    if ( axisValid( axisId ) )
+        return d_axisData[axisId]->maxMajor;
+    else
+        return 0;
+}
+
+/*!
+  \return the maximum number of minor ticks for a specified axis
+  \param axisId axis index
+  \sa setAxisMaxMinor()
+*/
+int QwtPlot::axisMaxMinor( int axisId ) const
+{
+    if ( axisValid( axisId ) )
+        return d_axisData[axisId]->maxMinor;
+    else
+        return 0;
+}
+
+/*!
+  \brief Return the scale division of a specified axis
+
+  axisScaleDiv(axisId)->lowerBound(), axisScaleDiv(axisId)->upperBound()
+  are the current limits of the axis scale.
+
+  \param axisId axis index
+  \return Scale division
+
+  \sa QwtScaleDiv, setAxisScaleDiv()
+*/
+const QwtScaleDiv *QwtPlot::axisScaleDiv( int axisId ) const
+{
+    if ( !axisValid( axisId ) )
+        return NULL;
+
+    return &d_axisData[axisId]->scaleDiv;
+}
+
+/*!
+  \brief Return the scale division of a specified axis
+
+  axisScaleDiv(axisId)->lowerBound(), axisScaleDiv(axisId)->upperBound()
+  are the current limits of the axis scale.
+
+  \param axisId axis index
+  \return Scale division
+
+  \sa QwtScaleDiv, setAxisScaleDiv()
+*/
+QwtScaleDiv *QwtPlot::axisScaleDiv( int axisId )
+{
+    if ( !axisValid( axisId ) )
+        return NULL;
+
+    return &d_axisData[axisId]->scaleDiv;
+}
+
+/*!
+  \returns the scale draw of a specified axis
+  \param axisId axis index
+  \return specified scaleDraw for axis, or NULL if axis is invalid.
+  \sa QwtScaleDraw
+*/
+const QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId ) const
+{
+    if ( !axisValid( axisId ) )
+        return NULL;
+
+    return axisWidget( axisId )->scaleDraw();
+}
+
+/*!
+  \returns the scale draw of a specified axis
+  \param axisId axis index
+  \return specified scaleDraw for axis, or NULL if axis is invalid.
+  \sa QwtScaleDraw
+*/
+QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId )
+{
+    if ( !axisValid( axisId ) )
+        return NULL;
+
+    return axisWidget( axisId )->scaleDraw();
+}
+
+/*!
+   Return the step size parameter, that has been set
+   in setAxisScale. This doesn't need to be the step size
+   of the current scale.
+
+  \param axisId axis index
+  \return step size parameter value
+
+   \sa setAxisScale()
+*/
+double QwtPlot::axisStepSize( int axisId ) const
+{
+    if ( !axisValid( axisId ) )
+        return 0;
+
+    return d_axisData[axisId]->stepSize;
+}
+
+/*!
+  \brief Return the current interval of the specified axis
+
+  This is only a convenience function for axisScaleDiv( axisId )->interval();
+  
+  \param axisId axis index
+  \return Scale interval
+
+  \sa QwtScaleDiv, axisScaleDiv()
+*/
+QwtInterval QwtPlot::axisInterval( int axisId ) const
+{
+    if ( !axisValid( axisId ) )
+        return QwtInterval();
+
+    return d_axisData[axisId]->scaleDiv.interval();
+}
+
+/*!
+  \return the title of a specified axis
+  \param axisId axis index
+*/
+QwtText QwtPlot::axisTitle( int axisId ) const
+{
+    if ( axisValid( axisId ) )
+        return axisWidget( axisId )->title();
+    else
+        return QwtText();
+}
+
+/*!
+  \brief Enable or disable a specified axis
+
+  When an axis is disabled, this only means that it is not
+  visible on the screen. Curves, markers and can be attached
+  to disabled axes, and transformation of screen coordinates
+  into values works as normal.
+
+  Only xBottom and yLeft are enabled by default.
+  \param axisId axis index
+  \param tf \c true (enabled) or \c false (disabled)
+*/
+void QwtPlot::enableAxis( int axisId, bool tf )
+{
+    if ( axisValid( axisId ) && tf != d_axisData[axisId]->isEnabled )
+    {
+        d_axisData[axisId]->isEnabled = tf;
+        updateLayout();
+    }
+}
+
+/*!
+  Transform the x or y coordinate of a position in the
+  drawing region into a value.
+  \param axisId axis index
+  \param pos position
+  \warning The position can be an x or a y coordinate,
+           depending on the specified axis.
+*/
+double QwtPlot::invTransform( int axisId, int pos ) const
+{
+    if ( axisValid( axisId ) )
+        return( canvasMap( axisId ).invTransform( pos ) );
+    else
+        return 0.0;
+}
+
+
+/*!
+  \brief Transform a value into a coordinate in the plotting region
+  \param axisId axis index
+  \param value value
+  \return X or y coordinate in the plotting region corresponding
+          to the value.
+*/
+double QwtPlot::transform( int axisId, double value ) const
+{
+    if ( axisValid( axisId ) )
+        return( canvasMap( axisId ).transform( value ) );
+    else
+        return 0.0;
+}
+
+/*!
+  \brief Change the font of an axis
+  \param axisId axis index
+  \param f font
+  \warning This function changes the font of the tick labels,
+           not of the axis title.
+*/
+void QwtPlot::setAxisFont( int axisId, const QFont &f )
+{
+    if ( axisValid( axisId ) )
+        axisWidget( axisId )->setFont( f );
+}
+
+/*!
+  \brief Enable autoscaling for a specified axis
+
+  This member function is used to switch back to autoscaling mode
+  after a fixed scale has been set. Autoscaling is enabled by default.
+
+  \param axisId axis index
+  \param on On/Off
+  \sa setAxisScale(), setAxisScaleDiv(), updateAxes()
+
+  \note The autoscaling flag has no effect until updateAxes() is executed
+        ( called by replot() ).
+*/
+void QwtPlot::setAxisAutoScale( int axisId, bool on )
+{
+    if ( axisValid( axisId ) && ( d_axisData[axisId]->doAutoScale != on ) )
+    {
+        d_axisData[axisId]->doAutoScale = on;
+        autoRefresh();
+    }
+}
+
+/*!
+  \brief Disable autoscaling and specify a fixed scale for a selected axis.
+  \param axisId axis index
+  \param min
+  \param max minimum and maximum of the scale
+  \param stepSize Major step size. If <code>step == 0</code>, the step size is
+            calculated automatically using the maxMajor setting.
+  \sa setAxisMaxMajor(), setAxisAutoScale(), axisStepSize()
+*/
+void QwtPlot::setAxisScale( int axisId, double min, double max, double stepSize )
+{
+    if ( axisValid( axisId ) )
+    {
+        AxisData &d = *d_axisData[axisId];
+
+        d.doAutoScale = false;
+        d.scaleDiv.invalidate();
+
+        d.minValue = min;
+        d.maxValue = max;
+        d.stepSize = stepSize;
+
+        autoRefresh();
+    }
+}
+
+/*!
+  \brief Disable autoscaling and specify a fixed scale for a selected axis.
+  \param axisId axis index
+  \param scaleDiv Scale division
+  \sa setAxisScale(), setAxisAutoScale()
+*/
+void QwtPlot::setAxisScaleDiv( int axisId, const QwtScaleDiv &scaleDiv )
+{
+    if ( axisValid( axisId ) )
+    {
+        AxisData &d = *d_axisData[axisId];
+
+        d.doAutoScale = false;
+        d.scaleDiv = scaleDiv;
+
+        autoRefresh();
+    }
+}
+
+/*!
+  \brief Set a scale draw
+  \param axisId axis index
+  \param scaleDraw object responsible for drawing scales.
+
+  By passing scaleDraw it is possible to extend QwtScaleDraw
+  functionality and let it take place in QwtPlot. Please note
+  that scaleDraw has to be created with new and will be deleted
+  by the corresponding QwtScale member ( like a child object ).
+
+  \sa QwtScaleDraw, QwtScaleWidget
+  \warning The attributes of scaleDraw will be overwritten by those of the
+           previous QwtScaleDraw.
+*/
+
+void QwtPlot::setAxisScaleDraw( int axisId, QwtScaleDraw *scaleDraw )
+{
+    if ( axisValid( axisId ) )
+    {
+        axisWidget( axisId )->setScaleDraw( scaleDraw );
+        autoRefresh();
+    }
+}
+
+/*!
+  Change the alignment of the tick labels
+  \param axisId axis index
+  \param alignment Or'd Qt::AlignmentFlags see <qnamespace.h>
+  \sa QwtScaleDraw::setLabelAlignment()
+*/
+void QwtPlot::setAxisLabelAlignment( int axisId, Qt::Alignment alignment )
+{
+    if ( axisValid( axisId ) )
+        axisWidget( axisId )->setLabelAlignment( alignment );
+}
+
+/*!
+  Rotate all tick labels
+  \param axisId axis index
+  \param rotation Angle in degrees. When changing the label rotation,
+                  the label alignment might be adjusted too.
+  \sa QwtScaleDraw::setLabelRotation(), setAxisLabelAlignment()
+*/
+void QwtPlot::setAxisLabelRotation( int axisId, double rotation )
+{
+    if ( axisValid( axisId ) )
+        axisWidget( axisId )->setLabelRotation( rotation );
+}
+
+/*!
+  Set the maximum number of minor scale intervals for a specified axis
+
+  \param axisId axis index
+  \param maxMinor maximum number of minor steps
+  \sa axisMaxMinor()
+*/
+void QwtPlot::setAxisMaxMinor( int axisId, int maxMinor )
+{
+    if ( axisValid( axisId ) )
+    {
+        maxMinor = qBound( 0, maxMinor, 100 );
+
+        AxisData &d = *d_axisData[axisId];
+        if ( maxMinor != d.maxMinor )
+        {
+            d.maxMinor = maxMinor;
+            d.scaleDiv.invalidate();
+            autoRefresh();
+        }
+    }
+}
+
+/*!
+  Set the maximum number of major scale intervals for a specified axis
+
+  \param axisId axis index
+  \param maxMajor maximum number of major steps
+  \sa axisMaxMajor()
+*/
+void QwtPlot::setAxisMaxMajor( int axisId, int maxMajor )
+{
+    if ( axisValid( axisId ) )
+    {
+        maxMajor = qBound( 1, maxMajor, 10000 );
+
+        AxisData &d = *d_axisData[axisId];
+        if ( maxMajor != d.maxMajor )
+        {
+            d.maxMajor = maxMajor;
+            d.scaleDiv.invalidate();
+            autoRefresh();
+        }
+    }
+}
+
+/*!
+  \brief Change the title of a specified axis
+  \param axisId axis index
+  \param title axis title
+*/
+void QwtPlot::setAxisTitle( int axisId, const QString &title )
+{
+    if ( axisValid( axisId ) )
+        axisWidget( axisId )->setTitle( title );
+}
+
+/*!
+  \brief Change the title of a specified axis
+  \param axisId axis index
+  \param title axis title
+*/
+void QwtPlot::setAxisTitle( int axisId, const QwtText &title )
+{
+    if ( axisValid( axisId ) )
+        axisWidget( axisId )->setTitle( title );
+}
+
+//! Rebuild the scales
+void QwtPlot::updateAxes()
+{
+    // Find bounding interval of the item data
+    // for all axes, where autoscaling is enabled
+
+    QwtInterval intv[axisCnt];
+
+    const QwtPlotItemList& itmList = itemList();
+
+    QwtPlotItemIterator it;
+    for ( it = itmList.begin(); it != itmList.end(); ++it )
+    {
+        const QwtPlotItem *item = *it;
+
+        if ( !item->testItemAttribute( QwtPlotItem::AutoScale ) )
+            continue;
+
+        if ( !item->isVisible() )
+            continue;
+
+        if ( axisAutoScale( item->xAxis() ) || axisAutoScale( item->yAxis() ) )
+        {
+            const QRectF rect = item->boundingRect();
+            intv[item->xAxis()] |= QwtInterval( rect.left(), rect.right() );
+            intv[item->yAxis()] |= QwtInterval( rect.top(), rect.bottom() );
+        }
+    }
+
+    // Adjust scales
+
+    for ( int axisId = 0; axisId < axisCnt; axisId++ )
+    {
+        AxisData &d = *d_axisData[axisId];
+
+        double minValue = d.minValue;
+        double maxValue = d.maxValue;
+        double stepSize = d.stepSize;
+
+        if ( d.doAutoScale && intv[axisId].isValid() )
+        {
+            d.scaleDiv.invalidate();
+
+            minValue = intv[axisId].minValue();
+            maxValue = intv[axisId].maxValue();
+
+            d.scaleEngine->autoScale( d.maxMajor,
+                minValue, maxValue, stepSize );
+        }
+        if ( !d.scaleDiv.isValid() )
+        {
+            d.scaleDiv = d.scaleEngine->divideScale(
+                minValue, maxValue,
+                d.maxMajor, d.maxMinor, stepSize );
+        }
+
+        QwtScaleWidget *scaleWidget = axisWidget( axisId );
+        scaleWidget->setScaleDiv(
+            d.scaleEngine->transformation(), d.scaleDiv );
+
+        int startDist, endDist;
+        scaleWidget->getBorderDistHint( startDist, endDist );
+        scaleWidget->setBorderDist( startDist, endDist );
+    }
+
+    for ( it = itmList.begin(); it != itmList.end(); ++it )
+    {
+        QwtPlotItem *item = *it;
+        item->updateScaleDiv( *axisScaleDiv( item->xAxis() ),
+            *axisScaleDiv( item->yAxis() ) );
+    }
+}
+
Index: trunk/BNC/qwt/qwt_plot_canvas.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_canvas.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_canvas.cpp	(revision 4271)
@@ -0,0 +1,1079 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_canvas.h"
+#include "qwt_painter.h"
+#include "qwt_null_paintdevice.h"
+#include "qwt_math.h"
+#include "qwt_plot.h"
+#include <qpainter.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+#include <qpaintengine.h>
+#include <qevent.h>
+#include <qbitmap.h>
+#ifdef Q_WS_X11
+#include <qx11info_x11.h>
+#endif
+
+class QwtStyleSheetRecorder: public QwtNullPaintDevice
+{
+public:
+    QwtStyleSheetRecorder( const QSize &size ):
+        QwtNullPaintDevice( QPaintEngine::AllFeatures )
+    {
+        setSize( size );
+    }
+
+    virtual void updateState( const QPaintEngineState &state )
+    {
+        if ( state.state() & QPaintEngine::DirtyPen )
+        {
+            d_pen = state.pen();
+        }
+        if ( state.state() & QPaintEngine::DirtyBrush )
+        {
+            d_brush = state.brush();
+        }
+        if ( state.state() & QPaintEngine::DirtyBrushOrigin )
+        {
+            d_origin = state.brushOrigin();
+        }
+    }
+
+    virtual void drawRects(const QRectF *rects, int count )
+    {
+        for ( int i = 0; i < count; i++ )
+            border.rectList += rects[i];
+    }
+
+    virtual void drawPath( const QPainterPath &path )
+    {
+        const QRectF rect( QPointF( 0.0, 0.0 ) , size() );
+        if ( path.controlPointRect().contains( rect.center() ) )
+        {
+            setCornerRects( path );
+            alignCornerRects( rect );
+
+            background.path = path;
+            background.brush = d_brush;
+            background.origin = d_origin;
+        }
+        else
+        {
+            border.pathList += path;
+        }
+    }
+
+    void setCornerRects( const QPainterPath &path )
+    {
+        QPointF pos( 0.0, 0.0 );
+
+        for ( int i = 0; i < path.elementCount(); i++ )
+        {
+            QPainterPath::Element el = path.elementAt(i); 
+            switch( el.type )
+            {
+                case QPainterPath::MoveToElement:
+                case QPainterPath::LineToElement:
+                {
+                    pos.setX( el.x );
+                    pos.setY( el.y );
+                    break;
+                }
+                case QPainterPath::CurveToElement:
+                {
+                    QRectF r( pos, QPointF( el.x, el.y ) );
+                    clipRects += r.normalized();
+
+                    pos.setX( el.x );
+                    pos.setY( el.y );
+
+                    break;
+                }
+                case QPainterPath::CurveToDataElement:
+                {
+                    if ( clipRects.size() > 0 )
+                    {
+                        QRectF r = clipRects.last();
+                        r.setCoords( 
+                            qMin( r.left(), el.x ),
+                            qMin( r.top(), el.y ),
+                            qMax( r.right(), el.x ),
+                            qMax( r.bottom(), el.y )
+                        );
+                        clipRects.last() = r.normalized();
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+private:
+    void alignCornerRects( const QRectF &rect )
+    {
+        for ( int i = 0; i < clipRects.size(); i++ )
+        {
+            QRectF &r = clipRects[i];
+            if ( r.center().x() < rect.center().x() )
+                r.setLeft( rect.left() );
+            else
+                r.setRight( rect.right() );
+
+            if ( r.center().y() < rect.center().y() )
+                r.setTop( rect.top() );
+            else
+                r.setBottom( rect.bottom() );
+        }
+    }
+
+
+public:
+    QVector<QRectF> clipRects;
+
+    struct Border
+    {
+        QList<QPainterPath> pathList;
+        QList<QRectF> rectList;
+        QRegion clipRegion;
+    } border;
+
+    struct Background
+    {
+        QPainterPath path;
+        QBrush brush;
+        QPointF origin;
+    } background;
+
+private:
+    QPen d_pen;
+    QBrush d_brush;
+    QPointF d_origin;
+};
+
+static void qwtDrawBackground( QPainter *painter, QWidget *widget )
+{
+    const QBrush &brush = 
+        widget->palette().brush( widget->backgroundRole() );
+
+    if ( brush.style() == Qt::TexturePattern )
+    {
+        QPixmap pm( widget->size() );
+        pm.fill( widget, 0, 0 );
+        painter->drawPixmap( 0, 0, pm );
+    }
+    else if ( brush.gradient() )
+    {
+        QVector<QRect> rects;
+
+        if ( brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode )
+        {
+            rects += widget->rect();
+        } 
+        else 
+        {
+            rects = painter->clipRegion().rects();
+        }
+
+#if 1
+        bool useRaster = false;
+
+        if ( painter->paintEngine()->type() == QPaintEngine::X11 )
+        {
+            // Qt 4.7.1: gradients on X11 are broken ( subrects + 
+            // QGradient::StretchToDeviceMode ) and horrible slow.
+            // As workaround we have to use the raster paintengine.
+            // Even if the QImage -> QPixmap translation is slow
+            // it is three times faster, than using X11 directly
+
+            useRaster = true;
+        }
+#endif
+        if ( useRaster )
+        {
+            QImage::Format format = QImage::Format_RGB32;
+
+            const QGradientStops stops = brush.gradient()->stops();
+            for ( int i = 0; i < stops.size(); i++ )
+            {
+                if ( stops[i].second.alpha() != 255 )
+                {
+                    // don't use Format_ARGB32_Premultiplied. It's
+                    // recommended by the Qt docs, but QPainter::drawImage()
+                    // is horrible slow on X11.
+
+                    format = QImage::Format_ARGB32;
+                    break;
+                }
+            }
+            
+            QImage image( widget->size(), format );
+
+            QPainter p( &image );
+            p.setPen( Qt::NoPen );
+            p.setBrush( brush );
+
+            p.drawRects( rects );
+
+            p.end();
+
+            painter->drawImage( 0, 0, image );
+        }
+        else
+        {
+            painter->save();
+
+            painter->setPen( Qt::NoPen );
+            painter->setBrush( brush );
+
+            painter->drawRects( rects );
+
+            painter->restore();
+        }
+    }
+    else
+    {
+        painter->save();
+
+        painter->setPen( Qt::NoPen );
+        painter->setBrush( brush );
+
+        painter->drawRects( painter->clipRegion().rects() );
+
+        painter->restore();
+    }
+}
+
+static inline void qwtRevertPath( QPainterPath &path )
+{
+    if ( path.elementCount() == 4 )
+    {
+        QPainterPath::Element &el0 = 
+            const_cast<QPainterPath::Element &>( path.elementAt(0) );
+        QPainterPath::Element &el2 = 
+            const_cast<QPainterPath::Element &>( path.elementAt(3) );
+
+        qSwap( el0.x, el2.x );
+        qSwap( el0.y, el2.y );
+    }
+}
+
+static QPainterPath qwtCombinePathList( const QRectF &rect, 
+    const QList<QPainterPath> &pathList )
+{
+    if ( pathList.isEmpty() )
+        return QPainterPath();
+
+    QPainterPath ordered[8]; // starting top left
+
+    for ( int i = 0; i < pathList.size(); i++ )
+    {
+        int index = -1;
+        QPainterPath subPath = pathList[i];
+
+        const QRectF br = pathList[i].controlPointRect();
+        if ( br.center().x() < rect.center().x() )
+        {
+            if ( br.center().y() < rect.center().y() )
+            {
+                if ( qAbs( br.top() - rect.top() ) < 
+                    qAbs( br.left() - rect.left() ) )
+                {
+                    index = 1;
+                }
+                else
+                {
+                    index = 0;
+                }
+            }
+            else
+            {
+                if ( qAbs( br.bottom() - rect.bottom() ) < 
+                    qAbs( br.left() - rect.left() ) )
+                {
+                    index = 6;
+                }
+                else
+                {
+                    index = 7;
+                }
+            }
+
+            if ( subPath.currentPosition().y() > br.center().y() )
+                qwtRevertPath( subPath );
+        }
+        else
+        {
+            if ( br.center().y() < rect.center().y() )
+            {
+                if ( qAbs( br.top() - rect.top() ) < 
+                    qAbs( br.right() - rect.right() ) )
+                {
+                    index = 2;
+                }
+                else
+                {
+                    index = 3;
+                }
+            }
+            else
+            {
+                if ( qAbs( br.bottom() - rect.bottom() ) < 
+                    qAbs( br.right() - rect.right() ) )
+                {
+                    index = 5;
+                }
+                else
+                {
+                    index = 4;
+                }
+            }
+            if ( subPath.currentPosition().y() < br.center().y() )
+                qwtRevertPath( subPath );
+        }   
+        ordered[index] = subPath;
+    }
+
+    for ( int i = 0; i < 4; i++ )
+    {
+        if ( ordered[ 2 * i].isEmpty() != ordered[2 * i + 1].isEmpty() )
+        {
+            // we don't accept incomplete rounded borders
+            return QPainterPath();
+        }
+    }
+
+
+    const QPolygonF corners( rect );
+
+    QPainterPath path;
+    //path.moveTo( rect.topLeft() );
+
+    for ( int i = 0; i < 4; i++ )
+    {
+        if ( ordered[2 * i].isEmpty() )
+        {
+            path.lineTo( corners[i] );
+        }
+        else
+        {
+            path.connectPath( ordered[2 * i] );
+            path.connectPath( ordered[2 * i + 1] );
+        }
+    }
+
+    path.closeSubpath();
+
+#if 0
+    return path.simplified();
+#else
+    return path;
+#endif
+}
+
+static inline void qwtDrawStyledBackground( 
+    QWidget *w, QPainter *painter )
+{
+    QStyleOption opt;
+    opt.initFrom(w);
+    w->style()->drawPrimitive( QStyle::PE_Widget, &opt, painter, w);
+}
+
+static QWidget *qwtBackgroundWidget( QWidget *w )
+{
+    if ( w->parentWidget() == NULL )
+        return w;
+
+    if ( w->autoFillBackground() )
+    {
+        const QBrush brush = w->palette().brush( w->backgroundRole() );
+        if ( brush.color().alpha() > 0 )
+            return w;
+    }
+
+    if ( w->testAttribute( Qt::WA_StyledBackground ) )
+    {
+        QImage image( 1, 1, QImage::Format_ARGB32 );
+        image.fill( Qt::transparent );
+
+        QPainter painter( &image );
+        painter.translate( -w->rect().center() );
+        qwtDrawStyledBackground( w, &painter );
+        painter.end();
+
+        if ( qAlpha( image.pixel( 0, 0 ) ) != 0 )
+            return w;
+    }
+
+    return qwtBackgroundWidget( w->parentWidget() );
+}
+
+static void qwtFillBackground( QPainter *painter, 
+    QWidget *widget, const QVector<QRectF> &fillRects )
+{
+    if ( fillRects.isEmpty() )
+        return;
+
+    QRegion clipRegion;
+    if ( painter->hasClipping() )
+        clipRegion = painter->transform().map( painter->clipRegion() );
+    else
+        clipRegion = widget->contentsRect();
+
+    // Try to find out which widget fills
+    // the unfilled areas of the styled background
+
+    QWidget *bgWidget = qwtBackgroundWidget( widget->parentWidget() );
+
+    for ( int i = 0; i < fillRects.size(); i++ )
+    {
+        const QRect rect = fillRects[i].toAlignedRect();
+        if ( clipRegion.intersects( rect ) )
+        {
+            QPixmap pm( rect.size() );
+            pm.fill( bgWidget, widget->mapTo( bgWidget, rect.topLeft() ) );
+            painter->drawPixmap( rect, pm );
+        }
+    }
+}
+
+static void qwtFillBackground( QPainter *painter, QwtPlotCanvas *canvas )
+{
+    QVector<QRectF> rects;
+
+    if ( canvas->testAttribute( Qt::WA_StyledBackground ) )
+    {
+        QwtStyleSheetRecorder recorder( canvas->size() );
+
+        QPainter p( &recorder );
+        qwtDrawStyledBackground( canvas, &p );
+        p.end();
+
+        if ( recorder.background.brush.isOpaque() )
+            rects = recorder.clipRects;
+        else
+            rects += canvas->rect();
+    }
+    else
+    {
+        const QRectF r = canvas->rect();
+        const double radius = canvas->borderRadius();
+        if ( radius > 0.0 )
+        {
+            QSize sz( radius, radius );
+
+            rects += QRectF( r.topLeft(), sz );
+            rects += QRectF( r.topRight() - QPointF( radius, 0 ), sz );
+            rects += QRectF( r.bottomRight() - QPointF( radius, radius ), sz );
+            rects += QRectF( r.bottomLeft() - QPointF( 0, radius ), sz );
+        }
+    }
+
+    qwtFillBackground( painter, canvas, rects);
+}
+
+
+class QwtPlotCanvas::PrivateData
+{
+public:
+    PrivateData():
+        focusIndicator( NoFocusIndicator ),
+        borderRadius( 0 ),
+        paintAttributes( 0 ),
+        backingStore( NULL )
+    {
+        styleSheet.hasBorder = false;
+    }
+
+    ~PrivateData()
+    {
+        delete backingStore;
+    }
+
+    FocusIndicator focusIndicator;
+    double borderRadius;
+    QwtPlotCanvas::PaintAttributes paintAttributes;
+    QPixmap *backingStore;
+
+    struct StyleSheet
+    {
+        bool hasBorder;
+        QPainterPath borderPath;
+        QVector<QRectF> cornerRects;
+
+        struct StyleSheetBackground
+        {
+            QBrush brush;
+            QPointF origin;
+        } background;
+
+    } styleSheet;
+
+};
+
+//! Sets a cross cursor, enables QwtPlotCanvas::BackingStore
+
+QwtPlotCanvas::QwtPlotCanvas( QwtPlot *plot ):
+    QFrame( plot )
+{
+    d_data = new PrivateData;
+
+#ifndef QT_NO_CURSOR
+    setCursor( Qt::CrossCursor );
+#endif
+
+    setAutoFillBackground( true );
+    setPaintAttribute( QwtPlotCanvas::BackingStore, true );
+    setPaintAttribute( QwtPlotCanvas::Opaque, true );
+    setPaintAttribute( QwtPlotCanvas::HackStyledBackground, true );
+}
+
+//! Destructor
+QwtPlotCanvas::~QwtPlotCanvas()
+{
+    delete d_data;
+}
+
+//! Return parent plot widget
+QwtPlot *QwtPlotCanvas::plot()
+{
+    return qobject_cast<QwtPlot *>( parentWidget() );
+}
+
+//! Return parent plot widget
+const QwtPlot *QwtPlotCanvas::plot() const
+{
+    return qobject_cast<const QwtPlot *>( parentWidget() );
+}
+
+/*!
+  \brief Changing the paint attributes
+
+  \param attribute Paint attribute
+  \param on On/Off
+
+  \sa testPaintAttribute(), backingStore()
+*/
+void QwtPlotCanvas::setPaintAttribute( PaintAttribute attribute, bool on )
+{
+    if ( bool( d_data->paintAttributes & attribute ) == on )
+        return;
+
+    if ( on )
+        d_data->paintAttributes |= attribute;
+    else
+        d_data->paintAttributes &= ~attribute;
+
+    switch ( attribute )
+    {
+        case BackingStore:
+        {
+            if ( on )
+            {
+                if ( d_data->backingStore == NULL )
+                    d_data->backingStore = new QPixmap();
+
+                if ( isVisible() )
+                {
+                    *d_data->backingStore = 
+                        QPixmap::grabWidget( this, rect() );
+                }
+            }
+            else
+            {
+                delete d_data->backingStore;
+                d_data->backingStore = NULL;
+            }
+            break;
+        }
+        case Opaque:
+        {
+            if ( on )
+                setAttribute( Qt::WA_OpaquePaintEvent, true );
+
+            break;
+        }
+        case HackStyledBackground:
+        case ImmediatePaint:
+        {
+            break;
+        }
+    }
+}
+
+/*!
+  Test wether a paint attribute is enabled
+
+  \param attribute Paint attribute
+  \return true if the attribute is enabled
+  \sa setPaintAttribute()
+*/
+bool QwtPlotCanvas::testPaintAttribute( PaintAttribute attribute ) const
+{
+    return d_data->paintAttributes & attribute;
+}
+
+//! \return Backing store, might be null
+const QPixmap *QwtPlotCanvas::backingStore() const
+{
+    return d_data->backingStore;
+}
+
+//! Invalidate the internal backing store
+void QwtPlotCanvas::invalidateBackingStore()
+{
+    if ( d_data->backingStore )
+        *d_data->backingStore = QPixmap();
+}
+
+/*!
+  Set the focus indicator
+
+  \sa FocusIndicator, focusIndicator()
+*/
+void QwtPlotCanvas::setFocusIndicator( FocusIndicator focusIndicator )
+{
+    d_data->focusIndicator = focusIndicator;
+}
+
+/*!
+  \return Focus indicator
+
+  \sa FocusIndicator, setFocusIndicator()
+*/
+QwtPlotCanvas::FocusIndicator QwtPlotCanvas::focusIndicator() const
+{
+    return d_data->focusIndicator;
+}
+
+/*!
+  Set the radius for the corners of the border frame
+
+  \param radius Radius of a rounded corner
+  \sa borderRadius()
+*/
+void QwtPlotCanvas::setBorderRadius( double radius )
+{
+    d_data->borderRadius = qMax( 0.0, radius );
+}
+
+/*!
+  \return Radius for the corners of the border frame
+  \sa setBorderRadius()
+*/
+double QwtPlotCanvas::borderRadius() const
+{
+    return d_data->borderRadius;
+}
+
+/*!
+  Qt event handler for QEvent::PolishRequest and QEvent::StyleChange
+  \param event Qt Event
+*/
+bool QwtPlotCanvas::event( QEvent *event )
+{
+    if ( event->type() == QEvent::PolishRequest ) 
+    {
+        if ( testPaintAttribute( QwtPlotCanvas::Opaque ) )
+        {
+            // Setting a style sheet changes the 
+            // Qt::WA_OpaquePaintEvent attribute, but we insist
+            // on painting the background.
+            
+            setAttribute( Qt::WA_OpaquePaintEvent, true );
+        }
+    }
+
+    if ( event->type() == QEvent::PolishRequest || 
+        event->type() == QEvent::StyleChange )
+    {
+        updateStyleSheetInfo();
+    }
+
+    return QFrame::event( event );
+}
+
+/*!
+  Paint event
+  \param event Paint event
+*/
+void QwtPlotCanvas::paintEvent( QPaintEvent *event )
+{
+    QPainter painter( this );
+    painter.setClipRegion( event->region() );
+
+    if ( testPaintAttribute( QwtPlotCanvas::BackingStore ) &&
+        d_data->backingStore != NULL )
+    {
+        QPixmap &bs = *d_data->backingStore;
+        if ( bs.size() != size() )
+        {
+            bs = QPixmap( size() );
+
+#ifdef Q_WS_X11
+            if ( bs.x11Info().screen() != x11Info().screen() )
+                bs.x11SetScreen( x11Info().screen() );
+#endif
+
+            if ( testAttribute(Qt::WA_StyledBackground) )
+            {
+                QPainter p( &bs );
+                qwtFillBackground( &p, this );
+                drawCanvas( &p, true );
+            }
+            else
+            {
+                QPainter p;
+                if ( d_data->borderRadius <= 0.0 )
+                {
+                    bs.fill( this, 0, 0 );
+                    p.begin( &bs );
+                    drawCanvas( &p, false );
+                }
+                else
+                {
+                    p.begin( &bs );
+                    qwtFillBackground( &p, this );
+                    drawCanvas( &p, true );
+                }
+
+                if ( frameWidth() > 0 )
+                    drawBorder( &p );
+            }
+        }
+
+        painter.drawPixmap( 0, 0, *d_data->backingStore );
+    }
+    else
+    {
+        if ( testAttribute(Qt::WA_StyledBackground ) )
+        {
+            if ( testAttribute( Qt::WA_OpaquePaintEvent ) )
+            {
+                qwtFillBackground( &painter, this );
+                drawCanvas( &painter, true );
+            }
+            else
+            {
+                drawCanvas( &painter, false );
+            }
+        }
+        else
+        {
+            if ( testAttribute( Qt::WA_OpaquePaintEvent ) )
+            {
+                if ( autoFillBackground() )
+                    qwtDrawBackground( &painter, this );
+            }
+
+            drawCanvas( &painter, false );
+
+            if ( frameWidth() > 0 ) 
+                drawBorder( &painter );
+        }
+    }
+
+    if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )
+        drawFocusIndicator( &painter );
+}
+
+void QwtPlotCanvas::drawCanvas( QPainter *painter, bool withBackground ) 
+{
+    bool hackStyledBackground = false;
+
+    if ( withBackground && testAttribute( Qt::WA_StyledBackground ) 
+        && testPaintAttribute( HackStyledBackground ) )
+    {
+        // Antialiasing rounded borders is done by
+        // inserting pixels with colors between the 
+        // border color and the color on the canvas,
+        // When the border is painted before the plot items
+        // these colors are interpolated for the canvas
+        // and the plot items need to be clipped excluding
+        // the anialiased pixels. In situations, where
+        // the plot items fill the area at the rounded
+        // borders this is noticeable.
+        // The only way to avoid these annoying "artefacts"
+        // is to paint the border on top of the plot items.
+
+        if ( d_data->styleSheet.hasBorder &&
+            !d_data->styleSheet.borderPath.isEmpty() )
+        {
+            // We have a border with at least one rounded corner
+            hackStyledBackground = true;
+        }
+    }
+
+    if ( withBackground )
+    {
+        painter->save();
+
+        if ( testAttribute( Qt::WA_StyledBackground ) )
+        {
+            if ( hackStyledBackground )
+            {
+                // paint background without border
+
+                painter->setPen( Qt::NoPen );
+                painter->setBrush( d_data->styleSheet.background.brush ); 
+                painter->setBrushOrigin( d_data->styleSheet.background.origin );
+                painter->setClipPath( d_data->styleSheet.borderPath );
+                painter->drawRect( contentsRect() );
+            }
+            else
+            {
+                qwtDrawStyledBackground( this, painter );
+            }
+        }
+        else if ( autoFillBackground() )
+        {
+            painter->setPen( Qt::NoPen );
+            painter->setBrush( palette().brush( backgroundRole() ) );
+
+            if ( d_data->borderRadius > 0.0 )
+            {
+                if ( frameWidth() > 0 )
+                {
+                    painter->setClipPath( borderPath( rect() ) );
+                    painter->drawRect( rect() );
+                }
+                else
+                {
+                    painter->setRenderHint( QPainter::Antialiasing, true );
+                    painter->drawPath( borderPath( rect() ) );
+                }
+            }
+            else
+            {
+                painter->drawRect( contentsRect() );
+            }
+        }
+
+        painter->restore();
+    }
+
+    painter->save();
+
+    if ( !d_data->styleSheet.borderPath.isEmpty() )
+    {
+        painter->setClipPath( 
+            d_data->styleSheet.borderPath, Qt::IntersectClip );
+    }
+    else
+    {
+        if ( d_data->borderRadius > 0.0 )
+            painter->setClipPath( borderPath( rect() ), Qt::IntersectClip );
+        else
+            painter->setClipRect( contentsRect(), Qt::IntersectClip );
+    }
+
+    plot()->drawCanvas( painter );
+
+    painter->restore();
+
+    if ( withBackground && hackStyledBackground )
+    {
+        // Now paint the border on top
+        QStyleOptionFrame opt;
+        opt.initFrom(this);
+        style()->drawPrimitive( QStyle::PE_Frame, &opt, painter, this);
+    }
+}
+
+/*!
+  Draw the border of the plot canvas
+
+  \param painter Painter
+  \sa setBorderRadius(), QFrame::drawFrame()
+*/
+void QwtPlotCanvas::drawBorder( QPainter *painter )
+{
+    if ( d_data->borderRadius > 0 )
+    {
+        if ( frameWidth() > 0 )
+        {
+            QwtPainter::drawRoundedFrame( painter, QRectF( rect() ), 
+                d_data->borderRadius, d_data->borderRadius,
+                palette(), frameWidth(), frameStyle() );
+        }
+    }
+    else
+    {
+        drawFrame( painter );
+    }
+}
+
+/*!
+  Resize event
+  \param event Resize event
+*/
+void QwtPlotCanvas::resizeEvent( QResizeEvent *event )
+{
+    QFrame::resizeEvent( event );
+    updateStyleSheetInfo();
+}
+
+/*!
+  Draw the focus indication
+  \param painter Painter
+*/
+void QwtPlotCanvas::drawFocusIndicator( QPainter *painter )
+{
+    const int margin = 1;
+
+    QRect focusRect = contentsRect();
+    focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin,
+        focusRect.width() - 2 * margin, focusRect.height() - 2 * margin );
+
+    QwtPainter::drawFocusRect( painter, this, focusRect );
+}
+
+/*!
+   Invalidate the paint cache and repaint the canvas
+   \sa invalidatePaintCache()
+*/
+void QwtPlotCanvas::replot()
+{
+    invalidateBackingStore();
+
+    if ( testPaintAttribute( QwtPlotCanvas::ImmediatePaint ) )
+        repaint( contentsRect() );
+    else
+        update( contentsRect() );
+}
+
+//! Update the cached informations about the current style sheet
+void QwtPlotCanvas::updateStyleSheetInfo()
+{
+    if ( !testAttribute(Qt::WA_StyledBackground ) )
+        return;
+
+    QwtStyleSheetRecorder recorder( size() );
+    
+    QPainter painter( &recorder );
+    
+    QStyleOption opt;
+    opt.initFrom(this);
+    style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, this);
+    
+    painter.end();
+
+    d_data->styleSheet.hasBorder = !recorder.border.rectList.isEmpty();
+    d_data->styleSheet.cornerRects = recorder.clipRects;
+
+    if ( recorder.background.path.isEmpty() )
+    {
+        if ( !recorder.border.rectList.isEmpty() )
+        {
+            d_data->styleSheet.borderPath = 
+                qwtCombinePathList( rect(), recorder.border.pathList );
+        }
+    }
+    else
+    {
+        d_data->styleSheet.borderPath = recorder.background.path;
+        d_data->styleSheet.background.brush = recorder.background.brush;
+        d_data->styleSheet.background.origin = recorder.background.origin;
+    }
+}
+
+/*!
+   Calculate the painter path for a styled or rounded border
+
+   When the canvas has no styled background or rounded borders
+   the painter path is empty.
+
+   \param rect Bounding rectangle of the canvas
+   \return Painter path, that can be used for clipping
+*/
+QPainterPath QwtPlotCanvas::borderPath( const QRect &rect ) const
+{
+    if ( testAttribute(Qt::WA_StyledBackground ) )
+    {
+        QwtStyleSheetRecorder recorder( rect.size() );
+
+        QPainter painter( &recorder );
+
+        QStyleOption opt;
+        opt.initFrom(this);
+        opt.rect = rect;
+        style()->drawPrimitive( QStyle::PE_Widget, &opt, &painter, this);
+
+        painter.end();
+
+        if ( !recorder.background.path.isEmpty() )
+            return recorder.background.path;
+
+        if ( !recorder.border.rectList.isEmpty() )
+            return qwtCombinePathList( rect, recorder.border.pathList );
+    }
+    else if ( d_data->borderRadius > 0.0 )
+    {
+        double fw2 = frameWidth() * 0.5;
+        QRectF r = QRectF(rect).adjusted( fw2, fw2, -fw2, -fw2 );
+
+        QPainterPath path;
+        path.addRoundedRect( r, d_data->borderRadius, d_data->borderRadius );
+        return path;
+    }
+    
+    return QPainterPath();
+}
+
+/*!
+   Calculate a mask, that can be used to clip away the border frame
+
+   \param size Size including the frame
+*/
+QBitmap QwtPlotCanvas::borderMask( const QSize &size ) const
+{
+    const QRect r( 0, 0, size.width(), size.height() );
+
+    const QPainterPath path = borderPath( r );
+    if ( path.isEmpty() )
+        return QBitmap();
+
+    QImage image( size, QImage::Format_ARGB32_Premultiplied );
+    image.fill( Qt::color0 );
+
+    QPainter painter( &image );
+    painter.setClipPath( path );
+    painter.fillRect( r, Qt::color1 );
+
+    // now erase the frame
+
+    painter.setCompositionMode( QPainter::CompositionMode_DestinationOut );
+
+    if ( testAttribute(Qt::WA_StyledBackground ) )
+    {
+        QStyleOptionFrame opt;
+        opt.initFrom(this);
+        opt.rect = r;
+        style()->drawPrimitive( QStyle::PE_Frame, &opt, &painter, this );
+    }
+    else
+    {
+        if ( d_data->borderRadius > 0 && frameWidth() > 0 )
+        {
+            painter.setPen( QPen( Qt::color1, frameWidth() ) );
+            painter.setBrush( Qt::NoBrush );
+            painter.setRenderHint( QPainter::Antialiasing, true );
+
+            painter.drawPath( path );
+        }
+    }
+
+    painter.end();
+
+    const QImage mask = image.createMaskFromColor(
+        QColor( Qt::color1 ).rgb(), Qt::MaskOutColor );
+
+    return QBitmap::fromImage( mask );
+}
Index: trunk/BNC/qwt/qwt_plot_canvas.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_canvas.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_canvas.h	(revision 4271)
@@ -0,0 +1,168 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_CANVAS_H
+#define QWT_PLOT_CANVAS_H
+
+#include "qwt_global.h"
+#include <qframe.h>
+#include <qpen.h>
+#include <qpainterpath.h>
+#include <qbitmap.h>
+
+class QwtPlot;
+class QPixmap;
+
+/*!
+  \brief Canvas of a QwtPlot.
+  \sa QwtPlot
+*/
+class QWT_EXPORT QwtPlotCanvas : public QFrame
+{
+    Q_OBJECT
+
+public:
+
+    /*!
+      \brief Paint attributes
+
+      The default setting enables BackingStore and Opaque.
+
+      \sa setPaintAttribute(), testPaintAttribute()
+     */
+    enum PaintAttribute
+    {
+        /*!
+          \brief Paint double buffered reusing the content 
+                 of the pixmap buffer when possible. 
+
+          Using a backing store might improve the performance
+          significantly, when workin with widget overlays ( like rubberbands ).
+          Disabling the cache might improve the performance for
+          incremental paints (using QwtPlotDirectPainter ).
+
+          \sa backingStore(), invalidateBackingStore()
+         */
+        BackingStore = 1,
+
+        /*!
+          \brief Try to fill the complete contents rectangle
+                 of the plot canvas
+
+          When using styled backgrounds Qt assumes, that the
+          canvas doesn't fill its area completely 
+          ( f.e because of rounded borders ) and fills the area
+          below the canvas. When this is done with gradients it might
+          result in a serious performance bottleneck - depending on the size.
+
+          When the Opaque attribute is enabled the canvas tries to
+          identify the gaps with some heuristics and to fill those only. 
+
+          \warning Will not work for semitransparent backgrounds 
+         */
+        Opaque       = 2,
+
+        /*!
+          \brief Try to improve painting of styled backgrounds
+
+          QwtPlotCanvas supports the box model attributes for
+          customizing the layout with style sheets. Unfortunately
+          the design of Qt style sheets has no concept how to
+          handle backgrounds with rounded corners - beside of padding.
+
+          When HackStyledBackground is enabled the plot canvas tries
+          to seperate the background from the background border
+          by reverse engeneering to paint the background before and
+          the border after the plot items. In this order the border
+          gets prefectly antialiased and you can avoid some pixel
+          artifacts in the corners.
+         */
+        HackStyledBackground = 4,
+
+        /*!
+          When ImmediatePaint is set replot() calls repaint()
+          instead of update().
+
+          \sa replot(), QWidget::repaint(), QWidget::update()
+         */
+        ImmediatePaint = 8
+    };
+
+    //! Paint attributes
+    typedef QFlags<PaintAttribute> PaintAttributes;
+
+    /*!
+      \brief Focus indicator
+
+      - NoFocusIndicator\n
+        Don't paint a focus indicator
+
+      - CanvasFocusIndicator\n
+        The focus is related to the complete canvas.
+        Paint the focus indicator using paintFocus()
+
+      - ItemFocusIndicator\n
+        The focus is related to an item (curve, point, ...) on
+        the canvas. It is up to the application to display a
+        focus indication using f.e. highlighting.
+
+      \sa setFocusIndicator(), focusIndicator(), paintFocus()
+    */
+
+    enum FocusIndicator
+    {
+        NoFocusIndicator,
+        CanvasFocusIndicator,
+        ItemFocusIndicator
+    };
+
+    explicit QwtPlotCanvas( QwtPlot * );
+    virtual ~QwtPlotCanvas();
+
+    QwtPlot *plot();
+    const QwtPlot *plot() const;
+
+    void setFocusIndicator( FocusIndicator );
+    FocusIndicator focusIndicator() const;
+
+    void setBorderRadius( double );
+    double borderRadius() const;
+
+    QPainterPath borderPath( const QRect &rect ) const;
+    QBitmap borderMask( const QSize & ) const;
+
+    void setPaintAttribute( PaintAttribute, bool on = true );
+    bool testPaintAttribute( PaintAttribute ) const;
+
+    const QPixmap *backingStore() const;
+    void invalidateBackingStore();
+
+    void replot();
+
+    virtual bool event( QEvent * );
+
+protected:
+    virtual void paintEvent( QPaintEvent * );
+    virtual void resizeEvent( QResizeEvent * );
+
+    virtual void drawFocusIndicator( QPainter * );
+    virtual void drawBorder( QPainter * );
+
+    void updateStyleSheetInfo();
+
+private:
+    void drawCanvas( QPainter *, bool withBackground );
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCanvas::PaintAttributes )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_curve.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_curve.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_curve.cpp	(revision 4271)
@@ -0,0 +1,1124 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_curve.h"
+#include "qwt_math.h"
+#include "qwt_clipper.h"
+#include "qwt_painter.h"
+#include "qwt_legend.h"
+#include "qwt_legend_item.h"
+#include "qwt_scale_map.h"
+#include "qwt_plot.h"
+#include "qwt_plot_canvas.h"
+#include "qwt_curve_fitter.h"
+#include "qwt_symbol.h"
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qalgorithms.h>
+#include <qmath.h>
+
+static int verifyRange( int size, int &i1, int &i2 )
+{
+    if ( size < 1 )
+        return 0;
+
+    i1 = qBound( 0, i1, size - 1 );
+    i2 = qBound( 0, i2, size - 1 );
+
+    if ( i1 > i2 )
+        qSwap( i1, i2 );
+
+    return ( i2 - i1 + 1 );
+}
+
+class QwtPlotCurve::PrivateData
+{
+public:
+    PrivateData():
+        style( QwtPlotCurve::Lines ),
+        baseline( 0.0 ),
+        symbol( NULL ),
+        attributes( 0 ),
+        paintAttributes( QwtPlotCurve::ClipPolygons ),
+        legendAttributes( 0 )
+    {
+        pen = QPen( Qt::black );
+        curveFitter = new QwtSplineCurveFitter;
+    }
+
+    ~PrivateData()
+    {
+        delete symbol;
+        delete curveFitter;
+    }
+
+    QwtPlotCurve::CurveStyle style;
+    double baseline;
+
+    const QwtSymbol *symbol;
+    QwtCurveFitter *curveFitter;
+
+    QPen pen;
+    QBrush brush;
+
+    QwtPlotCurve::CurveAttributes attributes;
+    QwtPlotCurve::PaintAttributes paintAttributes;
+
+    QwtPlotCurve::LegendAttributes legendAttributes;
+};
+
+/*!
+  Constructor
+  \param title Title of the curve
+*/
+QwtPlotCurve::QwtPlotCurve( const QwtText &title ):
+    QwtPlotSeriesItem<QPointF>( title )
+{
+    init();
+}
+
+/*!
+  Constructor
+  \param title Title of the curve
+*/
+QwtPlotCurve::QwtPlotCurve( const QString &title ):
+    QwtPlotSeriesItem<QPointF>( QwtText( title ) )
+{
+    init();
+}
+
+//! Destructor
+QwtPlotCurve::~QwtPlotCurve()
+{
+    delete d_data;
+}
+
+//! Initialize internal members
+void QwtPlotCurve::init()
+{
+    setItemAttribute( QwtPlotItem::Legend );
+    setItemAttribute( QwtPlotItem::AutoScale );
+
+    d_data = new PrivateData;
+    d_series = new QwtPointSeriesData();
+
+    setZ( 20.0 );
+}
+
+//! \return QwtPlotItem::Rtti_PlotCurve
+int QwtPlotCurve::rtti() const
+{
+    return QwtPlotItem::Rtti_PlotCurve;
+}
+
+/*!
+  Specify an attribute how to draw the curve
+
+  \param attribute Paint attribute
+  \param on On/Off
+  \sa testPaintAttribute()
+*/
+void QwtPlotCurve::setPaintAttribute( PaintAttribute attribute, bool on )
+{
+    if ( on )
+        d_data->paintAttributes |= attribute;
+    else
+        d_data->paintAttributes &= ~attribute;
+}
+
+/*!
+    \brief Return the current paint attributes
+    \sa setPaintAttribute()
+*/
+bool QwtPlotCurve::testPaintAttribute( PaintAttribute attribute ) const
+{
+    return ( d_data->paintAttributes & attribute );
+}
+
+/*!
+  Specify an attribute how to draw the legend identifier
+
+  \param attribute Attribute
+  \param on On/Off
+  /sa testLegendAttribute()
+*/
+void QwtPlotCurve::setLegendAttribute( LegendAttribute attribute, bool on )
+{
+    if ( on )
+        d_data->legendAttributes |= attribute;
+    else
+        d_data->legendAttributes &= ~attribute;
+}
+
+/*!
+    \brief Return the current paint attributes
+    \sa setLegendAttribute()
+*/
+bool QwtPlotCurve::testLegendAttribute( LegendAttribute attribute ) const
+{
+    return ( d_data->legendAttributes & attribute );
+}
+
+/*!
+  Set the curve's drawing style
+
+  \param style Curve style
+  \sa style()
+*/
+void QwtPlotCurve::setStyle( CurveStyle style )
+{
+    if ( style != d_data->style )
+    {
+        d_data->style = style;
+        itemChanged();
+    }
+}
+
+/*!
+    Return the current style
+    \sa setStyle()
+*/
+QwtPlotCurve::CurveStyle QwtPlotCurve::style() const
+{
+    return d_data->style;
+}
+
+/*!
+  Assign a symbol
+
+  \param symbol Symbol
+  \sa symbol()
+*/
+void QwtPlotCurve::setSymbol( const QwtSymbol *symbol )
+{
+    if ( symbol != d_data->symbol )
+    {
+        delete d_data->symbol;
+        d_data->symbol = symbol;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Current symbol or NULL, when no symbol has been assigned
+  \sa setSymbol()
+*/
+const QwtSymbol *QwtPlotCurve::symbol() const
+{
+    return d_data->symbol;
+}
+
+/*!
+  Assign a pen
+
+  \param pen New pen
+  \sa pen(), brush()
+*/
+void QwtPlotCurve::setPen( const QPen &pen )
+{
+    if ( pen != d_data->pen )
+    {
+        d_data->pen = pen;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Pen used to draw the lines
+  \sa setPen(), brush()
+*/
+const QPen& QwtPlotCurve::pen() const
+{
+    return d_data->pen;
+}
+
+/*!
+  \brief Assign a brush.
+
+   In case of brush.style() != QBrush::NoBrush
+   and style() != QwtPlotCurve::Sticks
+   the area between the curve and the baseline will be filled.
+
+   In case !brush.color().isValid() the area will be filled by
+   pen.color(). The fill algorithm simply connects the first and the
+   last curve point to the baseline. So the curve data has to be sorted
+   (ascending or descending).
+
+  \param brush New brush
+  \sa brush(), setBaseline(), baseline()
+*/
+void QwtPlotCurve::setBrush( const QBrush &brush )
+{
+    if ( brush != d_data->brush )
+    {
+        d_data->brush = brush;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Brush used to fill the area between lines and the baseline
+  \sa setBrush(), setBaseline(), baseline()
+*/
+const QBrush& QwtPlotCurve::brush() const
+{
+    return d_data->brush;
+}
+
+/*!
+  Draw an interval of the curve
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param canvasRect Contents rect of the canvas
+  \param from Index of the first point to be painted
+  \param to Index of the last point to be painted. If to < 0 the
+         curve will be painted to its last point.
+
+  \sa drawCurve(), drawSymbols(),
+*/
+void QwtPlotCurve::drawSeries( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    if ( !painter || dataSize() <= 0 )
+        return;
+
+    if ( to < 0 )
+        to = dataSize() - 1;
+
+    if ( verifyRange( dataSize(), from, to ) > 0 )
+    {
+        painter->save();
+        painter->setPen( d_data->pen );
+
+        /*
+          Qt 4.0.0 is slow when drawing lines, but it's even
+          slower when the painter has a brush. So we don't
+          set the brush before we really need it.
+         */
+
+        drawCurve( painter, d_data->style, xMap, yMap, canvasRect, from, to );
+        painter->restore();
+
+        if ( d_data->symbol &&
+            ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
+        {
+            painter->save();
+            drawSymbols( painter, *d_data->symbol,
+                xMap, yMap, canvasRect, from, to );
+            painter->restore();
+        }
+    }
+}
+
+/*!
+  \brief Draw the line part (without symbols) of a curve interval.
+  \param painter Painter
+  \param style curve style, see QwtPlotCurve::CurveStyle
+  \param xMap x map
+  \param yMap y map
+  \param canvasRect Contents rect of the canvas
+  \param from index of the first point to be painted
+  \param to index of the last point to be painted
+  \sa draw(), drawDots(), drawLines(), drawSteps(), drawSticks()
+*/
+void QwtPlotCurve::drawCurve( QPainter *painter, int style,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    switch ( style )
+    {
+        case Lines:
+            if ( testCurveAttribute( Fitted ) )
+            {
+                // we always need the complete
+                // curve for fitting
+                from = 0;
+                to = dataSize() - 1;
+            }
+            drawLines( painter, xMap, yMap, canvasRect, from, to );
+            break;
+        case Sticks:
+            drawSticks( painter, xMap, yMap, canvasRect, from, to );
+            break;
+        case Steps:
+            drawSteps( painter, xMap, yMap, canvasRect, from, to );
+            break;
+        case Dots:
+            drawDots( painter, xMap, yMap, canvasRect, from, to );
+            break;
+        case NoCurve:
+        default:
+            break;
+    }
+}
+
+/*!
+  \brief Draw lines
+
+  If the CurveAttribute Fitted is enabled a QwtCurveFitter tries
+  to interpolate/smooth the curve, before it is painted.
+
+  \param painter Painter
+  \param xMap x map
+  \param yMap y map
+  \param canvasRect Contents rect of the canvas
+  \param from index of the first point to be painted
+  \param to index of the last point to be painted
+
+  \sa setCurveAttribute(), setCurveFitter(), draw(),
+      drawLines(), drawDots(), drawSteps(), drawSticks()
+*/
+void QwtPlotCurve::drawLines( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    int size = to - from + 1;
+    if ( size <= 0 )
+        return;
+
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    QPolygonF polyline( size );
+
+    QPointF *points = polyline.data();
+    for ( int i = from; i <= to; i++ )
+    {
+        const QPointF sample = d_series->sample( i );
+
+        double x = xMap.transform( sample.x() );
+        double y = yMap.transform( sample.y() );
+        if ( doAlign )
+        {
+            x = qRound( x );
+            y = qRound( y );
+        }
+
+        points[i - from].rx() = x;
+        points[i - from].ry() = y;
+    }
+
+    if ( ( d_data->attributes & Fitted ) && d_data->curveFitter )
+        polyline = d_data->curveFitter->fitCurve( polyline );
+
+    if ( d_data->paintAttributes & ClipPolygons )
+    {
+        qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
+        const QPolygonF clipped = QwtClipper::clipPolygonF( 
+            canvasRect.adjusted(-pw, -pw, pw, pw), polyline, false );
+
+        QwtPainter::drawPolyline( painter, clipped );
+    }
+    else
+    {
+        QwtPainter::drawPolyline( painter, polyline );
+    }
+
+    if ( d_data->brush.style() != Qt::NoBrush )
+        fillCurve( painter, xMap, yMap, canvasRect, polyline );
+}
+
+/*!
+  Draw sticks
+
+  \param painter Painter
+  \param xMap x map
+  \param yMap y map
+  \param canvasRect Contents rect of the canvas
+  \param from index of the first point to be painted
+  \param to index of the last point to be painted
+
+  \sa draw(), drawCurve(), drawDots(), drawLines(), drawSteps()
+*/
+void QwtPlotCurve::drawSticks( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &, int from, int to ) const
+{
+    painter->save();
+    painter->setRenderHint( QPainter::Antialiasing, false );
+
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    double x0 = xMap.transform( d_data->baseline );
+    double y0 = yMap.transform( d_data->baseline );
+    if ( doAlign )
+    {
+        x0 = qRound( x0 );
+        y0 = qRound( y0 );
+    }
+
+    const Qt::Orientation o = orientation();
+
+    for ( int i = from; i <= to; i++ )
+    {
+        const QPointF sample = d_series->sample( i );
+        double xi = xMap.transform( sample.x() );
+        double yi = yMap.transform( sample.y() );
+        if ( doAlign )
+        {
+            xi = qRound( xi );
+            yi = qRound( yi );
+        }
+
+        if ( o == Qt::Horizontal )
+            QwtPainter::drawLine( painter, x0, yi, xi, yi );
+        else
+            QwtPainter::drawLine( painter, xi, y0, xi, yi );
+    }
+
+    painter->restore();
+}
+
+/*!
+  Draw dots
+
+  \param painter Painter
+  \param xMap x map
+  \param yMap y map
+  \param canvasRect Contents rect of the canvas
+  \param from index of the first point to be painted
+  \param to index of the last point to be painted
+
+  \sa draw(), drawCurve(), drawSticks(), drawLines(), drawSteps()
+*/
+void QwtPlotCurve::drawDots( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    const bool doFill = d_data->brush.style() != Qt::NoBrush;
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    QPolygonF polyline;
+    if ( doFill )
+        polyline.resize( to - from + 1 );
+
+    QPointF *points = polyline.data();
+
+    for ( int i = from; i <= to; i++ )
+    {
+        const QPointF sample = d_series->sample( i );
+        double xi = xMap.transform( sample.x() );
+        double yi = yMap.transform( sample.y() );
+        if ( doAlign )
+        {
+            xi = qRound( xi );
+            yi = qRound( yi );
+        }
+
+        QwtPainter::drawPoint( painter, QPointF( xi, yi ) );
+
+        if ( doFill )
+        {
+            points[i - from].rx() = xi;
+            points[i - from].ry() = yi;
+        }
+    }
+
+    if ( doFill )
+        fillCurve( painter, xMap, yMap, canvasRect, polyline );
+}
+
+/*!
+  Draw step function
+
+  The direction of the steps depends on Inverted attribute.
+
+  \param painter Painter
+  \param xMap x map
+  \param yMap y map
+  \param canvasRect Contents rect of the canvas
+  \param from index of the first point to be painted
+  \param to index of the last point to be painted
+
+  \sa CurveAttribute, setCurveAttribute(),
+      draw(), drawCurve(), drawDots(), drawLines(), drawSticks()
+*/
+void QwtPlotCurve::drawSteps( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    QPolygonF polygon( 2 * ( to - from ) + 1 );
+    QPointF *points = polygon.data();
+
+    bool inverted = orientation() == Qt::Vertical;
+    if ( d_data->attributes & Inverted )
+        inverted = !inverted;
+
+    int i, ip;
+    for ( i = from, ip = 0; i <= to; i++, ip += 2 )
+    {
+        const QPointF sample = d_series->sample( i );
+        double xi = xMap.transform( sample.x() );
+        double yi = yMap.transform( sample.y() );
+        if ( doAlign )
+        {
+            xi = qRound( xi );
+            yi = qRound( yi );
+        }
+
+        if ( ip > 0 )
+        {
+            const QPointF &p0 = points[ip - 2];
+            QPointF &p = points[ip - 1];
+
+            if ( inverted )
+            {
+                p.rx() = p0.x();
+                p.ry() = yi;
+            }
+            else
+            {
+                p.rx() = xi;
+                p.ry() = p0.y();
+            }
+        }
+
+        points[ip].rx() = xi;
+        points[ip].ry() = yi;
+    }
+
+    if ( d_data->paintAttributes & ClipPolygons )
+    {
+        const QPolygonF clipped = QwtClipper::clipPolygonF( 
+            canvasRect, polygon, false );
+
+        QwtPainter::drawPolyline( painter, clipped );
+    }
+    else
+    {
+        QwtPainter::drawPolyline( painter, polygon );
+    }
+
+    if ( d_data->brush.style() != Qt::NoBrush )
+        fillCurve( painter, xMap, yMap, canvasRect, polygon );
+}
+
+
+/*!
+  Specify an attribute for drawing the curve
+
+  \param attribute Curve attribute
+  \param on On/Off
+
+  /sa testCurveAttribute(), setCurveFitter()
+*/
+void QwtPlotCurve::setCurveAttribute( CurveAttribute attribute, bool on )
+{
+    if ( bool( d_data->attributes & attribute ) == on )
+        return;
+
+    if ( on )
+        d_data->attributes |= attribute;
+    else
+        d_data->attributes &= ~attribute;
+
+    itemChanged();
+}
+
+/*!
+    \return true, if attribute is enabled
+    \sa setCurveAttribute()
+*/
+bool QwtPlotCurve::testCurveAttribute( CurveAttribute attribute ) const
+{
+    return d_data->attributes & attribute;
+}
+
+/*!
+  Assign a curve fitter
+
+  The curve fitter "smooths" the curve points, when the Fitted
+  CurveAttribute is set. setCurveFitter(NULL) also disables curve fitting.
+
+  The curve fitter operates on the translated points ( = widget coordinates)
+  to be functional for logarithmic scales. Obviously this is less performant
+  for fitting algorithms, that reduce the number of points.
+
+  For situations, where curve fitting is used to improve the performance
+  of painting huge series of points it might be better to execute the fitter
+  on the curve points once and to cache the result in the QwtSeriesData object.
+
+  \param curveFitter() Curve fitter
+  \sa Fitted
+*/
+void QwtPlotCurve::setCurveFitter( QwtCurveFitter *curveFitter )
+{
+    delete d_data->curveFitter;
+    d_data->curveFitter = curveFitter;
+
+    itemChanged();
+}
+
+/*!
+  Get the curve fitter. If curve fitting is disabled NULL is returned.
+
+  \return Curve fitter
+  \sa setCurveFitter(), Fitted
+*/
+QwtCurveFitter *QwtPlotCurve::curveFitter() const
+{
+    return d_data->curveFitter;
+}
+
+/*!
+  Fill the area between the curve and the baseline with
+  the curve brush
+
+  \param painter Painter
+  \param xMap x map
+  \param yMap y map
+  \param canvasRect Contents rect of the canvas
+  \param polygon Polygon - will be modified !
+
+  \sa setBrush(), setBaseline(), setStyle()
+*/
+void QwtPlotCurve::fillCurve( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, QPolygonF &polygon ) const
+{
+    if ( d_data->brush.style() == Qt::NoBrush )
+        return;
+
+    closePolyline( painter, xMap, yMap, polygon );
+    if ( polygon.count() <= 2 ) // a line can't be filled
+        return;
+
+    QBrush brush = d_data->brush;
+    if ( !brush.color().isValid() )
+        brush.setColor( d_data->pen.color() );
+
+    if ( d_data->paintAttributes & ClipPolygons )
+        polygon = QwtClipper::clipPolygonF( canvasRect, polygon, true );
+
+    painter->save();
+
+    painter->setPen( Qt::NoPen );
+    painter->setBrush( brush );
+
+    QwtPainter::drawPolygon( painter, polygon );
+
+    painter->restore();
+}
+
+/*!
+  \brief Complete a polygon to be a closed polygon including the 
+         area between the original polygon and the baseline.
+
+  \param painter Painter
+  \param xMap X map
+  \param yMap Y map
+  \param polygon Polygon to be completed
+*/
+void QwtPlotCurve::closePolyline( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    QPolygonF &polygon ) const
+{
+    if ( polygon.size() < 2 )
+        return;
+
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    double baseline = d_data->baseline;
+    
+    if ( orientation() == Qt::Vertical )
+    {
+        if ( yMap.transformation()->type() == QwtScaleTransformation::Log10 )
+        {
+            if ( baseline < QwtScaleMap::LogMin )
+                baseline = QwtScaleMap::LogMin;
+        }
+
+        double refY = yMap.transform( baseline );
+        if ( doAlign )
+            refY = qRound( refY );
+
+        polygon += QPointF( polygon.last().x(), refY );
+        polygon += QPointF( polygon.first().x(), refY );
+    }
+    else
+    {
+        if ( xMap.transformation()->type() == QwtScaleTransformation::Log10 )
+        {
+            if ( baseline < QwtScaleMap::LogMin )
+                baseline = QwtScaleMap::LogMin;
+        }
+
+        double refX = xMap.transform( baseline );
+        if ( doAlign )
+            refX = qRound( refX );
+
+        polygon += QPointF( refX, polygon.last().y() );
+        polygon += QPointF( refX, polygon.first().y() );
+    }
+}
+
+/*!
+  Draw symbols
+
+  \param painter Painter
+  \param symbol Curve symbol
+  \param xMap x map
+  \param yMap y map
+  \param canvasRect Contents rect of the canvas
+  \param from Index of the first point to be painted
+  \param to Index of the last point to be painted
+
+  \sa setSymbol(), drawSeries(), drawCurve()
+*/
+void QwtPlotCurve::drawSymbols( QPainter *painter, const QwtSymbol &symbol,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    bool usePixmap = testPaintAttribute( CacheSymbols );
+    if ( usePixmap && !doAlign )
+    {
+        // Don't use the pixmap, when the paint device
+        // could generate scalable vectors
+
+        usePixmap = false;
+    }
+
+    if ( usePixmap )
+    {
+        QPixmap pm( symbol.boundingSize() );
+        pm.fill( Qt::transparent );
+
+        const double pw2 = 0.5 * pm.width();
+        const double ph2 = 0.5 * pm.height();
+
+        QPainter p( &pm );
+        p.setRenderHints( painter->renderHints() );
+        symbol.drawSymbol( &p, QPointF( pw2, ph2 ) );
+        p.end();
+
+        for ( int i = from; i <= to; i++ )
+        {
+            const QPointF sample = d_series->sample( i );
+
+            double xi = xMap.transform( sample.x() );
+            double yi = yMap.transform( sample.y() );
+            if ( doAlign )
+            {
+                xi = qRound( xi );
+                yi = qRound( yi );
+            }
+
+            if ( canvasRect.contains( xi, yi ) )
+            {
+                const int left = qCeil( xi ) - pw2;
+                const int top = qCeil( yi ) - ph2;
+
+                painter->drawPixmap( left, top, pm );
+            }
+        }
+    }
+    else
+    {
+        const int chunkSize = 500;
+
+        for ( int i = from; i <= to; i += chunkSize )
+        {
+            const int n = qMin( chunkSize, to - i + 1 );
+
+            QPolygonF points;
+            for ( int j = 0; j < n; j++ )
+            {
+                const QPointF sample = d_series->sample( i + j );
+
+                const double xi = xMap.transform( sample.x() );
+                const double yi = yMap.transform( sample.y() );
+
+                if ( canvasRect.contains( xi, yi ) )
+                    points += QPointF( xi, yi );
+            }
+
+            if ( points.size() > 0 )
+                symbol.drawSymbols( painter, points );
+        }
+    }
+}
+
+/*!
+  \brief Set the value of the baseline
+
+  The baseline is needed for filling the curve with a brush or
+  the Sticks drawing style.
+  The interpretation of the baseline depends on the CurveType.
+  With QwtPlotCurve::Yfx, the baseline is interpreted as a horizontal line
+  at y = baseline(), with QwtPlotCurve::Yfy, it is interpreted as a vertical
+  line at x = baseline().
+
+  The default value is 0.0.
+
+  \param value Value of the baseline
+  \sa baseline(), setBrush(), setStyle(), setStyle()
+*/
+void QwtPlotCurve::setBaseline( double value )
+{
+    if ( d_data->baseline != value )
+    {
+        d_data->baseline = value;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Value of the baseline
+  \sa setBaseline()
+*/
+double QwtPlotCurve::baseline() const
+{
+    return d_data->baseline;
+}
+
+/*!
+  Find the closest curve point for a specific position
+
+  \param pos Position, where to look for the closest curve point
+  \param dist If dist != NULL, closestPoint() returns the distance between
+              the position and the clostest curve point
+  \return Index of the closest curve point, or -1 if none can be found
+          ( f.e when the curve has no points )
+  \note closestPoint() implements a dumb algorithm, that iterates
+        over all points
+*/
+int QwtPlotCurve::closestPoint( const QPoint &pos, double *dist ) const
+{
+    if ( plot() == NULL || dataSize() <= 0 )
+        return -1;
+
+    const QwtScaleMap xMap = plot()->canvasMap( xAxis() );
+    const QwtScaleMap yMap = plot()->canvasMap( yAxis() );
+
+    int index = -1;
+    double dmin = 1.0e10;
+
+    for ( uint i = 0; i < dataSize(); i++ )
+    {
+        const QPointF sample = d_series->sample( i );
+
+        const double cx = xMap.transform( sample.x() ) - pos.x();
+        const double cy = yMap.transform( sample.y() ) - pos.y();
+
+        const double f = qwtSqr( cx ) + qwtSqr( cy );
+        if ( f < dmin )
+        {
+            index = i;
+            dmin = f;
+        }
+    }
+    if ( dist )
+        *dist = qSqrt( dmin );
+
+    return index;
+}
+
+/*!
+   \brief Update the widget that represents the item on the legend
+
+   \param legend Legend
+   \sa drawLegendIdentifier(), legendItem(), QwtPlotItem::Legend
+*/
+void QwtPlotCurve::updateLegend( QwtLegend *legend ) const
+{
+    if ( legend && testItemAttribute( QwtPlotItem::Legend )
+        && ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol )
+        && d_data->symbol
+        && d_data->symbol->style() != QwtSymbol::NoSymbol )
+    {
+        QWidget *lgdItem = legend->find( this );
+        if ( lgdItem == NULL )
+        {
+            lgdItem = legendItem();
+            if ( lgdItem )
+                legend->insert( this, lgdItem );
+        }
+
+        QwtLegendItem *l = qobject_cast<QwtLegendItem *>( lgdItem );
+        if ( l )
+        {
+            QSize sz = d_data->symbol->boundingSize();
+            sz += QSize( 2, 2 ); // margin
+
+            if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine )
+            {
+                // Avoid, that the line is completely covered by the symbol
+
+                int w = qCeil( 1.5 * sz.width() );
+                if ( w % 2 )
+                    w++;
+
+                sz.setWidth( qMax( 8, w ) );
+            }
+
+            l->setIdentifierSize( sz );
+        }
+    }
+
+    QwtPlotItem::updateLegend( legend );
+}
+
+/*!
+  \brief Draw the identifier representing the curve on the legend
+
+  \param painter Painter
+  \param rect Bounding rectangle for the identifier
+
+  \sa setLegendAttribute(), QwtPlotItem::Legend
+*/
+void QwtPlotCurve::drawLegendIdentifier(
+    QPainter *painter, const QRectF &rect ) const
+{
+    if ( rect.isEmpty() )
+        return;
+
+    const int dim = qMin( rect.width(), rect.height() );
+
+    QSize size( dim, dim );
+
+    QRectF r( 0, 0, size.width(), size.height() );
+    r.moveCenter( rect.center() );
+
+    if ( d_data->legendAttributes == 0 )
+    {
+        QBrush brush = d_data->brush;
+        if ( brush.style() == Qt::NoBrush )
+        {
+            if ( style() != QwtPlotCurve::NoCurve )
+                brush = QBrush( pen().color() );
+            else if ( d_data->symbol &&
+                ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
+            {
+                brush = QBrush( d_data->symbol->pen().color() );
+            }
+        }
+        if ( brush.style() != Qt::NoBrush )
+            painter->fillRect( r, brush );
+    }
+    if ( d_data->legendAttributes & QwtPlotCurve::LegendShowBrush )
+    {
+        if ( d_data->brush.style() != Qt::NoBrush )
+            painter->fillRect( r, d_data->brush );
+    }
+    if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine )
+    {
+        if ( pen() != Qt::NoPen )
+        {
+            painter->setPen( pen() );
+            QwtPainter::drawLine( painter, rect.left(), rect.center().y(),
+                                  rect.right() - 1.0, rect.center().y() );
+        }
+    }
+    if ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol )
+    {
+        if ( d_data->symbol &&
+            ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
+        {
+            QSize symbolSize = d_data->symbol->boundingSize();
+            symbolSize -= QSize( 2, 2 );
+
+            // scale the symbol size down if it doesn't fit into rect.
+
+            double xRatio = 1.0;
+            if ( rect.width() < symbolSize.width() )
+                xRatio = rect.width() / symbolSize.width();
+            double yRatio = 1.0;
+            if ( rect.height() < symbolSize.height() )
+                yRatio = rect.height() / symbolSize.height();
+
+            const double ratio = qMin( xRatio, yRatio );
+
+            painter->save();
+            painter->scale( ratio, ratio );
+
+            d_data->symbol->drawSymbol( painter, rect.center() / ratio );
+
+            painter->restore();
+        }
+    }
+}
+
+/*!
+  Initialize data with an array of points (explicitly shared).
+
+  \param samples Vector of points
+*/
+void QwtPlotCurve::setSamples( const QVector<QPointF> &samples )
+{
+    delete d_series;
+    d_series = new QwtPointSeriesData( samples );
+    itemChanged();
+}
+
+#ifndef QWT_NO_COMPAT
+
+/*!
+  \brief Initialize the data by pointing to memory blocks which 
+         are not managed by QwtPlotCurve.
+
+  setRawSamples is provided for efficiency. 
+  It is important to keep the pointers
+  during the lifetime of the underlying QwtCPointerData class.
+
+  \param xData pointer to x data
+  \param yData pointer to y data
+  \param size size of x and y
+
+  \sa QwtCPointerData
+*/
+void QwtPlotCurve::setRawSamples( 
+    const double *xData, const double *yData, int size )
+{
+    delete d_series;
+    d_series = new QwtCPointerData( xData, yData, size );
+    itemChanged();
+}
+
+/*!
+  Set data by copying x- and y-values from specified memory blocks.
+  Contrary to setRawSamples(), this function makes a 'deep copy' of
+  the data.
+
+  \param xData pointer to x values
+  \param yData pointer to y values
+  \param size size of xData and yData
+
+  \sa QwtPointArrayData
+*/
+void QwtPlotCurve::setSamples( 
+    const double *xData, const double *yData, int size )
+{
+    delete d_series;
+    d_series = new QwtPointArrayData( xData, yData, size );
+    itemChanged();
+}
+
+/*!
+  \brief Initialize data with x- and y-arrays (explicitly shared)
+
+  \param xData x data
+  \param yData y data
+
+  \sa QwtPointArrayData
+*/
+void QwtPlotCurve::setSamples( const QVector<double> &xData,
+    const QVector<double> &yData )
+{
+    delete d_series;
+    d_series = new QwtPointArrayData( xData, yData );
+    itemChanged();
+}
+#endif // !QWT_NO_COMPAT
+
Index: trunk/BNC/qwt/qwt_plot_curve.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_curve.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_curve.h	(revision 4271)
@@ -0,0 +1,319 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_CURVE_H
+#define QWT_PLOT_CURVE_H
+
+#include "qwt_global.h"
+#include "qwt_plot_seriesitem.h"
+#include "qwt_series_data.h"
+#include "qwt_text.h"
+#include <qpen.h>
+#include <qstring.h>
+
+class QPainter;
+class QPolygonF;
+class QwtScaleMap;
+class QwtSymbol;
+class QwtCurveFitter;
+
+/*!
+  \brief A plot item, that represents a series of points
+
+  A curve is the representation of a series of points in the x-y plane.
+  It supports different display styles, interpolation ( f.e. spline )
+  and symbols.
+
+  \par Usage
+  <dl><dt>a) Assign curve properties</dt>
+  <dd>When a curve is created, it is configured to draw black solid lines
+  with in QwtPlotCurve::Lines style and no symbols. 
+  You can change this by calling
+  setPen(), setStyle() and setSymbol().</dd>
+  <dt>b) Connect/Assign data.</dt>
+  <dd>QwtPlotCurve gets its points using a QwtSeriesData object offering
+  a bridge to the real storage of the points ( like QAbstractItemModel ).
+  There are several convenience classes derived from QwtSeriesData, that also store
+  the points inside ( like QStandardItemModel ). QwtPlotCurve also offers
+  a couple of variations of setSamples(), that build QwtSeriesData objects from
+  arrays internally.</dd>
+  <dt>c) Attach the curve to a plot</dt>
+  <dd>See QwtPlotItem::attach()
+  </dd></dl>
+
+  \par Example:
+  see examples/bode
+
+  \sa QwtPointSeriesData, QwtSymbol, QwtScaleMap
+*/
+class QWT_EXPORT QwtPlotCurve: public QwtPlotSeriesItem<QPointF>
+{
+public:
+    /*!
+        Curve styles.
+        \sa setStyle(), style()
+    */
+    enum CurveStyle
+    {
+        /*!
+           Don't draw a curve. Note: This doesn't affect the symbols.
+        */
+        NoCurve = -1,
+
+        /*!
+           Connect the points with straight lines. The lines might
+           be interpolated depending on the 'Fitted' attribute. Curve
+           fitting can be configured using setCurveFitter().
+        */
+        Lines,
+
+        /*!
+           Draw vertical or horizontal sticks ( depending on the 
+           orientation() ) from a baseline which is defined by setBaseline().
+        */
+        Sticks,
+
+        /*!
+           Connect the points with a step function. The step function
+           is drawn from the left to the right or vice versa,
+           depending on the QwtPlotCurve::Inverted attribute.
+        */
+        Steps,
+
+        /*!
+           Draw dots at the locations of the data points. Note:
+           This is different from a dotted line (see setPen()), and faster
+           as a curve in QwtPlotCurve::NoStyle style and a symbol 
+           painting a point.
+        */
+        Dots,
+
+        /*!
+           Styles >= QwtPlotCurve::UserCurve are reserved for derived
+           classes of QwtPlotCurve that overload drawCurve() with
+           additional application specific curve types.
+        */
+        UserCurve = 100
+    };
+
+    /*!
+      Attribute for drawing the curve
+      \sa setCurveAttribute(), testCurveAttribute(), curveFitter()
+    */
+    enum CurveAttribute
+    {
+        /*!
+           For QwtPlotCurve::Steps only. 
+           Draws a step function from the right to the left.
+         */
+        Inverted = 0x01,
+
+        /*!
+          Only in combination with QwtPlotCurve::Lines
+          A QwtCurveFitter tries to
+          interpolate/smooth the curve, before it is painted.
+
+          \note Curve fitting requires temorary memory
+          for calculating coefficients and additional points.
+          If painting in QwtPlotCurve::Fitted mode is slow it might be better
+          to fit the points, before they are passed to QwtPlotCurve.
+         */
+        Fitted = 0x02
+    };
+
+    //! Curve attributes
+    typedef QFlags<CurveAttribute> CurveAttributes;
+
+    /*!
+        Attributes how to represent the curve on the legend
+
+        \sa setLegendAttribute(), testLegendAttribute(),
+            drawLegendIdentifier()
+     */
+
+    enum LegendAttribute
+    {
+        /*!
+          QwtPlotCurve tries to find a color representing the curve 
+          and paints a rectangle with it.
+         */
+        LegendNoAttribute = 0x00,
+
+        /*!
+          If the style() is not QwtPlotCurve::NoCurve a line 
+          is painted with the curve pen().
+         */
+        LegendShowLine = 0x01,
+
+        /*!
+          If the curve has a valid symbol it is painted.
+         */
+        LegendShowSymbol = 0x02,
+
+        /*!
+          If the curve has a brush a rectangle filled with the
+          curve brush() is painted.
+         */
+        LegendShowBrush = 0x04
+    };
+
+    //! Legend attributes
+    typedef QFlags<LegendAttribute> LegendAttributes;
+
+    /*!
+        Attributes to modify the drawing algorithm.
+        The default setting enables ClipPolygons
+
+        \sa setPaintAttribute(), testPaintAttribute()
+    */
+    enum PaintAttribute
+    {
+        /*!
+          Clip polygons before painting them. In situations, where points
+          are far outside the visible area (f.e when zooming deep) this
+          might be a substantial improvement for the painting performance
+         */
+        ClipPolygons = 0x01,
+
+        /*!
+          Paint the symbol to a QPixmap and paint the pixmap
+          instead rendering the symbol for each point. The flag has
+          no effect, when the curve is not painted to the canvas
+          ( f.e when exporting the plot to a PDF document ).
+         */
+        CacheSymbols = 0x02
+    };
+
+    //! Paint attributes
+    typedef QFlags<PaintAttribute> PaintAttributes;
+
+    explicit QwtPlotCurve( const QString &title = QString::null );
+    explicit QwtPlotCurve( const QwtText &title );
+
+    virtual ~QwtPlotCurve();
+
+    virtual int rtti() const;
+
+    void setPaintAttribute( PaintAttribute, bool on = true );
+    bool testPaintAttribute( PaintAttribute ) const;
+
+    void setLegendAttribute( LegendAttribute, bool on = true );
+    bool testLegendAttribute( LegendAttribute ) const;
+
+#ifndef QWT_NO_COMPAT
+    void setRawSamples( const double *xData, const double *yData, int size );
+    void setSamples( const double *xData, const double *yData, int size );
+    void setSamples( const QVector<double> &xData, const QVector<double> &yData );
+#endif
+    void setSamples( const QVector<QPointF> & );
+
+    int closestPoint( const QPoint &pos, double *dist = NULL ) const;
+
+    double minXValue() const;
+    double maxXValue() const;
+    double minYValue() const;
+    double maxYValue() const;
+
+    void setCurveAttribute( CurveAttribute, bool on = true );
+    bool testCurveAttribute( CurveAttribute ) const;
+
+    void setPen( const QPen & );
+    const QPen &pen() const;
+
+    void setBrush( const QBrush & );
+    const QBrush &brush() const;
+
+    void setBaseline( double ref );
+    double baseline() const;
+
+    void setStyle( CurveStyle style );
+    CurveStyle style() const;
+
+    void setSymbol( const QwtSymbol *s );
+    const QwtSymbol *symbol() const;
+
+    void setCurveFitter( QwtCurveFitter * );
+    QwtCurveFitter *curveFitter() const;
+
+    virtual void drawSeries( QPainter *,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    virtual void updateLegend( QwtLegend * ) const;
+    virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const;
+
+protected:
+
+    void init();
+
+    virtual void drawCurve( QPainter *p, int style,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    virtual void drawSymbols( QPainter *p, const QwtSymbol &,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    void drawLines( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    void drawSticks( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    void drawDots( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    void drawSteps( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    virtual void fillCurve( QPainter *,
+        const QwtScaleMap &, const QwtScaleMap &, 
+        const QRectF &canvasRect, QPolygonF & ) const;
+
+    void closePolyline( QPainter *,
+        const QwtScaleMap &, const QwtScaleMap &, QPolygonF & ) const;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+//! boundingRect().left()
+inline double QwtPlotCurve::minXValue() const
+{
+    return boundingRect().left();
+}
+
+//! boundingRect().right()
+inline double QwtPlotCurve::maxXValue() const
+{
+    return boundingRect().right();
+}
+
+//! boundingRect().top()
+inline double QwtPlotCurve::minYValue() const
+{
+    return boundingRect().top();
+}
+
+//! boundingRect().bottom()
+inline double QwtPlotCurve::maxYValue() const
+{
+    return boundingRect().bottom();
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::PaintAttributes )
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::LegendAttributes )
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::CurveAttributes )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_dict.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_dict.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_dict.cpp	(revision 4271)
@@ -0,0 +1,188 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_dict.h"
+
+class QwtPlotDict::PrivateData
+{
+public:
+
+    class ItemList: public QList<QwtPlotItem *>
+    {
+    public:
+        void insertItem( QwtPlotItem *item )
+        {
+            if ( item == NULL )
+                return;
+
+            QList<QwtPlotItem *>::iterator it =
+                qUpperBound( begin(), end(), item, LessZThan() );
+            insert( it, item );
+        }
+
+        void removeItem( QwtPlotItem *item )
+        {
+            if ( item == NULL )
+                return;
+
+            QList<QwtPlotItem *>::iterator it =
+                qLowerBound( begin(), end(), item, LessZThan() );
+
+            for ( ; it != end(); ++it )
+            {
+                if ( item == *it )
+                {
+                    erase( it );
+                    break;
+                }
+            }
+        }
+    private:
+        class LessZThan
+        {
+        public:
+            inline bool operator()( const QwtPlotItem *item1,
+                const QwtPlotItem *item2 ) const
+            {
+                return item1->z() < item2->z();
+            }
+        };
+    };
+
+    ItemList itemList;
+    bool autoDelete;
+};
+
+/*!
+   Constructor
+
+   Auto deletion is enabled.
+   \sa setAutoDelete(), attachItem()
+*/
+QwtPlotDict::QwtPlotDict()
+{
+    d_data = new QwtPlotDict::PrivateData;
+    d_data->autoDelete = true;
+}
+
+/*!
+   Destructor
+
+   If autoDelete is on, all attached items will be deleted
+   \sa setAutoDelete(), autoDelete(), attachItem()
+*/
+QwtPlotDict::~QwtPlotDict()
+{
+    detachItems( QwtPlotItem::Rtti_PlotItem, d_data->autoDelete );
+    delete d_data;
+}
+
+/*!
+   En/Disable Auto deletion
+
+   If Auto deletion is on all attached plot items will be deleted
+   in the destructor of QwtPlotDict. The default value is on.
+
+   \sa autoDelete(), attachItem()
+*/
+void QwtPlotDict::setAutoDelete( bool autoDelete )
+{
+    d_data->autoDelete = autoDelete;
+}
+
+/*!
+   \return true if auto deletion is enabled
+   \sa setAutoDelete(), attachItem()
+*/
+bool QwtPlotDict::autoDelete() const
+{
+    return d_data->autoDelete;
+}
+
+/*!
+   Attach/Detach a plot item
+
+   Attached items will be deleted in the destructor,
+   if auto deletion is enabled (default). Manually detached
+   items are not deleted.
+
+   \param item Plot item to attach/detach
+   \ on If true attach, else detach the item
+
+   \sa setAutoDelete(), ~QwtPlotDict()
+*/
+void QwtPlotDict::attachItem( QwtPlotItem *item, bool on )
+{
+    if ( on )
+        d_data->itemList.insertItem( item );
+    else
+        d_data->itemList.removeItem( item );
+}
+
+/*!
+   Detach items from the dictionary
+
+   \param rtti In case of QwtPlotItem::Rtti_PlotItem detach all items
+               otherwise only those items of the type rtti.
+   \param autoDelete If true, delete all detached items
+*/
+void QwtPlotDict::detachItems( int rtti, bool autoDelete )
+{
+    PrivateData::ItemList list = d_data->itemList;
+    QwtPlotItemIterator it = list.begin();
+    while ( it != list.end() )
+    {
+        QwtPlotItem *item = *it;
+
+        ++it; // increment before removing item from the list
+
+        if ( rtti == QwtPlotItem::Rtti_PlotItem || item->rtti() == rtti )
+        {
+            item->attach( NULL );
+            if ( autoDelete )
+                delete item;
+        }
+    }
+}
+
+/*!
+  \brief A QwtPlotItemList of all attached plot items.
+
+  Use caution when iterating these lists, as removing/detaching an item will
+  invalidate the iterator. Instead you can place pointers to objects to be
+  removed in a removal list, and traverse that list later.
+
+  \return List of all attached plot items.
+*/
+const QwtPlotItemList &QwtPlotDict::itemList() const
+{
+    return d_data->itemList;
+}
+
+/*!
+  \return List of all attached plot items of a specific type.
+  \sa QwtPlotItem::rtti()
+*/
+QwtPlotItemList QwtPlotDict::itemList( int rtti ) const
+{
+    if ( rtti == QwtPlotItem::Rtti_PlotItem )
+        return d_data->itemList;
+
+    QwtPlotItemList items;
+
+    PrivateData::ItemList list = d_data->itemList;
+    for ( QwtPlotItemIterator it = list.begin(); it != list.end(); ++it )
+    {
+        QwtPlotItem *item = *it;
+        if ( item->rtti() == rtti )
+            items += item;
+    }
+
+    return items;
+}
Index: trunk/BNC/qwt/qwt_plot_dict.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_dict.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_dict.h	(revision 4271)
@@ -0,0 +1,56 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+/*! \file !*/
+#ifndef QWT_PLOT_DICT
+#define QWT_PLOT_DICT
+
+#include "qwt_global.h"
+#include "qwt_plot_item.h"
+#include <qlist.h>
+
+/// \var typedef QList< QwtPlotItem *> QwtPlotItemList
+/// \brief See QT 4.x assistant documentation for QList
+typedef QList<QwtPlotItem *> QwtPlotItemList;
+typedef QList<QwtPlotItem *>::ConstIterator QwtPlotItemIterator;
+
+/*!
+  \brief A dictionary for plot items
+
+  QwtPlotDict organizes plot items in increasing z-order.
+  If autoDelete() is enabled, all attached items will be deleted
+  in the destructor of the dictionary.
+
+  \sa QwtPlotItem::attach(), QwtPlotItem::detach(), QwtPlotItem::z()
+*/
+class QWT_EXPORT QwtPlotDict
+{
+public:
+    explicit QwtPlotDict();
+    virtual ~QwtPlotDict();
+
+    void setAutoDelete( bool );
+    bool autoDelete() const;
+
+    const QwtPlotItemList& itemList() const;
+    QwtPlotItemList itemList( int rtti ) const;
+
+    void detachItems( int rtti = QwtPlotItem::Rtti_PlotItem,
+        bool autoDelete = true );
+
+private:
+    friend class QwtPlotItem;
+
+    void attachItem( QwtPlotItem *, bool );
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_directpainter.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_directpainter.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_directpainter.cpp	(revision 4271)
@@ -0,0 +1,313 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_directpainter.h"
+#include "qwt_scale_map.h"
+#include "qwt_plot.h"
+#include "qwt_plot_canvas.h"
+#include "qwt_plot_seriesitem.h"
+#include <qpainter.h>
+#include <qevent.h>
+#include <qapplication.h>
+#include <qpixmap.h>
+
+static inline void renderItem( 
+    QPainter *painter, const QRect &canvasRect,
+    QwtPlotAbstractSeriesItem *seriesItem, int from, int to )
+{
+    // A minor performance improvement is possible
+    // with caching the maps. TODO ...
+
+    QwtPlot *plot = seriesItem->plot();
+    const QwtScaleMap xMap = plot->canvasMap( seriesItem->xAxis() );
+    const QwtScaleMap yMap = plot->canvasMap( seriesItem->yAxis() );
+
+    painter->setRenderHint( QPainter::Antialiasing,
+        seriesItem->testRenderHint( QwtPlotItem::RenderAntialiased ) );
+    seriesItem->drawSeries( painter, xMap, yMap, canvasRect, from, to );
+}
+
+class QwtPlotDirectPainter::PrivateData
+{
+public:
+    PrivateData():
+        attributes( 0 ),
+        hasClipping(false),
+        seriesItem( NULL )
+    {
+    }
+
+    QwtPlotDirectPainter::Attributes attributes;
+
+    bool hasClipping;
+    QRegion clipRegion;
+
+    QPainter painter;
+
+    QwtPlotAbstractSeriesItem *seriesItem;
+    int from;
+    int to;
+};
+
+//! Constructor
+QwtPlotDirectPainter::QwtPlotDirectPainter( QObject *parent ):
+    QObject( parent )
+{
+    d_data = new PrivateData;
+}
+
+//! Destructor
+QwtPlotDirectPainter::~QwtPlotDirectPainter()
+{
+    delete d_data;
+}
+
+/*!
+  Change an attribute
+
+  \param attribute Attribute to change
+  \param on On/Off
+
+  \sa Attribute, testAttribute()
+*/
+void QwtPlotDirectPainter::setAttribute( Attribute attribute, bool on )
+{
+    if ( bool( d_data->attributes & attribute ) != on )
+    {
+        if ( on )
+            d_data->attributes |= attribute;
+        else
+            d_data->attributes &= ~attribute;
+
+        if ( ( attribute == AtomicPainter ) && on )
+            reset();
+    }
+}
+
+/*!
+  Check if a attribute is set.
+
+  \param attribute Attribute to be tested
+  \sa Attribute, setAttribute()
+*/
+bool QwtPlotDirectPainter::testAttribute( Attribute attribute ) const
+{
+    return d_data->attributes & attribute;
+}
+
+/*!
+  En/Disables clipping 
+
+  \param enable Enables clipping is true, disable it otherwise
+  \sa hasClipping(), clipRegion(), setClipRegion()
+*/
+void QwtPlotDirectPainter::setClipping( bool enable )
+{
+    d_data->hasClipping = enable;
+}
+
+/*!
+  \return true, when clipping is enabled
+  \sa setClipping(), clipRegion(), setClipRegion()
+*/
+bool QwtPlotDirectPainter::hasClipping() const
+{
+    return d_data->hasClipping;
+}
+
+/*!
+   \brief Assign a clip region and enable clipping
+
+   Depending on the environment setting a proper clip region might improve 
+   the performance heavily. F.e. on Qt embedded only the clipped part of
+   the backing store will be copied to a ( maybe unaccelerated ) frame buffer
+   device.
+   
+   \param region Clip region
+   \sa clipRegion(), hasClipping(), setClipping()
+*/
+void QwtPlotDirectPainter::setClipRegion( const QRegion &region )
+{
+    d_data->clipRegion = region;
+    d_data->hasClipping = true;
+}
+
+/*!
+   \return Currently set clip region.
+   \sa setClipRegion(), setClipping(), hasClipping()
+*/
+QRegion QwtPlotDirectPainter::clipRegion() const
+{
+    return d_data->clipRegion;
+}
+
+/*!
+  \brief Draw a set of points of a seriesItem.
+
+  When observing an measurement while it is running, new points have to be
+  added to an existing seriesItem. drawSeries can be used to display them avoiding
+  a complete redraw of the canvas.
+
+  Setting plot()->canvas()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true);
+  will result in faster painting, if the paint engine of the canvas widget
+  supports this feature.
+
+  \param seriesItem Item to be painted
+  \param from Index of the first point to be painted
+  \param to Index of the last point to be painted. If to < 0 the
+         series will be painted to its last point.
+*/
+void QwtPlotDirectPainter::drawSeries(
+    QwtPlotAbstractSeriesItem *seriesItem, int from, int to )
+{
+    if ( seriesItem == NULL || seriesItem->plot() == NULL )
+        return;
+
+    QwtPlotCanvas *canvas = seriesItem->plot()->canvas();
+    const QRect canvasRect = canvas->contentsRect();
+
+    const bool hasBackingStore = 
+        canvas->testPaintAttribute( QwtPlotCanvas::BackingStore ) 
+        && canvas->backingStore() && !canvas->backingStore()->isNull();
+
+    if ( hasBackingStore )
+    {
+        QPainter painter( const_cast<QPixmap *>( canvas->backingStore() ) );
+        painter.translate( -canvasRect.x(), -canvasRect.y() );
+
+        if ( d_data->hasClipping )
+            painter.setClipRegion( d_data->clipRegion );
+
+        renderItem( &painter, canvasRect, seriesItem, from, to );
+
+        if ( testAttribute( QwtPlotDirectPainter::FullRepaint ) )
+        {
+            canvas->repaint();
+            return;
+        }
+    }
+
+    bool immediatePaint = true;
+    if ( !canvas->testAttribute( Qt::WA_WState_InPaintEvent ) &&
+        !canvas->testAttribute( Qt::WA_PaintOutsidePaintEvent ) )
+    {
+        immediatePaint = false;
+    }
+
+    if ( immediatePaint )
+    {
+        QwtPlotCanvas *canvas = seriesItem->plot()->canvas();
+        if ( !d_data->painter.isActive() )
+        {
+            reset();
+
+            d_data->painter.begin( canvas );
+            canvas->installEventFilter( this );
+        }
+
+        if ( d_data->hasClipping )
+        {
+            d_data->painter.setClipRegion( 
+                QRegion( canvasRect ) & d_data->clipRegion );
+        }
+        else
+        {
+            if ( !d_data->painter.hasClipping() )
+                d_data->painter.setClipRect( canvasRect );
+        }
+
+        renderItem( &d_data->painter, canvasRect, seriesItem, from, to );
+
+        if ( d_data->attributes & QwtPlotDirectPainter::AtomicPainter )
+        {
+            reset();
+        }
+        else
+        {
+            if ( d_data->hasClipping )
+                d_data->painter.setClipping( false );
+        }
+    }
+    else
+    {
+        reset();
+
+        d_data->seriesItem = seriesItem;
+        d_data->from = from;
+        d_data->to = to;
+
+        QRegion clipRegion = canvasRect;
+        if ( d_data->hasClipping )
+            clipRegion &= d_data->clipRegion;
+
+        canvas->installEventFilter( this );
+        canvas->repaint(clipRegion);
+        canvas->removeEventFilter( this );
+
+        d_data->seriesItem = NULL;
+    }
+}
+
+//! Close the internal QPainter
+void QwtPlotDirectPainter::reset()
+{
+    if ( d_data->painter.isActive() )
+    {
+        QWidget *w = ( QWidget * )d_data->painter.device();
+        if ( w )
+            w->removeEventFilter( this );
+
+        d_data->painter.end();
+    }
+}
+
+//! Event filter
+bool QwtPlotDirectPainter::eventFilter( QObject *, QEvent *event )
+{
+    if ( event->type() == QEvent::Paint )
+    {
+        reset();
+
+        if ( d_data->seriesItem )
+        {
+            const QPaintEvent *pe = static_cast< QPaintEvent *>( event );
+
+            QwtPlotCanvas *canvas = d_data->seriesItem->plot()->canvas();
+
+            QPainter painter( canvas );
+            painter.setClipRegion( pe->region() );
+
+            bool copyCache = testAttribute( CopyBackingStore )
+                && canvas->testPaintAttribute( QwtPlotCanvas::BackingStore );
+
+            if ( copyCache )
+            {
+                // is something valid in the cache ?
+                copyCache = ( canvas->backingStore() != NULL )
+                    && !canvas->backingStore()->isNull();
+            }
+
+            if ( copyCache )
+            {
+                painter.drawPixmap( 
+                    canvas->contentsRect().topLeft(), 
+                    *canvas->backingStore() );
+            }
+            else
+            {
+                renderItem( &painter, canvas->contentsRect(),
+                    d_data->seriesItem, d_data->from, d_data->to );
+            }
+
+            return true; // don't call QwtPlotCanvas::paintEvent()
+        }
+    }
+
+    return false;
+}
Index: trunk/BNC/qwt/qwt_plot_directpainter.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_directpainter.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_directpainter.h	(revision 4271)
@@ -0,0 +1,100 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_DIRECT_PAINTER_H
+#define QWT_PLOT_DIRECT_PAINTER_H
+
+#include "qwt_global.h"
+#include <qobject.h>
+
+class QRegion;
+class QwtPlotAbstractSeriesItem;
+
+/*!
+    \brief Painter object trying to paint incrementally
+
+    Often applications want to display samples while they are
+    collected. When there are too many samples complete replots
+    will be expensive to be processed in a collection cycle.
+
+    QwtPlotDirectPainter offers an API to paint
+    subsets ( f.e all additions points ) without erasing/repainting
+    the plot canvas.
+
+    On certain environments it might be important to calculate a proper
+    clip region before painting. F.e. for Qt Embedded only the clipped part
+    of the backing store will be copied to a ( maybe unaccelerated ) 
+    frame buffer.
+
+    \warning Incremental painting will only help when no replot is triggered
+             by another operation ( like changing scales ) and nothing needs
+             to be erased.
+*/
+class QWT_EXPORT QwtPlotDirectPainter: public QObject
+{
+public:
+    /*!
+      \brief Paint attributes
+      \sa setAttribute(), testAttribute(), drawSeries()
+    */
+    enum Attribute
+    {
+        /*!
+          Initializing a QPainter is an expensive operation.
+          When AtomicPainter is set each call of drawSeries() opens/closes
+          a temporary QPainter. Otherwise QwtPlotDirectPainter tries to
+          use the same QPainter as long as possible.
+         */
+        AtomicPainter = 0x01,
+
+        /*!
+          When FullRepaint is set the plot canvas is explicitely repainted
+          after the samples have been rendered.
+         */
+        FullRepaint = 0x02,
+
+        /*!
+          When QwtPlotCanvas::BackingStore is enabled the painter
+          has to paint to the backing store and the widget. In certain 
+          situations/environments it might be faster to paint to 
+          the backing store only and then copy the backingstore to the canvas.
+          This flag can also be useful for settings, where Qt fills the
+          the clip region with the widget background.
+         */
+        CopyBackingStore = 0x04
+    };
+
+    //! Paint attributes
+    typedef QFlags<Attribute> Attributes;
+
+    QwtPlotDirectPainter( QObject *parent = NULL );
+    virtual ~QwtPlotDirectPainter();
+
+    void setAttribute( Attribute, bool on );
+    bool testAttribute( Attribute ) const;
+
+    void setClipping( bool );
+    bool hasClipping() const;
+
+    void setClipRegion( const QRegion & );
+    QRegion clipRegion() const;
+
+    void drawSeries( QwtPlotAbstractSeriesItem *, int from, int to );
+    void reset();
+
+    virtual bool eventFilter( QObject *, QEvent * );
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotDirectPainter::Attributes )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_grid.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_grid.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_grid.cpp	(revision 4271)
@@ -0,0 +1,367 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_grid.h"
+#include "qwt_painter.h"
+#include "qwt_text.h"
+#include "qwt_scale_map.h"
+#include "qwt_scale_div.h"
+#include "qwt_math.h"
+#include <qpainter.h>
+#include <qpen.h>
+
+class QwtPlotGrid::PrivateData
+{
+public:
+    PrivateData():
+        xEnabled( true ),
+        yEnabled( true ),
+        xMinEnabled( false ),
+        yMinEnabled( false )
+    {
+    }
+
+    bool xEnabled;
+    bool yEnabled;
+    bool xMinEnabled;
+    bool yMinEnabled;
+
+    QwtScaleDiv xScaleDiv;
+    QwtScaleDiv yScaleDiv;
+
+    QPen majPen;
+    QPen minPen;
+};
+
+//! Enables major grid, disables minor grid
+QwtPlotGrid::QwtPlotGrid():
+    QwtPlotItem( QwtText( "Grid" ) )
+{
+    d_data = new PrivateData;
+    setZ( 10.0 );
+}
+
+//! Destructor
+QwtPlotGrid::~QwtPlotGrid()
+{
+    delete d_data;
+}
+
+//! \return QwtPlotItem::Rtti_PlotGrid
+int QwtPlotGrid::rtti() const
+{
+    return QwtPlotItem::Rtti_PlotGrid;
+}
+
+/*!
+  \brief Enable or disable vertical gridlines
+  \param tf Enable (true) or disable
+
+  \sa Minor gridlines can be enabled or disabled with
+      enableXMin()
+*/
+void QwtPlotGrid::enableX( bool tf )
+{
+    if ( d_data->xEnabled != tf )
+    {
+        d_data->xEnabled = tf;
+        itemChanged();
+    }
+}
+
+/*!
+  \brief Enable or disable horizontal gridlines
+  \param tf Enable (true) or disable
+  \sa Minor gridlines can be enabled or disabled with enableYMin()
+*/
+void QwtPlotGrid::enableY( bool tf )
+{
+    if ( d_data->yEnabled != tf )
+    {
+        d_data->yEnabled = tf;
+        itemChanged();
+    }
+}
+
+/*!
+  \brief Enable or disable  minor vertical gridlines.
+  \param tf Enable (true) or disable
+  \sa enableX()
+*/
+void QwtPlotGrid::enableXMin( bool tf )
+{
+    if ( d_data->xMinEnabled != tf )
+    {
+        d_data->xMinEnabled = tf;
+        itemChanged();
+    }
+}
+
+/*!
+  \brief Enable or disable minor horizontal gridlines
+  \param tf Enable (true) or disable
+  \sa enableY()
+*/
+void QwtPlotGrid::enableYMin( bool tf )
+{
+    if ( d_data->yMinEnabled != tf )
+    {
+        d_data->yMinEnabled = tf;
+        itemChanged();
+    }
+}
+
+/*!
+  Assign an x axis scale division
+
+  \param scaleDiv Scale division
+*/
+void QwtPlotGrid::setXDiv( const QwtScaleDiv &scaleDiv )
+{
+    if ( d_data->xScaleDiv != scaleDiv )
+    {
+        d_data->xScaleDiv = scaleDiv;
+        itemChanged();
+    }
+}
+
+/*!
+  Assign a y axis division
+
+  \param scaleDiv Scale division
+*/
+void QwtPlotGrid::setYDiv( const QwtScaleDiv &scaleDiv )
+{
+    if ( d_data->yScaleDiv != scaleDiv )
+    {
+        d_data->yScaleDiv = scaleDiv;
+        itemChanged();
+    }
+}
+
+/*!
+  Assign a pen for both major and minor gridlines
+
+  \param pen Pen
+  \sa setMajPen(), setMinPen()
+*/
+void QwtPlotGrid::setPen( const QPen &pen )
+{
+    if ( d_data->majPen != pen || d_data->minPen != pen )
+    {
+        d_data->majPen = pen;
+        d_data->minPen = pen;
+        itemChanged();
+    }
+}
+
+/*!
+  Assign a pen for the major gridlines
+
+  \param pen Pen
+  \sa majPen(), setMinPen(), setPen()
+*/
+void QwtPlotGrid::setMajPen( const QPen &pen )
+{
+    if ( d_data->majPen != pen )
+    {
+        d_data->majPen = pen;
+        itemChanged();
+    }
+}
+
+/*!
+  Assign a pen for the minor gridlines
+
+  \param pen Pen
+  \sa minPen(), setMajPen(), setPen()
+*/
+void QwtPlotGrid::setMinPen( const QPen &pen )
+{
+    if ( d_data->minPen != pen )
+    {
+        d_data->minPen = pen;
+        itemChanged();
+    }
+}
+
+/*!
+  \brief Draw the grid
+
+  The grid is drawn into the bounding rectangle such that
+  gridlines begin and end at the rectangle's borders. The X and Y
+  maps are used to map the scale divisions into the drawing region
+  screen.
+  \param painter  Painter
+  \param xMap X axis map
+  \param yMap Y axis
+  \param canvasRect Contents rect of the plot canvas
+*/
+void QwtPlotGrid::draw( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect ) const
+{
+    //  draw minor gridlines
+    QPen minPen = d_data->minPen;
+    minPen.setCapStyle( Qt::FlatCap );
+
+    painter->setPen( minPen );
+
+    if ( d_data->xEnabled && d_data->xMinEnabled )
+    {
+        drawLines( painter, canvasRect, Qt::Vertical, xMap,
+            d_data->xScaleDiv.ticks( QwtScaleDiv::MinorTick ) );
+        drawLines( painter, canvasRect, Qt::Vertical, xMap,
+            d_data->xScaleDiv.ticks( QwtScaleDiv::MediumTick ) );
+    }
+
+    if ( d_data->yEnabled && d_data->yMinEnabled )
+    {
+        drawLines( painter, canvasRect, Qt::Horizontal, yMap,
+            d_data->yScaleDiv.ticks( QwtScaleDiv::MinorTick ) );
+        drawLines( painter, canvasRect, Qt::Horizontal, yMap,
+            d_data->yScaleDiv.ticks( QwtScaleDiv::MediumTick ) );
+    }
+
+    //  draw major gridlines
+    QPen majPen = d_data->majPen;
+    majPen.setCapStyle( Qt::FlatCap );
+
+    painter->setPen( majPen );
+
+    if ( d_data->xEnabled )
+    {
+        drawLines( painter, canvasRect, Qt::Vertical, xMap,
+            d_data->xScaleDiv.ticks( QwtScaleDiv::MajorTick ) );
+    }
+
+    if ( d_data->yEnabled )
+    {
+        drawLines( painter, canvasRect, Qt::Horizontal, yMap,
+            d_data->yScaleDiv.ticks( QwtScaleDiv::MajorTick ) );
+    }
+}
+
+void QwtPlotGrid::drawLines( QPainter *painter, const QRectF &canvasRect,
+    Qt::Orientation orientation, const QwtScaleMap &scaleMap,
+    const QList<double> &values ) const
+{
+    const double x1 = canvasRect.left();
+    const double x2 = canvasRect.right() - 1.0;
+    const double y1 = canvasRect.top();
+    const double y2 = canvasRect.bottom() - 1.0;
+
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    for ( int i = 0; i < values.count(); i++ )
+    {
+        double value = scaleMap.transform( values[i] );
+        if ( doAlign )
+            value = qRound( value );
+
+        if ( orientation == Qt::Horizontal )
+        {
+            if ( qwtFuzzyGreaterOrEqual( value, y1 ) &&
+                qwtFuzzyLessOrEqual( value, y2 ) )
+            {
+                QwtPainter::drawLine( painter, x1, value, x2, value );
+            }
+        }
+        else
+        {
+            if ( qwtFuzzyGreaterOrEqual( value, x1 ) &&
+                qwtFuzzyLessOrEqual( value, x2 ) )
+            {
+                QwtPainter::drawLine( painter, value, y1, value, y2 );
+            }
+        }
+    }
+}
+
+/*!
+  \return the pen for the major gridlines
+  \sa setMajPen(), setMinPen(), setPen()
+*/
+const QPen &QwtPlotGrid::majPen() const
+{
+    return d_data->majPen;
+}
+
+/*!
+  \return the pen for the minor gridlines
+  \sa setMinPen(), setMajPen(), setPen()
+*/
+const QPen &QwtPlotGrid::minPen() const
+{
+    return d_data->minPen;
+}
+
+/*!
+  \return true if vertical gridlines are enabled
+  \sa enableX()
+*/
+bool QwtPlotGrid::xEnabled() const
+{
+    return d_data->xEnabled;
+}
+
+/*!
+  \return true if minor vertical gridlines are enabled
+  \sa enableXMin()
+*/
+bool QwtPlotGrid::xMinEnabled() const
+{
+    return d_data->xMinEnabled;
+}
+
+/*!
+  \return true if horizontal gridlines are enabled
+  \sa enableY()
+*/
+bool QwtPlotGrid::yEnabled() const
+{
+    return d_data->yEnabled;
+}
+
+/*!
+  \return true if minor horizontal gridlines are enabled
+  \sa enableYMin()
+*/
+bool QwtPlotGrid::yMinEnabled() const
+{
+    return d_data->yMinEnabled;
+}
+
+
+/*! \return the scale division of the x axis */
+const QwtScaleDiv &QwtPlotGrid::xScaleDiv() const
+{
+    return d_data->xScaleDiv;
+}
+
+/*! \return the scale division of the y axis */
+const QwtScaleDiv &QwtPlotGrid::yScaleDiv() const
+{
+    return d_data->yScaleDiv;
+}
+
+/*!
+   Update the grid to changes of the axes scale division
+
+   \param xScaleDiv Scale division of the x-axis
+   \param yScaleDiv Scale division of the y-axis
+
+   \sa QwtPlot::updateAxes()
+*/
+void QwtPlotGrid::updateScaleDiv( const QwtScaleDiv& xScaleDiv,
+    const QwtScaleDiv& yScaleDiv )
+{
+    setXDiv( xScaleDiv );
+    setYDiv( yScaleDiv );
+}
Index: trunk/BNC/qwt/qwt_plot_grid.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_grid.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_grid.h	(revision 4271)
@@ -0,0 +1,84 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_GRID_H
+#define QWT_PLOT_GRID_H
+
+#include "qwt_global.h"
+#include "qwt_plot_item.h"
+#include "qwt_scale_div.h"
+
+class QPainter;
+class QPen;
+class QwtScaleMap;
+class QwtScaleDiv;
+
+/*!
+  \brief A class which draws a coordinate grid
+
+  The QwtPlotGrid class can be used to draw a coordinate grid.
+  A coordinate grid consists of major and minor vertical
+  and horizontal gridlines. The locations of the gridlines
+  are determined by the X and Y scale divisions which can
+  be assigned with setXDiv() and setYDiv().
+  The draw() member draws the grid within a bounding
+  rectangle.
+*/
+
+class QWT_EXPORT QwtPlotGrid: public QwtPlotItem
+{
+public:
+    explicit QwtPlotGrid();
+    virtual ~QwtPlotGrid();
+
+    virtual int rtti() const;
+
+    void enableX( bool tf );
+    bool xEnabled() const;
+
+    void enableY( bool tf );
+    bool yEnabled() const;
+
+    void enableXMin( bool tf );
+    bool xMinEnabled() const;
+
+    void enableYMin( bool tf );
+    bool yMinEnabled() const;
+
+    void setXDiv( const QwtScaleDiv &sx );
+    const QwtScaleDiv &xScaleDiv() const;
+
+    void setYDiv( const QwtScaleDiv &sy );
+    const QwtScaleDiv &yScaleDiv() const;
+
+    void setPen( const QPen &p );
+
+    void setMajPen( const QPen &p );
+    const QPen& majPen() const;
+
+    void setMinPen( const QPen &p );
+    const QPen& minPen() const;
+
+    virtual void draw( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &rect ) const;
+
+    virtual void updateScaleDiv( 
+        const QwtScaleDiv &xMap, const QwtScaleDiv &yMap );
+
+private:
+    void drawLines( QPainter *painter, const QRectF &,
+        Qt::Orientation orientation, const QwtScaleMap &,
+        const QList<double> & ) const;
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_histogram.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_histogram.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_histogram.cpp	(revision 4271)
@@ -0,0 +1,648 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_histogram.h"
+#include "qwt_plot.h"
+#include "qwt_legend.h"
+#include "qwt_legend_item.h"
+#include "qwt_painter.h"
+#include "qwt_column_symbol.h"
+#include "qwt_scale_map.h"
+#include <qstring.h>
+#include <qpainter.h>
+
+static inline bool isCombinable( const QwtInterval &d1,
+    const QwtInterval &d2 )
+{
+    if ( d1.isValid() && d2.isValid() )
+    {
+        if ( d1.maxValue() == d2.minValue() )
+        {
+            if ( !( d1.borderFlags() & QwtInterval::ExcludeMaximum
+                && d2.borderFlags() & QwtInterval::ExcludeMinimum ) )
+            {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+class QwtPlotHistogram::PrivateData
+{
+public:
+    PrivateData():
+        baseline( 0.0 ),
+        style( Columns ),
+        symbol( NULL )
+    {
+    }
+
+    ~PrivateData()
+    {
+        delete symbol;
+    }
+
+    double baseline;
+
+    QPen pen;
+    QBrush brush;
+    QwtPlotHistogram::HistogramStyle style;
+    const QwtColumnSymbol *symbol;
+};
+
+/*!
+  Constructor
+  \param title Title of the histogram.
+*/
+
+QwtPlotHistogram::QwtPlotHistogram( const QwtText &title ):
+    QwtPlotSeriesItem<QwtIntervalSample>( title )
+{
+    init();
+}
+
+/*!
+  Constructor
+  \param title Title of the histogram.
+*/
+QwtPlotHistogram::QwtPlotHistogram( const QString &title ):
+    QwtPlotSeriesItem<QwtIntervalSample>( title )
+{
+    init();
+}
+
+//! Destructor
+QwtPlotHistogram::~QwtPlotHistogram()
+{
+    delete d_data;
+}
+
+//! Initialize data members
+void QwtPlotHistogram::init()
+{
+    d_data = new PrivateData();
+    d_series = new QwtIntervalSeriesData();
+
+    setItemAttribute( QwtPlotItem::AutoScale, true );
+    setItemAttribute( QwtPlotItem::Legend, true );
+
+    setZ( 20.0 );
+}
+
+/*!
+  Set the histogram's drawing style
+
+  \param style Histogram style
+  \sa HistogramStyle, style()
+*/
+void QwtPlotHistogram::setStyle( HistogramStyle style )
+{
+    if ( style != d_data->style )
+    {
+        d_data->style = style;
+        itemChanged();
+    }
+}
+
+/*!
+    Return the current style
+    \sa HistogramStyle, setStyle()
+*/
+QwtPlotHistogram::HistogramStyle QwtPlotHistogram::style() const
+{
+    return d_data->style;
+}
+
+/*!
+  Assign a pen, that is used in a style() depending way.
+
+  \param pen New pen
+  \sa pen(), brush()
+*/
+void QwtPlotHistogram::setPen( const QPen &pen )
+{
+    if ( pen != d_data->pen )
+    {
+        d_data->pen = pen;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Pen used in a style() depending way.
+  \sa setPen(), brush()
+*/
+const QPen &QwtPlotHistogram::pen() const
+{
+    return d_data->pen;
+}
+
+/*!
+  Assign a brush, that is used in a style() depending way.
+
+  \param brush New brush
+  \sa pen(), brush()
+*/
+void QwtPlotHistogram::setBrush( const QBrush &brush )
+{
+    if ( brush != d_data->brush )
+    {
+        d_data->brush = brush;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Brush used in a style() depending way.
+  \sa setPen(), brush()
+*/
+const QBrush &QwtPlotHistogram::brush() const
+{
+    return d_data->brush;
+}
+
+/*!
+  \brief Assign a symbol
+
+  In Column style an optional symbol can be assigned, that is responsible
+  for displaying the rectangle that is defined by the interval and
+  the distance between baseline() and value. When no symbol has been
+  defined the area is displayed as plain rectangle using pen() and brush().
+
+  \sa style(), symbol(), drawColumn(), pen(), brush()
+
+  \note In applications, where different intervals need to be displayed
+        in a different way ( f.e different colors or even using differnt symbols)
+        it is recommended to overload drawColumn().
+*/
+void QwtPlotHistogram::setSymbol( const QwtColumnSymbol *symbol )
+{
+    if ( symbol != d_data->symbol )
+    {
+        delete d_data->symbol;
+        d_data->symbol = symbol;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Current symbol or NULL, when no symbol has been assigned
+  \sa setSymbol()
+*/
+const QwtColumnSymbol *QwtPlotHistogram::symbol() const
+{
+    return d_data->symbol;
+}
+
+/*!
+  \brief Set the value of the baseline
+
+  Each column representing an QwtIntervalSample is defined by its
+  interval and the interval between baseline and the value of the sample.
+
+  The default value of the baseline is 0.0.
+
+  \param value Value of the baseline
+  \sa baseline()
+*/
+void QwtPlotHistogram::setBaseline( double value )
+{
+    if ( d_data->baseline != value )
+    {
+        d_data->baseline = value;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Value of the baseline
+  \sa setBaseline()
+*/
+double QwtPlotHistogram::baseline() const
+{
+    return d_data->baseline;
+}
+
+/*!
+  \return Bounding rectangle of all samples.
+  For an empty series the rectangle is invalid.
+*/
+QRectF QwtPlotHistogram::boundingRect() const
+{
+    QRectF rect = d_series->boundingRect();
+    if ( !rect.isValid() )
+        return rect;
+
+    if ( orientation() == Qt::Horizontal )
+    {
+        rect = QRectF( rect.y(), rect.x(),
+            rect.height(), rect.width() );
+
+        if ( rect.left() > d_data->baseline )
+            rect.setLeft( d_data->baseline );
+        else if ( rect.right() < d_data->baseline )
+            rect.setRight( d_data->baseline );
+    }
+    else
+    {
+        if ( rect.bottom() < d_data->baseline )
+            rect.setBottom( d_data->baseline );
+        else if ( rect.top() > d_data->baseline )
+            rect.setTop( d_data->baseline );
+    }
+
+    return rect;
+}
+
+//! \return QwtPlotItem::Rtti_PlotHistogram
+int QwtPlotHistogram::rtti() const
+{
+    return QwtPlotItem::Rtti_PlotHistogram;
+}
+
+/*!
+  Initialize data with an array of samples.
+  \param samples Vector of points
+*/
+void QwtPlotHistogram::setSamples(
+    const QVector<QwtIntervalSample> &samples )
+{
+    delete d_series;
+    d_series = new QwtIntervalSeriesData( samples );
+    itemChanged();
+}
+
+/*!
+  Draw a subset of the histogram samples
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param canvasRect Contents rect of the canvas
+  \param from Index of the first sample to be painted
+  \param to Index of the last sample to be painted. If to < 0 the
+         series will be painted to its last sample.
+
+  \sa drawOutline(), drawLines(), drawColumns
+*/
+void QwtPlotHistogram::drawSeries( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &, int from, int to ) const
+{
+    if ( !painter || dataSize() <= 0 )
+        return;
+
+    if ( to < 0 )
+        to = dataSize() - 1;
+
+    switch ( d_data->style )
+    {
+        case Outline:
+            drawOutline( painter, xMap, yMap, from, to );
+            break;
+        case Lines:
+            drawLines( painter, xMap, yMap, from, to );
+            break;
+        case Columns:
+            drawColumns( painter, xMap, yMap, from, to );
+            break;
+        default:
+            break;
+    }
+}
+
+/*!
+  Draw a histogram in Outline style()
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param from Index of the first sample to be painted
+  \param to Index of the last sample to be painted. If to < 0 the
+         histogram will be painted to its last point.
+
+  \sa setStyle(), style()
+  \warning The outline style requires, that the intervals are in increasing
+           order and not overlapping.
+*/
+void QwtPlotHistogram::drawOutline( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    int from, int to ) const
+{
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    double v0 = ( orientation() == Qt::Horizontal ) ?
+        xMap.transform( baseline() ) : yMap.transform( baseline() );
+    if ( doAlign )
+        v0 = qRound( v0 );
+
+    QwtIntervalSample previous;
+
+    QPolygonF polygon;
+    for ( int i = from; i <= to; i++ )
+    {
+        const QwtIntervalSample sample = d_series->sample( i );
+
+        if ( !sample.interval.isValid() )
+        {
+            flushPolygon( painter, v0, polygon );
+            previous = sample;
+            continue;
+        }
+
+        if ( previous.interval.isValid() )
+        {
+            if ( !isCombinable( previous.interval, sample.interval ) )
+                flushPolygon( painter, v0, polygon );
+        }
+
+        if ( orientation() == Qt::Vertical )
+        {
+            double x1 = xMap.transform( sample.interval.minValue() );
+            double x2 = xMap.transform( sample.interval.maxValue() );
+            double y = yMap.transform( sample.value );
+            if ( doAlign )
+            {
+                x1 = qRound( x1 );
+                x2 = qRound( x2 );
+                y = qRound( y );
+            }
+
+            if ( polygon.size() == 0 )
+                polygon += QPointF( x1, v0 );
+
+            polygon += QPointF( x1, y );
+            polygon += QPointF( x2, y );
+        }
+        else
+        {
+            double y1 = yMap.transform( sample.interval.minValue() );
+            double y2 = yMap.transform( sample.interval.maxValue() );
+            double x = xMap.transform( sample.value );
+            if ( doAlign )
+            {
+                y1 = qRound( y1 );
+                y2 = qRound( y2 );
+                x = qRound( x );
+            }
+
+            if ( polygon.size() == 0 )
+                polygon += QPointF( v0, y1 );
+
+            polygon += QPointF( x, y1 );
+            polygon += QPointF( x, y2 );
+        }
+        previous = sample;
+    }
+
+    flushPolygon( painter, v0, polygon );
+}
+
+/*!
+  Draw a histogram in Columns style()
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param from Index of the first sample to be painted
+  \param to Index of the last sample to be painted. If to < 0 the
+         histogram will be painted to its last point.
+
+  \sa setStyle(), style(), setSymbol(), drawColumn()
+*/
+void QwtPlotHistogram::drawColumns( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    int from, int to ) const
+{
+    painter->setPen( d_data->pen );
+    painter->setBrush( d_data->brush );
+
+    for ( int i = from; i <= to; i++ )
+    {
+        const QwtIntervalSample sample = d_series->sample( i );
+        if ( !sample.interval.isNull() )
+        {
+            const QwtColumnRect rect = columnRect( sample, xMap, yMap );
+            drawColumn( painter, rect, sample );
+        }
+    }
+}
+
+/*!
+  Draw a histogram in Lines style()
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param from Index of the first sample to be painted
+  \param to Index of the last sample to be painted. If to < 0 the
+         histogram will be painted to its last point.
+
+  \sa setStyle(), style(), setPen()
+*/
+void QwtPlotHistogram::drawLines( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    int from, int to ) const
+{
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    painter->setPen( d_data->pen );
+    painter->setBrush( Qt::NoBrush );
+
+    for ( int i = from; i <= to; i++ )
+    {
+        const QwtIntervalSample sample = d_series->sample( i );
+        if ( !sample.interval.isNull() )
+        {
+            const QwtColumnRect rect = columnRect( sample, xMap, yMap );
+
+            QRectF r = rect.toRect();
+            if ( doAlign )
+            {
+                r.setLeft( qRound( r.left() ) );
+                r.setRight( qRound( r.right() ) );
+                r.setTop( qRound( r.top() ) );
+                r.setBottom( qRound( r.bottom() ) );
+            }
+
+            switch ( rect.direction )
+            {
+                case QwtColumnRect::LeftToRight:
+                {
+                    QwtPainter::drawLine( painter,
+                        r.topRight(), r.bottomRight() );
+                    break;
+                }
+                case QwtColumnRect::RightToLeft:
+                {
+                    QwtPainter::drawLine( painter,
+                        r.topLeft(), r.bottomLeft() );
+                    break;
+                }
+                case QwtColumnRect::TopToBottom:
+                {
+                    QwtPainter::drawLine( painter,
+                        r.bottomRight(), r.bottomLeft() );
+                    break;
+                }
+                case QwtColumnRect::BottomToTop:
+                {
+                    QwtPainter::drawLine( painter,
+                        r.topRight(), r.topLeft() );
+                    break;
+                }
+            }
+        }
+    }
+}
+
+//! Internal, used by the Outline style.
+void QwtPlotHistogram::flushPolygon( QPainter *painter,
+    double baseLine, QPolygonF &polygon ) const
+{
+    if ( polygon.size() == 0 )
+        return;
+
+    if ( orientation() == Qt::Horizontal )
+        polygon += QPointF( baseLine, polygon.last().y() );
+    else
+        polygon += QPointF( polygon.last().x(), baseLine );
+
+    if ( d_data->brush.style() != Qt::NoBrush )
+    {
+        painter->setPen( Qt::NoPen );
+        painter->setBrush( d_data->brush );
+
+        if ( orientation() == Qt::Horizontal )
+        {
+            polygon += QPointF( polygon.last().x(), baseLine );
+            polygon += QPointF( polygon.first().x(), baseLine );
+        }
+        else
+        {
+            polygon += QPointF( baseLine, polygon.last().y() );
+            polygon += QPointF( baseLine, polygon.first().y() );
+        }
+        QwtPainter::drawPolygon( painter, polygon );
+        polygon.resize( polygon.size() - 2 );
+    }
+    if ( d_data->pen.style() != Qt::NoPen )
+    {
+        painter->setBrush( Qt::NoBrush );
+        painter->setPen( d_data->pen );
+        QwtPainter::drawPolyline( painter, polygon );
+    }
+    polygon.clear();
+}
+
+/*!
+  Calculate the area that is covered by a sample
+
+  \param sample Sample
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+
+  \return Rectangle, that is covered by a sample
+*/
+QwtColumnRect QwtPlotHistogram::columnRect( const QwtIntervalSample &sample,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap ) const
+{
+    QwtColumnRect rect;
+
+    const QwtInterval &iv = sample.interval;
+    if ( !iv.isValid() )
+        return rect;
+
+    if ( orientation() == Qt::Horizontal )
+    {
+        const double x0 = xMap.transform( baseline() );
+        const double x  = xMap.transform( sample.value );
+        const double y1 = yMap.transform( iv.minValue() );
+        const double y2 = yMap.transform( iv.maxValue() );
+
+        rect.hInterval.setInterval( x0, x );
+        rect.vInterval.setInterval( y1, y2, iv.borderFlags() );
+        rect.direction = ( x < x0 ) ? QwtColumnRect::RightToLeft :
+                         QwtColumnRect::LeftToRight;
+    }
+    else
+    {
+        const double x1 = xMap.transform( iv.minValue() );
+        const double x2 = xMap.transform( iv.maxValue() );
+        const double y0 = yMap.transform( baseline() );
+        const double y = yMap.transform( sample.value );
+
+        rect.hInterval.setInterval( x1, x2, iv.borderFlags() );
+        rect.vInterval.setInterval( y0, y );
+        rect.direction = ( y < y0 ) ? QwtColumnRect::BottomToTop :
+            QwtColumnRect::TopToBottom;
+    }
+
+    return rect;
+}
+
+/*!
+  Draw a column for a sample in Columns style().
+
+  When a symbol() has been set the symbol is used otherwise the
+  column is displayed as plain rectangle using pen() and brush().
+
+  \param painter Painter
+  \param rect Rectangle where to paint the column in paint device coordinates
+  \param sample Sample to be displayed
+
+  \note In applications, where different intervals need to be displayed
+        in a different way ( f.e different colors or even using differnt symbols)
+        it is recommended to overload drawColumn().
+*/
+void QwtPlotHistogram::drawColumn( QPainter *painter,
+    const QwtColumnRect &rect, const QwtIntervalSample &sample ) const
+{
+    Q_UNUSED( sample );
+
+    if ( d_data->symbol &&
+        ( d_data->symbol->style() != QwtColumnSymbol::NoStyle ) )
+    {
+        d_data->symbol->draw( painter, rect );
+    }
+    else
+    {
+        QRectF r = rect.toRect();
+        if ( QwtPainter::roundingAlignment( painter ) )
+        {
+            r.setLeft( qRound( r.left() ) );
+            r.setRight( qRound( r.right() ) );
+            r.setTop( qRound( r.top() ) );
+            r.setBottom( qRound( r.bottom() ) );
+        }
+
+        QwtPainter::drawRect( painter, r );
+    }
+}
+
+/*!
+  Draw a plain rectangle without pen using the brush() as identifier
+
+  \param painter Painter
+  \param rect Bounding rectangle for the identifier
+*/
+void QwtPlotHistogram::drawLegendIdentifier(
+    QPainter *painter, const QRectF &rect ) const
+{
+    const double dim = qMin( rect.width(), rect.height() );
+
+    QSizeF size( dim, dim );
+
+    QRectF r( 0, 0, size.width(), size.height() );
+    r.moveCenter( rect.center() );
+
+    painter->fillRect( r, d_data->brush );
+}
Index: trunk/BNC/qwt/qwt_plot_histogram.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_histogram.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_histogram.h	(revision 4271)
@@ -0,0 +1,134 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_HISTOGRAM_H
+#define QWT_PLOT_HISTOGRAM_H
+
+#include "qwt_global.h"
+#include "qwt_plot_seriesitem.h"
+#include "qwt_column_symbol.h"
+#include <qcolor.h>
+#include <qvector.h>
+
+class QwtIntervalData;
+class QString;
+class QPolygonF;
+
+/*!
+  \brief QwtPlotHistogram represents a series of samples, where an interval
+         is associated with a value ( \f$y = f([x1,x2])\f$ ).
+
+  The representation depends on the style() and an optional symbol()
+  that is displayed for each interval.
+
+  \note The term "histogram" is used in a different way in the areas of
+        digital image processing and statistics. Wikipedia introduces the
+        terms "image histogram" and "color histogram" to avoid confusions.
+        While "image histograms" can be displayed by a QwtPlotCurve there
+        is no applicable plot item for a "color histogram" yet.
+*/
+
+class QWT_EXPORT QwtPlotHistogram: public QwtPlotSeriesItem<QwtIntervalSample>
+{
+public:
+    /*!
+        Histogram styles.
+        The default style is QwtPlotHistogram::Columns.
+
+        \sa setStyle(), style(), setSymbol(), symbol(), setBaseline()
+    */
+    enum HistogramStyle
+    {
+        /*!
+           Draw an outline around the area, that is build by all intervals
+           using the pen() and fill it with the brush(). The outline style
+           requires, that the intervals are in increasing order and
+           not overlapping.
+         */
+        Outline,
+
+        /*!
+           Draw a column for each interval. When a symbol() has been set
+           the symbol is used otherwise the column is displayed as 
+           plain rectangle using pen() and brush().
+         */
+        Columns,
+
+        /*!
+           Draw a simple line using the pen() for each interval.
+         */
+        Lines,
+
+        /*!
+           Styles >= UserStyle are reserved for derived
+           classes that overload drawSeries() with
+           additional application specific ways to display a histogram.
+         */
+        UserStyle = 100
+    };
+
+    explicit QwtPlotHistogram( const QString &title = QString::null );
+    explicit QwtPlotHistogram( const QwtText &title );
+    virtual ~QwtPlotHistogram();
+
+    virtual int rtti() const;
+
+    void setPen( const QPen & );
+    const QPen &pen() const;
+
+    void setBrush( const QBrush & );
+    const QBrush &brush() const;
+
+    void setSamples( const QVector<QwtIntervalSample> & );
+
+    void setBaseline( double reference );
+    double baseline() const;
+
+    void setStyle( HistogramStyle style );
+    HistogramStyle style() const;
+
+    void setSymbol( const QwtColumnSymbol * );
+    const QwtColumnSymbol *symbol() const;
+
+    virtual void drawSeries( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    virtual QRectF boundingRect() const;
+
+    virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const;
+
+protected:
+    virtual QwtColumnRect columnRect( const QwtIntervalSample &,
+        const QwtScaleMap &, const QwtScaleMap & ) const;
+
+    virtual void drawColumn( QPainter *, const QwtColumnRect &,
+        const QwtIntervalSample & ) const;
+
+    void drawColumns( QPainter *,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        int from, int to ) const;
+
+    void drawOutline( QPainter *,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        int from, int to ) const;
+
+    void drawLines( QPainter *,
+         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+         int from, int to ) const;
+
+private:
+    void init();
+    void flushPolygon( QPainter *, double baseLine, QPolygonF & ) const;
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_intervalcurve.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_intervalcurve.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_intervalcurve.cpp	(revision 4271)
@@ -0,0 +1,547 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_intervalcurve.h"
+#include "qwt_interval_symbol.h"
+#include "qwt_scale_map.h"
+#include "qwt_clipper.h"
+#include "qwt_painter.h"
+
+#include <qpainter.h>
+
+static inline bool qwtIsHSampleInside( const QwtIntervalSample &sample,
+    double xMin, double xMax, double yMin, double yMax )
+{
+    const double y = sample.value;
+    const double x1 = sample.interval.minValue();
+    const double x2 = sample.interval.maxValue();
+
+    const bool isOffScreen = ( y < yMin ) || ( y > yMax )
+        || ( x1 < xMin && x2 < xMin ) || ( x1 > yMax && x2 > xMax );
+
+    return !isOffScreen;
+}
+
+static inline bool qwtIsVSampleInside( const QwtIntervalSample &sample,
+    double xMin, double xMax, double yMin, double yMax )
+{
+    const double x = sample.value;
+    const double y1 = sample.interval.minValue();
+    const double y2 = sample.interval.maxValue();
+
+    const bool isOffScreen = ( x < xMin ) || ( x > xMax )
+        || ( y1 < yMin && y2 < yMin ) || ( y1 > yMax && y2 > yMax );
+
+    return !isOffScreen;
+}
+
+class QwtPlotIntervalCurve::PrivateData
+{
+public:
+    PrivateData():
+        style( Tube ),
+        symbol( NULL ),
+        pen( Qt::black ),
+        brush( Qt::white )
+    {
+        paintAttributes = QwtPlotIntervalCurve::ClipPolygons;
+        paintAttributes |= QwtPlotIntervalCurve::ClipSymbol;
+    
+        pen.setCapStyle( Qt::FlatCap );
+    }
+
+    ~PrivateData()
+    {
+        delete symbol;
+    }
+
+    CurveStyle style;
+    const QwtIntervalSymbol *symbol;
+
+    QPen pen;
+    QBrush brush;
+
+    QwtPlotIntervalCurve::PaintAttributes paintAttributes;
+};
+
+/*!
+  Constructor
+  \param title Title of the curve
+*/
+QwtPlotIntervalCurve::QwtPlotIntervalCurve( const QwtText &title ):
+    QwtPlotSeriesItem<QwtIntervalSample>( title )
+{
+    init();
+}
+
+/*!
+  Constructor
+  \param title Title of the curve
+*/
+QwtPlotIntervalCurve::QwtPlotIntervalCurve( const QString &title ):
+    QwtPlotSeriesItem<QwtIntervalSample>( QwtText( title ) )
+{
+    init();
+}
+
+//! Destructor
+QwtPlotIntervalCurve::~QwtPlotIntervalCurve()
+{
+    delete d_data;
+}
+
+//! Initialize internal members
+void QwtPlotIntervalCurve::init()
+{
+    setItemAttribute( QwtPlotItem::Legend, true );
+    setItemAttribute( QwtPlotItem::AutoScale, true );
+
+    d_data = new PrivateData;
+    d_series = new QwtIntervalSeriesData();
+
+    setZ( 19.0 );
+}
+
+//! \return QwtPlotItem::Rtti_PlotIntervalCurve
+int QwtPlotIntervalCurve::rtti() const
+{
+    return QwtPlotIntervalCurve::Rtti_PlotIntervalCurve;
+}
+
+/*!
+  Specify an attribute how to draw the curve
+
+  \param attribute Paint attribute
+  \param on On/Off
+  \sa testPaintAttribute()
+*/
+void QwtPlotIntervalCurve::setPaintAttribute( 
+    PaintAttribute attribute, bool on )
+{
+    if ( on )
+        d_data->paintAttributes |= attribute;
+    else
+        d_data->paintAttributes &= ~attribute;
+}
+
+/*!
+    \brief Return the current paint attributes
+    \sa PaintAttribute, setPaintAttribute()
+*/
+bool QwtPlotIntervalCurve::testPaintAttribute( 
+    PaintAttribute attribute ) const
+{
+    return ( d_data->paintAttributes & attribute );
+}
+
+/*!
+  Initialize data with an array of samples.
+  \param samples Vector of samples
+*/
+void QwtPlotIntervalCurve::setSamples(
+    const QVector<QwtIntervalSample> &samples )
+{
+    delete d_series;
+    d_series = new QwtIntervalSeriesData( samples );
+    itemChanged();
+}
+
+/*!
+  Set the curve's drawing style
+
+  \param style Curve style
+  \sa CurveStyle, style()
+*/
+void QwtPlotIntervalCurve::setStyle( CurveStyle style )
+{
+    if ( style != d_data->style )
+    {
+        d_data->style = style;
+        itemChanged();
+    }
+}
+
+/*!
+    \brief Return the current style
+    \sa setStyle()
+*/
+QwtPlotIntervalCurve::CurveStyle QwtPlotIntervalCurve::style() const
+{
+    return d_data->style;
+}
+
+/*!
+  Assign a symbol.
+
+  \param symbol Symbol
+  \sa symbol()
+*/
+void QwtPlotIntervalCurve::setSymbol( const QwtIntervalSymbol *symbol )
+{
+    if ( symbol != d_data->symbol )
+    {
+        delete d_data->symbol;
+        d_data->symbol = symbol;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Current symbol or NULL, when no symbol has been assigned
+  \sa setSymbol()
+*/
+const QwtIntervalSymbol *QwtPlotIntervalCurve::symbol() const
+{
+    return d_data->symbol;
+}
+
+/*!
+  \brief Assign a pen
+  \param pen New pen
+  \sa pen(), brush()
+*/
+void QwtPlotIntervalCurve::setPen( const QPen &pen )
+{
+    if ( pen != d_data->pen )
+    {
+        d_data->pen = pen;
+        itemChanged();
+    }
+}
+
+/*!
+    \brief Return the pen used to draw the lines
+    \sa setPen(), brush()
+*/
+const QPen& QwtPlotIntervalCurve::pen() const
+{
+    return d_data->pen;
+}
+
+/*!
+  Assign a brush.
+
+  The brush is used to fill the area in Tube style().
+
+  \param brush Brush
+  \sa brush(), pen(), setStyle(), CurveStyle
+*/
+void QwtPlotIntervalCurve::setBrush( const QBrush &brush )
+{
+    if ( brush != d_data->brush )
+    {
+        d_data->brush = brush;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Brush used to fill the area in Tube style()
+  \sa setBrush(), setStyle(), CurveStyle
+*/
+const QBrush& QwtPlotIntervalCurve::brush() const
+{
+    return d_data->brush;
+}
+
+/*!
+  \return Bounding rectangle of all samples.
+  For an empty series the rectangle is invalid.
+*/
+QRectF QwtPlotIntervalCurve::boundingRect() const
+{
+    QRectF rect = QwtPlotSeriesItem<QwtIntervalSample>::boundingRect();
+    if ( rect.isValid() && orientation() == Qt::Vertical )
+        rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() );
+
+    return rect;
+}
+
+/*!
+  Draw a subset of the samples
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param canvasRect Contents rect of the canvas
+  \param from Index of the first sample to be painted
+  \param to Index of the last sample to be painted. If to < 0 the
+         series will be painted to its last sample.
+
+  \sa drawTube(), drawSymbols()
+*/
+void QwtPlotIntervalCurve::drawSeries( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    if ( to < 0 )
+        to = dataSize() - 1;
+
+    if ( from < 0 )
+        from = 0;
+
+    if ( from > to )
+        return;
+
+    switch ( d_data->style )
+    {
+        case Tube:
+            drawTube( painter, xMap, yMap, canvasRect, from, to );
+            break;
+
+        case NoCurve:
+        default:
+            break;
+    }
+
+    if ( d_data->symbol &&
+        ( d_data->symbol->style() != QwtIntervalSymbol::NoSymbol ) )
+    {
+        drawSymbols( painter, *d_data->symbol, 
+            xMap, yMap, canvasRect, from, to );
+    }
+}
+
+/*!
+  Draw a tube
+
+  Builds 2 curves from the upper and lower limits of the intervals
+  and draws them with the pen(). The area between the curves is
+  filled with the brush().
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param canvasRect Contents rect of the canvas
+  \param from Index of the first sample to be painted
+  \param to Index of the last sample to be painted. If to < 0 the
+         series will be painted to its last sample.
+
+  \sa drawSeries(), drawSymbols()
+*/
+void QwtPlotIntervalCurve::drawTube( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    painter->save();
+
+    const size_t size = to - from + 1;
+    QPolygonF polygon( 2 * size );
+    QPointF *points = polygon.data();
+
+    for ( uint i = 0; i < size; i++ )
+    {
+        QPointF &minValue = points[i];
+        QPointF &maxValue = points[2 * size - 1 - i];
+
+        const QwtIntervalSample intervalSample = sample( from + i );
+        if ( orientation() == Qt::Vertical )
+        {
+            double x = xMap.transform( intervalSample.value );
+            double y1 = yMap.transform( intervalSample.interval.minValue() );
+            double y2 = yMap.transform( intervalSample.interval.maxValue() );
+            if ( doAlign )
+            {
+                x = qRound( x );
+                y1 = qRound( y1 );
+                y2 = qRound( y2 );
+            }
+
+            minValue.rx() = x;
+            minValue.ry() = y1;
+            maxValue.rx() = x;
+            maxValue.ry() = y2;
+        }
+        else
+        {
+            double y = yMap.transform( intervalSample.value );
+            double x1 = xMap.transform( intervalSample.interval.minValue() );
+            double x2 = xMap.transform( intervalSample.interval.maxValue() );
+            if ( doAlign )
+            {
+                y = qRound( y );
+                x1 = qRound( x1 );
+                x2 = qRound( x2 );
+            }
+
+            minValue.rx() = x1;
+            minValue.ry() = y;
+            maxValue.rx() = x2;
+            maxValue.ry() = y;
+        }
+    }
+
+    if ( d_data->brush.style() != Qt::NoBrush )
+    {
+        painter->setPen( QPen( Qt::NoPen ) );
+        painter->setBrush( d_data->brush );
+
+        if ( d_data->paintAttributes & ClipPolygons )
+        {
+            const qreal m = 1.0;
+            const QPolygonF p = QwtClipper::clipPolygonF( 
+                canvasRect.adjusted(-m, -m, m, m), polygon, true );
+
+            QwtPainter::drawPolygon( painter, p );
+        }
+        else
+        {
+            QwtPainter::drawPolygon( painter, polygon );
+        }
+    }
+
+    if ( d_data->pen.style() != Qt::NoPen )
+    {
+        painter->setPen( d_data->pen );
+        painter->setBrush( Qt::NoBrush );
+
+        if ( d_data->paintAttributes & ClipPolygons )
+        {
+            qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
+            const QRectF clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);
+
+            QPolygonF p;
+
+            p.resize( size );
+            qMemCopy( p.data(), points, size * sizeof( QPointF ) );
+            p = QwtClipper::clipPolygonF( canvasRect, p );
+            QwtPainter::drawPolyline( painter, p );
+
+            p.resize( size );
+            qMemCopy( p.data(), points + size, size * sizeof( QPointF ) );
+            p = QwtClipper::clipPolygonF( canvasRect, p );
+            QwtPainter::drawPolyline( painter, p );
+        }
+        else
+        {
+            QwtPainter::drawPolyline( painter, points, size );
+            QwtPainter::drawPolyline( painter, points + size, size );
+        }
+    }
+
+    painter->restore();
+}
+
+/*!
+  Draw symbols for a subset of the samples
+
+  \param painter Painter
+  \param symbol Interval symbol
+  \param xMap x map
+  \param yMap y map
+  \param canvasRect Contents rect of the canvas
+  \param from Index of the first sample to be painted
+  \param to Index of the last sample to be painted
+
+  \sa setSymbol(), drawSeries(), drawTube()
+*/
+void QwtPlotIntervalCurve::drawSymbols(
+    QPainter *painter, const QwtIntervalSymbol &symbol,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    painter->save();
+
+    QPen pen = symbol.pen();
+    pen.setCapStyle( Qt::FlatCap );
+
+    painter->setPen( pen );
+    painter->setBrush( symbol.brush() );
+
+    const QRectF &tr = QwtScaleMap::invTransform( xMap, yMap, canvasRect);
+
+    const double xMin = tr.left();
+    const double xMax = tr.right();
+    const double yMin = tr.top();
+    const double yMax = tr.bottom();
+
+    const bool doClip = d_data->paintAttributes & ClipPolygons;
+
+    for ( int i = from; i <= to; i++ )
+    {
+        const QwtIntervalSample s = sample( i );
+
+        if ( orientation() == Qt::Vertical )
+        {
+            if ( !doClip || qwtIsVSampleInside( s, xMin, xMax, yMin, yMax ) )
+            {
+                const double x = xMap.transform( s.value );
+                const double y1 = yMap.transform( s.interval.minValue() );
+                const double y2 = yMap.transform( s.interval.maxValue() );
+
+                symbol.draw( painter, orientation(),
+                    QPointF( x, y1 ), QPointF( x, y2 ) );
+            }
+        }
+        else
+        {
+            if ( !doClip || qwtIsHSampleInside( s, xMin, xMax, yMin, yMax ) )
+            {
+                const double y = yMap.transform( s.value );
+                const double x1 = xMap.transform( s.interval.minValue() );
+                const double x2 = xMap.transform( s.interval.maxValue() );
+
+                symbol.draw( painter, orientation(),
+                    QPointF( x1, y ), QPointF( x2, y ) );
+            }
+        }
+    }
+
+    painter->restore();
+}
+
+/*!
+  In case of Tibe stale() a plain rectangle is painted without a pen filled
+  the brush(). If a symbol is assigned it is painted cebtered into rect.
+
+  \param painter Painter
+  \param rect Bounding rectangle for the identifier
+*/
+
+void QwtPlotIntervalCurve::drawLegendIdentifier(
+    QPainter *painter, const QRectF &rect ) const
+{
+    const double dim = qMin( rect.width(), rect.height() );
+
+    QSizeF size( dim, dim );
+
+    QRectF r( 0, 0, size.width(), size.height() );
+    r.moveCenter( rect.center() );
+
+    if ( d_data->style == Tube )
+    {
+        painter->fillRect( r, d_data->brush );
+    }
+
+    if ( d_data->symbol &&
+        ( d_data->symbol->style() != QwtIntervalSymbol::NoSymbol ) )
+    {
+        QPen pen = d_data->symbol->pen();
+        pen.setWidthF( pen.widthF() );
+        pen.setCapStyle( Qt::FlatCap );
+
+        painter->setPen( pen );
+        painter->setBrush( d_data->symbol->brush() );
+
+        if ( orientation() == Qt::Vertical )
+        {
+            d_data->symbol->draw( painter, orientation(),
+                QPointF( r.center().x(), r.top() ),
+                QPointF( r.center().x(), r.bottom() - 1 ) );
+        }
+        else
+        {
+            d_data->symbol->draw( painter, orientation(),
+                QPointF( r.left(), r.center().y() ),
+                QPointF( r.right() - 1, r.center().y() ) );
+        }
+    }
+}
Index: trunk/BNC/qwt/qwt_plot_intervalcurve.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_intervalcurve.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_intervalcurve.h	(revision 4271)
@@ -0,0 +1,130 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_INTERVAL_CURVE_H
+#define QWT_PLOT_INTERVAL_CURVE_H
+
+#include "qwt_global.h"
+#include "qwt_plot_seriesitem.h"
+#include "qwt_series_data.h"
+
+class QwtIntervalSymbol;
+
+/*!
+  \brief QwtPlotIntervalCurve represents a series of samples, where each value
+         is associated with an interval ( \f$[y1,y2] = f(x)\f$ ).
+
+  The representation depends on the style() and an optional symbol()
+  that is displayed for each interval. QwtPlotIntervalCurve might be used
+  to disply error bars or the area between 2 curves.
+*/
+
+class QWT_EXPORT QwtPlotIntervalCurve: public QwtPlotSeriesItem<QwtIntervalSample>
+{
+public:
+    /*!
+        \brief Curve styles.
+        The default setting is QwtPlotIntervalCurve::Tube.
+
+        \sa setStyle(), style()
+    */
+
+    enum CurveStyle
+    {
+        /*!
+           Don't draw a curve. Note: This doesn't affect the symbols.
+         */
+        NoCurve,
+
+        /*!
+           Build 2 curves from the upper and lower limits of the intervals
+           and draw them with the pen(). The area between the curves is
+           filled with the brush().
+         */
+        Tube,
+
+        /*!
+           Styles >= QwtPlotIntervalCurve::UserCurve are reserved for derived
+           classes that overload drawSeries() with
+           additional application specific curve types.
+         */
+        UserCurve = 100
+    };
+
+    /*!
+        Attributes to modify the drawing algorithm.
+        \sa setPaintAttribute(), testPaintAttribute()
+    */
+    enum PaintAttribute
+    {
+        /*!
+          Clip polygons before painting them. In situations, where points
+          are far outside the visible area (f.e when zooming deep) this
+          might be a substantial improvement for the painting performance.
+         */
+        ClipPolygons = 0x01,
+
+        //! Check if a symbol is on the plot canvas before painting it.
+        ClipSymbol   = 0x02
+    };
+
+    //! Paint attributes
+    typedef QFlags<PaintAttribute> PaintAttributes;
+
+    explicit QwtPlotIntervalCurve( const QString &title = QString::null );
+    explicit QwtPlotIntervalCurve( const QwtText &title );
+
+    virtual ~QwtPlotIntervalCurve();
+
+    virtual int rtti() const;
+
+    void setPaintAttribute( PaintAttribute, bool on = true );
+    bool testPaintAttribute( PaintAttribute ) const;
+
+    void setSamples( const QVector<QwtIntervalSample> & );
+
+    void setPen( const QPen & );
+    const QPen &pen() const;
+
+    void setBrush( const QBrush & );
+    const QBrush &brush() const;
+
+    void setStyle( CurveStyle style );
+    CurveStyle style() const;
+
+    void setSymbol( const QwtIntervalSymbol * );
+    const QwtIntervalSymbol *symbol() const;
+
+    virtual void drawSeries( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    virtual QRectF boundingRect() const;
+    virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const;
+
+protected:
+
+    void init();
+
+    virtual void drawTube( QPainter *,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    virtual void drawSymbols( QPainter *, const QwtIntervalSymbol &,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotIntervalCurve::PaintAttributes )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_item.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_item.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_item.cpp	(revision 4271)
@@ -0,0 +1,542 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_item.h"
+#include "qwt_text.h"
+#include "qwt_plot.h"
+#include "qwt_legend.h"
+#include "qwt_legend_item.h"
+#include "qwt_scale_div.h"
+#include <qpainter.h>
+
+class QwtPlotItem::PrivateData
+{
+public:
+    PrivateData():
+        plot( NULL ),
+        isVisible( true ),
+        attributes( 0 ),
+        renderHints( 0 ),
+        z( 0.0 ),
+        xAxis( QwtPlot::xBottom ),
+        yAxis( QwtPlot::yLeft )
+    {
+    }
+
+    mutable QwtPlot *plot;
+
+    bool isVisible;
+    QwtPlotItem::ItemAttributes attributes;
+    QwtPlotItem::RenderHints renderHints;
+    double z;
+
+    int xAxis;
+    int yAxis;
+
+    QwtText title;
+};
+
+/*!
+   Constructor
+   \param title Title of the item
+*/
+QwtPlotItem::QwtPlotItem( const QwtText &title )
+{
+    d_data = new PrivateData;
+    d_data->title = title;
+}
+
+//! Destroy the QwtPlotItem
+QwtPlotItem::~QwtPlotItem()
+{
+    attach( NULL );
+    delete d_data;
+}
+
+/*!
+  \brief Attach the item to a plot.
+
+  This method will attach a QwtPlotItem to the QwtPlot argument. It will first
+  detach the QwtPlotItem from any plot from a previous call to attach (if
+  necessary). If a NULL argument is passed, it will detach from any QwtPlot it
+  was attached to.
+
+  \param plot Plot widget
+  \sa detach()
+*/
+void QwtPlotItem::attach( QwtPlot *plot )
+{
+    if ( plot == d_data->plot )
+        return;
+
+    // remove the item from the previous plot
+
+    if ( d_data->plot )
+    {
+        if ( d_data->plot->legend() )
+            d_data->plot->legend()->remove( this );
+
+        d_data->plot->attachItem( this, false );
+
+        if ( d_data->plot->autoReplot() )
+            d_data->plot->update();
+    }
+
+    d_data->plot = plot;
+
+    if ( d_data->plot )
+    {
+        // insert the item into the current plot
+
+        d_data->plot->attachItem( this, true );
+        itemChanged();
+    }
+}
+
+/*!
+   \brief This method detaches a QwtPlotItem from any 
+          QwtPlot it has been associated with.
+
+   detach() is equivalent to calling attach( NULL )
+   \sa attach()
+*/
+void QwtPlotItem::detach()
+{
+    attach( NULL );
+}
+
+/*!
+   Return rtti for the specific class represented. QwtPlotItem is simply
+   a virtual interface class, and base classes will implement this method
+   with specific rtti values so a user can differentiate them.
+
+   The rtti value is useful for environments, where the
+   runtime type information is disabled and it is not possible
+   to do a dynamic_cast<...>.
+
+   \return rtti value
+   \sa RttiValues
+*/
+int QwtPlotItem::rtti() const
+{
+    return Rtti_PlotItem;
+}
+
+//! Return attached plot
+QwtPlot *QwtPlotItem::plot() const
+{
+    return d_data->plot;
+}
+
+/*!
+   Plot items are painted in increasing z-order.
+
+   \return setZ(), QwtPlotDict::itemList()
+*/
+double QwtPlotItem::z() const
+{
+    return d_data->z;
+}
+
+/*!
+   \brief Set the z value
+
+   Plot items are painted in increasing z-order.
+
+   \param z Z-value
+   \sa z(), QwtPlotDict::itemList()
+*/
+void QwtPlotItem::setZ( double z )
+{
+    if ( d_data->z != z )
+    {
+        if ( d_data->plot ) // update the z order
+            d_data->plot->attachItem( this, false );
+
+        d_data->z = z;
+
+        if ( d_data->plot )
+            d_data->plot->attachItem( this, true );
+
+        itemChanged();
+    }
+}
+
+/*!
+   Set a new title
+
+   \param title Title
+   \sa title()
+*/
+void QwtPlotItem::setTitle( const QString &title )
+{
+    setTitle( QwtText( title ) );
+}
+
+/*!
+   Set a new title
+
+   \param title Title
+   \sa title()
+*/
+void QwtPlotItem::setTitle( const QwtText &title )
+{
+    if ( d_data->title != title )
+    {
+        d_data->title = title;
+        itemChanged();
+    }
+}
+
+/*!
+   \return Title of the item
+   \sa setTitle()
+*/
+const QwtText &QwtPlotItem::title() const
+{
+    return d_data->title;
+}
+
+/*!
+   Toggle an item attribute
+
+   \param attribute Attribute type
+   \param on true/false
+
+   \sa testItemAttribute(), ItemAttribute
+*/
+void QwtPlotItem::setItemAttribute( ItemAttribute attribute, bool on )
+{
+    if ( bool( d_data->attributes & attribute ) != on )
+    {
+        if ( on )
+            d_data->attributes |= attribute;
+        else
+            d_data->attributes &= ~attribute;
+
+        itemChanged();
+    }
+}
+
+/*!
+   Test an item attribute
+
+   \param attribute Attribute type
+   \return true/false
+   \sa setItemAttribute(), ItemAttribute
+*/
+bool QwtPlotItem::testItemAttribute( ItemAttribute attribute ) const
+{
+    return ( d_data->attributes & attribute );
+}
+
+/*!
+   Toggle an render hint
+
+   \param hint Render hint
+   \param on true/false
+
+   \sa testRenderHint(), RenderHint
+*/
+void QwtPlotItem::setRenderHint( RenderHint hint, bool on )
+{
+    if ( ( ( d_data->renderHints & hint ) != 0 ) != on )
+    {
+        if ( on )
+            d_data->renderHints |= hint;
+        else
+            d_data->renderHints &= ~hint;
+
+        itemChanged();
+    }
+}
+
+/*!
+   Test a render hint
+
+   \param hint Render hint
+   \return true/false
+   \sa setRenderHint(), RenderHint
+*/
+bool QwtPlotItem::testRenderHint( RenderHint hint ) const
+{
+    return ( d_data->renderHints & hint );
+}
+
+//! Show the item
+void QwtPlotItem::show()
+{
+    setVisible( true );
+}
+
+//! Hide the item
+void QwtPlotItem::hide()
+{
+    setVisible( false );
+}
+
+/*!
+    Show/Hide the item
+
+    \param on Show if true, otherwise hide
+    \sa isVisible(), show(), hide()
+*/
+void QwtPlotItem::setVisible( bool on )
+{
+    if ( on != d_data->isVisible )
+    {
+        d_data->isVisible = on;
+        itemChanged();
+    }
+}
+
+/*!
+    \return true if visible
+    \sa setVisible(), show(), hide()
+*/
+bool QwtPlotItem::isVisible() const
+{
+    return d_data->isVisible;
+}
+
+/*!
+   Update the legend and call QwtPlot::autoRefresh for the
+   parent plot.
+
+   \sa updateLegend()
+*/
+void QwtPlotItem::itemChanged()
+{
+    if ( d_data->plot )
+    {
+        if ( d_data->plot->legend() )
+            updateLegend( d_data->plot->legend() );
+
+        d_data->plot->autoRefresh();
+    }
+}
+
+/*!
+   Set X and Y axis
+
+   The item will painted according to the coordinates its Axes.
+
+   \param xAxis X Axis
+   \param yAxis Y Axis
+
+   \sa setXAxis(), setYAxis(), xAxis(), yAxis()
+*/
+void QwtPlotItem::setAxes( int xAxis, int yAxis )
+{
+    if ( xAxis == QwtPlot::xBottom || xAxis == QwtPlot::xTop )
+        d_data->xAxis = xAxis;
+
+    if ( yAxis == QwtPlot::yLeft || yAxis == QwtPlot::yRight )
+        d_data->yAxis = yAxis;
+
+    itemChanged();
+}
+
+/*!
+   Set the X axis
+
+   The item will painted according to the coordinates its Axes.
+
+   \param axis X Axis
+   \sa setAxes(), setYAxis(), xAxis()
+*/
+void QwtPlotItem::setXAxis( int axis )
+{
+    if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
+    {
+        d_data->xAxis = axis;
+        itemChanged();
+    }
+}
+
+/*!
+   Set the Y axis
+
+   The item will painted according to the coordinates its Axes.
+
+   \param axis Y Axis
+   \sa setAxes(), setXAxis(), yAxis()
+*/
+void QwtPlotItem::setYAxis( int axis )
+{
+    if ( axis == QwtPlot::yLeft || axis == QwtPlot::yRight )
+    {
+        d_data->yAxis = axis;
+        itemChanged();
+    }
+}
+
+//! Return xAxis
+int QwtPlotItem::xAxis() const
+{
+    return d_data->xAxis;
+}
+
+//! Return yAxis
+int QwtPlotItem::yAxis() const
+{
+    return d_data->yAxis;
+}
+
+/*!
+   \return An invalid bounding rect: QRectF(1.0, 1.0, -2.0, -2.0)
+*/
+QRectF QwtPlotItem::boundingRect() const
+{
+    return QRectF( 1.0, 1.0, -2.0, -2.0 ); // invalid
+}
+
+/*!
+   \brief Allocate the widget that represents the item on the legend
+
+   The default implementation returns a QwtLegendItem(), but an item 
+   could be represented by any type of widget,
+   by overloading legendItem() and updateLegend().
+
+   \return QwtLegendItem()
+   \sa updateLegend() QwtLegend()
+*/
+QWidget *QwtPlotItem::legendItem() const
+{
+    QwtLegendItem *item = new QwtLegendItem;
+    if ( d_data->plot )
+    {
+        QObject::connect( item, SIGNAL( clicked() ),
+            d_data->plot, SLOT( legendItemClicked() ) );
+        QObject::connect( item, SIGNAL( checked( bool ) ),
+            d_data->plot, SLOT( legendItemChecked( bool ) ) );
+    }
+    return item;
+}
+
+/*!
+   \brief Update the widget that represents the item on the legend
+
+   updateLegend() is called from itemChanged() to adopt the widget
+   representing the item on the legend to its new configuration.
+
+   The default implementation updates a QwtLegendItem(), 
+   but an item could be represented by any type of widget,
+   by overloading legendItem() and updateLegend().
+
+   \param legend Legend
+
+   \sa legendItem(), itemChanged(), QwtLegend()
+*/
+void QwtPlotItem::updateLegend( QwtLegend *legend ) const
+{
+    if ( legend == NULL )
+        return;
+
+    QWidget *lgdItem = legend->find( this );
+    if ( testItemAttribute( QwtPlotItem::Legend ) )
+    {
+        if ( lgdItem == NULL )
+        {
+            lgdItem = legendItem();
+            if ( lgdItem )
+                legend->insert( this, lgdItem );
+        }
+
+        QwtLegendItem *label = qobject_cast<QwtLegendItem *>( lgdItem );
+        if ( label )
+        {
+            // paint the identifier
+            const QSize sz = label->identifierSize();
+
+            QPixmap identifier( sz.width(), sz.height() );
+            identifier.fill( Qt::transparent );
+
+            QPainter painter( &identifier );
+            painter.setRenderHint( QPainter::Antialiasing,
+                testRenderHint( QwtPlotItem::RenderAntialiased ) );
+            drawLegendIdentifier( &painter,
+                QRect( 0, 0, sz.width(), sz.height() ) );
+            painter.end();
+
+            const bool doUpdate = label->updatesEnabled();
+            if ( doUpdate )
+                label->setUpdatesEnabled( false );
+
+            label->setText( title() );
+            label->setIdentifier( identifier );
+            label->setItemMode( legend->itemMode() );
+
+            if ( doUpdate )
+                label->setUpdatesEnabled( true );
+
+            label->update();
+        }
+    }
+    else
+    {
+        if ( lgdItem )
+        {
+            lgdItem->hide();
+            lgdItem->deleteLater();
+        }
+    }
+}
+
+/*!
+   \brief Update the item to changes of the axes scale division
+
+   Update the item, when the axes of plot have changed.
+   The default implementation does nothing, but items that depend
+   on the scale division (like QwtPlotGrid()) have to reimplement
+   updateScaleDiv()
+
+   \param xScaleDiv Scale division of the x-axis
+   \param yScaleDiv Scale division of the y-axis
+
+   \sa QwtPlot::updateAxes()
+*/
+void QwtPlotItem::updateScaleDiv( const QwtScaleDiv &xScaleDiv,
+    const QwtScaleDiv &yScaleDiv )
+{
+    Q_UNUSED( xScaleDiv );
+    Q_UNUSED( yScaleDiv );
+}
+
+/*!
+   \brief Calculate the bounding scale rect of 2 maps
+
+   \param xMap X map
+   \param yMap X map
+
+   \return Bounding scale rect of the scale maps, normalized
+*/
+QRectF QwtPlotItem::scaleRect( const QwtScaleMap &xMap,
+    const QwtScaleMap &yMap ) const
+{
+    return QRectF( xMap.s1(), yMap.s1(),
+        xMap.sDist(), yMap.sDist() );
+}
+
+/*!
+   \brief Calculate the bounding paint rect of 2 maps
+
+   \param xMap X map
+   \param yMap X map
+
+   \return Bounding paint rect of the scale maps, normalized
+*/
+QRectF QwtPlotItem::paintRect( const QwtScaleMap &xMap,
+    const QwtScaleMap &yMap ) const
+{
+    const QRectF rect( xMap.p1(), yMap.p1(),
+        xMap.pDist(), yMap.pDist() );
+
+    return rect;
+}
Index: trunk/BNC/qwt/qwt_plot_item.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_item.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_item.h	(revision 4271)
@@ -0,0 +1,192 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_ITEM_H
+#define QWT_PLOT_ITEM_H
+
+#include "qwt_global.h"
+#include "qwt_legend_itemmanager.h"
+#include "qwt_text.h"
+#include <qrect.h>
+
+class QString;
+class QPainter;
+class QWidget;
+class QwtPlot;
+class QwtLegend;
+class QwtScaleMap;
+class QwtScaleDiv;
+
+/*!
+  \brief Base class for items on the plot canvas
+
+  A plot item is "something", that can be painted on the plot canvas,
+  or only affects the scales of the plot widget. They can be categorized as:
+
+  - Representator\n
+    A "Representator" is an item that represents some sort of data
+    on the plot canvas. The different representator classes are organized
+    according to the characteristics of the data:
+    - QwtPlotMarker
+      Represents a point or a horizontal/vertical coordinate
+    - QwtPlotCurve
+      Represents a series of points
+    - QwtPlotSpectrogram ( QwtPlotRasterItem )
+      Represents raster data
+    - ...
+
+  - Decorators\n
+    A "Decorator" is an item, that displays additional information, that
+    is not related to any data:
+    - QwtPlotGrid
+    - QwtPlotScaleItem
+    - QwtPlotSvgItem
+    - ...
+
+  Depending on the QwtPlotItem::ItemAttribute flags, an item is included
+  into autoscaling or has an entry on the legnd.
+
+  Before misusing the existing item classes it might be better to
+  implement a new type of plot item
+  ( don't implement a watermark as spectrogram ).
+  Deriving a new type of QwtPlotItem primarily means to implement
+  the YourPlotItem::draw() method.
+
+  \sa The cpuplot example shows the implementation of additional plot items.
+*/
+
+class QWT_EXPORT QwtPlotItem: public QwtLegendItemManager
+{
+public:
+    /*!
+        \brief Runtime type information
+
+        RttiValues is used to cast plot items, without
+        having to enable runtime type information of the compiler.
+     */
+    enum RttiValues
+    {
+        Rtti_PlotItem = 0,
+
+        Rtti_PlotGrid,
+        Rtti_PlotScale,
+        Rtti_PlotMarker,
+        Rtti_PlotCurve,
+        Rtti_PlotSpectroCurve,
+        Rtti_PlotIntervalCurve,
+        Rtti_PlotHistogram,
+        Rtti_PlotSpectrogram,
+        Rtti_PlotSVG,
+
+        Rtti_PlotUserItem = 1000
+    };
+
+    /*!
+       Plot Item Attributes
+       \sa setItemAttribute(), testItemAttribute()
+     */
+    enum ItemAttribute
+    {
+        //! The item is represented on the legend.
+        Legend = 0x01,
+
+        /*!
+         The boundingRect() of the item is included in the
+         autoscaling calculation.
+         */
+        AutoScale = 0x02
+    };
+
+    //! Plot Item Attributes
+    typedef QFlags<ItemAttribute> ItemAttributes;
+
+    //! Render hints
+    enum RenderHint
+    {
+        //! Enable antialiasing
+        RenderAntialiased = 1
+    };
+
+    //! Render hints
+    typedef QFlags<RenderHint> RenderHints;
+
+    explicit QwtPlotItem( const QwtText &title = QwtText() );
+    virtual ~QwtPlotItem();
+
+    void attach( QwtPlot *plot );
+    void detach();
+
+    QwtPlot *plot() const;
+
+    void setTitle( const QString &title );
+    void setTitle( const QwtText &title );
+    const QwtText &title() const;
+
+    virtual int rtti() const;
+
+    void setItemAttribute( ItemAttribute, bool on = true );
+    bool testItemAttribute( ItemAttribute ) const;
+
+    void setRenderHint( RenderHint, bool on = true );
+    bool testRenderHint( RenderHint ) const;
+
+    double z() const;
+    void setZ( double z );
+
+    void show();
+    void hide();
+    virtual void setVisible( bool );
+    bool isVisible () const;
+
+    void setAxes( int xAxis, int yAxis );
+
+    void setXAxis( int axis );
+    int xAxis() const;
+
+    void setYAxis( int axis );
+    int yAxis() const;
+
+    virtual void itemChanged();
+
+    /*!
+      \brief Draw the item
+
+      \param painter Painter
+      \param xMap Maps x-values into pixel coordinates.
+      \param yMap Maps y-values into pixel coordinates.
+      \param canvasRect Contents rect of the canvas in painter coordinates
+    */
+    virtual void draw( QPainter *painter,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect ) const = 0;
+
+    virtual QRectF boundingRect() const;
+
+    virtual void updateLegend( QwtLegend * ) const;
+    virtual void updateScaleDiv( 
+        const QwtScaleDiv&, const QwtScaleDiv& );
+
+    virtual QWidget *legendItem() const;
+
+    QRectF scaleRect( const QwtScaleMap &, const QwtScaleMap & ) const;
+    QRectF paintRect( const QwtScaleMap &, const QwtScaleMap & ) const;
+
+private:
+    // Disabled copy constructor and operator=
+    QwtPlotItem( const QwtPlotItem & );
+    QwtPlotItem &operator=( const QwtPlotItem & );
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::ItemAttributes )
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::RenderHints )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_layout.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_layout.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_layout.cpp	(revision 4271)
@@ -0,0 +1,1227 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_layout.h"
+#include "qwt_text.h"
+#include "qwt_text_label.h"
+#include "qwt_plot_canvas.h"
+#include "qwt_scale_widget.h"
+#include "qwt_legend.h"
+#include <qscrollbar.h>
+#include <qmath.h>
+
+class QwtPlotLayout::LayoutData
+{
+public:
+    void init( const QwtPlot *, const QRectF &rect );
+
+    struct t_legendData
+    {
+        int frameWidth;
+        int vScrollBarWidth;
+        int hScrollBarHeight;
+        QSize hint;
+    } legend;
+
+    struct t_titleData
+    {
+        QwtText text;
+        int frameWidth;
+    } title;
+
+    struct t_scaleData
+    {
+        bool isEnabled;
+        const QwtScaleWidget *scaleWidget;
+        QFont scaleFont;
+        int start;
+        int end;
+        int baseLineOffset;
+        int tickOffset;
+        int dimWithoutTitle;
+    } scale[QwtPlot::axisCnt];
+
+    struct t_canvasData
+    {
+        int frameWidth;
+    } canvas;
+};
+
+/*
+  Extract all layout relevant data from the plot components
+*/
+
+void QwtPlotLayout::LayoutData::init( const QwtPlot *plot, const QRectF &rect )
+{
+    // legend
+
+    if ( plot->plotLayout()->legendPosition() != QwtPlot::ExternalLegend
+        && plot->legend() )
+    {
+        legend.frameWidth = plot->legend()->frameWidth();
+        legend.vScrollBarWidth =
+            plot->legend()->verticalScrollBar()->sizeHint().width();
+        legend.hScrollBarHeight =
+            plot->legend()->horizontalScrollBar()->sizeHint().height();
+
+        const QSize hint = plot->legend()->sizeHint();
+
+        int w = qMin( hint.width(), qFloor( rect.width() ) );
+        int h = plot->legend()->heightForWidth( w );
+        if ( h == 0 )
+            h = hint.height();
+
+        if ( h > rect.height() )
+            w += legend.vScrollBarWidth;
+
+        legend.hint = QSize( w, h );
+    }
+
+    // title
+
+    title.frameWidth = 0;
+    title.text = QwtText();
+
+    if ( plot->titleLabel() )
+    {
+        const QwtTextLabel *label = plot->titleLabel();
+        title.text = label->text();
+        if ( !( title.text.testPaintAttribute( QwtText::PaintUsingTextFont ) ) )
+            title.text.setFont( label->font() );
+
+        title.frameWidth = plot->titleLabel()->frameWidth();
+    }
+
+    // scales
+
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        if ( plot->axisEnabled( axis ) )
+        {
+            const QwtScaleWidget *scaleWidget = plot->axisWidget( axis );
+
+            scale[axis].isEnabled = true;
+
+            scale[axis].scaleWidget = scaleWidget;
+
+            scale[axis].scaleFont = scaleWidget->font();
+
+            scale[axis].start = scaleWidget->startBorderDist();
+            scale[axis].end = scaleWidget->endBorderDist();
+
+            scale[axis].baseLineOffset = scaleWidget->margin();
+            scale[axis].tickOffset = scaleWidget->margin();
+            if ( scaleWidget->scaleDraw()->hasComponent(
+                QwtAbstractScaleDraw::Ticks ) )
+            {
+                scale[axis].tickOffset +=
+                    scaleWidget->scaleDraw()->maxTickLength();
+            }
+
+            scale[axis].dimWithoutTitle = scaleWidget->dimForLength(
+                QWIDGETSIZE_MAX, scale[axis].scaleFont );
+
+            if ( !scaleWidget->title().isEmpty() )
+            {
+                scale[axis].dimWithoutTitle -=
+                    scaleWidget->titleHeightForWidth( QWIDGETSIZE_MAX );
+            }
+        }
+        else
+        {
+            scale[axis].isEnabled = false;
+            scale[axis].start = 0;
+            scale[axis].end = 0;
+            scale[axis].baseLineOffset = 0;
+            scale[axis].tickOffset = 0;
+            scale[axis].dimWithoutTitle = 0;
+        }
+    }
+
+    // canvas
+
+    canvas.frameWidth = plot->canvas()->frameWidth();
+}
+
+class QwtPlotLayout::PrivateData
+{
+public:
+    PrivateData():
+        spacing( 5 ),
+        alignCanvasToScales( false )
+    {
+    }
+
+    QRectF titleRect;
+    QRectF legendRect;
+    QRectF scaleRect[QwtPlot::axisCnt];
+    QRectF canvasRect;
+
+    QwtPlotLayout::LayoutData layoutData;
+
+    QwtPlot::LegendPosition legendPos;
+    double legendRatio;
+    unsigned int spacing;
+    unsigned int canvasMargin[QwtPlot::axisCnt];
+    bool alignCanvasToScales;
+};
+
+/*!
+  \brief Constructor
+ */
+
+QwtPlotLayout::QwtPlotLayout()
+{
+    d_data = new PrivateData;
+
+    setLegendPosition( QwtPlot::BottomLegend );
+    setCanvasMargin( 4 );
+
+    invalidate();
+}
+
+//! Destructor
+QwtPlotLayout::~QwtPlotLayout()
+{
+    delete d_data;
+}
+
+/*!
+  Change a margin of the canvas. The margin is the space
+  above/below the scale ticks. A negative margin will
+  be set to -1, excluding the borders of the scales.
+
+  \param margin New margin
+  \param axis One of QwtPlot::Axis. Specifies where the position of the margin.
+              -1 means margin at all borders.
+  \sa canvasMargin()
+
+  \warning The margin will have no effect when alignCanvasToScales is true
+*/
+
+void QwtPlotLayout::setCanvasMargin( int margin, int axis )
+{
+    if ( margin < -1 )
+        margin = -1;
+
+    if ( axis == -1 )
+    {
+        for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
+            d_data->canvasMargin[axis] = margin;
+    }
+    else if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        d_data->canvasMargin[axis] = margin;
+}
+
+/*!
+    \return Margin around the scale tick borders
+    \sa setCanvasMargin()
+*/
+int QwtPlotLayout::canvasMargin( int axis ) const
+{
+    if ( axis < 0 || axis >= QwtPlot::axisCnt )
+        return 0;
+
+    return d_data->canvasMargin[axis];
+}
+
+/*!
+  Change the align-canvas-to-axis-scales setting. The canvas may:
+  - extend beyond the axis scale ends to maximize its size,
+  - align with the axis scale ends to control its size.
+
+  \param alignCanvasToScales New align-canvas-to-axis-scales setting
+
+  \sa setCanvasMargin()
+  \note In this context the term 'scale' means the backbone of a scale.
+  \warning In case of alignCanvasToScales == true canvasMargin will have
+           no effect
+*/
+void QwtPlotLayout::setAlignCanvasToScales( bool alignCanvasToScales )
+{
+    d_data->alignCanvasToScales = alignCanvasToScales;
+}
+
+/*!
+  Return the align-canvas-to-axis-scales setting. The canvas may:
+  - extend beyond the axis scale ends to maximize its size
+  - align with the axis scale ends to control its size.
+
+  \return align-canvas-to-axis-scales setting
+  \sa setAlignCanvasToScales, setCanvasMargin()
+  \note In this context the term 'scale' means the backbone of a scale.
+*/
+bool QwtPlotLayout::alignCanvasToScales() const
+{
+    return d_data->alignCanvasToScales;
+}
+
+/*!
+  Change the spacing of the plot. The spacing is the distance
+  between the plot components.
+
+  \param spacing new spacing
+  \sa setMargin(), spacing()
+*/
+void QwtPlotLayout::setSpacing( int spacing )
+{
+    d_data->spacing = qMax( 0, spacing );
+}
+
+/*!
+  \return spacing
+  \sa margin(), setSpacing()
+*/
+int QwtPlotLayout::spacing() const
+{
+    return d_data->spacing;
+}
+
+/*!
+  \brief Specify the position of the legend
+  \param pos The legend's position.
+  \param ratio Ratio between legend and the bounding rect
+               of title, canvas and axes. The legend will be shrinked
+               if it would need more space than the given ratio.
+               The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
+               it will be reset to the default ratio.
+               The default vertical/horizontal ratio is 0.33/0.5.
+
+  \sa QwtPlot::setLegendPosition()
+*/
+
+void QwtPlotLayout::setLegendPosition( QwtPlot::LegendPosition pos, double ratio )
+{
+    if ( ratio > 1.0 )
+        ratio = 1.0;
+
+    switch ( pos )
+    {
+        case QwtPlot::TopLegend:
+        case QwtPlot::BottomLegend:
+            if ( ratio <= 0.0 )
+                ratio = 0.33;
+            d_data->legendRatio = ratio;
+            d_data->legendPos = pos;
+            break;
+        case QwtPlot::LeftLegend:
+        case QwtPlot::RightLegend:
+            if ( ratio <= 0.0 )
+                ratio = 0.5;
+            d_data->legendRatio = ratio;
+            d_data->legendPos = pos;
+            break;
+        case QwtPlot::ExternalLegend:
+            d_data->legendRatio = ratio; // meaningless
+            d_data->legendPos = pos;
+        default:
+            break;
+    }
+}
+
+/*!
+  \brief Specify the position of the legend
+  \param pos The legend's position. Valid values are
+      \c QwtPlot::LeftLegend, \c QwtPlot::RightLegend,
+      \c QwtPlot::TopLegend, \c QwtPlot::BottomLegend.
+
+  \sa QwtPlot::setLegendPosition()
+*/
+void QwtPlotLayout::setLegendPosition( QwtPlot::LegendPosition pos )
+{
+    setLegendPosition( pos, 0.0 );
+}
+
+/*!
+  \return Position of the legend
+  \sa setLegendPosition(), QwtPlot::setLegendPosition(),
+      QwtPlot::legendPosition()
+*/
+QwtPlot::LegendPosition QwtPlotLayout::legendPosition() const
+{
+    return d_data->legendPos;
+}
+
+/*!
+  Specify the relative size of the legend in the plot
+  \param ratio Ratio between legend and the bounding rect
+               of title, canvas and axes. The legend will be shrinked
+               if it would need more space than the given ratio.
+               The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
+               it will be reset to the default ratio.
+               The default vertical/horizontal ratio is 0.33/0.5.
+*/
+void QwtPlotLayout::setLegendRatio( double ratio )
+{
+    setLegendPosition( legendPosition(), ratio );
+}
+
+/*!
+  \return The relative size of the legend in the plot.
+  \sa setLegendPosition()
+*/
+double QwtPlotLayout::legendRatio() const
+{
+    return d_data->legendRatio;
+}
+
+/*!
+  \return Geometry for the title
+  \sa activate(), invalidate()
+*/
+
+const QRectF &QwtPlotLayout::titleRect() const
+{
+    return d_data->titleRect;
+}
+
+/*!
+  \return Geometry for the legend
+  \sa activate(), invalidate()
+*/
+
+const QRectF &QwtPlotLayout::legendRect() const
+{
+    return d_data->legendRect;
+}
+
+/*!
+  \param axis Axis index
+  \return Geometry for the scale
+  \sa activate(), invalidate()
+*/
+
+const QRectF &QwtPlotLayout::scaleRect( int axis ) const
+{
+    if ( axis < 0 || axis >= QwtPlot::axisCnt )
+    {
+        static QRectF dummyRect;
+        return dummyRect;
+    }
+    return d_data->scaleRect[axis];
+}
+
+/*!
+  \return Geometry for the canvas
+  \sa activate(), invalidate()
+*/
+
+const QRectF &QwtPlotLayout::canvasRect() const
+{
+    return d_data->canvasRect;
+}
+
+/*!
+  Invalidate the geometry of all components.
+  \sa activate()
+*/
+void QwtPlotLayout::invalidate()
+{
+    d_data->titleRect = d_data->legendRect = d_data->canvasRect = QRect();
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+        d_data->scaleRect[axis] = QRect();
+}
+
+/*!
+  \brief Return a minimum size hint
+  \sa QwtPlot::minimumSizeHint()
+*/
+
+QSize QwtPlotLayout::minimumSizeHint( const QwtPlot *plot ) const
+{
+    class ScaleData
+    {
+    public:
+        ScaleData()
+        {
+            w = h = minLeft = minRight = tickOffset = 0;
+        }
+
+        int w;
+        int h;
+        int minLeft;
+        int minRight;
+        int tickOffset;
+    } scaleData[QwtPlot::axisCnt];
+
+    int canvasBorder[QwtPlot::axisCnt];
+
+    int axis;
+    for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        if ( plot->axisEnabled( axis ) )
+        {
+            const QwtScaleWidget *scl = plot->axisWidget( axis );
+            ScaleData &sd = scaleData[axis];
+
+            const QSize hint = scl->minimumSizeHint();
+            sd.w = hint.width();
+            sd.h = hint.height();
+            scl->getBorderDistHint( sd.minLeft, sd.minRight );
+            sd.tickOffset = scl->margin();
+            if ( scl->scaleDraw()->hasComponent( QwtAbstractScaleDraw::Ticks ) )
+                sd.tickOffset += scl->scaleDraw()->maxTickLength();
+        }
+
+        canvasBorder[axis] = plot->canvas()->frameWidth() +
+            d_data->canvasMargin[axis] + 1;
+
+    }
+
+
+    for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        ScaleData &sd = scaleData[axis];
+        if ( sd.w && ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) )
+        {
+            if ( ( sd.minLeft > canvasBorder[QwtPlot::yLeft] )
+                && scaleData[QwtPlot::yLeft].w )
+            {
+                int shiftLeft = sd.minLeft - canvasBorder[QwtPlot::yLeft];
+                if ( shiftLeft > scaleData[QwtPlot::yLeft].w )
+                    shiftLeft = scaleData[QwtPlot::yLeft].w;
+
+                sd.w -= shiftLeft;
+            }
+            if ( ( sd.minRight > canvasBorder[QwtPlot::yRight] )
+                && scaleData[QwtPlot::yRight].w )
+            {
+                int shiftRight = sd.minRight - canvasBorder[QwtPlot::yRight];
+                if ( shiftRight > scaleData[QwtPlot::yRight].w )
+                    shiftRight = scaleData[QwtPlot::yRight].w;
+
+                sd.w -= shiftRight;
+            }
+        }
+
+        if ( sd.h && ( axis == QwtPlot::yLeft || axis == QwtPlot::yRight ) )
+        {
+            if ( ( sd.minLeft > canvasBorder[QwtPlot::xBottom] ) &&
+                scaleData[QwtPlot::xBottom].h )
+            {
+                int shiftBottom = sd.minLeft - canvasBorder[QwtPlot::xBottom];
+                if ( shiftBottom > scaleData[QwtPlot::xBottom].tickOffset )
+                    shiftBottom = scaleData[QwtPlot::xBottom].tickOffset;
+
+                sd.h -= shiftBottom;
+            }
+            if ( ( sd.minLeft > canvasBorder[QwtPlot::xTop] ) &&
+                scaleData[QwtPlot::xTop].h )
+            {
+                int shiftTop = sd.minRight - canvasBorder[QwtPlot::xTop];
+                if ( shiftTop > scaleData[QwtPlot::xTop].tickOffset )
+                    shiftTop = scaleData[QwtPlot::xTop].tickOffset;
+
+                sd.h -= shiftTop;
+            }
+        }
+    }
+
+    const QwtPlotCanvas *canvas = plot->canvas();
+    const QSize minCanvasSize = canvas->minimumSize();
+
+    int w = scaleData[QwtPlot::yLeft].w + scaleData[QwtPlot::yRight].w;
+    int cw = qMax( scaleData[QwtPlot::xBottom].w, scaleData[QwtPlot::xTop].w )
+        + 2 * ( canvas->frameWidth() + 1 );
+    w += qMax( cw, minCanvasSize.width() );
+
+    int h = scaleData[QwtPlot::xBottom].h + scaleData[QwtPlot::xTop].h;
+    int ch = qMax( scaleData[QwtPlot::yLeft].h, scaleData[QwtPlot::yRight].h )
+        + 2 * ( canvas->frameWidth() + 1 );
+    h += qMax( ch, minCanvasSize.height() );
+
+    const QwtTextLabel *title = plot->titleLabel();
+    if ( title && !title->text().isEmpty() )
+    {
+        // If only QwtPlot::yLeft or QwtPlot::yRight is showing,
+        // we center on the plot canvas.
+        const bool centerOnCanvas = !( plot->axisEnabled( QwtPlot::yLeft )
+            && plot->axisEnabled( QwtPlot::yRight ) );
+
+        int titleW = w;
+        if ( centerOnCanvas )
+        {
+            titleW -= scaleData[QwtPlot::yLeft].w
+                + scaleData[QwtPlot::yRight].w;
+        }
+
+        int titleH = title->heightForWidth( titleW );
+        if ( titleH > titleW ) // Compensate for a long title
+        {
+            w = titleW = titleH;
+            if ( centerOnCanvas )
+            {
+                w += scaleData[QwtPlot::yLeft].w
+                    + scaleData[QwtPlot::yRight].w;
+            }
+
+            titleH = title->heightForWidth( titleW );
+        }
+        h += titleH + d_data->spacing;
+    }
+
+    // Compute the legend contribution
+
+    const QwtLegend *legend = plot->legend();
+    if ( d_data->legendPos != QwtPlot::ExternalLegend
+        && legend && !legend->isEmpty() )
+    {
+        if ( d_data->legendPos == QwtPlot::LeftLegend
+            || d_data->legendPos == QwtPlot::RightLegend )
+        {
+            int legendW = legend->sizeHint().width();
+            int legendH = legend->heightForWidth( legendW );
+
+            if ( legend->frameWidth() > 0 )
+                w += d_data->spacing;
+
+            if ( legendH > h )
+                legendW += legend->verticalScrollBar()->sizeHint().height();
+
+            if ( d_data->legendRatio < 1.0 )
+                legendW = qMin( legendW, int( w / ( 1.0 - d_data->legendRatio ) ) );
+
+            w += legendW + d_data->spacing;
+        }
+        else // QwtPlot::Top, QwtPlot::Bottom
+        {
+            int legendW = qMin( legend->sizeHint().width(), w );
+            int legendH = legend->heightForWidth( legendW );
+
+            if ( legend->frameWidth() > 0 )
+                h += d_data->spacing;
+
+            if ( d_data->legendRatio < 1.0 )
+                legendH = qMin( legendH, int( h / ( 1.0 - d_data->legendRatio ) ) );
+
+            h += legendH + d_data->spacing;
+        }
+    }
+
+    return QSize( w, h );
+}
+
+/*!
+  Find the geometry for the legend
+  \param options Options how to layout the legend
+  \param rect Rectangle where to place the legend
+  \return Geometry for the legend
+  \sa Options
+*/
+
+QRectF QwtPlotLayout::layoutLegend( Options options,
+    const QRectF &rect ) const
+{
+    const QSize hint( d_data->layoutData.legend.hint );
+
+    int dim;
+    if ( d_data->legendPos == QwtPlot::LeftLegend
+        || d_data->legendPos == QwtPlot::RightLegend )
+    {
+        // We don't allow vertical legends to take more than
+        // half of the available space.
+
+        dim = qMin( hint.width(), int( rect.width() * d_data->legendRatio ) );
+
+        if ( !( options & IgnoreScrollbars ) )
+        {
+            if ( hint.height() > rect.height() )
+            {
+                // The legend will need additional
+                // space for the vertical scrollbar.
+
+                dim += d_data->layoutData.legend.vScrollBarWidth;
+            }
+        }
+    }
+    else
+    {
+        dim = qMin( hint.height(), int( rect.height() * d_data->legendRatio ) );
+        dim = qMax( dim, d_data->layoutData.legend.hScrollBarHeight );
+    }
+
+    QRectF legendRect = rect;
+    switch ( d_data->legendPos )
+    {
+        case QwtPlot::LeftLegend:
+            legendRect.setWidth( dim );
+            break;
+        case QwtPlot::RightLegend:
+            legendRect.setX( rect.right() - dim );
+            legendRect.setWidth( dim );
+            break;
+        case QwtPlot::TopLegend:
+            legendRect.setHeight( dim );
+            break;
+        case QwtPlot::BottomLegend:
+            legendRect.setY( rect.bottom() - dim );
+            legendRect.setHeight( dim );
+            break;
+        case QwtPlot::ExternalLegend:
+            break;
+    }
+
+    return legendRect;
+}
+
+/*!
+  Align the legend to the canvas
+  \param canvasRect Geometry of the canvas
+  \param legendRect Maximum geometry for the legend
+  \return Geometry for the aligned legend
+*/
+QRectF QwtPlotLayout::alignLegend( const QRectF &canvasRect,
+    const QRectF &legendRect ) const
+{
+    QRectF alignedRect = legendRect;
+
+    if ( d_data->legendPos == QwtPlot::BottomLegend
+        || d_data->legendPos == QwtPlot::TopLegend )
+    {
+        if ( d_data->layoutData.legend.hint.width() < canvasRect.width() )
+        {
+            alignedRect.setX( canvasRect.x() );
+            alignedRect.setWidth( canvasRect.width() );
+        }
+    }
+    else
+    {
+        if ( d_data->layoutData.legend.hint.height() < canvasRect.height() )
+        {
+            alignedRect.setY( canvasRect.y() );
+            alignedRect.setHeight( canvasRect.height() );
+        }
+    }
+
+    return alignedRect;
+}
+
+/*!
+  Expand all line breaks in text labels, and calculate the height
+  of their widgets in orientation of the text.
+
+  \param options Options how to layout the legend
+  \param rect Bounding rect for title, axes and canvas.
+  \param dimTitle Expanded height of the title widget
+  \param dimAxis Expanded heights of the axis in axis orientation.
+
+  \sa Options
+*/
+void QwtPlotLayout::expandLineBreaks( int options, const QRectF &rect,
+    int &dimTitle, int dimAxis[QwtPlot::axisCnt] ) const
+{
+    dimTitle = 0;
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+        dimAxis[axis] = 0;
+
+    int backboneOffset[QwtPlot::axisCnt];
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        backboneOffset[axis] = 0;
+        if ( !d_data->alignCanvasToScales )
+            backboneOffset[axis] += d_data->canvasMargin[axis];
+        if ( !( options & IgnoreFrames ) )
+            backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
+    }
+
+    bool done = false;
+    while ( !done )
+    {
+        done = true;
+
+        // the size for the 4 axis depend on each other. Expanding
+        // the height of a horizontal axis will shrink the height
+        // for the vertical axis, shrinking the height of a vertical
+        // axis will result in a line break what will expand the
+        // width and results in shrinking the width of a horizontal
+        // axis what might result in a line break of a horizontal
+        // axis ... . So we loop as long until no size changes.
+
+        if ( !d_data->layoutData.title.text.isEmpty() )
+        {
+            int w = rect.width();
+
+            if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
+                != d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
+            {
+                // center to the canvas
+                w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight];
+            }
+
+            int d = qCeil( d_data->layoutData.title.text.heightForWidth( w ) );
+            if ( !( options & IgnoreFrames ) )
+                d += 2 * d_data->layoutData.title.frameWidth;
+
+            if ( d > dimTitle )
+            {
+                dimTitle = d;
+                done = false;
+            }
+        }
+
+        for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+        {
+            const struct LayoutData::t_scaleData &scaleData =
+                d_data->layoutData.scale[axis];
+
+            if ( scaleData.isEnabled )
+            {
+                int length;
+                if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
+                {
+                    length = rect.width() - dimAxis[QwtPlot::yLeft]
+                        - dimAxis[QwtPlot::yRight];
+                    length -= scaleData.start + scaleData.end;
+
+                    if ( dimAxis[QwtPlot::yRight] > 0 )
+                        length -= 1;
+
+                    length += qMin( dimAxis[QwtPlot::yLeft],
+                        scaleData.start - backboneOffset[QwtPlot::yLeft] );
+                    length += qMin( dimAxis[QwtPlot::yRight],
+                        scaleData.end - backboneOffset[QwtPlot::yRight] );
+                }
+                else // QwtPlot::yLeft, QwtPlot::yRight
+                {
+                    length = rect.height() - dimAxis[QwtPlot::xTop]
+                        - dimAxis[QwtPlot::xBottom];
+                    length -= scaleData.start + scaleData.end;
+                    length -= 1;
+
+                    if ( dimAxis[QwtPlot::xBottom] <= 0 )
+                        length -= 1;
+                    if ( dimAxis[QwtPlot::xTop] <= 0 )
+                        length -= 1;
+
+                    if ( dimAxis[QwtPlot::xBottom] > 0 )
+                    {
+                        length += qMin(
+                            d_data->layoutData.scale[QwtPlot::xBottom].tickOffset,
+                            scaleData.start - backboneOffset[QwtPlot::xBottom] );
+                    }
+                    if ( dimAxis[QwtPlot::xTop] > 0 )
+                    {
+                        length += qMin(
+                            d_data->layoutData.scale[QwtPlot::xTop].tickOffset,
+                            scaleData.end - backboneOffset[QwtPlot::xTop] );
+                    }
+
+                    if ( dimTitle > 0 )
+                        length -= dimTitle + d_data->spacing;
+                }
+
+                int d = scaleData.dimWithoutTitle;
+                if ( !scaleData.scaleWidget->title().isEmpty() )
+                {
+                    d += scaleData.scaleWidget->titleHeightForWidth( length );
+                }
+
+
+                if ( d > dimAxis[axis] )
+                {
+                    dimAxis[axis] = d;
+                    done = false;
+                }
+            }
+        }
+    }
+}
+
+/*!
+  Align the ticks of the axis to the canvas borders using
+  the empty corners.
+
+  \sa Options
+*/
+
+void QwtPlotLayout::alignScales( int options,
+    QRectF &canvasRect, QRectF scaleRect[QwtPlot::axisCnt] ) const
+{
+    int backboneOffset[QwtPlot::axisCnt];
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        backboneOffset[axis] = 0;
+        if ( !d_data->alignCanvasToScales )
+            backboneOffset[axis] += d_data->canvasMargin[axis];
+        if ( !( options & IgnoreFrames ) )
+            backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
+    }
+
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        if ( !scaleRect[axis].isValid() )
+            continue;
+
+        const int startDist = d_data->layoutData.scale[axis].start;
+        const int endDist = d_data->layoutData.scale[axis].end;
+
+        QRectF &axisRect = scaleRect[axis];
+
+        if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
+        {
+            const QRectF &leftScaleRect = scaleRect[QwtPlot::yLeft];
+            const int leftOffset =
+                backboneOffset[QwtPlot::yLeft] - startDist;
+
+            if ( leftScaleRect.isValid() )
+            {
+                const int dx = leftOffset + leftScaleRect.width();
+                if ( d_data->alignCanvasToScales && dx < 0 )
+                {
+                    /*
+                      The axis needs more space than the width
+                      of the left scale.
+                     */
+                    canvasRect.setLeft( qMax( canvasRect.left(),
+                        axisRect.left() - dx ) );
+                }
+                else
+                {
+                    const double minLeft = leftScaleRect.left();
+                    const double left = axisRect.left() + leftOffset;
+                    axisRect.setLeft( qMax( left, minLeft ) );
+                }
+            }
+            else
+            {
+                if ( d_data->alignCanvasToScales && leftOffset < 0 )
+                {
+                    canvasRect.setLeft( qMax( canvasRect.left(),
+                        axisRect.left() - leftOffset ) );
+                }
+                else
+                {
+                    if ( leftOffset > 0 )
+                        axisRect.setLeft( axisRect.left() + leftOffset );
+                }
+            }
+
+            const QRectF &rightScaleRect = scaleRect[QwtPlot::yRight];
+            const int rightOffset =
+                backboneOffset[QwtPlot::yRight] - endDist + 1;
+
+            if ( rightScaleRect.isValid() )
+            {
+                const int dx = rightOffset + rightScaleRect.width();
+                if ( d_data->alignCanvasToScales && dx < 0 )
+                {
+                    /*
+                      The axis needs more space than the width
+                      of the right scale.
+                     */
+                    canvasRect.setRight( qMin( canvasRect.right(),
+                        axisRect.right() + dx ) );
+                }   
+
+                const double maxRight = rightScaleRect.right();
+                const double right = axisRect.right() - rightOffset;
+                axisRect.setRight( qMin( right, maxRight ) );
+            }
+            else
+            {
+                if ( d_data->alignCanvasToScales && rightOffset < 0 )
+                {
+                    canvasRect.setRight( qMin( canvasRect.right(),
+                        axisRect.right() + rightOffset ) );
+                }
+                else
+                {
+                    if ( rightOffset > 0 )
+                        axisRect.setRight( axisRect.right() - rightOffset );
+                }
+            }
+        }
+        else // QwtPlot::yLeft, QwtPlot::yRight
+        {
+            const QRectF &bottomScaleRect = scaleRect[QwtPlot::xBottom];
+            const int bottomOffset =
+                backboneOffset[QwtPlot::xBottom] - endDist + 1;
+
+            if ( bottomScaleRect.isValid() )
+            {
+                const int dy = bottomOffset + bottomScaleRect.height();
+                if ( d_data->alignCanvasToScales && dy < 0 )
+                {
+                    /*
+                      The axis needs more space than the height
+                      of the bottom scale.
+                     */
+                    canvasRect.setBottom( qMin( canvasRect.bottom(),
+                        axisRect.bottom() + dy ) );
+                }
+                else
+                {
+                    const double maxBottom = bottomScaleRect.top() +
+                        d_data->layoutData.scale[QwtPlot::xBottom].tickOffset;
+                    const double bottom = axisRect.bottom() - bottomOffset;
+                    axisRect.setBottom( qMin( bottom, maxBottom ) );
+                }
+            }
+            else
+            {
+                if ( d_data->alignCanvasToScales && bottomOffset < 0 )
+                {
+                    canvasRect.setBottom( qMin( canvasRect.bottom(),
+                        axisRect.bottom() + bottomOffset ) );
+                }
+                else
+                {
+                    if ( bottomOffset > 0 )
+                        axisRect.setBottom( axisRect.bottom() - bottomOffset );
+                }
+            }
+
+            const QRectF &topScaleRect = scaleRect[QwtPlot::xTop];
+            const int topOffset = backboneOffset[QwtPlot::xTop] - startDist;
+
+            if ( topScaleRect.isValid() )
+            {
+                const int dy = topOffset + topScaleRect.height();
+                if ( d_data->alignCanvasToScales && dy < 0 )
+                {
+                    /*
+                      The axis needs more space than the height
+                      of the top scale.
+                     */
+                    canvasRect.setTop( qMax( canvasRect.top(),
+                        axisRect.top() - dy ) );
+                }
+                else
+                {
+                    const double minTop = topScaleRect.bottom() -
+                        d_data->layoutData.scale[QwtPlot::xTop].tickOffset;
+                    const double top = axisRect.top() + topOffset;
+                    axisRect.setTop( qMax( top, minTop ) );
+                }
+            }
+            else
+            {
+                if ( d_data->alignCanvasToScales && topOffset < 0 )
+                {
+                    canvasRect.setTop( qMax( canvasRect.top(),
+                        axisRect.top() - topOffset ) );
+                }
+                else
+                {
+                    if ( topOffset > 0 )
+                        axisRect.setTop( axisRect.top() + topOffset );
+                }
+            }
+        }
+    }
+
+    if ( d_data->alignCanvasToScales )
+    {
+        /*
+          The canvas has been aligned to the scale with largest
+          border distances. Now we have to realign the other scale.
+         */
+
+        int fw = 0;
+        if ( !( options & IgnoreFrames ) )
+            fw = d_data->layoutData.canvas.frameWidth;
+
+        for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+        {
+            if ( !scaleRect[axis].isValid() )
+                continue;
+
+            if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
+            {
+                scaleRect[axis].setLeft( canvasRect.left() + fw
+                    - d_data->layoutData.scale[axis].start );
+                scaleRect[axis].setRight( canvasRect.right() - fw - 1
+                    + d_data->layoutData.scale[axis].end );
+            }   
+            else
+            {
+                scaleRect[axis].setTop( canvasRect.top() + fw
+                    - d_data->layoutData.scale[axis].start );
+                scaleRect[axis].setBottom( canvasRect.bottom() - fw - 1
+                    + d_data->layoutData.scale[axis].end );
+            }
+        }
+
+        if ( scaleRect[QwtPlot::xTop].isValid() )
+            scaleRect[QwtPlot::xTop].setBottom( canvasRect.top() );
+        if ( scaleRect[QwtPlot::xBottom].isValid() )
+            scaleRect[QwtPlot::xBottom].setTop( canvasRect.bottom() );
+        if ( scaleRect[QwtPlot::yLeft].isValid() )
+            scaleRect[QwtPlot::yLeft].setRight( canvasRect.left() );
+        if ( scaleRect[QwtPlot::yRight].isValid() )
+            scaleRect[QwtPlot::yRight].setLeft( canvasRect.right() );
+    }
+}
+
+/*!
+  \brief Recalculate the geometry of all components.
+
+  \param plot Plot to be layout
+  \param plotRect Rect where to place the components
+  \param options Layout options
+
+  \sa invalidate(), titleRect(),
+      legendRect(), scaleRect(), canvasRect()
+*/
+void QwtPlotLayout::activate( const QwtPlot *plot,
+    const QRectF &plotRect, Options options )
+{
+    invalidate();
+
+    QRectF rect( plotRect );  // undistributed rest of the plot rect
+
+    // We extract all layout relevant data from the widgets,
+    // filter them through pfilter and save them to d_data->layoutData.
+
+    d_data->layoutData.init( plot, rect );
+
+    if ( !( options & IgnoreLegend )
+        && d_data->legendPos != QwtPlot::ExternalLegend
+        && plot->legend() && !plot->legend()->isEmpty() )
+    {
+        d_data->legendRect = layoutLegend( options, rect );
+
+        // subtract d_data->legendRect from rect
+
+        const QRegion region( rect.toRect() );
+        rect = region.subtract( d_data->legendRect.toRect() ).boundingRect();
+
+        switch ( d_data->legendPos )
+        {
+            case QwtPlot::LeftLegend:
+                rect.setLeft( rect.left() + d_data->spacing );
+                break;
+            case QwtPlot::RightLegend:
+                rect.setRight( rect.right() - d_data->spacing );
+                break;
+            case QwtPlot::TopLegend:
+                rect.setTop( rect.top() + d_data->spacing );
+                break;
+            case QwtPlot::BottomLegend:
+                rect.setBottom( rect.bottom() - d_data->spacing );
+                break;
+            case QwtPlot::ExternalLegend:
+                break; // suppress compiler warning
+        }
+    }
+
+    /*
+     +---+-----------+---+
+     |       Title       |
+     +---+-----------+---+
+     |   |   Axis    |   |
+     +---+-----------+---+
+     | A |           | A |
+     | x |  Canvas   | x |
+     | i |           | i |
+     | s |           | s |
+     +---+-----------+---+
+     |   |   Axis    |   |
+     +---+-----------+---+
+    */
+
+    // axes and title include text labels. The height of each
+    // label depends on its line breaks, that depend on the width
+    // for the label. A line break in a horizontal text will reduce
+    // the available width for vertical texts and vice versa.
+    // expandLineBreaks finds the height/width for title and axes
+    // including all line breaks.
+
+    int dimTitle, dimAxes[QwtPlot::axisCnt];
+    expandLineBreaks( options, rect, dimTitle, dimAxes );
+
+    if ( dimTitle > 0 )
+    {
+        d_data->titleRect = QRect( rect.x(), rect.y(),
+            rect.width(), dimTitle );
+
+        if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
+            d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
+        {
+            // if only one of the y axes is missing we align
+            // the title centered to the canvas
+
+            d_data->titleRect.setX( rect.x() + dimAxes[QwtPlot::yLeft] );
+            d_data->titleRect.setWidth( rect.width()
+                - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight] );
+        }
+
+        // subtract title
+        rect.setTop( rect.top() + dimTitle + d_data->spacing );
+    }
+
+    d_data->canvasRect.setRect(
+        rect.x() + dimAxes[QwtPlot::yLeft],
+        rect.y() + dimAxes[QwtPlot::xTop],
+        rect.width() - dimAxes[QwtPlot::yRight] - dimAxes[QwtPlot::yLeft],
+        rect.height() - dimAxes[QwtPlot::xBottom] - dimAxes[QwtPlot::xTop] );
+
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        // set the rects for the axes
+
+        if ( dimAxes[axis] )
+        {
+            int dim = dimAxes[axis];
+            QRectF &scaleRect = d_data->scaleRect[axis];
+
+            scaleRect = d_data->canvasRect;
+            switch ( axis )
+            {
+                case QwtPlot::yLeft:
+                    scaleRect.setX( d_data->canvasRect.left() - dim );
+                    scaleRect.setWidth( dim );
+                    break;
+                case QwtPlot::yRight:
+                    scaleRect.setX( d_data->canvasRect.right() );
+                    scaleRect.setWidth( dim );
+                    break;
+                case QwtPlot::xBottom:
+                    scaleRect.setY( d_data->canvasRect.bottom() );
+                    scaleRect.setHeight( dim );
+                    break;
+                case QwtPlot::xTop:
+                    scaleRect.setY( d_data->canvasRect.top() - dim );
+                    scaleRect.setHeight( dim );
+                    break;
+            }
+            scaleRect = scaleRect.normalized();
+        }
+    }
+
+    // +---+-----------+---+
+    // |  <-   Axis   ->   |
+    // +-^-+-----------+-^-+
+    // | | |           | | |
+    // |   |           |   |
+    // | A |           | A |
+    // | x |  Canvas   | x |
+    // | i |           | i |
+    // | s |           | s |
+    // |   |           |   |
+    // | | |           | | |
+    // +-V-+-----------+-V-+
+    // |   <-  Axis   ->   |
+    // +---+-----------+---+
+
+    // The ticks of the axes - not the labels above - should
+    // be aligned to the canvas. So we try to use the empty
+    // corners to extend the axes, so that the label texts
+    // left/right of the min/max ticks are moved into them.
+
+    alignScales( options, d_data->canvasRect, d_data->scaleRect );
+
+    if ( !d_data->legendRect.isEmpty() )
+    {
+        // We prefer to align the legend to the canvas - not to
+        // the complete plot - if possible.
+
+        d_data->legendRect = alignLegend( d_data->canvasRect, d_data->legendRect );
+    }
+}
Index: trunk/BNC/qwt/qwt_plot_layout.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_layout.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_layout.h	(revision 4271)
@@ -0,0 +1,105 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_LAYOUT_H
+#define QWT_PLOT_LAYOUT_H
+
+#include "qwt_global.h"
+#include "qwt_plot.h"
+
+/*!
+  \brief Layout engine for QwtPlot.
+
+  It is used by the QwtPlot widget to organize its internal widgets
+  or by QwtPlot::print() to render its content to a QPaintDevice like
+  a QPrinter, QPixmap/QImage or QSvgRenderer.
+*/
+
+class QWT_EXPORT QwtPlotLayout
+{
+public:
+    /*!
+      Options to configure the plot layout engine
+      \sa activate(), QwtPlotRenderer
+     */
+    enum Option
+    {
+        //! Unused
+        AlignScales = 0x01,
+
+        /*!
+          Ignore the dimension of the scrollbars. There are no
+          scrollbars, when the plot is not rendered to widgets.
+         */
+        IgnoreScrollbars = 0x02,
+
+        //! Ignore all frames. 
+        IgnoreFrames = 0x04,
+
+        //! Ignore the legend.
+        IgnoreLegend = 0x08
+    };
+
+    //! Layout options
+    typedef QFlags<Option> Options;
+
+    explicit QwtPlotLayout();
+    virtual ~QwtPlotLayout();
+
+    void setCanvasMargin( int margin, int axis = -1 );
+    int canvasMargin( int axis ) const;
+
+    void setAlignCanvasToScales( bool );
+    bool alignCanvasToScales() const;
+
+    void setSpacing( int );
+    int spacing() const;
+
+    void setLegendPosition( QwtPlot::LegendPosition pos, double ratio );
+    void setLegendPosition( QwtPlot::LegendPosition pos );
+    QwtPlot::LegendPosition legendPosition() const;
+
+    void setLegendRatio( double ratio );
+    double legendRatio() const;
+
+    virtual QSize minimumSizeHint( const QwtPlot * ) const;
+
+    virtual void activate( const QwtPlot *,
+        const QRectF &rect, Options options = 0x00 );
+
+    virtual void invalidate();
+
+    const QRectF &titleRect() const;
+    const QRectF &legendRect() const;
+    const QRectF &scaleRect( int axis ) const;
+    const QRectF &canvasRect() const;
+
+    class LayoutData;
+
+protected:
+
+    QRectF layoutLegend( Options options, const QRectF & ) const;
+    QRectF alignLegend( const QRectF &canvasRect,
+        const QRectF &legendRect ) const;
+
+    void expandLineBreaks( int options, const QRectF &rect,
+        int &dimTitle, int dimAxes[QwtPlot::axisCnt] ) const;
+
+    void alignScales( int options, QRectF &canvasRect,
+        QRectF scaleRect[QwtPlot::axisCnt] ) const;
+
+private:
+    class PrivateData;
+
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotLayout::Options )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_magnifier.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_magnifier.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_magnifier.cpp	(revision 4271)
@@ -0,0 +1,143 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot.h"
+#include "qwt_plot_canvas.h"
+#include "qwt_scale_div.h"
+#include "qwt_plot_magnifier.h"
+#include <qevent.h>
+
+class QwtPlotMagnifier::PrivateData
+{
+public:
+    PrivateData()
+    {
+        for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+            isAxisEnabled[axis] = true;
+    }
+
+    bool isAxisEnabled[QwtPlot::axisCnt];
+};
+
+/*!
+   Constructor
+   \param canvas Plot canvas to be magnified
+*/
+QwtPlotMagnifier::QwtPlotMagnifier( QwtPlotCanvas *canvas ):
+    QwtMagnifier( canvas )
+{
+    d_data = new PrivateData();
+}
+
+//! Destructor
+QwtPlotMagnifier::~QwtPlotMagnifier()
+{
+    delete d_data;
+}
+
+/*!
+   \brief En/Disable an axis
+
+   Only Axes that are enabled will be zoomed.
+   All other axes will remain unchanged.
+
+   \param axis Axis, see QwtPlot::Axis
+   \param on On/Off
+
+   \sa isAxisEnabled()
+*/
+void QwtPlotMagnifier::setAxisEnabled( int axis, bool on )
+{
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        d_data->isAxisEnabled[axis] = on;
+}
+
+/*!
+   Test if an axis is enabled
+
+   \param axis Axis, see QwtPlot::Axis
+   \return True, if the axis is enabled
+
+   \sa setAxisEnabled()
+*/
+bool QwtPlotMagnifier::isAxisEnabled( int axis ) const
+{
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        return d_data->isAxisEnabled[axis];
+
+    return true;
+}
+
+//! Return observed plot canvas
+QwtPlotCanvas *QwtPlotMagnifier::canvas()
+{
+    return qobject_cast<QwtPlotCanvas *>( parent() );
+}
+
+//! Return Observed plot canvas
+const QwtPlotCanvas *QwtPlotMagnifier::canvas() const
+{
+    return qobject_cast<const QwtPlotCanvas *>( parent() );
+}
+
+//! Return plot widget, containing the observed plot canvas
+QwtPlot *QwtPlotMagnifier::plot()
+{
+    QwtPlotCanvas *w = canvas();
+    if ( w )
+        return w->plot();
+
+    return NULL;
+}
+
+//! Return plot widget, containing the observed plot canvas
+const QwtPlot *QwtPlotMagnifier::plot() const
+{
+    const QwtPlotCanvas *w = canvas();
+    if ( w )
+        return w->plot();
+
+    return NULL;
+}
+
+/*!
+   Zoom in/out the axes scales
+   \param factor A value < 1.0 zooms in, a value > 1.0 zooms out.
+*/
+void QwtPlotMagnifier::rescale( double factor )
+{
+    factor = qAbs( factor );
+    if ( factor == 1.0 || factor == 0.0 )
+        return;
+
+    bool doReplot = false;
+    QwtPlot* plt = plot();
+
+    const bool autoReplot = plt->autoReplot();
+    plt->setAutoReplot( false );
+
+    for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
+    {
+        const QwtScaleDiv *scaleDiv = plt->axisScaleDiv( axisId );
+        if ( isAxisEnabled( axisId ) && scaleDiv->isValid() )
+        {
+            const double center =
+                scaleDiv->lowerBound() + scaleDiv->range() / 2;
+            const double width_2 = scaleDiv->range() / 2 * factor;
+
+            plt->setAxisScale( axisId, center - width_2, center + width_2 );
+            doReplot = true;
+        }
+    }
+
+    plt->setAutoReplot( autoReplot );
+
+    if ( doReplot )
+        plt->replot();
+}
Index: trunk/BNC/qwt/qwt_plot_magnifier.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_magnifier.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_magnifier.h	(revision 4271)
@@ -0,0 +1,55 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_MAGNIFIER_H
+#define QWT_PLOT_MAGNIFIER_H 1
+
+#include "qwt_global.h"
+#include "qwt_magnifier.h"
+
+class QwtPlotCanvas;
+class QwtPlot;
+
+/*!
+  \brief QwtPlotMagnifier provides zooming, by magnifying in steps.
+
+  Using QwtPlotMagnifier a plot can be zoomed in/out in steps using
+  keys, the mouse wheel or moving a mouse button in vertical direction.
+
+  Together with QwtPlotZoomer and QwtPlotPanner it is possible to implement
+  individual and powerful navigation of the plot canvas.
+
+  \sa QwtPlotZoomer, QwtPlotPanner, QwtPlot
+*/
+class QWT_EXPORT QwtPlotMagnifier: public QwtMagnifier
+{
+    Q_OBJECT
+
+public:
+    explicit QwtPlotMagnifier( QwtPlotCanvas * );
+    virtual ~QwtPlotMagnifier();
+
+    void setAxisEnabled( int axis, bool on );
+    bool isAxisEnabled( int axis ) const;
+
+    QwtPlotCanvas *canvas();
+    const QwtPlotCanvas *canvas() const;
+
+    QwtPlot *plot();
+    const QwtPlot *plot() const;
+
+protected:
+    virtual void rescale( double factor );
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_marker.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_marker.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_marker.cpp	(revision 4271)
@@ -0,0 +1,602 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_marker.h"
+#include "qwt_painter.h"
+#include "qwt_scale_map.h"
+#include "qwt_symbol.h"
+#include "qwt_text.h"
+#include "qwt_math.h"
+#include "qwt_legend.h"
+#include "qwt_legend_item.h"
+#include <qpainter.h>
+
+class QwtPlotMarker::PrivateData
+{
+public:
+    PrivateData():
+        labelAlignment( Qt::AlignCenter ),
+        labelOrientation( Qt::Horizontal ),
+        spacing( 2 ),
+        symbol( NULL ),
+        style( QwtPlotMarker::NoLine ),
+        xValue( 0.0 ),
+        yValue( 0.0 )
+    {
+    }
+
+    ~PrivateData()
+    {
+        delete symbol;
+    }
+
+    QwtText label;
+    Qt::Alignment labelAlignment;
+    Qt::Orientation labelOrientation;
+    int spacing;
+
+    QPen pen;
+    const QwtSymbol *symbol;
+    LineStyle style;
+
+    double xValue;
+    double yValue;
+};
+
+//! Sets alignment to Qt::AlignCenter, and style to QwtPlotMarker::NoLine
+QwtPlotMarker::QwtPlotMarker():
+    QwtPlotItem( QwtText( "Marker" ) )
+{
+    d_data = new PrivateData;
+    setZ( 30.0 );
+}
+
+//! Destructor
+QwtPlotMarker::~QwtPlotMarker()
+{
+    delete d_data;
+}
+
+//! \return QwtPlotItem::Rtti_PlotMarker
+int QwtPlotMarker::rtti() const
+{
+    return QwtPlotItem::Rtti_PlotMarker;
+}
+
+//! Return Value
+QPointF QwtPlotMarker::value() const
+{
+    return QPointF( d_data->xValue, d_data->yValue );
+}
+
+//! Return x Value
+double QwtPlotMarker::xValue() const
+{
+    return d_data->xValue;
+}
+
+//! Return y Value
+double QwtPlotMarker::yValue() const
+{
+    return d_data->yValue;
+}
+
+//! Set Value
+void QwtPlotMarker::setValue( const QPointF& pos )
+{
+    setValue( pos.x(), pos.y() );
+}
+
+//! Set Value
+void QwtPlotMarker::setValue( double x, double y )
+{
+    if ( x != d_data->xValue || y != d_data->yValue )
+    {
+        d_data->xValue = x;
+        d_data->yValue = y;
+        itemChanged();
+    }
+}
+
+//! Set X Value
+void QwtPlotMarker::setXValue( double x )
+{
+    setValue( x, d_data->yValue );
+}
+
+//! Set Y Value
+void QwtPlotMarker::setYValue( double y )
+{
+    setValue( d_data->xValue, y );
+}
+
+/*!
+  Draw the marker
+
+  \param painter Painter
+  \param xMap x Scale Map
+  \param yMap y Scale Map
+  \param canvasRect Contents rect of the canvas in painter coordinates
+*/
+void QwtPlotMarker::draw( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect ) const
+{
+    const QPointF pos( xMap.transform( d_data->xValue ), 
+        yMap.transform( d_data->yValue ) );
+
+    // draw lines
+
+    drawLines( painter, canvasRect, pos );
+
+    // draw symbol
+    if ( d_data->symbol &&
+        ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
+    {
+        d_data->symbol->drawSymbol( painter, pos );
+    }
+
+    drawLabel( painter, canvasRect, pos );
+}
+
+/*!
+  Draw the lines marker
+
+  \param painter Painter
+  \param canvasRect Contents rect of the canvas in painter coordinates
+  \param pos Position of the marker, translated into widget coordinates
+
+  \sa drawLabel(), QwtSymbol::drawSymbol()
+*/
+void QwtPlotMarker::drawLines( QPainter *painter,
+    const QRectF &canvasRect, const QPointF &pos ) const
+{
+    if ( d_data->style == NoLine )
+        return;
+
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    painter->setPen( d_data->pen );
+    if ( d_data->style == QwtPlotMarker::HLine ||
+        d_data->style == QwtPlotMarker::Cross )
+    {
+        double y = pos.y();
+        if ( doAlign )
+            y = qRound( y );
+
+        QwtPainter::drawLine( painter, canvasRect.left(),
+            y, canvasRect.right() - 1.0, y );
+    }
+    if ( d_data->style == QwtPlotMarker::VLine ||
+        d_data->style == QwtPlotMarker::Cross )
+    {
+        double x = pos.x();
+        if ( doAlign )
+            x = qRound( x );
+
+        QwtPainter::drawLine( painter, x,
+            canvasRect.top(), x, canvasRect.bottom() - 1.0 );
+    }
+}
+
+/*!
+  Align and draw the text label of the marker
+
+  \param painter Painter
+  \param canvasRect Contents rect of the canvas in painter coordinates
+  \param pos Position of the marker, translated into widget coordinates
+
+  \sa drawLabel(), QwtSymbol::drawSymbol()
+*/
+void QwtPlotMarker::drawLabel( QPainter *painter,
+    const QRectF &canvasRect, const QPointF &pos ) const
+{
+    if ( d_data->label.isEmpty() )
+        return;
+
+    Qt::Alignment align = d_data->labelAlignment;
+    QPointF alignPos = pos;
+
+    QSizeF symbolOff( 0, 0 );
+
+    switch ( d_data->style )
+    {
+        case QwtPlotMarker::VLine:
+        {
+            // In VLine-style the y-position is pointless and
+            // the alignment flags are relative to the canvas
+
+            if ( d_data->labelAlignment & Qt::AlignTop )
+            {
+                alignPos.setY( canvasRect.top() );
+                align &= ~Qt::AlignTop;
+                align |= Qt::AlignBottom;
+            }
+            else if ( d_data->labelAlignment & Qt::AlignBottom )
+            {
+                // In HLine-style the x-position is pointless and
+                // the alignment flags are relative to the canvas
+
+                alignPos.setY( canvasRect.bottom() - 1 );
+                align &= ~Qt::AlignBottom;
+                align |= Qt::AlignTop;
+            }
+            else
+            {
+                alignPos.setY( canvasRect.center().y() );
+            }
+            break;
+        }
+        case QwtPlotMarker::HLine:
+        {
+            if ( d_data->labelAlignment & Qt::AlignLeft )
+            {
+                alignPos.setX( canvasRect.left() );
+                align &= ~Qt::AlignLeft;
+                align |= Qt::AlignRight;
+            }
+            else if ( d_data->labelAlignment & Qt::AlignRight )
+            {
+                alignPos.setX( canvasRect.right() - 1 );
+                align &= ~Qt::AlignRight;
+                align |= Qt::AlignLeft;
+            }
+            else
+            {
+                alignPos.setX( canvasRect.center().x() );
+            }
+            break;
+        }
+        default:
+        {
+            if ( d_data->symbol &&
+                ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
+            {
+                symbolOff = d_data->symbol->size() + QSizeF( 1, 1 );
+                symbolOff /= 2;
+            }
+        }
+    }
+
+    qreal pw2 = d_data->pen.widthF() / 2.0;
+    if ( pw2 == 0.0 )
+        pw2 = 0.5;
+
+    const int spacing = d_data->spacing;
+
+    const qreal xOff = qMax( pw2, symbolOff.width() );
+    const qreal yOff = qMax( pw2, symbolOff.height() );
+
+    const QSizeF textSize = d_data->label.textSize( painter->font() );
+
+    if ( align & Qt::AlignLeft )
+    {
+        alignPos.rx() -= xOff + spacing;
+        if ( d_data->labelOrientation == Qt::Vertical )
+            alignPos.rx() -= textSize.height();
+        else
+            alignPos.rx() -= textSize.width();
+    }
+    else if ( align & Qt::AlignRight )
+    {
+        alignPos.rx() += xOff + spacing;
+    }
+    else
+    {
+        if ( d_data->labelOrientation == Qt::Vertical )
+            alignPos.rx() -= textSize.height() / 2;
+        else
+            alignPos.rx() -= textSize.width() / 2;
+    }
+
+    if ( align & Qt::AlignTop )
+    {
+        alignPos.ry() -= yOff + spacing;
+        if ( d_data->labelOrientation != Qt::Vertical )
+            alignPos.ry() -= textSize.height();
+    }
+    else if ( align & Qt::AlignBottom )
+    {
+        alignPos.ry() += yOff + spacing;
+        if ( d_data->labelOrientation == Qt::Vertical )
+            alignPos.ry() += textSize.width();
+    }
+    else
+    {
+        if ( d_data->labelOrientation == Qt::Vertical )
+            alignPos.ry() += textSize.width() / 2;
+        else
+            alignPos.ry() -= textSize.height() / 2;
+    }
+
+    painter->translate( alignPos.x(), alignPos.y() );
+    if ( d_data->labelOrientation == Qt::Vertical )
+        painter->rotate( -90.0 );
+
+    const QRectF textRect( 0, 0, textSize.width(), textSize.height() );
+    d_data->label.draw( painter, textRect );
+}
+
+/*!
+  \brief Set the line style
+  \param style Line style. 
+  \sa lineStyle()
+*/
+void QwtPlotMarker::setLineStyle( LineStyle style )
+{
+    if ( style != d_data->style )
+    {
+        d_data->style = style;
+        itemChanged();
+    }
+}
+
+/*!
+  \return the line style
+  \sa setLineStyle()
+*/
+QwtPlotMarker::LineStyle QwtPlotMarker::lineStyle() const
+{
+    return d_data->style;
+}
+
+/*!
+  \brief Assign a symbol
+  \param symbol New symbol
+  \sa symbol()
+*/
+void QwtPlotMarker::setSymbol( const QwtSymbol *symbol )
+{
+    if ( symbol != d_data->symbol )
+    {
+        delete d_data->symbol;
+        d_data->symbol = symbol;
+        itemChanged();
+    }
+}
+
+/*!
+  \return the symbol
+  \sa setSymbol(), QwtSymbol
+*/
+const QwtSymbol *QwtPlotMarker::symbol() const
+{
+    return d_data->symbol;
+}
+
+/*!
+  \brief Set the label
+  \param label label text
+  \sa label()
+*/
+void QwtPlotMarker::setLabel( const QwtText& label )
+{
+    if ( label != d_data->label )
+    {
+        d_data->label = label;
+        itemChanged();
+    }
+}
+
+/*!
+  \return the label
+  \sa setLabel()
+*/
+QwtText QwtPlotMarker::label() const
+{
+    return d_data->label;
+}
+
+/*!
+  \brief Set the alignment of the label
+
+  In case of QwtPlotMarker::HLine the alignment is relative to the
+  y position of the marker, but the horizontal flags correspond to the
+  canvas rectangle. In case of QwtPlotMarker::VLine the alignment is
+  relative to the x position of the marker, but the vertical flags
+  correspond to the canvas rectangle.
+
+  In all other styles the alignment is relative to the marker's position.
+
+  \param align Alignment. 
+  \sa labelAlignment(), labelOrientation()
+*/
+void QwtPlotMarker::setLabelAlignment( Qt::Alignment align )
+{
+    if ( align != d_data->labelAlignment )
+    {
+        d_data->labelAlignment = align;
+        itemChanged();
+    }
+}
+
+/*!
+  \return the label alignment
+  \sa setLabelAlignment(), setLabelOrientation()
+*/
+Qt::Alignment QwtPlotMarker::labelAlignment() const
+{
+    return d_data->labelAlignment;
+}
+
+/*!
+  \brief Set the orientation of the label
+
+  When orientation is Qt::Vertical the label is rotated by 90.0 degrees
+  ( from bottom to top ).
+
+  \param orientation Orientation of the label
+
+  \sa labelOrientation(), setLabelAlignment()
+*/
+void QwtPlotMarker::setLabelOrientation( Qt::Orientation orientation )
+{
+    if ( orientation != d_data->labelOrientation )
+    {
+        d_data->labelOrientation = orientation;
+        itemChanged();
+    }
+}
+
+/*!
+  \return the label orientation
+  \sa setLabelOrientation(), labelAlignment()
+*/
+Qt::Orientation QwtPlotMarker::labelOrientation() const
+{
+    return d_data->labelOrientation;
+}
+
+/*!
+  \brief Set the spacing
+
+  When the label is not centered on the marker position, the spacing
+  is the distance between the position and the label.
+
+  \param spacing Spacing
+  \sa spacing(), setLabelAlignment()
+*/
+void QwtPlotMarker::setSpacing( int spacing )
+{
+    if ( spacing < 0 )
+        spacing = 0;
+
+    if ( spacing == d_data->spacing )
+        return;
+
+    d_data->spacing = spacing;
+    itemChanged();
+}
+
+/*!
+  \return the spacing
+  \sa setSpacing()
+*/
+int QwtPlotMarker::spacing() const
+{
+    return d_data->spacing;
+}
+
+/*!
+  Specify a pen for the line.
+
+  \param pen New pen
+  \sa linePen()
+*/
+void QwtPlotMarker::setLinePen( const QPen &pen )
+{
+    if ( pen != d_data->pen )
+    {
+        d_data->pen = pen;
+        itemChanged();
+    }
+}
+
+/*!
+  \return the line pen
+  \sa setLinePen()
+*/
+const QPen &QwtPlotMarker::linePen() const
+{
+    return d_data->pen;
+}
+
+QRectF QwtPlotMarker::boundingRect() const
+{
+    return QRectF( d_data->xValue, d_data->yValue, 0.0, 0.0 );
+}
+
+/*!
+   \brief Update the widget that represents the item on the legend
+
+   \param legend Legend
+   \sa drawLegendIdentifier(), legendItem(), itemChanged(), QwtLegend()
+
+   \note In the default setting QwtPlotItem::Legend is disabled 
+*/
+void QwtPlotMarker::updateLegend( QwtLegend *legend ) const
+{
+    if ( legend && testItemAttribute( QwtPlotItem::Legend )
+        && d_data->symbol && d_data->symbol->style() != QwtSymbol::NoSymbol )
+    {
+        QWidget *lgdItem = legend->find( this );
+        if ( lgdItem == NULL )
+        {
+            lgdItem = legendItem();
+            if ( lgdItem )
+                legend->insert( this, lgdItem );
+        }
+
+        QwtLegendItem *l = qobject_cast<QwtLegendItem *>( lgdItem );
+        if ( l )
+            l->setIdentifierSize( d_data->symbol->boundingSize() );
+    }
+
+    QwtPlotItem::updateLegend( legend );
+}
+
+/*!
+  \brief Draw the identifier representing the marker on the legend
+
+  \param painter Painter
+  \param rect Bounding rectangle for the identifier
+
+  \sa updateLegend(), QwtPlotItem::Legend
+*/
+void QwtPlotMarker::drawLegendIdentifier(
+    QPainter *painter, const QRectF &rect ) const
+{
+    if ( rect.isEmpty() )
+        return;
+
+    painter->save();
+    painter->setClipRect( rect, Qt::IntersectClip );
+
+    if ( d_data->style != QwtPlotMarker::NoLine )
+    {
+        painter->setPen( d_data->pen );
+
+        if ( d_data->style == QwtPlotMarker::HLine ||
+            d_data->style == QwtPlotMarker::Cross )
+        {
+            QwtPainter::drawLine( painter, rect.left(), rect.center().y(),
+                rect.right(), rect.center().y() );
+        }
+
+        if ( d_data->style == QwtPlotMarker::VLine ||
+            d_data->style == QwtPlotMarker::Cross )
+        {
+            QwtPainter::drawLine( painter, rect.center().x(), rect.top(),
+                rect.center().x(), rect.bottom() );
+        }
+    }
+
+    if ( d_data->symbol && d_data->symbol->style() != QwtSymbol::NoSymbol )
+    {
+        QSize symbolSize = d_data->symbol->boundingSize();
+        symbolSize -= QSize( 2, 2 );
+
+        // scale the symbol size down if it doesn't fit into rect.
+
+        double xRatio = 1.0;
+        if ( rect.width() < symbolSize.width() )
+            xRatio = rect.width() / symbolSize.width();
+        double yRatio = 1.0;
+        if ( rect.height() < symbolSize.height() )
+            yRatio = rect.height() / symbolSize.height();
+
+        const double ratio = qMin( xRatio, yRatio );
+
+        painter->scale( ratio, ratio );
+        d_data->symbol->drawSymbol( painter, rect.center() / ratio );
+    }
+
+    painter->restore();
+}
+
Index: trunk/BNC/qwt/qwt_plot_marker.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_marker.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_marker.h	(revision 4271)
@@ -0,0 +1,124 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_MARKER_H
+#define QWT_PLOT_MARKER_H
+
+#include <qpen.h>
+#include <qfont.h>
+#include <qstring.h>
+#include <qbrush.h>
+#include "qwt_global.h"
+#include "qwt_plot_item.h"
+
+class QRectF;
+class QwtText;
+class QwtSymbol;
+
+/*!
+  \brief A class for drawing markers
+
+  A marker can be a horizontal line, a vertical line,
+  a symbol, a label or any combination of them, which can
+  be drawn around a center point inside a bounding rectangle.
+
+  The QwtPlotMarker::setSymbol() member assigns a symbol to the marker.
+  The symbol is drawn at the specified point.
+
+  With setLabel(), a label can be assigned to the marker.
+  The setLabelAlignment() member specifies where the label is
+  drawn. All the Align*-constants in Qt::AlignmentFlags (see Qt documentation)
+  are valid. The interpretation of the alignment depends on the marker's
+  line style. The alignment refers to the center point of
+  the marker, which means, for example, that the label would be printed
+  left above the center point if the alignment was set to 
+  Qt::AlignLeft | Qt::AlignTop.
+*/
+
+class QWT_EXPORT QwtPlotMarker: public QwtPlotItem
+{
+public:
+
+    /*!
+        Line styles.
+        \sa setLineStyle(), lineStyle()
+    */
+    enum LineStyle
+    {
+        //! No line
+        NoLine,
+
+        //! A horizontal line
+        HLine,
+
+        //! A vertical line
+        VLine,
+
+        //! A crosshair
+        Cross
+    };
+
+    explicit QwtPlotMarker();
+    virtual ~QwtPlotMarker();
+
+    virtual int rtti() const;
+
+    double xValue() const;
+    double yValue() const;
+    QPointF value() const;
+
+    void setXValue( double );
+    void setYValue( double );
+    void setValue( double, double );
+    void setValue( const QPointF & );
+
+    void setLineStyle( LineStyle st );
+    LineStyle lineStyle() const;
+
+    void setLinePen( const QPen &p );
+    const QPen &linePen() const;
+
+    void setSymbol( const QwtSymbol * );
+    const QwtSymbol *symbol() const;
+
+    void setLabel( const QwtText& );
+    QwtText label() const;
+
+    void setLabelAlignment( Qt::Alignment );
+    Qt::Alignment labelAlignment() const;
+
+    void setLabelOrientation( Qt::Orientation );
+    Qt::Orientation labelOrientation() const;
+
+    void setSpacing( int );
+    int spacing() const;
+
+    virtual void draw( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF & ) const;
+
+    virtual QRectF boundingRect() const;
+
+    virtual void updateLegend( QwtLegend * ) const;
+    virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const;
+
+protected:
+    virtual void drawLines( QPainter *, 
+        const QRectF &, const QPointF & ) const;
+
+    virtual void drawLabel( QPainter *, 
+        const QRectF &, const QPointF & ) const;
+
+private:
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_panner.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_panner.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_panner.cpp	(revision 4271)
@@ -0,0 +1,175 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_panner.h"
+#include "qwt_scale_div.h"
+#include "qwt_plot.h"
+#include "qwt_plot_canvas.h"
+
+class QwtPlotPanner::PrivateData
+{
+public:
+    PrivateData()
+    {
+        for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+            isAxisEnabled[axis] = true;
+    }
+
+    bool isAxisEnabled[QwtPlot::axisCnt];
+};
+
+/*!
+  \brief Create a plot panner
+
+  The panner is enabled for all axes
+
+  \param canvas Plot canvas to pan, also the parent object
+
+  \sa setAxisEnabled()
+*/
+QwtPlotPanner::QwtPlotPanner( QwtPlotCanvas *canvas ):
+    QwtPanner( canvas )
+{
+    d_data = new PrivateData();
+
+    connect( this, SIGNAL( panned( int, int ) ),
+        SLOT( moveCanvas( int, int ) ) );
+}
+
+//! Destructor
+QwtPlotPanner::~QwtPlotPanner()
+{
+    delete d_data;
+}
+
+/*!
+   \brief En/Disable an axis
+
+   Axes that are enabled will be synchronized to the
+   result of panning. All other axes will remain unchanged.
+
+   \param axis Axis, see QwtPlot::Axis
+   \param on On/Off
+
+   \sa isAxisEnabled(), moveCanvas()
+*/
+void QwtPlotPanner::setAxisEnabled( int axis, bool on )
+{
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        d_data->isAxisEnabled[axis] = on;
+}
+
+/*!
+   Test if an axis is enabled
+
+   \param axis Axis, see QwtPlot::Axis
+   \return True, if the axis is enabled
+
+   \sa setAxisEnabled(), moveCanvas()
+*/
+bool QwtPlotPanner::isAxisEnabled( int axis ) const
+{
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        return d_data->isAxisEnabled[axis];
+
+    return true;
+}
+
+//! Return observed plot canvas
+QwtPlotCanvas *QwtPlotPanner::canvas()
+{
+    return qobject_cast<QwtPlotCanvas *>( parentWidget() );
+}
+
+//! Return Observed plot canvas
+const QwtPlotCanvas *QwtPlotPanner::canvas() const
+{
+    return qobject_cast<const QwtPlotCanvas *>( parentWidget() );
+}
+
+//! Return plot widget, containing the observed plot canvas
+QwtPlot *QwtPlotPanner::plot()
+{
+    QwtPlotCanvas *w = canvas();
+    if ( w )
+        return w->plot();
+
+    return NULL;
+}
+
+//! Return plot widget, containing the observed plot canvas
+const QwtPlot *QwtPlotPanner::plot() const
+{
+    const QwtPlotCanvas *w = canvas();
+    if ( w )
+        return w->plot();
+
+    return NULL;
+}
+
+/*!
+   Adjust the enabled axes according to dx/dy
+
+   \param dx Pixel offset in x direction
+   \param dy Pixel offset in y direction
+
+   \sa QwtPanner::panned()
+*/
+void QwtPlotPanner::moveCanvas( int dx, int dy )
+{
+    if ( dx == 0 && dy == 0 )
+        return;
+
+    QwtPlot *plot = this->plot();
+    if ( plot == NULL )
+        return;
+
+    const bool doAutoReplot = plot->autoReplot();
+    plot->setAutoReplot( false );
+
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        if ( !d_data->isAxisEnabled[axis] )
+            continue;
+
+        const QwtScaleMap map = plot->canvasMap( axis );
+
+        const double p1 = map.transform( plot->axisScaleDiv( axis )->lowerBound() );
+        const double p2 = map.transform( plot->axisScaleDiv( axis )->upperBound() );
+
+        double d1, d2;
+        if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
+        {
+            d1 = map.invTransform( p1 - dx );
+            d2 = map.invTransform( p2 - dx );
+        }
+        else
+        {
+            d1 = map.invTransform( p1 - dy );
+            d2 = map.invTransform( p2 - dy );
+        }
+
+        plot->setAxisScale( axis, d1, d2 );
+    }
+
+    plot->setAutoReplot( doAutoReplot );
+    plot->replot();
+}
+
+/*!
+    Calculate a mask from the border mask of the canvas
+    \sa QwtPlotCanvas::borderMask()
+*/
+QBitmap QwtPlotPanner::contentsMask() const
+{
+    if ( canvas() )
+        return canvas()->borderMask( size() );
+
+    return QwtPanner::contentsMask();
+}
Index: trunk/BNC/qwt/qwt_plot_panner.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_panner.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_panner.h	(revision 4271)
@@ -0,0 +1,60 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_PANNER_H
+#define QWT_PLOT_PANNER_H 1
+
+#include "qwt_global.h"
+#include "qwt_panner.h"
+
+class QwtPlotCanvas;
+class QwtPlot;
+
+/*!
+  \brief QwtPlotPanner provides panning of a plot canvas
+
+  QwtPlotPanner is a panner for a QwtPlotCanvas, that
+  adjusts the scales of the axes after dropping
+  the canvas on its new position.
+
+  Together with QwtPlotZoomer and QwtPlotMagnifier powerful ways
+  of navigating on a QwtPlot widget can be implemented easily.
+
+  \note The axes are not updated, while dragging the canvas
+  \sa QwtPlotZoomer, QwtPlotMagnifier
+*/
+class QWT_EXPORT QwtPlotPanner: public QwtPanner
+{
+    Q_OBJECT
+
+public:
+    explicit QwtPlotPanner( QwtPlotCanvas * );
+    virtual ~QwtPlotPanner();
+
+    QwtPlotCanvas *canvas();
+    const QwtPlotCanvas *canvas() const;
+
+    QwtPlot *plot();
+    const QwtPlot *plot() const;
+
+    void setAxisEnabled( int axis, bool on );
+    bool isAxisEnabled( int axis ) const;
+
+protected Q_SLOTS:
+    virtual void moveCanvas( int dx, int dy );
+
+protected:
+    virtual QBitmap contentsMask() const;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_picker.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_picker.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_picker.cpp	(revision 4271)
@@ -0,0 +1,382 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_picker.h"
+#include "qwt_plot.h"
+#include "qwt_scale_div.h"
+#include "qwt_painter.h"
+#include "qwt_scale_map.h"
+#include "qwt_picker_machine.h"
+
+/*!
+  \brief Create a plot picker
+
+  The picker is set to those x- and y-axis of the plot
+  that are enabled. If both or no x-axis are enabled, the picker
+  is set to QwtPlot::xBottom. If both or no y-axis are
+  enabled, it is set to QwtPlot::yLeft.
+
+  \param canvas Plot canvas to observe, also the parent object
+
+  \sa QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
+*/
+
+QwtPlotPicker::QwtPlotPicker( QwtPlotCanvas *canvas ):
+    QwtPicker( canvas ),
+    d_xAxis( -1 ),
+    d_yAxis( -1 )
+{
+    if ( !canvas )
+        return;
+
+    // attach axes
+
+    int xAxis = QwtPlot::xBottom;
+
+    const QwtPlot *plot = QwtPlotPicker::plot();
+    if ( !plot->axisEnabled( QwtPlot::xBottom ) &&
+        plot->axisEnabled( QwtPlot::xTop ) )
+    {
+        xAxis = QwtPlot::xTop;
+    }
+
+    int yAxis = QwtPlot::yLeft;
+    if ( !plot->axisEnabled( QwtPlot::yLeft ) &&
+        plot->axisEnabled( QwtPlot::yRight ) )
+    {
+        yAxis = QwtPlot::yRight;
+    }
+
+    setAxis( xAxis, yAxis );
+}
+
+/*!
+  Create a plot picker
+
+  \param xAxis Set the x axis of the picker
+  \param yAxis Set the y axis of the picker
+  \param canvas Plot canvas to observe, also the parent object
+
+  \sa QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
+*/
+QwtPlotPicker::QwtPlotPicker( int xAxis, int yAxis, QwtPlotCanvas *canvas ):
+    QwtPicker( canvas ),
+    d_xAxis( xAxis ),
+    d_yAxis( yAxis )
+{
+}
+
+/*!
+  Create a plot picker
+
+  \param xAxis X axis of the picker
+  \param yAxis Y axis of the picker
+  \param rubberBand Rubberband style
+  \param trackerMode Tracker mode
+  \param canvas Plot canvas to observe, also the parent object
+
+  \sa QwtPicker, QwtPicker::setSelectionFlags(), QwtPicker::setRubberBand(),
+      QwtPicker::setTrackerMode
+
+  \sa QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
+*/
+QwtPlotPicker::QwtPlotPicker( int xAxis, int yAxis,
+        RubberBand rubberBand, DisplayMode trackerMode,
+        QwtPlotCanvas *canvas ):
+    QwtPicker( rubberBand, trackerMode, canvas ),
+    d_xAxis( xAxis ),
+    d_yAxis( yAxis )
+{
+}
+
+//! Destructor
+QwtPlotPicker::~QwtPlotPicker()
+{
+}
+
+//! Return observed plot canvas
+QwtPlotCanvas *QwtPlotPicker::canvas()
+{
+    return qobject_cast<QwtPlotCanvas *>( parentWidget() );
+}
+
+//! Return Observed plot canvas
+const QwtPlotCanvas *QwtPlotPicker::canvas() const
+{
+    return qobject_cast<const QwtPlotCanvas *>( parentWidget() );
+}
+
+//! Return plot widget, containing the observed plot canvas
+QwtPlot *QwtPlotPicker::plot()
+{
+    QwtPlotCanvas *w = canvas();
+    if ( w )
+        return w->plot();
+
+    return NULL;
+}
+
+//! Return plot widget, containing the observed plot canvas
+const QwtPlot *QwtPlotPicker::plot() const
+{
+    const QwtPlotCanvas *w = canvas();
+    if ( w )
+        return w->plot();
+
+    return NULL;
+}
+
+/*!
+  Return normalized bounding rect of the axes
+
+  \sa QwtPlot::autoReplot(), QwtPlot::replot().
+*/
+QRectF QwtPlotPicker::scaleRect() const
+{
+    QRectF rect;
+
+    if ( plot() )
+    {
+        const QwtScaleDiv *xs = plot()->axisScaleDiv( xAxis() );
+        const QwtScaleDiv *ys = plot()->axisScaleDiv( yAxis() );
+
+        if ( xs && ys )
+        {
+            rect = QRectF( xs->lowerBound(), ys->lowerBound(),
+                xs->range(), ys->range() );
+            rect = rect.normalized();
+        }
+    }
+
+    return rect;
+}
+
+/*!
+  Set the x and y axes of the picker
+
+  \param xAxis X axis
+  \param yAxis Y axis
+*/
+void QwtPlotPicker::setAxis( int xAxis, int yAxis )
+{
+    const QwtPlot *plt = plot();
+    if ( !plt )
+        return;
+
+    if ( xAxis != d_xAxis || yAxis != d_yAxis )
+    {
+        d_xAxis = xAxis;
+        d_yAxis = yAxis;
+    }
+}
+
+//! Return x axis
+int QwtPlotPicker::xAxis() const
+{
+    return d_xAxis;
+}
+
+//! Return y axis
+int QwtPlotPicker::yAxis() const
+{
+    return d_yAxis;
+}
+
+/*!
+  Translate a pixel position into a position string
+
+  \param pos Position in pixel coordinates
+  \return Position string
+*/
+QwtText QwtPlotPicker::trackerText( const QPoint &pos ) const
+{
+    return trackerTextF( invTransform( pos ) );
+}
+
+/*!
+  \brief Translate a position into a position string
+
+  In case of HLineRubberBand the label is the value of the
+  y position, in case of VLineRubberBand the value of the x position.
+  Otherwise the label contains x and y position separated by a ',' .
+
+  The format for the double to string conversion is "%.4f".
+
+  \param pos Position
+  \return Position string
+*/
+QwtText QwtPlotPicker::trackerTextF( const QPointF &pos ) const
+{
+    QString text;
+
+    switch ( rubberBand() )
+    {
+        case HLineRubberBand:
+            text.sprintf( "%.4f", pos.y() );
+            break;
+        case VLineRubberBand:
+            text.sprintf( "%.4f", pos.x() );
+            break;
+        default:
+            text.sprintf( "%.4f, %.4f", pos.x(), pos.y() );
+    }
+    return QwtText( text );
+}
+
+/*!
+  Append a point to the selection and update rubberband and tracker.
+
+  \param pos Additional point
+  \sa isActive, begin(), end(), move(), appended()
+
+  \note The appended(const QPoint &), appended(const QDoublePoint &)
+        signals are emitted.
+*/
+void QwtPlotPicker::append( const QPoint &pos )
+{
+    QwtPicker::append( pos );
+    Q_EMIT appended( invTransform( pos ) );
+}
+
+/*!
+  Move the last point of the selection
+
+  \param pos New position
+  \sa isActive, begin(), end(), append()
+
+  \note The moved(const QPoint &), moved(const QDoublePoint &)
+        signals are emitted.
+*/
+void QwtPlotPicker::move( const QPoint &pos )
+{
+    QwtPicker::move( pos );
+    Q_EMIT moved( invTransform( pos ) );
+}
+
+/*!
+  Close a selection setting the state to inactive.
+
+  \param ok If true, complete the selection and emit selected signals
+            otherwise discard the selection.
+  \return true if the selection is accepted, false otherwise
+*/
+
+bool QwtPlotPicker::end( bool ok )
+{
+    ok = QwtPicker::end( ok );
+    if ( !ok )
+        return false;
+
+    QwtPlot *plot = QwtPlotPicker::plot();
+    if ( !plot )
+        return false;
+
+    const QPolygon pa = selection();
+    if ( pa.count() == 0 )
+        return false;
+
+    QwtPickerMachine::SelectionType selectionType =
+        QwtPickerMachine::NoSelection;
+
+    if ( stateMachine() )
+        selectionType = stateMachine()->selectionType();
+
+    switch ( selectionType )
+    {
+        case QwtPickerMachine::PointSelection:
+        {
+            const QPointF pos = invTransform( pa[0] );
+            Q_EMIT selected( pos );
+            break;
+        }
+        case QwtPickerMachine::RectSelection:
+        {
+            if ( pa.count() >= 2 )
+            {
+                const QPoint p1 = pa[0];
+                const QPoint p2 = pa[int( pa.count() - 1 )];
+
+                const QRect rect = QRect( p1, p2 ).normalized();
+                Q_EMIT selected( invTransform( rect ) );
+            }
+            break;
+        }
+        case QwtPickerMachine::PolygonSelection:
+        {
+            QVector<QPointF> dpa( pa.count() );
+            for ( int i = 0; i < int( pa.count() ); i++ )
+                dpa[i] = invTransform( pa[i] );
+
+            Q_EMIT selected( dpa );
+        }
+        default:
+            break;
+    }
+
+    return true;
+}
+
+/*!
+    Translate a rectangle from pixel into plot coordinates
+
+    \return Rectangle in plot coordinates
+    \sa transform()
+*/
+QRectF QwtPlotPicker::invTransform( const QRect &rect ) const
+{
+    const QwtScaleMap xMap = plot()->canvasMap( d_xAxis );
+    const QwtScaleMap yMap = plot()->canvasMap( d_yAxis );
+
+    return QwtScaleMap::invTransform( xMap, yMap, rect );
+}
+
+/*!
+    Translate a rectangle from plot into pixel coordinates
+    \return Rectangle in pixel coordinates
+    \sa invTransform()
+*/
+QRect QwtPlotPicker::transform( const QRectF &rect ) const
+{
+    const QwtScaleMap xMap = plot()->canvasMap( d_xAxis );
+    const QwtScaleMap yMap = plot()->canvasMap( d_yAxis );
+
+    return QwtScaleMap::transform( xMap, yMap, rect ).toRect();
+}
+
+/*!
+    Translate a point from pixel into plot coordinates
+    \return Point in plot coordinates
+    \sa transform()
+*/
+QPointF QwtPlotPicker::invTransform( const QPoint &pos ) const
+{
+    QwtScaleMap xMap = plot()->canvasMap( d_xAxis );
+    QwtScaleMap yMap = plot()->canvasMap( d_yAxis );
+
+    return QPointF(
+        xMap.invTransform( pos.x() ),
+        yMap.invTransform( pos.y() )
+    );
+}
+
+/*!
+    Translate a point from plot into pixel coordinates
+    \return Point in pixel coordinates
+    \sa invTransform()
+*/
+QPoint QwtPlotPicker::transform( const QPointF &pos ) const
+{
+    QwtScaleMap xMap = plot()->canvasMap( d_xAxis );
+    QwtScaleMap yMap = plot()->canvasMap( d_yAxis );
+
+    const QPointF p( xMap.transform( pos.x() ),
+        yMap.transform( pos.y() ) );
+
+    return p.toPoint();
+}
Index: trunk/BNC/qwt/qwt_plot_picker.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_picker.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_picker.h	(revision 4271)
@@ -0,0 +1,113 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_PICKER_H
+#define QWT_PLOT_PICKER_H
+
+#include "qwt_global.h"
+#include "qwt_plot_canvas.h"
+#include "qwt_picker.h"
+#include <qvector.h>
+
+class QwtPlot;
+
+/*!
+  \brief QwtPlotPicker provides selections on a plot canvas
+
+  QwtPlotPicker is a QwtPicker tailored for selections on
+  a plot canvas. It is set to a x-Axis and y-Axis and
+  translates all pixel coordinates into this coodinate system.
+*/
+
+class QWT_EXPORT QwtPlotPicker: public QwtPicker
+{
+    Q_OBJECT
+
+public:
+    explicit QwtPlotPicker( QwtPlotCanvas * );
+    virtual ~QwtPlotPicker();
+
+    explicit QwtPlotPicker( int xAxis, int yAxis, QwtPlotCanvas * );
+
+    explicit QwtPlotPicker( int xAxis, int yAxis,
+        RubberBand rubberBand, DisplayMode trackerMode,
+        QwtPlotCanvas * );
+
+    virtual void setAxis( int xAxis, int yAxis );
+
+    int xAxis() const;
+    int yAxis() const;
+
+    QwtPlot *plot();
+    const QwtPlot *plot() const;
+
+    QwtPlotCanvas *canvas();
+    const QwtPlotCanvas *canvas() const;
+
+Q_SIGNALS:
+
+    /*!
+      A signal emitted in case of selectionFlags() & PointSelection.
+      \param pos Selected point
+    */
+    void selected( const QPointF &pos );
+
+    /*!
+      A signal emitted in case of selectionFlags() & RectSelection.
+      \param rect Selected rectangle
+    */
+    void selected( const QRectF &rect );
+
+    /*!
+      A signal emitting the selected points,
+      at the end of a selection.
+
+      \param pa Selected points
+    */
+    void selected( const QVector<QPointF> &pa );
+
+    /*!
+      A signal emitted when a point has been appended to the selection
+
+      \param pos Position of the appended point.
+      \sa append(). moved()
+    */
+    void appended( const QPointF &pos );
+
+    /*!
+      A signal emitted whenever the last appended point of the
+      selection has been moved.
+
+      \param pos Position of the moved last point of the selection.
+      \sa move(), appended()
+    */
+    void moved( const QPointF &pos );
+
+protected:
+    QRectF scaleRect() const;
+
+    QRectF invTransform( const QRect & ) const;
+    QRect transform( const QRectF & ) const;
+
+    QPointF invTransform( const QPoint & ) const;
+    QPoint transform( const QPointF & ) const;
+
+    virtual QwtText trackerText( const QPoint & ) const;
+    virtual QwtText trackerTextF( const QPointF & ) const;
+
+    virtual void move( const QPoint & );
+    virtual void append( const QPoint & );
+    virtual bool end( bool ok = true );
+
+private:
+    int d_xAxis;
+    int d_yAxis;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_rasteritem.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_rasteritem.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_rasteritem.cpp	(revision 4271)
@@ -0,0 +1,904 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_rasteritem.h"
+#include "qwt_legend.h"
+#include "qwt_legend_item.h"
+#include "qwt_scale_map.h"
+#include "qwt_painter.h"
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#include <qpainter.h>
+#include <qpaintengine.h>
+#include <float.h>
+
+class QwtPlotRasterItem::PrivateData
+{
+public:
+    PrivateData():
+        alpha( -1 ),
+        paintAttributes( QwtPlotRasterItem::PaintInDeviceResolution )
+    {
+        cache.policy = QwtPlotRasterItem::NoCache;
+    }
+
+    int alpha;
+    QwtPlotRasterItem::PaintAttributes paintAttributes;
+
+    struct ImageCache
+    {
+        QwtPlotRasterItem::CachePolicy policy;
+        QRectF area;
+        QSizeF size;
+        QImage image;
+    } cache;
+};
+
+
+static QRectF qwtAlignRect(const QRectF &rect)
+{
+    QRectF r;
+    r.setLeft( qRound( rect.left() ) );
+    r.setRight( qRound( rect.right() ) );
+    r.setTop( qRound( rect.top() ) );
+    r.setBottom( qRound( rect.bottom() ) );
+
+    return r;
+}
+
+static QRectF qwtStripRect(const QRectF &rect, const QRectF &area,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QwtInterval &xInterval, const QwtInterval &yInterval)
+{
+    QRectF r = rect;
+    if ( xInterval.borderFlags() & QwtInterval::ExcludeMinimum )
+    {
+        if ( area.left() <= xInterval.minValue() )
+        {
+            if ( xMap.isInverting() )
+                r.adjust(0, 0, -1, 0);
+            else
+                r.adjust(1, 0, 0, 0);
+        }
+    }
+
+    if ( xInterval.borderFlags() & QwtInterval::ExcludeMaximum )
+    {
+        if ( area.right() >= xInterval.maxValue() )
+        {
+            if ( xMap.isInverting() )
+                r.adjust(1, 0, 0, 0);
+            else
+                r.adjust(0, 0, -1, 0);
+        }
+    }
+
+    if ( yInterval.borderFlags() & QwtInterval::ExcludeMinimum )
+    {
+        if ( area.top() <= yInterval.minValue() )
+        {
+            if ( yMap.isInverting() )
+                r.adjust(0, 0, 0, -1);
+            else
+                r.adjust(0, 1, 0, 0);
+        }
+    }
+
+    if ( yInterval.borderFlags() & QwtInterval::ExcludeMaximum )
+    {
+        if ( area.bottom() >= yInterval.maxValue() )
+        {
+            if ( yMap.isInverting() )
+                r.adjust(0, 1, 0, 0);
+            else
+                r.adjust(0, 0, 0, -1);
+        }
+    }
+
+    return r;
+}
+
+static QImage qwtExpandImage(const QImage &image,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &area, const QRectF &area2, const QRectF &paintRect,
+    const QwtInterval &xInterval, const QwtInterval &yInterval )
+{
+    const QRectF strippedRect = qwtStripRect(paintRect, area2,
+        xMap, yMap, xInterval, yInterval);
+    const QSize sz = strippedRect.toRect().size();
+
+    const int w = image.width();
+    const int h = image.height();
+
+    const QRectF r = QwtScaleMap::transform(xMap, yMap, area).normalized();
+    const double pw = ( r.width() - 1) / w;
+    const double ph = ( r.height() - 1) / h;
+
+    double px0, py0;
+    if ( !xMap.isInverting() )
+    {
+        px0 = xMap.transform( area2.left() );
+        px0 = qRound( px0 );
+        px0 = px0 - xMap.transform( area.left() );
+    }
+    else
+    {
+        px0 = xMap.transform( area2.right() );
+        px0 = qRound( px0 );
+        px0 -= xMap.transform( area.right() );
+
+        px0 -= 1.0;
+    }
+    px0 += strippedRect.left() - paintRect.left();
+
+    if ( !yMap.isInverting() )
+    {
+        py0 = yMap.transform( area2.top() );
+        py0 = qRound( py0 );
+        py0 -= yMap.transform( area.top() );
+    }
+    else
+    {
+        py0 = yMap.transform( area2.bottom() );
+        py0 = qRound( py0 );
+        py0 -= yMap.transform( area.bottom() );
+
+        py0 -= 1.0;
+    }
+    py0 += strippedRect.top() - paintRect.top();
+
+    QImage expanded(sz, image.format());
+
+    switch( image.depth() )
+    {
+        case 32:
+        {
+            for ( int y1 = 0; y1 < h; y1++ )
+            {
+                int yy1;
+                if ( y1 == 0 )
+                {
+                    yy1 = 0;
+                }
+                else
+                {
+                    yy1 = qRound( y1 * ph - py0 );
+                    if ( yy1 < 0 )
+                        yy1 = 0;
+                }
+
+                int yy2;
+                if ( y1 == h - 1 )
+                {
+                    yy2 = sz.height();
+                }
+                else
+                {
+                    yy2 = qRound( ( y1 + 1 ) * ph - py0 );
+                    if ( yy2 > sz.height() )
+                        yy2 = sz.height();
+                }
+
+                const quint32 *line1 = (const quint32 *) image.scanLine( y1 );
+
+                for ( int x1 = 0; x1 < w; x1++ )
+                {
+                    int xx1;
+                    if ( x1 == 0 )
+                    {
+                        xx1 = 0;
+                    }
+                    else
+                    {
+                        xx1 = qRound( x1 * pw - px0 );
+                        if ( xx1 < 0 )
+                            xx1 = 0;
+                    }
+
+                    int xx2;
+                    if ( x1 == w - 1 )
+                    {
+                        xx2 = sz.width();
+                    }
+                    else
+                    {
+                        xx2 = qRound( ( x1 + 1 ) * pw - px0 );
+                        if ( xx2 > sz.width() )
+                            xx2 = sz.width();
+                    }
+
+                    const quint32 rgb( line1[x1] );
+                    for ( int y2 = yy1; y2 < yy2; y2++ )
+                    {
+                        quint32 *line2 = ( quint32 *) expanded.scanLine( y2 );
+                        for ( int x2 = xx1; x2 < xx2; x2++ ) 
+                            line2[x2] = rgb;
+                    }       
+                }   
+            }   
+            break;
+        }
+        case 8:
+        {
+            for ( int y1 = 0; y1 < h; y1++ )
+            {
+                int yy1;
+                if ( y1 == 0 )
+                {
+                    yy1 = 0;
+                }   
+                else
+                {
+                    yy1 = qRound( y1 * ph - py0 );
+                    if ( yy1 < 0 )
+                        yy1 = 0; 
+                }       
+                
+                int yy2;
+                if ( y1 == h - 1 )
+                {
+                    yy2 = sz.height();
+                }   
+                else
+                {
+                    yy2 = qRound( ( y1 + 1 ) * ph - py0 );
+                    if ( yy2 > sz.height() )
+                        yy2 = sz.height();
+                }
+    
+                const uchar *line1 = image.scanLine( y1 );
+
+                for ( int x1 = 0; x1 < w; x1++ )
+                {
+                    int xx1;
+                    if ( x1 == 0 )
+                    {
+                        xx1 = 0;
+                    }
+                    else
+                    {
+                        xx1 = qRound( x1 * pw - px0 );
+                        if ( xx1 < 0 )
+                            xx1 = 0;
+                    }
+
+                    int xx2;
+                    if ( x1 == w - 1 )
+                    {
+                        xx2 = sz.width();
+                    }
+                    else
+                    {
+                        xx2 = qRound( ( x1 + 1 ) * pw - px0 );
+                        if ( xx2 > sz.width() )
+                            xx2 = sz.width();
+                    }
+
+                    for ( int y2 = yy1; y2 < yy2; y2++ )
+                    {
+                        uchar *line2 = expanded.scanLine( y2 );
+                        memset( line2 + xx1, line1[x1], xx2 - xx1 );
+                    }       
+                }   
+            }
+            break;
+        }
+        default:
+            expanded = image;
+    }
+    
+    return expanded;
+}   
+
+static QRectF expandToPixels(const QRectF &rect, const QRectF &pixelRect)
+{
+    const double pw = pixelRect.width();
+    const double ph = pixelRect.height();
+
+    const double dx1 = pixelRect.left() - rect.left();
+    const double dx2 = pixelRect.right() - rect.right();
+    const double dy1 = pixelRect.top() - rect.top();
+    const double dy2 = pixelRect.bottom() - rect.bottom();
+
+    QRectF r;
+    r.setLeft( pixelRect.left() - qCeil( dx1 / pw ) * pw );
+    r.setTop( pixelRect.top() - qCeil( dy1 / ph ) * ph );
+    r.setRight( pixelRect.right() - qFloor( dx2 / pw ) * pw );
+    r.setBottom( pixelRect.bottom() - qFloor( dy2 / ph ) * ph );
+
+    return r;
+}
+
+static void transformMaps( const QTransform &tr,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    QwtScaleMap &xxMap, QwtScaleMap &yyMap )
+{
+    const QPointF p1 = tr.map( QPointF( xMap.p1(), yMap.p1() ) );
+    const QPointF p2 = tr.map( QPointF( xMap.p2(), yMap.p2() ) );
+
+    xxMap = xMap;
+    xxMap.setPaintInterval( p1.x(), p2.x() );
+
+    yyMap = yMap;
+    yyMap.setPaintInterval( p1.y(), p2.y() );
+}
+
+static void adjustMaps( QwtScaleMap &xMap, QwtScaleMap &yMap,
+    const QRectF &area, const QRectF &paintRect)
+{
+    double sx1 = area.left();
+    double sx2 = area.right();
+    if ( xMap.isInverting() )
+        qSwap(sx1, sx2);
+
+    double sy1 = area.top();
+    double sy2 = area.bottom();
+
+    if ( yMap.isInverting() )
+        qSwap(sy1, sy2);
+
+    xMap.setPaintInterval(paintRect.left(), paintRect.right());
+    xMap.setScaleInterval(sx1, sx2);
+
+    yMap.setPaintInterval(paintRect.top(), paintRect.bottom());
+    yMap.setScaleInterval(sy1, sy2);
+}
+
+static bool useCache( QwtPlotRasterItem::CachePolicy policy,
+    const QPainter *painter )
+{
+    bool doCache = false;
+
+    if ( policy == QwtPlotRasterItem::PaintCache )
+    {
+        // Caching doesn't make sense, when the item is
+        // not painted to screen
+
+        switch ( painter->paintEngine()->type() )
+        {
+            case QPaintEngine::SVG:
+            case QPaintEngine::Pdf:
+            case QPaintEngine::PostScript:
+            case QPaintEngine::MacPrinter:
+            case QPaintEngine::Picture:
+                break;
+            default:;
+                doCache = true;
+        }
+    }
+
+    return doCache;
+}
+
+static QImage toRgba( const QImage& image, int alpha )
+{
+    if ( alpha < 0 || alpha >= 255 )
+        return image;
+
+    QImage alphaImage( image.size(), QImage::Format_ARGB32 );
+
+    const QRgb mask1 = qRgba( 0, 0, 0, alpha );
+    const QRgb mask2 = qRgba( 255, 255, 255, 0 );
+    const QRgb mask3 = qRgba( 0, 0, 0, 255 );
+
+    const int w = image.size().width();
+    const int h = image.size().height();
+
+    if ( image.depth() == 8 )
+    {
+        for ( int y = 0; y < h; y++ )
+        {
+            QRgb* alphaLine = ( QRgb* )alphaImage.scanLine( y );
+            const unsigned char *line = image.scanLine( y );
+
+            for ( int x = 0; x < w; x++ )
+                *alphaLine++ = ( image.color( *line++ ) & mask2 ) | mask1;
+        }
+    }
+    else if ( image.depth() == 32 )
+    {
+        for ( int y = 0; y < h; y++ )
+        {
+            QRgb* alphaLine = ( QRgb* )alphaImage.scanLine( y );
+            const QRgb* line = ( const QRgb* ) image.scanLine( y );
+
+            for ( int x = 0; x < w; x++ )
+            {
+                const QRgb rgb = *line++;
+                if ( rgb & mask3 ) // alpha != 0
+                    *alphaLine++ = ( rgb & mask2 ) | mask1;
+                else
+                    *alphaLine++ = rgb;
+            }
+        }
+    }
+
+    return alphaImage;
+}
+
+//! Constructor
+QwtPlotRasterItem::QwtPlotRasterItem( const QString& title ):
+    QwtPlotItem( QwtText( title ) )
+{
+    init();
+}
+
+//! Constructor
+QwtPlotRasterItem::QwtPlotRasterItem( const QwtText& title ):
+    QwtPlotItem( title )
+{
+    init();
+}
+
+//! Destructor
+QwtPlotRasterItem::~QwtPlotRasterItem()
+{
+    delete d_data;
+}
+
+void QwtPlotRasterItem::init()
+{
+    d_data = new PrivateData();
+
+    setItemAttribute( QwtPlotItem::AutoScale, true );
+    setItemAttribute( QwtPlotItem::Legend, false );
+
+    setZ( 8.0 );
+}
+
+/*!
+  Specify an attribute how to draw the raster item
+
+  \param attribute Paint attribute
+  \param on On/Off
+  /sa PaintAttribute, testPaintAttribute()
+*/
+void QwtPlotRasterItem::setPaintAttribute( PaintAttribute attribute, bool on )
+{
+    if ( on )
+        d_data->paintAttributes |= attribute;
+    else
+        d_data->paintAttributes &= ~attribute;
+}
+
+/*!
+    \brief Return the current paint attributes
+    \sa PaintAttribute, setPaintAttribute()
+*/
+bool QwtPlotRasterItem::testPaintAttribute( PaintAttribute attribute ) const
+{
+    return ( d_data->paintAttributes & attribute );
+}
+
+/*!
+   \brief Set an alpha value for the raster data
+
+   Often a plot has several types of raster data organized in layers.
+   ( f.e a geographical map, with weather statistics ).
+   Using setAlpha() raster items can be stacked easily.
+
+   The alpha value is a value [0, 255] to
+   control the transparency of the image. 0 represents a fully
+   transparent color, while 255 represents a fully opaque color.
+
+   \param alpha Alpha value
+
+   - alpha >= 0\n
+     All alpha values of the pixels returned by renderImage() will be set to
+     alpha, beside those with an alpha value of 0 (invalid pixels).
+   - alpha < 0
+     The alpha values returned by renderImage() are not changed.
+
+   The default alpha value is -1.
+
+   \sa alpha()
+*/
+void QwtPlotRasterItem::setAlpha( int alpha )
+{
+    if ( alpha < 0 )
+        alpha = -1;
+
+    if ( alpha > 255 )
+        alpha = 255;
+
+    if ( alpha != d_data->alpha )
+    {
+        d_data->alpha = alpha;
+
+        itemChanged();
+    }
+}
+
+/*!
+  \return Alpha value of the raster item
+  \sa setAlpha()
+*/
+int QwtPlotRasterItem::alpha() const
+{
+    return d_data->alpha;
+}
+
+/*!
+  Change the cache policy
+
+  The default policy is NoCache
+
+  \param policy Cache policy
+  \sa CachePolicy, cachePolicy()
+*/
+void QwtPlotRasterItem::setCachePolicy(
+    QwtPlotRasterItem::CachePolicy policy )
+{
+    if ( d_data->cache.policy != policy )
+    {
+        d_data->cache.policy = policy;
+
+        invalidateCache();
+        itemChanged();
+    }
+}
+
+/*!
+  \return Cache policy
+  \sa CachePolicy, setCachePolicy()
+*/
+QwtPlotRasterItem::CachePolicy QwtPlotRasterItem::cachePolicy() const
+{
+    return d_data->cache.policy;
+}
+
+/*!
+   Invalidate the paint cache
+   \sa setCachePolicy()
+*/
+void QwtPlotRasterItem::invalidateCache()
+{
+    d_data->cache.image = QImage();
+    d_data->cache.area = QRect();
+    d_data->cache.size = QSize();
+}
+
+/*!
+   \brief Pixel hint
+
+   The geometry of a pixel is used to calculated the resolution and
+   alignment of the rendered image. 
+
+   Width and height of the hint need to be the horizontal  
+   and vertical distances between 2 neighboured points. 
+   The center of the hint has to be the position of any point 
+   ( it doesn't matter which one ).
+
+   Limiting the resolution of the image might significantly improve
+   the performance and heavily reduce the amount of memory when rendering
+   a QImage from the raster data. 
+
+   The default implementation returns an empty rectangle (QRectF()),
+   meaning, that the image will be rendered in target device ( f.e screen )
+   resolution.
+
+   \param area In most implementations the resolution of the data doesn't
+               depend on the requested area.
+
+   \return Bounding rectangle of a pixel
+
+   \sa render(), renderImage()
+*/
+QRectF QwtPlotRasterItem::pixelHint( const QRectF &area ) const
+{
+    Q_UNUSED( area );
+    return QRectF();
+}
+
+/*!
+  \brief Draw the raster data
+  \param painter Painter
+  \param xMap X-Scale Map
+  \param yMap Y-Scale Map
+  \param canvasRect Contents rect of the plot canvas
+*/
+void QwtPlotRasterItem::draw( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect ) const
+{
+    if ( canvasRect.isEmpty() || d_data->alpha == 0 )
+        return;
+
+    const bool doCache = useCache( d_data->cache.policy, painter );
+
+    const QwtInterval xInterval = interval( Qt::XAxis );
+    const QwtInterval yInterval = interval( Qt::YAxis );
+
+    /*
+        Scaling a rastered image always results in a loss of
+        precision/quality. So we always render the image in
+        paint device resolution.
+    */
+
+    QwtScaleMap xxMap, yyMap;
+    transformMaps( painter->transform(), xMap, yMap, xxMap, yyMap );
+
+    QRectF paintRect = painter->transform().mapRect( canvasRect );
+    QRectF area = QwtScaleMap::invTransform( xxMap, yyMap, paintRect );
+
+    const QRectF br = boundingRect();
+    if ( br.isValid() && !br.contains( area ) )
+    {
+        area &= br;
+        if ( !area.isValid() )
+            return;
+
+        paintRect = QwtScaleMap::transform( xxMap, yyMap, area );
+    }
+
+    QRectF imageRect;
+    QImage image;
+
+    QRectF pixelRect = pixelHint(area);
+    if ( !pixelRect.isEmpty() )
+    {
+        const QRectF r = QwtScaleMap::invTransform( 
+            xxMap, yyMap, QRectF(0, 0, 1, 1) ).normalized();
+
+        if ( r.width() > pixelRect.width() &&
+            r.height() > pixelRect.height() )
+        {
+            /*
+              When the resolution of the data pixels is higher than
+              the resolution of the target device we render in
+              target device resolution.
+             */
+            pixelRect = QRectF();
+        }
+    }
+
+    if ( pixelRect.isEmpty() )
+    {
+        if ( QwtPainter::roundingAlignment( painter ) )
+        {
+            // we want to have maps, where the boundaries of
+            // the aligned paint rectangle exactly match the area
+
+            paintRect = qwtAlignRect(paintRect);
+            adjustMaps(xxMap, yyMap, area, paintRect);
+        }
+
+        // When we have no information about position and size of
+        // data pixels we render in resolution of the paint device.
+
+        image = compose(xxMap, yyMap, 
+            area, paintRect, paintRect.size().toSize(), doCache);
+        if ( image.isNull() )
+            return;
+
+        // Remove pixels at the boundaries, when explicitly
+        // excluded in the intervals
+
+        imageRect = qwtStripRect(paintRect, area, 
+            xxMap, yyMap, xInterval, yInterval);
+
+        if ( imageRect != paintRect )
+        {
+            const QRect r( 
+                qRound( imageRect.x() - paintRect.x()),
+                qRound( imageRect.y() - paintRect.y() ),
+                qRound( imageRect.width() ),
+                qRound( imageRect.height() ) );
+                
+            image = image.copy(r);
+        }   
+    }
+    else
+    {
+        if ( QwtPainter::roundingAlignment( painter ) )
+            paintRect = qwtAlignRect(paintRect);
+
+        // align the area to the data pixels
+        QRectF imageArea = expandToPixels(area, pixelRect);
+
+        if ( imageArea.right() == xInterval.maxValue() &&
+            !( xInterval.borderFlags() & QwtInterval::ExcludeMaximum ) )
+        {
+            imageArea.adjust(0, 0, pixelRect.width(), 0);
+        }
+        if ( imageArea.bottom() == yInterval.maxValue() &&
+            !( yInterval.borderFlags() & QwtInterval::ExcludeMaximum ) )
+        {
+            imageArea.adjust(0, 0, 0, pixelRect.height() );
+        }
+
+        QSize imageSize;
+        imageSize.setWidth( qRound( imageArea.width() / pixelRect.width() ) );
+        imageSize.setHeight( qRound( imageArea.height() / pixelRect.height() ) );
+        image = compose(xxMap, yyMap, 
+            imageArea, paintRect, imageSize, doCache );
+        if ( image.isNull() )
+            return;
+
+        imageRect = qwtStripRect(paintRect, area, 
+            xxMap, yyMap, xInterval, yInterval);
+
+        if ( ( image.width() > 1 || image.height() > 1 ) &&
+            testPaintAttribute( PaintInDeviceResolution ) )
+        {
+            // Because of rounding errors the pixels 
+            // need to be expanded manually to rectangles of 
+            // different sizes
+
+            image = qwtExpandImage(image, xxMap, yyMap, 
+                imageArea, area, paintRect, xInterval, yInterval );
+        }
+    }
+
+    painter->save();
+    painter->setWorldTransform( QTransform() );
+    
+    QwtPainter::drawImage( painter, imageRect, image );
+
+    painter->restore();
+}
+
+/*!
+   \return Bounding interval for an axis
+
+   This method is intended to be reimplemented by derived classes.
+   The default implementation returns an invalid interval.
+   
+   \param axis X, Y, or Z axis
+*/
+QwtInterval QwtPlotRasterItem::interval(Qt::Axis axis) const
+{
+    Q_UNUSED( axis );
+    return QwtInterval();
+}
+
+/*!
+   \return Bounding rect of the data
+   \sa QwtPlotRasterItem::interval()
+*/
+QRectF QwtPlotRasterItem::boundingRect() const
+{
+    const QwtInterval intervalX = interval( Qt::XAxis );
+    const QwtInterval intervalY = interval( Qt::YAxis );
+
+    if ( !intervalX.isValid() && !intervalY.isValid() )
+        return QRectF(); // no bounding rect
+
+    QRectF r;
+
+    if ( intervalX.isValid() )
+    {
+        r.setLeft( intervalX.minValue() );
+        r.setRight( intervalX.maxValue() );
+    }
+    else
+    {
+        r.setLeft(-0.5 * FLT_MAX);
+        r.setWidth(FLT_MAX);
+    }
+
+    if ( intervalY.isValid() )
+    {
+        r.setTop( intervalY.minValue() );
+        r.setBottom( intervalY.maxValue() );
+    }
+    else
+    {
+        r.setTop(-0.5 * FLT_MAX);
+        r.setHeight(FLT_MAX);
+    }
+
+    return r.normalized();
+}
+
+QImage QwtPlotRasterItem::compose( 
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &imageArea, const QRectF &paintRect, 
+    const QSize &imageSize, bool doCache) const
+{
+    QImage image;
+    if ( imageArea.isEmpty() || paintRect.isEmpty() || imageSize.isEmpty() )
+        return image;
+
+    if ( doCache )
+    {
+        if ( !d_data->cache.image.isNull()
+            && d_data->cache.area == imageArea
+            && d_data->cache.size == paintRect.size() )
+        {
+            image = d_data->cache.image;
+        }
+    }
+
+    if ( image.isNull() )
+    {
+        double dx = 0.0;
+        if ( paintRect.toRect().width() > imageSize.width() )
+            dx = imageArea.width() / imageSize.width();
+
+        const QwtScaleMap xxMap = 
+            imageMap(Qt::Horizontal, xMap, imageArea, imageSize, dx);
+        
+        double dy = 0.0;
+        if ( paintRect.toRect().height() > imageSize.height() )
+            dy = imageArea.height() / imageSize.height();
+
+        const QwtScaleMap yyMap = 
+            imageMap(Qt::Vertical, yMap, imageArea, imageSize, dy);
+
+        image = renderImage( xxMap, yyMap, imageArea, imageSize );
+
+        if ( doCache )
+        {
+            d_data->cache.area = imageArea;
+            d_data->cache.size = paintRect.size();
+            d_data->cache.image = image;
+        }
+    }
+
+    if ( d_data->alpha >= 0 && d_data->alpha < 255 )
+        image = toRgba( image, d_data->alpha );
+
+    return image;
+}
+
+/*!
+   \brief Calculate a scale map for painting to an image
+
+   \param orientation Orientation, Qt::Horizontal means a X axis
+   \param map Scale map for rendering the plot item
+   \param area Area to be painted on the image
+   \param imageSize Image size
+   \param pixelSize Width/Height of a data pixel
+*/
+QwtScaleMap QwtPlotRasterItem::imageMap(
+    Qt::Orientation orientation,
+    const QwtScaleMap &map, const QRectF &area,
+    const QSize &imageSize, double pixelSize) const
+{
+    double p1, p2, s1, s2;
+
+    if ( orientation == Qt::Horizontal )
+    {
+        p1 = 0.0;
+        p2 = imageSize.width();
+        s1 = area.left();
+        s2 = area.right();
+    }
+    else
+    {
+        p1 = 0.0;
+        p2 = imageSize.height();
+        s1 = area.top();
+        s2 = area.bottom();
+    }
+
+    if ( pixelSize > 0.0 )
+    {
+        double off = 0.5 * pixelSize;
+        if ( map.isInverting() )
+            off = -off;
+
+        s1 += off;
+        s2 += off;
+    }
+    else
+    {
+        p2--;
+    }
+
+    if ( map.isInverting() && ( s1 < s2 ) )
+        qSwap( s1, s2 );
+
+    QwtScaleMap newMap = map;
+    newMap.setPaintInterval( p1, p2 );
+    newMap.setScaleInterval( s1, s2 );
+
+    return newMap;
+}
Index: trunk/BNC/qwt/qwt_plot_rasteritem.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_rasteritem.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_rasteritem.h	(revision 4271)
@@ -0,0 +1,146 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_RASTERITEM_H
+#define QWT_PLOT_RASTERITEM_H
+
+#include "qwt_global.h"
+#include "qwt_plot_item.h"
+#include "qwt_interval.h"
+#include <qglobal.h>
+#include <qstring.h>
+#include <qimage.h>
+
+/*!
+  \brief A class, which displays raster data
+
+  Raster data is a grid of pixel values, that can be represented
+  as a QImage. It is used for many types of information like
+  spectrograms, cartograms, geographical maps ...
+
+  Often a plot has several types of raster data organized in layers.
+  ( f.e a geographical map, with weather statistics ).
+  Using setAlpha() raster items can be stacked easily.
+
+  QwtPlotRasterItem is only implemented for images of the following formats:
+  QImage::Format_Indexed8, QImage::Format_ARGB32.
+
+  \sa QwtPlotSpectrogram
+*/
+
+class QWT_EXPORT QwtPlotRasterItem: public QwtPlotItem
+{
+public:
+    /*!
+      - NoCache\n
+        renderImage() is called, whenever the item has to be repainted
+      - PaintCache\n
+        renderImage() is called, whenever the image cache is not valid,
+        or the scales, or the size of the canvas has changed. This type
+        of cache is only useful for improving the performance of hide/show
+        operations. All other situations are already handled by the
+        plot canvas cache.
+
+      The default policy is NoCache
+     */
+    enum CachePolicy
+    {
+        NoCache,
+        PaintCache
+    };
+
+    /*!
+        Attributes to modify the drawing algorithm.
+        \sa setPaintAttribute(), testPaintAttribute()
+    */
+    enum PaintAttribute
+    {
+        /*!
+          When the image is rendered according to the data pixels
+          ( QwtRasterData::pixelHint() ) it can be expanded to paint
+          device resolution before it is passed to QPainter. 
+          The expansion algorithm rounds the pixel borders in the same 
+          way as the axis ticks, what is usually better than the
+          scaling algorithm implemented in Qt.
+          Disabling this flag might make sense, to reduce the size of a 
+          document/file. If this is possible for a document format
+          depends on the implementation of the specific QPaintEngine.
+         */
+
+        PaintInDeviceResolution = 1
+    };
+
+    //! Paint attributes
+    typedef QFlags<PaintAttribute> PaintAttributes;
+
+    explicit QwtPlotRasterItem( const QString& title = QString::null );
+    explicit QwtPlotRasterItem( const QwtText& title );
+    virtual ~QwtPlotRasterItem();
+
+    void setPaintAttribute( PaintAttribute, bool on = true );
+    bool testPaintAttribute( PaintAttribute ) const;
+
+    void setAlpha( int alpha );
+    int alpha() const;
+
+    void setCachePolicy( CachePolicy );
+    CachePolicy cachePolicy() const;
+
+    void invalidateCache();
+
+    virtual void draw( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &rect ) const;
+
+    virtual QRectF pixelHint( const QRectF & ) const;
+
+    virtual QwtInterval interval(Qt::Axis) const;
+    virtual QRectF boundingRect() const;
+
+protected:
+    /*!
+      \brief Render an image 
+
+      An implementation of render() might iterate over all
+      pixels of imageRect. Each pixel has to be translated into 
+      the corresponding position in scale coordinates using the maps.
+      This position can be used to look up a value in a implementation
+      specific way and to map it into a color.
+
+      \param xMap X-Scale Map
+      \param yMap Y-Scale Map
+      \param area Requested area for the image in scale coordinates
+      \param imageSize Requested size of the image
+     */
+    virtual QImage renderImage( const QwtScaleMap &xMap,
+        const QwtScaleMap &yMap, const QRectF &area,
+        const QSize &imageSize ) const = 0;
+
+    virtual QwtScaleMap imageMap( Qt::Orientation,
+        const QwtScaleMap &map, const QRectF &area,
+        const QSize &imageSize, double pixelSize) const;
+
+private:
+    QwtPlotRasterItem( const QwtPlotRasterItem & );
+    QwtPlotRasterItem &operator=( const QwtPlotRasterItem & );
+
+    void init();
+
+    QImage compose( const QwtScaleMap &, const QwtScaleMap &,
+        const QRectF &imageArea, const QRectF &paintRect,
+        const QSize &imageSize, bool doCache) const;
+
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotRasterItem::PaintAttributes )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_renderer.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_renderer.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_renderer.cpp	(revision 4271)
@@ -0,0 +1,833 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_renderer.h"
+#include "qwt_plot.h"
+#include "qwt_painter.h"
+#include "qwt_plot_canvas.h"
+#include "qwt_plot_layout.h"
+#include "qwt_legend.h"
+#include "qwt_legend_item.h"
+#include "qwt_dyngrid_layout.h"
+#include "qwt_scale_widget.h"
+#include "qwt_scale_engine.h"
+#include "qwt_text.h"
+#include "qwt_text_label.h"
+#include "qwt_math.h"
+#include <qpainter.h>
+#include <qpaintengine.h>
+#include <qtransform.h>
+#include <qprinter.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+#include <qimagewriter.h>
+#include <qfileinfo.h>
+#ifndef QWT_NO_SVG
+#ifdef QT_SVG_LIB
+#include <qsvggenerator.h>
+#endif
+#endif
+
+class QwtPlotRenderer::PrivateData
+{
+public:
+    PrivateData():
+        discardFlags( QwtPlotRenderer::DiscardBackground ),
+        layoutFlags( QwtPlotRenderer::DefaultLayout )
+    {
+    }
+
+    QwtPlotRenderer::DiscardFlags discardFlags;
+    QwtPlotRenderer::LayoutFlags layoutFlags;
+};
+
+static void qwtRenderBackground( QPainter *painter,
+    const QRectF &rect, const QWidget *widget )
+{
+    if ( widget->testAttribute( Qt::WA_StyledBackground ) )
+    {
+        QStyleOption opt;
+        opt.initFrom( widget );
+        opt.rect = rect.toAlignedRect();
+
+        widget->style()->drawPrimitive(
+            QStyle::PE_Widget, &opt, painter, widget);
+    }
+    else
+    {
+        const QBrush brush = 
+            widget->palette().brush( widget->backgroundRole() );
+
+        painter->fillRect( rect, brush );
+    }
+}
+
+/*! 
+   Constructor
+   \param parent Parent object
+*/
+QwtPlotRenderer::QwtPlotRenderer( QObject *parent ):
+    QObject( parent )
+{
+    d_data = new PrivateData;
+}
+
+//! Destructor
+QwtPlotRenderer::~QwtPlotRenderer()
+{
+    delete d_data;
+}
+
+/*!
+  Change a flag, indicating what to discard from rendering
+
+  \param flag Flag to change
+  \param on On/Off
+
+  \sa DiscardFlag, testDiscardFlag(), setDiscardFlags(), discardFlags()
+*/
+void QwtPlotRenderer::setDiscardFlag( DiscardFlag flag, bool on )
+{
+    if ( on )
+        d_data->discardFlags |= flag;
+    else
+        d_data->discardFlags &= ~flag;
+}
+
+/*!
+  Check if a flag is set.
+
+  \param flag Flag to be tested
+  \sa DiscardFlag, setDiscardFlag(), setDiscardFlags(), discardFlags()
+*/
+bool QwtPlotRenderer::testDiscardFlag( DiscardFlag flag ) const
+{
+    return d_data->discardFlags & flag;
+}
+
+/*!
+  Set the flags, indicating what to discard from rendering
+
+  \param flags Flags
+  \sa DiscardFlag, setDiscardFlag(), testDiscardFlag(), discardFlags()
+*/
+void QwtPlotRenderer::setDiscardFlags( DiscardFlags flags )
+{
+    d_data->discardFlags = flags;
+}
+
+/*!
+  \return Flags, indicating what to discard from rendering
+  \sa DiscardFlag, setDiscardFlags(), setDiscardFlag(), testDiscardFlag()
+*/
+QwtPlotRenderer::DiscardFlags QwtPlotRenderer::discardFlags() const
+{
+    return d_data->discardFlags;
+}
+
+/*!
+  Change a layout flag
+
+  \param flag Flag to change
+  \param on On/Off
+
+  \sa LayoutFlag, testLayoutFlag(), setLayoutFlags(), layoutFlags()
+*/
+void QwtPlotRenderer::setLayoutFlag( LayoutFlag flag, bool on )
+{
+    if ( on )
+        d_data->layoutFlags |= flag;
+    else
+        d_data->layoutFlags &= ~flag;
+}
+
+/*!
+  Check if a flag is set.
+
+  \param flag Flag to be tested
+  \sa LayoutFlag, setLayoutFlag(), setLayoutFlags(), layoutFlags()
+*/
+bool QwtPlotRenderer::testLayoutFlag( LayoutFlag flag ) const
+{
+    return d_data->layoutFlags & flag;
+}
+
+/*!
+  Set the layout flags
+
+  \param flags Flags
+  \sa LayoutFlag, setLayoutFlag(), testLayoutFlag(), layoutFlags()
+*/
+void QwtPlotRenderer::setLayoutFlags( LayoutFlags flags )
+{
+    d_data->layoutFlags = flags;
+}
+
+/*!
+  \return Layout flags
+  \sa LayoutFlag, setLayoutFlags(), setLayoutFlag(), testLayoutFlag()
+*/
+QwtPlotRenderer::LayoutFlags QwtPlotRenderer::layoutFlags() const
+{
+    return d_data->layoutFlags;
+}
+
+/*!
+  Render a plot to a file
+
+  The format of the document will be autodetected from the
+  suffix of the filename.
+
+  \param plot Plot widget
+  \param fileName Path of the file, where the document will be stored
+  \param sizeMM Size for the document in millimeters.
+  \param resolution Resolution in dots per Inch (dpi)
+*/
+void QwtPlotRenderer::renderDocument( QwtPlot *plot,
+    const QString &fileName, const QSizeF &sizeMM, int resolution )
+{
+    renderDocument( plot, fileName,
+        QFileInfo( fileName ).suffix(), sizeMM, resolution );
+}
+
+/*!
+  Render a plot to a file
+
+  Supported formats are:
+
+  - pdf\n
+    Portable Document Format PDF
+  - ps\n
+    Postcript
+  - svg\n
+    Scalable Vector Graphics SVG
+  - all image formats supported by Qt\n
+    see QImageWriter::supportedImageFormats()
+
+  Scalable vector graphic formats like PDF or SVG are superior to
+  raster graphics formats.
+
+  \param plot Plot widget
+  \param fileName Path of the file, where the document will be stored
+  \param format Format for the document
+  \param sizeMM Size for the document in millimeters.
+  \param resolution Resolution in dots per Inch (dpi)
+
+  \sa renderTo(), render(), QwtPainter::setRoundingAlignment()
+*/
+void QwtPlotRenderer::renderDocument( QwtPlot *plot,
+    const QString &fileName, const QString &format,
+    const QSizeF &sizeMM, int resolution )
+{
+    if ( plot == NULL || sizeMM.isEmpty() || resolution <= 0 )
+        return;
+
+    QString title = plot->title().text();
+    if ( title.isEmpty() )
+        title = "Plot Document";
+
+    const double mmToInch = 1.0 / 25.4;
+    const QSizeF size = sizeMM * mmToInch * resolution;
+
+    const QRectF documentRect( 0.0, 0.0, size.width(), size.height() );
+
+    const QString fmt = format.toLower();
+    if ( fmt == "pdf" || fmt == "ps" )
+    {
+#ifndef QT_NO_PRINTER
+        QPrinter printer;
+        printer.setFullPage( true );
+        printer.setPaperSize( sizeMM, QPrinter::Millimeter );
+        printer.setDocName( title );
+        printer.setOutputFileName( fileName );
+        printer.setOutputFormat( ( format == "pdf" )
+            ? QPrinter::PdfFormat : QPrinter::PostScriptFormat );
+        printer.setResolution( resolution );
+
+        QPainter painter( &printer );
+        render( plot, &painter, documentRect );
+#endif
+    }
+    else if ( fmt == "svg" )
+    {
+#ifndef QWT_NO_SVG
+#ifdef QT_SVG_LIB
+#if QT_VERSION >= 0x040500
+        QSvgGenerator generator;
+        generator.setTitle( title );
+        generator.setFileName( fileName );
+        generator.setResolution( resolution );
+        generator.setViewBox( documentRect );
+
+        QPainter painter( &generator );
+        render( plot, &painter, documentRect );
+#endif
+#endif
+#endif
+    }
+    else
+    {
+        if ( QImageWriter::supportedImageFormats().indexOf(
+            format.toLatin1() ) >= 0 )
+        {
+            const QRect imageRect = documentRect.toRect();
+            const int dotsPerMeter = qRound( resolution * mmToInch * 1000.0 );
+
+            QImage image( imageRect.size(), QImage::Format_ARGB32 );
+            image.setDotsPerMeterX( dotsPerMeter );
+            image.setDotsPerMeterY( dotsPerMeter );
+            image.fill( QColor( Qt::white ).rgb() );
+
+            QPainter painter( &image );
+            render( plot, &painter, imageRect );
+            painter.end();
+
+            image.save( fileName, format.toLatin1() );
+        }
+    }
+}
+
+/*!
+  \brief Render the plot to a \c QPaintDevice
+
+  This function renders the contents of a QwtPlot instance to
+  \c QPaintDevice object. The target rectangle is derived from
+  its device metrics.
+
+  \param plot Plot to be rendered
+  \param paintDevice device to paint on, f.e a QImage
+
+  \sa renderDocument(), render(), QwtPainter::setRoundingAlignment()
+*/
+
+void QwtPlotRenderer::renderTo(
+    QwtPlot *plot, QPaintDevice &paintDevice ) const
+{
+    int w = paintDevice.width();
+    int h = paintDevice.height();
+
+    QPainter p( &paintDevice );
+    render( plot, &p, QRectF( 0, 0, w, h ) );
+}
+
+/*!
+  \brief Render the plot to a QPrinter
+
+  This function renders the contents of a QwtPlot instance to
+  \c QPaintDevice object. The size is derived from the printer
+  metrics.
+
+  \param plot Plot to be rendered
+  \param printer Printer to paint on
+
+  \sa renderDocument(), render(), QwtPainter::setRoundingAlignment()
+*/
+
+#ifndef QT_NO_PRINTER
+
+void QwtPlotRenderer::renderTo(
+    QwtPlot *plot, QPrinter &printer ) const
+{
+    int w = printer.width();
+    int h = printer.height();
+
+    QRectF rect( 0, 0, w, h );
+    double aspect = rect.width() / rect.height();
+    if ( ( aspect < 1.0 ) )
+        rect.setHeight( aspect * rect.width() );
+
+    QPainter p( &printer );
+    render( plot, &p, rect );
+}
+
+#endif
+
+#ifndef QWT_NO_SVG
+#ifdef QT_SVG_LIB
+#if QT_VERSION >= 0x040500
+
+/*!
+  \brief Render the plot to a QSvgGenerator
+
+  If the generator has a view box, the plot will be rendered into it.
+  If it has no viewBox but a valid size the target coordinates
+  will be (0, 0, generator.width(), generator.height()). Otherwise
+  the target rectangle will be QRectF(0, 0, 800, 600);
+
+  \param plot Plot to be rendered
+  \param generator SVG generator
+*/
+void QwtPlotRenderer::renderTo(
+    QwtPlot *plot, QSvgGenerator &generator ) const
+{
+    QRectF rect = generator.viewBoxF();
+    if ( rect.isEmpty() )
+        rect.setRect( 0, 0, generator.width(), generator.height() );
+
+    if ( rect.isEmpty() )
+        rect.setRect( 0, 0, 800, 600 ); // something
+
+    QPainter p( &generator );
+    render( plot, &p, rect );
+}
+#endif
+#endif
+#endif
+
+/*!
+  Paint the contents of a QwtPlot instance into a given rectangle.
+
+  \param plot Plot to be rendered
+  \param painter Painter
+  \param plotRect Bounding rectangle
+
+  \sa renderDocument(), renderTo(), QwtPainter::setRoundingAlignment()
+*/
+void QwtPlotRenderer::render( QwtPlot *plot,
+    QPainter *painter, const QRectF &plotRect ) const
+{
+    int axisId;
+
+    if ( painter == 0 || !painter->isActive() ||
+            !plotRect.isValid() || plot->size().isNull() )
+        return;
+
+    if ( !( d_data->discardFlags & DiscardBackground ) )
+        qwtRenderBackground( painter, plotRect, plot );
+
+    /*
+      The layout engine uses the same methods as they are used
+      by the Qt layout system. Therefore we need to calculate the
+      layout in screen coordinates and paint with a scaled painter.
+     */
+    QTransform transform;
+    transform.scale(
+        double( painter->device()->logicalDpiX() ) / plot->logicalDpiX(),
+        double( painter->device()->logicalDpiY() ) / plot->logicalDpiY() );
+
+    painter->save();
+
+    int baseLineDists[QwtPlot::axisCnt];
+    if ( d_data->layoutFlags & FrameWithScales )
+    {
+        for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
+        {
+            QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
+            if ( scaleWidget )
+            {
+                baseLineDists[axisId] = scaleWidget->margin();
+                scaleWidget->setMargin( 0 );
+            }
+        }
+    }
+    // Calculate the layout for the print.
+
+    QwtPlotLayout::Options layoutOptions = 
+        QwtPlotLayout::IgnoreScrollbars | QwtPlotLayout::IgnoreFrames;
+    if ( d_data->discardFlags & DiscardLegend )
+        layoutOptions |= QwtPlotLayout::IgnoreLegend;
+
+    const QRectF layoutRect = transform.inverted().mapRect( plotRect );
+    plot->plotLayout()->activate( plot, layoutRect, layoutOptions );
+
+    painter->setWorldTransform( transform, true );
+
+    // canvas
+
+    QwtScaleMap maps[QwtPlot::axisCnt];
+    buildCanvasMaps( plot, plot->plotLayout()->canvasRect(), maps );
+    renderCanvas( plot, painter, plot->plotLayout()->canvasRect(), maps );
+
+    if ( !( d_data->discardFlags & DiscardTitle )
+        && ( !plot->titleLabel()->text().isEmpty() ) )
+    {
+        renderTitle( plot, painter, plot->plotLayout()->titleRect() );
+    }
+
+    if ( !( d_data->discardFlags & DiscardLegend )
+        && plot->legend() && !plot->legend()->isEmpty() )
+    {
+        renderLegend( plot, painter, plot->plotLayout()->legendRect() );
+    }
+
+    for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
+    {
+        QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
+        if ( scaleWidget )
+        {
+            int baseDist = scaleWidget->margin();
+
+            int startDist, endDist;
+            scaleWidget->getBorderDistHint( startDist, endDist );
+
+            renderScale( plot, painter, axisId, startDist, endDist,
+                baseDist, plot->plotLayout()->scaleRect( axisId ) );
+        }
+    }
+
+
+    plot->plotLayout()->invalidate();
+
+    // reset all widgets with their original attributes.
+    if ( d_data->layoutFlags & FrameWithScales )
+    {
+        // restore the previous base line dists
+
+        for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
+        {
+            QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
+            if ( scaleWidget  )
+                scaleWidget->setMargin( baseLineDists[axisId] );
+        }
+    }
+
+    painter->restore();
+}
+
+/*!
+  Render the title into a given rectangle.
+
+  \param plot Plot widget
+  \param painter Painter
+  \param rect Bounding rectangle
+*/
+void QwtPlotRenderer::renderTitle( const QwtPlot *plot,
+    QPainter *painter, const QRectF &rect ) const
+{
+    painter->setFont( plot->titleLabel()->font() );
+
+    const QColor color = plot->titleLabel()->palette().color(
+            QPalette::Active, QPalette::Text );
+
+    painter->setPen( color );
+    plot->titleLabel()->text().draw( painter, rect );
+}
+
+/*!
+  Render the legend into a given rectangle.
+
+  \param plot Plot widget
+  \param painter Painter
+  \param rect Bounding rectangle
+*/
+void QwtPlotRenderer::renderLegend( const QwtPlot *plot,
+    QPainter *painter, const QRectF &rect ) const
+{
+    if ( !plot->legend() || plot->legend()->isEmpty() )
+        return;
+
+    if ( !( d_data->discardFlags & DiscardBackground ) )
+    {
+        if ( plot->legend()->autoFillBackground() ||
+            plot->legend()->testAttribute( Qt::WA_StyledBackground ) )
+        {
+            qwtRenderBackground( painter, rect, plot->legend() );
+        }
+    }
+
+    const QwtDynGridLayout *legendLayout = qobject_cast<QwtDynGridLayout *>( 
+        plot->legend()->contentsWidget()->layout() );
+    if ( legendLayout == NULL )
+        return;
+
+    uint numCols = legendLayout->columnsForWidth( rect.width() );
+    QList<QRect> itemRects =
+        legendLayout->layoutItems( rect.toRect(), numCols );
+
+    int index = 0;
+
+    for ( int i = 0; i < legendLayout->count(); i++ )
+    {
+        QLayoutItem *item = legendLayout->itemAt( i );
+        QWidget *w = item->widget();
+        if ( w )
+        {
+            painter->save();
+
+            painter->setClipRect( itemRects[index] );
+            renderLegendItem( plot, painter, w, itemRects[index] );
+
+            index++;
+            painter->restore();
+        }
+    }
+}
+
+/*!
+  Render the legend item into a given rectangle.
+
+  \param plot Plot widget
+  \param painter Painter
+  \param widget Widget representing a legend item
+  \param rect Bounding rectangle
+
+  \note When widget is not derived from QwtLegendItem renderLegendItem
+        does nothing and needs to be overloaded
+*/
+void QwtPlotRenderer::renderLegendItem( const QwtPlot *plot,
+    QPainter *painter, const QWidget *widget, const QRectF &rect ) const
+{
+    if ( !( d_data->discardFlags & DiscardBackground ) )
+    {
+        if ( widget->autoFillBackground() ||
+            widget->testAttribute( Qt::WA_StyledBackground ) )
+        {
+            qwtRenderBackground( painter, rect, widget );
+        }
+    }
+
+    const QwtLegendItem *item = qobject_cast<const QwtLegendItem *>( widget );
+    if ( item )
+    {
+        const QSize sz = item->identifierSize();
+
+        const QRectF identifierRect( rect.x() + item->margin(), 
+            rect.center().y() - 0.5 * sz.height(), sz.width(), sz.height() );
+
+        QwtLegendItemManager *itemManger = plot->legend()->find( item );
+        if ( itemManger )
+        {
+            painter->save();
+            painter->setClipRect( identifierRect, Qt::IntersectClip );
+            itemManger->drawLegendIdentifier( painter, identifierRect );
+            painter->restore();
+        }
+
+        // Label
+
+        QRectF titleRect = rect;
+        titleRect.setX( identifierRect.right() + 2 * item->spacing() );
+
+        painter->setFont( item->font() );
+        item->text().draw( painter, titleRect );
+    }
+}
+
+/*!
+  \brief Paint a scale into a given rectangle.
+  Paint the scale into a given rectangle.
+
+  \param plot Plot widget
+  \param painter Painter
+  \param axisId Axis
+  \param startDist Start border distance
+  \param endDist End border distance
+  \param baseDist Base distance
+  \param rect Bounding rectangle
+*/
+void QwtPlotRenderer::renderScale( const QwtPlot *plot,
+    QPainter *painter,
+    int axisId, int startDist, int endDist, int baseDist,
+    const QRectF &rect ) const
+{
+    if ( !plot->axisEnabled( axisId ) )
+        return;
+
+    const QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
+    if ( scaleWidget->isColorBarEnabled()
+        && scaleWidget->colorBarWidth() > 0 )
+    {
+        scaleWidget->drawColorBar( painter, scaleWidget->colorBarRect( rect ) );
+
+        const int off = scaleWidget->colorBarWidth() + scaleWidget->spacing();
+        if ( scaleWidget->scaleDraw()->orientation() == Qt::Horizontal )
+            baseDist += off;
+        else
+            baseDist += off;
+    }
+
+    painter->save();
+
+    QwtScaleDraw::Alignment align;
+    double x, y, w;
+
+    switch ( axisId )
+    {
+        case QwtPlot::yLeft:
+        {
+            x = rect.right() - 1.0 - baseDist;
+            y = rect.y() + startDist;
+            w = rect.height() - startDist - endDist;
+            align = QwtScaleDraw::LeftScale;
+            break;
+        }
+        case QwtPlot::yRight:
+        {
+            x = rect.left() + baseDist;
+            y = rect.y() + startDist;
+            w = rect.height() - startDist - endDist;
+            align = QwtScaleDraw::RightScale;
+            break;
+        }
+        case QwtPlot::xTop:
+        {
+            x = rect.left() + startDist;
+            y = rect.bottom() - 1.0 - baseDist;
+            w = rect.width() - startDist - endDist;
+            align = QwtScaleDraw::TopScale;
+            break;
+        }
+        case QwtPlot::xBottom:
+        {
+            x = rect.left() + startDist;
+            y = rect.top() + baseDist;
+            w = rect.width() - startDist - endDist;
+            align = QwtScaleDraw::BottomScale;
+            break;
+        }
+        default:
+            return;
+    }
+
+    scaleWidget->drawTitle( painter, align, rect );
+
+    painter->setFont( scaleWidget->font() );
+
+    QwtScaleDraw *sd = const_cast<QwtScaleDraw *>( scaleWidget->scaleDraw() );
+    const QPointF sdPos = sd->pos();
+    const double sdLength = sd->length();
+
+    sd->move( x, y );
+    sd->setLength( w );
+
+    QPalette palette = scaleWidget->palette();
+    palette.setCurrentColorGroup( QPalette::Active );
+    sd->draw( painter, palette );
+
+    // reset previous values
+    sd->move( sdPos );
+    sd->setLength( sdLength );
+
+    painter->restore();
+}
+
+/*!
+  Render the canvas into a given rectangle.
+
+  \param plot Plot widget
+  \param painter Painter
+  \param map Maps mapping between plot and paint device coordinates
+  \param canvasRect Canvas rectangle
+*/
+void QwtPlotRenderer::renderCanvas( const QwtPlot *plot,
+    QPainter *painter, const QRectF &canvasRect, 
+    const QwtScaleMap *map ) const
+{
+    painter->save();
+
+    QPainterPath clipPath;
+
+    QRectF r = canvasRect.adjusted( 0.0, 0.0, -1.0, -1.0 );
+
+    if ( d_data->layoutFlags & FrameWithScales )
+    {
+        r.adjust( -1.0, -1.0, 1.0, 1.0 );
+        painter->setPen( QPen( Qt::black ) );
+
+        if ( !( d_data->discardFlags & DiscardCanvasBackground ) )
+        {
+            const QBrush bgBrush =
+                plot->canvas()->palette().brush( plot->backgroundRole() );
+            painter->setBrush( bgBrush );
+        }
+
+        QwtPainter::drawRect( painter, r );
+    }
+    else
+    {
+        if ( !( d_data->discardFlags & DiscardCanvasBackground ) )
+        {
+            qwtRenderBackground( painter, r, plot->canvas() );
+
+            if ( plot->canvas()->testAttribute( Qt::WA_StyledBackground ) )
+            {
+                // The clip region is calculated in integers
+                // To avoid too much rounding errors better
+                // calculate it in target device resolution
+                // TODO ...
+
+                int x1 = qCeil( canvasRect.left() );
+                int x2 = qFloor( canvasRect.right() );
+                int y1 = qCeil( canvasRect.top() );
+                int y2 = qFloor( canvasRect.bottom() );
+
+                clipPath = plot->canvas()->borderPath( 
+                    QRect( x1, y1, x2 - x1 - 1, y2 - y1 - 1 ) );
+            }
+        }
+    }
+
+    painter->restore();
+
+    painter->save();
+
+    if ( clipPath.isEmpty() )
+        painter->setClipRect( canvasRect );
+    else
+        painter->setClipPath( clipPath );
+
+    plot->drawItems( painter, canvasRect, map );
+
+    painter->restore();
+}
+
+/*!
+   Calculated the scale maps for rendering the canvas
+
+   \param plot Plot widget
+   \param canvasRect Target rectangle
+   \param maps Scale maps to be calculated
+*/
+void QwtPlotRenderer::buildCanvasMaps( const QwtPlot *plot,
+    const QRectF &canvasRect, QwtScaleMap maps[] ) const
+{
+    for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
+    {
+        maps[axisId].setTransformation(
+            plot->axisScaleEngine( axisId )->transformation() );
+
+        const QwtScaleDiv &scaleDiv = *plot->axisScaleDiv( axisId );
+        maps[axisId].setScaleInterval(
+            scaleDiv.lowerBound(), scaleDiv.upperBound() );
+
+        double from, to;
+        if ( plot->axisEnabled( axisId ) )
+        {
+            const int sDist = plot->axisWidget( axisId )->startBorderDist();
+            const int eDist = plot->axisWidget( axisId )->endBorderDist();
+            const QRectF &scaleRect = plot->plotLayout()->scaleRect( axisId );
+
+            if ( axisId == QwtPlot::xTop || axisId == QwtPlot::xBottom )
+            {
+                from = scaleRect.left() + sDist;
+                to = scaleRect.right() - eDist;
+            }
+            else
+            {
+                from = scaleRect.bottom() - eDist;
+                to = scaleRect.top() + sDist;
+            }
+        }
+        else
+        {
+            int margin = plot->plotLayout()->canvasMargin( axisId );
+            if ( axisId == QwtPlot::yLeft || axisId == QwtPlot::yRight )
+            {
+                from = canvasRect.bottom() - margin;
+                to = canvasRect.top() + margin;
+            }
+            else
+            {
+                from = canvasRect.left() + margin;
+                to = canvasRect.right() - margin;
+            }
+        }
+        maps[axisId].setPaintInterval( from, to );
+    }
+}
Index: trunk/BNC/qwt/qwt_plot_renderer.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_renderer.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_renderer.h	(revision 4271)
@@ -0,0 +1,154 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_RENDERER_H
+#define QWT_PLOT_RENDERER_H
+
+#include "qwt_global.h"
+#include <qobject.h>
+
+class QwtPlot;
+class QwtScaleMap;
+class QSizeF;
+class QRectF;
+class QPainter;
+class QPaintDevice;
+
+#ifndef QT_NO_PRINTER
+class QPrinter;
+#endif
+
+#ifndef QWT_NO_SVG
+#ifdef QT_SVG_LIB
+class QSvgGenerator;
+#endif
+#endif
+
+/*!
+    \brief Renderer for exporting a plot to a document, a printer
+           or anything else, that is supported by QPainter/QPaintDevice
+*/
+class QWT_EXPORT QwtPlotRenderer: public QObject
+{
+    Q_OBJECT
+
+public:
+    //! Disard flags
+    enum DiscardFlag
+    {
+        //! Render all components of the plot
+        DiscardNone             = 0x00,
+
+        //! Don't render the background of the plot
+        DiscardBackground       = 0x01,
+
+        //! Don't render the title of the plot
+        DiscardTitle            = 0x02,
+
+        //! Don't render the legend of the plot
+        DiscardLegend           = 0x04,
+
+        //! Don't render the background of the canvas
+        DiscardCanvasBackground = 0x08
+    };
+
+    //! Disard flags
+    typedef QFlags<DiscardFlag> DiscardFlags;
+
+    /*!
+       \brief Layout flags
+       \sa setLayoutFlag(), testLayoutFlag()
+     */
+    enum LayoutFlag
+    {
+        //! Use the default layout without margins and frames
+        DefaultLayout   = 0x00,
+
+        //! Render all frames of the plot
+        KeepFrames      = 0x01,
+
+        /*!
+          Instead of the scales a box is painted around the plot canvas,
+          where the scale ticks are aligned to.
+         */
+        FrameWithScales = 0x02
+    };
+
+    //! Layout flags
+    typedef QFlags<LayoutFlag> LayoutFlags;
+
+    explicit QwtPlotRenderer( QObject * = NULL );
+    virtual ~QwtPlotRenderer();
+
+    void setDiscardFlag( DiscardFlag flag, bool on = true );
+    bool testDiscardFlag( DiscardFlag flag ) const;
+
+    void setDiscardFlags( DiscardFlags flags );
+    DiscardFlags discardFlags() const;
+
+    void setLayoutFlag( LayoutFlag flag, bool on = true );
+    bool testLayoutFlag( LayoutFlag flag ) const;
+
+    void setLayoutFlags( LayoutFlags flags );
+    LayoutFlags layoutFlags() const;
+
+    void renderDocument( QwtPlot *, const QString &format,
+        const QSizeF &sizeMM, int resolution = 85 );
+
+    void renderDocument( QwtPlot *,
+        const QString &title, const QString &format,
+        const QSizeF &sizeMM, int resolution = 85 );
+
+#ifndef QWT_NO_SVG
+#ifdef QT_SVG_LIB
+#if QT_VERSION >= 0x040500
+    void renderTo( QwtPlot *, QSvgGenerator & ) const;
+#endif
+#endif
+#endif
+
+#ifndef QT_NO_PRINTER
+    void renderTo( QwtPlot *, QPrinter & ) const;
+#endif
+
+    void renderTo( QwtPlot *, QPaintDevice &p ) const;
+
+    virtual void render( QwtPlot *,
+        QPainter *, const QRectF &rect ) const;
+
+    virtual void renderLegendItem( const QwtPlot *, 
+        QPainter *, const QWidget *, const QRectF & ) const;
+
+    virtual void renderTitle( const QwtPlot *,
+        QPainter *, const QRectF & ) const;
+
+    virtual void renderScale( const QwtPlot *, QPainter *,
+        int axisId, int startDist, int endDist,
+        int baseDist, const QRectF & ) const;
+
+    virtual void renderCanvas( const QwtPlot *,
+        QPainter *, const QRectF &canvasRect,
+        const QwtScaleMap* maps ) const;
+
+    virtual void renderLegend( 
+        const QwtPlot *, QPainter *, const QRectF & ) const;
+
+protected:
+    void buildCanvasMaps( const QwtPlot *,
+        const QRectF &, QwtScaleMap maps[] ) const;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotRenderer::DiscardFlags )
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotRenderer::LayoutFlags )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_rescaler.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_rescaler.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_rescaler.cpp	(revision 4271)
@@ -0,0 +1,624 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_rescaler.h"
+#include "qwt_plot.h"
+#include "qwt_plot_canvas.h"
+#include "qwt_scale_div.h"
+#include "qwt_interval.h"
+#include <qevent.h>
+#include <qalgorithms.h>
+
+class QwtPlotRescaler::AxisData
+{
+public:
+    AxisData():
+        aspectRatio( 1.0 ),
+        expandingDirection( QwtPlotRescaler::ExpandUp )
+    {
+    }
+
+    double aspectRatio;
+    QwtInterval intervalHint;
+    QwtPlotRescaler::ExpandingDirection expandingDirection;
+    mutable QwtScaleDiv scaleDiv;
+};
+
+class QwtPlotRescaler::PrivateData
+{
+public:
+    PrivateData():
+        referenceAxis( QwtPlot::xBottom ),
+        rescalePolicy( QwtPlotRescaler::Expanding ),
+        isEnabled( false ),
+        inReplot( 0 )
+    {
+    }
+
+    int referenceAxis;
+    RescalePolicy rescalePolicy;
+    QwtPlotRescaler::AxisData axisData[QwtPlot::axisCnt];
+    bool isEnabled;
+
+    mutable int inReplot;
+};
+
+/*!
+   Constructor
+
+   \param canvas Canvas
+   \param referenceAxis Reference axis, see RescalePolicy
+   \param policy Rescale policy
+
+   \sa setRescalePolicy(), setReferenceAxis()
+*/
+QwtPlotRescaler::QwtPlotRescaler( QwtPlotCanvas *canvas,
+        int referenceAxis, RescalePolicy policy ):
+    QObject( canvas )
+{
+    d_data = new PrivateData;
+    d_data->referenceAxis = referenceAxis;
+    d_data->rescalePolicy = policy;
+
+    setEnabled( true );
+}
+
+//! Destructor
+QwtPlotRescaler::~QwtPlotRescaler()
+{
+    delete d_data;
+}
+
+/*!
+  \brief En/disable the rescaler
+
+  When enabled is true an event filter is installed for
+  the canvas, otherwise the event filter is removed.
+
+  \param on true or false
+  \sa isEnabled(), eventFilter()
+*/
+void QwtPlotRescaler::setEnabled( bool on )
+{
+    if ( d_data->isEnabled != on )
+    {
+        d_data->isEnabled = on;
+
+        QWidget *w = canvas();
+        if ( w )
+        {
+            if ( d_data->isEnabled )
+                w->installEventFilter( this );
+            else
+                w->removeEventFilter( this );
+        }
+    }
+}
+
+/*!
+  \return true when enabled, false otherwise
+  \sa setEnabled, eventFilter()
+*/
+bool QwtPlotRescaler::isEnabled() const
+{
+    return d_data->isEnabled;
+}
+
+/*!
+  Change the rescale policy
+
+  \param policy Rescale policy
+  \sa rescalePolicy()
+*/
+void QwtPlotRescaler::setRescalePolicy( RescalePolicy policy )
+{
+    d_data->rescalePolicy = policy;
+}
+
+/*!
+  \return Rescale policy
+  \sa setRescalePolicy()
+*/
+QwtPlotRescaler::RescalePolicy QwtPlotRescaler::rescalePolicy() const
+{
+    return d_data->rescalePolicy;
+}
+
+/*!
+  Set the reference axis ( see RescalePolicy )
+
+  \param axis Axis index ( QwtPlot::Axis )
+  \sa referenceAxis()
+*/
+void QwtPlotRescaler::setReferenceAxis( int axis )
+{
+    d_data->referenceAxis = axis;
+}
+
+/*!
+  \return Reference axis ( see RescalePolicy )
+  \sa setReferenceAxis()
+*/
+int QwtPlotRescaler::referenceAxis() const
+{
+    return d_data->referenceAxis;
+}
+
+/*!
+  Set the direction in which all axis should be expanded
+
+  \param direction Direction
+  \sa expandingDirection()
+*/
+void QwtPlotRescaler::setExpandingDirection(
+    ExpandingDirection direction )
+{
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+        setExpandingDirection( axis, direction );
+}
+
+/*!
+  Set the direction in which an axis should be expanded
+
+  \param axis Axis index ( see QwtPlot::AxisId )
+  \param direction Direction
+  \sa expandingDirection()
+*/
+void QwtPlotRescaler::setExpandingDirection(
+    int axis, ExpandingDirection direction )
+{
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        d_data->axisData[axis].expandingDirection = direction;
+}
+
+/*!
+  Return direction in which an axis should be expanded
+
+  \param axis Axis index ( see QwtPlot::AxisId )
+  \sa setExpandingDirection()
+*/
+QwtPlotRescaler::ExpandingDirection
+QwtPlotRescaler::expandingDirection( int axis ) const
+{
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        return d_data->axisData[axis].expandingDirection;
+
+    return ExpandBoth;
+}
+
+/*!
+  Set the aspect ratio between the scale of the reference axis
+  and the other scales. The default ratio is 1.0
+
+  \param ratio Aspect ratio
+  \sa aspectRatio()
+*/
+void QwtPlotRescaler::setAspectRatio( double ratio )
+{
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+        setAspectRatio( axis, ratio );
+}
+
+/*!
+  Set the aspect ratio between the scale of the reference axis
+  and another scale. The default ratio is 1.0
+
+  \param axis Axis index ( see QwtPlot::AxisId )
+  \param ratio Aspect ratio
+  \sa aspectRatio()
+*/
+void QwtPlotRescaler::setAspectRatio( int axis, double ratio )
+{
+    if ( ratio < 0.0 )
+        ratio = 0.0;
+
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        d_data->axisData[axis].aspectRatio = ratio;
+}
+
+/*!
+  Return aspect ratio between an axis and the reference axis.
+
+  \param axis Axis index ( see QwtPlot::AxisId )
+  \sa setAspectRatio()
+*/
+double QwtPlotRescaler::aspectRatio( int axis ) const
+{
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        return d_data->axisData[axis].aspectRatio;
+
+    return 0.0;
+}
+
+/*!
+  Set an interval hint for an axis
+
+  In Fitting mode, the hint is used as minimal interval
+  taht always needs to be displayed.
+
+  \param axis Axis, see QwtPlot::Axis
+  \param interval Axis
+  \sa intervalHint(), RescalePolicy
+*/
+void QwtPlotRescaler::setIntervalHint( int axis,
+    const QwtInterval &interval )
+{
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        d_data->axisData[axis].intervalHint = interval;
+}
+
+/*!
+  \param axis Axis, see QwtPlot::Axis
+  \return Interval hint
+  \sa setIntervalHint(), RescalePolicy
+*/
+QwtInterval QwtPlotRescaler::intervalHint( int axis ) const
+{
+    if ( axis >= 0 && axis < QwtPlot::axisCnt )
+        return d_data->axisData[axis].intervalHint;
+
+    return QwtInterval();
+}
+
+//! \return plot canvas
+QwtPlotCanvas *QwtPlotRescaler::canvas()
+{
+    return qobject_cast<QwtPlotCanvas *>( parent() );
+}
+
+//! \return plot canvas
+const QwtPlotCanvas *QwtPlotRescaler::canvas() const
+{
+    return qobject_cast<const QwtPlotCanvas *>( parent() );
+}
+
+//! \return plot widget
+QwtPlot *QwtPlotRescaler::plot()
+{
+    QwtPlotCanvas *w = canvas();
+    if ( w )
+        return w->plot();
+
+    return NULL;
+}
+
+//! \return plot widget
+const QwtPlot *QwtPlotRescaler::plot() const
+{
+    const QwtPlotCanvas *w = canvas();
+    if ( w )
+        return w->plot();
+
+    return NULL;
+}
+
+//!  Event filter for the plot canvas
+bool QwtPlotRescaler::eventFilter( QObject *o, QEvent *e )
+{
+    if ( o && o == canvas() )
+    {
+        switch ( e->type() )
+        {
+            case QEvent::Resize:
+                canvasResizeEvent( ( QResizeEvent * )e );
+                break;
+            case QEvent::PolishRequest:
+                rescale();
+                break;
+            default:;
+        }
+    }
+
+    return false;
+}
+
+/*!
+  Event handler for resize events of the plot canvas
+
+  \param event Resize event
+  \sa rescale()
+*/
+void QwtPlotRescaler::canvasResizeEvent( QResizeEvent* event )
+{
+    const int fw = 2 * canvas()->frameWidth();
+    const QSize newSize = event->size() - QSize( fw, fw );
+    const QSize oldSize = event->oldSize() - QSize( fw, fw );
+
+    rescale( oldSize, newSize );
+}
+
+//! Adjust the plot axes scales
+void QwtPlotRescaler::rescale() const
+{
+    const QSize size = canvas()->contentsRect().size();
+    rescale( size, size );
+}
+
+/*!
+   Adjust the plot axes scales
+
+   \param oldSize Previous size of the canvas
+   \param newSize New size of the canvas
+*/
+void QwtPlotRescaler::rescale(
+    const QSize &oldSize, const QSize &newSize ) const
+{
+    if ( newSize.isEmpty() )
+        return;
+
+    QwtInterval intervals[QwtPlot::axisCnt];
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+        intervals[axis] = interval( axis );
+
+    const int refAxis = referenceAxis();
+    intervals[refAxis] = expandScale( refAxis, oldSize, newSize );
+
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        if ( aspectRatio( axis ) > 0.0 && axis != refAxis )
+            intervals[axis] = syncScale( axis, intervals[refAxis], newSize );
+    }
+
+    updateScales( intervals );
+}
+
+/*!
+  Calculate the new scale interval of a plot axis
+
+  \param axis Axis index ( see QwtPlot::AxisId )
+  \param oldSize Previous size of the canvas
+  \param newSize New size of the canvas
+
+  \return Calculated new interval for the axis
+*/
+QwtInterval QwtPlotRescaler::expandScale( int axis,
+        const QSize &oldSize, const QSize &newSize ) const
+{
+    const QwtInterval oldInterval = interval( axis );
+
+    QwtInterval expanded = oldInterval;
+    switch ( rescalePolicy() )
+    {
+        case Fixed:
+        {
+            break; // do nothing
+        }
+        case Expanding:
+        {
+            if ( !oldSize.isEmpty() )
+            {
+                double width = oldInterval.width();
+                if ( orientation( axis ) == Qt::Horizontal )
+                    width *= double( newSize.width() ) / oldSize.width();
+                else
+                    width *= double( newSize.height() ) / oldSize.height();
+
+                expanded = expandInterval( oldInterval,
+                    width, expandingDirection( axis ) );
+            }
+            break;
+        }
+        case Fitting:
+        {
+            double dist = 0.0;
+            for ( int ax = 0; ax < QwtPlot::axisCnt; ax++ )
+            {
+                const double d = pixelDist( ax, newSize );
+                if ( d > dist )
+                    dist = d;
+            }
+            if ( dist > 0.0 )
+            {
+                double width;
+                if ( orientation( axis ) == Qt::Horizontal )
+                    width = newSize.width() * dist;
+                else
+                    width = newSize.height() * dist;
+
+                expanded = expandInterval( intervalHint( axis ),
+                    width, expandingDirection( axis ) );
+            }
+            break;
+        }
+    }
+
+    return expanded;
+}
+
+/*!
+   Synchronize an axis scale according to the scale of the reference axis
+
+  \param axis Axis index ( see QwtPlot::AxisId )
+  \param reference Interval of the reference axis
+  \param size Size of the canvas
+*/
+QwtInterval QwtPlotRescaler::syncScale( int axis,
+    const QwtInterval& reference, const QSize &size ) const
+{
+    double dist;
+    if ( orientation( referenceAxis() ) == Qt::Horizontal )
+        dist = reference.width() / size.width();
+    else
+        dist = reference.width() / size.height();
+
+    if ( orientation( axis ) == Qt::Horizontal )
+        dist *= size.width();
+    else
+        dist *= size.height();
+
+    dist /= aspectRatio( axis );
+
+    QwtInterval intv;
+    if ( rescalePolicy() == Fitting )
+        intv = intervalHint( axis );
+    else
+        intv = interval( axis );
+
+    intv = expandInterval( intv, dist, expandingDirection( axis ) );
+
+    return intv;
+}
+
+/*!
+  Return orientation of an axis
+  \param axis Axis index ( see QwtPlot::AxisId )
+*/
+Qt::Orientation QwtPlotRescaler::orientation( int axis ) const
+{
+    if ( axis == QwtPlot::yLeft || axis == QwtPlot::yRight )
+        return Qt::Vertical;
+
+    return Qt::Horizontal;
+}
+
+/*!
+  Return interval of an axis
+  \param axis Axis index ( see QwtPlot::AxisId )
+*/
+QwtInterval QwtPlotRescaler::interval( int axis ) const
+{
+    if ( axis < 0 || axis >= QwtPlot::axisCnt )
+        return QwtInterval();
+
+    const QwtPlot *plt = plot();
+
+    const double v1 = plt->axisScaleDiv( axis )->lowerBound();
+    const double v2 = plt->axisScaleDiv( axis )->upperBound();
+
+    return QwtInterval( v1, v2 ).normalized();
+}
+
+/*!
+  Expand the interval
+
+  \param interval Interval to be expanded
+  \param width Distance to be added to the interval
+  \param direction Direction of the expand operation
+
+  \return Expanded interval
+*/
+QwtInterval QwtPlotRescaler::expandInterval(
+    const QwtInterval &interval, double width,
+    ExpandingDirection direction ) const
+{
+    QwtInterval expanded = interval;
+
+    switch ( direction )
+    {
+        case ExpandUp:
+            expanded.setMinValue( interval.minValue() );
+            expanded.setMaxValue( interval.minValue() + width );
+            break;
+
+        case ExpandDown:
+            expanded.setMaxValue( interval.maxValue() );
+            expanded.setMinValue( interval.maxValue() - width );
+            break;
+
+        case ExpandBoth:
+        default:
+            expanded.setMinValue( interval.minValue() +
+                interval.width() / 2.0 - width / 2.0 );
+            expanded.setMaxValue( expanded.minValue() + width );
+    }
+    return expanded;
+}
+
+double QwtPlotRescaler::pixelDist( int axis, const QSize &size ) const
+{
+    const QwtInterval intv = intervalHint( axis );
+
+    double dist = 0.0;
+    if ( !intv.isNull() )
+    {
+        if ( axis == referenceAxis() )
+            dist = intv.width();
+        else
+        {
+            const double r = aspectRatio( axis );
+            if ( r > 0.0 )
+                dist = intv.width() * r;
+        }
+    }
+
+    if ( dist > 0.0 )
+    {
+        if ( orientation( axis ) == Qt::Horizontal )
+            dist /= size.width();
+        else
+            dist /= size.height();
+    }
+
+    return dist;
+}
+
+/*!
+   Update the axes scales
+
+   \param intervals Scale intervals
+*/
+void QwtPlotRescaler::updateScales(
+    QwtInterval intervals[QwtPlot::axisCnt] ) const
+{
+    if ( d_data->inReplot >= 5 )
+    {
+        return;
+    }
+
+    QwtPlot *plt = const_cast<QwtPlot *>( plot() );
+
+    const bool doReplot = plt->autoReplot();
+    plt->setAutoReplot( false );
+
+    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
+    {
+        if ( axis == referenceAxis() || aspectRatio( axis ) > 0.0 )
+        {
+            double v1 = intervals[axis].minValue();
+            double v2 = intervals[axis].maxValue();
+
+            if ( plt->axisScaleDiv( axis )->lowerBound() >
+                plt->axisScaleDiv( axis )->upperBound() )
+            {
+                qSwap( v1, v2 );
+            }
+
+            if ( d_data->inReplot >= 1 )
+            {
+                d_data->axisData[axis].scaleDiv = *plt->axisScaleDiv( axis );
+            }
+
+            if ( d_data->inReplot >= 2 )
+            {
+                QList<double> ticks[QwtScaleDiv::NTickTypes];
+                for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
+                    ticks[i] = d_data->axisData[axis].scaleDiv.ticks( i );
+
+                plt->setAxisScaleDiv( axis, QwtScaleDiv( v1, v2, ticks ) );
+            }
+            else
+            {
+                plt->setAxisScale( axis, v1, v2 );
+            }
+        }
+    }
+
+    const bool immediatePaint = 
+        plt->canvas()->testPaintAttribute( QwtPlotCanvas::ImmediatePaint );
+    plt->canvas()->setPaintAttribute( QwtPlotCanvas::ImmediatePaint, false );
+
+    plt->setAutoReplot( doReplot );
+
+    d_data->inReplot++;
+    plt->replot();
+    d_data->inReplot--;
+
+    plt->canvas()->setPaintAttribute( 
+        QwtPlotCanvas::ImmediatePaint, immediatePaint );
+}
Index: trunk/BNC/qwt/qwt_plot_rescaler.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_rescaler.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_rescaler.h	(revision 4271)
@@ -0,0 +1,143 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_RESCALER_H
+#define QWT_PLOT_RESCALER_H 1
+
+#include "qwt_global.h"
+#include "qwt_interval.h"
+#include "qwt_plot.h"
+#include <qobject.h>
+
+class QwtPlotCanvas;
+class QwtPlot;
+class QResizeEvent;
+
+/*!
+    \brief QwtPlotRescaler takes care of fixed aspect ratios for plot scales
+
+    QwtPlotRescaler autoadjusts the axes of a QwtPlot according
+    to fixed aspect ratios.
+*/
+
+class QWT_EXPORT QwtPlotRescaler: public QObject
+{
+public:
+    /*!
+      The rescale policy defines how to rescale the reference axis and
+      their depending axes.
+
+      \sa ExpandingDirection, setIntervalHint()
+    */
+    enum RescalePolicy
+    {
+        /*!
+          The interval of the reference axis remains unchanged, when the
+          geometry of the canvas changes. All other axes
+          will be adjusted according to their aspect ratio.
+         */
+        Fixed,
+
+        /*!
+          The interval of the reference axis will be shrinked/expanded,
+          when the geometry of the canvas changes. All other axes
+          will be adjusted according to their aspect ratio.
+
+          The interval, that is represented by one pixel is fixed.
+
+         */
+        Expanding,
+
+        /*!
+          The intervals of the axes are calculated, so that all axes include
+          their interval hint.
+         */
+        Fitting
+    };
+
+    /*!
+       When rescalePolicy() is set to Expanding its direction depends
+       on ExpandingDirection
+     */
+    enum ExpandingDirection
+    {
+        //! The upper limit of the scale is adjusted
+        ExpandUp,
+
+        //! The lower limit of the scale is adjusted
+        ExpandDown,
+
+        //! Both limits of the scale are adjusted
+        ExpandBoth
+    };
+
+    explicit QwtPlotRescaler( QwtPlotCanvas *,
+        int referenceAxis = QwtPlot::xBottom,
+        RescalePolicy = Expanding );
+
+    virtual ~QwtPlotRescaler();
+
+    void setEnabled( bool );
+    bool isEnabled() const;
+
+    void setRescalePolicy( RescalePolicy );
+    RescalePolicy rescalePolicy() const;
+
+    void setExpandingDirection( ExpandingDirection );
+    void setExpandingDirection( int axis, ExpandingDirection );
+    ExpandingDirection expandingDirection( int axis ) const;
+
+    void setReferenceAxis( int axis );
+    int referenceAxis() const;
+
+    void setAspectRatio( double ratio );
+    void setAspectRatio( int axis, double ratio );
+    double aspectRatio( int axis ) const;
+
+    void setIntervalHint( int axis, const QwtInterval& );
+    QwtInterval intervalHint( int axis ) const;
+
+    QwtPlotCanvas *canvas();
+    const QwtPlotCanvas *canvas() const;
+
+    QwtPlot *plot();
+    const QwtPlot *plot() const;
+
+    virtual bool eventFilter( QObject *, QEvent * );
+
+    void rescale() const;
+
+protected:
+    virtual void canvasResizeEvent( QResizeEvent * );
+
+    virtual void rescale( const QSize &oldSize, const QSize &newSize ) const;
+    virtual QwtInterval expandScale( 
+        int axis, const QSize &oldSize, const QSize &newSize ) const;
+
+    virtual QwtInterval syncScale(
+        int axis, const QwtInterval& reference,
+        const QSize &size ) const;
+
+    virtual void updateScales(
+        QwtInterval intervals[QwtPlot::axisCnt] ) const;
+
+    Qt::Orientation orientation( int axis ) const;
+    QwtInterval interval( int axis ) const;
+    QwtInterval expandInterval( const QwtInterval &,
+        double width, ExpandingDirection ) const;
+
+private:
+    double pixelDist( int axis, const QSize & ) const;
+
+    class AxisData;
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_scaleitem.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_scaleitem.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_scaleitem.cpp	(revision 4271)
@@ -0,0 +1,443 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_scaleitem.h"
+#include "qwt_plot.h"
+#include "qwt_plot_canvas.h"
+#include "qwt_scale_map.h"
+#include "qwt_interval.h"
+#include <qpalette.h>
+#include <qpainter.h>
+
+class QwtPlotScaleItem::PrivateData
+{
+public:
+    PrivateData():
+        position( 0.0 ),
+        borderDistance( -1 ),
+        scaleDivFromAxis( true ),
+        scaleDraw( new QwtScaleDraw() )
+    {
+    }
+
+    ~PrivateData()
+    {
+        delete scaleDraw;
+    }
+
+    void updateBorders( const QRectF &,
+        const QwtScaleMap &, const QwtScaleMap & );
+
+    QPalette palette;
+    QFont font;
+    double position;
+    int borderDistance;
+    bool scaleDivFromAxis;
+    QwtScaleDraw *scaleDraw;
+    QRectF canvasRectCache;
+};
+
+void QwtPlotScaleItem::PrivateData::updateBorders( const QRectF &canvasRect,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap )
+{
+    canvasRectCache = canvasRect;
+
+    QwtInterval interval;
+    if ( scaleDraw->orientation() == Qt::Horizontal )
+    {
+        interval.setMinValue( xMap.invTransform( canvasRect.left() ) );
+        interval.setMaxValue( xMap.invTransform( canvasRect.right() - 1 ) );
+    }
+    else
+    {
+        interval.setMinValue( yMap.invTransform( canvasRect.bottom() - 1 ) );
+        interval.setMaxValue( yMap.invTransform( canvasRect.top() ) );
+    }
+
+    QwtScaleDiv scaleDiv = scaleDraw->scaleDiv();
+    scaleDiv.setInterval( interval );
+    scaleDraw->setScaleDiv( scaleDiv );
+}
+/*!
+   \brief Constructor for scale item at the position pos.
+
+   \param alignment In case of QwtScaleDraw::BottomScale or QwtScaleDraw::TopScale
+                    the scale item is corresponding to the xAxis(),
+                    otherwise it corresponds to the yAxis().
+
+   \param pos x or y position, depending on the corresponding axis.
+
+   \sa setPosition(), setAlignment()
+*/
+QwtPlotScaleItem::QwtPlotScaleItem(
+        QwtScaleDraw::Alignment alignment, const double pos ):
+    QwtPlotItem( QwtText( "Scale" ) )
+{
+    d_data = new PrivateData;
+    d_data->position = pos;
+    d_data->scaleDraw->setAlignment( alignment );
+
+    setZ( 11.0 );
+}
+
+//! Destructor
+QwtPlotScaleItem::~QwtPlotScaleItem()
+{
+    delete d_data;
+}
+
+//! \return QwtPlotItem::Rtti_PlotScale
+int QwtPlotScaleItem::rtti() const
+{
+    return QwtPlotItem::Rtti_PlotScale;
+}
+
+/*!
+   \brief Assign a scale division
+
+   When assigning a scaleDiv the scale division won't be synchronized
+   with the corresponding axis anymore.
+
+   \param scaleDiv Scale division
+   \sa scaleDiv(), setScaleDivFromAxis(), isScaleDivFromAxis()
+*/
+void QwtPlotScaleItem::setScaleDiv( const QwtScaleDiv& scaleDiv )
+{
+    d_data->scaleDivFromAxis = false;
+    d_data->scaleDraw->setScaleDiv( scaleDiv );
+}
+
+//! \return Scale division
+const QwtScaleDiv& QwtPlotScaleItem::scaleDiv() const
+{
+    return d_data->scaleDraw->scaleDiv();
+}
+
+/*!
+   Enable/Disable the synchronization of the scale division with
+   the corresponding axis.
+
+   \param on true/false
+   \sa isScaleDivFromAxis()
+*/
+void QwtPlotScaleItem::setScaleDivFromAxis( bool on )
+{
+    if ( on != d_data->scaleDivFromAxis )
+    {
+        d_data->scaleDivFromAxis = on;
+        if ( on )
+        {
+            const QwtPlot *plt = plot();
+            if ( plt )
+            {
+                updateScaleDiv( *plt->axisScaleDiv( xAxis() ),
+                    *plt->axisScaleDiv( yAxis() ) );
+                itemChanged();
+            }
+        }
+    }
+}
+
+/*!
+   \return True, if the synchronization of the scale division with
+           the corresponding axis is enabled.
+   \sa setScaleDiv(), setScaleDivFromAxis()
+*/
+bool QwtPlotScaleItem::isScaleDivFromAxis() const
+{
+    return d_data->scaleDivFromAxis;
+}
+
+/*!
+   Set the palette
+   \sa QwtAbstractScaleDraw::draw(), palette()
+*/
+void QwtPlotScaleItem::setPalette( const QPalette &palette )
+{
+    if ( palette != d_data->palette )
+    {
+        d_data->palette = palette;
+        itemChanged();
+    }
+}
+
+/*!
+   \return palette
+   \sa setPalette()
+*/
+QPalette QwtPlotScaleItem::palette() const
+{
+    return d_data->palette;
+}
+
+/*!
+   Change the tick label font
+   \sa font()
+*/
+void QwtPlotScaleItem::setFont( const QFont &font )
+{
+    if ( font != d_data->font )
+    {
+        d_data->font = font;
+        itemChanged();
+    }
+}
+
+/*!
+   \return tick label font
+   \sa setFont()
+*/
+QFont QwtPlotScaleItem::font() const
+{
+    return d_data->font;
+}
+
+/*!
+  \brief Set a scale draw
+
+  \param scaleDraw object responsible for drawing scales.
+
+  The main use case for replacing the default QwtScaleDraw is
+  to overload QwtAbstractScaleDraw::label, to replace or swallow
+  tick labels.
+
+  \sa scaleDraw()
+*/
+void QwtPlotScaleItem::setScaleDraw( QwtScaleDraw *scaleDraw )
+{
+    if ( scaleDraw == NULL )
+        return;
+
+    if ( scaleDraw != d_data->scaleDraw )
+        delete d_data->scaleDraw;
+
+    d_data->scaleDraw = scaleDraw;
+
+    const QwtPlot *plt = plot();
+    if ( plt )
+    {
+        updateScaleDiv( *plt->axisScaleDiv( xAxis() ),
+            *plt->axisScaleDiv( yAxis() ) );
+    }
+
+    itemChanged();
+}
+
+/*!
+   \return Scale draw
+   \sa setScaleDraw()
+*/
+const QwtScaleDraw *QwtPlotScaleItem::scaleDraw() const
+{
+    return d_data->scaleDraw;
+}
+
+/*!
+   \return Scale draw
+   \sa setScaleDraw()
+*/
+QwtScaleDraw *QwtPlotScaleItem::scaleDraw()
+{
+    return d_data->scaleDraw;
+}
+
+/*!
+   Change the position of the scale
+
+   The position is interpreted as y value for horizontal axes
+   and as x value for vertical axes.
+
+   The border distance is set to -1.
+
+   \param pos New position
+   \sa position(), setAlignment()
+*/
+void QwtPlotScaleItem::setPosition( double pos )
+{
+    if ( d_data->position != pos )
+    {
+        d_data->position = pos;
+        d_data->borderDistance = -1;
+        itemChanged();
+    }
+}
+
+/*!
+   \return Position of the scale
+   \sa setPosition(), setAlignment()
+*/
+double QwtPlotScaleItem::position() const
+{
+    return d_data->position;
+}
+
+/*!
+   \brief Align the scale to the canvas
+
+   If distance is >= 0 the scale will be aligned to a
+   border of the contents rect of the canvas. If
+   alignment() is QwtScaleDraw::LeftScale, the scale will
+   be aligned to the right border, if it is QwtScaleDraw::TopScale
+   it will be aligned to the bottom (and vice versa),
+
+   If distance is < 0 the scale will be at the position().
+
+   \param distance Number of pixels between the canvas border and the
+                   backbone of the scale.
+
+   \sa setPosition(), borderDistance()
+*/
+void QwtPlotScaleItem::setBorderDistance( int distance )
+{
+    if ( distance < 0 )
+        distance = -1;
+
+    if ( distance != d_data->borderDistance )
+    {
+        d_data->borderDistance = distance;
+        itemChanged();
+    }
+}
+
+/*!
+   \return Distance from a canvas border
+   \sa setBorderDistance(), setPosition()
+*/
+int QwtPlotScaleItem::borderDistance() const
+{
+    return d_data->borderDistance;
+}
+
+/*!
+   Change the alignment of the scale
+
+   The alignment sets the orientation of the scale and the position of
+   the ticks:
+
+   - QwtScaleDraw::BottomScale: horizontal, ticks below
+   - QwtScaleDraw::TopScale: horizontal, ticks above
+   - QwtScaleDraw::LeftScale: vertical, ticks left
+   - QwtScaleDraw::RightScale: vertical, ticks right
+
+   For horizontal scales the position corresponds to QwtPlotItem::yAxis(),
+   otherwise to QwtPlotItem::xAxis().
+
+   \sa scaleDraw(), QwtScaleDraw::alignment(), setPosition()
+*/
+void QwtPlotScaleItem::setAlignment( QwtScaleDraw::Alignment alignment )
+{
+    QwtScaleDraw *sd = d_data->scaleDraw;
+    if ( sd->alignment() != alignment )
+    {
+        sd->setAlignment( alignment );
+        itemChanged();
+    }
+}
+
+/*!
+  \brief Draw the scale
+*/
+void QwtPlotScaleItem::draw( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect ) const
+{
+    if ( d_data->scaleDivFromAxis )
+    {
+        if ( canvasRect != d_data->canvasRectCache )
+            d_data->updateBorders( canvasRect, xMap, yMap );
+    }
+
+    QPen pen = painter->pen();
+    pen.setStyle( Qt::SolidLine );
+    painter->setPen( pen );
+
+    QwtScaleDraw *sd = d_data->scaleDraw;
+    if ( sd->orientation() == Qt::Horizontal )
+    {
+        double y;
+        if ( d_data->borderDistance >= 0 )
+        {
+            if ( sd->alignment() == QwtScaleDraw::BottomScale )
+                y = canvasRect.top() + d_data->borderDistance;
+            else
+            {
+                y = canvasRect.bottom() - d_data->borderDistance;
+            }
+
+        }
+        else
+        {
+            y = yMap.transform( d_data->position );
+        }
+
+        if ( y < canvasRect.top() || y > canvasRect.bottom() )
+            return;
+
+        sd->move( canvasRect.left(), y );
+        sd->setLength( canvasRect.width() - 1 );
+        sd->setTransformation( xMap.transformation()->copy() );
+    }
+    else // == Qt::Vertical
+    {
+        double x;
+        if ( d_data->borderDistance >= 0 )
+        {
+            if ( sd->alignment() == QwtScaleDraw::RightScale )
+                x = canvasRect.left() + d_data->borderDistance;
+            else
+            {
+                x = canvasRect.right() - d_data->borderDistance;
+            }
+        }
+        else
+        {
+            x = xMap.transform( d_data->position );
+        }
+        if ( x < canvasRect.left() || x > canvasRect.right() )
+            return;
+
+        sd->move( x, canvasRect.top() );
+        sd->setLength( canvasRect.height() - 1 );
+        sd->setTransformation( yMap.transformation()->copy() );
+    }
+
+    painter->setFont( d_data->font );
+
+    sd->draw( painter, d_data->palette );
+}
+
+/*!
+   \brief Update the item to changes of the axes scale division
+
+   In case of isScaleDivFromAxis(), the scale draw is synchronized
+   to the correspond axis.
+
+   \param xScaleDiv Scale division of the x-axis
+   \param yScaleDiv Scale division of the y-axis
+
+   \sa QwtPlot::updateAxes()
+*/
+
+void QwtPlotScaleItem::updateScaleDiv( const QwtScaleDiv& xScaleDiv,
+    const QwtScaleDiv& yScaleDiv )
+{
+    QwtScaleDraw *sd = d_data->scaleDraw;
+    if ( d_data->scaleDivFromAxis && sd )
+    {
+        sd->setScaleDiv(
+            sd->orientation() == Qt::Horizontal ? xScaleDiv : yScaleDiv );
+
+        const QwtPlot *plt = plot();
+        if ( plt != NULL )
+        {
+            d_data->updateBorders( plt->canvas()->contentsRect(),
+                plt->canvasMap( xAxis() ), plt->canvasMap( yAxis() ) );
+        }
+    }
+}
Index: trunk/BNC/qwt/qwt_plot_scaleitem.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_scaleitem.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_scaleitem.h	(revision 4271)
@@ -0,0 +1,94 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_SCALE_ITEM_H
+#define QWT_PLOT_SCALE_ITEM_H
+
+#include "qwt_global.h"
+#include "qwt_plot_item.h"
+#include "qwt_scale_draw.h"
+
+class QPalette;
+
+/*!
+  \brief A class which draws a scale inside the plot canvas
+
+  QwtPlotScaleItem can be used to draw an axis inside the plot canvas.
+  It might by synchronized to one of the axis of the plot, but can
+  also display its own ticks and labels.
+
+  It is allowed to synchronize the scale item with a disabled axis.
+  In plots with vertical and horizontal scale items, it might be
+  necessary to remove ticks at the intersections, by overloading
+  updateScaleDiv().
+
+  The scale might be at a specific position (f.e 0.0) or it might be
+  aligned to a canvas border.
+
+  \par Example
+  The following example shows how to replace the left axis, by a scale item
+  at the x position 0.0.
+  \verbatim
+QwtPlotScaleItem *scaleItem =
+    new QwtPlotScaleItem(QwtScaleDraw::RightScale, 0.0);
+scaleItem->setFont(plot->axisWidget(QwtPlot::yLeft)->font());
+scaleItem->attach(plot);
+
+plot->enableAxis(QwtPlot::yLeft, false);
+\endverbatim
+*/
+
+class QWT_EXPORT QwtPlotScaleItem: public QwtPlotItem
+{
+public:
+    explicit QwtPlotScaleItem(
+        QwtScaleDraw::Alignment = QwtScaleDraw::BottomScale,
+        const double pos = 0.0 );
+
+    virtual ~QwtPlotScaleItem();
+
+    virtual int rtti() const;
+
+    void setScaleDiv( const QwtScaleDiv& );
+    const QwtScaleDiv& scaleDiv() const;
+
+    void setScaleDivFromAxis( bool on );
+    bool isScaleDivFromAxis() const;
+
+    void setPalette( const QPalette & );
+    QPalette palette() const;
+
+    void setFont( const QFont& );
+    QFont font() const;
+
+    void setScaleDraw( QwtScaleDraw * );
+
+    const QwtScaleDraw *scaleDraw() const;
+    QwtScaleDraw *scaleDraw();
+
+    void setPosition( double pos );
+    double position() const;
+
+    void setBorderDistance( int numPixels );
+    int borderDistance() const;
+
+    void setAlignment( QwtScaleDraw::Alignment );
+
+    virtual void draw( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &rect ) const;
+
+    virtual void updateScaleDiv( const QwtScaleDiv &, const QwtScaleDiv & );
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_seriesitem.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_seriesitem.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_seriesitem.cpp	(revision 4271)
@@ -0,0 +1,90 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_seriesitem.h"
+
+class QwtPlotAbstractSeriesItem::PrivateData
+{
+public:
+    PrivateData():
+        orientation( Qt::Vertical )
+    {
+    }
+
+    Qt::Orientation orientation;
+};
+
+/*!
+  Constructor
+  \param title Title of the curve
+*/
+QwtPlotAbstractSeriesItem::QwtPlotAbstractSeriesItem( const QwtText &title ):
+    QwtPlotItem( title )
+{
+    d_data = new PrivateData();
+}
+
+/*!
+  Constructor
+  \param title Title of the curve
+*/
+QwtPlotAbstractSeriesItem::QwtPlotAbstractSeriesItem( const QString &title ):
+    QwtPlotItem( QwtText( title ) )
+{
+    d_data = new PrivateData();
+}
+
+//! Destructor
+QwtPlotAbstractSeriesItem::~QwtPlotAbstractSeriesItem()
+{
+    delete d_data;
+}
+
+/*!
+  Set the orientation of the item.
+
+  The orientation() might be used in specific way by a plot item.
+  F.e. a QwtPlotCurve uses it to identify how to display the curve
+  int QwtPlotCurve::Steps or QwtPlotCurve::Sticks style.
+
+  \sa orientation()
+*/
+void QwtPlotAbstractSeriesItem::setOrientation( Qt::Orientation orientation )
+{
+    if ( d_data->orientation != orientation )
+    {
+        d_data->orientation = orientation;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Orientation of the plot item
+  \sa setOrientation()
+*/
+Qt::Orientation QwtPlotAbstractSeriesItem::orientation() const
+{
+    return d_data->orientation;
+}
+
+/*!
+  \brief Draw the complete series
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param canvasRect Contents rect of the canvas
+*/
+void QwtPlotAbstractSeriesItem::draw( QPainter *painter,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect ) const
+{
+    drawSeries( painter, xMap, yMap, canvasRect, 0, -1 );
+}
+
Index: trunk/BNC/qwt/qwt_plot_seriesitem.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_seriesitem.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_seriesitem.h	(revision 4271)
@@ -0,0 +1,203 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_SERIES_ITEM_H
+#define QWT_PLOT_SERIES_ITEM_H
+
+#include "qwt_global.h"
+#include "qwt_plot_item.h"
+#include "qwt_scale_div.h"
+#include "qwt_series_data.h"
+
+/*!
+  \brief Base class for plot items representing a series of samples
+*/
+class QWT_EXPORT QwtPlotAbstractSeriesItem: public QwtPlotItem
+{
+public:
+    explicit QwtPlotAbstractSeriesItem( const QString &title = QString::null );
+    explicit QwtPlotAbstractSeriesItem( const QwtText &title );
+
+    virtual ~QwtPlotAbstractSeriesItem();
+
+    void setOrientation( Qt::Orientation );
+    Qt::Orientation orientation() const;
+
+    virtual void draw( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF & ) const;
+
+    /*!
+      Draw a subset of the samples
+
+      \param painter Painter
+      \param xMap Maps x-values into pixel coordinates.
+      \param yMap Maps y-values into pixel coordinates.
+      \param canvasRect Contents rect of the canvas
+      \param from Index of the first point to be painted
+      \param to Index of the last point to be painted. If to < 0 the
+             curve will be painted to its last point.
+    */
+    virtual void drawSeries( QPainter *painter,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const = 0;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+/*!
+  \brief Class template for plot items representing a series of samples
+*/
+template <typename T>
+class QwtPlotSeriesItem: public QwtPlotAbstractSeriesItem
+{
+public:
+    explicit QwtPlotSeriesItem<T>( const QString &title = QString::null );
+    explicit QwtPlotSeriesItem<T>( const QwtText &title );
+
+    virtual ~QwtPlotSeriesItem<T>();
+
+    void setData( QwtSeriesData<T> * );
+
+    QwtSeriesData<T> *data();
+    const QwtSeriesData<T> *data() const;
+
+    size_t dataSize() const;
+    T sample( int index ) const;
+
+    virtual QRectF boundingRect() const;
+    virtual void updateScaleDiv( const QwtScaleDiv &,
+                                 const QwtScaleDiv & );
+
+protected:
+    //! Series
+    QwtSeriesData<T> *d_series;
+};
+
+/*!
+  Constructor
+  \param title Title of the series item
+*/
+template <typename T>
+QwtPlotSeriesItem<T>::QwtPlotSeriesItem( const QString &title ):
+    QwtPlotAbstractSeriesItem( QwtText( title ) ),
+    d_series( NULL )
+{
+}
+
+/*!
+  Constructor
+  \param title Title of the series item
+*/
+template <typename T>
+QwtPlotSeriesItem<T>::QwtPlotSeriesItem( const QwtText &title ):
+    QwtPlotAbstractSeriesItem( title ),
+    d_series( NULL )
+{
+}
+
+//! Destructor
+template <typename T>
+QwtPlotSeriesItem<T>::~QwtPlotSeriesItem()
+{
+    delete d_series;
+}
+
+//! \return the the curve data
+template <typename T>
+inline QwtSeriesData<T> *QwtPlotSeriesItem<T>::data()
+{
+    return d_series;
+}
+
+//! \return the the curve data
+template <typename T>
+inline const QwtSeriesData<T> *QwtPlotSeriesItem<T>::data() const
+{
+    return d_series;
+}
+
+/*!
+    \param index Index
+    \return Sample at position index
+*/
+template <typename T>
+inline T QwtPlotSeriesItem<T>::sample( int index ) const
+{
+    return d_series ? d_series->sample( index ) : T();
+}
+
+/*!
+  Assign a series of samples
+
+  \param data Data
+  \warning The item takes ownership of the data object, deleting
+           it when its not used anymore.
+*/
+template <typename T>
+void QwtPlotSeriesItem<T>::setData( QwtSeriesData<T> *data )
+{
+    if ( d_series != data )
+    {
+        delete d_series;
+        d_series = data;
+        itemChanged();
+    }
+}
+
+/*!
+  Return the size of the data arrays
+  \sa setData()
+*/
+template <typename T>
+size_t QwtPlotSeriesItem<T>::dataSize() const
+{
+    if ( d_series == NULL )
+        return 0;
+
+    return d_series->size();
+}
+
+/*!
+  \return Bounding rectangle of the data.
+  If there is no bounding rect, like for empty data the rectangle is invalid.
+
+  \sa QwtSeriesData<T>::boundingRect(), QRectF::isValid()
+*/
+template <typename T>
+QRectF QwtPlotSeriesItem<T>::boundingRect() const
+{
+    if ( d_series == NULL )
+        return QRectF( 1.0, 1.0, -2.0, -2.0 ); // invalid
+
+    return d_series->boundingRect();
+}
+
+/*!
+   Update the rect of interest according to the current scale ranges
+
+   \param xScaleDiv Scale division of the x-axis
+   \param yScaleDiv Scale division of the y-axis
+
+   \sa QwtSeriesData<T>::setRectOfInterest()
+*/
+template <typename T>
+void QwtPlotSeriesItem<T>::updateScaleDiv( 
+    const QwtScaleDiv &xScaleDiv, const QwtScaleDiv &yScaleDiv )
+{
+    const QRectF rect = QRectF(
+        xScaleDiv.lowerBound(), yScaleDiv.lowerBound(),
+        xScaleDiv.range(), yScaleDiv.range() );
+
+    d_series->setRectOfInterest( rect );
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_spectrocurve.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_spectrocurve.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_spectrocurve.cpp	(revision 4271)
@@ -0,0 +1,300 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_spectrocurve.h"
+#include "qwt_color_map.h"
+#include "qwt_scale_map.h"
+#include "qwt_painter.h"
+#include <qpainter.h>
+
+class QwtPlotSpectroCurve::PrivateData
+{
+public:
+    PrivateData():
+        colorRange( 0.0, 1000.0 ),
+        penWidth(0.0),
+        paintAttributes( QwtPlotSpectroCurve::ClipPoints )
+    {
+        colorMap = new QwtLinearColorMap();
+    }
+
+    ~PrivateData()
+    {
+        delete colorMap;
+    }
+
+    QwtColorMap *colorMap;
+    QwtInterval colorRange;
+    QVector<QRgb> colorTable;
+    double penWidth;
+    QwtPlotSpectroCurve::PaintAttributes paintAttributes;
+};
+
+/*!
+  Constructor
+  \param title Title of the curve
+*/
+QwtPlotSpectroCurve::QwtPlotSpectroCurve( const QwtText &title ):
+    QwtPlotSeriesItem<QwtPoint3D>( title )
+{
+    init();
+}
+
+/*!
+  Constructor
+  \param title Title of the curve
+*/
+QwtPlotSpectroCurve::QwtPlotSpectroCurve( const QString &title ):
+    QwtPlotSeriesItem<QwtPoint3D>( QwtText( title ) )
+{
+    init();
+}
+
+//! Destructor
+QwtPlotSpectroCurve::~QwtPlotSpectroCurve()
+{
+    delete d_data;
+}
+
+/*!
+  \brief Initialize data members
+*/
+void QwtPlotSpectroCurve::init()
+{
+    setItemAttribute( QwtPlotItem::Legend );
+    setItemAttribute( QwtPlotItem::AutoScale );
+
+    d_data = new PrivateData;
+    d_series = new QwtPoint3DSeriesData();
+
+    setZ( 20.0 );
+}
+
+//! \return QwtPlotItem::Rtti_PlotSpectroCurve
+int QwtPlotSpectroCurve::rtti() const
+{
+    return QwtPlotItem::Rtti_PlotSpectroCurve;
+}
+
+/*!
+  Specify an attribute how to draw the curve
+
+  \param attribute Paint attribute
+  \param on On/Off
+  /sa PaintAttribute, testPaintAttribute()
+*/
+void QwtPlotSpectroCurve::setPaintAttribute( PaintAttribute attribute, bool on )
+{
+    if ( on )
+        d_data->paintAttributes |= attribute;
+    else
+        d_data->paintAttributes &= ~attribute;
+}
+
+/*!
+    \brief Return the current paint attributes
+    \sa PaintAttribute, setPaintAttribute()
+*/
+bool QwtPlotSpectroCurve::testPaintAttribute( PaintAttribute attribute ) const
+{
+    return ( d_data->paintAttributes & attribute );
+}
+
+/*!
+  Initialize data with an array of samples.
+  \param samples Vector of points
+*/
+void QwtPlotSpectroCurve::setSamples( const QVector<QwtPoint3D> &samples )
+{
+    delete d_series;
+    d_series = new QwtPoint3DSeriesData( samples );
+    itemChanged();
+}
+
+/*!
+  Change the color map
+
+  Often it is useful to display the mapping between intensities and
+  colors as an additional plot axis, showing a color bar.
+
+  \param colorMap Color Map
+
+  \sa colorMap(), setColorRange(), QwtColorMap::color(),
+      QwtScaleWidget::setColorBarEnabled(), QwtScaleWidget::setColorMap()
+*/
+void QwtPlotSpectroCurve::setColorMap( QwtColorMap *colorMap )
+{
+    if ( colorMap != d_data->colorMap )
+    {
+        delete d_data->colorMap;
+        d_data->colorMap = colorMap;
+    }
+
+    itemChanged();
+}
+
+/*!
+   \return Color Map used for mapping the intensity values to colors
+   \sa setColorMap(), setColorRange(), QwtColorMap::color()
+*/
+const QwtColorMap *QwtPlotSpectroCurve::colorMap() const
+{
+    return d_data->colorMap;
+}
+
+/*!
+   Set the value interval, that corresponds to the color map
+
+   \param interval interval.minValue() corresponds to 0.0,
+                   interval.maxValue() to 1.0 on the color map.
+
+   \sa colorRange(), setColorMap(), QwtColorMap::color()
+*/
+void QwtPlotSpectroCurve::setColorRange( const QwtInterval &interval )
+{
+    if ( interval != d_data->colorRange )
+    {
+        d_data->colorRange = interval;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Value interval, that corresponds to the color map
+  \sa setColorRange(), setColorMap(), QwtColorMap::color()
+*/
+QwtInterval &QwtPlotSpectroCurve::colorRange() const
+{
+    return d_data->colorRange;
+}
+
+/*!
+  Assign a pen width
+
+  \param penWidth New pen width
+  \sa penWidth()
+*/
+void QwtPlotSpectroCurve::setPenWidth(double penWidth)
+{
+    if ( penWidth < 0.0 )
+        penWidth = 0.0;
+
+    if ( d_data->penWidth != penWidth )
+    {
+        d_data->penWidth = penWidth;
+        itemChanged();
+    }
+}
+
+/*!
+  \return Pen width used to draw a dot
+  \sa setPenWidth()
+*/
+double QwtPlotSpectroCurve::penWidth() const
+{
+    return d_data->penWidth;
+}
+
+/*!
+  Draw a subset of the points
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param canvasRect Contents rect of the canvas
+  \param from Index of the first sample to be painted
+  \param to Index of the last sample to be painted. If to < 0 the
+         series will be painted to its last sample.
+
+  \sa drawDots()
+*/
+void QwtPlotSpectroCurve::drawSeries( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    if ( !painter || dataSize() <= 0 )
+        return;
+
+    if ( to < 0 )
+        to = dataSize() - 1;
+
+    if ( from < 0 )
+        from = 0;
+
+    if ( from >= to )
+        return;
+
+    drawDots( painter, xMap, yMap, canvasRect, from, to );
+}
+
+/*!
+  Draw a subset of the points
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param canvasRect Contents rect of the canvas
+  \param from Index of the first sample to be painted
+  \param to Index of the last sample to be painted. If to < 0 the
+         series will be painted to its last sample.
+
+  \sa drawSeries()
+*/
+void QwtPlotSpectroCurve::drawDots( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect, int from, int to ) const
+{
+    if ( !d_data->colorRange.isValid() )
+        return;
+
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    const QwtColorMap::Format format = d_data->colorMap->format();
+    if ( format == QwtColorMap::Indexed )
+        d_data->colorTable = d_data->colorMap->colorTable( d_data->colorRange );
+
+    for ( int i = from; i <= to; i++ )
+    {
+        const QwtPoint3D sample = d_series->sample( i );
+
+        double xi = xMap.transform( sample.x() );
+        double yi = yMap.transform( sample.y() );
+        if ( doAlign )
+        {
+            xi = qRound( xi );
+            yi = qRound( yi );
+        }
+
+        if ( d_data->paintAttributes & QwtPlotSpectroCurve::ClipPoints )
+        {
+            if ( !canvasRect.contains( xi, yi ) )
+                continue;
+        }
+
+        if ( format == QwtColorMap::RGB )
+        {
+            const QRgb rgb = d_data->colorMap->rgb(
+                d_data->colorRange, sample.z() );
+
+            painter->setPen( QPen( QColor( rgb ), d_data->penWidth ) );
+        }
+        else
+        {
+            const unsigned char index = d_data->colorMap->colorIndex(
+                d_data->colorRange, sample.z() );
+
+            painter->setPen( QPen( QColor( d_data->colorTable[index] ), 
+                d_data->penWidth ) );
+        }
+
+        QwtPainter::drawPoint( painter, QPointF( xi, yi ) );
+    }
+
+    d_data->colorTable.clear();
+}
Index: trunk/BNC/qwt/qwt_plot_spectrocurve.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_spectrocurve.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_spectrocurve.h	(revision 4271)
@@ -0,0 +1,76 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_CURVE_3D_H
+#define QWT_PLOT_CURVE_3D_H
+
+#include "qwt_global.h"
+#include "qwt_plot_seriesitem.h"
+#include "qwt_series_data.h"
+
+class QwtSymbol;
+class QwtColorMap;
+
+/*!
+    \brief Curve that displays 3D points as dots, where the z coordinate is
+           mapped to a color.
+*/
+class QWT_EXPORT QwtPlotSpectroCurve: public QwtPlotSeriesItem<QwtPoint3D>
+{
+public:
+    //! Paint attributes
+    enum PaintAttribute
+    {
+        //! Clip points outside the canvas rectangle
+        ClipPoints = 1
+    };
+
+    //! Paint attributes
+    typedef QFlags<PaintAttribute> PaintAttributes;
+
+    explicit QwtPlotSpectroCurve( const QString &title = QString::null );
+    explicit QwtPlotSpectroCurve( const QwtText &title );
+
+    virtual ~QwtPlotSpectroCurve();
+
+    virtual int rtti() const;
+
+    void setPaintAttribute( PaintAttribute, bool on = true );
+    bool testPaintAttribute( PaintAttribute ) const;
+
+    void setSamples( const QVector<QwtPoint3D> & );
+
+    void setColorMap( QwtColorMap * );
+    const QwtColorMap *colorMap() const;
+
+    void setColorRange( const QwtInterval & );
+    QwtInterval & colorRange() const;
+
+    virtual void drawSeries( QPainter *,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+    void setPenWidth(double width);
+    double penWidth() const;
+
+protected:
+    virtual void drawDots( QPainter *,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &canvasRect, int from, int to ) const;
+
+private:
+    void init();
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotSpectroCurve::PaintAttributes )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_spectrogram.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_spectrogram.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_spectrogram.cpp	(revision 4271)
@@ -0,0 +1,665 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_spectrogram.h"
+#include "qwt_painter.h"
+#include "qwt_interval.h"
+#include "qwt_scale_map.h"
+#include "qwt_color_map.h"
+#include <qimage.h>
+#include <qpen.h>
+#include <qpainter.h>
+#include <qmath.h>
+#include <qalgorithms.h>
+#if QT_VERSION >= 0x040400
+#include <qthread.h>
+#include <qfuture.h>
+#include <qtconcurrentrun.h>
+#endif
+
+class QwtPlotSpectrogram::PrivateData
+{
+public:
+    PrivateData():
+        data( NULL ),
+        renderThreadCount( 1 )
+    {
+        colorMap = new QwtLinearColorMap();
+        displayMode = ImageMode;
+
+        conrecFlags = QwtRasterData::IgnoreAllVerticesOnLevel;
+        conrecFlags |= QwtRasterData::IgnoreOutOfRange;
+    }
+    ~PrivateData()
+    {
+        delete data;
+        delete colorMap;
+    }
+
+    QwtRasterData *data;
+    QwtColorMap *colorMap;
+    DisplayModes displayMode;
+
+    uint renderThreadCount;
+
+    QList<double> contourLevels;
+    QPen defaultContourPen;
+    QwtRasterData::ConrecFlags conrecFlags;
+};
+
+/*!
+   Sets the following item attributes:
+   - QwtPlotItem::AutoScale: true
+   - QwtPlotItem::Legend:    false
+
+   The z value is initialized by 8.0.
+
+   \param title Title
+
+   \sa QwtPlotItem::setItemAttribute(), QwtPlotItem::setZ()
+*/
+QwtPlotSpectrogram::QwtPlotSpectrogram( const QString &title ):
+    QwtPlotRasterItem( title )
+{
+    d_data = new PrivateData();
+
+    setItemAttribute( QwtPlotItem::AutoScale, true );
+    setItemAttribute( QwtPlotItem::Legend, false );
+
+    setZ( 8.0 );
+}
+
+//! Destructor
+QwtPlotSpectrogram::~QwtPlotSpectrogram()
+{
+    delete d_data;
+}
+
+//! \return QwtPlotItem::Rtti_PlotSpectrogram
+int QwtPlotSpectrogram::rtti() const
+{
+    return QwtPlotItem::Rtti_PlotSpectrogram;
+}
+
+/*!
+   The display mode controls how the raster data will be represented.
+
+   \param mode Display mode
+   \param on On/Off
+
+   The default setting enables ImageMode.
+
+   \sa DisplayMode, displayMode()
+*/
+void QwtPlotSpectrogram::setDisplayMode( DisplayMode mode, bool on )
+{
+    if ( on != bool( mode & d_data->displayMode ) )
+    {
+        if ( on )
+            d_data->displayMode |= mode;
+        else
+            d_data->displayMode &= ~mode;
+    }
+
+    itemChanged();
+}
+
+/*!
+   The display mode controls how the raster data will be represented.
+
+   \param mode Display mode
+   \return true if mode is enabled
+*/
+bool QwtPlotSpectrogram::testDisplayMode( DisplayMode mode ) const
+{
+    return ( d_data->displayMode & mode );
+}
+
+/*!
+   Rendering an image from the raster data can often be done
+   parallel on a multicore system.
+
+   \param numThreads Number of threads to be used for rendering.
+                     If numThreads is set to 0, the system specific
+                     ideal thread count is used.
+
+   The default thread count is 1 ( = no additional threads )
+
+   \warning Rendering in multiple threads is only supported for Qt >= 4.4
+   \sa renderThreadCount(), renderImage(), renderTile()
+*/
+void QwtPlotSpectrogram::setRenderThreadCount( uint numThreads )
+{
+    d_data->renderThreadCount = numThreads;
+}
+
+/*!
+   \return Number of threads to be used for rendering.
+           If numThreads is set to 0, the system specific
+           ideal thread count is used.
+
+   \warning Rendering in multiple threads is only supported for Qt >= 4.4
+   \sa setRenderThreadCount(), renderImage(), renderTile()
+*/
+uint QwtPlotSpectrogram::renderThreadCount() const
+{
+    return d_data->renderThreadCount;
+}
+
+/*!
+  Change the color map
+
+  Often it is useful to display the mapping between intensities and
+  colors as an additional plot axis, showing a color bar.
+
+  \param colorMap Color Map
+
+  \sa colorMap(), QwtScaleWidget::setColorBarEnabled(),
+      QwtScaleWidget::setColorMap()
+*/
+void QwtPlotSpectrogram::setColorMap( QwtColorMap *colorMap )
+{
+    if ( d_data->colorMap != colorMap )
+    {
+        delete d_data->colorMap;
+        d_data->colorMap = colorMap;
+    }
+
+    invalidateCache();
+    itemChanged();
+}
+
+/*!
+   \return Color Map used for mapping the intensity values to colors
+   \sa setColorMap()
+*/
+const QwtColorMap *QwtPlotSpectrogram::colorMap() const
+{
+    return d_data->colorMap;
+}
+
+/*!
+   \brief Set the default pen for the contour lines
+
+   If the spectrogram has a valid default contour pen
+   a contour line is painted using the default contour pen.
+   Otherwise (pen.style() == Qt::NoPen) the pen is calculated
+   for each contour level using contourPen().
+
+   \sa defaultContourPen(), contourPen()
+*/
+void QwtPlotSpectrogram::setDefaultContourPen( const QPen &pen )
+{
+    if ( pen != d_data->defaultContourPen )
+    {
+        d_data->defaultContourPen = pen;
+        itemChanged();
+    }
+}
+
+/*!
+   \return Default contour pen
+   \sa setDefaultContourPen()
+*/
+QPen QwtPlotSpectrogram::defaultContourPen() const
+{
+    return d_data->defaultContourPen;
+}
+
+/*!
+   \brief Calculate the pen for a contour line
+
+   The color of the pen is the color for level calculated by the color map
+
+   \param level Contour level
+   \return Pen for the contour line
+   \note contourPen is only used if defaultContourPen().style() == Qt::NoPen
+
+   \sa setDefaultContourPen(), setColorMap(), setContourLevels()
+*/
+QPen QwtPlotSpectrogram::contourPen( double level ) const
+{
+    if ( d_data->data == NULL || d_data->colorMap == NULL )
+        return QPen();
+
+    const QwtInterval intensityRange = d_data->data->interval(Qt::ZAxis);
+    const QColor c( d_data->colorMap->rgb( intensityRange, level ) );
+
+    return QPen( c );
+}
+
+/*!
+   Modify an attribute of the CONREC algorithm, used to calculate
+   the contour lines.
+
+   \param flag CONREC flag
+   \param on On/Off
+
+   \sa testConrecFlag(), renderContourLines(),
+       QwtRasterData::contourLines()
+*/
+void QwtPlotSpectrogram::setConrecFlag(
+    QwtRasterData::ConrecFlag flag, bool on )
+{
+    if ( bool( d_data->conrecFlags & flag ) == on )
+        return;
+
+    if ( on )
+        d_data->conrecFlags |= flag;
+    else
+        d_data->conrecFlags &= ~flag;
+
+    itemChanged();
+}
+
+/*!
+   Test an attribute of the CONREC algorithm, used to calculate
+   the contour lines.
+
+   \param flag CONREC flag
+   \return true, is enabled
+
+   \sa setConrecClag(), renderContourLines(),
+       QwtRasterData::contourLines()
+*/
+bool QwtPlotSpectrogram::testConrecFlag(
+    QwtRasterData::ConrecFlag flag ) const
+{
+    return d_data->conrecFlags & flag;
+}
+
+/*!
+   Set the levels of the contour lines
+
+   \param levels Values of the contour levels
+   \sa contourLevels(), renderContourLines(),
+       QwtRasterData::contourLines()
+
+   \note contourLevels returns the same levels but sorted.
+*/
+void QwtPlotSpectrogram::setContourLevels( const QList<double> &levels )
+{
+    d_data->contourLevels = levels;
+    qSort( d_data->contourLevels );
+    itemChanged();
+}
+
+/*!
+   \brief Return the levels of the contour lines.
+
+   The levels are sorted in increasing order.
+
+   \sa contourLevels(), renderContourLines(),
+       QwtRasterData::contourLines()
+*/
+QList<double> QwtPlotSpectrogram::contourLevels() const
+{
+    return d_data->contourLevels;
+}
+
+/*!
+  Set the data to be displayed
+
+  \param data Spectrogram Data
+  \sa data()
+*/
+void QwtPlotSpectrogram::setData( QwtRasterData *data )
+{
+    if ( data != d_data->data )
+    {
+        delete d_data->data;
+        d_data->data = data;
+
+        invalidateCache();
+        itemChanged();
+    }
+}
+
+/*!
+  \return Spectrogram data
+  \sa setData()
+*/
+const QwtRasterData *QwtPlotSpectrogram::data() const
+{
+    return d_data->data;
+}
+
+/*!
+  \return Spectrogram data
+  \sa setData()
+*/
+QwtRasterData *QwtPlotSpectrogram::data()
+{
+    return d_data->data;
+}
+
+/*!
+   \return Bounding interval for an axis
+
+   The default implementation returns the interval of the
+   associated raster data object.
+
+   \param axis X, Y, or Z axis
+   \sa QwtRasterData::interval()
+*/
+QwtInterval QwtPlotSpectrogram::interval(Qt::Axis axis) const
+{
+    if ( d_data->data == NULL )
+        return QwtInterval();
+
+    return d_data->data->interval( axis );
+}
+
+/*!
+   \brief Pixel hint
+
+   The geometry of a pixel is used to calculated the resolution and
+   alignment of the rendered image. 
+
+   The default implementation returns data()->pixelHint( rect );
+
+   \param area In most implementations the resolution of the data doesn't
+               depend on the requested area.
+
+   \return Bounding rectangle of a pixel
+
+   \sa QwtPlotRasterItem::pixelHint(), QwtRasterData::pixelHint(), 
+       render(), renderImage()
+*/
+QRectF QwtPlotSpectrogram::pixelHint( const QRectF &area ) const
+{
+    if ( d_data->data == NULL )
+        return QRectF();
+
+    return d_data->data->pixelHint( area );
+}
+
+/*!
+   \brief Render an image from data and color map.
+
+   For each pixel of rect the value is mapped into a color.
+
+  \param xMap X-Scale Map
+  \param yMap Y-Scale Map
+  \param area Requested area for the image in scale coordinates
+  \param imageSize Size of the requested image
+
+   \return A QImage::Format_Indexed8 or QImage::Format_ARGB32 depending
+           on the color map.
+
+   \sa QwtRasterData::value(), QwtColorMap::rgb(),
+       QwtColorMap::colorIndex()
+*/
+QImage QwtPlotSpectrogram::renderImage(
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &area, const QSize &imageSize ) const
+{
+    if ( imageSize.isEmpty() || d_data->data == NULL 
+        || d_data->colorMap == NULL )
+    {
+        return QImage();
+    }
+
+    const QwtInterval intensityRange = d_data->data->interval( Qt::ZAxis );
+    if ( !intensityRange.isValid() )
+        return QImage();
+
+    QImage::Format format = ( d_data->colorMap->format() == QwtColorMap::RGB )
+        ? QImage::Format_ARGB32 : QImage::Format_Indexed8;
+
+    QImage image( imageSize, format );
+
+    if ( d_data->colorMap->format() == QwtColorMap::Indexed )
+        image.setColorTable( d_data->colorMap->colorTable( intensityRange ) );
+
+    d_data->data->initRaster( area, image.size() );
+
+#if QT_VERSION >= 0x040400 && !defined(QT_NO_QFUTURE)
+    uint numThreads = d_data->renderThreadCount;
+
+    if ( numThreads <= 0 )
+        numThreads = QThread::idealThreadCount();
+
+    if ( numThreads <= 0 )
+        numThreads = 1;
+
+    const int numRows = imageSize.height() / numThreads;
+
+    QList< QFuture<void> > futures;
+    for ( uint i = 0; i < numThreads; i++ )
+    {
+        QRect tile( 0, i * numRows, image.width(), numRows );
+        if ( i == numThreads - 1 )
+        {
+            tile.setHeight( image.height() - i * numRows );
+            renderTile( xMap, yMap, tile, &image );
+        }
+        else
+        {
+            futures += QtConcurrent::run(
+                this, &QwtPlotSpectrogram::renderTile,
+                xMap, yMap, tile, &image );
+        }
+    }
+    for ( int i = 0; i < futures.size(); i++ )
+        futures[i].waitForFinished();
+
+#else // QT_VERSION < 0x040400
+    const QRect tile( 0, 0, image.width(), image.height() );
+    renderTile( xMap, yMap, tile, &image );
+#endif
+
+    d_data->data->discardRaster();
+
+    return image;
+}
+
+/*!
+    \brief Render a tile of an image.
+
+    Rendering in tiles can be used to composite an image in parallel
+    threads.
+
+    \param xMap X-Scale Map
+    \param yMap Y-Scale Map
+    \param tile Geometry of the tile in image coordinates
+    \param image Image to be rendered
+*/
+void QwtPlotSpectrogram::renderTile(
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRect &tile, QImage *image ) const
+{
+    const QwtInterval range = d_data->data->interval( Qt::ZAxis );
+    if ( !range.isValid() )
+        return;
+
+    if ( d_data->colorMap->format() == QwtColorMap::RGB )
+    {
+        for ( int y = tile.top(); y <= tile.bottom(); y++ )
+        {
+            const double ty = yMap.invTransform( y );
+
+            QRgb *line = ( QRgb * )image->scanLine( y );
+            line += tile.left();
+
+            for ( int x = tile.left(); x <= tile.right(); x++ )
+            {
+                const double tx = xMap.invTransform( x );
+
+                *line++ = d_data->colorMap->rgb( range,
+                    d_data->data->value( tx, ty ) );
+            }
+        }
+    }
+    else if ( d_data->colorMap->format() == QwtColorMap::Indexed )
+    {
+        for ( int y = tile.top(); y <= tile.bottom(); y++ )
+        {
+            const double ty = yMap.invTransform( y );
+
+            unsigned char *line = image->scanLine( y );
+            line += tile.left();
+
+            for ( int x = tile.left(); x <= tile.right(); x++ )
+            {
+                const double tx = xMap.invTransform( x );
+
+                *line++ = d_data->colorMap->colorIndex( range,
+                    d_data->data->value( tx, ty ) );
+            }
+        }
+    }
+}
+
+/*!
+   \brief Return the raster to be used by the CONREC contour algorithm.
+
+   A larger size will improve the precisision of the CONREC algorithm,
+   but will slow down the time that is needed to calculate the lines.
+
+   The default implementation returns rect.size() / 2 bounded to
+   the resolution depending on pixelSize().
+
+   \param area Rect, where to calculate the contour lines
+   \param rect Rect in pixel coordinates, where to paint the contour lines
+   \return Raster to be used by the CONREC contour algorithm.
+
+   \note The size will be bounded to rect.size().
+
+   \sa drawContourLines(), QwtRasterData::contourLines()
+*/
+QSize QwtPlotSpectrogram::contourRasterSize( 
+    const QRectF &area, const QRect &rect ) const
+{
+    QSize raster = rect.size() / 2;
+
+    const QRectF pixelRect = pixelHint( area );
+    if ( !pixelRect.isEmpty() )
+    {
+        const QSize res( qCeil( rect.width() / pixelRect.width() ),
+            qCeil( rect.height() / pixelRect.height() ) );
+        raster = raster.boundedTo( res );
+    }
+
+    return raster;
+}
+
+/*!
+   Calculate contour lines
+
+   \param rect Rectangle, where to calculate the contour lines
+   \param raster Raster, used by the CONREC algorithm
+
+   \sa contourLevels(), setConrecFlag(),
+       QwtRasterData::contourLines()
+*/
+QwtRasterData::ContourLines QwtPlotSpectrogram::renderContourLines(
+    const QRectF &rect, const QSize &raster ) const
+{
+    if ( d_data->data == NULL )
+        return QwtRasterData::ContourLines();
+
+    return d_data->data->contourLines( rect, raster,
+        d_data->contourLevels, d_data->conrecFlags );
+}
+
+/*!
+   Paint the contour lines
+
+   \param painter Painter
+   \param xMap Maps x-values into pixel coordinates.
+   \param yMap Maps y-values into pixel coordinates.
+   \param contourLines Contour lines
+
+   \sa renderContourLines(), defaultContourPen(), contourPen()
+*/
+void QwtPlotSpectrogram::drawContourLines( QPainter *painter,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QwtRasterData::ContourLines &contourLines ) const
+{
+    if ( d_data->data == NULL )
+        return;
+
+    const QwtInterval intensityRange = d_data->data->interval( Qt::ZAxis );
+
+    const int numLevels = d_data->contourLevels.size();
+    for ( int l = 0; l < numLevels; l++ )
+    {
+        const double level = d_data->contourLevels[l];
+
+        QPen pen = defaultContourPen();
+        if ( pen.style() == Qt::NoPen )
+            pen = contourPen( level );
+
+        if ( pen.style() == Qt::NoPen )
+            continue;
+
+        painter->setPen( pen );
+
+        const QPolygonF &lines = contourLines[level];
+        for ( int i = 0; i < lines.size(); i += 2 )
+        {
+            const QPointF p1( xMap.transform( lines[i].x() ),
+                yMap.transform( lines[i].y() ) );
+            const QPointF p2( xMap.transform( lines[i+1].x() ),
+                yMap.transform( lines[i+1].y() ) );
+
+            QwtPainter::drawLine( painter, p1, p2 );
+        }
+    }
+}
+
+/*!
+  \brief Draw the spectrogram
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param canvasRect Contents rect of the canvas in painter coordinates
+
+  \sa setDisplayMode(), renderImage(),
+      QwtPlotRasterItem::draw(), drawContourLines()
+*/
+void QwtPlotSpectrogram::draw( QPainter *painter,
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+    const QRectF &canvasRect ) const
+{
+    if ( d_data->displayMode & ImageMode )
+        QwtPlotRasterItem::draw( painter, xMap, yMap, canvasRect );
+
+    if ( d_data->displayMode & ContourMode )
+    {
+        // Add some pixels at the borders
+        const int margin = 2;
+        QRectF rasterRect( canvasRect.x() - margin, canvasRect.y() - margin,
+            canvasRect.width() + 2 * margin, canvasRect.height() + 2 * margin );
+
+        QRectF area = QwtScaleMap::invTransform( xMap, yMap, rasterRect );
+
+        const QRectF br = boundingRect();
+        if ( br.isValid() )
+        {
+            area &= br;
+            if ( area.isEmpty() )
+                return;
+
+            rasterRect = QwtScaleMap::transform( xMap, yMap, area );
+        }
+
+        QSize raster = contourRasterSize( area, rasterRect.toRect() );
+        raster = raster.boundedTo( rasterRect.toRect().size() );
+        if ( raster.isValid() )
+        {
+            const QwtRasterData::ContourLines lines =
+                renderContourLines( area, raster );
+
+            drawContourLines( painter, xMap, yMap, lines );
+        }
+    }
+}
Index: trunk/BNC/qwt/qwt_plot_spectrogram.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_spectrogram.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_spectrogram.h	(revision 4271)
@@ -0,0 +1,115 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_SPECTROGRAM_H
+#define QWT_PLOT_SPECTROGRAM_H
+
+#include "qwt_global.h"
+#include "qwt_raster_data.h"
+#include "qwt_plot_rasteritem.h"
+#include <qlist.h>
+
+class QwtColorMap;
+
+/*!
+  \brief A plot item, which displays a spectrogram
+
+  A spectrogram displays threedimenional data, where the 3rd dimension
+  ( the intensity ) is displayed using colors. The colors are calculated
+  from the values using a color map.
+
+  In ContourMode contour lines are painted for the contour levels.
+
+  \image html spectrogram3.png
+
+  \sa QwtRasterData, QwtColorMap
+*/
+
+class QWT_EXPORT QwtPlotSpectrogram: public QwtPlotRasterItem
+{
+public:
+    /*!
+      The display mode controls how the raster data will be represented.
+      \sa setDisplayMode(), testDisplayMode()
+    */
+
+    enum DisplayMode
+    {
+        //! The values are mapped to colors using a color map.
+        ImageMode = 0x01,
+
+        //! The data is displayed using contour lines
+        ContourMode = 0x02
+    };
+
+    //! Display modes
+    typedef QFlags<DisplayMode> DisplayModes;
+
+    explicit QwtPlotSpectrogram( const QString &title = QString::null );
+    virtual ~QwtPlotSpectrogram();
+
+    void setRenderThreadCount( uint numThreads );
+    uint renderThreadCount() const;
+
+    void setDisplayMode( DisplayMode, bool on = true );
+    bool testDisplayMode( DisplayMode ) const;
+
+    void setData( QwtRasterData *data );
+    const QwtRasterData *data() const;
+    QwtRasterData *data();
+
+    void setColorMap( QwtColorMap * );
+    const QwtColorMap *colorMap() const;
+
+    virtual QwtInterval interval(Qt::Axis) const;
+    virtual QRectF pixelHint( const QRectF & ) const;
+
+    void setDefaultContourPen( const QPen & );
+    QPen defaultContourPen() const;
+
+    virtual QPen contourPen( double level ) const;
+
+    void setConrecFlag( QwtRasterData::ConrecFlag, bool on );
+    bool testConrecFlag( QwtRasterData::ConrecFlag ) const;
+
+    void setContourLevels( const QList<double> & );
+    QList<double> contourLevels() const;
+
+    virtual int rtti() const;
+
+    virtual void draw( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &rect ) const;
+
+protected:
+    virtual QImage renderImage(
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRectF &area, const QSize &imageSize ) const;
+
+    virtual QSize contourRasterSize(
+        const QRectF &, const QRect & ) const;
+
+    virtual QwtRasterData::ContourLines renderContourLines(
+        const QRectF &rect, const QSize &raster ) const;
+
+    virtual void drawContourLines( QPainter *p,
+        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QwtRasterData::ContourLines& lines ) const;
+
+    void renderTile( const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+        const QRect &imageRect, QImage *image ) const;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotSpectrogram::DisplayModes )
+
+#endif
Index: trunk/BNC/qwt/qwt_plot_xml.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_xml.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_xml.cpp	(revision 4271)
@@ -0,0 +1,41 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot.h"
+
+/*!
+  This method is intended for manipulating the plot widget
+  from a specific editor in the Qwt designer plugin.
+
+  \warning The plot editor has never been implemented.
+*/
+void QwtPlot::applyProperties( const QString & /* xmlDocument */ )
+{
+#if 0
+    // Temporary dummy code, for designer tests
+    setTitle( xmlDocument );
+    replot();
+#endif
+}
+
+/*!
+  This method is intended for manipulating the plot widget
+  from a specific editor in the Qwt designer plugin.
+
+  \warning The plot editor has never been implemented.
+*/
+QString QwtPlot::grabProperties() const
+{
+#if 0
+    // Temporary dummy code, for designer tests
+    return title().text();
+#else
+    return QString::null;
+#endif
+}
Index: trunk/BNC/qwt/qwt_plot_zoomer.cpp
===================================================================
--- trunk/BNC/qwt/qwt_plot_zoomer.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_zoomer.cpp	(revision 4271)
@@ -0,0 +1,607 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_plot_zoomer.h"
+#include "qwt_plot.h"
+#include "qwt_plot_canvas.h"
+#include "qwt_scale_div.h"
+#include "qwt_picker_machine.h"
+#include <qalgorithms.h>
+
+class QwtPlotZoomer::PrivateData
+{
+public:
+    uint zoomRectIndex;
+    QStack<QRectF> zoomStack;
+
+    int maxStackDepth;
+};
+
+/*!
+  \brief Create a zoomer for a plot canvas.
+
+  The zoomer is set to those x- and y-axis of the parent plot of the
+  canvas that are enabled. If both or no x-axis are enabled, the picker
+  is set to QwtPlot::xBottom. If both or no y-axis are
+  enabled, it is set to QwtPlot::yLeft.
+
+  The zoomer is initialized with a QwtPickerDragRectMachine,
+  the tracker mode is set to QwtPicker::ActiveOnly and the rubberband
+  is set to QwtPicker::RectRubberBand
+
+  \param canvas Plot canvas to observe, also the parent object
+  \param doReplot Call replot for the attached plot before initializing
+                  the zoomer with its scales. This might be necessary,
+                  when the plot is in a state with pending scale changes.
+
+  \sa QwtPlot::autoReplot(), QwtPlot::replot(), setZoomBase()
+*/
+QwtPlotZoomer::QwtPlotZoomer( QwtPlotCanvas *canvas, bool doReplot ):
+    QwtPlotPicker( canvas )
+{
+    if ( canvas )
+        init( doReplot );
+}
+
+/*!
+  \brief Create a zoomer for a plot canvas.
+
+  The zoomer is initialized with a QwtPickerDragRectMachine,
+  the tracker mode is set to QwtPicker::ActiveOnly and the rubberband
+  is set to QwtPicker;;RectRubberBand
+
+  \param xAxis X axis of the zoomer
+  \param yAxis Y axis of the zoomer
+  \param canvas Plot canvas to observe, also the parent object
+  \param doReplot Call replot for the attached plot before initializing
+                  the zoomer with its scales. This might be necessary,
+                  when the plot is in a state with pending scale changes.
+
+  \sa QwtPlot::autoReplot(), QwtPlot::replot(), setZoomBase()
+*/
+
+QwtPlotZoomer::QwtPlotZoomer( int xAxis, int yAxis,
+        QwtPlotCanvas *canvas, bool doReplot ):
+    QwtPlotPicker( xAxis, yAxis, canvas )
+{
+    if ( canvas )
+        init( doReplot );
+}
+
+//! Init the zoomer, used by the constructors
+void QwtPlotZoomer::init( bool doReplot )
+{
+    d_data = new PrivateData;
+
+    d_data->maxStackDepth = -1;
+
+    setTrackerMode( ActiveOnly );
+    setRubberBand( RectRubberBand );
+    setStateMachine( new QwtPickerDragRectMachine() );
+
+    if ( doReplot && plot() )
+        plot()->replot();
+
+    setZoomBase( scaleRect() );
+}
+
+QwtPlotZoomer::~QwtPlotZoomer()
+{
+    delete d_data;
+}
+
+/*!
+  \brief Limit the number of recursive zoom operations to depth.
+
+  A value of -1 set the depth to unlimited, 0 disables zooming.
+  If the current zoom rectangle is below depth, the plot is unzoomed.
+
+  \param depth Maximum for the stack depth
+  \sa maxStackDepth()
+  \note depth doesn't include the zoom base, so zoomStack().count() might be
+              maxStackDepth() + 1.
+*/
+void QwtPlotZoomer::setMaxStackDepth( int depth )
+{
+    d_data->maxStackDepth = depth;
+
+    if ( depth >= 0 )
+    {
+        // unzoom if the current depth is below d_data->maxStackDepth
+
+        const int zoomOut =
+            int( d_data->zoomStack.count() ) - 1 - depth; // -1 for the zoom base
+
+        if ( zoomOut > 0 )
+        {
+            zoom( -zoomOut );
+            for ( int i = int( d_data->zoomStack.count() ) - 1;
+                i > int( d_data->zoomRectIndex ); i-- )
+            {
+                ( void )d_data->zoomStack.pop(); // remove trailing rects
+            }
+        }
+    }
+}
+
+/*!
+  \return Maximal depth of the zoom stack.
+  \sa setMaxStackDepth()
+*/
+int QwtPlotZoomer::maxStackDepth() const
+{
+    return d_data->maxStackDepth;
+}
+
+/*!
+  Return the zoom stack. zoomStack()[0] is the zoom base,
+  zoomStack()[1] the first zoomed rectangle.
+
+  \sa setZoomStack(), zoomRectIndex()
+*/
+const QStack<QRectF> &QwtPlotZoomer::zoomStack() const
+{
+    return d_data->zoomStack;
+}
+
+/*!
+  \return Initial rectangle of the zoomer
+  \sa setZoomBase(), zoomRect()
+*/
+QRectF QwtPlotZoomer::zoomBase() const
+{
+    return d_data->zoomStack[0];
+}
+
+/*!
+  Reinitialized the zoom stack with scaleRect() as base.
+
+  \param doReplot Call replot for the attached plot before initializing
+                  the zoomer with its scales. This might be necessary,
+                  when the plot is in a state with pending scale changes.
+
+  \sa zoomBase(), scaleRect() QwtPlot::autoReplot(), QwtPlot::replot().
+*/
+void QwtPlotZoomer::setZoomBase( bool doReplot )
+{
+    QwtPlot *plt = plot();
+    if ( plt == NULL )
+        return;
+
+    if ( doReplot )
+        plt->replot();
+
+    d_data->zoomStack.clear();
+    d_data->zoomStack.push( scaleRect() );
+    d_data->zoomRectIndex = 0;
+
+    rescale();
+}
+
+/*!
+  \brief Set the initial size of the zoomer.
+
+  base is united with the current scaleRect() and the zoom stack is
+  reinitalized with it as zoom base. plot is zoomed to scaleRect().
+
+  \param base Zoom base
+
+  \sa zoomBase(), scaleRect()
+*/
+void QwtPlotZoomer::setZoomBase( const QRectF &base )
+{
+    const QwtPlot *plt = plot();
+    if ( !plt )
+        return;
+
+    const QRectF sRect = scaleRect();
+    const QRectF bRect = base | sRect;
+
+    d_data->zoomStack.clear();
+    d_data->zoomStack.push( bRect );
+    d_data->zoomRectIndex = 0;
+
+    if ( base != sRect )
+    {
+        d_data->zoomStack.push( sRect );
+        d_data->zoomRectIndex++;
+    }
+
+    rescale();
+}
+
+/*!
+  Rectangle at the current position on the zoom stack.
+
+  \sa zoomRectIndex(), scaleRect().
+*/
+QRectF QwtPlotZoomer::zoomRect() const
+{
+    return d_data->zoomStack[d_data->zoomRectIndex];
+}
+
+/*!
+  \return Index of current position of zoom stack.
+*/
+uint QwtPlotZoomer::zoomRectIndex() const
+{
+    return d_data->zoomRectIndex;
+}
+
+/*!
+  \brief Zoom in
+
+  Clears all rectangles above the current position of the
+  zoom stack and pushs the normalized rect on it.
+
+  \note If the maximal stack depth is reached, zoom is ignored.
+  \note The zoomed signal is emitted.
+*/
+
+void QwtPlotZoomer::zoom( const QRectF &rect )
+{
+    if ( d_data->maxStackDepth >= 0 &&
+            int( d_data->zoomRectIndex ) >= d_data->maxStackDepth )
+    {
+        return;
+    }
+
+    const QRectF zoomRect = rect.normalized();
+    if ( zoomRect != d_data->zoomStack[d_data->zoomRectIndex] )
+    {
+        for ( uint i = int( d_data->zoomStack.count() ) - 1;
+           i > d_data->zoomRectIndex; i-- )
+        {
+            ( void )d_data->zoomStack.pop();
+        }
+
+        d_data->zoomStack.push( zoomRect );
+        d_data->zoomRectIndex++;
+
+        rescale();
+
+        Q_EMIT zoomed( zoomRect );
+    }
+}
+
+/*!
+  \brief Zoom in or out
+
+  Activate a rectangle on the zoom stack with an offset relative
+  to the current position. Negative values of offest will zoom out,
+  positive zoom in. A value of 0 zooms out to the zoom base.
+
+  \param offset Offset relative to the current position of the zoom stack.
+  \note The zoomed signal is emitted.
+  \sa zoomRectIndex()
+*/
+void QwtPlotZoomer::zoom( int offset )
+{
+    if ( offset == 0 )
+        d_data->zoomRectIndex = 0;
+    else
+    {
+        int newIndex = d_data->zoomRectIndex + offset;
+        newIndex = qMax( 0, newIndex );
+        newIndex = qMin( int( d_data->zoomStack.count() ) - 1, newIndex );
+
+        d_data->zoomRectIndex = uint( newIndex );
+    }
+
+    rescale();
+
+    Q_EMIT zoomed( zoomRect() );
+}
+
+/*!
+  \brief Assign a zoom stack
+
+  In combination with other types of navigation it might be useful to
+  modify to manipulate the complete zoom stack.
+
+  \param zoomStack New zoom stack
+  \param zoomRectIndex Index of the current position of zoom stack.
+                       In case of -1 the current position is at the top
+                       of the stack.
+
+  \note The zoomed signal might be emitted.
+  \sa zoomStack(), zoomRectIndex()
+*/
+void QwtPlotZoomer::setZoomStack(
+    const QStack<QRectF> &zoomStack, int zoomRectIndex )
+{
+    if ( zoomStack.isEmpty() )
+        return;
+
+    if ( d_data->maxStackDepth >= 0 &&
+        int( zoomStack.count() ) > d_data->maxStackDepth )
+    {
+        return;
+    }
+
+    if ( zoomRectIndex < 0 || zoomRectIndex > int( zoomStack.count() ) )
+        zoomRectIndex = zoomStack.count() - 1;
+
+    const bool doRescale = zoomStack[zoomRectIndex] != zoomRect();
+
+    d_data->zoomStack = zoomStack;
+    d_data->zoomRectIndex = uint( zoomRectIndex );
+
+    if ( doRescale )
+    {
+        rescale();
+        Q_EMIT zoomed( zoomRect() );
+    }
+}
+
+/*!
+  Adjust the observed plot to zoomRect()
+
+  \note Initiates QwtPlot::replot
+*/
+
+void QwtPlotZoomer::rescale()
+{
+    QwtPlot *plt = plot();
+    if ( !plt )
+        return;
+
+    const QRectF &rect = d_data->zoomStack[d_data->zoomRectIndex];
+    if ( rect != scaleRect() )
+    {
+        const bool doReplot = plt->autoReplot();
+        plt->setAutoReplot( false );
+
+        double x1 = rect.left();
+        double x2 = rect.right();
+        if ( plt->axisScaleDiv( xAxis() )->lowerBound() >
+            plt->axisScaleDiv( xAxis() )->upperBound() )
+        {
+            qSwap( x1, x2 );
+        }
+
+        plt->setAxisScale( xAxis(), x1, x2 );
+
+        double y1 = rect.top();
+        double y2 = rect.bottom();
+        if ( plt->axisScaleDiv( yAxis() )->lowerBound() >
+            plt->axisScaleDiv( yAxis() )->upperBound() )
+        {
+            qSwap( y1, y2 );
+        }
+        plt->setAxisScale( yAxis(), y1, y2 );
+
+        plt->setAutoReplot( doReplot );
+
+        plt->replot();
+    }
+}
+
+/*!
+  Reinitialize the axes, and set the zoom base to their scales.
+
+  \param xAxis X axis
+  \param yAxis Y axis
+*/
+
+void QwtPlotZoomer::setAxis( int xAxis, int yAxis )
+{
+    if ( xAxis != QwtPlotPicker::xAxis() || yAxis != QwtPlotPicker::yAxis() )
+    {
+        QwtPlotPicker::setAxis( xAxis, yAxis );
+        setZoomBase( scaleRect() );
+    }
+}
+
+/*!
+   Qt::MidButton zooms out one position on the zoom stack,
+   Qt::RightButton to the zoom base.
+
+   Changes the current position on the stack, but doesn't pop
+   any rectangle.
+
+   \note The mouse events can be changed, using
+         QwtEventPattern::setMousePattern: 2, 1
+*/
+void QwtPlotZoomer::widgetMouseReleaseEvent( QMouseEvent *me )
+{
+    if ( mouseMatch( MouseSelect2, me ) )
+        zoom( 0 );
+    else if ( mouseMatch( MouseSelect3, me ) )
+        zoom( -1 );
+    else if ( mouseMatch( MouseSelect6, me ) )
+        zoom( +1 );
+    else
+        QwtPlotPicker::widgetMouseReleaseEvent( me );
+}
+
+/*!
+   Qt::Key_Plus zooms in, Qt::Key_Minus zooms out one position on the
+   zoom stack, Qt::Key_Escape zooms out to the zoom base.
+
+   Changes the current position on the stack, but doesn't pop
+   any rectangle.
+
+   \note The keys codes can be changed, using
+         QwtEventPattern::setKeyPattern: 3, 4, 5
+*/
+
+void QwtPlotZoomer::widgetKeyPressEvent( QKeyEvent *ke )
+{
+    if ( !isActive() )
+    {
+        if ( keyMatch( KeyUndo, ke ) )
+            zoom( -1 );
+        else if ( keyMatch( KeyRedo, ke ) )
+            zoom( +1 );
+        else if ( keyMatch( KeyHome, ke ) )
+            zoom( 0 );
+    }
+
+    QwtPlotPicker::widgetKeyPressEvent( ke );
+}
+
+/*!
+  Move the current zoom rectangle.
+
+  \param dx X offset
+  \param dy Y offset
+
+  \note The changed rectangle is limited by the zoom base
+*/
+void QwtPlotZoomer::moveBy( double dx, double dy )
+{
+    const QRectF &rect = d_data->zoomStack[d_data->zoomRectIndex];
+    moveTo( QPointF( rect.left() + dx, rect.top() + dy ) );
+}
+
+/*!
+  Move the the current zoom rectangle.
+
+  \param pos New position
+
+  \sa QRectF::moveTo()
+  \note The changed rectangle is limited by the zoom base
+*/
+void QwtPlotZoomer::moveTo( const QPointF &pos )
+{
+    double x = pos.x();
+    double y = pos.y();
+
+    if ( x < zoomBase().left() )
+        x = zoomBase().left();
+    if ( x > zoomBase().right() - zoomRect().width() )
+        x = zoomBase().right() - zoomRect().width();
+
+    if ( y < zoomBase().top() )
+        y = zoomBase().top();
+    if ( y > zoomBase().bottom() - zoomRect().height() )
+        y = zoomBase().bottom() - zoomRect().height();
+
+    if ( x != zoomRect().left() || y != zoomRect().top() )
+    {
+        d_data->zoomStack[d_data->zoomRectIndex].moveTo( x, y );
+        rescale();
+    }
+}
+
+/*!
+  \brief Check and correct a selected rectangle
+
+  Reject rectangles with a hight or width < 2, otherwise
+  expand the selected rectangle to a minimum size of 11x11
+  and accept it.
+
+  \return true If rect is accepted, or has been changed
+          to a accepted rectangle.
+*/
+
+bool QwtPlotZoomer::accept( QPolygon &pa ) const
+{
+    if ( pa.count() < 2 )
+        return false;
+
+    QRect rect = QRect( pa[0], pa[int( pa.count() ) - 1] );
+    rect = rect.normalized();
+
+    const int minSize = 2;
+    if ( rect.width() < minSize && rect.height() < minSize )
+        return false;
+
+    const int minZoomSize = 11;
+
+    const QPoint center = rect.center();
+    rect.setSize( rect.size().expandedTo( QSize( minZoomSize, minZoomSize ) ) );
+    rect.moveCenter( center );
+
+    pa.resize( 2 );
+    pa[0] = rect.topLeft();
+    pa[1] = rect.bottomRight();
+
+    return true;
+}
+
+/*!
+  \brief Limit zooming by a minimum rectangle
+
+  \return zoomBase().width() / 10e4, zoomBase().height() / 10e4
+*/
+QSizeF QwtPlotZoomer::minZoomSize() const
+{
+    return QSizeF( d_data->zoomStack[0].width() / 10e4,
+        d_data->zoomStack[0].height() / 10e4 );
+}
+
+/*!
+  Rejects selections, when the stack depth is too deep, or
+  the zoomed rectangle is minZoomSize().
+
+  \sa minZoomSize(), maxStackDepth()
+*/
+void QwtPlotZoomer::begin()
+{
+    if ( d_data->maxStackDepth >= 0 )
+    {
+        if ( d_data->zoomRectIndex >= uint( d_data->maxStackDepth ) )
+            return;
+    }
+
+    const QSizeF minSize = minZoomSize();
+    if ( minSize.isValid() )
+    {
+        const QSizeF sz =
+            d_data->zoomStack[d_data->zoomRectIndex].size() * 0.9999;
+
+        if ( minSize.width() >= sz.width() &&
+            minSize.height() >= sz.height() )
+        {
+            return;
+        }
+    }
+
+    QwtPlotPicker::begin();
+}
+
+/*!
+  Expand the selected rectangle to minZoomSize() and zoom in
+  if accepted.
+
+  \sa accept(), minZoomSize()
+*/
+bool QwtPlotZoomer::end( bool ok )
+{
+    ok = QwtPlotPicker::end( ok );
+    if ( !ok )
+        return false;
+
+    QwtPlot *plot = QwtPlotZoomer::plot();
+    if ( !plot )
+        return false;
+
+    const QPolygon &pa = selection();
+    if ( pa.count() < 2 )
+        return false;
+
+    QRect rect = QRect( pa[0], pa[int( pa.count() - 1 )] );
+    rect = rect.normalized();
+
+    QRectF zoomRect = invTransform( rect ).normalized();
+
+    const QSizeF minSize = minZoomSize();
+    if ( minSize.isValid() )
+    {
+        const QPointF center = zoomRect.center();
+        zoomRect.setSize( zoomRect.size().expandedTo( minZoomSize() ) );
+        zoomRect.moveCenter( center );
+    }
+
+    zoom( zoomRect );
+
+    return true;
+}
Index: trunk/BNC/qwt/qwt_plot_zoomer.h
===================================================================
--- trunk/BNC/qwt/qwt_plot_zoomer.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_plot_zoomer.h	(revision 4271)
@@ -0,0 +1,104 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_PLOT_ZOOMER_H
+#define QWT_PLOT_ZOOMER_H
+
+#include "qwt_global.h"
+#include "qwt_plot_picker.h"
+#include <qstack.h>
+
+/*!
+  \brief QwtPlotZoomer provides stacked zooming for a plot widget
+
+  QwtPlotZoomer offers rubberband selections on the plot canvas,
+  translating the selected rectangles into plot coordinates and
+  adjusting the axes to them. Zooming can repeated as often as
+  possible, limited only by maxStackDepth() or minZoomSize().
+  Each rectangle is pushed on a stack.
+
+  Zoom rectangles can be selected depending on selectionFlags() using the
+  mouse or keyboard (QwtEventPattern, QwtPickerMachine).
+  QwtEventPattern::MouseSelect3,QwtEventPattern::KeyUndo,
+  or QwtEventPattern::MouseSelect6,QwtEventPattern::KeyRedo
+  walk up and down the zoom stack.
+  QwtEventPattern::MouseSelect2 or QwtEventPattern::KeyHome unzoom to
+  the initial size.
+
+  QwtPlotZoomer is tailored for plots with one x and y axis, but it is
+  allowed to attach a second QwtPlotZoomer for the other axes.
+
+  \note The realtime example includes an derived zoomer class that adds
+        scrollbars to the plot canvas.
+*/
+
+class QWT_EXPORT QwtPlotZoomer: public QwtPlotPicker
+{
+    Q_OBJECT
+public:
+    explicit QwtPlotZoomer( QwtPlotCanvas *, bool doReplot = true );
+    explicit QwtPlotZoomer( int xAxis, int yAxis,
+                            QwtPlotCanvas *, bool doReplot = true );
+
+    virtual ~QwtPlotZoomer();
+
+    virtual void setZoomBase( bool doReplot = true );
+    virtual void setZoomBase( const QRectF & );
+
+    QRectF zoomBase() const;
+    QRectF zoomRect() const;
+
+    virtual void setAxis( int xAxis, int yAxis );
+
+    void setMaxStackDepth( int );
+    int maxStackDepth() const;
+
+    const QStack<QRectF> &zoomStack() const;
+    void setZoomStack( const QStack<QRectF> &,
+        int zoomRectIndex = -1 );
+
+    uint zoomRectIndex() const;
+
+public Q_SLOTS:
+    void moveBy( double x, double y );
+    virtual void moveTo( const QPointF & );
+
+    virtual void zoom( const QRectF & );
+    virtual void zoom( int up );
+
+Q_SIGNALS:
+    /*!
+      A signal emitting the zoomRect(), when the plot has been
+      zoomed in or out.
+
+      \param rect Current zoom rectangle.
+    */
+
+    void zoomed( const QRectF &rect );
+
+protected:
+    virtual void rescale();
+
+    virtual QSizeF minZoomSize() const;
+
+    virtual void widgetMouseReleaseEvent( QMouseEvent * );
+    virtual void widgetKeyPressEvent( QKeyEvent * );
+
+    virtual void begin();
+    virtual bool end( bool ok = true );
+    virtual bool accept( QPolygon & ) const;
+
+private:
+    void init( bool doReplot );
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_point_3d.cpp
===================================================================
--- trunk/BNC/qwt/qwt_point_3d.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_point_3d.cpp	(revision 4271)
@@ -0,0 +1,22 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_point_3d.h"
+
+#ifndef QT_NO_DEBUG_STREAM
+
+QDebug operator<<( QDebug debug, const QwtPoint3D &point )
+{
+    debug.nospace() << "QwtPoint3D(" << point.x() 
+        << "," << point.y() << "," << point.z() << ")";
+    return debug.space();
+}
+
+#endif
+
Index: trunk/BNC/qwt/qwt_point_3d.h
===================================================================
--- trunk/BNC/qwt/qwt_point_3d.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_point_3d.h	(revision 4271)
@@ -0,0 +1,189 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+/*! \file */
+#ifndef QWT_POINT_3D_H
+#define QWT_POINT_3D_H 1
+
+#include "qwt_global.h"
+#include <qpoint.h>
+#ifndef QT_NO_DEBUG_STREAM
+#include <qdebug.h>
+#endif
+
+/*!
+  \brief QwtPoint3D class defines a 3D point in double coordinates
+*/
+
+class QWT_EXPORT QwtPoint3D
+{
+public:
+    QwtPoint3D();
+    QwtPoint3D( double x, double y, double z );
+    QwtPoint3D( const QwtPoint3D & );
+    QwtPoint3D( const QPointF & );
+
+    bool isNull()    const;
+
+    double x() const;
+    double y() const;
+    double z() const;
+
+    double &rx();
+    double &ry();
+    double &rz();
+
+    void setX( double x );
+    void setY( double y );
+    void setZ( double y );
+
+    QPointF toPoint() const;
+
+    bool operator==( const QwtPoint3D & ) const;
+    bool operator!=( const QwtPoint3D & ) const;
+
+private:
+    double d_x;
+    double d_y;
+    double d_z;
+};
+
+Q_DECLARE_TYPEINFO(QwtPoint3D, Q_MOVABLE_TYPE);
+
+#ifndef QT_NO_DEBUG_STREAM
+QWT_EXPORT QDebug operator<<( QDebug, const QwtPoint3D & );
+#endif
+
+/*!
+    Constructs a null point.
+    \sa isNull()
+*/
+inline QwtPoint3D::QwtPoint3D():
+    d_x( 0.0 ),
+    d_y( 0.0 ),
+    d_z( 0.0 )
+{
+}
+
+//! Constructs a point with coordinates specified by x, y and z.
+inline QwtPoint3D::QwtPoint3D( double x, double y, double z = 0.0 ):
+    d_x( x ),
+    d_y( y ),
+    d_z( z )
+{
+}
+
+/*!
+    Copy constructor.
+    Constructs a point using the values of the point specified.
+*/
+inline QwtPoint3D::QwtPoint3D( const QwtPoint3D &other ):
+    d_x( other.d_x ),
+    d_y( other.d_y ),
+    d_z( other.d_z )
+{
+}
+
+/*!
+    Constructs a point with x and y coordinates from a 2D point,
+    and a z coordinate of 0.
+*/
+inline QwtPoint3D::QwtPoint3D( const QPointF &other ):
+    d_x( other.x() ),
+    d_y( other.y() ),
+    d_z( 0.0 )
+{
+}
+
+/*!
+    Returns true if the point is null; otherwise returns false.
+
+    A point is considered to be null if x, y and z-coordinates
+    are equal to zero.
+*/
+inline bool QwtPoint3D::isNull() const
+{
+    return d_x == 0.0 && d_y == 0.0 && d_z == 0;
+}
+
+//! Returns the x-coordinate of the point.
+inline double QwtPoint3D::x() const
+{
+    return d_x;
+}
+
+//! Returns the y-coordinate of the point.
+inline double QwtPoint3D::y() const
+{
+    return d_y;
+}
+
+//! Returns the z-coordinate of the point.
+inline double QwtPoint3D::z() const
+{
+    return d_z;
+}
+
+//! Returns a reference to the x-coordinate of the point.
+inline double &QwtPoint3D::rx()
+{
+    return d_x;
+}
+
+//! Returns a reference to the y-coordinate of the point.
+inline double &QwtPoint3D::ry()
+{
+    return d_y;
+}
+
+//! Returns a reference to the z-coordinate of the point.
+inline double &QwtPoint3D::rz()
+{
+    return d_z;
+}
+
+//! Sets the x-coordinate of the point to the value specified by x.
+inline void QwtPoint3D::setX( double x )
+{
+    d_x = x;
+}
+
+//! Sets the y-coordinate of the point to the value specified by y.
+inline void QwtPoint3D::setY( double y )
+{
+    d_y = y;
+}
+
+//! Sets the z-coordinate of the point to the value specified by z.
+inline void QwtPoint3D::setZ( double z )
+{
+    d_z = z;
+}
+
+/*!
+   Rounds 2D point, where the z coordinate is dropped.
+*/
+inline QPointF QwtPoint3D::toPoint() const
+{
+    return QPointF( d_x, d_y );
+}
+
+//! Returns true if this point and other are equal; otherwise returns false.
+inline bool QwtPoint3D::operator==( const QwtPoint3D &other ) const
+{
+    return ( d_x == other.d_x ) && ( d_y == other.d_y ) && ( d_z == other.d_z );
+}
+
+//! Returns true if this rect and other are different; otherwise returns false.
+inline bool QwtPoint3D::operator!=( const QwtPoint3D &other ) const
+{
+    return !operator==( other );
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_point_polar.cpp
===================================================================
--- trunk/BNC/qwt/qwt_point_polar.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_point_polar.cpp	(revision 4271)
@@ -0,0 +1,114 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * QwtPolar Widget Library
+ * Copyright (C) 2008   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_point_polar.h"
+#include "qwt_math.h"
+
+#if QT_VERSION < 0x040601
+#define qAtan2(y, x) ::atan2(y, x)
+#endif
+
+/*!
+   Convert and assign values from a point in Cartesian coordinates
+
+   \param p Point in Cartesian coordinates
+   \sa setPoint(), toPoint()
+*/
+QwtPointPolar::QwtPointPolar( const QPointF &p )
+{
+    d_radius = qSqrt( qwtSqr( p.x() ) + qwtSqr( p.y() ) );
+    d_azimuth = qAtan2( p.y(), p.x() );
+}
+
+/*!
+   Convert and assign values from a point in Cartesian coordinates
+   \param p Point in Cartesian coordinates
+*/
+void QwtPointPolar::setPoint( const QPointF &p )
+{
+    d_radius = qSqrt( qwtSqr( p.x() ) + qwtSqr( p.y() ) );
+    d_azimuth = qAtan2( p.y(), p.x() );
+}
+
+/*!
+   Convert and return values in Cartesian coordinates
+
+   \note Invalid or null points will be returned as QPointF(0.0, 0.0)
+   \sa isValid(), isNull()
+*/
+QPointF QwtPointPolar::toPoint() const
+{
+    if ( d_radius <= 0.0 )
+        return QPointF( 0.0, 0.0 );
+
+    const double x = d_radius * qCos( d_azimuth );
+    const double y = d_radius * qSin( d_azimuth );
+
+    return QPointF( x, y );
+}
+
+/*!
+    Returns true if point1 is equal to point2; otherwise returns false.
+
+    Two points are equal to each other if radius and
+    azimuth-coordinates are the same. Points are not equal, when
+    the azimuth differs, but other.azimuth() == azimuth() % (2 * PI).
+
+    \sa normalized()
+*/
+bool QwtPointPolar::operator==( const QwtPointPolar &other ) const
+{
+    return d_radius == other.d_radius && d_azimuth == other.d_azimuth;
+}
+
+/*!
+    Returns true if point1 is not equal to point2; otherwise returns false.
+
+    Two points are equal to each other if radius and
+    azimuth-coordinates are the same. Points are not equal, when
+    the azimuth differs, but other.azimuth() == azimuth() % (2 * PI).
+
+    \sa normalized()
+*/
+bool QwtPointPolar::operator!=( const QwtPointPolar &other ) const
+{
+    return d_radius != other.d_radius || d_azimuth != other.d_azimuth;
+}
+
+/*!
+   Normalize radius and azimuth
+
+   When the radius is < 0.0 it is set to 0.0. The azimuth is
+   a value >= 0.0 and < 2 * M_PI.
+*/
+QwtPointPolar QwtPointPolar::normalized() const
+{
+    const double radius = qMax( d_radius, 0.0 );
+
+    double azimuth = d_azimuth;
+    if ( azimuth < -2.0 * M_PI || azimuth >= 2 * M_PI )
+        azimuth = ::fmod( d_azimuth, 2 * M_PI );
+
+    if ( azimuth < 0.0 )
+        azimuth += 2 * M_PI;
+
+    return QwtPointPolar( azimuth, radius );
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+
+QDebug operator<<( QDebug debug, const QwtPointPolar &point )
+{
+    debug.nospace() << "QwtPointPolar(" 
+        << point.azimuth() << "," << point.radius() << ")";
+
+    return debug.space();
+}
+
+#endif
+
Index: trunk/BNC/qwt/qwt_point_polar.h
===================================================================
--- trunk/BNC/qwt/qwt_point_polar.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_point_polar.h	(revision 4271)
@@ -0,0 +1,195 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+/*! \file */
+#ifndef _QWT_POINT_POLAR_H_
+#define _QWT_POINT_POLAR_H_ 1
+
+#include "qwt_global.h"
+#include "qwt_math.h"
+#include <qpoint.h>
+#ifndef QT_NO_DEBUG_STREAM
+#include <qdebug.h>
+#endif
+
+/*!
+  \brief A point in polar coordinates
+
+  In polar coordinates a point is determined by an angle and a distance.
+  See http://en.wikipedia.org/wiki/Polar_coordinate_system
+*/
+
+class QWT_EXPORT QwtPointPolar
+{
+public:
+    QwtPointPolar();
+    QwtPointPolar( double azimuth, double radius );
+    QwtPointPolar( const QwtPointPolar & );
+    QwtPointPolar( const QPointF & );
+
+    void setPoint( const QPointF & );
+    QPointF toPoint() const;
+
+    bool isValid() const;
+    bool isNull() const;
+
+    double radius() const;
+    double azimuth() const;
+
+    double &rRadius();
+    double &rAzimuth();
+
+    void setRadius( double );
+    void setAzimuth( double );
+
+    bool operator==( const QwtPointPolar & ) const;
+    bool operator!=( const QwtPointPolar & ) const;
+
+    QwtPointPolar normalized() const;
+
+private:
+    double d_azimuth;
+    double d_radius;
+};
+
+/*!
+    Constructs a null point, with a radius and azimuth set to 0.0.
+    \sa QPointF::isNull
+*/
+inline QwtPointPolar::QwtPointPolar():
+    d_azimuth( 0.0 ),
+    d_radius( 0.0 )
+{
+}
+
+/*!
+   Constructs a point with coordinates specified by radius and azimuth.
+
+   \param azimuth Azimuth
+   \param radius Radius
+*/
+inline QwtPointPolar::QwtPointPolar( double azimuth, double radius ):
+    d_azimuth( azimuth ),
+    d_radius( radius )
+{
+}
+
+/*!
+    Constructs a point using the values of the point specified.
+    \param other Other point
+*/
+inline QwtPointPolar::QwtPointPolar( const QwtPointPolar &other ):
+    d_azimuth( other.d_azimuth ),
+    d_radius( other.d_radius )
+{
+}
+
+//! Returns true if radius() >= 0.0
+inline bool QwtPointPolar::isValid() const
+{
+    return d_radius >= 0.0;
+}
+
+//! Returns true if radius() >= 0.0
+inline bool QwtPointPolar::isNull() const
+{
+    return d_radius == 0.0;
+}
+
+//! Returns the radius.
+inline double QwtPointPolar::radius() const
+{
+    return d_radius;
+}
+
+//! Returns the azimuth.
+inline double QwtPointPolar::azimuth() const
+{
+    return d_azimuth;
+}
+
+//! Returns the radius.
+inline double &QwtPointPolar::rRadius()
+{
+    return d_radius;
+}
+
+//! Returns the azimuth.
+inline double &QwtPointPolar::rAzimuth()
+{
+    return d_azimuth;
+}
+
+//! Sets the radius to radius.
+inline void QwtPointPolar::setRadius( double radius )
+{
+    d_radius = radius;
+}
+
+//! Sets the atimuth to atimuth.
+inline void QwtPointPolar::setAzimuth( double azimuth )
+{
+    d_azimuth = azimuth;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QWT_EXPORT QDebug operator<<( QDebug, const QwtPointPolar & );
+#endif
+
+inline QPoint qwtPolar2Pos( const QPoint &pole,
+    double radius, double angle )
+{
+    const double x = pole.x() + radius * qCos( angle );
+    const double y = pole.y() - radius * qSin( angle );
+
+    return QPoint( qRound( x ), qRound( y ) );
+}
+
+inline QPoint qwtDegree2Pos( const QPoint &pole,
+    double radius, double angle )
+{
+    return qwtPolar2Pos( pole, radius, angle / 180.0 * M_PI );
+}
+
+inline QPointF qwtPolar2Pos( const QPointF &pole,
+    double radius, double angle )
+{
+    const double x = pole.x() + radius * qCos( angle );
+    const double y = pole.y() - radius * qSin( angle );
+
+    return QPointF( x, y);
+}
+
+inline QPointF qwtDegree2Pos( const QPointF &pole,
+    double radius, double angle )
+{
+    return qwtPolar2Pos( pole, radius, angle / 180.0 * M_PI );
+}
+
+inline QPointF qwtFastPolar2Pos( const QPointF &pole,
+    double radius, double angle )
+{
+#if QT_VERSION < 0x040601
+    const double x = pole.x() + radius * ::cos( angle );
+    const double y = pole.y() - radius * ::sin( angle );
+#else
+    const double x = pole.x() + radius * qFastCos( angle );
+    const double y = pole.y() - radius * qFastSin( angle );
+#endif
+
+    return QPointF( x, y);
+}
+
+inline QPointF qwtFastDegree2Pos( const QPointF &pole,
+    double radius, double angle )
+{   
+    return qwtFastPolar2Pos( pole, radius, angle / 180.0 * M_PI );
+} 
+
+#endif 
Index: trunk/BNC/qwt/qwt_raster_data.cpp
===================================================================
--- trunk/BNC/qwt/qwt_raster_data.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_raster_data.cpp	(revision 4271)
@@ -0,0 +1,390 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_raster_data.h"
+#include "qwt_point_3d.h"
+
+class QwtRasterData::ContourPlane
+{
+public:
+    inline ContourPlane( double z ):
+        d_z( z )
+    {
+    }
+
+    inline bool intersect( const QwtPoint3D vertex[3],
+        QPointF line[2], bool ignoreOnPlane ) const;
+
+    inline double z() const { return d_z; }
+
+private:
+    inline int compare( double z ) const;
+    inline QPointF intersection(
+        const QwtPoint3D& p1, const QwtPoint3D &p2 ) const;
+
+    double d_z;
+};
+
+inline bool QwtRasterData::ContourPlane::intersect(
+    const QwtPoint3D vertex[3], QPointF line[2],
+    bool ignoreOnPlane ) const
+{
+    bool found = true;
+
+    // Are the vertices below (-1), on (0) or above (1) the plan ?
+    const int eq1 = compare( vertex[0].z() );
+    const int eq2 = compare( vertex[1].z() );
+    const int eq3 = compare( vertex[2].z() );
+
+    /*
+        (a) All the vertices lie below the contour level.
+        (b) Two vertices lie below and one on the contour level.
+        (c) Two vertices lie below and one above the contour level.
+        (d) One vertex lies below and two on the contour level.
+        (e) One vertex lies below, one on and one above the contour level.
+        (f) One vertex lies below and two above the contour level.
+        (g) Three vertices lie on the contour level.
+        (h) Two vertices lie on and one above the contour level.
+        (i) One vertex lies on and two above the contour level.
+        (j) All the vertices lie above the contour level.
+     */
+
+    static const int tab[3][3][3] =
+    {
+        // jump table to avoid nested case statements
+        { { 0, 0, 8 }, { 0, 2, 5 }, { 7, 6, 9 } },
+        { { 0, 3, 4 }, { 1, 10, 1 }, { 4, 3, 0 } },
+        { { 9, 6, 7 }, { 5, 2, 0 }, { 8, 0, 0 } }
+    };
+
+    const int edgeType = tab[eq1+1][eq2+1][eq3+1];
+    switch ( edgeType )
+    {
+        case 1:
+            // d(0,0,-1), h(0,0,1)
+            line[0] = vertex[0].toPoint();
+            line[1] = vertex[1].toPoint();
+            break;
+        case 2:
+            // d(-1,0,0), h(1,0,0)
+            line[0] = vertex[1].toPoint();
+            line[1] = vertex[2].toPoint();
+            break;
+        case 3:
+            // d(0,-1,0), h(0,1,0)
+            line[0] = vertex[2].toPoint();
+            line[1] = vertex[0].toPoint();
+            break;
+        case 4:
+            // e(0,-1,1), e(0,1,-1)
+            line[0] = vertex[0].toPoint();
+            line[1] = intersection( vertex[1], vertex[2] );
+            break;
+        case 5:
+            // e(-1,0,1), e(1,0,-1)
+            line[0] = vertex[1].toPoint();
+            line[1] = intersection( vertex[2], vertex[0] );
+            break;
+        case 6:
+            // e(-1,1,0), e(1,0,-1)
+            line[0] = vertex[1].toPoint();
+            line[1] = intersection( vertex[0], vertex[1] );
+            break;
+        case 7:
+            // c(-1,1,-1), f(1,1,-1)
+            line[0] = intersection( vertex[0], vertex[1] );
+            line[1] = intersection( vertex[1], vertex[2] );
+            break;
+        case 8:
+            // c(-1,-1,1), f(1,1,-1)
+            line[0] = intersection( vertex[1], vertex[2] );
+            line[1] = intersection( vertex[2], vertex[0] );
+            break;
+        case 9:
+            // f(-1,1,1), c(1,-1,-1)
+            line[0] = intersection( vertex[2], vertex[0] );
+            line[1] = intersection( vertex[0], vertex[1] );
+            break;
+        case 10:
+            // g(0,0,0)
+            // The CONREC algorithm has no satisfying solution for
+            // what to do, when all vertices are on the plane.
+
+            if ( ignoreOnPlane )
+                found = false;
+            else
+            {
+                line[0] = vertex[2].toPoint();
+                line[1] = vertex[0].toPoint();
+            }
+            break;
+        default:
+            found = false;
+    }
+
+    return found;
+}
+
+inline int QwtRasterData::ContourPlane::compare( double z ) const
+{
+    if ( z > d_z )
+        return 1;
+
+    if ( z < d_z )
+        return -1;
+
+    return 0;
+}
+
+inline QPointF QwtRasterData::ContourPlane::intersection(
+    const QwtPoint3D& p1, const QwtPoint3D &p2 ) const
+{
+    const double h1 = p1.z() - d_z;
+    const double h2 = p2.z() - d_z;
+
+    const double x = ( h2 * p1.x() - h1 * p2.x() ) / ( h2 - h1 );
+    const double y = ( h2 * p1.y() - h1 * p2.y() ) / ( h2 - h1 );
+
+    return QPointF( x, y );
+}
+
+//! Constructor
+QwtRasterData::QwtRasterData()
+{
+}
+
+//! Destructor
+QwtRasterData::~QwtRasterData()
+{
+}
+
+/*!
+   Set the bounding interval for the x, y or z coordinates.
+
+   \param axis Axis
+   \param interval Bounding interval
+
+   \sa interval()
+*/
+void QwtRasterData::setInterval( Qt::Axis axis, const QwtInterval &interval )
+{
+    d_intervals[axis] = interval;
+}
+
+/*!
+  \brief Initialize a raster
+
+  Before the composition of an image QwtPlotSpectrogram calls initRaster,
+  announcing the area and its resolution that will be requested.
+
+  The default implementation does nothing, but for data sets that
+  are stored in files, it might be good idea to reimplement initRaster,
+  where the data is resampled and loaded into memory.
+
+  \param area Area of the raster
+  \param raster Number of horizontal and vertical pixels
+
+  \sa initRaster(), value()
+*/
+void QwtRasterData::initRaster( const QRectF &area, const QSize &raster )
+{
+    Q_UNUSED( area );
+    Q_UNUSED( raster );
+}
+
+/*!
+  \brief Discard a raster
+
+  After the composition of an image QwtPlotSpectrogram calls discardRaster().
+
+  The default implementation does nothing, but if data has been loaded
+  in initRaster(), it could deleted now.
+
+  \sa initRaster(), value()
+*/
+void QwtRasterData::discardRaster()
+{
+}
+
+/*!
+   \brief Pixel hint
+
+   pixelHint() returns the geometry of a pixel, that can be used 
+   to calculate the resolution and alignment of the plot item, that is
+   representing the data. 
+   
+   Width and height of the hint need to be the horizontal  
+   and vertical distances between 2 neighboured points. 
+   The center of the hint has to be the position of any point 
+   ( it doesn't matter which one ).
+
+   An empty hint indicates, that there are values for any detail level.
+
+   Limiting the resolution of the image might significantly improve
+   the performance and heavily reduce the amount of memory when rendering
+   a QImage from the raster data. 
+
+   The default implementation returns an empty rectangle recommending
+   to render in target device ( f.e. screen ) resolution.
+
+   \param area In most implementations the resolution of the data doesn't
+               depend on the requested area.
+
+   \return Bounding rectangle of a pixel 
+*/
+QRectF QwtRasterData::pixelHint( const QRectF &area ) const
+{
+    Q_UNUSED( area );
+    return QRectF(); 
+}
+
+/*!
+   Calculate contour lines
+
+   An adaption of CONREC, a simple contouring algorithm.
+   http://local.wasp.uwa.edu.au/~pbourke/papers/conrec/
+*/
+QwtRasterData::ContourLines QwtRasterData::contourLines(
+    const QRectF &rect, const QSize &raster,
+    const QList<double> &levels, ConrecFlags flags ) const
+{
+    ContourLines contourLines;
+
+    if ( levels.size() == 0 || !rect.isValid() || !raster.isValid() )
+        return contourLines;
+
+    const double dx = rect.width() / raster.width();
+    const double dy = rect.height() / raster.height();
+
+    const bool ignoreOnPlane =
+        flags & QwtRasterData::IgnoreAllVerticesOnLevel;
+
+    const QwtInterval range = interval( Qt::ZAxis );
+    bool ignoreOutOfRange = false;
+    if ( range.isValid() )
+        ignoreOutOfRange = flags & IgnoreOutOfRange;
+
+    QwtRasterData *that = const_cast<QwtRasterData *>( this );
+    that->initRaster( rect, raster );
+
+    for ( int y = 0; y < raster.height() - 1; y++ )
+    {
+        enum Position
+        {
+            Center,
+
+            TopLeft,
+            TopRight,
+            BottomRight,
+            BottomLeft,
+
+            NumPositions
+        };
+
+        QwtPoint3D xy[NumPositions];
+
+        for ( int x = 0; x < raster.width() - 1; x++ )
+        {
+            const QPointF pos( rect.x() + x * dx, rect.y() + y * dy );
+
+            if ( x == 0 )
+            {
+                xy[TopRight].setX( pos.x() );
+                xy[TopRight].setY( pos.y() );
+                xy[TopRight].setZ(
+                    value( xy[TopRight].x(), xy[TopRight].y() )
+                );
+
+                xy[BottomRight].setX( pos.x() );
+                xy[BottomRight].setY( pos.y() + dy );
+                xy[BottomRight].setZ(
+                    value( xy[BottomRight].x(), xy[BottomRight].y() )
+                );
+            }
+
+            xy[TopLeft] = xy[TopRight];
+            xy[BottomLeft] = xy[BottomRight];
+
+            xy[TopRight].setX( pos.x() + dx );
+            xy[TopRight].setY( pos.y() );
+            xy[BottomRight].setX( pos.x() + dx );
+            xy[BottomRight].setY( pos.y() + dy );
+
+            xy[TopRight].setZ(
+                value( xy[TopRight].x(), xy[TopRight].y() )
+            );
+            xy[BottomRight].setZ(
+                value( xy[BottomRight].x(), xy[BottomRight].y() )
+            );
+
+            double zMin = xy[TopLeft].z();
+            double zMax = zMin;
+            double zSum = zMin;
+
+            for ( int i = TopRight; i <= BottomLeft; i++ )
+            {
+                const double z = xy[i].z();
+
+                zSum += z;
+                if ( z < zMin )
+                    zMin = z;
+                if ( z > zMax )
+                    zMax = z;
+            }
+
+            if ( ignoreOutOfRange )
+            {
+                if ( !range.contains( zMin ) || !range.contains( zMax ) )
+                    continue;
+            }
+
+            if ( zMax < levels[0] ||
+                zMin > levels[levels.size() - 1] )
+            {
+                continue;
+            }
+
+            xy[Center].setX( pos.x() + 0.5 * dx );
+            xy[Center].setY( pos.y() + 0.5 * dy );
+            xy[Center].setZ( 0.25 * zSum );
+
+            const int numLevels = levels.size();
+            for ( int l = 0; l < numLevels; l++ )
+            {
+                const double level = levels[l];
+                if ( level < zMin || level > zMax )
+                    continue;
+                QPolygonF &lines = contourLines[level];
+                const ContourPlane plane( level );
+
+                QPointF line[2];
+                QwtPoint3D vertex[3];
+
+                for ( int m = TopLeft; m < NumPositions; m++ )
+                {
+                    vertex[0] = xy[m];
+                    vertex[1] = xy[0];
+                    vertex[2] = xy[m != BottomLeft ? m + 1 : TopLeft];
+
+                    const bool intersects =
+                        plane.intersect( vertex, line, ignoreOnPlane );
+                    if ( intersects )
+                    {
+                        lines += line[0];
+                        lines += line[1];
+                    }
+                }
+            }
+        }
+    }
+
+    that->discardRaster();
+
+    return contourLines;
+}
Index: trunk/BNC/qwt/qwt_raster_data.h
===================================================================
--- trunk/BNC/qwt/qwt_raster_data.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_raster_data.h	(revision 4271)
@@ -0,0 +1,95 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_RASTER_DATA_H
+#define QWT_RASTER_DATA_H 1
+
+#include "qwt_global.h"
+#include "qwt_interval.h"
+#include <qmap.h>
+#include <qlist.h>
+#include <qpolygon.h>
+
+class QwtScaleMap;
+
+/*!
+  \brief QwtRasterData defines an interface to any type of raster data.
+
+  QwtRasterData is an abstract interface, that is used by
+  QwtPlotRasterItem to find the values at the pixels of its raster.
+
+  Often a raster item is used to display values from a matrix. Then the
+  derived raster data class needs to implement some sort of resampling,
+  that maps the raster of the matrix into the requested raster of
+  the raster item ( depending on resolution and scales of the canvas ).
+*/
+class QWT_EXPORT QwtRasterData
+{
+public:
+    //! Contour lines
+    typedef QMap<double, QPolygonF> ContourLines;
+
+    //! Flags to modify the contour algorithm
+    enum ConrecFlag
+    {
+        //! Ignore all verices on the same level
+        IgnoreAllVerticesOnLevel = 0x01,
+
+        //! Ignore all values, that are out of range
+        IgnoreOutOfRange = 0x02
+    };
+
+    //! Flags to modify the contour algorithm
+    typedef QFlags<ConrecFlag> ConrecFlags;
+
+    QwtRasterData();
+    virtual ~QwtRasterData();
+
+    virtual void setInterval( Qt::Axis, const QwtInterval & );
+    const QwtInterval &interval(Qt::Axis) const;
+
+    virtual QRectF pixelHint( const QRectF & ) const;
+
+    virtual void initRaster( const QRectF &, const QSize& raster );
+    virtual void discardRaster();
+
+    /*!
+       \return the value at a raster position
+       \param x X value in plot coordinates
+       \param y Y value in plot coordinates
+    */
+    virtual double value( double x, double y ) const = 0;
+
+    virtual ContourLines contourLines( const QRectF &rect,
+        const QSize &raster, const QList<double> &levels,
+        ConrecFlags ) const;
+
+    class Contour3DPoint;
+    class ContourPlane;
+
+private:
+    // Disabled copy constructor and operator=
+    QwtRasterData( const QwtRasterData & );
+    QwtRasterData &operator=( const QwtRasterData & );
+
+    QwtInterval d_intervals[3];
+};
+
+/*!
+   \return Bounding interval for a axis
+   \sa setInterval
+*/
+inline const QwtInterval &QwtRasterData::interval( Qt::Axis axis) const
+{
+    return d_intervals[axis];
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtRasterData::ConrecFlags )
+
+#endif
Index: trunk/BNC/qwt/qwt_round_scale_draw.cpp
===================================================================
--- trunk/BNC/qwt/qwt_round_scale_draw.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_round_scale_draw.cpp	(revision 4271)
@@ -0,0 +1,306 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_round_scale_draw.h"
+#include "qwt_painter.h"
+#include "qwt_scale_div.h"
+#include "qwt_scale_map.h"
+#include <qpen.h>
+#include <qpainter.h>
+#include <qfontmetrics.h>
+#include <qmath.h>
+
+class QwtRoundScaleDraw::PrivateData
+{
+public:
+    PrivateData():
+        center( 50, 50 ),
+        radius( 50 ),
+        startAngle( -135 * 16 ),
+        endAngle( 135 * 16 )
+    {
+    }
+
+    QPointF center;
+    double radius;
+
+    double startAngle;
+    double endAngle;
+};
+
+/*!
+  \brief Constructor
+
+  The range of the scale is initialized to [0, 100],
+  The center is set to (50, 50) with a radius of 50.
+  The angle range is set to [-135, 135].
+*/
+QwtRoundScaleDraw::QwtRoundScaleDraw()
+{
+    d_data = new QwtRoundScaleDraw::PrivateData;
+
+    setRadius( 50 );
+    scaleMap().setPaintInterval( d_data->startAngle, d_data->endAngle );
+}
+
+//! Destructor
+QwtRoundScaleDraw::~QwtRoundScaleDraw()
+{
+    delete d_data;
+}
+
+/*!
+  Change of radius the scale
+
+  Radius is the radius of the backbone without ticks and labels.
+
+  \param radius New Radius
+  \sa moveCenter()
+*/
+void QwtRoundScaleDraw::setRadius( int radius )
+{
+    d_data->radius = radius;
+}
+
+/*!
+  Get the radius
+
+  Radius is the radius of the backbone without ticks and labels.
+
+  \sa setRadius(), extent()
+*/
+int QwtRoundScaleDraw::radius() const
+{
+    return d_data->radius;
+}
+
+/*!
+   Move the center of the scale draw, leaving the radius unchanged
+
+   \param center New center
+   \sa setRadius()
+*/
+void QwtRoundScaleDraw::moveCenter( const QPointF &center )
+{
+    d_data->center = center;
+}
+
+//! Get the center of the scale
+QPointF QwtRoundScaleDraw::center() const
+{
+    return d_data->center;
+}
+
+/*!
+  \brief Adjust the baseline circle segment for round scales.
+
+  The baseline will be drawn from min(angle1,angle2) to max(angle1, angle2).
+  The default setting is [ -135, 135 ].
+  An angle of 0 degrees corresponds to the 12 o'clock position,
+  and positive angles count in a clockwise direction.
+  \param angle1
+  \param angle2 boundaries of the angle interval in degrees.
+  \warning <ul>
+  <li>The angle range is limited to [-360, 360] degrees. Angles exceeding
+      this range will be clipped.
+  <li>For angles more than 359 degrees above or below min(angle1, angle2),
+      scale marks will not be drawn.
+  <li>If you need a counterclockwise scale, use QwtScaleDiv::setRange
+  </ul>
+*/
+void QwtRoundScaleDraw::setAngleRange( double angle1, double angle2 )
+{
+    angle1 = qBound( -360.0, angle1, 360.0 );
+    angle2 = qBound( -360.0, angle2, 360.0 );
+
+    d_data->startAngle = angle1 * 16.0;
+    d_data->endAngle = angle2 * 16.0;
+
+    if ( d_data->startAngle == d_data->endAngle )
+    {
+        d_data->startAngle -= 1;
+        d_data->endAngle += 1;
+    }
+
+    scaleMap().setPaintInterval( d_data->startAngle, d_data->endAngle );
+}
+
+/*!
+   Draws the label for a major scale tick
+
+   \param painter Painter
+   \param value Value
+
+   \sa drawTick(), drawBackbone()
+*/
+void QwtRoundScaleDraw::drawLabel( QPainter *painter, double value ) const
+{
+    const QwtText label = tickLabel( painter->font(), value );
+    if ( label.isEmpty() )
+        return;
+
+    const double tval = scaleMap().transform( value );
+    if ( ( tval > d_data->startAngle + 359 * 16 )
+        || ( tval < d_data->startAngle - 359 * 16 ) )
+    {
+        return;
+    }
+
+    double radius = d_data->radius;
+    if ( hasComponent( QwtAbstractScaleDraw::Ticks ) ||
+        hasComponent( QwtAbstractScaleDraw::Backbone ) )
+    {
+        radius += spacing();
+    }
+
+    if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
+        radius += tickLength( QwtScaleDiv::MajorTick );
+
+    const QSizeF sz = label.textSize( painter->font() );
+    const double arc = tval / 16.0 / 360.0 * 2 * M_PI;
+
+    const double x = d_data->center.x() +
+        ( radius + sz.width() / 2.0 ) * qSin( arc );
+    const double y = d_data->center.y() -
+        ( radius + sz.height() / 2.0 ) * cos( arc );
+
+    const QRectF r( x - sz.width() / 2, y - sz.height() / 2,
+        sz.width(), sz.height() );
+    label.draw( painter, r );
+}
+
+/*!
+   Draw a tick
+
+   \param painter Painter
+   \param value Value of the tick
+   \param len Lenght of the tick
+
+   \sa drawBackbone(), drawLabel()
+*/
+void QwtRoundScaleDraw::drawTick( QPainter *painter, double value, double len ) const
+{
+    if ( len <= 0 )
+        return;
+
+    const double tval = scaleMap().transform( value );
+
+    const double cx = d_data->center.x();
+    const double cy = d_data->center.y();
+    const double radius = d_data->radius;
+
+    if ( ( tval <= d_data->startAngle + 359 * 16 )
+        || ( tval >= d_data->startAngle - 359 * 16 ) )
+    {
+        const double arc = double( tval ) / 16.0 * M_PI / 180.0;
+
+        const double sinArc = qSin( arc );
+        const double cosArc = qCos( arc );
+
+        const double x1 = cx + radius * sinArc;
+        const double x2 = cx + ( radius + len ) * sinArc;
+        const double y1 = cy - radius * cosArc;
+        const double y2 = cy - ( radius + len ) * cosArc;
+
+        QwtPainter::drawLine( painter, x1, y1, x2, y2 );
+    }
+}
+
+/*!
+   Draws the baseline of the scale
+   \param painter Painter
+
+   \sa drawTick(), drawLabel()
+*/
+void QwtRoundScaleDraw::drawBackbone( QPainter *painter ) const
+{
+    const double a1 = qMin( scaleMap().p1(), scaleMap().p2() ) - 90 * 16;
+    const double a2 = qMax( scaleMap().p1(), scaleMap().p2() ) - 90 * 16;
+
+    const double radius = d_data->radius;
+    const double x = d_data->center.x() - radius;
+    const double y = d_data->center.y() - radius;
+
+    painter->drawArc( x, y, 2 * radius, 2 * radius,
+        -a2, a2 - a1 + 1 );          // counterclockwise
+}
+
+/*!
+   Calculate the extent of the scale
+
+   The extent is the distance between the baseline to the outermost
+   pixel of the scale draw. radius() + extent() is an upper limit
+   for the radius of the bounding circle.
+
+   \param font Font used for painting the labels
+
+   \sa setMinimumExtent(), minimumExtent()
+   \warning The implemented algo is not too smart and
+            calculates only an upper limit, that might be a
+            few pixels too large
+*/
+double QwtRoundScaleDraw::extent( const QFont &font ) const
+{
+    double d = 0.0;
+
+    if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
+    {
+        const QwtScaleDiv &sd = scaleDiv();
+        const QList<double> &ticks = sd.ticks( QwtScaleDiv::MajorTick );
+        for ( int i = 0; i < ticks.count(); i++ )
+        {
+            const double value = ticks[i];
+            if ( !sd.contains( value ) )
+                continue;
+
+            const QwtText label = tickLabel( font, value );
+            if ( label.isEmpty() )
+                continue;
+
+            const double tval = scaleMap().transform( value );
+            if ( ( tval < d_data->startAngle + 360 * 16 )
+                && ( tval > d_data->startAngle - 360 * 16 ) )
+            {
+                const double arc = tval / 16.0 / 360.0 * 2 * M_PI;
+
+                const QSizeF sz = label.textSize( font );
+                const double off = qMax( sz.width(), sz.height() );
+
+                double x = off * qSin( arc );
+                double y = off * qCos( arc );
+
+                const double dist = qSqrt( x * x + y * y );
+                if ( dist > d )
+                    d = dist;
+            }
+        }
+    }
+
+    if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
+    {
+        d += maxTickLength();
+    }
+
+    if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
+    {
+        const double pw = qMax( 1, penWidth() );  // penwidth can be zero
+        d += pw;
+    }
+
+    if ( hasComponent( QwtAbstractScaleDraw::Labels ) &&
+        ( hasComponent( QwtAbstractScaleDraw::Ticks ) ||
+            hasComponent( QwtAbstractScaleDraw::Backbone ) ) )
+    {
+        d += spacing();
+    }
+
+    d = qMax( d, minimumExtent() );
+
+    return d;
+}
Index: trunk/BNC/qwt/qwt_round_scale_draw.h
===================================================================
--- trunk/BNC/qwt/qwt_round_scale_draw.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_round_scale_draw.h	(revision 4271)
@@ -0,0 +1,68 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_ROUND_SCALE_DRAW_H
+#define QWT_ROUND_SCALE_DRAW_H
+
+#include "qwt_global.h"
+#include "qwt_abstract_scale_draw.h"
+#include <qpoint.h>
+
+class QPen;
+
+/*!
+  \brief A class for drawing round scales
+
+  QwtRoundScaleDraw can be used to draw round scales.
+  The circle segment can be adjusted by QwtRoundScaleDraw::setAngleRange().
+  The geometry of the scale can be specified with
+  QwtRoundScaleDraw::moveCenter() and QwtRoundScaleDraw::setRadius().
+
+  After a scale division has been specified as a QwtScaleDiv object
+  using QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s),
+  the scale can be drawn with the QwtAbstractScaleDraw::draw() member.
+*/
+
+class QWT_EXPORT QwtRoundScaleDraw: public QwtAbstractScaleDraw
+{
+public:
+    QwtRoundScaleDraw();
+    virtual ~QwtRoundScaleDraw();
+
+    void setRadius( int radius );
+    int radius() const;
+
+    void moveCenter( double x, double y );
+    void moveCenter( const QPointF & );
+    QPointF center() const;
+
+    void setAngleRange( double angle1, double angle2 );
+
+    virtual double extent( const QFont & ) const;
+
+protected:
+    virtual void drawTick( QPainter *p, double val, double len ) const;
+    virtual void drawBackbone( QPainter *p ) const;
+    virtual void drawLabel( QPainter *p, double val ) const;
+
+private:
+    QwtRoundScaleDraw( const QwtRoundScaleDraw & );
+    QwtRoundScaleDraw &operator=( const QwtRoundScaleDraw &other );
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+//! Move the center of the scale draw, leaving the radius unchanged
+inline void QwtRoundScaleDraw::moveCenter( double x, double y )
+{
+    moveCenter( QPointF( x, y ) );
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_sampling_thread.cpp
===================================================================
--- trunk/BNC/qwt/qwt_sampling_thread.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_sampling_thread.cpp	(revision 4271)
@@ -0,0 +1,106 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_sampling_thread.h"
+#include "qwt_system_clock.h"
+
+class QwtSamplingThread::PrivateData
+{
+public:
+    QwtSystemClock clock;
+
+    double interval;
+    bool isStopped;
+};
+
+
+//! Constructor
+QwtSamplingThread::QwtSamplingThread( QObject *parent ):
+    QThread( parent )
+{
+    d_data = new PrivateData;
+    d_data->interval = 1000; // 1 second
+    d_data->isStopped = true;
+}
+
+//! Destructor
+QwtSamplingThread::~QwtSamplingThread()
+{
+    delete d_data;
+}
+
+/*!
+   Change the interval (in ms), when sample() is called.
+   The default interval is 1000.0 ( = 1s )
+
+   \param interval Interval
+   \sa interval()
+*/
+void QwtSamplingThread::setInterval( double interval )
+{
+    if ( interval < 0.0 )
+        interval = 0.0;
+
+    d_data->interval = interval;
+}
+
+/*!
+   \return Interval (in ms), between 2 calls of sample()
+   \sa setInterval()
+*/
+double QwtSamplingThread::interval() const
+{
+    return d_data->interval;
+}
+
+/*!
+   \return Time (in ms) since the thread was started
+   \sa QThread::start(), run()
+*/
+double QwtSamplingThread::elapsed() const
+{
+    if ( d_data->isStopped )
+        return 0.0;
+
+    return d_data->clock.elapsed();
+}
+
+/*!
+   Terminate the collecting thread
+   \sa QThread::start(), run()
+*/
+void QwtSamplingThread::stop()
+{
+    d_data->isStopped = true;
+}
+
+/*!
+   Loop collecting samples started from QThread::start()
+   \sa stop()
+*/
+void QwtSamplingThread::run()
+{
+    d_data->clock.start();
+    d_data->isStopped = false;
+
+    while ( !d_data->isStopped )
+    {
+        const double elapsed = d_data->clock.elapsed();
+        sample( elapsed / 1000.0 );
+
+        if ( d_data->interval > 0.0 )
+        {
+            const double msecs =
+                d_data->interval - ( d_data->clock.elapsed() - elapsed );
+
+            if ( msecs > 0.0 )
+                usleep( qRound( 1000.0 * msecs ) );
+        }
+    }
+}
Index: trunk/BNC/qwt/qwt_sampling_thread.h
===================================================================
--- trunk/BNC/qwt/qwt_sampling_thread.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_sampling_thread.h	(revision 4271)
@@ -0,0 +1,50 @@
+#ifndef _QWT_SAMPLING_THREAD_H_
+#define _QWT_SAMPLING_THREAD_H_
+
+#include "qwt_global.h"
+#include <qthread.h>
+
+/*!
+  \brief A thread collecting samples at regular intervals.
+
+  Contiounous signals are converted into a discrete signal by
+  collecting samples at regular intervals. A discrete signal
+  can be displayed by a QwtPlotSeriesItem on a QwtPlot widget.
+
+  QwtSamplingThread starts a thread calling perodically sample(),
+  to collect and store ( or emit ) a single sample.
+
+  \sa QwtPlotCurve, QwtPlotSeriesItem
+*/
+class QWT_EXPORT QwtSamplingThread: public QThread
+{
+    Q_OBJECT
+
+public:
+    virtual ~QwtSamplingThread();
+
+    double interval() const;
+    double elapsed() const;
+
+public Q_SLOTS:
+    void setInterval( double interval );
+    void stop();
+
+protected:
+    explicit QwtSamplingThread( QObject *parent = NULL );
+
+    virtual void run();
+
+    /*!
+       Collect a sample
+
+       \param elapsed Time since the thread was started in miliseconds
+     */
+    virtual void sample( double elapsed ) = 0;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_scale_div.cpp
===================================================================
--- trunk/BNC/qwt/qwt_scale_div.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_div.cpp	(revision 4271)
@@ -0,0 +1,173 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_scale_div.h"
+#include "qwt_math.h"
+#include "qwt_interval.h"
+#include <qalgorithms.h>
+
+//! Construct an invalid QwtScaleDiv instance.
+QwtScaleDiv::QwtScaleDiv():
+    d_lowerBound( 0.0 ),
+    d_upperBound( 0.0 ),
+    d_isValid( false )
+{
+}
+
+/*!
+  Construct QwtScaleDiv instance.
+
+  \param interval Interval
+  \param ticks List of major, medium and minor ticks
+*/
+QwtScaleDiv::QwtScaleDiv( const QwtInterval &interval,
+        QList<double> ticks[NTickTypes] ):
+    d_lowerBound( interval.minValue() ),
+    d_upperBound( interval.maxValue() ),
+    d_isValid( true )
+{
+    for ( int i = 0; i < NTickTypes; i++ )
+        d_ticks[i] = ticks[i];
+}
+
+/*!
+  Construct QwtScaleDiv instance.
+
+  \param lowerBound First interval limit
+  \param upperBound Second interval limit
+  \param ticks List of major, medium and minor ticks
+*/
+QwtScaleDiv::QwtScaleDiv(
+        double lowerBound, double upperBound,
+        QList<double> ticks[NTickTypes] ):
+    d_lowerBound( lowerBound ),
+    d_upperBound( upperBound ),
+    d_isValid( true )
+{
+    for ( int i = 0; i < NTickTypes; i++ )
+        d_ticks[i] = ticks[i];
+}
+
+/*!
+   Change the interval
+   \param interval Interval
+*/
+void QwtScaleDiv::setInterval( const QwtInterval &interval )
+{
+    setInterval( interval.minValue(), interval.maxValue() );
+}
+
+/*!
+  \brief Equality operator
+  \return true if this instance is equal to other
+*/
+bool QwtScaleDiv::operator==( const QwtScaleDiv &other ) const
+{
+    if ( d_lowerBound != other.d_lowerBound ||
+        d_upperBound != other.d_upperBound ||
+        d_isValid != other.d_isValid )
+    {
+        return false;
+    }
+
+    for ( int i = 0; i < NTickTypes; i++ )
+    {
+        if ( d_ticks[i] != other.d_ticks[i] )
+            return false;
+    }
+
+    return true;
+}
+
+/*!
+  \brief Inequality
+  \return true if this instance is not equal to s
+*/
+bool QwtScaleDiv::operator!=( const QwtScaleDiv &s ) const
+{
+    return ( !( *this == s ) );
+}
+
+//! Invalidate the scale division
+void QwtScaleDiv::invalidate()
+{
+    d_isValid = false;
+
+    // detach arrays
+    for ( int i = 0; i < NTickTypes; i++ )
+        d_ticks[i].clear();
+
+    d_lowerBound = d_upperBound = 0;
+}
+
+//! Check if the scale division is valid
+bool QwtScaleDiv::isValid() const
+{
+    return d_isValid;
+}
+
+/*!
+  Return if a value is between lowerBound() and upperBound()
+
+  \param value Value
+  \return true/false
+*/
+bool QwtScaleDiv::contains( double value ) const
+{
+    if ( !d_isValid )
+        return false;
+
+    const double min = qMin( d_lowerBound, d_upperBound );
+    const double max = qMax( d_lowerBound, d_upperBound );
+
+    return value >= min && value <= max;
+}
+
+//! Invert the scale divison
+void QwtScaleDiv::invert()
+{
+    qSwap( d_lowerBound, d_upperBound );
+
+    for ( int i = 0; i < NTickTypes; i++ )
+    {
+        QList<double>& ticks = d_ticks[i];
+
+        const int size = ticks.count();
+        const int size2 = size / 2;
+
+        for ( int i = 0; i < size2; i++ )
+            qSwap( ticks[i], ticks[size - 1 - i] );
+    }
+}
+
+/*!
+    Assign ticks
+
+   \param type MinorTick, MediumTick or MajorTick
+   \param ticks Values of the tick positions
+*/
+void QwtScaleDiv::setTicks( int type, const QList<double> &ticks )
+{
+    if ( type >= 0 || type < NTickTypes )
+        d_ticks[type] = ticks;
+}
+
+/*!
+   Return a list of ticks
+
+   \param type MinorTick, MediumTick or MajorTick
+*/
+const QList<double> &QwtScaleDiv::ticks( int type ) const
+{
+    if ( type >= 0 || type < NTickTypes )
+        return d_ticks[type];
+
+    static QList<double> noTicks;
+    return noTicks;
+}
Index: trunk/BNC/qwt/qwt_scale_div.h
===================================================================
--- trunk/BNC/qwt/qwt_scale_div.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_div.h	(revision 4271)
@@ -0,0 +1,132 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_SCALE_DIV_H
+#define QWT_SCALE_DIV_H
+
+#include "qwt_global.h"
+#include "qwt_interval.h"
+#include <qlist.h>
+
+class QwtInterval;
+
+/*!
+  \brief A class representing a scale division
+
+  A scale division consists of its limits and 3 list
+  of tick values qualified as major, medium and minor ticks.
+
+  In most cases scale divisions are calculated by a QwtScaleEngine.
+
+  \sa subDivideInto(), subDivide()
+*/
+
+class QWT_EXPORT QwtScaleDiv
+{
+public:
+    //! Scale tick types
+    enum TickType
+    {
+        //! No ticks
+        NoTick = -1,
+
+        //! Minor ticks
+        MinorTick,
+
+        //! Medium ticks
+        MediumTick,
+
+        //! Major ticks
+        MajorTick,
+
+        //! Number of valid tick types
+        NTickTypes
+    };
+
+    explicit QwtScaleDiv();
+    explicit QwtScaleDiv( const QwtInterval &, QList<double>[NTickTypes] );
+    explicit QwtScaleDiv( 
+        double lowerBound, double upperBound, QList<double>[NTickTypes] );
+
+    bool operator==( const QwtScaleDiv &s ) const;
+    bool operator!=( const QwtScaleDiv &s ) const;
+
+    void setInterval( double lowerBound, double upperBound );
+    void setInterval( const QwtInterval & );
+    QwtInterval interval() const;
+
+    double lowerBound() const;
+    double upperBound() const;
+    double range() const;
+
+    bool contains( double v ) const;
+
+    void setTicks( int type, const QList<double> & );
+    const QList<double> &ticks( int type ) const;
+
+    void invalidate();
+    bool isValid() const;
+
+    void invert();
+
+private:
+    double d_lowerBound;
+    double d_upperBound;
+    QList<double> d_ticks[NTickTypes];
+
+    bool d_isValid;
+};
+
+Q_DECLARE_TYPEINFO(QwtScaleDiv, Q_MOVABLE_TYPE);
+
+/*!
+   Change the interval
+   \param lowerBound lower bound
+   \param upperBound upper bound
+*/
+inline void QwtScaleDiv::setInterval( double lowerBound, double upperBound )
+{
+    d_lowerBound = lowerBound;
+    d_upperBound = upperBound;
+}
+
+/*!
+  \return lowerBound -> upperBound
+*/
+inline QwtInterval QwtScaleDiv::interval() const
+{
+    return QwtInterval( d_lowerBound, d_upperBound );
+}
+
+/*!
+  \return lower bound
+  \sa upperBound()
+*/
+inline double QwtScaleDiv::lowerBound() const
+{
+    return d_lowerBound;
+}
+
+/*!
+  \return upper bound
+  \sa lowerBound()
+*/
+inline double QwtScaleDiv::upperBound() const
+{
+    return d_upperBound;
+}
+
+/*!
+  \return upperBound() - lowerBound()
+*/
+inline double QwtScaleDiv::range() const
+{
+    return d_upperBound - d_lowerBound;
+}
+#endif
Index: trunk/BNC/qwt/qwt_scale_draw.cpp
===================================================================
--- trunk/BNC/qwt/qwt_scale_draw.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_draw.cpp	(revision 4271)
@@ -0,0 +1,899 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_scale_draw.h"
+#include "qwt_scale_div.h"
+#include "qwt_scale_map.h"
+#include "qwt_math.h"
+#include "qwt_painter.h"
+#include <qpen.h>
+#include <qpainter.h>
+#include <qmath.h>
+
+class QwtScaleDraw::PrivateData
+{
+public:
+    PrivateData():
+        len( 0 ),
+        alignment( QwtScaleDraw::BottomScale ),
+        labelAlignment( 0 ),
+        labelRotation( 0.0 )
+    {
+    }
+
+    QPointF pos;
+    double len;
+
+    Alignment alignment;
+
+    Qt::Alignment labelAlignment;
+    double labelRotation;
+};
+
+/*!
+  \brief Constructor
+
+  The range of the scale is initialized to [0, 100],
+  The position is at (0, 0) with a length of 100.
+  The orientation is QwtAbstractScaleDraw::Bottom.
+*/
+QwtScaleDraw::QwtScaleDraw()
+{
+    d_data = new QwtScaleDraw::PrivateData;
+    setLength( 100 );
+}
+
+//! Destructor
+QwtScaleDraw::~QwtScaleDraw()
+{
+    delete d_data;
+}
+
+/*!
+   Return alignment of the scale
+   \sa setAlignment()
+*/
+QwtScaleDraw::Alignment QwtScaleDraw::alignment() const
+{
+    return d_data->alignment;
+}
+
+/*!
+   Set the alignment of the scale
+
+   The default alignment is QwtScaleDraw::BottomScale
+   \sa alignment()
+*/
+void QwtScaleDraw::setAlignment( Alignment align )
+{
+    d_data->alignment = align;
+}
+
+/*!
+  Return the orientation
+
+  TopScale, BottomScale are horizontal (Qt::Horizontal) scales,
+  LeftScale, RightScale are vertical (Qt::Vertical) scales.
+
+  \sa alignment()
+*/
+Qt::Orientation QwtScaleDraw::orientation() const
+{
+    switch ( d_data->alignment )
+    {
+        case TopScale:
+        case BottomScale:
+            return Qt::Horizontal;
+        case LeftScale:
+        case RightScale:
+        default:
+            return Qt::Vertical;
+    }
+}
+
+/*!
+  \brief Determine the minimum border distance
+
+  This member function returns the minimum space
+  needed to draw the mark labels at the scale's endpoints.
+
+  \param font Font
+  \param start Start border distance
+  \param end End border distance
+*/
+void QwtScaleDraw::getBorderDistHint( const QFont &font,
+                                      int &start, int &end ) const
+{
+    start = 0;
+    end = 0;
+
+    if ( !hasComponent( QwtAbstractScaleDraw::Labels ) )
+        return;
+
+    const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
+    if ( ticks.count() == 0 )
+        return;
+
+    // Find the ticks, that are mapped to the borders.
+    // minTick is the tick, that is mapped to the top/left-most position
+    // in widget coordinates.
+
+    double minTick = ticks[0];
+    double minPos = scaleMap().transform( minTick );
+    double maxTick = minTick;
+    double maxPos = minPos;
+
+    for ( int i = 1; i < ticks.count(); i++ )
+    {
+        const double tickPos = scaleMap().transform( ticks[i] );
+        if ( tickPos < minPos )
+        {
+            minTick = ticks[i];
+            minPos = tickPos;
+        }
+        if ( tickPos > scaleMap().transform( maxTick ) )
+        {
+            maxTick = ticks[i];
+            maxPos = tickPos;
+        }
+    }
+
+    double e = 0.0;
+    double s = 0.0;
+    if ( orientation() == Qt::Vertical )
+    {
+        s = -labelRect( font, minTick ).top();
+        s -= qAbs( minPos - qRound( scaleMap().p2() ) );
+
+        e = labelRect( font, maxTick ).bottom();
+        e -= qAbs( maxPos - scaleMap().p1() );
+    }
+    else
+    {
+        s = -labelRect( font, minTick ).left();
+        s -= qAbs( minPos - scaleMap().p1() );
+
+        e = labelRect( font, maxTick ).right();
+        e -= qAbs( maxPos - scaleMap().p2() );
+    }
+
+    if ( s < 0.0 )
+        s = 0.0;
+    if ( e < 0.0 )
+        e = 0.0;
+
+    start = qCeil( s );
+    end = qCeil( e );
+}
+
+/*!
+  Determine the minimum distance between two labels, that is necessary
+  that the texts don't overlap.
+
+  \param font Font
+  \return The maximum width of a label
+
+  \sa getBorderDistHint()
+*/
+
+int QwtScaleDraw::minLabelDist( const QFont &font ) const
+{
+    if ( !hasComponent( QwtAbstractScaleDraw::Labels ) )
+        return 0;
+
+    const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
+    if ( ticks.count() == 0 )
+        return 0;
+
+    const QFontMetrics fm( font );
+
+    const bool vertical = ( orientation() == Qt::Vertical );
+
+    QRectF bRect1;
+    QRectF bRect2 = labelRect( font, ticks[0] );
+    if ( vertical )
+    {
+        bRect2.setRect( -bRect2.bottom(), 0, bRect2.height(), bRect2.width() );
+    }
+    int maxDist = 0;
+
+    for ( int i = 1; i < ticks.count(); i++ )
+    {
+        bRect1 = bRect2;
+        bRect2 = labelRect( font, ticks[i] );
+        if ( vertical )
+        {
+            bRect2.setRect( -bRect2.bottom(), 0,
+                bRect2.height(), bRect2.width() );
+        }
+
+        int dist = fm.leading(); // space between the labels
+        if ( bRect1.right() > 0 )
+            dist += bRect1.right();
+        if ( bRect2.left() < 0 )
+            dist += -bRect2.left();
+
+        if ( dist > maxDist )
+            maxDist = dist;
+    }
+
+    double angle = labelRotation() / 180.0 * M_PI;
+    if ( vertical )
+        angle += M_PI / 2;
+
+    if ( qSin( angle ) == 0.0 )
+        return maxDist;
+
+    const int fmHeight = fm.ascent() - 2;
+
+    // The distance we need until there is
+    // the height of the label font. This height is needed
+    // for the neighbour labal.
+
+    int labelDist = qFloor( fmHeight / qSin( angle ) * qCos( angle ) );
+    if ( labelDist < 0 )
+        labelDist = -labelDist;
+
+    // The cast above floored labelDist. We want to ceil.
+    labelDist++;
+
+    // For text orientations close to the scale orientation
+
+    if ( labelDist > maxDist )
+        labelDist = maxDist;
+
+    // For text orientations close to the opposite of the
+    // scale orientation
+
+    if ( labelDist < fmHeight )
+        labelDist = fmHeight;
+
+    return labelDist;
+}
+
+/*!
+   Calculate the width/height that is needed for a
+   vertical/horizontal scale.
+
+   The extent is calculated from the pen width of the backbone,
+   the major tick length, the spacing and the maximum width/height
+   of the labels.
+
+   \param font Font used for painting the labels
+
+   \sa minLength()
+*/
+double QwtScaleDraw::extent( const QFont &font ) const
+{
+    double d = 0;
+
+    if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
+    {
+        if ( orientation() == Qt::Vertical )
+            d = maxLabelWidth( font );
+        else
+            d = maxLabelHeight( font );
+
+        if ( d > 0 )
+            d += spacing();
+    }
+
+    if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
+    {
+        d += maxTickLength();
+    }
+
+    if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
+    {
+        const double pw = qMax( 1, penWidth() );  // penwidth can be zero
+        d += pw;
+    }
+
+    d = qMax( d, minimumExtent() );
+    return d;
+}
+
+/*!
+   Calculate the minimum length that is needed to draw the scale
+
+   \param font Font used for painting the labels
+
+   \sa extent()
+*/
+int QwtScaleDraw::minLength( const QFont &font ) const
+{
+    int startDist, endDist;
+    getBorderDistHint( font, startDist, endDist );
+
+    const QwtScaleDiv &sd = scaleDiv();
+
+    const uint minorCount =
+        sd.ticks( QwtScaleDiv::MinorTick ).count() +
+        sd.ticks( QwtScaleDiv::MediumTick ).count();
+    const uint majorCount =
+        sd.ticks( QwtScaleDiv::MajorTick ).count();
+
+    int lengthForLabels = 0;
+    if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
+        lengthForLabels = minLabelDist( font ) * majorCount;
+
+    int lengthForTicks = 0;
+    if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
+    {
+        const double pw = qMax( 1, penWidth() );  // penwidth can be zero
+        lengthForTicks = qCeil( ( majorCount + minorCount ) * ( pw + 1.0 ) );
+    }
+
+    return startDist + endDist + qMax( lengthForLabels, lengthForTicks );
+}
+
+/*!
+   Find the position, where to paint a label
+
+   The position has a distance of majTickLength() + spacing() + 1
+   from the backbone. The direction depends on the alignment()
+
+   \param value Value
+*/
+QPointF QwtScaleDraw::labelPosition( double value ) const
+{
+    const double tval = scaleMap().transform( value );
+    double dist = spacing();
+    if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
+        dist += qMax( 1, penWidth() );
+
+    if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
+        dist += tickLength( QwtScaleDiv::MajorTick );
+
+    double px = 0;
+    double py = 0;
+
+    switch ( alignment() )
+    {
+        case RightScale:
+        {
+            px = d_data->pos.x() + dist;
+            py = tval;
+            break;
+        }
+        case LeftScale:
+        {
+            px = d_data->pos.x() - dist;
+            py = tval;
+            break;
+        }
+        case BottomScale:
+        {
+            px = tval;
+            py = d_data->pos.y() + dist;
+            break;
+        }
+        case TopScale:
+        {
+            px = tval;
+            py = d_data->pos.y() - dist;
+            break;
+        }
+    }
+
+    return QPointF( px, py );
+}
+
+/*!
+   Draw a tick
+
+   \param painter Painter
+   \param value Value of the tick
+   \param len Lenght of the tick
+
+   \sa drawBackbone(), drawLabel()
+*/
+void QwtScaleDraw::drawTick( QPainter *painter, double value, double len ) const
+{
+    if ( len <= 0 )
+        return;
+
+    const bool roundingAlignment = QwtPainter::roundingAlignment( painter );
+
+    QPointF pos = d_data->pos;
+
+    double tval = scaleMap().transform( value );
+    if ( roundingAlignment )
+        tval = qRound( tval );
+
+    const int pw = penWidth();
+    int a = 0;
+    if ( pw > 1 && roundingAlignment )
+        a = 1;
+
+    switch ( alignment() )
+    {
+        case LeftScale:
+        {
+            double x1 = pos.x() + a;
+            double x2 = pos.x() + a - pw - len;
+            if ( roundingAlignment )
+            {
+                x1 = qRound( x1 );
+                x2 = qRound( x2 );
+            }
+
+            QwtPainter::drawLine( painter, x1, tval, x2, tval );
+            break;
+        }
+
+        case RightScale:
+        {
+            double x1 = pos.x();
+            double x2 = pos.x() + pw + len;
+            if ( roundingAlignment )
+            {
+                x1 = qRound( x1 );
+                x2 = qRound( x2 );
+            }
+
+            QwtPainter::drawLine( painter, x1, tval, x2, tval );
+            break;
+        }
+
+        case BottomScale:
+        {
+            double y1 = pos.y();
+            double y2 = pos.y() + pw + len;
+            if ( roundingAlignment )
+            {
+                y1 = qRound( y1 );
+                y2 = qRound( y2 );
+            }
+
+            QwtPainter::drawLine( painter, tval, y1, tval, y2 );
+            break;
+        }
+
+        case TopScale:
+        {
+            double y1 = pos.y() + a;
+            double y2 = pos.y() - pw - len + a;
+            if ( roundingAlignment )
+            {
+                y1 = qRound( y1 );
+                y2 = qRound( y2 );
+            }
+
+            QwtPainter::drawLine( painter, tval, y1, tval, y2 );
+            break;
+        }
+    }
+}
+
+/*!
+   Draws the baseline of the scale
+   \param painter Painter
+
+   \sa drawTick(), drawLabel()
+*/
+void QwtScaleDraw::drawBackbone( QPainter *painter ) const
+{
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    const QPointF &pos = d_data->pos;
+    const double len = d_data->len;
+    const int pw = qMax( penWidth(), 1 );
+
+    // pos indicates a border not the center of the backbone line
+    // so we need to shift its position depending on the pen width
+    // and the alignment of the scale
+
+    double off;
+    if ( doAlign )
+    {
+        if ( alignment() == LeftScale || alignment() == TopScale )
+            off = ( pw - 1 ) / 2;
+        else
+            off = pw / 2;
+    }
+    else
+    {
+        off = 0.5 * penWidth();
+    }
+
+    switch ( alignment() )
+    {
+        case LeftScale:
+        {
+            double x = pos.x() - off;
+            if ( doAlign )
+                x = qRound( x );
+
+            QwtPainter::drawLine( painter, x, pos.y(), x, pos.y() + len );
+            break;
+        }
+        case RightScale:
+        {
+            double x = pos.x() + off;
+            if ( doAlign )
+                x = qRound( x );
+
+            QwtPainter::drawLine( painter, x, pos.y(), x, pos.y() + len );
+            break;
+        }
+        case TopScale:
+        {
+            double y = pos.y() - off;
+            if ( doAlign )
+                y = qRound( y );
+
+            QwtPainter::drawLine( painter, pos.x(), y, pos.x() + len, y );
+            break;
+        }
+        case BottomScale:
+        {
+            double y = pos.y() + off;
+            if ( doAlign )
+                y = qRound( y );
+
+            QwtPainter::drawLine( painter, pos.x(), y, pos.x() + len, y );
+            break;
+        }
+    }
+}
+
+/*!
+  \brief Move the position of the scale
+
+  The meaning of the parameter pos depends on the alignment:
+  <dl>
+  <dt>QwtScaleDraw::LeftScale
+  <dd>The origin is the topmost point of the
+      backbone. The backbone is a vertical line.
+      Scale marks and labels are drawn
+      at the left of the backbone.
+  <dt>QwtScaleDraw::RightScale
+  <dd>The origin is the topmost point of the
+      backbone. The backbone is a vertical line.
+      Scale marks and labels are drawn
+      at the right of the backbone.
+  <dt>QwtScaleDraw::TopScale
+  <dd>The origin is the leftmost point of the
+      backbone. The backbone is a horizontal line.
+      Scale marks and labels are drawn
+      above the backbone.
+  <dt>QwtScaleDraw::BottomScale
+  <dd>The origin is the leftmost point of the
+      backbone. The backbone is a horizontal line
+      Scale marks and labels are drawn
+      below the backbone.
+  </dl>
+
+  \param pos Origin of the scale
+
+  \sa pos(), setLength()
+*/
+void QwtScaleDraw::move( const QPointF &pos )
+{
+    d_data->pos = pos;
+    updateMap();
+}
+
+/*!
+   \return Origin of the scale
+   \sa move(), length()
+*/
+QPointF QwtScaleDraw::pos() const
+{
+    return d_data->pos;
+}
+
+/*!
+  Set the length of the backbone.
+
+  The length doesn't include the space needed for
+  overlapping labels.
+
+  \sa move(), minLabelDist()
+*/
+void QwtScaleDraw::setLength( double length )
+{
+    if ( length >= 0 && length < 10 )
+        length = 10;
+    if ( length < 0 && length > -10 )
+        length = -10;
+
+    d_data->len = length;
+    updateMap();
+}
+
+/*!
+   \return the length of the backbone
+   \sa setLength(), pos()
+*/
+double QwtScaleDraw::length() const
+{
+    return d_data->len;
+}
+
+/*!
+   Draws the label for a major scale tick
+
+   \param painter Painter
+   \param value Value
+
+   \sa drawTick(), drawBackbone(), boundingLabelRect()
+*/
+void QwtScaleDraw::drawLabel( QPainter *painter, double value ) const
+{
+    QwtText lbl = tickLabel( painter->font(), value );
+    if ( lbl.isEmpty() )
+        return;
+
+    QPointF pos = labelPosition( value );
+
+    QSizeF labelSize = lbl.textSize( painter->font() );
+
+    const QTransform transform = labelTransformation( pos, labelSize );
+
+    painter->save();
+    painter->setWorldTransform( transform, true );
+
+    lbl.draw ( painter, QRect( QPoint( 0, 0 ), labelSize.toSize() ) );
+
+    painter->restore();
+}
+
+/*!
+  Find the bounding rect for the label. The coordinates of
+  the rect are absolute coordinates ( calculated from pos() ).
+  in direction of the tick.
+
+  \param font Font used for painting
+  \param value Value
+
+  \sa labelRect()
+*/
+QRect QwtScaleDraw::boundingLabelRect( const QFont &font, double value ) const
+{
+    QwtText lbl = tickLabel( font, value );
+    if ( lbl.isEmpty() )
+        return QRect();
+
+    const QPointF pos = labelPosition( value );
+    QSizeF labelSize = lbl.textSize( font );
+
+    const QTransform transform = labelTransformation( pos, labelSize );
+    return transform.mapRect( QRect( QPoint( 0, 0 ), labelSize.toSize() ) );
+}
+
+/*!
+   Calculate the transformation that is needed to paint a label
+   depending on its alignment and rotation.
+
+   \param pos Position where to paint the label
+   \param size Size of the label
+
+   \sa setLabelAlignment(), setLabelRotation()
+*/
+QTransform QwtScaleDraw::labelTransformation(
+    const QPointF &pos, const QSizeF &size ) const
+{
+    QTransform transform;
+    transform.translate( pos.x(), pos.y() );
+    transform.rotate( labelRotation() );
+
+    int flags = labelAlignment();
+    if ( flags == 0 )
+    {
+        switch ( alignment() )
+        {
+            case RightScale:
+            {
+                if ( flags == 0 )
+                    flags = Qt::AlignRight | Qt::AlignVCenter;
+                break;
+            }
+            case LeftScale:
+            {
+                if ( flags == 0 )
+                    flags = Qt::AlignLeft | Qt::AlignVCenter;
+                break;
+            }
+            case BottomScale:
+            {
+                if ( flags == 0 )
+                    flags = Qt::AlignHCenter | Qt::AlignBottom;
+                break;
+            }
+            case TopScale:
+            {
+                if ( flags == 0 )
+                    flags = Qt::AlignHCenter | Qt::AlignTop;
+                break;
+            }
+        }
+    }
+
+    double x, y;
+
+    if ( flags & Qt::AlignLeft )
+        x = -size.width();
+    else if ( flags & Qt::AlignRight )
+        x = 0.0;
+    else // Qt::AlignHCenter
+        x = -( 0.5 * size.width() );
+
+    if ( flags & Qt::AlignTop )
+        y = -size.height();
+    else if ( flags & Qt::AlignBottom )
+        y = 0;
+    else // Qt::AlignVCenter
+        y = -( 0.5 * size.height() );
+
+    transform.translate( x, y );
+
+    return transform;
+}
+
+/*!
+  Find the bounding rect for the label. The coordinates of
+  the rect are relative to spacing + ticklength from the backbone
+  in direction of the tick.
+
+  \param font Font used for painting
+  \param value Value
+*/
+QRectF QwtScaleDraw::labelRect( const QFont &font, double value ) const
+{
+    QwtText lbl = tickLabel( font, value );
+    if ( lbl.isEmpty() )
+        return QRectF( 0.0, 0.0, 0.0, 0.0 );
+
+    const QPointF pos = labelPosition( value );
+
+    const QSizeF labelSize = lbl.textSize( font );
+    const QTransform transform = labelTransformation( pos, labelSize );
+
+    QRectF br = transform.mapRect( QRectF( QPointF( 0, 0 ), labelSize ) );
+    br.translate( -pos.x(), -pos.y() );
+
+    return br;
+}
+
+/*!
+   Calculate the size that is needed to draw a label
+
+   \param font Label font
+   \param value Value
+*/
+QSizeF QwtScaleDraw::labelSize( const QFont &font, double value ) const
+{
+    return labelRect( font, value ).size();
+}
+
+/*!
+  Rotate all labels.
+
+  When changing the rotation, it might be necessary to
+  adjust the label flags too. Finding a useful combination is
+  often the result of try and error.
+
+  \param rotation Angle in degrees. When changing the label rotation,
+                  the label flags often needs to be adjusted too.
+
+  \sa setLabelAlignment(), labelRotation(), labelAlignment().
+
+*/
+void QwtScaleDraw::setLabelRotation( double rotation )
+{
+    d_data->labelRotation = rotation;
+}
+
+/*!
+  \return the label rotation
+  \sa setLabelRotation(), labelAlignment()
+*/
+double QwtScaleDraw::labelRotation() const
+{
+    return d_data->labelRotation;
+}
+
+/*!
+  \brief Change the label flags
+
+  Labels are aligned to the point ticklength + spacing away from the backbone.
+
+  The alignment is relative to the orientation of the label text.
+  In case of an flags of 0 the label will be aligned
+  depending on the orientation of the scale:
+
+      QwtScaleDraw::TopScale: Qt::AlignHCenter | Qt::AlignTop\n
+      QwtScaleDraw::BottomScale: Qt::AlignHCenter | Qt::AlignBottom\n
+      QwtScaleDraw::LeftScale: Qt::AlignLeft | Qt::AlignVCenter\n
+      QwtScaleDraw::RightScale: Qt::AlignRight | Qt::AlignVCenter\n
+
+  Changing the alignment is often necessary for rotated labels.
+
+  \param alignment Or'd Qt::AlignmentFlags see <qnamespace.h>
+
+  \sa setLabelRotation(), labelRotation(), labelAlignment()
+  \warning The various alignments might be confusing.
+           The alignment of the label is not the alignment
+           of the scale and is not the alignment of the flags
+           (QwtText::flags()) returned from QwtAbstractScaleDraw::label().
+*/
+
+void QwtScaleDraw::setLabelAlignment( Qt::Alignment alignment )
+{
+    d_data->labelAlignment = alignment;
+}
+
+/*!
+  \return the label flags
+  \sa setLabelAlignment(), labelRotation()
+*/
+Qt::Alignment QwtScaleDraw::labelAlignment() const
+{
+    return d_data->labelAlignment;
+}
+
+/*!
+  \param font Font
+  \return the maximum width of a label
+*/
+int QwtScaleDraw::maxLabelWidth( const QFont &font ) const
+{
+    int maxWidth = 0;
+
+    const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
+    for ( int i = 0; i < ticks.count(); i++ )
+    {
+        const double v = ticks[i];
+        if ( scaleDiv().contains( v ) )
+        {
+            const int w = labelSize( font, ticks[i] ).width();
+            if ( w > maxWidth )
+                maxWidth = w;
+        }
+    }
+
+    return maxWidth;
+}
+
+/*!
+  \param font Font
+  \return the maximum height of a label
+*/
+int QwtScaleDraw::maxLabelHeight( const QFont &font ) const
+{
+    int maxHeight = 0;
+
+    const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
+    for ( int i = 0; i < ticks.count(); i++ )
+    {
+        const double v = ticks[i];
+        if ( scaleDiv().contains( v ) )
+        {
+            const int h = labelSize( font, ticks[i] ).height();
+            if ( h > maxHeight )
+                maxHeight = h;
+        }
+    }
+
+    return maxHeight;
+}
+
+void QwtScaleDraw::updateMap()
+{
+    const QPointF pos = d_data->pos;
+    double len = d_data->len;
+
+    QwtScaleMap &sm = scaleMap();
+    if ( orientation() == Qt::Vertical )
+        sm.setPaintInterval( pos.y() + len, pos.y() );
+    else
+        sm.setPaintInterval( pos.x(), pos.x() + len );
+}
Index: trunk/BNC/qwt/qwt_scale_draw.h
===================================================================
--- trunk/BNC/qwt/qwt_scale_draw.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_draw.h	(revision 4271)
@@ -0,0 +1,117 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_SCALE_DRAW_H
+#define QWT_SCALE_DRAW_H
+
+#include "qwt_global.h"
+#include "qwt_abstract_scale_draw.h"
+#include <qpoint.h>
+#include <qrect.h>
+#include <qtransform.h>
+
+/*!
+  \brief A class for drawing scales
+
+  QwtScaleDraw can be used to draw linear or logarithmic scales.
+  A scale has a position, an alignment and a length, which can be specified .
+  The labels can be rotated and aligned
+  to the ticks using setLabelRotation() and setLabelAlignment().
+
+  After a scale division has been specified as a QwtScaleDiv object
+  using QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s),
+  the scale can be drawn with the QwtAbstractScaleDraw::draw() member.
+*/
+
+class QWT_EXPORT QwtScaleDraw: public QwtAbstractScaleDraw
+{
+public:
+    /*!
+        Alignment of the scale draw
+        \sa setAlignment(), alignment()
+     */
+    enum Alignment 
+    { 
+        //! The scale is below
+        BottomScale, 
+
+        //! The scale is above
+        TopScale, 
+
+        //! The scale is left
+        LeftScale, 
+
+        //! The scale is right
+        RightScale 
+    };
+
+    QwtScaleDraw();
+    virtual ~QwtScaleDraw();
+
+    void getBorderDistHint( const QFont &, int &start, int &end ) const;
+    int minLabelDist( const QFont & ) const;
+
+    int minLength( const QFont & ) const;
+    virtual double extent( const QFont & ) const;
+
+    void move( double x, double y );
+    void move( const QPointF & );
+    void setLength( double length );
+
+    Alignment alignment() const;
+    void setAlignment( Alignment );
+
+    Qt::Orientation orientation() const;
+
+    QPointF pos() const;
+    double length() const;
+
+    void setLabelAlignment( Qt::Alignment );
+    Qt::Alignment labelAlignment() const;
+
+    void setLabelRotation( double rotation );
+    double labelRotation() const;
+
+    int maxLabelHeight( const QFont & ) const;
+    int maxLabelWidth( const QFont & ) const;
+
+    QPointF labelPosition( double val ) const;
+
+    QRectF labelRect( const QFont &, double val ) const;
+    QSizeF labelSize( const QFont &, double val ) const;
+
+    QRect boundingLabelRect( const QFont &, double val ) const;
+
+protected:
+    QTransform labelTransformation( const QPointF &, const QSizeF & ) const;
+
+    virtual void drawTick( QPainter *, double val, double len ) const;
+    virtual void drawBackbone( QPainter * ) const;
+    virtual void drawLabel( QPainter *, double val ) const;
+
+private:
+    QwtScaleDraw( const QwtScaleDraw & );
+    QwtScaleDraw &operator=( const QwtScaleDraw &other );
+
+    void updateMap();
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+/*!
+   Move the position of the scale
+   \sa move(const QPointF &)
+*/
+inline void QwtScaleDraw::move( double x, double y )
+{
+    move( QPointF( x, y ) );
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_scale_engine.cpp
===================================================================
--- trunk/BNC/qwt/qwt_scale_engine.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_engine.cpp	(revision 4271)
@@ -0,0 +1,942 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_scale_engine.h"
+#include "qwt_math.h"
+#include "qwt_scale_map.h"
+#include <qalgorithms.h>
+#include <qmath.h>
+
+#if QT_VERSION < 0x040601
+#define qFabs(x) ::fabs(x)
+#define qExp(x) ::exp(x)
+#endif
+
+static const double _eps = 1.0e-6;
+
+/*!
+  Ceil a value, relative to an interval
+
+  \param value Value to ceil
+  \param intervalSize Interval size
+
+  \sa floorEps()
+*/
+double QwtScaleArithmetic::ceilEps( double value,
+    double intervalSize )
+{
+    const double eps = _eps * intervalSize;
+
+    value = ( value - eps ) / intervalSize;
+    return qwtCeilF( value ) * intervalSize;
+}
+
+/*!
+  Floor a value, relative to an interval
+
+  \param value Value to floor
+  \param intervalSize Interval size
+
+  \sa floorEps()
+*/
+double QwtScaleArithmetic::floorEps( double value, double intervalSize )
+{
+    const double eps = _eps * intervalSize;
+
+    value = ( value + eps ) / intervalSize;
+    return qwtFloorF( value ) * intervalSize;
+}
+
+/*!
+  \brief Divide an interval into steps
+
+  \f$stepSize = (intervalSize - intervalSize * 10e^{-6}) / numSteps\f$
+
+  \param intervalSize Interval size
+  \param numSteps Number of steps
+  \return Step size
+*/
+double QwtScaleArithmetic::divideEps( double intervalSize, double numSteps )
+{
+    if ( numSteps == 0.0 || intervalSize == 0.0 )
+        return 0.0;
+
+    return ( intervalSize - ( _eps * intervalSize ) ) / numSteps;
+}
+
+/*!
+  Find the smallest value out of {1,2,5}*10^n with an integer number n
+  which is greater than or equal to x
+
+  \param x Input value
+*/
+double QwtScaleArithmetic::ceil125( double x )
+{
+    if ( x == 0.0 )
+        return 0.0;
+
+    const double sign = ( x > 0 ) ? 1.0 : -1.0;
+    const double lx = ::log10( qFabs( x ) );
+    const double p10 = qwtFloorF( lx );
+
+    double fr = qPow( 10.0, lx - p10 );
+    if ( fr <= 1.0 )
+        fr = 1.0;
+    else if ( fr <= 2.0 )
+        fr = 2.0;
+    else if ( fr <= 5.0 )
+        fr = 5.0;
+    else
+        fr = 10.0;
+
+    return sign * fr * qPow( 10.0, p10 );
+}
+
+/*!
+  \brief Find the largest value out of {1,2,5}*10^n with an integer number n
+  which is smaller than or equal to x
+
+  \param x Input value
+*/
+double QwtScaleArithmetic::floor125( double x )
+{
+    if ( x == 0.0 )
+        return 0.0;
+
+    double sign = ( x > 0 ) ? 1.0 : -1.0;
+    const double lx = ::log10( qFabs( x ) );
+    const double p10 = qwtFloorF( lx );
+
+    double fr = qPow( 10.0, lx - p10 );
+    if ( fr >= 10.0 )
+        fr = 10.0;
+    else if ( fr >= 5.0 )
+        fr = 5.0;
+    else if ( fr >= 2.0 )
+        fr = 2.0;
+    else
+        fr = 1.0;
+
+    return sign * fr * qPow( 10.0, p10 );
+}
+
+class QwtScaleEngine::PrivateData
+{
+public:
+    PrivateData():
+        attributes( QwtScaleEngine::NoAttribute ),
+        lowerMargin( 0.0 ),
+        upperMargin( 0.0 ),
+        referenceValue( 0.0 )
+    {
+    }
+
+    QwtScaleEngine::Attributes attributes;       // scale attributes
+
+    double lowerMargin;      // margins
+    double upperMargin;
+
+    double referenceValue; // reference value
+
+};
+
+//! Constructor
+QwtScaleEngine::QwtScaleEngine()
+{
+    d_data = new PrivateData;
+}
+
+
+//! Destructor
+QwtScaleEngine::~QwtScaleEngine ()
+{
+    delete d_data;
+}
+
+/*!
+    \return the margin at the lower end of the scale
+    The default margin is 0.
+
+    \sa setMargins()
+*/
+double QwtScaleEngine::lowerMargin() const
+{
+    return d_data->lowerMargin;
+}
+
+/*!
+    \return the margin at the upper end of the scale
+    The default margin is 0.
+
+    \sa setMargins()
+*/
+double QwtScaleEngine::upperMargin() const
+{
+    return d_data->upperMargin;
+}
+
+/*!
+  \brief Specify margins at the scale's endpoints
+  \param lower minimum distance between the scale's lower boundary and the
+             smallest enclosed value
+  \param upper minimum distance between the scale's upper boundary and the
+             greatest enclosed value
+
+  Margins can be used to leave a minimum amount of space between
+  the enclosed intervals and the boundaries of the scale.
+
+  \warning
+  \li QwtLog10ScaleEngine measures the margins in decades.
+
+  \sa upperMargin(), lowerMargin()
+*/
+
+void QwtScaleEngine::setMargins( double lower, double upper )
+{
+    d_data->lowerMargin = qMax( lower, 0.0 );
+    d_data->upperMargin = qMax( upper, 0.0 );
+}
+
+/*!
+  Calculate a step size for an interval size
+
+  \param intervalSize Interval size
+  \param numSteps Number of steps
+
+  \return Step size
+*/
+double QwtScaleEngine::divideInterval(
+    double intervalSize, int numSteps ) const
+{
+    if ( numSteps <= 0 )
+        return 0.0;
+
+    double v = QwtScaleArithmetic::divideEps( intervalSize, numSteps );
+    return QwtScaleArithmetic::ceil125( v );
+}
+
+/*!
+  Check if an interval "contains" a value
+
+  \param interval Interval
+  \param value Value
+
+  \sa QwtScaleArithmetic::compareEps()
+*/
+bool QwtScaleEngine::contains(
+    const QwtInterval &interval, double value ) const
+{
+    if ( !interval.isValid() )
+        return false;
+
+    if ( qwtFuzzyCompare( value, interval.minValue(), interval.width() ) < 0 )
+        return false;
+
+    if ( qwtFuzzyCompare( value, interval.maxValue(), interval.width() ) > 0 )
+        return false;
+
+    return true;
+}
+
+/*!
+  Remove ticks from a list, that are not inside an interval
+
+  \param ticks Tick list
+  \param interval Interval
+
+  \return Stripped tick list
+*/
+QList<double> QwtScaleEngine::strip( const QList<double>& ticks,
+    const QwtInterval &interval ) const
+{
+    if ( !interval.isValid() || ticks.count() == 0 )
+        return QList<double>();
+
+    if ( contains( interval, ticks.first() )
+        && contains( interval, ticks.last() ) )
+    {
+        return ticks;
+    }
+
+    QList<double> strippedTicks;
+    for ( int i = 0; i < ticks.count(); i++ )
+    {
+        if ( contains( interval, ticks[i] ) )
+            strippedTicks += ticks[i];
+    }
+    return strippedTicks;
+}
+
+/*!
+  \brief Build an interval for a value
+
+  In case of v == 0.0 the interval is [-0.5, 0.5],
+  otherwide it is [0.5 * v, 1.5 * v]
+*/
+
+QwtInterval QwtScaleEngine::buildInterval( double v ) const
+{
+    const double delta = ( v == 0.0 ) ? 0.5 : qAbs( 0.5 * v );
+    return QwtInterval( v - delta, v + delta );
+}
+
+/*!
+  Change a scale attribute
+
+  \param attribute Attribute to change
+  \param on On/Off
+
+  \sa Attribute, testAttribute()
+*/
+void QwtScaleEngine::setAttribute( Attribute attribute, bool on )
+{
+    if ( on )
+        d_data->attributes |= attribute;
+    else
+        d_data->attributes &= ~attribute;
+}
+
+/*!
+  Check if a attribute is set.
+
+  \param attribute Attribute to be tested
+  \sa Attribute, setAttribute()
+*/
+bool QwtScaleEngine::testAttribute( Attribute attribute ) const
+{
+    return ( d_data->attributes & attribute );
+}
+
+/*!
+  Change the scale attribute
+
+  \param attributes Set scale attributes
+  \sa Attribute, attributes()
+*/
+void QwtScaleEngine::setAttributes( Attributes attributes )
+{
+    d_data->attributes = attributes;
+}
+
+/*!
+  Return the scale attributes
+  \sa Attribute, setAttributes(), testAttribute()
+*/
+QwtScaleEngine::Attributes QwtScaleEngine::attributes() const
+{
+    return d_data->attributes;
+}
+
+/*!
+  \brief Specify a reference point
+  \param r new reference value
+
+  The reference point is needed if options IncludeReference or
+  Symmetric are active. Its default value is 0.0.
+
+  \sa Attribute
+*/
+void QwtScaleEngine::setReference( double r )
+{
+    d_data->referenceValue = r;
+}
+
+/*!
+ \return the reference value
+ \sa setReference(), setAttribute()
+*/
+double QwtScaleEngine::reference() const
+{
+    return d_data->referenceValue;
+}
+
+/*!
+  Return a transformation, for linear scales
+*/
+QwtScaleTransformation *QwtLinearScaleEngine::transformation() const
+{
+    return new QwtScaleTransformation( QwtScaleTransformation::Linear );
+}
+
+/*!
+    Align and divide an interval
+
+   \param maxNumSteps Max. number of steps
+   \param x1 First limit of the interval (In/Out)
+   \param x2 Second limit of the interval (In/Out)
+   \param stepSize Step size (Out)
+
+   \sa setAttribute()
+*/
+void QwtLinearScaleEngine::autoScale( int maxNumSteps,
+    double &x1, double &x2, double &stepSize ) const
+{
+    QwtInterval interval( x1, x2 );
+    interval = interval.normalized();
+
+    interval.setMinValue( interval.minValue() - lowerMargin() );
+    interval.setMaxValue( interval.maxValue() + upperMargin() );
+
+    if ( testAttribute( QwtScaleEngine::Symmetric ) )
+        interval = interval.symmetrize( reference() );
+
+    if ( testAttribute( QwtScaleEngine::IncludeReference ) )
+        interval = interval.extend( reference() );
+
+    if ( interval.width() == 0.0 )
+        interval = buildInterval( interval.minValue() );
+
+    stepSize = divideInterval( interval.width(), qMax( maxNumSteps, 1 ) );
+
+    if ( !testAttribute( QwtScaleEngine::Floating ) )
+        interval = align( interval, stepSize );
+
+    x1 = interval.minValue();
+    x2 = interval.maxValue();
+
+    if ( testAttribute( QwtScaleEngine::Inverted ) )
+    {
+        qSwap( x1, x2 );
+        stepSize = -stepSize;
+    }
+}
+
+/*!
+   \brief Calculate a scale division
+
+   \param x1 First interval limit
+   \param x2 Second interval limit
+   \param maxMajSteps Maximum for the number of major steps
+   \param maxMinSteps Maximum number of minor steps
+   \param stepSize Step size. If stepSize == 0, the scaleEngine
+                   calculates one.
+
+   \sa QwtScaleEngine::stepSize(), QwtScaleEngine::subDivide()
+*/
+QwtScaleDiv QwtLinearScaleEngine::divideScale( double x1, double x2,
+    int maxMajSteps, int maxMinSteps, double stepSize ) const
+{
+    QwtInterval interval = QwtInterval( x1, x2 ).normalized();
+    if ( interval.width() <= 0 )
+        return QwtScaleDiv();
+
+    stepSize = qAbs( stepSize );
+    if ( stepSize == 0.0 )
+    {
+        if ( maxMajSteps < 1 )
+            maxMajSteps = 1;
+
+        stepSize = divideInterval( interval.width(), maxMajSteps );
+    }
+
+    QwtScaleDiv scaleDiv;
+
+    if ( stepSize != 0.0 )
+    {
+        QList<double> ticks[QwtScaleDiv::NTickTypes];
+        buildTicks( interval, stepSize, maxMinSteps, ticks );
+
+        scaleDiv = QwtScaleDiv( interval, ticks );
+    }
+
+    if ( x1 > x2 )
+        scaleDiv.invert();
+
+    return scaleDiv;
+}
+
+/*!
+   \brief Calculate ticks for an interval
+
+   \param interval Interval
+   \param stepSize Step size
+   \param maxMinSteps Maximum number of minor steps
+   \param ticks Arrays to be filled with the calculated ticks
+
+   \sa buildMajorTicks(), buildMinorTicks
+*/
+void QwtLinearScaleEngine::buildTicks(
+    const QwtInterval& interval, double stepSize, int maxMinSteps,
+    QList<double> ticks[QwtScaleDiv::NTickTypes] ) const
+{
+    const QwtInterval boundingInterval =
+        align( interval, stepSize );
+
+    ticks[QwtScaleDiv::MajorTick] =
+        buildMajorTicks( boundingInterval, stepSize );
+
+    if ( maxMinSteps > 0 )
+    {
+        buildMinorTicks( ticks[QwtScaleDiv::MajorTick], maxMinSteps, stepSize,
+            ticks[QwtScaleDiv::MinorTick], ticks[QwtScaleDiv::MediumTick] );
+    }
+
+    for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
+    {
+        ticks[i] = strip( ticks[i], interval );
+
+        // ticks very close to 0.0 are
+        // explicitely set to 0.0
+
+        for ( int j = 0; j < ticks[i].count(); j++ )
+        {
+            if ( qwtFuzzyCompare( ticks[i][j], 0.0, stepSize ) == 0 )
+                ticks[i][j] = 0.0;
+        }
+    }
+}
+
+/*!
+   \brief Calculate major ticks for an interval
+
+   \param interval Interval
+   \param stepSize Step size
+
+   \return Calculated ticks
+*/
+QList<double> QwtLinearScaleEngine::buildMajorTicks(
+    const QwtInterval &interval, double stepSize ) const
+{
+    int numTicks = qRound( interval.width() / stepSize ) + 1;
+    if ( numTicks > 10000 )
+        numTicks = 10000;
+
+    QList<double> ticks;
+
+    ticks += interval.minValue();
+    for ( int i = 1; i < numTicks - 1; i++ )
+        ticks += interval.minValue() + i * stepSize;
+    ticks += interval.maxValue();
+
+    return ticks;
+}
+
+/*!
+   \brief Calculate minor/medium ticks for major ticks
+
+   \param majorTicks Major ticks
+   \param maxMinSteps Maximum number of minor steps
+   \param stepSize Step size
+   \param minorTicks Array to be filled with the calculated minor ticks
+   \param mediumTicks Array to be filled with the calculated medium ticks
+
+*/
+void QwtLinearScaleEngine::buildMinorTicks(
+    const QList<double>& majorTicks,
+    int maxMinSteps, double stepSize,
+    QList<double> &minorTicks,
+    QList<double> &mediumTicks ) const
+{
+    double minStep = divideInterval( stepSize, maxMinSteps );
+    if ( minStep == 0.0 )
+        return;
+
+    // # ticks per interval
+    int numTicks = qCeil( qAbs( stepSize / minStep ) ) - 1;
+
+    // Do the minor steps fit into the interval?
+    if ( qwtFuzzyCompare( ( numTicks +  1 ) * qAbs( minStep ),
+        qAbs( stepSize ), stepSize ) > 0 )
+    {
+        numTicks = 1;
+        minStep = stepSize * 0.5;
+    }
+
+    int medIndex = -1;
+    if ( numTicks % 2 )
+        medIndex = numTicks / 2;
+
+    // calculate minor ticks
+
+    for ( int i = 0; i < majorTicks.count(); i++ )
+    {
+        double val = majorTicks[i];
+        for ( int k = 0; k < numTicks; k++ )
+        {
+            val += minStep;
+
+            double alignedValue = val;
+            if ( qwtFuzzyCompare( val, 0.0, stepSize ) == 0 )
+                alignedValue = 0.0;
+
+            if ( k == medIndex )
+                mediumTicks += alignedValue;
+            else
+                minorTicks += alignedValue;
+        }
+    }
+}
+
+/*!
+  \brief Align an interval to a step size
+
+  The limits of an interval are aligned that both are integer
+  multiples of the step size.
+
+  \param interval Interval
+  \param stepSize Step size
+
+  \return Aligned interval
+*/
+QwtInterval QwtLinearScaleEngine::align(
+    const QwtInterval &interval, double stepSize ) const
+{
+    double x1 = QwtScaleArithmetic::floorEps( interval.minValue(), stepSize );
+    if ( qwtFuzzyCompare( interval.minValue(), x1, stepSize ) == 0 )
+        x1 = interval.minValue();
+
+    double x2 = QwtScaleArithmetic::ceilEps( interval.maxValue(), stepSize );
+    if ( qwtFuzzyCompare( interval.maxValue(), x2, stepSize ) == 0 )
+        x2 = interval.maxValue();
+
+    return QwtInterval( x1, x2 );
+}
+
+/*!
+  Return a transformation, for logarithmic (base 10) scales
+*/
+QwtScaleTransformation *QwtLog10ScaleEngine::transformation() const
+{
+    return new QwtScaleTransformation( QwtScaleTransformation::Log10 );
+}
+
+/*!
+    Align and divide an interval
+
+   \param maxNumSteps Max. number of steps
+   \param x1 First limit of the interval (In/Out)
+   \param x2 Second limit of the interval (In/Out)
+   \param stepSize Step size (Out)
+
+   \sa QwtScaleEngine::setAttribute()
+*/
+void QwtLog10ScaleEngine::autoScale( int maxNumSteps,
+                                     double &x1, double &x2, double &stepSize ) const
+{
+    if ( x1 > x2 )
+        qSwap( x1, x2 );
+
+    QwtInterval interval( x1 / qPow( 10.0, lowerMargin() ),
+        x2 * qPow( 10.0, upperMargin() ) );
+
+    if ( interval.maxValue() / interval.minValue() < 10.0 )
+    {
+        // scale width is less than one decade -> build linear scale
+
+        QwtLinearScaleEngine linearScaler;
+        linearScaler.setAttributes( attributes() );
+        linearScaler.setReference( reference() );
+        linearScaler.setMargins( lowerMargin(), upperMargin() );
+
+        linearScaler.autoScale( maxNumSteps, x1, x2, stepSize );
+        stepSize = ::log10( stepSize );
+
+        return;
+    }
+
+    double logRef = 1.0;
+    if ( reference() > LOG_MIN / 2 )
+        logRef = qMin( reference(), LOG_MAX / 2 );
+
+    if ( testAttribute( QwtScaleEngine::Symmetric ) )
+    {
+        const double delta = qMax( interval.maxValue() / logRef,
+            logRef / interval.minValue() );
+        interval.setInterval( logRef / delta, logRef * delta );
+    }
+
+    if ( testAttribute( QwtScaleEngine::IncludeReference ) )
+        interval = interval.extend( logRef );
+
+    interval = interval.limited( LOG_MIN, LOG_MAX );
+
+    if ( interval.width() == 0.0 )
+        interval = buildInterval( interval.minValue() );
+
+    stepSize = divideInterval( log10( interval ).width(), qMax( maxNumSteps, 1 ) );
+    if ( stepSize < 1.0 )
+        stepSize = 1.0;
+
+    if ( !testAttribute( QwtScaleEngine::Floating ) )
+        interval = align( interval, stepSize );
+
+    x1 = interval.minValue();
+    x2 = interval.maxValue();
+
+    if ( testAttribute( QwtScaleEngine::Inverted ) )
+    {
+        qSwap( x1, x2 );
+        stepSize = -stepSize;
+    }
+}
+
+/*!
+   \brief Calculate a scale division
+
+   \param x1 First interval limit
+   \param x2 Second interval limit
+   \param maxMajSteps Maximum for the number of major steps
+   \param maxMinSteps Maximum number of minor steps
+   \param stepSize Step size. If stepSize == 0, the scaleEngine
+                   calculates one.
+
+   \sa QwtScaleEngine::stepSize(), QwtLog10ScaleEngine::subDivide()
+*/
+QwtScaleDiv QwtLog10ScaleEngine::divideScale( double x1, double x2,
+    int maxMajSteps, int maxMinSteps, double stepSize ) const
+{
+    QwtInterval interval = QwtInterval( x1, x2 ).normalized();
+    interval = interval.limited( LOG_MIN, LOG_MAX );
+
+    if ( interval.width() <= 0 )
+        return QwtScaleDiv();
+
+    if ( interval.maxValue() / interval.minValue() < 10.0 )
+    {
+        // scale width is less than one decade -> build linear scale
+
+        QwtLinearScaleEngine linearScaler;
+        linearScaler.setAttributes( attributes() );
+        linearScaler.setReference( reference() );
+        linearScaler.setMargins( lowerMargin(), upperMargin() );
+
+        if ( stepSize != 0.0 )
+            stepSize = qPow( 10.0, stepSize );
+
+        return linearScaler.divideScale( x1, x2,
+            maxMajSteps, maxMinSteps, stepSize );
+    }
+
+    stepSize = qAbs( stepSize );
+    if ( stepSize == 0.0 )
+    {
+        if ( maxMajSteps < 1 )
+            maxMajSteps = 1;
+
+        stepSize = divideInterval( log10( interval ).width(), maxMajSteps );
+        if ( stepSize < 1.0 )
+            stepSize = 1.0; // major step must be >= 1 decade
+    }
+
+    QwtScaleDiv scaleDiv;
+    if ( stepSize != 0.0 )
+    {
+        QList<double> ticks[QwtScaleDiv::NTickTypes];
+        buildTicks( interval, stepSize, maxMinSteps, ticks );
+
+        scaleDiv = QwtScaleDiv( interval, ticks );
+    }
+
+    if ( x1 > x2 )
+        scaleDiv.invert();
+
+    return scaleDiv;
+}
+
+/*!
+   \brief Calculate ticks for an interval
+
+   \param interval Interval
+   \param maxMinSteps Maximum number of minor steps
+   \param stepSize Step size
+   \param ticks Arrays to be filled with the calculated ticks
+
+   \sa buildMajorTicks(), buildMinorTicks
+*/
+void QwtLog10ScaleEngine::buildTicks(
+    const QwtInterval& interval, double stepSize, int maxMinSteps,
+    QList<double> ticks[QwtScaleDiv::NTickTypes] ) const
+{
+    const QwtInterval boundingInterval = align( interval, stepSize );
+
+    ticks[QwtScaleDiv::MajorTick] =
+        buildMajorTicks( boundingInterval, stepSize );
+
+    if ( maxMinSteps > 0 )
+    {
+        ticks[QwtScaleDiv::MinorTick] = buildMinorTicks(
+            ticks[QwtScaleDiv::MajorTick], maxMinSteps, stepSize );
+    }
+
+    for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
+        ticks[i] = strip( ticks[i], interval );
+}
+
+/*!
+   \brief Calculate major ticks for an interval
+
+   \param interval Interval
+   \param stepSize Step size
+
+   \return Calculated ticks
+*/
+QList<double> QwtLog10ScaleEngine::buildMajorTicks(
+    const QwtInterval &interval, double stepSize ) const
+{
+    double width = log10( interval ).width();
+
+    int numTicks = qRound( width / stepSize ) + 1;
+    if ( numTicks > 10000 )
+        numTicks = 10000;
+
+    const double lxmin = ::log( interval.minValue() );
+    const double lxmax = ::log( interval.maxValue() );
+    const double lstep = ( lxmax - lxmin ) / double( numTicks - 1 );
+
+    QList<double> ticks;
+
+    ticks += interval.minValue();
+
+    for ( int i = 1; i < numTicks - 1; i++ )
+        ticks += qExp( lxmin + double( i ) * lstep );
+
+    ticks += interval.maxValue();
+
+    return ticks;
+}
+
+/*!
+   \brief Calculate minor/medium ticks for major ticks
+
+   \param majorTicks Major ticks
+   \param maxMinSteps Maximum number of minor steps
+   \param stepSize Step size
+*/
+QList<double> QwtLog10ScaleEngine::buildMinorTicks(
+    const QList<double> &majorTicks,
+    int maxMinSteps, double stepSize ) const
+{
+    if ( stepSize < 1.1 )          // major step width is one decade
+    {
+        if ( maxMinSteps < 1 )
+            return QList<double>();
+
+        int k0, kstep, kmax;
+
+        if ( maxMinSteps >= 8 )
+        {
+            k0 = 2;
+            kmax = 9;
+            kstep = 1;
+        }
+        else if ( maxMinSteps >= 4 )
+        {
+            k0 = 2;
+            kmax = 8;
+            kstep = 2;
+        }
+        else if ( maxMinSteps >= 2 )
+        {
+            k0 = 2;
+            kmax = 5;
+            kstep = 3;
+        }
+        else
+        {
+            k0 = 5;
+            kmax = 5;
+            kstep = 1;
+        }
+
+        QList<double> minorTicks;
+
+        for ( int i = 0; i < majorTicks.count(); i++ )
+        {
+            const double v = majorTicks[i];
+            for ( int k = k0; k <= kmax; k += kstep )
+                minorTicks += v * double( k );
+        }
+
+        return minorTicks;
+    }
+    else  // major step > one decade
+    {
+        double minStep = divideInterval( stepSize, maxMinSteps );
+        if ( minStep == 0.0 )
+            return QList<double>();
+
+        if ( minStep < 1.0 )
+            minStep = 1.0;
+
+        // # subticks per interval
+        int nMin = qRound( stepSize / minStep ) - 1;
+
+        // Do the minor steps fit into the interval?
+
+        if ( qwtFuzzyCompare( ( nMin +  1 ) * minStep,
+            qAbs( stepSize ), stepSize ) > 0 )
+        {
+            nMin = 0;
+        }
+
+        if ( nMin < 1 )
+            return QList<double>();      // no subticks
+
+        // substep factor = 10^substeps
+        const qreal minFactor = qMax( qPow( 10.0, minStep ), qreal( 10.0 ) );
+
+        QList<double> minorTicks;
+        for ( int i = 0; i < majorTicks.count(); i++ )
+        {
+            double val = majorTicks[i];
+            for ( int k = 0; k < nMin; k++ )
+            {
+                val *= minFactor;
+                minorTicks += val;
+            }
+        }
+        return minorTicks;
+    }
+}
+
+/*!
+  \brief Align an interval to a step size
+
+  The limits of an interval are aligned that both are integer
+  multiples of the step size.
+
+  \param interval Interval
+  \param stepSize Step size
+
+  \return Aligned interval
+*/
+QwtInterval QwtLog10ScaleEngine::align(
+    const QwtInterval &interval, double stepSize ) const
+{
+    const QwtInterval intv = log10( interval );
+
+    double x1 = QwtScaleArithmetic::floorEps( intv.minValue(), stepSize );
+    if ( qwtFuzzyCompare( interval.minValue(), x1, stepSize ) == 0 )
+        x1 = interval.minValue();
+
+    double x2 = QwtScaleArithmetic::ceilEps( intv.maxValue(), stepSize );
+    if ( qwtFuzzyCompare( interval.maxValue(), x2, stepSize ) == 0 )
+        x2 = interval.maxValue();
+
+    return pow10( QwtInterval( x1, x2 ) );
+}
+
+/*!
+  Return the interval [log10(interval.minValue(), log10(interval.maxValue]
+*/
+
+QwtInterval QwtLog10ScaleEngine::log10( const QwtInterval &interval ) const
+{
+    return QwtInterval( ::log10( interval.minValue() ),
+            ::log10( interval.maxValue() ) );
+}
+
+/*!
+  Return the interval [pow10(interval.minValue(), pow10(interval.maxValue]
+*/
+QwtInterval QwtLog10ScaleEngine::pow10( const QwtInterval &interval ) const
+{
+    return QwtInterval( qPow( 10.0, interval.minValue() ),
+            qPow( 10.0, interval.maxValue() ) );
+}
Index: trunk/BNC/qwt/qwt_scale_engine.h
===================================================================
--- trunk/BNC/qwt/qwt_scale_engine.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_engine.h	(revision 4271)
@@ -0,0 +1,217 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_SCALE_ENGINE_H
+#define QWT_SCALE_ENGINE_H
+
+#include "qwt_global.h"
+#include "qwt_scale_div.h"
+#include "qwt_interval.h"
+
+class QwtScaleTransformation;
+
+/*!
+  \brief Arithmetic including a tolerance
+*/
+class QWT_EXPORT QwtScaleArithmetic
+{
+public:
+    static double ceilEps( double value, double intervalSize );
+    static double floorEps( double value, double intervalSize );
+
+    static double divideEps( double interval, double steps );
+
+    static double ceil125( double x );
+    static double floor125( double x );
+};
+
+/*!
+  \brief Base class for scale engines.
+
+  A scale engine tries to find "reasonable" ranges and step sizes
+  for scales.
+
+  The layout of the scale can be varied with setAttribute().
+
+  Qwt offers implementations for logarithmic (log10)
+  and linear scales. Contributions for other types of scale engines
+  (date/time, log2 ... ) are welcome.
+*/
+
+class QWT_EXPORT QwtScaleEngine
+{
+public:
+    /*! 
+       Layout attributes
+       \sa setAttribute(), testAttribute(), reference(),
+           lowerMargin(), upperMargin()
+     */
+
+    enum Attribute
+    {
+        //! No attributes
+        NoAttribute = 0x00,
+
+        //! Build a scale which includes the reference() value.
+        IncludeReference = 0x01,
+
+        //! Build a scale which is symmetric to the reference() value.
+        Symmetric = 0x02,
+
+        /*!
+           The endpoints of the scale are supposed to be equal the
+           outmost included values plus the specified margins 
+           (see setMargins()).
+           If this attribute is *not* set, the endpoints of the scale will
+           be integer multiples of the step size.
+         */
+        Floating = 0x04,
+
+        //! Turn the scale upside down.
+        Inverted = 0x08
+    };
+
+    //! Layout attributes
+    typedef QFlags<Attribute> Attributes;
+
+    explicit QwtScaleEngine();
+    virtual ~QwtScaleEngine();
+
+    void setAttribute( Attribute, bool on = true );
+    bool testAttribute( Attribute ) const;
+
+    void setAttributes( Attributes );
+    Attributes attributes() const;
+
+    void setReference( double reference );
+    double reference() const;
+
+    void setMargins( double lower, double upper );
+    double lowerMargin() const;
+    double upperMargin() const;
+
+    /*!
+      Align and divide an interval
+
+      \param maxNumSteps Max. number of steps
+      \param x1 First limit of the interval (In/Out)
+      \param x2 Second limit of the interval (In/Out)
+      \param stepSize Step size (Return value)
+    */
+    virtual void autoScale( int maxNumSteps,
+        double &x1, double &x2, double &stepSize ) const = 0;
+
+    /*!
+      \brief Calculate a scale division
+
+      \param x1 First interval limit
+      \param x2 Second interval limit
+      \param maxMajSteps Maximum for the number of major steps
+      \param maxMinSteps Maximum number of minor steps
+      \param stepSize Step size. If stepSize == 0.0, the scaleEngine
+                   calculates one.
+    */
+    virtual QwtScaleDiv divideScale( double x1, double x2,
+        int maxMajSteps, int maxMinSteps,
+        double stepSize = 0.0 ) const = 0;
+
+    //! \return a transformation
+    virtual QwtScaleTransformation *transformation() const = 0;
+
+protected:
+    bool contains( const QwtInterval &, double val ) const;
+    QList<double> strip( const QList<double>&, const QwtInterval & ) const;
+    double divideInterval( double interval, int numSteps ) const;
+
+    QwtInterval buildInterval( double v ) const;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+/*!
+  \brief A scale engine for linear scales
+
+  The step size will fit into the pattern
+  \f$\left\{ 1,2,5\right\} \cdot 10^{n}\f$, where n is an integer.
+*/
+
+class QWT_EXPORT QwtLinearScaleEngine: public QwtScaleEngine
+{
+public:
+    virtual void autoScale( int maxSteps,
+        double &x1, double &x2, double &stepSize ) const;
+
+    virtual QwtScaleDiv divideScale( double x1, double x2,
+        int numMajorSteps, int numMinorSteps,
+                                     double stepSize = 0.0 ) const;
+
+    virtual QwtScaleTransformation *transformation() const;
+
+protected:
+    QwtInterval align( const QwtInterval&, double stepSize ) const;
+
+    void buildTicks(
+        const QwtInterval &, double stepSize, int maxMinSteps,
+        QList<double> ticks[QwtScaleDiv::NTickTypes] ) const;
+
+    QList<double> buildMajorTicks(
+        const QwtInterval &interval, double stepSize ) const;
+
+    void buildMinorTicks(
+        const QList<double>& majorTicks,
+        int maxMinMark, double step,
+        QList<double> &, QList<double> & ) const;
+};
+
+/*!
+  \brief A scale engine for logarithmic (base 10) scales
+
+  The step size is measured in *decades*
+  and the major step size will be adjusted to fit the pattern
+  \f$\left\{ 1,2,3,5\right\} \cdot 10^{n}\f$, where n is a natural number
+  including zero.
+
+  \warning the step size as well as the margins are measured in *decades*.
+*/
+
+class QWT_EXPORT QwtLog10ScaleEngine: public QwtScaleEngine
+{
+public:
+    virtual void autoScale( int maxSteps,
+        double &x1, double &x2, double &stepSize ) const;
+
+    virtual QwtScaleDiv divideScale( double x1, double x2,
+        int numMajorSteps, int numMinorSteps,
+        double stepSize = 0.0 ) const;
+
+    virtual QwtScaleTransformation *transformation() const;
+
+protected:
+    QwtInterval log10( const QwtInterval& ) const;
+    QwtInterval pow10( const QwtInterval& ) const;
+
+    QwtInterval align( const QwtInterval&, double stepSize ) const;
+
+    void buildTicks(
+        const QwtInterval &, double stepSize, int maxMinSteps,
+        QList<double> ticks[QwtScaleDiv::NTickTypes] ) const;
+
+    QList<double> buildMajorTicks(
+        const QwtInterval &interval, double stepSize ) const;
+
+    QList<double> buildMinorTicks(
+        const QList<double>& majorTicks,
+        int maxMinMark, double step ) const;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtScaleEngine::Attributes )
+
+#endif
Index: trunk/BNC/qwt/qwt_scale_map.cpp
===================================================================
--- trunk/BNC/qwt/qwt_scale_map.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_map.cpp	(revision 4271)
@@ -0,0 +1,344 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_scale_map.h"
+#include <qrect.h>
+#include <qalgorithms.h>
+#include <qmath.h>
+#include <qdebug.h>
+
+#if QT_VERSION < 0x040601
+#define qExp(x) ::exp(x)
+#endif
+
+//! Smallest allowed value for logarithmic scales: 1.0e-150
+QT_STATIC_CONST_IMPL double QwtScaleMap::LogMin = 1.0e-150;
+
+//! Largest allowed value for logarithmic scales: 1.0e150
+QT_STATIC_CONST_IMPL double QwtScaleMap::LogMax = 1.0e150;
+
+//! Constructor for a linear transformation
+QwtScaleTransformation::QwtScaleTransformation( Type type ):
+    d_type( type )
+{
+}
+
+//! Destructor
+QwtScaleTransformation::~QwtScaleTransformation()
+{
+}
+
+//! Create a clone of the transformation
+QwtScaleTransformation *QwtScaleTransformation::copy() const
+{
+    return new QwtScaleTransformation( d_type );
+}
+
+/*!
+  \brief Transform a value from the coordinate system of a scale
+         into the coordinate system of the paint device
+
+  \param s  Value related to the coordinate system of the scale
+  \param s1 First border of the coordinate system of the scale
+  \param s2 Second border of the coordinate system of the scale
+  \param p1 First border of the coordinate system of the paint device
+  \param p2 Second border of the coordinate system of the paint device
+  \return
+  <dl>
+  <dt>linear mapping:<dd>p1 + (p2 - p1) / (s2 - s1) * (s - s1);</dd>
+  </dl>
+  <dl>
+  <dt>log10 mapping: <dd>p1 + (p2 - p1) / log(s2 / s1) * log(s / s1);</dd>
+  </dl>
+*/
+
+double QwtScaleTransformation::xForm(
+    double s, double s1, double s2, double p1, double p2 ) const
+{
+    if ( d_type == Log10 )
+        return p1 + ( p2 - p1 ) / log( s2 / s1 ) * log( s / s1 );
+    else
+        return p1 + ( p2 - p1 ) / ( s2 - s1 ) * ( s - s1 );
+}
+
+/*!
+  \brief Transform a value from the coordinate system of the paint device
+         into the coordinate system of a scale.
+
+  \param p Value related to the coordinate system of the paint device 
+  \param p1 First border of the coordinate system of the paint device
+  \param p2 Second border of the coordinate system of the paint device
+  \param s1 First border of the coordinate system of the scale
+  \param s2 Second border of the coordinate system of the scale
+  \return
+  <dl>
+  <dt>linear mapping:<dd>s1 + ( s2 - s1 ) / ( p2 - p1 ) * ( p - p1 );</dd>
+  </dl>
+  <dl>
+  <dt>log10 mapping:<dd>exp((p - p1) / (p2 - p1) * log(s2 / s1)) * s1;</dd>
+  </dl>
+*/
+
+double QwtScaleTransformation::invXForm( double p, double p1, double p2,
+    double s1, double s2 ) const
+{
+    if ( d_type == Log10 )
+        return qExp( ( p - p1 ) / ( p2 - p1 ) * log( s2 / s1 ) ) * s1;
+    else
+        return s1 + ( s2 - s1 ) / ( p2 - p1 ) * ( p - p1 );
+}
+
+/*!
+  \brief Constructor
+
+  The scale and paint device intervals are both set to [0,1].
+*/
+QwtScaleMap::QwtScaleMap():
+    d_s1( 0.0 ),
+    d_s2( 1.0 ),
+    d_p1( 0.0 ),
+    d_p2( 1.0 ),
+    d_cnv( 1.0 )
+{
+    d_transformation = new QwtScaleTransformation(
+        QwtScaleTransformation::Linear );
+}
+
+//! Copy constructor
+QwtScaleMap::QwtScaleMap( const QwtScaleMap& other ):
+    d_s1( other.d_s1 ),
+    d_s2( other.d_s2 ),
+    d_p1( other.d_p1 ),
+    d_p2( other.d_p2 ),
+    d_cnv( other.d_cnv )
+{
+    d_transformation = other.d_transformation->copy();
+}
+
+/*!
+  Destructor
+*/
+QwtScaleMap::~QwtScaleMap()
+{
+    delete d_transformation;
+}
+
+//! Assignment operator
+QwtScaleMap &QwtScaleMap::operator=( const QwtScaleMap & other )
+{
+    d_s1 = other.d_s1;
+    d_s2 = other.d_s2;
+    d_p1 = other.d_p1;
+    d_p2 = other.d_p2;
+    d_cnv = other.d_cnv;
+
+    delete d_transformation;
+    d_transformation = other.d_transformation->copy();
+
+    return *this;
+}
+
+/*!
+   Initialize the map with a transformation
+*/
+void QwtScaleMap::setTransformation(
+    QwtScaleTransformation *transformation )
+{
+    if ( transformation == NULL )
+        return;
+
+    if ( transformation != d_transformation )
+    {
+        delete d_transformation;
+        d_transformation = transformation;
+    }
+
+    setScaleInterval( d_s1, d_s2 );
+}
+
+//! Get the transformation
+const QwtScaleTransformation *QwtScaleMap::transformation() const
+{
+    return d_transformation;
+}
+
+/*!
+  \brief Specify the borders of the scale interval
+  \param s1 first border
+  \param s2 second border
+  \warning logarithmic scales might be aligned to [LogMin, LogMax]
+*/
+void QwtScaleMap::setScaleInterval( double s1, double s2 )
+{
+    if ( d_transformation->type() == QwtScaleTransformation::Log10 )
+    {
+        if ( s1 < LogMin )
+            s1 = LogMin;
+        else if ( s1 > LogMax )
+            s1 = LogMax;
+
+        if ( s2 < LogMin )
+            s2 = LogMin;
+        else if ( s2 > LogMax )
+            s2 = LogMax;
+    }
+
+    d_s1 = s1;
+    d_s2 = s2;
+
+    if ( d_transformation->type() != QwtScaleTransformation::Other )
+        newFactor();
+}
+
+/*!
+  \brief Specify the borders of the paint device interval
+  \param p1 first border
+  \param p2 second border
+*/
+void QwtScaleMap::setPaintInterval( double p1, double p2 )
+{
+    d_p1 = p1;
+    d_p2 = p2;
+
+    if ( d_transformation->type() != QwtScaleTransformation::Other )
+        newFactor();
+}
+
+/*!
+  \brief Re-calculate the conversion factor.
+*/
+void QwtScaleMap::newFactor()
+{
+    d_cnv = 0.0;
+
+    switch ( d_transformation->type() )
+    {
+        case QwtScaleTransformation::Linear:
+        {
+            if ( d_s2 != d_s1 )
+                d_cnv = ( d_p2 - d_p1 ) / ( d_s2 - d_s1 );
+            break;
+        }
+        case QwtScaleTransformation::Log10:
+        {
+            if ( d_s1 != 0 )
+                d_cnv = ( d_p2 - d_p1 ) / log( d_s2 / d_s1 );
+            break;
+        }
+        default:;
+    }
+}
+
+/*!
+   Transform a rectangle from scale to paint coordinates
+
+   \param xMap X map
+   \param yMap Y map
+   \param rect Rectangle in scale coordinates
+   \return Rectangle in paint coordinates
+
+   \sa invTransform()
+*/
+QRectF QwtScaleMap::transform( const QwtScaleMap &xMap,
+    const QwtScaleMap &yMap, const QRectF &rect )
+{
+    double x1 = xMap.transform( rect.left() );
+    double x2 = xMap.transform( rect.right() );
+    double y1 = yMap.transform( rect.top() );
+    double y2 = yMap.transform( rect.bottom() );
+
+    if ( x2 < x1 )
+        qSwap( x1, x2 );
+    if ( y2 < y1 )
+        qSwap( y1, y2 );
+
+    if ( qwtFuzzyCompare( x1, 0.0, x2 - x1 ) == 0 )
+        x1 = 0.0;
+    if ( qwtFuzzyCompare( x2, 0.0, x2 - x1 ) == 0 )
+        x2 = 0.0;
+    if ( qwtFuzzyCompare( y1, 0.0, y2 - y1 ) == 0 )
+        y1 = 0.0;
+    if ( qwtFuzzyCompare( y2, 0.0, y2 - y1 ) == 0 )
+        y2 = 0.0;
+
+    return QRectF( x1, y1, x2 - x1 + 1, y2 - y1 + 1 );
+}
+
+/*!
+   Transform a rectangle from paint to scale coordinates
+
+   \param xMap X map
+   \param yMap Y map
+   \param pos Position in paint coordinates
+   \return Position in scale coordinates
+   \sa transform()
+*/
+QPointF QwtScaleMap::invTransform( const QwtScaleMap &xMap,
+    const QwtScaleMap &yMap, const QPointF &pos )
+{
+    return QPointF( 
+        xMap.invTransform( pos.x() ), 
+        yMap.invTransform( pos.y() ) 
+    );
+}
+
+/*!
+   Transform a point from scale to paint coordinates
+
+   \param xMap X map
+   \param yMap Y map
+   \param pos Position in scale coordinates
+   \return Position in paint coordinates
+
+   \sa invTransform()
+*/
+QPointF QwtScaleMap::transform( const QwtScaleMap &xMap,
+    const QwtScaleMap &yMap, const QPointF &pos )
+{
+    return QPointF( 
+        xMap.transform( pos.x() ), 
+        yMap.transform( pos.y() )
+    );
+}
+
+/*!
+   Transform a rectangle from paint to scale coordinates
+
+   \param xMap X map
+   \param yMap Y map
+   \param rect Rectangle in paint coordinates
+   \return Rectangle in scale coordinates
+   \sa transform()
+*/
+QRectF QwtScaleMap::invTransform( const QwtScaleMap &xMap,
+    const QwtScaleMap &yMap, const QRectF &rect )
+{
+    const double x1 = xMap.invTransform( rect.left() );
+    const double x2 = xMap.invTransform( rect.right() - 1 );
+    const double y1 = yMap.invTransform( rect.top() );
+    const double y2 = yMap.invTransform( rect.bottom() - 1 );
+
+    const QRectF r( x1, y1, x2 - x1, y2 - y1 );
+    return r.normalized();
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+
+QDebug operator<<( QDebug debug, const QwtScaleMap &map )
+{
+    debug.nospace() << "QwtScaleMap("
+        << static_cast<int>( map.transformation()->type() )
+        << ", s:" << map.s1() << "->" << map.s2()
+        << ", p:" << map.p1() << "->" << map.p2()
+        << ")";
+
+    return debug.space();
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_scale_map.h
===================================================================
--- trunk/BNC/qwt/qwt_scale_map.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_map.h	(revision 4271)
@@ -0,0 +1,219 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_SCALE_MAP_H
+#define QWT_SCALE_MAP_H
+
+#include "qwt_global.h"
+#include "qwt_math.h"
+#ifndef QT_NO_DEBUG_STREAM
+#include <qdebug.h>
+#endif
+
+class QRectF;
+
+/*!
+   \brief A transformation between coordinate systems
+
+   QwtScaleTransformation offers transformations from the coordinate system
+   of a scale into the linear coordinate system of a paint device 
+   and vice versa.
+*/
+class QWT_EXPORT QwtScaleTransformation
+{
+public:
+    //! Transformation type
+    enum Type
+    {
+        //! Transformation between 2 linear scales
+        Linear,
+
+        //! Transformation between a linear and a logarithmic ( base 10 ) scale
+        Log10,
+
+        //! Any other type of transformation
+        Other
+    };
+
+    QwtScaleTransformation( Type type );
+    virtual ~QwtScaleTransformation();
+
+    virtual double xForm( double x, double s1, double s2,
+        double p1, double p2 ) const;
+    virtual double invXForm( double x, double p1, double p2,
+        double s1, double s2 ) const;
+
+    Type type() const;
+
+    virtual QwtScaleTransformation *copy() const;
+
+private:
+    QwtScaleTransformation();
+    QwtScaleTransformation &operator=( const QwtScaleTransformation );
+
+    const Type d_type;
+};
+
+//! \return Transformation type
+inline QwtScaleTransformation::Type QwtScaleTransformation::type() const
+{
+    return d_type;
+}
+
+/*!
+   \brief A scale map
+
+   QwtScaleMap offers transformations from the coordinate system
+   of a scale into the linear coordinate system of a paint device 
+   and vice versa.
+*/
+class QWT_EXPORT QwtScaleMap
+{
+public:
+    QwtScaleMap();
+    QwtScaleMap( const QwtScaleMap& );
+
+    ~QwtScaleMap();
+
+    QwtScaleMap &operator=( const QwtScaleMap & );
+
+    void setTransformation( QwtScaleTransformation * );
+    const QwtScaleTransformation *transformation() const;
+
+    void setPaintInterval( double p1, double p2 );
+    void setScaleInterval( double s1, double s2 );
+
+    double transform( double s ) const;
+    double invTransform( double p ) const;
+
+    double p1() const;
+    double p2() const;
+
+    double s1() const;
+    double s2() const;
+
+    double pDist() const;
+    double sDist() const;
+
+    QT_STATIC_CONST double LogMin;
+    QT_STATIC_CONST double LogMax;
+
+    static QRectF transform( const QwtScaleMap &,
+        const QwtScaleMap &, const QRectF & );
+    static QRectF invTransform( const QwtScaleMap &,
+        const QwtScaleMap &, const QRectF & );
+
+    static QPointF transform( const QwtScaleMap &,
+        const QwtScaleMap &, const QPointF & );
+    static QPointF invTransform( const QwtScaleMap &,
+        const QwtScaleMap &, const QPointF & );
+
+    bool isInverting() const;
+
+private:
+    void newFactor();
+
+    double d_s1, d_s2;     // scale interval boundaries
+    double d_p1, d_p2;     // paint device interval boundaries
+
+    double d_cnv;       // conversion factor
+
+    QwtScaleTransformation *d_transformation;
+};
+
+/*!
+    \return First border of the scale interval
+*/
+inline double QwtScaleMap::s1() const
+{
+    return d_s1;
+}
+
+/*!
+    \return Second border of the scale interval
+*/
+inline double QwtScaleMap::s2() const
+{
+    return d_s2;
+}
+
+/*!
+    \return First border of the paint interval
+*/
+inline double QwtScaleMap::p1() const
+{
+    return d_p1;
+}
+
+/*!
+    \return Second border of the paint interval
+*/
+inline double QwtScaleMap::p2() const
+{
+    return d_p2;
+}
+
+/*!
+    \return qwtAbs(p2() - p1())
+*/
+inline double QwtScaleMap::pDist() const
+{
+    return qAbs( d_p2 - d_p1 );
+}
+
+/*!
+    \return qwtAbs(s2() - s1())
+*/
+inline double QwtScaleMap::sDist() const
+{
+    return qAbs( d_s2 - d_s1 );
+}
+
+/*!
+  Transform a point related to the scale interval into an point
+  related to the interval of the paint device
+
+  \param s Value relative to the coordinates of the scale
+*/
+inline double QwtScaleMap::transform( double s ) const
+{
+    // try to inline code from QwtScaleTransformation
+
+    if ( d_transformation->type() == QwtScaleTransformation::Linear )
+        return d_p1 + ( s - d_s1 ) * d_cnv;
+
+    if ( d_transformation->type() == QwtScaleTransformation::Log10 )
+        return d_p1 + log( s / d_s1 ) * d_cnv;
+
+    return d_transformation->xForm( s, d_s1, d_s2, d_p1, d_p2 );
+}
+
+/*!
+  Transform an paint device value into a value in the
+  interval of the scale.
+
+  \param p Value relative to the coordinates of the paint device
+  \sa transform()
+*/
+inline double QwtScaleMap::invTransform( double p ) const
+{
+    return d_transformation->invXForm( p, d_p1, d_p2, d_s1, d_s2 );
+}
+
+//! \return True, when ( p1() < p2() ) != ( s1() < s2() )
+inline bool QwtScaleMap::isInverting() const
+{
+    return ( ( d_p1 < d_p2 ) != ( d_s1 < d_s2 ) );
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QWT_EXPORT QDebug operator<<( QDebug, const QwtScaleMap & );
+#endif
+
+#endif
Index: trunk/BNC/qwt/qwt_scale_widget.cpp
===================================================================
--- trunk/BNC/qwt/qwt_scale_widget.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_widget.cpp	(revision 4271)
@@ -0,0 +1,917 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_scale_widget.h"
+#include "qwt_painter.h"
+#include "qwt_color_map.h"
+#include "qwt_scale_map.h"
+#include "qwt_math.h"
+#include "qwt_scale_div.h"
+#include "qwt_text.h"
+#include <qpainter.h>
+#include <qevent.h>
+#include <qmath.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+
+class QwtScaleWidget::PrivateData
+{
+public:
+    PrivateData():
+        scaleDraw( NULL )
+    {
+        colorBar.colorMap = NULL;
+    }
+
+    ~PrivateData()
+    {
+        delete scaleDraw;
+        delete colorBar.colorMap;
+    }
+
+    QwtScaleDraw *scaleDraw;
+
+    int borderDist[2];
+    int minBorderDist[2];
+    int scaleLength;
+    int margin;
+
+    int titleOffset;
+    int spacing;
+    QwtText title;
+
+    QwtScaleWidget::LayoutFlags layoutFlags;
+
+    struct t_colorBar
+    {
+        bool isEnabled;
+        int width;
+        QwtInterval interval;
+        QwtColorMap *colorMap;
+    } colorBar;
+};
+
+/*!
+  \brief Create a scale with the position QwtScaleWidget::Left
+  \param parent Parent widget
+*/
+QwtScaleWidget::QwtScaleWidget( QWidget *parent ):
+    QWidget( parent )
+{
+    initScale( QwtScaleDraw::LeftScale );
+}
+
+/*!
+  \brief Constructor
+  \param align Alignment.
+  \param parent Parent widget
+*/
+QwtScaleWidget::QwtScaleWidget(
+        QwtScaleDraw::Alignment align, QWidget *parent ):
+    QWidget( parent )
+{
+    initScale( align );
+}
+
+//! Destructor
+QwtScaleWidget::~QwtScaleWidget()
+{
+    delete d_data;
+}
+
+//! Initialize the scale
+void QwtScaleWidget::initScale( QwtScaleDraw::Alignment align )
+{
+    d_data = new PrivateData;
+
+    d_data->layoutFlags = 0;
+    if ( align == QwtScaleDraw::RightScale )
+        d_data->layoutFlags |= TitleInverted;
+
+    d_data->borderDist[0] = 0;
+    d_data->borderDist[1] = 0;
+    d_data->minBorderDist[0] = 0;
+    d_data->minBorderDist[1] = 0;
+    d_data->margin = 4;
+    d_data->titleOffset = 0;
+    d_data->spacing = 2;
+
+    d_data->scaleDraw = new QwtScaleDraw;
+    d_data->scaleDraw->setAlignment( align );
+    d_data->scaleDraw->setLength( 10 );
+
+    d_data->colorBar.colorMap = new QwtLinearColorMap();
+    d_data->colorBar.isEnabled = false;
+    d_data->colorBar.width = 10;
+
+    const int flags = Qt::AlignHCenter
+        | Qt::TextExpandTabs | Qt::TextWordWrap;
+    d_data->title.setRenderFlags( flags );
+    d_data->title.setFont( font() );
+
+    QSizePolicy policy( QSizePolicy::MinimumExpanding,
+        QSizePolicy::Fixed );
+    if ( d_data->scaleDraw->orientation() == Qt::Vertical )
+        policy.transpose();
+
+    setSizePolicy( policy );
+
+    setAttribute( Qt::WA_WState_OwnSizePolicy, false );
+}
+
+/*!
+   Toggle an layout flag
+
+   \param flag Layout flag
+   \param on true/false
+
+   \sa testLayoutFlag(), LayoutFlag
+*/
+void QwtScaleWidget::setLayoutFlag( LayoutFlag flag, bool on )
+{
+    if ( ( ( d_data->layoutFlags & flag ) != 0 ) != on )
+    {
+        if ( on )
+            d_data->layoutFlags |= flag;
+        else
+            d_data->layoutFlags &= ~flag;
+    }
+}
+
+/*!
+   Test a layout flag
+
+   \param flag Layout flag
+   \return true/false
+   \sa setLayoutFlag(), LayoutFlag
+*/
+bool QwtScaleWidget::testLayoutFlag( LayoutFlag flag ) const
+{
+    return ( d_data->layoutFlags & flag );
+}
+
+/*!
+  Give title new text contents
+
+  \param title New title
+  \sa title(), setTitle(const QwtText &);
+*/
+void QwtScaleWidget::setTitle( const QString &title )
+{
+    if ( d_data->title.text() != title )
+    {
+        d_data->title.setText( title );
+        layoutScale();
+    }
+}
+
+/*!
+  Give title new text contents
+
+  \param title New title
+  \sa title()
+  \warning The title flags are interpreted in
+               direction of the label, AlignTop, AlignBottom can't be set
+               as the title will always be aligned to the scale.
+*/
+void QwtScaleWidget::setTitle( const QwtText &title )
+{
+    QwtText t = title;
+    const int flags = title.renderFlags() & ~( Qt::AlignTop | Qt::AlignBottom );
+    t.setRenderFlags( flags );
+
+    if ( t != d_data->title )
+    {
+        d_data->title = t;
+        layoutScale();
+    }
+}
+
+/*!
+  Change the alignment
+
+  \param alignment New alignment
+  \sa alignment()
+*/
+void QwtScaleWidget::setAlignment( QwtScaleDraw::Alignment alignment )
+{
+    if ( !testAttribute( Qt::WA_WState_OwnSizePolicy ) )
+    {
+        QSizePolicy policy( QSizePolicy::MinimumExpanding,
+            QSizePolicy::Fixed );
+        if ( d_data->scaleDraw->orientation() == Qt::Vertical )
+            policy.transpose();
+        setSizePolicy( policy );
+
+        setAttribute( Qt::WA_WState_OwnSizePolicy, false );
+    }
+
+    if ( d_data->scaleDraw )
+        d_data->scaleDraw->setAlignment( alignment );
+    layoutScale();
+}
+
+
+/*!
+    \return position
+    \sa setPosition()
+*/
+QwtScaleDraw::Alignment QwtScaleWidget::alignment() const
+{
+    if ( !scaleDraw() )
+        return QwtScaleDraw::LeftScale;
+
+    return scaleDraw()->alignment();
+}
+
+/*!
+  Specify distances of the scale's endpoints from the
+  widget's borders. The actual borders will never be less
+  than minimum border distance.
+  \param dist1 Left or top Distance
+  \param dist2 Right or bottom distance
+  \sa borderDist()
+*/
+void QwtScaleWidget::setBorderDist( int dist1, int dist2 )
+{
+    if ( dist1 != d_data->borderDist[0] || dist2 != d_data->borderDist[1] )
+    {
+        d_data->borderDist[0] = dist1;
+        d_data->borderDist[1] = dist2;
+        layoutScale();
+    }
+}
+
+/*!
+  \brief Specify the margin to the colorBar/base line.
+  \param margin Margin
+  \sa margin()
+*/
+void QwtScaleWidget::setMargin( int margin )
+{
+    margin = qMax( 0, margin );
+    if ( margin != d_data->margin )
+    {
+        d_data->margin = margin;
+        layoutScale();
+    }
+}
+
+/*!
+  \brief Specify the distance between color bar, scale and title
+  \param spacing Spacing
+  \sa spacing()
+*/
+void QwtScaleWidget::setSpacing( int spacing )
+{
+    spacing = qMax( 0, spacing );
+    if ( spacing != d_data->spacing )
+    {
+        d_data->spacing = spacing;
+        layoutScale();
+    }
+}
+
+/*!
+  \brief Change the alignment for the labels.
+
+  \sa QwtScaleDraw::setLabelAlignment(), setLabelRotation()
+*/
+void QwtScaleWidget::setLabelAlignment( Qt::Alignment alignment )
+{
+    d_data->scaleDraw->setLabelAlignment( alignment );
+    layoutScale();
+}
+
+/*!
+  \brief Change the rotation for the labels.
+  See QwtScaleDraw::setLabelRotation().
+
+  \param rotation Rotation
+  \sa QwtScaleDraw::setLabelRotation(), setLabelFlags()
+*/
+void QwtScaleWidget::setLabelRotation( double rotation )
+{
+    d_data->scaleDraw->setLabelRotation( rotation );
+    layoutScale();
+}
+
+/*!
+  Set a scale draw
+  sd has to be created with new and will be deleted in
+  ~QwtScaleWidget() or the next call of setScaleDraw().
+
+  \param sd ScaleDraw object
+  \sa scaleDraw()
+*/
+void QwtScaleWidget::setScaleDraw( QwtScaleDraw *sd )
+{
+    if ( sd == NULL || sd == d_data->scaleDraw )
+        return;
+
+    if ( d_data->scaleDraw )
+        sd->setAlignment( d_data->scaleDraw->alignment() );
+
+    delete d_data->scaleDraw;
+    d_data->scaleDraw = sd;
+
+    layoutScale();
+}
+
+/*!
+    scaleDraw of this scale
+    \sa setScaleDraw(), QwtScaleDraw::setScaleDraw()
+*/
+const QwtScaleDraw *QwtScaleWidget::scaleDraw() const
+{
+    return d_data->scaleDraw;
+}
+
+/*!
+    scaleDraw of this scale
+    \sa QwtScaleDraw::setScaleDraw()
+*/
+QwtScaleDraw *QwtScaleWidget::scaleDraw()
+{
+    return d_data->scaleDraw;
+}
+
+/*!
+    \return title
+    \sa setTitle()
+*/
+QwtText QwtScaleWidget::title() const
+{
+    return d_data->title;
+}
+
+/*!
+    \return start border distance
+    \sa setBorderDist()
+*/
+int QwtScaleWidget::startBorderDist() const
+{
+    return d_data->borderDist[0];
+}
+
+/*!
+    \return end border distance
+    \sa setBorderDist()
+*/
+int QwtScaleWidget::endBorderDist() const
+{
+    return d_data->borderDist[1];
+}
+
+/*!
+    \return margin
+    \sa setMargin()
+*/
+int QwtScaleWidget::margin() const
+{
+    return d_data->margin;
+}
+
+/*!
+    \return distance between scale and title
+    \sa setMargin()
+*/
+int QwtScaleWidget::spacing() const
+{
+    return d_data->spacing;
+}
+
+/*!
+  \brief paintEvent
+*/
+void QwtScaleWidget::paintEvent( QPaintEvent *event )
+{
+    QPainter painter( this );
+    painter.setClipRegion( event->region() );
+
+    QStyleOption opt;
+    opt.init(this);
+    style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
+
+    draw( &painter );
+}
+
+/*!
+  \brief draw the scale
+*/
+void QwtScaleWidget::draw( QPainter *painter ) const
+{
+    d_data->scaleDraw->draw( painter, palette() );
+
+    if ( d_data->colorBar.isEnabled && d_data->colorBar.width > 0 &&
+        d_data->colorBar.interval.isValid() )
+    {
+        drawColorBar( painter, colorBarRect( contentsRect() ) );
+    }
+
+    QRect r = contentsRect();
+    if ( d_data->scaleDraw->orientation() == Qt::Horizontal )
+    {
+        r.setLeft( r.left() + d_data->borderDist[0] );
+        r.setWidth( r.width() - d_data->borderDist[1] );
+    }
+    else
+    {
+        r.setTop( r.top() + d_data->borderDist[0] );
+        r.setHeight( r.height() - d_data->borderDist[1] );
+    }
+
+    if ( !d_data->title.isEmpty() )
+        drawTitle( painter, d_data->scaleDraw->alignment(), r );
+}
+
+/*!
+  Calculate the the rectangle for the color bar
+
+  \param rect Bounding rectangle for all components of the scale
+  \return Rectabgle for the color bar
+*/
+QRectF QwtScaleWidget::colorBarRect( const QRectF& rect ) const
+{
+    QRectF cr = rect;
+
+    if ( d_data->scaleDraw->orientation() == Qt::Horizontal )
+    {
+        cr.setLeft( cr.left() + d_data->borderDist[0] );
+        cr.setWidth( cr.width() - d_data->borderDist[1] + 1 );
+    }
+    else
+    {
+        cr.setTop( cr.top() + d_data->borderDist[0] );
+        cr.setHeight( cr.height() - d_data->borderDist[1] + 1 );
+    }
+
+    switch ( d_data->scaleDraw->alignment() )
+    {
+        case QwtScaleDraw::LeftScale:
+        {
+            cr.setLeft( cr.right() - d_data->margin
+                - d_data->colorBar.width );
+            cr.setWidth( d_data->colorBar.width );
+            break;
+        }
+
+        case QwtScaleDraw::RightScale:
+        {
+            cr.setLeft( cr.left() + d_data->margin );
+            cr.setWidth( d_data->colorBar.width );
+            break;
+        }
+
+        case QwtScaleDraw::BottomScale:
+        {
+            cr.setTop( cr.top() + d_data->margin );
+            cr.setHeight( d_data->colorBar.width );
+            break;
+        }
+
+        case QwtScaleDraw::TopScale:
+        {
+            cr.setTop( cr.bottom() - d_data->margin
+                - d_data->colorBar.width );
+            cr.setHeight( d_data->colorBar.width );
+            break;
+        }
+    }
+
+    return cr;
+}
+
+/*!
+  Event handler for resize event
+  \param event Resize event
+*/
+void QwtScaleWidget::resizeEvent( QResizeEvent *event )
+{
+    Q_UNUSED( event );
+    layoutScale( false );
+}
+
+/*!
+  Recalculate the scale's geometry and layout based on
+  the current rect and fonts.
+
+  \param update_geometry Notify the layout system and call update
+                         to redraw the scale
+*/
+
+void QwtScaleWidget::layoutScale( bool update_geometry )
+{
+    int bd0, bd1;
+    getBorderDistHint( bd0, bd1 );
+    if ( d_data->borderDist[0] > bd0 )
+        bd0 = d_data->borderDist[0];
+    if ( d_data->borderDist[1] > bd1 )
+        bd1 = d_data->borderDist[1];
+
+    int colorBarWidth = 0;
+    if ( d_data->colorBar.isEnabled && d_data->colorBar.interval.isValid() )
+        colorBarWidth = d_data->colorBar.width + d_data->spacing;
+
+    const QRectF r = contentsRect();
+    double x, y, length;
+
+    if ( d_data->scaleDraw->orientation() == Qt::Vertical )
+    {
+        y = r.top() + bd0;
+        length = r.height() - ( bd0 + bd1 );
+
+        if ( d_data->scaleDraw->alignment() == QwtScaleDraw::LeftScale )
+            x = r.right() - 1.0 - d_data->margin - colorBarWidth;
+        else
+            x = r.left() + d_data->margin + colorBarWidth;
+    }
+    else
+    {
+        x = r.left() + bd0;
+        length = r.width() - ( bd0 + bd1 );
+
+        if ( d_data->scaleDraw->alignment() == QwtScaleDraw::BottomScale )
+            y = r.top() + d_data->margin + colorBarWidth;
+        else
+            y = r.bottom() - 1.0 - d_data->margin - colorBarWidth;
+    }
+
+    d_data->scaleDraw->move( x, y );
+    d_data->scaleDraw->setLength( length );
+
+    const int extent = qCeil( d_data->scaleDraw->extent( font() ) );
+
+    d_data->titleOffset =
+        d_data->margin + d_data->spacing + colorBarWidth + extent;
+
+    if ( update_geometry )
+    {
+        updateGeometry();
+        update();
+    }
+}
+
+/*!
+  Draw the color bar of the scale widget
+
+  \param painter Painter
+  \param rect Bounding rectangle for the color bar
+
+  \sa setColorBarEnabled()
+*/
+void QwtScaleWidget::drawColorBar( QPainter *painter, const QRectF& rect ) const
+{
+    if ( !d_data->colorBar.interval.isValid() )
+        return;
+
+    const QwtScaleDraw* sd = d_data->scaleDraw;
+
+    QwtPainter::drawColorBar( painter, *d_data->colorBar.colorMap,
+        d_data->colorBar.interval.normalized(), sd->scaleMap(),
+        sd->orientation(), rect );
+}
+
+/*!
+  Rotate and paint a title according to its position into a given rectangle.
+
+  \param painter Painter
+  \param align Alignment
+  \param rect Bounding rectangle
+*/
+
+void QwtScaleWidget::drawTitle( QPainter *painter,
+    QwtScaleDraw::Alignment align, const QRectF &rect ) const
+{
+    QRectF r = rect;
+    double angle;
+    int flags = d_data->title.renderFlags() &
+        ~( Qt::AlignTop | Qt::AlignBottom | Qt::AlignVCenter );
+
+    switch ( align )
+    {
+        case QwtScaleDraw::LeftScale:
+            angle = -90.0;
+            flags |= Qt::AlignTop;
+            r.setRect( r.left(), r.bottom(),
+                r.height(), r.width() - d_data->titleOffset );
+            break;
+
+        case QwtScaleDraw::RightScale:
+            angle = -90.0;
+            flags |= Qt::AlignTop;
+            r.setRect( r.left() + d_data->titleOffset, r.bottom(),
+                r.height(), r.width() - d_data->titleOffset );
+            break;
+
+        case QwtScaleDraw::BottomScale:
+            angle = 0.0;
+            flags |= Qt::AlignBottom;
+            r.setTop( r.top() + d_data->titleOffset );
+            break;
+
+        case QwtScaleDraw::TopScale:
+        default:
+            angle = 0.0;
+            flags |= Qt::AlignTop;
+            r.setBottom( r.bottom() - d_data->titleOffset );
+            break;
+    }
+
+    if ( d_data->layoutFlags & TitleInverted )
+    {
+        if ( align == QwtScaleDraw::LeftScale
+            || align == QwtScaleDraw::RightScale )
+        {
+            angle = -angle;
+            r.setRect( r.x() + r.height(), r.y() - r.width(),
+                r.width(), r.height() );
+        }
+    }
+
+    painter->save();
+    painter->setFont( font() );
+    painter->setPen( palette().color( QPalette::Text ) );
+
+    painter->translate( r.x(), r.y() );
+    if ( angle != 0.0 )
+        painter->rotate( angle );
+
+    QwtText title = d_data->title;
+    title.setRenderFlags( flags );
+    title.draw( painter, QRect( 0, 0, r.width(), r.height() ) );
+
+    painter->restore();
+}
+
+/*!
+  \brief Notify a change of the scale
+
+  This virtual function can be overloaded by derived
+  classes. The default implementation updates the geometry
+  and repaints the widget.
+*/
+
+void QwtScaleWidget::scaleChange()
+{
+    layoutScale();
+}
+
+/*!
+  \return a size hint
+*/
+QSize QwtScaleWidget::sizeHint() const
+{
+    return minimumSizeHint();
+}
+
+/*!
+  \return a minimum size hint
+*/
+QSize QwtScaleWidget::minimumSizeHint() const
+{
+    const Qt::Orientation o = d_data->scaleDraw->orientation();
+
+    // Border Distance cannot be less than the scale borderDistHint
+    // Note, the borderDistHint is already included in minHeight/minWidth
+    int length = 0;
+    int mbd1, mbd2;
+    getBorderDistHint( mbd1, mbd2 );
+    length += qMax( 0, d_data->borderDist[0] - mbd1 );
+    length += qMax( 0, d_data->borderDist[1] - mbd2 );
+    length += d_data->scaleDraw->minLength( font() );
+
+    int dim = dimForLength( length, font() );
+    if ( length < dim )
+    {
+        // compensate for long titles
+        length = dim;
+        dim = dimForLength( length, font() );
+    }
+
+    QSize size( length + 2, dim );
+    if ( o == Qt::Vertical )
+        size.transpose();
+
+    int left, right, top, bottom;
+    getContentsMargins( &left, &top, &right, &bottom );
+    return size + QSize( left + right, top + bottom );
+}
+
+/*!
+  \brief Find the height of the title for a given width.
+  \param width Width
+  \return height Height
+ */
+
+int QwtScaleWidget::titleHeightForWidth( int width ) const
+{
+    return d_data->title.heightForWidth( width, font() );
+}
+
+/*!
+  \brief Find the minimum dimension for a given length.
+         dim is the height, length the width seen in
+         direction of the title.
+  \param length width for horizontal, height for vertical scales
+  \param scaleFont Font of the scale
+  \return height for horizontal, width for vertical scales
+*/
+
+int QwtScaleWidget::dimForLength( int length, const QFont &scaleFont ) const
+{
+    const int extent = qCeil( d_data->scaleDraw->extent( scaleFont ) );
+
+    int dim = d_data->margin + extent + 1;
+
+    if ( !d_data->title.isEmpty() )
+        dim += titleHeightForWidth( length ) + d_data->spacing;
+
+    if ( d_data->colorBar.isEnabled && d_data->colorBar.interval.isValid() )
+        dim += d_data->colorBar.width + d_data->spacing;
+
+    return dim;
+}
+
+/*!
+  \brief Calculate a hint for the border distances.
+
+  This member function calculates the distance
+  of the scale's endpoints from the widget borders which
+  is required for the mark labels to fit into the widget.
+  The maximum of this distance an the minimum border distance
+  is returned.
+
+  \warning
+  <ul> <li>The minimum border distance depends on the font.</ul>
+  \sa setMinBorderDist(), getMinBorderDist(), setBorderDist()
+*/
+void QwtScaleWidget::getBorderDistHint( int &start, int &end ) const
+{
+    d_data->scaleDraw->getBorderDistHint( font(), start, end );
+
+    if ( start < d_data->minBorderDist[0] )
+        start = d_data->minBorderDist[0];
+
+    if ( end < d_data->minBorderDist[1] )
+        end = d_data->minBorderDist[1];
+}
+
+/*!
+  Set a minimum value for the distances of the scale's endpoints from
+  the widget borders. This is useful to avoid that the scales
+  are "jumping", when the tick labels or their positions change
+  often.
+
+  \param start Minimum for the start border
+  \param end Minimum for the end border
+  \sa getMinBorderDist(), getBorderDistHint()
+*/
+void QwtScaleWidget::setMinBorderDist( int start, int end )
+{
+    d_data->minBorderDist[0] = start;
+    d_data->minBorderDist[1] = end;
+}
+
+/*!
+  Get the minimum value for the distances of the scale's endpoints from
+  the widget borders.
+
+  \sa setMinBorderDist(), getBorderDistHint()
+*/
+void QwtScaleWidget::getMinBorderDist( int &start, int &end ) const
+{
+    start = d_data->minBorderDist[0];
+    end = d_data->minBorderDist[1];
+}
+
+/*!
+  \brief Assign a scale division
+
+  The scale division determines where to set the tick marks.
+
+  \param transformation Transformation, needed to translate between
+                        scale and pixal values
+  \param scaleDiv Scale Division
+  \sa For more information about scale divisions, see QwtScaleDiv.
+*/
+void QwtScaleWidget::setScaleDiv(
+    QwtScaleTransformation *transformation,
+    const QwtScaleDiv &scaleDiv )
+{
+    QwtScaleDraw *sd = d_data->scaleDraw;
+    if ( sd->scaleDiv() != scaleDiv ||
+        sd->scaleMap().transformation()->type() != transformation->type() )
+    {
+        sd->setTransformation( transformation );
+        sd->setScaleDiv( scaleDiv );
+        layoutScale();
+
+        Q_EMIT scaleDivChanged();
+    }
+    else
+    {
+        /*
+          The transformation doesn't anything different as the 
+          previous one. So we better throw it silently away instead of 
+          initiating heavy updates
+         */
+
+        delete transformation;
+    }
+}
+
+/*!
+  En/disable a color bar associated to the scale
+  \sa isColorBarEnabled(), setColorBarWidth()
+*/
+void QwtScaleWidget::setColorBarEnabled( bool on )
+{
+    if ( on != d_data->colorBar.isEnabled )
+    {
+        d_data->colorBar.isEnabled = on;
+        layoutScale();
+    }
+}
+
+/*!
+  \return true, when the color bar is enabled
+  \sa setColorBarEnabled(), setColorBarWidth()
+*/
+bool QwtScaleWidget::isColorBarEnabled() const
+{
+    return d_data->colorBar.isEnabled;
+}
+
+/*!
+  Set the width of the color bar
+
+  \param width Width
+  \sa colorBarWidth(), setColorBarEnabled()
+*/
+void QwtScaleWidget::setColorBarWidth( int width )
+{
+    if ( width != d_data->colorBar.width )
+    {
+        d_data->colorBar.width = width;
+        if ( isColorBarEnabled() )
+            layoutScale();
+    }
+}
+
+/*!
+  \return Width of the color bar
+  \sa setColorBarEnabled(), setColorBarEnabled()
+*/
+int QwtScaleWidget::colorBarWidth() const
+{
+    return d_data->colorBar.width;
+}
+
+/*!
+  \return Value interval for the color bar
+  \sa setColorMap(), colorMap()
+*/
+QwtInterval QwtScaleWidget::colorBarInterval() const
+{
+    return d_data->colorBar.interval;
+}
+
+/*!
+  Set the color map and value interval, that are used for displaying
+  the color bar.
+
+  \param interval Value interval
+  \param colorMap Color map
+
+  \sa colorMap(), colorBarInterval()
+*/
+void QwtScaleWidget::setColorMap(
+    const QwtInterval &interval, QwtColorMap *colorMap )
+{
+    d_data->colorBar.interval = interval;
+
+    if ( colorMap != d_data->colorBar.colorMap )
+    {
+        delete d_data->colorBar.colorMap;
+        d_data->colorBar.colorMap = colorMap;
+    }
+
+    if ( isColorBarEnabled() )
+        layoutScale();
+}
+
+/*!
+  \return Color map
+  \sa setColorMap(), colorBarInterval()
+*/
+const QwtColorMap *QwtScaleWidget::colorMap() const
+{
+    return d_data->colorBar.colorMap;
+}
Index: trunk/BNC/qwt/qwt_scale_widget.h
===================================================================
--- trunk/BNC/qwt/qwt_scale_widget.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_scale_widget.h	(revision 4271)
@@ -0,0 +1,135 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_SCALE_WIDGET_H
+#define QWT_SCALE_WIDGET_H
+
+#include "qwt_global.h"
+#include "qwt_text.h"
+#include "qwt_scale_draw.h"
+#include <qwidget.h>
+#include <qfont.h>
+#include <qcolor.h>
+#include <qstring.h>
+
+class QPainter;
+class QwtScaleTransformation;
+class QwtScaleDiv;
+class QwtColorMap;
+
+/*!
+  \brief A Widget which contains a scale
+
+  This Widget can be used to decorate composite widgets with
+  a scale.
+*/
+
+class QWT_EXPORT QwtScaleWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    //! Layout flags of the title
+    enum LayoutFlag
+    {
+        /*!
+          The title of vertical scales is painted from top to bottom. 
+          Otherwise it is painted from bottom to top.
+         */
+        TitleInverted = 1
+    };
+
+    //! Layout flags of the title
+    typedef QFlags<LayoutFlag> LayoutFlags;
+
+    explicit QwtScaleWidget( QWidget *parent = NULL );
+    explicit QwtScaleWidget( QwtScaleDraw::Alignment, QWidget *parent = NULL );
+    virtual ~QwtScaleWidget();
+
+Q_SIGNALS:
+    //! Signal emitted, whenever the scale divison changes
+    void scaleDivChanged();
+
+public:
+    void setTitle( const QString &title );
+    void setTitle( const QwtText &title );
+    QwtText title() const;
+
+    void setLayoutFlag( LayoutFlag, bool on );
+    bool testLayoutFlag( LayoutFlag ) const;
+
+    void setBorderDist( int start, int end );
+    int startBorderDist() const;
+    int endBorderDist() const;
+
+    void getBorderDistHint( int &start, int &end ) const;
+
+    void getMinBorderDist( int &start, int &end ) const;
+    void setMinBorderDist( int start, int end );
+
+    void setMargin( int );
+    int margin() const;
+
+    void setSpacing( int td );
+    int spacing() const;
+
+    void setScaleDiv( QwtScaleTransformation *, const QwtScaleDiv &sd );
+
+    void setScaleDraw( QwtScaleDraw * );
+    const QwtScaleDraw *scaleDraw() const;
+    QwtScaleDraw *scaleDraw();
+
+    void setLabelAlignment( Qt::Alignment );
+    void setLabelRotation( double rotation );
+
+    void setColorBarEnabled( bool );
+    bool isColorBarEnabled() const;
+
+    void setColorBarWidth( int );
+    int colorBarWidth() const;
+
+    void setColorMap( const QwtInterval &, QwtColorMap * );
+
+    QwtInterval colorBarInterval() const;
+    const QwtColorMap *colorMap() const;
+
+    virtual QSize sizeHint() const;
+    virtual QSize minimumSizeHint() const;
+
+    int titleHeightForWidth( int width ) const;
+    int dimForLength( int length, const QFont &scaleFont ) const;
+
+    void drawColorBar( QPainter *painter, const QRectF & ) const;
+    void drawTitle( QPainter *painter, QwtScaleDraw::Alignment,
+        const QRectF &rect ) const;
+
+    void setAlignment( QwtScaleDraw::Alignment );
+    QwtScaleDraw::Alignment alignment() const;
+
+    QRectF colorBarRect( const QRectF& ) const;
+
+protected:
+    virtual void paintEvent( QPaintEvent * );
+    virtual void resizeEvent( QResizeEvent * );
+
+    void draw( QPainter *p ) const;
+
+    void scaleChange();
+    void layoutScale( bool update = true );
+
+private:
+    void initScale( QwtScaleDraw::Alignment );
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtScaleWidget::LayoutFlags )
+
+#endif
Index: trunk/BNC/qwt/qwt_series_data.cpp
===================================================================
--- trunk/BNC/qwt/qwt_series_data.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_series_data.cpp	(revision 4271)
@@ -0,0 +1,586 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_series_data.h"
+#include "qwt_math.h"
+
+static inline QRectF qwtBoundingRect( const QPointF &sample )
+{
+    return QRectF( sample.x(), sample.y(), 0.0, 0.0 );
+}
+
+static inline QRectF qwtBoundingRect( const QwtPoint3D &sample )
+{
+    return QRectF( sample.x(), sample.y(), 0.0, 0.0 );
+}
+
+static inline QRectF qwtBoundingRect( const QwtPointPolar &sample )
+{
+    return QRectF( sample.azimuth(), sample.radius(), 0.0, 0.0 );
+}
+
+static inline QRectF qwtBoundingRect( const QwtIntervalSample &sample )
+{
+    return QRectF( sample.interval.minValue(), sample.value,
+        sample.interval.maxValue() - sample.interval.minValue(), 0.0 );
+}
+
+static inline QRectF qwtBoundingRect( const QwtSetSample &sample )
+{
+    double minX = sample.set[0];
+    double maxX = sample.set[0];
+
+    for ( int i = 1; i < ( int )sample.set.size(); i++ )
+    {
+        if ( sample.set[i] < minX )
+            minX = sample.set[i];
+        if ( sample.set[i] > maxX )
+            maxX = sample.set[i];
+    }
+
+    double minY = sample.value;
+    double maxY = sample.value;
+
+    return QRectF( minX, minY, maxX - minX, maxY - minY );
+}
+
+/*!
+  \brief Calculate the bounding rect of a series subset
+
+  Slow implementation, that iterates over the series.
+
+  \param series Series
+  \param from Index of the first sample, <= 0 means from the beginning
+  \param to Index of the last sample, < 0 means to the end
+
+  \return Bounding rectangle
+*/
+
+template <class T>
+QRectF qwtBoundingRectT( 
+    const QwtSeriesData<T>& series, int from, int to )
+{
+    QRectF boundingRect( 1.0, 1.0, -2.0, -2.0 ); // invalid;
+
+    if ( from < 0 )
+        from = 0;
+
+    if ( to < 0 )
+        to = series.size() - 1;
+
+    if ( to < from )
+        return boundingRect;
+
+    int i;
+    for ( i = from; i <= to; i++ )
+    {
+        const QRectF rect = qwtBoundingRect( series.sample( i ) );
+        if ( rect.width() >= 0.0 && rect.height() >= 0.0 )
+        {
+            boundingRect = rect;
+            i++;
+            break;
+        }
+    }
+
+    for ( ; i <= to; i++ )
+    {
+        const QRectF rect = qwtBoundingRect( series.sample( i ) );
+        if ( rect.width() >= 0.0 && rect.height() >= 0.0 )
+        {
+            boundingRect.setLeft( qMin( boundingRect.left(), rect.left() ) );
+            boundingRect.setRight( qMax( boundingRect.right(), rect.right() ) );
+            boundingRect.setTop( qMin( boundingRect.top(), rect.top() ) );
+            boundingRect.setBottom( qMax( boundingRect.bottom(), rect.bottom() ) );
+        }
+    }
+
+    return boundingRect;
+}
+
+/*!
+  \brief Calculate the bounding rect of a series subset
+
+  Slow implementation, that iterates over the series.
+
+  \param series Series
+  \param from Index of the first sample, <= 0 means from the beginning
+  \param to Index of the last sample, < 0 means to the end
+
+  \return Bounding rectangle
+*/
+QRectF qwtBoundingRect( 
+    const QwtSeriesData<QPointF> &series, int from, int to )
+{
+    return qwtBoundingRectT<QPointF>( series, from, to );
+}
+
+/*!
+  \brief Calculate the bounding rect of a series subset
+
+  Slow implementation, that iterates over the series.
+
+  \param series Series
+  \param from Index of the first sample, <= 0 means from the beginning
+  \param to Index of the last sample, < 0 means to the end
+
+  \return Bounding rectangle
+*/
+QRectF qwtBoundingRect( 
+    const QwtSeriesData<QwtPoint3D> &series, int from, int to )
+{
+    return qwtBoundingRectT<QwtPoint3D>( series, from, to );
+}
+
+/*!
+  \brief Calculate the bounding rect of a series subset
+
+  The horizontal coordinates represent the azimuth, the
+  vertical coordinates the radius.
+
+  Slow implementation, that iterates over the series.
+
+  \param series Series
+  \param from Index of the first sample, <= 0 means from the beginning
+  \param to Index of the last sample, < 0 means to the end
+
+  \return Bounding rectangle
+*/
+QRectF qwtBoundingRect( 
+    const QwtSeriesData<QwtPointPolar> &series, int from, int to )
+{
+    return qwtBoundingRectT<QwtPointPolar>( series, from, to );
+}
+
+/*!
+  \brief Calculate the bounding rect of a series subset
+
+  Slow implementation, that iterates over the series.
+
+  \param series Series
+  \param from Index of the first sample, <= 0 means from the beginning
+  \param to Index of the last sample, < 0 means to the end
+
+  \return Bounding rectangle
+*/
+QRectF qwtBoundingRect( 
+    const QwtSeriesData<QwtIntervalSample>& series, int from, int to )
+{
+    return qwtBoundingRectT<QwtIntervalSample>( series, from, to );
+}
+
+/*!
+  \brief Calculate the bounding rect of a series subset
+
+  Slow implementation, that iterates over the series.
+
+  \param series Series
+  \param from Index of the first sample, <= 0 means from the beginning
+  \param to Index of the last sample, < 0 means to the end
+
+  \return Bounding rectangle
+*/
+QRectF qwtBoundingRect( 
+    const QwtSeriesData<QwtSetSample>& series, int from, int to )
+{
+    return qwtBoundingRectT<QwtSetSample>( series, from, to );
+}
+
+/*!
+   Constructor
+   \param samples Samples
+*/
+QwtPointSeriesData::QwtPointSeriesData(
+        const QVector<QPointF> &samples ):
+    QwtArraySeriesData<QPointF>( samples )
+{
+}
+
+/*!
+  \brief Calculate the bounding rect
+
+  The bounding rectangle is calculated once by iterating over all
+  points and is stored for all following requests.
+
+  \return Bounding rectangle
+*/
+QRectF QwtPointSeriesData::boundingRect() const
+{
+    if ( d_boundingRect.width() < 0.0 )
+        d_boundingRect = qwtBoundingRect( *this );
+
+    return d_boundingRect;
+}
+
+/*!
+   Constructor
+   \param samples Samples
+*/
+QwtPoint3DSeriesData::QwtPoint3DSeriesData(
+        const QVector<QwtPoint3D> &samples ):
+    QwtArraySeriesData<QwtPoint3D>( samples )
+{
+}
+
+/*!
+  \brief Calculate the bounding rect
+
+  The bounding rectangle is calculated once by iterating over all
+  points and is stored for all following requests.
+
+  \return Bounding rectangle
+*/
+QRectF QwtPoint3DSeriesData::boundingRect() const
+{
+    if ( d_boundingRect.width() < 0.0 )
+        d_boundingRect = qwtBoundingRect( *this );
+
+    return d_boundingRect;
+}
+
+/*!
+   Constructor
+   \param samples Samples
+*/
+QwtIntervalSeriesData::QwtIntervalSeriesData(
+        const QVector<QwtIntervalSample> &samples ):
+    QwtArraySeriesData<QwtIntervalSample>( samples )
+{
+}
+
+/*!
+  \brief Calculate the bounding rect
+
+  The bounding rectangle is calculated once by iterating over all
+  points and is stored for all following requests.
+
+  \return Bounding rectangle
+*/
+QRectF QwtIntervalSeriesData::boundingRect() const
+{
+    if ( d_boundingRect.width() < 0.0 )
+        d_boundingRect = qwtBoundingRect( *this );
+
+    return d_boundingRect;
+}
+
+/*!
+   Constructor
+   \param samples Samples
+*/
+QwtSetSeriesData::QwtSetSeriesData(
+        const QVector<QwtSetSample> &samples ):
+    QwtArraySeriesData<QwtSetSample>( samples )
+{
+}
+
+/*!
+  \brief Calculate the bounding rect
+
+  The bounding rectangle is calculated once by iterating over all
+  points and is stored for all following requests.
+
+  \return Bounding rectangle
+*/
+QRectF QwtSetSeriesData::boundingRect() const
+{
+    if ( d_boundingRect.width() < 0.0 )
+        d_boundingRect = qwtBoundingRect( *this );
+
+    return d_boundingRect;
+}
+
+/*!
+  Constructor
+
+  \param x Array of x values
+  \param y Array of y values
+
+  \sa QwtPlotCurve::setData(), QwtPlotCurve::setSamples()
+*/
+QwtPointArrayData::QwtPointArrayData(
+        const QVector<double> &x, const QVector<double> &y ):
+    d_x( x ),
+    d_y( y )
+{
+}
+
+/*!
+  Constructor
+
+  \param x Array of x values
+  \param y Array of y values
+  \param size Size of the x and y arrays
+  \sa QwtPlotCurve::setData(), QwtPlotCurve::setSamples()
+*/
+QwtPointArrayData::QwtPointArrayData( const double *x,
+        const double *y, size_t size )
+{
+    d_x.resize( size );
+    qMemCopy( d_x.data(), x, size * sizeof( double ) );
+
+    d_y.resize( size );
+    qMemCopy( d_y.data(), y, size * sizeof( double ) );
+}
+
+/*!
+  \brief Calculate the bounding rect
+
+  The bounding rectangle is calculated once by iterating over all
+  points and is stored for all following requests.
+
+  \return Bounding rectangle
+*/
+QRectF QwtPointArrayData::boundingRect() const
+{
+    if ( d_boundingRect.width() < 0 )
+        d_boundingRect = qwtBoundingRect( *this );
+
+    return d_boundingRect;
+}
+
+//! \return Size of the data set
+size_t QwtPointArrayData::size() const
+{
+    return qMin( d_x.size(), d_y.size() );
+}
+
+/*!
+  Return the sample at position i
+
+  \param i Index
+  \return Sample at position i
+*/
+QPointF QwtPointArrayData::sample( size_t i ) const
+{
+    return QPointF( d_x[int( i )], d_y[int( i )] );
+}
+
+//! \return Array of the x-values
+const QVector<double> &QwtPointArrayData::xData() const
+{
+    return d_x;
+}
+
+//! \return Array of the y-values
+const QVector<double> &QwtPointArrayData::yData() const
+{
+    return d_y;
+}
+
+/*!
+  Constructor
+
+  \param x Array of x values
+  \param y Array of y values
+  \param size Size of the x and y arrays
+
+  \warning The programmer must assure that the memory blocks referenced
+           by the pointers remain valid during the lifetime of the
+           QwtPlotCPointer object.
+
+  \sa QwtPlotCurve::setData(), QwtPlotCurve::setRawSamples()
+*/
+QwtCPointerData::QwtCPointerData(
+        const double *x, const double *y, size_t size ):
+    d_x( x ),
+    d_y( y ),
+    d_size( size )
+{
+}
+
+/*!
+  \brief Calculate the bounding rect
+
+  The bounding rectangle is calculated once by iterating over all
+  points and is stored for all following requests.
+
+  \return Bounding rectangle
+*/
+QRectF QwtCPointerData::boundingRect() const
+{
+    if ( d_boundingRect.width() < 0 )
+        d_boundingRect = qwtBoundingRect( *this );
+
+    return d_boundingRect;
+}
+
+//! \return Size of the data set
+size_t QwtCPointerData::size() const
+{
+    return d_size;
+}
+
+/*!
+  Return the sample at position i
+
+  \param i Index
+  \return Sample at position i
+*/
+QPointF QwtCPointerData::sample( size_t i ) const
+{
+    return QPointF( d_x[int( i )], d_y[int( i )] );
+}
+
+//! \return Array of the x-values
+const double *QwtCPointerData::xData() const
+{
+    return d_x;
+}
+
+//! \return Array of the y-values
+const double *QwtCPointerData::yData() const
+{
+    return d_y;
+}
+
+/*!
+   Constructor
+
+   \param size Number of points
+   \param interval Bounding interval for the points
+
+   \sa setInterval(), setSize()
+*/
+QwtSyntheticPointData::QwtSyntheticPointData(
+        size_t size, const QwtInterval &interval ):
+    d_size( size ),
+    d_interval( interval )
+{
+}
+
+/*!
+  Change the number of points
+
+  \param size Number of points
+  \sa size(), setInterval()
+*/
+void QwtSyntheticPointData::setSize( size_t size )
+{
+    d_size = size;
+}
+
+/*!
+  \return Number of points
+  \sa setSize(), interval()
+*/
+size_t QwtSyntheticPointData::size() const
+{
+    return d_size;
+}
+
+/*!
+   Set the bounding interval
+
+   \param interval Interval
+   \sa interval(), setSize()
+*/
+void QwtSyntheticPointData::setInterval( const QwtInterval &interval )
+{
+    d_interval = interval.normalized();
+}
+
+/*!
+   \return Bounding interval
+   \sa setInterval(), size()
+*/
+QwtInterval QwtSyntheticPointData::interval() const
+{
+    return d_interval;
+}
+
+/*!
+   Set a the "rect of interest"
+
+   QwtPlotSeriesItem defines the current area of the plot canvas
+   as "rect of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).
+
+   If interval().isValid() == false the x values are calculated
+   in the interval rect.left() -> rect.right().
+
+   \sa rectOfInterest()
+*/
+void QwtSyntheticPointData::setRectOfInterest( const QRectF &rect )
+{
+    d_rectOfInterest = rect;
+    d_intervalOfInterest = QwtInterval(
+        rect.left(), rect.right() ).normalized();
+}
+
+/*!
+   \return "rect of interest"
+   \sa setRectOfInterest()
+*/
+QRectF QwtSyntheticPointData::rectOfInterest() const
+{
+    return d_rectOfInterest;
+}
+
+/*!
+  \brief Calculate the bounding rect
+
+  This implementation iterates over all points, what could often
+  be implemented much faster using the characteristics of the series.
+  When there are many points it is recommended to overload and
+  reimplement this method using the characteristics of the series
+  ( if possible ).
+
+  \return Bounding rectangle
+*/
+QRectF QwtSyntheticPointData::boundingRect() const
+{
+    if ( d_size == 0 || 
+        !( d_interval.isValid() || d_intervalOfInterest.isValid() ) )
+    {
+        return QRectF(1.0, 1.0, -2.0, -2.0); // something invalid
+    }
+
+    return qwtBoundingRect( *this );
+}
+
+/*!
+   Calculate the point from an index
+
+   \param index Index
+   \return QPointF(x(index), y(x(index)));
+
+   \warning For invalid indices ( index < 0 || index >= size() )
+            (0, 0) is returned.
+*/
+QPointF QwtSyntheticPointData::sample( size_t index ) const
+{
+    if ( index >= d_size )
+        return QPointF( 0, 0 );
+
+    const double xValue = x( index );
+    const double yValue = y( xValue );
+
+    return QPointF( xValue, yValue );
+}
+
+/*!
+   Calculate a x-value from an index
+
+   x values are calculated by deviding an interval into
+   equidistant steps. If !interval().isValid() the
+   interval is calculated from the "rect of interest".
+
+   \sa interval(), rectOfInterest(), y()
+*/
+double QwtSyntheticPointData::x( uint index ) const
+{
+    const QwtInterval &interval = d_interval.isValid() ?
+        d_interval : d_intervalOfInterest;
+
+    if ( !interval.isValid() || d_size == 0 || index >= d_size )
+        return 0.0;
+
+    const double dx = interval.width() / d_size;
+    return interval.minValue() + index * dx;
+}
Index: trunk/BNC/qwt/qwt_series_data.h
===================================================================
--- trunk/BNC/qwt/qwt_series_data.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_series_data.h	(revision 4271)
@@ -0,0 +1,442 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_SERIES_DATA_H
+#define QWT_SERIES_DATA_H 1
+
+#include "qwt_global.h"
+#include "qwt_interval.h"
+#include "qwt_point_3d.h"
+#include "qwt_point_polar.h"
+#include <qvector.h>
+#include <qrect.h>
+
+//! \brief A sample of the types (x1-x2, y) or (x, y1-y2)
+class QWT_EXPORT QwtIntervalSample
+{
+public:
+    QwtIntervalSample();
+    QwtIntervalSample( double, const QwtInterval & );
+    QwtIntervalSample( double value, double min, double max );
+
+    bool operator==( const QwtIntervalSample & ) const;
+    bool operator!=( const QwtIntervalSample & ) const;
+
+    //! Value
+    double value;
+
+    //! Interval
+    QwtInterval interval;
+};
+
+/*!
+  Constructor
+  The value is set to 0.0, the interval is invalid
+*/
+inline QwtIntervalSample::QwtIntervalSample():
+    value( 0.0 )
+{
+}
+
+//! Constructor
+inline QwtIntervalSample::QwtIntervalSample(
+        double v, const QwtInterval &intv ):
+    value( v ),
+    interval( intv )
+{
+}
+
+//! Constructor
+inline QwtIntervalSample::QwtIntervalSample(
+        double v, double min, double max ):
+    value( v ),
+    interval( min, max )
+{
+}
+
+//! Compare operator
+inline bool QwtIntervalSample::operator==( 
+    const QwtIntervalSample &other ) const
+{
+    return value == other.value && interval == other.interval;
+}
+
+//! Compare operator
+inline bool QwtIntervalSample::operator!=( 
+    const QwtIntervalSample &other ) const
+{
+    return !( *this == other );
+}
+
+//! \brief A sample of the types (x1...xn, y) or (x, y1..yn)
+class QWT_EXPORT QwtSetSample
+{
+public:
+    QwtSetSample();
+    bool operator==( const QwtSetSample &other ) const;
+    bool operator!=( const QwtSetSample &other ) const;
+
+    //! value
+    double value;
+
+    //! Vector of values associated to value
+    QVector<double> set;
+};
+
+/*!
+  Constructor
+  The value is set to 0.0
+*/
+inline QwtSetSample::QwtSetSample():
+    value( 0.0 )
+{
+}
+
+//! Compare operator
+inline bool QwtSetSample::operator==( const QwtSetSample &other ) const
+{
+    return value == other.value && set == other.set;
+}
+
+//! Compare operator
+inline bool QwtSetSample::operator!=( const QwtSetSample &other ) const
+{
+    return !( *this == other );
+}
+
+/*!
+   \brief Abstract interface for iterating over samples
+
+   Qwt offers several implementations of the QwtSeriesData API,
+   but in situations, where data of an application specific format
+   needs to be displayed, without having to copy it, it is recommended
+   to implement an individual data access.
+*/
+template <typename T>
+class QwtSeriesData
+{
+public:
+    QwtSeriesData();
+    virtual ~QwtSeriesData();
+
+    //! \return Number of samples
+    virtual size_t size() const = 0;
+
+    /*!
+      Return a sample
+      \param i Index
+      \return Sample at position i
+     */
+    virtual T sample( size_t i ) const = 0;
+
+    /*!
+       Calculate the bounding rect of all samples
+
+       The bounding rect is necessary for autoscaling and can be used
+       for a couple of painting optimizations.
+
+       qwtBoundingRect(...) offers slow implementations iterating
+       over the samples. For large sets it is recommended to implement
+       something faster f.e. by caching the bounding rect.
+     */
+    virtual QRectF boundingRect() const = 0;
+
+    virtual void setRectOfInterest( const QRectF & );
+
+protected:
+    //! Can be used to cache a calculated bounding rectangle
+    mutable QRectF d_boundingRect;
+
+private:
+    QwtSeriesData<T> &operator=( const QwtSeriesData<T> & );
+};
+
+//! Constructor
+template <typename T>
+QwtSeriesData<T>::QwtSeriesData():
+    d_boundingRect( 0.0, 0.0, -1.0, -1.0 )
+{
+}
+
+//! Destructor
+template <typename T>
+QwtSeriesData<T>::~QwtSeriesData()
+{
+}
+
+/*!
+   Set a the "rect of interest"
+
+   QwtPlotSeriesItem defines the current area of the plot canvas
+   as "rect of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).
+   It can be used to implement different levels of details.
+
+   The default implementation does nothing.
+*/
+template <typename T>
+void QwtSeriesData<T>::setRectOfInterest( const QRectF & )
+{
+}
+
+/*!
+  \brief Template class for data, that is organized as QVector
+
+  QVector uses implicit data sharing and can be
+  passed around as argument efficiently.
+*/
+template <typename T>
+class QwtArraySeriesData: public QwtSeriesData<T>
+{
+public:
+    QwtArraySeriesData();
+    QwtArraySeriesData( const QVector<T> & );
+
+    void setSamples( const QVector<T> & );
+    const QVector<T> samples() const;
+
+    virtual size_t size() const;
+    virtual T sample( size_t ) const;
+
+protected:
+    //! Vector of samples
+    QVector<T> d_samples;
+};
+
+//! Constructor
+template <typename T>
+QwtArraySeriesData<T>::QwtArraySeriesData()
+{
+}
+
+/*!
+   Constructor
+   \param samples Array of samples
+*/
+template <typename T>
+QwtArraySeriesData<T>::QwtArraySeriesData( const QVector<T> &samples ):
+    d_samples( samples )
+{
+}
+
+/*!
+  Assign an array of samples
+  \param samples Array of samples
+*/
+template <typename T>
+void QwtArraySeriesData<T>::setSamples( const QVector<T> &samples )
+{
+    QwtSeriesData<T>::d_boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
+    d_samples = samples;
+}
+
+//! \return Array of samples
+template <typename T>
+const QVector<T> QwtArraySeriesData<T>::samples() const
+{
+    return d_samples;
+}
+
+//! \return Number of samples
+template <typename T>
+size_t QwtArraySeriesData<T>::size() const
+{
+    return d_samples.size();
+}
+
+/*!
+  Return a sample
+  \param i Index
+  \return Sample at position i
+*/
+template <typename T>
+T QwtArraySeriesData<T>::sample( size_t i ) const
+{
+    return d_samples[i];
+}
+
+//! Interface for iterating over an array of points
+class QWT_EXPORT QwtPointSeriesData: public QwtArraySeriesData<QPointF>
+{
+public:
+    QwtPointSeriesData(
+        const QVector<QPointF> & = QVector<QPointF>() );
+
+    virtual QRectF boundingRect() const;
+};
+
+//! Interface for iterating over an array of 3D points
+class QWT_EXPORT QwtPoint3DSeriesData: public QwtArraySeriesData<QwtPoint3D>
+{
+public:
+    QwtPoint3DSeriesData(
+        const QVector<QwtPoint3D> & = QVector<QwtPoint3D>() );
+    virtual QRectF boundingRect() const;
+};
+
+//! Interface for iterating over an array of intervals
+class QWT_EXPORT QwtIntervalSeriesData: public QwtArraySeriesData<QwtIntervalSample>
+{
+public:
+    QwtIntervalSeriesData(
+        const QVector<QwtIntervalSample> & = QVector<QwtIntervalSample>() );
+
+    virtual QRectF boundingRect() const;
+};
+
+//! Interface for iterating over an array of samples
+class QWT_EXPORT QwtSetSeriesData: public QwtArraySeriesData<QwtSetSample>
+{
+public:
+    QwtSetSeriesData(
+        const QVector<QwtSetSample> & = QVector<QwtSetSample>() );
+
+    virtual QRectF boundingRect() const;
+};
+
+/*!
+  \brief Interface for iterating over two QVector<double> objects.
+*/
+class QWT_EXPORT QwtPointArrayData: public QwtSeriesData<QPointF>
+{
+public:
+    QwtPointArrayData( const QVector<double> &x, const QVector<double> &y );
+    QwtPointArrayData( const double *x, const double *y, size_t size );
+
+    virtual QRectF boundingRect() const;
+
+    virtual size_t size() const;
+    virtual QPointF sample( size_t i ) const;
+
+    const QVector<double> &xData() const;
+    const QVector<double> &yData() const;
+
+private:
+    QVector<double> d_x;
+    QVector<double> d_y;
+};
+
+/*!
+  \brief Data class containing two pointers to memory blocks of doubles.
+ */
+class QWT_EXPORT QwtCPointerData: public QwtSeriesData<QPointF>
+{
+public:
+    QwtCPointerData( const double *x, const double *y, size_t size );
+
+    virtual QRectF boundingRect() const;
+    virtual size_t size() const;
+    virtual QPointF sample( size_t i ) const;
+
+    const double *xData() const;
+    const double *yData() const;
+
+private:
+    const double *d_x;
+    const double *d_y;
+    size_t d_size;
+};
+
+/*!
+  \brief Synthetic point data
+
+  QwtSyntheticPointData provides a fixed number of points for an interval.
+  The points are calculated in equidistant steps in x-direction.
+
+  If the interval is invalid, the points are calculated for
+  the "rect of interest", what normally is the displayed area on the
+  plot canvas. In this mode you get different levels of detail, when
+  zooming in/out.
+
+  \par Example
+
+  The following example shows how to implement a sinus curve.
+
+  \verbatim
+#include <cmath>
+#include <qwt_series_data.h>
+#include <qwt_plot_curve.h>
+#include <qwt_plot.h>
+#include <qapplication.h>
+
+class SinusData: public QwtSyntheticPointData
+{
+public:
+    SinusData():
+        QwtSyntheticPointData(100)
+    {
+    }
+    virtual double y(double x) const
+    {
+        return qSin(x);
+    }
+};
+
+int main(int argc, char **argv)
+{
+    QApplication a(argc, argv);
+
+    QwtPlot plot;
+    plot.setAxisScale(QwtPlot::xBottom, 0.0, 10.0);
+    plot.setAxisScale(QwtPlot::yLeft, -1.0, 1.0);
+
+    QwtPlotCurve *curve = new QwtPlotCurve("y = sin(x)");
+    curve->setData(SinusData());
+    curve->attach(&plot);
+
+    plot.show();
+    return a.exec();
+}
+   \endverbatim
+*/
+class QWT_EXPORT QwtSyntheticPointData: public QwtSeriesData<QPointF>
+{
+public:
+    QwtSyntheticPointData( size_t size,
+        const QwtInterval & = QwtInterval() );
+
+    void setSize( size_t size );
+    size_t size() const;
+
+    void setInterval( const QwtInterval& );
+    QwtInterval interval() const;
+
+    virtual QRectF boundingRect() const;
+    virtual QPointF sample( size_t i ) const;
+
+    /*!
+       Calculate a y value for a x value
+
+       \param x x value
+       \return Corresponding y value
+     */
+    virtual double y( double x ) const = 0;
+    virtual double x( uint index ) const;
+
+    virtual void setRectOfInterest( const QRectF & );
+    QRectF rectOfInterest() const;
+
+private:
+    size_t d_size;
+    QwtInterval d_interval;
+    QRectF d_rectOfInterest;
+    QwtInterval d_intervalOfInterest;
+};
+
+QWT_EXPORT QRectF qwtBoundingRect(
+    const QwtSeriesData<QPointF> &, int from = 0, int to = -1 );
+QWT_EXPORT QRectF qwtBoundingRect(
+    const QwtSeriesData<QwtPoint3D> &, int from = 0, int to = -1 );
+QWT_EXPORT QRectF qwtBoundingRect(
+    const QwtSeriesData<QwtPointPolar> &, int from = 0, int to = -1 );
+QWT_EXPORT QRectF qwtBoundingRect(
+    const QwtSeriesData<QwtIntervalSample> &, int from = 0, int to = -1 );
+QWT_EXPORT QRectF qwtBoundingRect(
+    const QwtSeriesData<QwtSetSample> &, int from = 0, int to = -1 );
+
+#endif 
Index: trunk/BNC/qwt/qwt_spline.cpp
===================================================================
--- trunk/BNC/qwt/qwt_spline.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_spline.cpp	(revision 4271)
@@ -0,0 +1,380 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_spline.h"
+#include "qwt_math.h"
+
+class QwtSpline::PrivateData
+{
+public:
+    PrivateData():
+        splineType( QwtSpline::Natural )
+    {
+    }
+
+    QwtSpline::SplineType splineType;
+
+    // coefficient vectors
+    QVector<double> a;
+    QVector<double> b;
+    QVector<double> c;
+
+    // control points
+    QPolygonF points;
+};
+
+static int lookup( double x, const QPolygonF &values )
+{
+#if 0
+//qLowerBound/qHigherBound ???
+#endif
+    int i1;
+    const int size = values.size();
+
+    if ( x <= values[0].x() )
+        i1 = 0;
+    else if ( x >= values[size - 2].x() )
+        i1 = size - 2;
+    else
+    {
+        i1 = 0;
+        int i2 = size - 2;
+        int i3 = 0;
+
+        while ( i2 - i1 > 1 )
+        {
+            i3 = i1 + ( ( i2 - i1 ) >> 1 );
+
+            if ( values[i3].x() > x )
+                i2 = i3;
+            else
+                i1 = i3;
+        }
+    }
+    return i1;
+}
+
+//! Constructor
+QwtSpline::QwtSpline()
+{
+    d_data = new PrivateData;
+}
+
+/*!
+   Copy constructor
+   \param other Spline used for initilization
+*/
+QwtSpline::QwtSpline( const QwtSpline& other )
+{
+    d_data = new PrivateData( *other.d_data );
+}
+
+/*!
+   Assignment operator
+   \param other Spline used for initilization
+*/
+QwtSpline &QwtSpline::operator=( const QwtSpline & other )
+{
+    *d_data = *other.d_data;
+    return *this;
+}
+
+//! Destructor
+QwtSpline::~QwtSpline()
+{
+    delete d_data;
+}
+
+/*!
+   Select the algorithm used for calculating the spline
+
+   \param splineType Spline type
+   \sa splineType()
+*/
+void QwtSpline::setSplineType( SplineType splineType )
+{
+    d_data->splineType = splineType;
+}
+
+/*!
+   \return the spline type
+   \sa setSplineType()
+*/
+QwtSpline::SplineType QwtSpline::splineType() const
+{
+    return d_data->splineType;
+}
+
+/*!
+  \brief Calculate the spline coefficients
+
+  Depending on the value of \a periodic, this function
+  will determine the coefficients for a natural or a periodic
+  spline and store them internally.
+
+  \param points Points
+  \return true if successful
+  \warning The sequence of x (but not y) values has to be strictly monotone
+           increasing, which means <code>points[i].x() < points[i+1].x()</code>.
+       If this is not the case, the function will return false
+*/
+bool QwtSpline::setPoints( const QPolygonF& points )
+{
+    const int size = points.size();
+    if ( size <= 2 )
+    {
+        reset();
+        return false;
+    }
+
+    d_data->points = points;
+
+    d_data->a.resize( size - 1 );
+    d_data->b.resize( size - 1 );
+    d_data->c.resize( size - 1 );
+
+    bool ok;
+    if ( d_data->splineType == Periodic )
+        ok = buildPeriodicSpline( points );
+    else
+        ok = buildNaturalSpline( points );
+
+    if ( !ok )
+        reset();
+
+    return ok;
+}
+
+/*!
+   Return points passed by setPoints
+*/
+QPolygonF QwtSpline::points() const
+{
+    return d_data->points;
+}
+
+//! \return A coefficients
+const QVector<double> &QwtSpline::coefficientsA() const
+{
+    return d_data->a;
+}
+
+//! \return B coefficients
+const QVector<double> &QwtSpline::coefficientsB() const
+{
+    return d_data->b;
+}
+
+//! \return C coefficients
+const QVector<double> &QwtSpline::coefficientsC() const
+{
+    return d_data->c;
+}
+
+
+//! Free allocated memory and set size to 0
+void QwtSpline::reset()
+{
+    d_data->a.resize( 0 );
+    d_data->b.resize( 0 );
+    d_data->c.resize( 0 );
+    d_data->points.resize( 0 );
+}
+
+//! True if valid
+bool QwtSpline::isValid() const
+{
+    return d_data->a.size() > 0;
+}
+
+/*!
+  Calculate the interpolated function value corresponding
+  to a given argument x.
+*/
+double QwtSpline::value( double x ) const
+{
+    if ( d_data->a.size() == 0 )
+        return 0.0;
+
+    const int i = lookup( x, d_data->points );
+
+    const double delta = x - d_data->points[i].x();
+    return( ( ( ( d_data->a[i] * delta ) + d_data->b[i] )
+        * delta + d_data->c[i] ) * delta + d_data->points[i].y() );
+}
+
+/*!
+  \brief Determines the coefficients for a natural spline
+  \return true if successful
+*/
+bool QwtSpline::buildNaturalSpline( const QPolygonF &points )
+{
+    int i;
+
+    const QPointF *p = points.data();
+    const int size = points.size();
+
+    double *a = d_data->a.data();
+    double *b = d_data->b.data();
+    double *c = d_data->c.data();
+
+    //  set up tridiagonal equation system; use coefficient
+    //  vectors as temporary buffers
+    QVector<double> h( size - 1 );
+    for ( i = 0; i < size - 1; i++ )
+    {
+        h[i] = p[i+1].x() - p[i].x();
+        if ( h[i] <= 0 )
+            return false;
+    }
+
+    QVector<double> d( size - 1 );
+    double dy1 = ( p[1].y() - p[0].y() ) / h[0];
+    for ( i = 1; i < size - 1; i++ )
+    {
+        b[i] = c[i] = h[i];
+        a[i] = 2.0 * ( h[i-1] + h[i] );
+
+        const double dy2 = ( p[i+1].y() - p[i].y() ) / h[i];
+        d[i] = 6.0 * ( dy1 - dy2 );
+        dy1 = dy2;
+    }
+
+    //
+    // solve it
+    //
+
+    // L-U Factorization
+    for ( i = 1; i < size - 2; i++ )
+    {
+        c[i] /= a[i];
+        a[i+1] -= b[i] * c[i];
+    }
+
+    // forward elimination
+    QVector<double> s( size );
+    s[1] = d[1];
+    for ( i = 2; i < size - 1; i++ )
+        s[i] = d[i] - c[i-1] * s[i-1];
+
+    // backward elimination
+    s[size - 2] = - s[size - 2] / a[size - 2];
+    for ( i = size - 3; i > 0; i-- )
+        s[i] = - ( s[i] + b[i] * s[i+1] ) / a[i];
+    s[size - 1] = s[0] = 0.0;
+
+    //
+    // Finally, determine the spline coefficients
+    //
+    for ( i = 0; i < size - 1; i++ )
+    {
+        a[i] = ( s[i+1] - s[i] ) / ( 6.0 * h[i] );
+        b[i] = 0.5 * s[i];
+        c[i] = ( p[i+1].y() - p[i].y() ) / h[i]
+            - ( s[i+1] + 2.0 * s[i] ) * h[i] / 6.0;
+    }
+
+    return true;
+}
+
+/*!
+  \brief Determines the coefficients for a periodic spline
+  \return true if successful
+*/
+bool QwtSpline::buildPeriodicSpline( const QPolygonF &points )
+{
+    int i;
+
+    const QPointF *p = points.data();
+    const int size = points.size();
+
+    double *a = d_data->a.data();
+    double *b = d_data->b.data();
+    double *c = d_data->c.data();
+
+    QVector<double> d( size - 1 );
+    QVector<double> h( size - 1 );
+    QVector<double> s( size );
+
+    //
+    //  setup equation system; use coefficient
+    //  vectors as temporary buffers
+    //
+    for ( i = 0; i < size - 1; i++ )
+    {
+        h[i] = p[i+1].x() - p[i].x();
+        if ( h[i] <= 0.0 )
+            return false;
+    }
+
+    const int imax = size - 2;
+    double htmp = h[imax];
+    double dy1 = ( p[0].y() - p[imax].y() ) / htmp;
+    for ( i = 0; i <= imax; i++ )
+    {
+        b[i] = c[i] = h[i];
+        a[i] = 2.0 * ( htmp + h[i] );
+        const double dy2 = ( p[i+1].y() - p[i].y() ) / h[i];
+        d[i] = 6.0 * ( dy1 - dy2 );
+        dy1 = dy2;
+        htmp = h[i];
+    }
+
+    //
+    // solve it
+    //
+
+    // L-U Factorization
+    a[0] = qSqrt( a[0] );
+    c[0] = h[imax] / a[0];
+    double sum = 0;
+
+    for ( i = 0; i < imax - 1; i++ )
+    {
+        b[i] /= a[i];
+        if ( i > 0 )
+            c[i] = - c[i-1] * b[i-1] / a[i];
+        a[i+1] = qSqrt( a[i+1] - qwtSqr( b[i] ) );
+        sum += qwtSqr( c[i] );
+    }
+    b[imax-1] = ( b[imax-1] - c[imax-2] * b[imax-2] ) / a[imax-1];
+    a[imax] = qSqrt( a[imax] - qwtSqr( b[imax-1] ) - sum );
+
+
+    // forward elimination
+    s[0] = d[0] / a[0];
+    sum = 0;
+    for ( i = 1; i < imax; i++ )
+    {
+        s[i] = ( d[i] - b[i-1] * s[i-1] ) / a[i];
+        sum += c[i-1] * s[i-1];
+    }
+    s[imax] = ( d[imax] - b[imax-1] * s[imax-1] - sum ) / a[imax];
+
+
+    // backward elimination
+    s[imax] = - s[imax] / a[imax];
+    s[imax-1] = -( s[imax-1] + b[imax-1] * s[imax] ) / a[imax-1];
+    for ( i = imax - 2; i >= 0; i-- )
+        s[i] = - ( s[i] + b[i] * s[i+1] + c[i] * s[imax] ) / a[i];
+
+    //
+    // Finally, determine the spline coefficients
+    //
+    s[size-1] = s[0];
+    for ( i = 0; i < size - 1; i++ )
+    {
+        a[i] = ( s[i+1] - s[i] ) / ( 6.0 * h[i] );
+        b[i] = 0.5 * s[i];
+        c[i] = ( p[i+1].y() - p[i].y() )
+            / h[i] - ( s[i+1] + 2.0 * s[i] ) * h[i] / 6.0;
+    }
+
+    return true;
+}
Index: trunk/BNC/qwt/qwt_spline.h
===================================================================
--- trunk/BNC/qwt/qwt_spline.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_spline.h	(revision 4271)
@@ -0,0 +1,101 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_SPLINE_H
+#define QWT_SPLINE_H
+
+#include "qwt_global.h"
+#include <qpolygon.h>
+#include <qvector.h>
+
+/*!
+  \brief A class for spline interpolation
+
+  The QwtSpline class is used for cubical spline interpolation.
+  Two types of splines, natural and periodic, are supported.
+
+  \par Usage:
+  <ol>
+  <li>First call setPoints() to determine the spline coefficients
+      for a tabulated function y(x).
+  <li>After the coefficients have been set up, the interpolated
+      function value for an argument x can be determined by calling
+      QwtSpline::value().
+  </ol>
+
+  \par Example:
+  \code
+#include <qwt_spline.h>
+
+QPolygonF interpolate(const QPolygonF& points, int numValues)
+{
+    QwtSpline spline;
+    if ( !spline.setPoints(points) )
+        return points;
+
+    QPolygonF interpolatedPoints(numValues);
+
+    const double delta =
+        (points[numPoints - 1].x() - points[0].x()) / (points.size() - 1);
+    for(i = 0; i < points.size(); i++)  / interpolate
+    {
+        const double x = points[0].x() + i * delta;
+        interpolatedPoints[i].setX(x);
+        interpolatedPoints[i].setY(spline.value(x));
+    }
+    return interpolatedPoints;
+}
+  \endcode
+*/
+
+class QWT_EXPORT QwtSpline
+{
+public:
+    //! Spline type
+    enum SplineType
+    {
+        //! A natural spline
+        Natural,
+
+        //! A periodic spline
+        Periodic
+    };
+
+    QwtSpline();
+    QwtSpline( const QwtSpline & );
+
+    ~QwtSpline();
+
+    QwtSpline &operator=( const QwtSpline & );
+
+    void setSplineType( SplineType );
+    SplineType splineType() const;
+
+    bool setPoints( const QPolygonF& points );
+    QPolygonF points() const;
+
+    void reset();
+
+    bool isValid() const;
+    double value( double x ) const;
+
+    const QVector<double> &coefficientsA() const;
+    const QVector<double> &coefficientsB() const;
+    const QVector<double> &coefficientsC() const;
+
+protected:
+    bool buildNaturalSpline( const QPolygonF & );
+    bool buildPeriodicSpline( const QPolygonF & );
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_symbol.cpp
===================================================================
--- trunk/BNC/qwt/qwt_symbol.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_symbol.cpp	(revision 4271)
@@ -0,0 +1,1004 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_symbol.h"
+#include "qwt_painter.h"
+#include <qapplication.h>
+#include <qpainter.h>
+#include <qmath.h>
+
+namespace QwtTriangle
+{
+    enum Type
+    {
+        Left,
+        Right,
+        Up,
+        Down
+    };
+}
+
+static inline void qwtDrawEllipseSymbols( QPainter *painter,
+    const QPointF *points, int numPoints, const QwtSymbol &symbol )
+{
+    painter->setBrush( symbol.brush() );
+    painter->setPen( symbol.pen() );
+
+    const QSize size = symbol.size();
+
+    if ( QwtPainter::roundingAlignment( painter ) )
+    {
+        const int sw = size.width();
+        const int sh = size.height();
+        const int sw2 = size.width() / 2;
+        const int sh2 = size.height() / 2;
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            const int x = qRound( points[i].x() );
+            const int y = qRound( points[i].y() );
+
+            const QRectF r( x - sw2, y - sh2, sw, sh );
+            QwtPainter::drawEllipse( painter, r );
+        }
+    }
+    else
+    {
+        const double sw = size.width();
+        const double sh = size.height();
+        const double sw2 = 0.5 * size.width();
+        const double sh2 = 0.5 * size.height();
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            const double x = points[i].x();
+            const double y = points[i].y();
+
+            const QRectF r( x - sw2, y - sh2, sw, sh );
+            QwtPainter::drawEllipse( painter, r );
+        }
+    }
+}
+
+static inline void qwtDrawRectSymbols( QPainter *painter,
+    const QPointF *points, int numPoints, const QwtSymbol &symbol )
+{
+    const QSize size = symbol.size();
+
+    QPen pen = symbol.pen();
+    pen.setJoinStyle( Qt::MiterJoin );
+    painter->setPen( pen );
+    painter->setBrush( symbol.brush() );
+    painter->setRenderHint( QPainter::Antialiasing, false );
+
+    if ( QwtPainter::roundingAlignment( painter ) )
+    {
+        const int sw = size.width();
+        const int sh = size.height();
+        const int sw2 = size.width() / 2;
+        const int sh2 = size.height() / 2;
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            const int x = qRound( points[i].x() );
+            const int y = qRound( points[i].y() );
+
+            const QRect r( x - sw2, y - sh2, sw, sh );
+            QwtPainter::drawRect( painter, r );
+        }
+    }
+    else
+    {
+        const double sw = size.width();
+        const double sh = size.height();
+        const double sw2 = 0.5 * size.width();
+        const double sh2 = 0.5 * size.height();
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            const double x = points[i].x();
+            const double y = points[i].y();
+
+            const QRectF r( x - sw2, y - sh2, sw, sh );
+            QwtPainter::drawRect( painter, r );
+        }
+    }
+}
+
+static inline void qwtDrawDiamondSymbols( QPainter *painter,
+    const QPointF *points, int numPoints, const QwtSymbol &symbol )
+{
+    const QSize size = symbol.size();
+
+    QPen pen = symbol.pen();
+    pen.setJoinStyle( Qt::MiterJoin );
+    painter->setPen( pen );
+    painter->setBrush( symbol.brush() );
+
+    if ( QwtPainter::roundingAlignment( painter ) )
+    {
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            const int x = qRound( points[i].x() );
+            const int y = qRound( points[i].y() );
+
+            const int x1 = x - size.width() / 2;
+            const int y1 = y - size.height() / 2;
+            const int x2 = x1 + size.width();
+            const int y2 = y1 + size.height();
+
+            QPolygonF polygon;
+            polygon += QPointF( x, y1 );
+            polygon += QPointF( x1, y );
+            polygon += QPointF( x, y2 );
+            polygon += QPointF( x2, y );
+
+            QwtPainter::drawPolygon( painter, polygon );
+        }
+    }
+    else
+    {
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            const QPointF &pos = points[i];
+
+            const double x1 = pos.x() - 0.5 * size.width();
+            const double y1 = pos.y() - 0.5 * size.height();
+            const double x2 = x1 + size.width();
+            const double y2 = y1 + size.height();
+
+            QPolygonF polygon;
+            polygon += QPointF( pos.x(), y1 );
+            polygon += QPointF( x2, pos.y() );
+            polygon += QPointF( pos.x(), y2 );
+            polygon += QPointF( x1, pos.y() );
+
+            QwtPainter::drawPolygon( painter, polygon );
+        }
+    }
+}
+
+static inline void qwtDrawTriangleSymbols(
+    QPainter *painter, QwtTriangle::Type type,
+    const QPointF *points, int numPoints,
+    const QwtSymbol &symbol )
+{
+    const QSize size = symbol.size();
+
+    QPen pen = symbol.pen();
+    pen.setJoinStyle( Qt::MiterJoin );
+    painter->setPen( pen );
+
+    painter->setBrush( symbol.brush() );
+
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    double sw2 = 0.5 * size.width();
+    double sh2 = 0.5 * size.height();
+
+    if ( doAlign )
+    {
+        sw2 = qFloor( sw2 );
+        sh2 = qFloor( sh2 );
+    }
+
+    QPolygonF triangle( 3 );
+    QPointF *trianglePoints = triangle.data();
+
+    for ( int i = 0; i < numPoints; i++ )
+    {
+        const QPointF &pos = points[i];
+
+        double x = pos.x();
+        double y = pos.y();
+
+        if ( doAlign )
+        {
+            x = qRound( x );
+            y = qRound( y );
+        }
+
+        const double x1 = x - sw2;
+        const double x2 = x1 + size.width();
+        const double y1 = y - sh2;
+        const double y2 = y1 + size.height();
+
+        switch ( type )
+        {
+            case QwtTriangle::Left:
+            {
+                trianglePoints[0].rx() = x2;
+                trianglePoints[0].ry() = y1;
+
+                trianglePoints[1].rx() = x1;
+                trianglePoints[1].ry() = y;
+
+                trianglePoints[2].rx() = x2;
+                trianglePoints[2].ry() = y2;
+
+                break;
+            }
+            case QwtTriangle::Right:
+            {
+                trianglePoints[0].rx() = x1;
+                trianglePoints[0].ry() = y1;
+
+                trianglePoints[1].rx() = x2;
+                trianglePoints[1].ry() = y;
+
+                trianglePoints[2].rx() = x1;
+                trianglePoints[2].ry() = y2;
+
+                break;
+            }
+            case QwtTriangle::Up:
+            {
+                trianglePoints[0].rx() = x1;
+                trianglePoints[0].ry() = y2;
+
+                trianglePoints[1].rx() = x;
+                trianglePoints[1].ry() = y1;
+
+                trianglePoints[2].rx() = x2;
+                trianglePoints[2].ry() = y2;
+
+                break;
+            }
+            case QwtTriangle::Down:
+            {
+                trianglePoints[0].rx() = x1;
+                trianglePoints[0].ry() = y1;
+
+                trianglePoints[1].rx() = x;
+                trianglePoints[1].ry() = y2;
+
+                trianglePoints[2].rx() = x2;
+                trianglePoints[2].ry() = y1;
+
+                break;
+            }
+        }
+        QwtPainter::drawPolygon( painter, triangle );
+    }
+}
+
+static inline void qwtDrawLineSymbols(
+    QPainter *painter, int orientations,
+    const QPointF *points, int numPoints, const QwtSymbol &symbol )
+{
+    const QSize size = symbol.size();
+
+    int off = 0;
+
+    QPen pen = symbol.pen();
+    if ( pen.width() > 1 )
+    {
+        pen.setCapStyle( Qt::FlatCap );
+        off = 1;
+    }
+
+    painter->setPen( pen );
+    painter->setRenderHint( QPainter::Antialiasing, false );
+
+    if ( QwtPainter::roundingAlignment( painter ) )
+    {
+        const int sw = qFloor( size.width() );
+        const int sh = qFloor( size.height() );
+        const int sw2 = size.width() / 2;
+        const int sh2 = size.height() / 2;
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            if ( orientations & Qt::Horizontal )
+            {
+                const int x = qRound( points[i].x() ) - sw2;
+                const int y = qRound( points[i].y() );
+
+                QwtPainter::drawLine( painter, x, y, x + sw + off, y );
+            }
+            if ( orientations & Qt::Vertical )
+            {
+                const int x = qRound( points[i].x() );
+                const int y = qRound( points[i].y() ) - sh2;
+
+                QwtPainter::drawLine( painter, x, y, x, y + sh + off );
+            }
+        }
+    }
+    else
+    {
+        const double sw = size.width();
+        const double sh = size.height();
+        const double sw2 = 0.5 * size.width();
+        const double sh2 = 0.5 * size.height();
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            if ( orientations & Qt::Horizontal )
+            {
+                const double x = points[i].x() - sw2;
+                const double y = points[i].y();
+
+                QwtPainter::drawLine( painter, x, y, x + sw, y );
+            }
+            if ( orientations & Qt::Vertical )
+            {
+                const double y = points[i].y() - sh2;
+                const double x = points[i].x();
+
+                QwtPainter::drawLine( painter, x, y, x, y + sh );
+            }
+        }
+    }
+}
+
+static inline void qwtDrawXCrossSymbols( QPainter *painter,
+    const QPointF *points, int numPoints, const QwtSymbol &symbol )
+{
+    const QSize size = symbol.size();
+    int off = 0;
+
+    QPen pen = symbol.pen();
+    if ( pen.width() > 1 )
+    {
+        pen.setCapStyle( Qt::FlatCap );
+        off = 1;
+    }
+    painter->setPen( pen );
+
+
+    if ( QwtPainter::roundingAlignment( painter ) )
+    {
+        const int sw = size.width();
+        const int sh = size.height();
+        const int sw2 = size.width() / 2;
+        const int sh2 = size.height() / 2;
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            const QPointF &pos = points[i];
+
+            const int x = qRound( pos.x() );
+            const int y = qRound( pos.y() );
+
+            const int x1 = x - sw2;
+            const int x2 = x1 + sw + off;
+            const int y1 = y - sh2;
+            const int y2 = y1 + sh + off;
+
+            QwtPainter::drawLine( painter, x1, y1, x2, y2 );
+            QwtPainter::drawLine( painter, x2, y1, x1, y2 );
+        }
+    }
+    else
+    {
+        const double sw = size.width();
+        const double sh = size.height();
+        const double sw2 = 0.5 * size.width();
+        const double sh2 = 0.5 * size.height();
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            const QPointF &pos = points[i];
+
+            const double x1 = pos.x() - sw2;
+            const double x2 = x1 + sw;
+            const double y1 = pos.y() - sh2;
+            const double y2 = y1 + sh;
+
+            QwtPainter::drawLine( painter, x1, y1, x2, y2 );
+            QwtPainter::drawLine( painter, x1, y2, x2, y1 );
+        }
+    }
+}
+
+static inline void qwtDrawStar1Symbols( QPainter *painter,
+    const QPointF *points, int numPoints, const QwtSymbol &symbol )
+{
+    const QSize size = symbol.size();
+    painter->setPen( symbol.pen() );
+
+    if ( QwtPainter::roundingAlignment( painter ) )
+    {
+        QRect r( 0, 0, size.width(), size.height() );
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            r.moveCenter( points[i].toPoint() );
+
+            const double sqrt1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
+
+            const double d1 = r.width() / 2.0 * ( 1.0 - sqrt1_2 );
+
+            QwtPainter::drawLine( painter,
+                qRound( r.left() + d1 ), qRound( r.top() + d1 ),
+                qRound( r.right() - d1 ), qRound( r.bottom() - d1 ) );
+            QwtPainter::drawLine( painter,
+                qRound( r.left() + d1 ), qRound( r.bottom() - d1 ),
+                qRound( r .right() - d1), qRound( r.top() + d1 ) );
+
+            const QPoint c = r.center();
+
+            QwtPainter::drawLine( painter,
+                c.x(), r.top(), c.x(), r.bottom() );
+            QwtPainter::drawLine( painter,
+                r.left(), c.y(), r.right(), c.y() );
+        }
+    }
+    else
+    {
+        QRectF r( 0, 0, size.width(), size.height() );
+
+        for ( int i = 0; i < numPoints; i++ )
+        {
+            r.moveCenter( points[i] );
+
+            const double sqrt1_2 = 0.70710678118654752440; /* 1/sqrt(2) */
+
+            const QPointF c = r.center();
+            const double d1  = r.width() / 2.0 * ( 1.0 - sqrt1_2 );
+
+            QwtPainter::drawLine( painter,
+                r.left() + d1, r.top() + d1,
+                r.right() - d1, r.bottom() - d1 );
+            QwtPainter::drawLine( painter,
+                r.left() + d1, r.bottom() - d1,
+                r.right() - d1, r.top() + d1 );
+            QwtPainter::drawLine( painter,
+                c.x(), r.top(),
+                c.x(), r.bottom() );
+            QwtPainter::drawLine( painter,
+                r.left(), c.y(),
+                r.right(), c.y() );
+        }
+    }
+}
+
+static inline void qwtDrawStar2Symbols( QPainter *painter,
+    const QPointF *points, int numPoints, const QwtSymbol &symbol )
+{
+    QPen pen = symbol.pen();
+    if ( pen.width() > 1 )
+        pen.setCapStyle( Qt::FlatCap );
+    pen.setJoinStyle( Qt::MiterJoin );
+    painter->setPen( pen );
+
+    painter->setBrush( symbol.brush() );
+
+    const double cos30 = 0.866025; // cos(30°)
+
+    const double dy = 0.25 * symbol.size().height();
+    const double dx = 0.5 * symbol.size().width() * cos30 / 3.0;
+
+    QPolygonF star( 12 );
+    QPointF *starPoints = star.data();
+
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    for ( int i = 0; i < numPoints; i++ )
+    {
+        double x = points[i].x();
+        double y = points[i].y();
+        if ( doAlign )
+        {
+            x = qRound( x );
+            y = qRound( y );
+        }
+
+        double x1 = x - 3 * dx;
+        double y1 = y - 2 * dy;
+        if ( doAlign )
+        {
+            x1 = qRound( x - 3 * dx );
+            y1 = qRound( y - 2 * dy );
+        }
+
+        const double x2 = x1 + 1 * dx;
+        const double x3 = x1 + 2 * dx;
+        const double x4 = x1 + 3 * dx;
+        const double x5 = x1 + 4 * dx;
+        const double x6 = x1 + 5 * dx;
+        const double x7 = x1 + 6 * dx;
+
+        const double y2 = y1 + 1 * dy;
+        const double y3 = y1 + 2 * dy;
+        const double y4 = y1 + 3 * dy;
+        const double y5 = y1 + 4 * dy;
+
+        starPoints[0].rx() = x4;
+        starPoints[0].ry() = y1;
+
+        starPoints[1].rx() = x5;
+        starPoints[1].ry() = y2;
+
+        starPoints[2].rx() = x7;
+        starPoints[2].ry() = y2;
+
+        starPoints[3].rx() = x6;
+        starPoints[3].ry() = y3;
+
+        starPoints[4].rx() = x7;
+        starPoints[4].ry() = y4;
+
+        starPoints[5].rx() = x5;
+        starPoints[5].ry() = y4;
+
+        starPoints[6].rx() = x4;
+        starPoints[6].ry() = y5;
+
+        starPoints[7].rx() = x3;
+        starPoints[7].ry() = y4;
+
+        starPoints[8].rx() = x1;
+        starPoints[8].ry() = y4;
+
+        starPoints[9].rx() = x2;
+        starPoints[9].ry() = y3;
+
+        starPoints[10].rx() = x1;
+        starPoints[10].ry() = y2;
+
+        starPoints[11].rx() = x3;
+        starPoints[11].ry() = y2;
+
+        QwtPainter::drawPolygon( painter, star );
+    }
+}
+
+static inline void qwtDrawHexagonSymbols( QPainter *painter,
+    const QPointF *points, int numPoints, const QwtSymbol &symbol )
+{
+    painter->setBrush( symbol.brush() );
+    painter->setPen( symbol.pen() );
+
+    const double cos30 = 0.866025; // cos(30°)
+    const double dx = 0.5 * ( symbol.size().width() - cos30 );
+
+    const double dy = 0.25 * symbol.size().height();
+
+    QPolygonF hexaPolygon( 6 );
+    QPointF *hexaPoints = hexaPolygon.data();
+
+    const bool doAlign = QwtPainter::roundingAlignment( painter );
+
+    for ( int i = 0; i < numPoints; i++ )
+    {
+        double x = points[i].x();
+        double y = points[i].y();
+        if ( doAlign )
+        {
+            x = qRound( x );
+            y = qRound( y );
+        }
+
+        double x1 = x - dx;
+        double y1 = y - 2 * dy;
+        if ( doAlign )
+        {
+            x1 = qCeil( x1 );
+            y1 = qCeil( y1 );
+        }
+
+        const double x2 = x1 + 1 * dx;
+        const double x3 = x1 + 2 * dx;
+
+        const double y2 = y1 + 1 * dy;
+        const double y3 = y1 + 3 * dy;
+        const double y4 = y1 + 4 * dy;
+
+        hexaPoints[0].rx() = x2;
+        hexaPoints[0].ry() = y1;
+
+        hexaPoints[1].rx() = x3;
+        hexaPoints[1].ry() = y2;
+
+        hexaPoints[2].rx() = x3;
+        hexaPoints[2].ry() = y3;
+
+        hexaPoints[3].rx() = x2;
+        hexaPoints[3].ry() = y4;
+
+        hexaPoints[4].rx() = x1;
+        hexaPoints[4].ry() = y3;
+
+        hexaPoints[5].rx() = x1;
+        hexaPoints[5].ry() = y2;
+
+        QwtPainter::drawPolygon( painter, hexaPolygon );
+    }
+}
+
+class QwtSymbol::PrivateData
+{
+public:
+    PrivateData( QwtSymbol::Style st, const QBrush &br,
+            const QPen &pn, const QSize &sz ):
+        style( st ),
+        size( sz ),
+        brush( br ),
+        pen( pn )
+    {
+    }
+
+    bool operator==( const PrivateData &other ) const
+    {
+        return ( style == other.style )
+            && ( size == other.size )
+            && ( brush == other.brush )
+            && ( pen == other.pen );
+    }
+
+
+    Style style;
+    QSize size;
+    QBrush brush;
+    QPen pen;
+};
+
+/*!
+  Default Constructor
+  \param style Symbol Style
+
+  The symbol is constructed with gray interior,
+  black outline with zero width, no size and style 'NoSymbol'.
+*/
+QwtSymbol::QwtSymbol( Style style )
+{
+    d_data = new PrivateData( style, QBrush( Qt::gray ),
+        QPen( Qt::black ), QSize( 0.0, 0.0 ) );
+}
+
+/*!
+  \brief Constructor
+  \param style Symbol Style
+  \param brush brush to fill the interior
+  \param pen outline pen
+  \param size size
+
+  \sa setStyle(), setBrush(), setPen(), setSize()
+*/
+QwtSymbol::QwtSymbol( QwtSymbol::Style style, const QBrush &brush,
+    const QPen &pen, const QSize &size )
+{
+    d_data = new PrivateData( style, brush, pen, size );
+}
+
+/*!
+  \brief Copy constructor
+
+  \param other Symbol
+*/
+QwtSymbol::QwtSymbol( const QwtSymbol &other )
+{
+    d_data = new PrivateData( other.style(), other.brush(),
+        other.pen(), other.size() );
+};
+
+//! Destructor
+QwtSymbol::~QwtSymbol()
+{
+    delete d_data;
+}
+
+//! \brief Assignment operator
+QwtSymbol &QwtSymbol::operator=( const QwtSymbol &other )
+{
+    *d_data = *other.d_data;
+    return *this;
+}
+
+//! \brief Compare two symbols
+bool QwtSymbol::operator==( const QwtSymbol &other ) const
+{
+    return *d_data == *other.d_data;
+}
+
+//! \brief Compare two symbols
+bool QwtSymbol::operator!=( const QwtSymbol &other ) const
+{
+    return !( *d_data == *other.d_data );
+}
+
+/*!
+  \brief Specify the symbol's size
+
+  If the 'h' parameter is left out or less than 0,
+  and the 'w' parameter is greater than or equal to 0,
+  the symbol size will be set to (w,w).
+  \param width Width
+  \param height Height (defaults to -1)
+
+  \sa size()
+*/
+void QwtSymbol::setSize( int width, int height )
+{
+    if ( ( width >= 0 ) && ( height < 0 ) )
+        height = width;
+
+    d_data->size = QSize( width, height );
+}
+
+/*!
+   Set the symbol's size
+   \param size Size
+
+   \sa size()
+*/
+void QwtSymbol::setSize( const QSize &size )
+{
+    if ( size.isValid() )
+        d_data->size = size;
+}
+
+/*!
+   \return Size
+   \sa setSize()
+*/
+const QSize& QwtSymbol::size() const
+{
+    return d_data->size;
+}
+
+/*!
+  \brief Assign a brush
+
+  The brush is used to draw the interior of the symbol.
+  \param brush Brush
+
+  \sa brush()
+*/
+void QwtSymbol::setBrush( const QBrush &brush )
+{
+    d_data->brush = brush;
+}
+
+/*!
+  \return Brush
+  \sa setBrush()
+*/
+const QBrush& QwtSymbol::brush() const
+{
+    return d_data->brush;
+}
+
+/*!
+  Assign a pen
+
+  The pen is used to draw the symbol's outline.
+
+  \param pen Pen
+  \sa pen(), setBrush()
+*/
+void QwtSymbol::setPen( const QPen &pen )
+{
+    d_data->pen = pen;
+}
+
+/*!
+  \return Pen
+  \sa setPen(), brush()
+*/
+const QPen& QwtSymbol::pen() const
+{
+    return d_data->pen;
+}
+
+/*!
+  \brief Set the color of the symbol
+
+  Change the color of the brush for symbol types with a filled area.
+  For all other symbol types the color will be assigned to the pen.
+
+  \param color Color
+
+  \sa setBrush(), setPen(), brush(), pen()
+*/
+void QwtSymbol::setColor( const QColor &color )
+{
+    switch ( d_data->style )
+    {
+        case QwtSymbol::Ellipse:
+        case QwtSymbol::Rect:
+        case QwtSymbol::Diamond:
+        case QwtSymbol::Triangle:
+        case QwtSymbol::UTriangle:
+        case QwtSymbol::DTriangle:
+        case QwtSymbol::RTriangle:
+        case QwtSymbol::LTriangle:
+        case QwtSymbol::Star2:
+        case QwtSymbol::Hexagon:
+        {
+            d_data->brush.setColor( color );
+            break;
+        }
+        case QwtSymbol::Cross:
+        case QwtSymbol::XCross:
+        case QwtSymbol::HLine:
+        case QwtSymbol::VLine:
+        case QwtSymbol::Star1:
+        {
+            d_data->pen.setColor( color );
+            break;
+        }
+        default:
+        {
+            d_data->brush.setColor( color );
+            d_data->pen.setColor( color );
+        }
+    }
+}
+
+/*!
+  Draw an array of symbols
+
+  Painting several symbols is more effective than drawing symbols
+  one by one, as a couple of layout calculations and setting of pen/brush
+  can be done once for the complete array.
+
+  \param painter Painter
+  \param points Array of points
+  \param numPoints Number of points
+*/
+void QwtSymbol::drawSymbols( QPainter *painter,
+    const QPointF *points, int numPoints ) const
+{
+    if ( numPoints <= 0 )
+        return;
+
+    painter->save();
+
+    switch ( d_data->style )
+    {
+        case QwtSymbol::Ellipse:
+        {
+            qwtDrawEllipseSymbols( painter, points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::Rect:
+        {
+            qwtDrawRectSymbols( painter, points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::Diamond:
+        {
+            qwtDrawDiamondSymbols( painter, points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::Cross:
+        {
+            qwtDrawLineSymbols( painter, Qt::Horizontal | Qt::Vertical,
+                points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::XCross:
+        {
+            qwtDrawXCrossSymbols( painter, points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::Triangle:
+        case QwtSymbol::UTriangle:
+        {
+            qwtDrawTriangleSymbols( painter, QwtTriangle::Up,
+                points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::DTriangle:
+        {
+            qwtDrawTriangleSymbols( painter, QwtTriangle::Down,
+                points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::RTriangle:
+        {
+            qwtDrawTriangleSymbols( painter, QwtTriangle::Right,
+                points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::LTriangle:
+        {
+            qwtDrawTriangleSymbols( painter, QwtTriangle::Left,
+                points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::HLine:
+        {
+            qwtDrawLineSymbols( painter, Qt::Horizontal,
+                points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::VLine:
+        {
+            qwtDrawLineSymbols( painter, Qt::Vertical,
+                points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::Star1:
+        {
+            qwtDrawStar1Symbols( painter, points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::Star2:
+        {
+            qwtDrawStar2Symbols( painter, points, numPoints, *this );
+            break;
+        }
+        case QwtSymbol::Hexagon:
+        {
+            qwtDrawHexagonSymbols( painter, points, numPoints, *this );
+            break;
+        }
+        default:;
+    }
+    painter->restore();
+}
+
+//!  \return Size of the bounding rectangle of a symbol
+QSize QwtSymbol::boundingSize() const
+{
+    QSize size;
+
+    switch ( d_data->style )
+    {
+        case QwtSymbol::Ellipse:
+        case QwtSymbol::Rect:
+        case QwtSymbol::Hexagon:
+        {
+            qreal pw = 0.0;
+            if ( d_data->pen.style() != Qt::NoPen )
+                pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) );
+
+            size = d_data->size + QSize( pw, pw );
+
+            break;
+        }
+        case QwtSymbol::XCross:
+        case QwtSymbol::Diamond:
+        case QwtSymbol::Triangle:
+        case QwtSymbol::UTriangle:
+        case QwtSymbol::DTriangle:
+        case QwtSymbol::RTriangle:
+        case QwtSymbol::LTriangle:
+        case QwtSymbol::Star1:
+        case QwtSymbol::Star2:
+        {
+            qreal pw = 0.0;
+            if ( d_data->pen.style() != Qt::NoPen )
+                pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) );
+
+            size = d_data->size + QSize( 2 * pw, 2 * pw );
+            break;
+        }
+        default:
+        {
+            size = d_data->size;
+        }
+    }
+
+    return size + QSize( 1, 1 ); // for antialiasing
+}
+
+/*!
+  Specify the symbol style
+
+  \param style Style
+  \sa style()
+*/
+void QwtSymbol::setStyle( QwtSymbol::Style style )
+{
+    d_data->style = style;
+}
+
+/*!
+  \return Current symbol style
+  \sa setStyle()
+*/
+QwtSymbol::Style QwtSymbol::style() const
+{
+    return d_data->style;
+}
Index: trunk/BNC/qwt/qwt_symbol.h
===================================================================
--- trunk/BNC/qwt/qwt_symbol.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_symbol.h	(revision 4271)
@@ -0,0 +1,154 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_SYMBOL_H
+#define QWT_SYMBOL_H
+
+#include "qwt_global.h"
+#include <QPolygonF>
+
+class QPainter;
+class QRect;
+class QSize;
+class QBrush;
+class QPen;
+class QColor;
+class QPointF;
+
+//! A class for drawing symbols
+class QWT_EXPORT QwtSymbol
+{
+public:
+    /*!
+      Symbol Style
+      \sa setStyle(), style()
+     */
+    enum Style
+    {
+        //! No Style. The symbol cannot be drawn.
+        NoSymbol = -1,
+
+        //! Ellipse or circle
+        Ellipse,
+
+        //! Rectangle
+        Rect,
+
+        //!  Diamond
+        Diamond,
+
+        //! Triangle pointing upwards
+        Triangle,
+
+        //! Triangle pointing downwards
+        DTriangle,
+
+        //! Triangle pointing upwards
+        UTriangle,
+
+        //! Triangle pointing left
+        LTriangle,
+
+        //! Triangle pointing right
+        RTriangle,
+
+        //! Cross (+)
+        Cross,
+
+        //! Diagonal cross (X)
+        XCross,
+
+        //! Horizontal line
+        HLine,
+
+        //! Vertical line
+        VLine,
+
+        //! X combined with +
+        Star1,
+
+        //! Six-pointed star
+        Star2,
+
+        //! Hexagon
+        Hexagon,
+
+        /*!
+         Styles >= QwtSymbol::UserSymbol are reserved for derived
+         classes of QwtSymbol that overload drawSymbols() with
+         additional application specific symbol types.
+         */
+        UserStyle = 1000
+    };
+
+public:
+    QwtSymbol( Style = NoSymbol );
+    QwtSymbol( Style, const QBrush &, const QPen &, const QSize & );
+    QwtSymbol( const QwtSymbol & );
+    virtual ~QwtSymbol();
+
+    QwtSymbol &operator=( const QwtSymbol & );
+    bool operator==( const QwtSymbol & ) const;
+    bool operator!=( const QwtSymbol & ) const;
+
+    void setSize( const QSize & );
+    void setSize( int width, int height = -1 );
+    const QSize& size() const;
+
+    virtual void setColor( const QColor & );
+
+    void setBrush( const QBrush& b );
+    const QBrush& brush() const;
+
+    void setPen( const QPen & );
+    const QPen& pen() const;
+
+    void setStyle( Style );
+    Style style() const;
+
+    void drawSymbol( QPainter *, const QPointF & ) const;
+    void drawSymbols( QPainter *, const QPolygonF & ) const;
+
+    virtual QSize boundingSize() const;
+
+protected:
+    virtual void drawSymbols( QPainter *,
+        const QPointF *, int numPoints ) const;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+/*!
+  \brief Draw the symbol at a specified position
+
+  \param painter Painter
+  \param pos Position of the symbol in screen coordinates
+*/
+inline void QwtSymbol::drawSymbol(
+    QPainter *painter, const QPointF &pos ) const
+{
+    drawSymbols( painter, &pos, 1 );
+}
+
+/*!
+  \brief Draw symbols at the specified points
+
+  \param painter Painter
+  \param points Positions of the symbols in screen coordinates
+*/
+
+inline void QwtSymbol::drawSymbols(
+    QPainter *painter, const QPolygonF &points ) const
+{
+    drawSymbols( painter, points.data(), points.size() );
+}
+
+#endif
Index: trunk/BNC/qwt/qwt_system_clock.cpp
===================================================================
--- trunk/BNC/qwt/qwt_system_clock.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_system_clock.cpp	(revision 4271)
@@ -0,0 +1,364 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_system_clock.h"
+#include <qdatetime.h>
+
+#if !defined(Q_OS_WIN)
+#include <unistd.h>
+#endif
+
+#if defined(Q_OS_MAC)
+#include <stdint.h>
+#include <mach/mach_time.h>
+#define QWT_HIGH_RESOLUTION_CLOCK
+#elif defined(_POSIX_TIMERS)
+#include <time.h>
+#define QWT_HIGH_RESOLUTION_CLOCK
+#elif defined(Q_OS_WIN)
+#define QWT_HIGH_RESOLUTION_CLOCK
+#include <qt_windows.h>
+#endif
+
+#if defined(QWT_HIGH_RESOLUTION_CLOCK)
+
+class QwtHighResolutionClock
+{
+public:
+    QwtHighResolutionClock();
+
+    void start();
+    double restart();
+    double elapsed() const;
+
+    bool isNull() const;
+
+    static double precision();
+
+private:
+
+#if defined(Q_OS_MAC)
+    static double msecsTo( uint64_t, uint64_t );
+
+    uint64_t d_timeStamp;
+#elif defined(_POSIX_TIMERS)
+
+    static double msecsTo( const struct timespec &,
+        const struct timespec & );
+
+    static bool isMonotonic();
+
+    struct timespec d_timeStamp;
+    clockid_t d_clockId;
+
+#elif defined(Q_OS_WIN)
+
+    LARGE_INTEGER d_startTicks;
+    LARGE_INTEGER d_ticksPerSecond;
+#endif
+};
+
+#if defined(Q_OS_MAC)
+QwtHighResolutionClock::QwtHighResolutionClock():
+    d_timeStamp( 0 )
+{
+}
+
+double QwtHighResolutionClock::precision()
+{
+    return 1e-6;
+}
+
+void QwtHighResolutionClock::start()
+{
+    d_timeStamp = mach_absolute_time();
+}
+
+double QwtHighResolutionClock::restart()
+{
+    const uint64_t timeStamp = mach_absolute_time();
+    const double elapsed = msecsTo( d_timeStamp, timeStamp );
+    d_timeStamp = timeStamp;
+
+    return elapsed;
+}
+
+double QwtHighResolutionClock::elapsed() const
+{
+    return msecsTo( d_timeStamp, mach_absolute_time() );
+}
+
+bool QwtHighResolutionClock::isNull() const
+{
+    return d_timeStamp == 0;
+}
+
+double QwtHighResolutionClock::msecsTo(
+    uint64_t from, uint64_t to )
+{
+    const uint64_t difference = to - from;
+
+    static double conversion = 0.0;
+    if ( conversion == 0.0 )
+    {
+        mach_timebase_info_data_t info;
+        kern_return_t err = mach_timebase_info( &info );
+
+        //Convert the timebase into ms
+        if ( err == 0  )
+            conversion = 1e-6 * ( double ) info.numer / ( double ) info.denom;
+    }
+
+    return conversion * ( double ) difference;
+}
+
+#elif defined(_POSIX_TIMERS)
+
+QwtHighResolutionClock::QwtHighResolutionClock()
+{
+    d_clockId = isMonotonic() ? CLOCK_MONOTONIC : CLOCK_REALTIME;
+    d_timeStamp.tv_sec = d_timeStamp.tv_nsec = 0;
+}
+
+double QwtHighResolutionClock::precision()
+{
+    struct timespec resolution;
+
+    int clockId = isMonotonic() ? CLOCK_MONOTONIC : CLOCK_REALTIME;
+    ::clock_getres( clockId, &resolution );
+
+    return resolution.tv_nsec / 1e3;
+}
+
+inline bool QwtHighResolutionClock::isNull() const
+{
+    return d_timeStamp.tv_sec <= 0 && d_timeStamp.tv_nsec <= 0;
+}
+
+inline void QwtHighResolutionClock::start()
+{
+    ::clock_gettime( d_clockId, &d_timeStamp );
+}
+
+double QwtHighResolutionClock::restart()
+{
+    struct timespec timeStamp;
+    ::clock_gettime( d_clockId, &timeStamp );
+
+    const double elapsed = msecsTo( d_timeStamp, timeStamp );
+
+    d_timeStamp = timeStamp;
+    return elapsed;
+}
+
+inline double QwtHighResolutionClock::elapsed() const
+{
+    struct timespec timeStamp;
+    ::clock_gettime( d_clockId, &timeStamp );
+
+    return msecsTo( d_timeStamp, timeStamp );
+}
+
+inline double QwtHighResolutionClock::msecsTo(
+    const struct timespec &t1, const struct timespec &t2 )
+{
+    return ( t2.tv_sec - t1.tv_sec ) * 1e3
+        + ( t2.tv_nsec - t1.tv_nsec ) * 1e-6;
+}
+
+bool QwtHighResolutionClock::isMonotonic()
+{
+    // code copied from qcore_unix.cpp
+
+#if (_POSIX_MONOTONIC_CLOCK-0 > 0)
+    return true;
+#else
+    static int returnValue = 0;
+
+    if ( returnValue == 0 )
+    {
+#if (_POSIX_MONOTONIC_CLOCK-0 < 0) || !defined(_SC_MONOTONIC_CLOCK)
+        returnValue = -1;
+#elif (_POSIX_MONOTONIC_CLOCK == 0)
+        // detect if the system support monotonic timers
+        const long x = sysconf( _SC_MONOTONIC_CLOCK );
+        returnValue = ( x >= 200112L ) ? 1 : -1;
+#endif
+    }
+
+    return returnValue != -1;
+#endif
+}
+
+#elif defined(Q_OS_WIN)
+
+QwtHighResolutionClock::QwtHighResolutionClock()
+{
+    d_startTicks.QuadPart = 0;
+    QueryPerformanceFrequency( &d_ticksPerSecond );
+}
+
+double QwtHighResolutionClock::precision()
+{
+    LARGE_INTEGER ticks;
+    if ( QueryPerformanceFrequency( &ticks ) && ticks.QuadPart > 0 )
+        return 1e3 / ticks.QuadPart;
+
+    return 0.0;
+}
+
+inline bool QwtHighResolutionClock::isNull() const
+{
+    return d_startTicks.QuadPart <= 0;
+}
+
+inline void QwtHighResolutionClock::start()
+{
+    QueryPerformanceCounter( &d_startTicks );
+}
+
+inline double QwtHighResolutionClock::restart()
+{
+    LARGE_INTEGER ticks;
+    QueryPerformanceCounter( &ticks );
+
+    const double dt = ticks.QuadPart - d_startTicks.QuadPart;
+    d_startTicks = ticks;
+
+    return dt / d_ticksPerSecond.QuadPart * 1e3;
+}
+
+inline double QwtHighResolutionClock::elapsed() const
+{
+    LARGE_INTEGER ticks;
+    QueryPerformanceCounter( &ticks );
+
+    const double dt = ticks.QuadPart - d_startTicks.QuadPart;
+    return dt / d_ticksPerSecond.QuadPart * 1e3;
+}
+
+#endif
+
+#endif // QWT_HIGH_RESOLUTION_CLOCK
+
+class QwtSystemClock::PrivateData
+{
+public:
+#if defined(QWT_HIGH_RESOLUTION_CLOCK)
+    QwtHighResolutionClock *clock;
+#endif
+    QTime time;
+};
+
+//!  Constructs a null clock object.
+QwtSystemClock::QwtSystemClock()
+{
+    d_data = new PrivateData;
+
+#if defined(QWT_HIGH_RESOLUTION_CLOCK)
+    d_data->clock = NULL;
+    if ( QwtHighResolutionClock::precision() > 0.0 )
+        d_data->clock = new QwtHighResolutionClock;
+#endif
+}
+
+//! Destructor
+QwtSystemClock::~QwtSystemClock()
+{
+#if defined(QWT_HIGH_RESOLUTION_CLOCK)
+    delete d_data->clock;
+#endif
+    delete d_data;
+}
+
+/*!
+  \return true if the clock has never been started.
+*/
+bool QwtSystemClock::isNull() const
+{
+#if defined(QWT_HIGH_RESOLUTION_CLOCK)
+    if ( d_data->clock )
+        return d_data->clock->isNull();
+#endif
+
+    return d_data->time.isNull();
+}
+
+/*!
+  Sets the start time to the current time.
+*/
+void QwtSystemClock::start()
+{
+#if defined(QWT_HIGH_RESOLUTION_CLOCK)
+    if ( d_data->clock )
+    {
+        d_data->clock->start();
+        return;
+    }
+#endif
+
+    d_data->time.start();
+}
+
+/*!
+  The start time to the current time and
+  return the time, that is elapsed since the
+  previous start time.
+*/
+double QwtSystemClock::restart()
+{
+#if defined(QWT_HIGH_RESOLUTION_CLOCK)
+    if ( d_data->clock )
+        return d_data->clock->restart();
+#endif
+
+    return d_data->time.restart();
+}
+
+/*!
+  \return Number of milliseconds that have elapsed since the last time
+          start() or restart() was called or 0.0 for null clocks.
+*/
+double QwtSystemClock::elapsed() const
+{
+    double elapsed = 0.0;
+
+#if defined(QWT_HIGH_RESOLUTION_CLOCK)
+    if ( d_data->clock )
+    {
+        if ( !d_data->clock->isNull() )
+            elapsed = d_data->clock->elapsed();
+
+        return elapsed;
+    }
+#endif
+
+    if ( !d_data->time.isNull() )
+        elapsed = d_data->time.elapsed();
+
+    return elapsed;
+}
+
+/*!
+  \return Accuracy of the system clock in milliseconds.
+*/
+double QwtSystemClock::precision()
+{
+    static double prec = 0.0;
+    if ( prec <= 0.0 )
+    {
+#if defined(QWT_HIGH_RESOLUTION_CLOCK)
+        prec = QwtHighResolutionClock::precision();
+#endif
+        if ( prec <= 0.0 )
+            prec = 1.0; // QTime offers 1 ms
+    }
+
+    return prec;
+}
Index: trunk/BNC/qwt/qwt_system_clock.h
===================================================================
--- trunk/BNC/qwt/qwt_system_clock.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_system_clock.h	(revision 4271)
@@ -0,0 +1,49 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_SYSTEM_CLOCK_H
+#define QWT_SYSTEM_CLOCK_H
+
+#include "qwt_global.h"
+
+/*!
+  \brief QwtSystemClock provides high resolution clock time functions.
+
+  Sometimes the resolution offered by QTime ( millisecond ) is not accurate
+  enough for implementing time measurements ( f.e. sampling ).
+  QwtSystemClock offers a subset of the QTime functionality using higher
+  resolution timers ( if possible ).
+
+  Precision and time intervals are multiples of milliseconds (ms).
+
+  \note The implementation uses high-resolution performance counter on Windows,
+        mach_absolute_time() on the Mac or POSIX timers on other systems. 
+        If none is available it falls back on QTimer.
+*/
+
+class QWT_EXPORT QwtSystemClock
+{
+public:
+    QwtSystemClock();
+    virtual ~QwtSystemClock();
+
+    bool isNull() const;
+
+    void start();
+    double restart();
+    double elapsed() const;
+
+    static double precision();
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
Index: trunk/BNC/qwt/qwt_text.cpp
===================================================================
--- trunk/BNC/qwt/qwt_text.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_text.cpp	(revision 4271)
@@ -0,0 +1,643 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2003   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_text.h"
+#include "qwt_painter.h"
+#include "qwt_text_engine.h"
+#include <qmap.h>
+#include <qfont.h>
+#include <qcolor.h>
+#include <qpen.h>
+#include <qbrush.h>
+#include <qpainter.h>
+#include <qapplication.h>
+#include <qdesktopwidget.h>
+#include <qmath.h>
+
+class QwtTextEngineDict
+{
+public:
+    static QwtTextEngineDict &dict();
+
+    void setTextEngine( QwtText::TextFormat, QwtTextEngine * );
+
+    const QwtTextEngine *textEngine( QwtText::TextFormat ) const;
+    const QwtTextEngine *textEngine( const QString &,
+        QwtText::TextFormat ) const;
+
+private:
+    QwtTextEngineDict();
+    ~QwtTextEngineDict();
+
+    typedef QMap<int, QwtTextEngine *> EngineMap;
+
+    inline const QwtTextEngine *engine( EngineMap::const_iterator &it ) const
+    {
+        return it.value();
+    }
+
+    EngineMap d_map;
+};
+
+QwtTextEngineDict &QwtTextEngineDict::dict()
+{
+    static QwtTextEngineDict engineDict;
+    return engineDict;
+}
+
+QwtTextEngineDict::QwtTextEngineDict()
+{
+    d_map.insert( QwtText::PlainText, new QwtPlainTextEngine() );
+#ifndef QT_NO_RICHTEXT
+    d_map.insert( QwtText::RichText, new QwtRichTextEngine() );
+#endif
+}
+
+QwtTextEngineDict::~QwtTextEngineDict()
+{
+    for ( EngineMap::const_iterator it = d_map.begin();
+        it != d_map.end(); ++it )
+    {
+        const QwtTextEngine *textEngine = engine( it );
+        delete textEngine;
+    }
+}
+
+const QwtTextEngine *QwtTextEngineDict::textEngine( const QString& text,
+    QwtText::TextFormat format ) const
+{
+    if ( format == QwtText::AutoText )
+    {
+        for ( EngineMap::const_iterator it = d_map.begin();
+            it != d_map.end(); ++it )
+        {
+            if ( it.key() != QwtText::PlainText )
+            {
+                const QwtTextEngine *e = engine( it );
+                if ( e && e->mightRender( text ) )
+                    return e;
+            }
+        }
+    }
+
+    EngineMap::const_iterator it = d_map.find( format );
+    if ( it != d_map.end() )
+    {
+        const QwtTextEngine *e = engine( it );
+        if ( e )
+            return e;
+    }
+
+    it = d_map.find( QwtText::PlainText );
+    return engine( it );
+}
+
+void QwtTextEngineDict::setTextEngine( QwtText::TextFormat format,
+    QwtTextEngine *engine )
+{
+    if ( format == QwtText::AutoText )
+        return;
+
+    if ( format == QwtText::PlainText && engine == NULL )
+        return;
+
+    EngineMap::const_iterator it = d_map.find( format );
+    if ( it != d_map.end() )
+    {
+        const QwtTextEngine *e = this->engine( it );
+        if ( e )
+            delete e;
+
+        d_map.remove( format );
+    }
+
+    if ( engine != NULL )
+        d_map.insert( format, engine );
+}
+
+const QwtTextEngine *QwtTextEngineDict::textEngine(
+    QwtText::TextFormat format ) const
+{
+    const QwtTextEngine *e = NULL;
+
+    EngineMap::const_iterator it = d_map.find( format );
+    if ( it != d_map.end() )
+        e = engine( it );
+
+    return e;
+}
+
+class QwtText::PrivateData
+{
+public:
+    PrivateData():
+        renderFlags( Qt::AlignCenter ),
+        backgroundPen( Qt::NoPen ),
+        backgroundBrush( Qt::NoBrush ),
+        paintAttributes( 0 ),
+        layoutAttributes( 0 ),
+        textEngine( NULL )
+    {
+    }
+
+    int renderFlags;
+    QString text;
+    QFont font;
+    QColor color;
+    QPen backgroundPen;
+    QBrush backgroundBrush;
+
+    QwtText::PaintAttributes paintAttributes;
+    QwtText::LayoutAttributes layoutAttributes;
+
+    const QwtTextEngine *textEngine;
+};
+
+class QwtText::LayoutCache
+{
+public:
+    void invalidate()
+    {
+        textSize = QSizeF();
+    }
+
+    QFont font;
+    QSizeF textSize;
+};
+
+/*!
+   Constructor
+
+   \param text Text content
+   \param textFormat Text format
+*/
+QwtText::QwtText( const QString &text, QwtText::TextFormat textFormat )
+{
+    d_data = new PrivateData;
+    d_data->text = text;
+    d_data->textEngine = textEngine( text, textFormat );
+
+    d_layoutCache = new LayoutCache;
+}
+
+//! Copy constructor
+QwtText::QwtText( const QwtText &other )
+{
+    d_data = new PrivateData;
+    *d_data = *other.d_data;
+
+    d_layoutCache = new LayoutCache;
+    *d_layoutCache = *other.d_layoutCache;
+}
+
+//! Destructor
+QwtText::~QwtText()
+{
+    delete d_data;
+    delete d_layoutCache;
+}
+
+//! Assignment operator
+QwtText &QwtText::operator=( const QwtText & other )
+{
+    *d_data = *other.d_data;
+    *d_layoutCache = *other.d_layoutCache;
+    return *this;
+}
+
+//! Relational operator
+bool QwtText::operator==( const QwtText &other ) const
+{
+    return d_data->renderFlags == other.d_data->renderFlags &&
+        d_data->text == other.d_data->text &&
+        d_data->font == other.d_data->font &&
+        d_data->color == other.d_data->color &&
+        d_data->backgroundPen == other.d_data->backgroundPen &&
+        d_data->backgroundBrush == other.d_data->backgroundBrush &&
+        d_data->paintAttributes == other.d_data->paintAttributes &&
+        d_data->textEngine == other.d_data->textEngine;
+}
+
+//! Relational operator
+bool QwtText::operator!=( const QwtText &other ) const // invalidate
+{
+    return !( other == *this );
+}
+
+/*!
+   Assign a new text content
+
+   \param text Text content
+   \param textFormat Text format
+
+   \sa text()
+*/
+void QwtText::setText( const QString &text,
+    QwtText::TextFormat textFormat )
+{
+    d_data->text = text;
+    d_data->textEngine = textEngine( text, textFormat );
+    d_layoutCache->invalidate();
+}
+
+/*!
+   Return the text.
+   \sa setText()
+*/
+QString QwtText::text() const
+{
+    return d_data->text;
+}
+
+/*!
+   \brief Change the render flags
+
+   The default setting is Qt::AlignCenter
+
+   \param renderFlags Bitwise OR of the flags used like in QPainter::drawText
+
+   \sa renderFlags(), QwtTextEngine::draw()
+   \note Some renderFlags might have no effect, depending on the text format.
+*/
+void QwtText::setRenderFlags( int renderFlags )
+{
+    if ( renderFlags != d_data->renderFlags )
+    {
+        d_data->renderFlags = renderFlags;
+        d_layoutCache->invalidate();
+    }
+}
+
+/*!
+   \return Render flags
+   \sa setRenderFlags()
+*/
+int QwtText::renderFlags() const
+{
+    return d_data->renderFlags;
+}
+
+/*!
+   Set the font.
+
+   \param font Font
+   \note Setting the font might have no effect, when
+         the text contains control sequences for setting fonts.
+*/
+void QwtText::setFont( const QFont &font )
+{
+    d_data->font = font;
+    setPaintAttribute( PaintUsingTextFont );
+}
+
+//! Return the font.
+QFont QwtText::font() const
+{
+    return d_data->font;
+}
+
+/*!
+  Return the font of the text, if it has one.
+  Otherwise return defaultFont.
+
+  \param defaultFont Default font
+  \sa setFont(), font(), PaintAttributes
+*/
+QFont QwtText::usedFont( const QFont &defaultFont ) const
+{
+    if ( d_data->paintAttributes & PaintUsingTextFont )
+        return d_data->font;
+
+    return defaultFont;
+}
+
+/*!
+   Set the pen color used for painting the text.
+
+   \param color Color
+   \note Setting the color might have no effect, when
+         the text contains control sequences for setting colors.
+*/
+void QwtText::setColor( const QColor &color )
+{
+    d_data->color = color;
+    setPaintAttribute( PaintUsingTextColor );
+}
+
+//! Return the pen color, used for painting the text
+QColor QwtText::color() const
+{
+    return d_data->color;
+}
+
+/*!
+  Return the color of the text, if it has one.
+  Otherwise return defaultColor.
+
+  \param defaultColor Default color
+  \sa setColor(), color(), PaintAttributes
+*/
+QColor QwtText::usedColor( const QColor &defaultColor ) const
+{
+    if ( d_data->paintAttributes & PaintUsingTextColor )
+        return d_data->color;
+
+    return defaultColor;
+}
+
+/*!
+   Set the background pen
+
+   \param pen Background pen
+   \sa backgroundPen(), setBackgroundBrush()
+*/
+void QwtText::setBackgroundPen( const QPen &pen )
+{
+    d_data->backgroundPen = pen;
+    setPaintAttribute( PaintBackground );
+}
+
+/*!
+   \return Background pen
+   \sa setBackgroundPen(), backgroundBrush()
+*/
+QPen QwtText::backgroundPen() const
+{
+    return d_data->backgroundPen;
+}
+
+/*!
+   Set the background brush
+
+   \param brush Background brush
+   \sa backgroundBrush(), setBackgroundPen()
+*/
+void QwtText::setBackgroundBrush( const QBrush &brush )
+{
+    d_data->backgroundBrush = brush;
+    setPaintAttribute( PaintBackground );
+}
+
+/*!
+   \return Background brush
+   \sa setBackgroundBrush(), backgroundPen()
+*/
+QBrush QwtText::backgroundBrush() const
+{
+    return d_data->backgroundBrush;
+}
+
+/*!
+   Change a paint attribute
+
+   \param attribute Paint attribute
+   \param on On/Off
+
+   \note Used by setFont(), setColor(),
+         setBackgroundPen() and setBackgroundBrush()
+   \sa testPaintAttribute()
+*/
+void QwtText::setPaintAttribute( PaintAttribute attribute, bool on )
+{
+    if ( on )
+        d_data->paintAttributes |= attribute;
+    else
+        d_data->paintAttributes &= ~attribute;
+}
+
+/*!
+   Test a paint attribute
+
+   \param attribute Paint attribute
+   \return true, if attribute is enabled
+
+   \sa setPaintAttribute()
+*/
+bool QwtText::testPaintAttribute( PaintAttribute attribute ) const
+{
+    return d_data->paintAttributes & attribute;
+}
+
+/*!
+   Change a layout attribute
+
+   \param attribute Layout attribute
+   \param on On/Off
+   \sa testLayoutAttribute()
+*/
+void QwtText::setLayoutAttribute( LayoutAttribute attribute, bool on )
+{
+    if ( on )
+        d_data->layoutAttributes |= attribute;
+    else
+        d_data->layoutAttributes &= ~attribute;
+}
+
+/*!
+   Test a layout attribute
+
+   \param attribute Layout attribute
+   \return true, if attribute is enabled
+
+   \sa setLayoutAttribute()
+*/
+bool QwtText::testLayoutAttribute( LayoutAttribute attribute ) const
+{
+    return d_data->layoutAttributes | attribute;
+}
+
+/*!
+   Find the height for a given width
+
+   \param defaultFont Font, used for the calculation if the text has no font
+   \param width Width
+
+   \return Calculated height
+*/
+double QwtText::heightForWidth( double width, const QFont &defaultFont ) const
+{
+    // We want to calculate in screen metrics. So
+    // we need a font that uses screen metrics
+
+    const QFont font( usedFont( defaultFont ), QApplication::desktop() );
+
+    double h = 0;
+
+    if ( d_data->layoutAttributes & MinimumLayout )
+    {
+        double left, right, top, bottom;
+        d_data->textEngine->textMargins( font, d_data->text,
+            left, right, top, bottom );
+
+        h = d_data->textEngine->heightForWidth(
+            font, d_data->renderFlags, d_data->text,
+            width + left + right );
+
+        h -= top + bottom;
+    }
+    else
+    {
+        h = d_data->textEngine->heightForWidth(
+            font, d_data->renderFlags, d_data->text, width );
+    }
+
+    return h;
+}
+
+/*!
+   Find the height for a given width
+
+   \param defaultFont Font, used for the calculation if the text has no font
+
+   \return Calculated height
+*/
+
+/*!
+   Returns the size, that is needed to render text
+
+   \param defaultFont Font of the text
+   \return Caluclated size
+*/
+QSizeF QwtText::textSize( const QFont &defaultFont ) const
+{
+    // We want to calculate in screen metrics. So
+    // we need a font that uses screen metrics
+
+    const QFont font( usedFont( defaultFont ), QApplication::desktop() );
+
+    if ( !d_layoutCache->textSize.isValid()
+        || d_layoutCache->font != font )
+    {
+        d_layoutCache->textSize = d_data->textEngine->textSize(
+            font, d_data->renderFlags, d_data->text );
+        d_layoutCache->font = font;
+    }
+
+    QSizeF sz = d_layoutCache->textSize;
+
+    if ( d_data->layoutAttributes & MinimumLayout )
+    {
+        double left, right, top, bottom;
+        d_data->textEngine->textMargins( font, d_data->text,
+            left, right, top, bottom );
+        sz -= QSizeF( left + right, top + bottom );
+    }
+
+    return sz;
+}
+
+/*!
+   Draw a text into a rectangle
+
+   \param painter Painter
+   \param rect Rectangle
+*/
+void QwtText::draw( QPainter *painter, const QRectF &rect ) const
+{
+    if ( d_data->paintAttributes & PaintBackground )
+    {
+        if ( d_data->backgroundPen != Qt::NoPen ||
+            d_data->backgroundBrush != Qt::NoBrush )
+        {
+            painter->save();
+            painter->setPen( d_data->backgroundPen );
+            painter->setBrush( d_data->backgroundBrush );
+            QwtPainter::drawRect( painter, rect );
+            painter->restore();
+        }
+    }
+
+    painter->save();
+
+    if ( d_data->paintAttributes & PaintUsingTextFont )
+    {
+        painter->setFont( d_data->font );
+    }
+
+    if ( d_data->paintAttributes & PaintUsingTextColor )
+    {
+        if ( d_data->color.isValid() )
+            painter->setPen( d_data->color );
+    }
+
+    QRectF expandedRect = rect;
+    if ( d_data->layoutAttributes & MinimumLayout )
+    {
+        // We want to calculate in screen metrics. So
+        // we need a font that uses screen metrics
+
+        const QFont font( painter->font(), QApplication::desktop() );
+
+        double left, right, top, bottom;
+        d_data->textEngine->textMargins(
+            font, d_data->text, left, right, top, bottom );
+
+        expandedRect.setTop( rect.top() - top );
+        expandedRect.setBottom( rect.bottom() + bottom );
+        expandedRect.setLeft( rect.left() - left );
+        expandedRect.setRight( rect.right() + right );
+    }
+
+    d_data->textEngine->draw( painter, expandedRect,
+        d_data->renderFlags, d_data->text );
+
+    painter->restore();
+}
+
+/*!
+   Find the text engine for a text format
+
+   In case of QwtText::AutoText the first text engine
+   (beside QwtPlainTextEngine) is returned, where QwtTextEngine::mightRender
+   returns true. If there is none QwtPlainTextEngine is returnd.
+
+   If no text engine is registered for the format QwtPlainTextEngine
+   is returnd.
+
+   \param text Text, needed in case of AutoText
+   \param format Text format
+*/
+const QwtTextEngine *QwtText::textEngine( const QString &text,
+    QwtText::TextFormat format )
+{
+    return QwtTextEngineDict::dict().textEngine( text, format );
+}
+
+/*!
+   Assign/Replace a text engine for a text format
+
+   With setTextEngine it is possible to extend Qwt with
+   other types of text formats.
+
+   For QwtText::PlainText it is not allowed to assign a engine == NULL.
+
+   \param format Text format
+   \param engine Text engine
+
+   \sa QwtMathMLTextEngine
+   \warning Using QwtText::AutoText does nothing.
+*/
+void QwtText::setTextEngine( QwtText::TextFormat format,
+    QwtTextEngine *engine )
+{
+    QwtTextEngineDict::dict().setTextEngine( format, engine );
+}
+
+/*!
+   \brief Find the text engine for a text format
+
+   textEngine can be used to find out if a text format is supported.
+
+   \param format Text format
+   \return The text engine, or NULL if no engine is available.
+*/
+const QwtTextEngine *QwtText::textEngine( QwtText::TextFormat format )
+{
+    return  QwtTextEngineDict::dict().textEngine( format );
+}
Index: trunk/BNC/qwt/qwt_text.h
===================================================================
--- trunk/BNC/qwt/qwt_text.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_text.h	(revision 4271)
@@ -0,0 +1,216 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2003   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_TEXT_H
+#define QWT_TEXT_H
+
+#include "qwt_global.h"
+#include <qstring.h>
+#include <qsize.h>
+#include <qfont.h>
+
+class QColor;
+class QPen;
+class QBrush;
+class QRectF;
+class QPainter;
+class QwtTextEngine;
+
+/*!
+  \brief A class representing a text
+
+  A QwtText is a text including a set of attributes how to render it.
+
+  - Format\n
+    A text might include control sequences (f.e tags) describing
+    how to render it. Each format (f.e MathML, TeX, Qt Rich Text)
+    has its own set of control sequences, that can be handles by
+    a QwtTextEngine for this format.
+  - Background\n
+    A text might have a background, defined by a QPen and QBrush
+    to improve its visibility.
+  - Font\n
+    A text might have an individual font.
+  - Color\n
+    A text might have an individual color.
+  - Render Flags\n
+    Flags from Qt::AlignmentFlag and Qt::TextFlag used like in
+    QPainter::drawText.
+
+  \sa QwtTextEngine, QwtTextLabel
+*/
+
+class QWT_EXPORT QwtText
+{
+public:
+
+    /*!
+      \brief Text format
+
+      The text format defines the QwtTextEngine, that is used to render
+      the text.
+
+      \sa QwtTextEngine, setTextEngine()
+    */
+
+    enum TextFormat
+    {
+        /*!
+          The text format is determined using QwtTextEngine::mightRender for
+          all available text engines in increasing order > PlainText.
+          If none of the text engines can render the text is rendered
+          like QwtText::PlainText.
+         */
+        AutoText = 0,
+
+        //! Draw the text as it is, using a QwtPlainTextEngine.
+        PlainText,
+
+        //! Use the Scribe framework (Qt Rich Text) to render the text.
+        RichText,
+
+        /*!
+          Use a MathML (http://en.wikipedia.org/wiki/MathML) render engine
+          to display the text. The Qwt MathML extension offers such an engine
+          based on the MathML renderer of the Qt solutions package. 
+          To enable MathML support the following code needs to be added to the
+          application:
+\verbatim QwtText::setTextEngine(QwtText::MathMLText, new QwtMathMLTextEngine()); \endverbatim
+         */
+        MathMLText,
+
+        /*!
+          Use a TeX (http://en.wikipedia.org/wiki/TeX) render engine
+          to display the text ( not implemented yet ).
+         */
+        TeXText,
+
+        /*!
+          The number of text formats can be extended using setTextEngine.
+          Formats >= QwtText::OtherFormat are not used by Qwt.
+         */
+        OtherFormat = 100
+    };
+
+    /*!
+      \brief Paint Attributes
+
+      Font and color and background are optional attributes of a QwtText.
+      The paint attributes hold the information, if they are set.
+    */
+    enum PaintAttribute
+    {
+        //! The text has an individual font.
+        PaintUsingTextFont = 0x01,
+
+        //! The text has an individual color.
+        PaintUsingTextColor = 0x02,
+
+        //! The text has an individual background.
+        PaintBackground = 0x04
+    };
+
+    //! Paint attributes
+    typedef QFlags<PaintAttribute> PaintAttributes;
+
+    /*!
+      \brief Layout Attributes
+      The layout attributes affects some aspects of the layout of the text.
+    */
+    enum LayoutAttribute
+    {
+        /*!
+          Layout the text without its margins. This mode is useful if a
+          text needs to be aligned accurately, like the tick labels of a scale.
+          If QwtTextEngine::textMargins is not implemented for the format
+          of the text, MinimumLayout has no effect.
+         */
+        MinimumLayout = 0x01
+    };
+
+    //! Layout attributes
+    typedef QFlags<LayoutAttribute> LayoutAttributes;
+
+    QwtText( const QString & = QString::null,
+             TextFormat textFormat = AutoText );
+    QwtText( const QwtText & );
+    ~QwtText();
+
+    QwtText &operator=( const QwtText & );
+
+    bool operator==( const QwtText & ) const;
+    bool operator!=( const QwtText & ) const;
+
+    void setText( const QString &,
+        QwtText::TextFormat textFormat = AutoText );
+    QString text() const;
+
+    bool isNull() const;
+    bool isEmpty() const;
+
+    void setFont( const QFont & );
+    QFont font() const;
+
+    QFont usedFont( const QFont & ) const;
+
+    void setRenderFlags( int flags );
+    int renderFlags() const;
+
+    void setColor( const QColor & );
+    QColor color() const;
+
+    QColor usedColor( const QColor & ) const;
+
+    void setBackgroundPen( const QPen & );
+    QPen backgroundPen() const;
+
+    void setBackgroundBrush( const QBrush & );
+    QBrush backgroundBrush() const;
+
+    void setPaintAttribute( PaintAttribute, bool on = true );
+    bool testPaintAttribute( PaintAttribute ) const;
+
+    void setLayoutAttribute( LayoutAttribute, bool on = true );
+    bool testLayoutAttribute( LayoutAttribute ) const;
+
+    double heightForWidth( double width, const QFont & = QFont() ) const;
+    QSizeF textSize( const QFont & = QFont() ) const;
+
+    void draw( QPainter *painter, const QRectF &rect ) const;
+
+    static const QwtTextEngine *textEngine( 
+        const QString &text, QwtText::TextFormat = AutoText );
+
+    static const QwtTextEngine *textEngine( QwtText::TextFormat );
+    static void setTextEngine( QwtText::TextFormat, QwtTextEngine * );
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+
+    class LayoutCache;
+    LayoutCache *d_layoutCache;
+};
+
+//! \return text().isNull()
+inline bool QwtText::isNull() const
+{
+    return text().isNull();
+}
+
+//! \return text().isEmpty()
+inline bool QwtText::isEmpty() const
+{
+    return text().isEmpty();
+}
+
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtText::PaintAttributes )
+Q_DECLARE_OPERATORS_FOR_FLAGS( QwtText::LayoutAttributes )
+
+#endif
Index: trunk/BNC/qwt/qwt_text_engine.cpp
===================================================================
--- trunk/BNC/qwt/qwt_text_engine.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_text_engine.cpp	(revision 4271)
@@ -0,0 +1,344 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2003   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_text_engine.h"
+#include "qwt_math.h"
+#include "qwt_painter.h"
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qimage.h>
+#include <qmap.h>
+#include <qwidget.h>
+#include <qtextobject.h>
+#include <qtextdocument.h>
+#include <qabstracttextdocumentlayout.h>
+
+static QString taggedRichText( const QString &text, int flags )
+{
+    QString richText = text;
+
+    // By default QSimpleRichText is Qt::AlignLeft
+    if ( flags & Qt::AlignJustify )
+    {
+        richText.prepend( QString::fromLatin1( "<div align=\"justify\">" ) );
+        richText.append( QString::fromLatin1( "</div>" ) );
+    }
+    else if ( flags & Qt::AlignRight )
+    {
+        richText.prepend( QString::fromLatin1( "<div align=\"right\">" ) );
+        richText.append( QString::fromLatin1( "</div>" ) );
+    }
+    else if ( flags & Qt::AlignHCenter )
+    {
+        richText.prepend( QString::fromLatin1( "<div align=\"center\">" ) );
+        richText.append( QString::fromLatin1( "</div>" ) );
+    }
+
+    return richText;
+}
+
+class QwtRichTextDocument: public QTextDocument
+{
+public:
+    QwtRichTextDocument( const QString &text, int flags, const QFont &font )
+    {
+        setUndoRedoEnabled( false );
+        setDefaultFont( font );
+        setHtml( text );
+
+        // make sure we have a document layout
+        ( void )documentLayout();
+
+        QTextOption option = defaultTextOption();
+        if ( flags & Qt::TextWordWrap )
+            option.setWrapMode( QTextOption::WordWrap );
+        else
+            option.setWrapMode( QTextOption::NoWrap );
+
+        option.setAlignment( ( Qt::Alignment ) flags );
+        setDefaultTextOption( option );
+
+        QTextFrame *root = rootFrame();
+        QTextFrameFormat fm = root->frameFormat();
+        fm.setBorder( 0 );
+        fm.setMargin( 0 );
+        fm.setPadding( 0 );
+        fm.setBottomMargin( 0 );
+        fm.setLeftMargin( 0 );
+        root->setFrameFormat( fm );
+
+        adjustSize();
+    }
+};
+
+class QwtPlainTextEngine::PrivateData
+{
+public:
+    int effectiveAscent( const QFont &font ) const
+    {
+        const QString fontKey = font.key();
+
+        QMap<QString, int>::const_iterator it =
+            d_ascentCache.find( fontKey );
+        if ( it == d_ascentCache.end() )
+        {
+            int ascent = findAscent( font );
+            it = d_ascentCache.insert( fontKey, ascent );
+        }
+
+        return ( *it );
+    }
+
+private:
+    int findAscent( const QFont &font ) const
+    {
+        static const QString dummy( "E" );
+        static const QColor white( Qt::white );
+
+        const QFontMetrics fm( font );
+        QPixmap pm( fm.width( dummy ), fm.height() );
+        pm.fill( white );
+
+        QPainter p( &pm );
+        p.setFont( font );
+        p.drawText( 0, 0,  pm.width(), pm.height(), 0, dummy );
+        p.end();
+
+        const QImage img = pm.toImage();
+
+        int row = 0;
+        for ( row = 0; row < img.height(); row++ )
+        {
+            const QRgb *line = ( const QRgb * )img.scanLine( row );
+
+            const int w = pm.width();
+            for ( int col = 0; col < w; col++ )
+            {
+                if ( line[col] != white.rgb() )
+                    return fm.ascent() - row + 1;
+            }
+        }
+
+        return fm.ascent();
+    }
+
+    mutable QMap<QString, int> d_ascentCache;
+};
+
+//! Constructor
+QwtTextEngine::QwtTextEngine()
+{
+}
+
+//! Destructor
+QwtTextEngine::~QwtTextEngine()
+{
+}
+
+//! Constructor
+QwtPlainTextEngine::QwtPlainTextEngine()
+{
+    d_data = new PrivateData;
+}
+
+//! Destructor
+QwtPlainTextEngine::~QwtPlainTextEngine()
+{
+    delete d_data;
+}
+
+/*!
+   Find the height for a given width
+
+   \param font Font of the text
+   \param flags Bitwise OR of the flags used like in QPainter::drawText
+   \param text Text to be rendered
+   \param width Width
+
+   \return Calculated height
+*/
+double QwtPlainTextEngine::heightForWidth( const QFont& font, int flags,
+        const QString& text, double width ) const
+{
+    const QFontMetricsF fm( font );
+    const QRectF rect = fm.boundingRect(
+        QRectF( 0, 0, width, QWIDGETSIZE_MAX ), flags, text );
+
+    return rect.height();
+}
+
+/*!
+  Returns the size, that is needed to render text
+
+  \param font Font of the text
+  \param flags Bitwise OR of the flags used like in QPainter::drawText
+  \param text Text to be rendered
+
+  \return Caluclated size
+*/
+QSizeF QwtPlainTextEngine::textSize( const QFont &font,
+    int flags, const QString& text ) const
+{
+    const QFontMetricsF fm( font );
+    const QRectF rect = fm.boundingRect(
+        QRectF( 0, 0, QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ), flags, text );
+
+    return rect.size();
+}
+
+/*!
+  Return margins around the texts
+
+  \param font Font of the text
+  \param left Return 0
+  \param right Return 0
+  \param top Return value for the top margin
+  \param bottom Return value for the bottom margin
+*/
+void QwtPlainTextEngine::textMargins( const QFont &font, const QString &,
+    double &left, double &right, double &top, double &bottom ) const
+{
+    left = right = top = 0;
+
+    const QFontMetricsF fm( font );
+    top = fm.ascent() - d_data->effectiveAscent( font );
+    bottom = fm.descent();
+}
+
+/*!
+  \brief Draw the text in a clipping rectangle
+
+  A wrapper for QPainter::drawText.
+
+  \param painter Painter
+  \param rect Clipping rectangle
+  \param flags Bitwise OR of the flags used like in QPainter::drawText
+  \param text Text to be rendered
+*/
+void QwtPlainTextEngine::draw( QPainter *painter, const QRectF &rect,
+    int flags, const QString& text ) const
+{
+    QwtPainter::drawText( painter, rect, flags, text );
+}
+
+/*!
+  Test if a string can be rendered by this text engine.
+  \return Always true. All texts can be rendered by QwtPlainTextEngine
+*/
+bool QwtPlainTextEngine::mightRender( const QString & ) const
+{
+    return true;
+}
+
+#ifndef QT_NO_RICHTEXT
+
+//! Constructor
+QwtRichTextEngine::QwtRichTextEngine()
+{
+}
+
+/*!
+   Find the height for a given width
+
+   \param font Font of the text
+   \param flags Bitwise OR of the flags used like in QPainter::drawText
+   \param text Text to be rendered
+   \param width Width
+
+   \return Calculated height
+*/
+double QwtRichTextEngine::heightForWidth( const QFont& font, int flags,
+        const QString& text, double width ) const
+{
+    QwtRichTextDocument doc( text, flags, font );
+
+    doc.setPageSize( QSizeF( width, QWIDGETSIZE_MAX ) );
+    return doc.documentLayout()->documentSize().height();
+}
+
+/*!
+  Returns the size, that is needed to render text
+
+  \param font Font of the text
+  \param flags Bitwise OR of the flags used like in QPainter::drawText
+  \param text Text to be rendered
+
+  \return Caluclated size
+*/
+
+QSizeF QwtRichTextEngine::textSize( const QFont &font,
+    int flags, const QString& text ) const
+{
+    QwtRichTextDocument doc( text, flags, font );
+
+    QTextOption option = doc.defaultTextOption();
+    if ( option.wrapMode() != QTextOption::NoWrap )
+    {
+        option.setWrapMode( QTextOption::NoWrap );
+        doc.setDefaultTextOption( option );
+        doc.adjustSize();
+    }
+
+    return doc.size();
+}
+
+/*!
+  Draw the text in a clipping rectangle
+
+  \param painter Painter
+  \param rect Clipping rectangle
+  \param flags Bitwise OR of the flags like in for QPainter::drawText
+  \param text Text to be rendered
+*/
+void QwtRichTextEngine::draw( QPainter *painter, const QRectF &rect,
+    int flags, const QString& text ) const
+{
+    QwtRichTextDocument doc( text, flags, painter->font() );
+    QwtPainter::drawSimpleRichText( painter, rect, flags, doc );
+}
+
+/*!
+   Wrap text into <div align=...> </div> tags according flags
+
+   \param text Text
+   \param flags Bitwise OR of the flags like in for QPainter::drawText
+
+   \return Tagged text
+*/
+QString QwtRichTextEngine::taggedText( const QString &text, int flags ) const
+{
+    return taggedRichText( text, flags );
+}
+
+/*!
+  Test if a string can be rendered by this text engine
+
+  \param text Text to be tested
+  \return QStyleSheet::mightBeRichText(text);
+*/
+bool QwtRichTextEngine::mightRender( const QString &text ) const
+{
+    return Qt::mightBeRichText( text );
+}
+
+/*!
+  Return margins around the texts
+
+  \param left Return 0
+  \param right Return 0
+  \param top Return 0
+  \param bottom Return 0
+*/
+void QwtRichTextEngine::textMargins( const QFont &, const QString &,
+    double &left, double &right, double &top, double &bottom ) const
+{
+    left = right = top = bottom = 0;
+}
+
+#endif // !QT_NO_RICHTEXT
Index: trunk/BNC/qwt/qwt_text_engine.h
===================================================================
--- trunk/BNC/qwt/qwt_text_engine.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_text_engine.h	(revision 4271)
@@ -0,0 +1,172 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2003   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_TEXT_ENGINE_H
+#define QWT_TEXT_ENGINE_H 1
+
+#include "qwt_global.h"
+#include <qsize.h>
+
+class QFont;
+class QRectF;
+class QString;
+class QPainter;
+
+/*!
+  \brief Abstract base class for rendering text strings
+
+  A text engine is responsible for rendering texts for a
+  specific text format. They are used by QwtText to render a text.
+
+  QwtPlainTextEngine and QwtRichTextEngine are part of the Qwt library.
+  The implementation of QwtMathMLTextEngine uses code from the 
+  Qt solution package. Because of license implications it is built into
+  a separate library.
+ 
+  \sa QwtText::setTextEngine()
+*/
+
+class QWT_EXPORT QwtTextEngine
+{
+public:
+    virtual ~QwtTextEngine();
+
+    /*!
+      Find the height for a given width
+
+      \param font Font of the text
+      \param flags Bitwise OR of the flags used like in QPainter::drawText
+      \param text Text to be rendered
+      \param width Width
+
+      \return Calculated height
+     */
+    virtual double heightForWidth( const QFont &font, int flags,
+        const QString &text, double width ) const = 0;
+
+    /*!
+      Returns the size, that is needed to render text
+
+      \param font Font of the text
+      \param flags Bitwise OR of the flags like in for QPainter::drawText
+      \param text Text to be rendered
+
+      \return Caluclated size
+     */
+    virtual QSizeF textSize( const QFont &font, int flags,
+        const QString &text ) const = 0;
+
+    /*!
+      Test if a string can be rendered by this text engine
+
+      \param text Text to be tested
+      \return true, if it can be rendered
+     */
+    virtual bool mightRender( const QString &text ) const = 0;
+
+    /*!
+      Return margins around the texts
+
+      The textSize might include margins around the
+      text, like QFontMetrics::descent. In situations
+      where texts need to be aligend in detail, knowing
+      these margins might improve the layout calculations.
+
+      \param font Font of the text
+      \param text Text to be rendered
+      \param left Return value for the left margin
+      \param right Return value for the right margin
+      \param top Return value for the top margin
+      \param bottom Return value for the bottom margin
+     */
+    virtual void textMargins( const QFont &font, const QString &text,
+        double &left, double &right, double &top, double &bottom ) const = 0;
+
+    /*!
+      Draw the text in a clipping rectangle
+
+      \param painter Painter
+      \param rect Clipping rectangle
+      \param flags Bitwise OR of the flags like in for QPainter::drawText
+      \param text Text to be rendered
+     */
+    virtual void draw( QPainter *painter, const QRectF &rect,
+        int flags, const QString &text ) const = 0;
+
+protected:
+    QwtTextEngine();
+};
+
+
+/*!
+  \brief A text engine for plain texts
+
+  QwtPlainTextEngine renders texts using the basic Qt classes
+  QPainter and QFontMetrics.
+*/
+class QWT_EXPORT QwtPlainTextEngine: public QwtTextEngine
+{
+public:
+    QwtPlainTextEngine();
+    virtual ~QwtPlainTextEngine();
+
+    virtual double heightForWidth( const QFont &font, int flags,
+        const QString &text, double width ) const;
+
+    virtual QSizeF textSize( const QFont &font, int flags,
+        const QString &text ) const;
+
+    virtual void draw( QPainter *painter, const QRectF &rect,
+        int flags, const QString &text ) const;
+
+    virtual bool mightRender( const QString & ) const;
+
+    virtual void textMargins( const QFont &, const QString &,
+        double &left, double &right, double &top, double &bottom ) const;
+
+private:
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+
+#ifndef QT_NO_RICHTEXT
+
+/*!
+  \brief A text engine for Qt rich texts
+
+  QwtRichTextEngine renders Qt rich texts using the classes
+  of the Scribe framework of Qt.
+*/
+class QWT_EXPORT QwtRichTextEngine: public QwtTextEngine
+{
+public:
+    QwtRichTextEngine();
+
+    virtual double heightForWidth( const QFont &font, int flags,
+        const QString &text, double width ) const;
+
+    virtual QSizeF textSize( const QFont &font, int flags,
+        const QString &text ) const;
+
+    virtual void draw( QPainter *painter, const QRectF &rect,
+        int flags, const QString &text ) const;
+
+    virtual bool mightRender( const QString & ) const;
+
+    virtual void textMargins( const QFont &, const QString &,
+        double &left, double &right, double &top, double &bottom ) const;
+
+private:
+    QString taggedText( const QString &, int flags ) const;
+};
+
+#endif // !QT_NO_RICHTEXT
+
+#endif
Index: trunk/BNC/qwt/qwt_text_label.cpp
===================================================================
--- trunk/BNC/qwt/qwt_text_label.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_text_label.cpp	(revision 4271)
@@ -0,0 +1,306 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#include "qwt_text_label.h"
+#include "qwt_text.h"
+#include "qwt_painter.h"
+#include <qpainter.h>
+#include <qevent.h>
+#include <qmath.h>
+
+class QwtTextLabel::PrivateData
+{
+public:
+    PrivateData():
+        indent( 4 ),
+        margin( 0 )
+    {
+    }
+
+    int indent;
+    int margin;
+    QwtText text;
+};
+
+/*!
+  Constructs an empty label.
+  \param parent Parent widget
+*/
+QwtTextLabel::QwtTextLabel( QWidget *parent ):
+    QFrame( parent )
+{
+    init();
+}
+
+/*!
+  Constructs a label that displays the text, text
+  \param parent Parent widget
+  \param text Text
+*/
+QwtTextLabel::QwtTextLabel( const QwtText &text, QWidget *parent ):
+    QFrame( parent )
+{
+    init();
+    d_data->text = text;
+}
+
+//! Destructor
+QwtTextLabel::~QwtTextLabel()
+{
+    delete d_data;
+}
+
+void QwtTextLabel::init()
+{
+    d_data = new PrivateData();
+    setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
+}
+
+/*!
+   Change the label's text, keeping all other QwtText attributes
+   \param text New text
+   \param textFormat Format of text
+
+  \sa QwtText
+*/
+void QwtTextLabel::setText( const QString &text, QwtText::TextFormat textFormat )
+{
+    d_data->text.setText( text, textFormat );
+
+    update();
+    updateGeometry();
+}
+
+/*!
+   Change the label's text
+   \param text New text
+*/
+void QwtTextLabel::setText( const QwtText &text )
+{
+    d_data->text = text;
+
+    update();
+    updateGeometry();
+}
+
+//! Return the text
+const QwtText &QwtTextLabel::text() const
+{
+    return d_data->text;
+}
+
+//! Clear the text and all QwtText attributes
+void QwtTextLabel::clear()
+{
+    d_data->text = QwtText();
+
+    update();
+    updateGeometry();
+}
+
+//! Return label's text indent in pixels
+int QwtTextLabel::indent() const
+{
+    return d_data->indent;
+}
+
+/*!
+  Set label's text indent in pixels
+  \param indent Indentation in pixels
+*/
+void QwtTextLabel::setIndent( int indent )
+{
+    if ( indent < 0 )
+        indent = 0;
+
+    d_data->indent = indent;
+
+    update();
+    updateGeometry();
+}
+
+//! Return label's text indent in pixels
+int QwtTextLabel::margin() const
+{
+    return d_data->margin;
+}
+
+/*!
+  Set label's margin in pixels
+  \param margin Margin in pixels
+*/
+void QwtTextLabel::setMargin( int margin )
+{
+    d_data->margin = margin;
+
+    update();
+    updateGeometry();
+}
+
+//! Return label's margin in pixels
+QSize QwtTextLabel::sizeHint() const
+{
+    return minimumSizeHint();
+}
+
+//! Return a minimum size hint
+QSize QwtTextLabel::minimumSizeHint() const
+{
+    QSizeF sz = d_data->text.textSize( font() );
+
+    int mw = 2 * ( frameWidth() + d_data->margin );
+    int mh = mw;
+
+    int indent = d_data->indent;
+    if ( indent <= 0 )
+        indent = defaultIndent();
+
+    if ( indent > 0 )
+    {
+        const int align = d_data->text.renderFlags();
+        if ( align & Qt::AlignLeft || align & Qt::AlignRight )
+            mw += d_data->indent;
+        else if ( align & Qt::AlignTop || align & Qt::AlignBottom )
+            mh += d_data->indent;
+    }
+
+    sz += QSizeF( mw, mh );
+
+    return QSize( qCeil( sz.width() ), qCeil( sz.height() ) );
+}
+
+/*!
+   Returns the preferred height for this widget, given the width.
+   \param width Width
+*/
+int QwtTextLabel::heightForWidth( int width ) const
+{
+    const int renderFlags = d_data->text.renderFlags();
+
+    int indent = d_data->indent;
+    if ( indent <= 0 )
+        indent = defaultIndent();
+
+    width -= 2 * frameWidth();
+    if ( renderFlags & Qt::AlignLeft || renderFlags & Qt::AlignRight )
+        width -= indent;
+
+    int height = d_data->text.heightForWidth( width, font() );
+    if ( renderFlags & Qt::AlignTop || renderFlags & Qt::AlignBottom )
+        height += indent;
+
+    height += 2 * frameWidth();
+
+    return height;
+}
+
+/*!
+   Qt paint event
+   \param event Paint event
+*/
+void QwtTextLabel::paintEvent( QPaintEvent *event )
+{
+    QPainter painter( this );
+
+    if ( !contentsRect().contains( event->rect() ) )
+    {
+        painter.save();
+        painter.setClipRegion( event->region() & frameRect() );
+        drawFrame( &painter );
+        painter.restore();
+    }
+
+    painter.setClipRegion( event->region() & contentsRect() );
+
+    drawContents( &painter );
+}
+
+//! Redraw the text and focus indicator
+void QwtTextLabel::drawContents( QPainter *painter )
+{
+    const QRect r = textRect();
+    if ( r.isEmpty() )
+        return;
+
+    painter->setFont( font() );
+    painter->setPen( palette().color( QPalette::Active, QPalette::Text ) );
+
+    drawText( painter, r );
+
+    if ( hasFocus() )
+    {
+        const int margin = 2;
+
+        QRect focusRect = contentsRect();
+        focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin,
+            focusRect.width() - 2 * margin - 2,
+            focusRect.height() - 2 * margin - 2 );
+
+        QwtPainter::drawFocusRect( painter, this, focusRect );
+    }
+}
+
+//! Redraw the text
+void QwtTextLabel::drawText( QPainter *painter, const QRect &textRect )
+{
+    d_data->text.draw( painter, textRect );
+}
+
+/*!
+  Calculate the rect for the text in widget coordinates
+  \return Text rect
+*/
+QRect QwtTextLabel::textRect() const
+{
+    QRect r = contentsRect();
+
+    if ( !r.isEmpty() && d_data->margin > 0 )
+    {
+        r.setRect( r.x() + d_data->margin, r.y() + d_data->margin,
+            r.width() - 2 * d_data->margin, r.height() - 2 * d_data->margin );
+    }
+
+    if ( !r.isEmpty() )
+    {
+        int indent = d_data->indent;
+        if ( indent <= 0 )
+            indent = defaultIndent();
+
+        if ( indent > 0 )
+        {
+            const int renderFlags = d_data->text.renderFlags();
+
+            if ( renderFlags & Qt::AlignLeft )
+                r.setX( r.x() + indent );
+            else if ( renderFlags & Qt::AlignRight )
+                r.setWidth( r.width() - indent );
+            else if ( renderFlags & Qt::AlignTop )
+                r.setY( r.y() + indent );
+            else if ( renderFlags & Qt::AlignBottom )
+                r.setHeight( r.height() - indent );
+        }
+    }
+
+    return r;
+}
+
+int QwtTextLabel::defaultIndent() const
+{
+    if ( frameWidth() <= 0 )
+        return 0;
+
+    QFont fnt;
+    if ( d_data->text.testPaintAttribute( QwtText::PaintUsingTextFont ) )
+        fnt = d_data->text.font();
+    else
+        fnt = font();
+
+    return QFontMetrics( fnt ).width( 'x' ) / 2;
+}
+
Index: trunk/BNC/qwt/qwt_text_label.h
===================================================================
--- trunk/BNC/qwt/qwt_text_label.h	(revision 4271)
+++ trunk/BNC/qwt/qwt_text_label.h	(revision 4271)
@@ -0,0 +1,72 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * Qwt Widget Library
+ * Copyright (C) 1997   Josef Wilgen
+ * Copyright (C) 2002   Uwe Rathmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the Qwt License, Version 1.0
+ *****************************************************************************/
+
+#ifndef QWT_TEXT_LABEL_H
+#define QWT_TEXT_LABEL_H
+
+#include "qwt_global.h"
+#include "qwt_text.h"
+#include <qframe.h>
+
+class QString;
+class QPaintEvent;
+class QPainter;
+
+/*!
+   \brief A Widget which displays a QwtText
+*/
+
+class QWT_EXPORT QwtTextLabel : public QFrame
+{
+    Q_OBJECT
+
+    Q_PROPERTY( int indent READ indent WRITE setIndent )
+    Q_PROPERTY( int margin READ margin WRITE setMargin )
+
+public:
+    explicit QwtTextLabel( QWidget *parent = NULL );
+    explicit QwtTextLabel( const QwtText &, QWidget *parent = NULL );
+    virtual ~QwtTextLabel();
+
+public Q_SLOTS:
+    void setText( const QString &,
+        QwtText::TextFormat textFormat = QwtText::AutoText );
+    virtual void setText( const QwtText & );
+
+    void clear();
+
+public:
+    const QwtText &text() const;
+
+    int indent() const;
+    void setIndent( int );
+
+    int margin() const;
+    void setMargin( int );
+
+    virtual QSize sizeHint() const;
+    virtual QSize minimumSizeHint() const;
+    virtual int heightForWidth( int ) const;
+
+    QRect textRect() const;
+
+protected:
+    virtual void paintEvent( QPaintEvent *e );
+    virtual void drawContents( QPainter * );
+    virtual void drawText( QPainter *, const QRect & );
+
+private:
+    void init();
+    int defaultIndent() const;
+
+    class PrivateData;
+    PrivateData *d_data;
+};
+
+#endif
