Changeset 8127 in ntrip for trunk


Ignore:
Timestamp:
May 10, 2017, 3:20:54 PM (7 years ago)
Author:
stoecker
Message:

update qwt and qwtpolar, many QT5 fixes (unfinished)

Location:
trunk/BNC
Files:
73 added
3 deleted
155 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/qwt/qwt.h

    r4271 r8127  
    1818namespace Qwt
    1919{
    20 };
     20}
    2121
    2222#endif
  • trunk/BNC/qwt/qwt.pro

    r5182 r8127  
    77CONFIG -= debug
    88CONFIG += release
    9 
    10 ###DEFINES += QWT_NO_SVG
    11 QT += svg
     9QWT_CONFIG = QwtPlot QwtWidgets QwtSvg
    1210
    1311OBJECTS_DIR = .obj
    1412MOC_DIR     = .moc
    1513
    16 HEADERS += \
    17     qwt.h \
    18     qwt_abstract_scale_draw.h \
    19     qwt_interval_symbol.h \
    20     qwt_clipper.h \
    21     qwt_color_map.h \
    22     qwt_compat.h \
    23     qwt_column_symbol.h \
    24     qwt_interval.h \
    25     qwt_dyngrid_layout.h \
    26     qwt_global.h \
    27     qwt_math.h \
    28     qwt_magnifier.h \
    29     qwt_null_paintdevice.h \
    30     qwt_painter.h \
    31     qwt_panner.h \
    32     qwt_picker.h \
    33     qwt_picker_machine.h \
    34     qwt_point_3d.h \
    35     qwt_point_polar.h \
    36     qwt_round_scale_draw.h \
    37     qwt_scale_div.h \
    38     qwt_scale_draw.h \
    39     qwt_scale_engine.h \
    40     qwt_scale_map.h \
    41     qwt_spline.h \
    42     qwt_symbol.h \
    43     qwt_system_clock.h \
    44     qwt_text_engine.h \
    45     qwt_text_label.h \
    46     qwt_text.h \
    47     qwt_curve_fitter.h \
    48     qwt_event_pattern.h \
    49     qwt_legend.h \
    50     qwt_legend_item.h \
    51     qwt_legend_itemmanager.h \
    52     qwt_plot.h \
    53     qwt_plot_renderer.h \
    54     qwt_plot_curve.h \
    55     qwt_plot_dict.h \
    56     qwt_plot_directpainter.h \
    57     qwt_plot_grid.h \
    58     qwt_plot_histogram.h \
    59     qwt_plot_item.h \
    60     qwt_plot_intervalcurve.h \
    61     qwt_plot_layout.h \
    62     qwt_plot_marker.h \
    63     qwt_plot_rasteritem.h \
    64     qwt_plot_spectrogram.h \
    65     qwt_plot_spectrocurve.h \
    66     qwt_plot_scaleitem.h \
    67     qwt_plot_seriesitem.h \
    68     qwt_plot_canvas.h \
    69     qwt_plot_panner.h \
    70     qwt_plot_picker.h \
    71     qwt_plot_zoomer.h \
    72     qwt_plot_magnifier.h \
    73     qwt_plot_rescaler.h \
    74     qwt_raster_data.h \
    75     qwt_matrix_raster_data.h \
    76     qwt_sampling_thread.h \
    77     qwt_series_data.h \
    78     qwt_scale_widget.h \
    79     qwt_plot_svgitem.h
    80 
    81 SOURCES += \
    82     qwt_abstract_scale_draw.cpp \
    83     qwt_interval_symbol.cpp \
    84     qwt_clipper.cpp \
    85     qwt_color_map.cpp \
    86     qwt_column_symbol.cpp \
    87     qwt_interval.cpp \
    88     qwt_dyngrid_layout.cpp \
    89     qwt_math.cpp \
    90     qwt_magnifier.cpp \
    91     qwt_panner.cpp \
    92     qwt_null_paintdevice.cpp \
    93     qwt_painter.cpp \
    94     qwt_picker.cpp \
    95     qwt_round_scale_draw.cpp \
    96     qwt_scale_div.cpp \
    97     qwt_scale_draw.cpp \
    98     qwt_scale_map.cpp \
    99     qwt_spline.cpp \
    100     qwt_text_engine.cpp \
    101     qwt_text_label.cpp \
    102     qwt_text.cpp \
    103     qwt_event_pattern.cpp \
    104     qwt_picker_machine.cpp \
    105     qwt_point_3d.cpp \
    106     qwt_point_polar.cpp \
    107     qwt_scale_engine.cpp \
    108     qwt_symbol.cpp \
    109     qwt_system_clock.cpp \
    110     qwt_curve_fitter.cpp \
    111     qwt_legend.cpp \
    112     qwt_legend_item.cpp \
    113     qwt_plot.cpp \
    114     qwt_plot_renderer.cpp \
    115     qwt_plot_xml.cpp \
    116     qwt_plot_axis.cpp \
    117     qwt_plot_curve.cpp \
    118     qwt_plot_dict.cpp \
    119     qwt_plot_directpainter.cpp \
    120     qwt_plot_grid.cpp \
    121     qwt_plot_histogram.cpp \
    122     qwt_plot_item.cpp \
    123     qwt_plot_intervalcurve.cpp \
    124     qwt_plot_spectrogram.cpp \
    125     qwt_plot_spectrocurve.cpp \
    126     qwt_plot_scaleitem.cpp \
    127     qwt_plot_seriesitem.cpp \
    128     qwt_plot_marker.cpp \
    129     qwt_plot_layout.cpp \
    130     qwt_plot_canvas.cpp \
    131     qwt_plot_panner.cpp \
    132     qwt_plot_rasteritem.cpp \
    133     qwt_plot_picker.cpp \
    134     qwt_plot_zoomer.cpp \
    135     qwt_plot_magnifier.cpp \
    136     qwt_plot_rescaler.cpp \
    137     qwt_raster_data.cpp \
    138     qwt_matrix_raster_data.cpp \
    139     qwt_sampling_thread.cpp \
    140     qwt_series_data.cpp \
    141     qwt_scale_widget.cpp \
    142     qwt_plot_svgitem.cpp
     14include ( src.pri )
  • trunk/BNC/qwt/qwt_abstract_scale_draw.cpp

    r4271 r8127  
    3838
    3939    QwtScaleMap map;
    40     QwtScaleDiv scldiv;
     40    QwtScaleDiv scaleDiv;
    4141
    4242    double spacing;
     
    8686/*!
    8787  Check if a component is enabled
     88
     89  \param component Component type
     90  \return true, when component is enabled
    8891  \sa enableComponent()
    8992*/
     
    9598/*!
    9699  Change the scale division
    97   \param sd New scale division
    98 */
    99 void QwtAbstractScaleDraw::setScaleDiv( const QwtScaleDiv &sd )
    100 {
    101     d_data->scldiv = sd;
    102     d_data->map.setScaleInterval( sd.lowerBound(), sd.upperBound() );
     100  \param scaleDiv New scale division
     101*/
     102void QwtAbstractScaleDraw::setScaleDiv( const QwtScaleDiv &scaleDiv )
     103{
     104    d_data->scaleDiv = scaleDiv;
     105    d_data->map.setScaleInterval( scaleDiv.lowerBound(), scaleDiv.upperBound() );
    103106    d_data->labelCache.clear();
    104107}
     
    109112*/
    110113void QwtAbstractScaleDraw::setTransformation(
    111     QwtScaleTransformation *transformation )
     114    QwtTransform *transformation )
    112115{
    113116    d_data->map.setTransformation( transformation );
     
    129132const QwtScaleDiv& QwtAbstractScaleDraw::scaleDiv() const
    130133{
    131     return d_data->scldiv;
     134    return d_data->scaleDiv;
    132135}
    133136
     
    179182
    180183        const QList<double> &majorTicks =
    181             d_data->scldiv.ticks( QwtScaleDiv::MajorTick );
     184            d_data->scaleDiv.ticks( QwtScaleDiv::MajorTick );
    182185
    183186        for ( int i = 0; i < majorTicks.count(); i++ )
    184187        {
    185188            const double v = majorTicks[i];
    186             if ( d_data->scldiv.contains( v ) )
    187                 drawLabel( painter, majorTicks[i] );
     189            if ( d_data->scaleDiv.contains( v ) )
     190                drawLabel( painter, v );
    188191        }
    189192
     
    204207            tickType < QwtScaleDiv::NTickTypes; tickType++ )
    205208        {
    206             const QList<double> &ticks = d_data->scldiv.ticks( tickType );
     209            const double tickLen = d_data->tickLength[tickType];
     210            if ( tickLen <= 0.0 )
     211                continue;
     212
     213            const QList<double> &ticks = d_data->scaleDiv.ticks( tickType );
    207214            for ( int i = 0; i < ticks.count(); i++ )
    208215            {
    209216                const double v = ticks[i];
    210                 if ( d_data->scldiv.contains( v ) )
    211                     drawTick( painter, v, d_data->tickLength[tickType] );
     217                if ( d_data->scaleDiv.contains( v ) )
     218                    drawTick( painter, v, tickLen );
    212219            }
    213220        }
     
    258265  The default spacing is 4 pixels.
    259266
     267  \return Spacing
    260268  \sa setSpacing()
    261269*/
     
    268276  \brief Set a minimum for the extent
    269277
    270   The extent is calculated from the coomponents of the
     278  The extent is calculated from the components of the
    271279  scale draw. In situations, where the labels are
    272280  changing and the layout depends on the extent (f.e scrolling
     
    288296/*!
    289297  Get the minimum extent
     298  \return Minimum extent
    290299  \sa extent(), setMinimumExtent()
    291300*/
     
    323332
    324333/*!
    325     Return the length of the ticks
    326 
     334    \return Length of the ticks
    327335    \sa setTickLength(), maxTickLength()
    328336*/
     
    357365
    358366  The value is converted to a plain text using
    359   QLocale::system().toString(value).
     367  QLocale().toString(value).
    360368  This method is often overloaded by applications to have individual
    361369  labels.
     
    401409
    402410/*!
    403    Invalidate the cache used by QwtAbstractScaleDraw::tickLabel
     411   Invalidate the cache used by tickLabel()
    404412
    405413   The cache is invalidated, when a new QwtScaleDiv is set. If
  • trunk/BNC/qwt/qwt_abstract_scale_draw.h

    r4271 r8127  
    1818class QPainter;
    1919class QFont;
    20 class QwtScaleTransformation;
     20class QwtTransform;
    2121class QwtScaleMap;
    2222
     
    2727
    2828  After a scale division has been specified as a QwtScaleDiv object
    29   using QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &s),
    30   the scale can be drawn with the QwtAbstractScaleDraw::draw() member.
     29  using setScaleDiv(), the scale can be drawn with the draw() member.
    3130*/
    3231class QWT_EXPORT QwtAbstractScaleDraw
     
    5958    const QwtScaleDiv& scaleDiv() const;
    6059
    61     void setTransformation( QwtScaleTransformation * );
     60    void setTransformation( QwtTransform * );
    6261    const QwtScaleMap &scaleMap() const;
    6362    QwtScaleMap &scaleMap();
     
    8382      Calculate the extent
    8483
    85       The extent is the distcance from the baseline to the outermost
     84      The extent is the distance from the baseline to the outermost
    8685      pixel of the scale draw in opposite to its orientation.
    8786      It is at least minimumExtent() pixels.
    8887
     88      \param font Font used for drawing the tick labels
     89      \return Number of pixels
     90
    8991      \sa setMinimumExtent(), minimumExtent()
    9092    */
    91     virtual double extent( const QFont & ) const = 0;
     93    virtual double extent( const QFont &font ) const = 0;
    9294
    9395    void setMinimumExtent( double );
     
    100102       \param painter Painter
    101103       \param value Value of the tick
    102        \param len Lenght of the tick
     104       \param len Length of the tick
    103105
    104106       \sa drawBackbone(), drawLabel()
  • trunk/BNC/qwt/qwt_clipper.cpp

    r4271 r8127  
    1111#include "qwt_point_polar.h"
    1212#include <qrect.h>
     13#include <string.h>
     14#include <stdlib.h>
    1315
    1416#if QT_VERSION < 0x040601
     
    4446    {
    4547        double dy = ( p1.y() - p2.y() ) / double( p1.x() - p2.x() );
    46         return Point( d_x1, ( Value ) ( p2.y() + ( d_x1 - p2.x() ) * dy ) );
     48        return Point( d_x1, static_cast< Value >( p2.y() + ( d_x1 - p2.x() ) * dy ) );
    4749    }
    4850private:
     
    6769    {
    6870        double dy = ( p1.y() - p2.y() ) / double( p1.x() - p2.x() );
    69         return Point( d_x2, ( Value ) ( p2.y() + ( d_x2 - p2.x() ) * dy ) );
     71        return Point( d_x2, static_cast<Value>( p2.y() + ( d_x2 - p2.x() ) * dy ) );
    7072    }
    7173
     
    9193    {
    9294        double dx = ( p1.x() - p2.x() ) / double( p1.y() - p2.y() );
    93         return Point( ( Value )( p2.x() + ( d_y1 - p2.y() ) * dx ), d_y1 );
     95        return Point( static_cast<Value>( p2.x() + ( d_y1 - p2.y() ) * dx ), d_y1 );
    9496    }
    9597
     
    115117    {
    116118        double dx = ( p1.x() - p2.x() ) / double( p1.y() - p2.y() );
    117         return Point( ( Value )( p2.x() + ( d_y2 - p2.y() ) * dx ), d_y2 );
     119        return Point( static_cast<Value>( p2.x() + ( d_y2 - p2.y() ) * dx ), d_y2 );
    118120    }
    119121
     
    138140    {
    139141        if ( m_buffer )
    140             qFree( m_buffer );
     142            ::free( m_buffer );
    141143    }
    142144
     
    146148
    147149        m_size = numPoints;
    148         qMemCopy( m_buffer, points, m_size * sizeof( Point ) );
     150        ::memcpy( m_buffer, points, m_size * sizeof( Point ) );
    149151    }
    150152
     
    191193            m_capacity *= 2;
    192194
    193         m_buffer = ( Point * ) qRealloc(
    194             m_buffer, m_capacity * sizeof( Point ) );
     195        m_buffer = static_cast<Point *>(
     196            ::realloc( m_buffer, m_capacity * sizeof( Point ) ) );
    195197    }
    196198
     
    230232        Polygon p;
    231233        p.resize( points1.size() );
    232         qMemCopy( p.data(), points1.data(), points1.size() * sizeof( Point ) );
     234        ::memcpy( p.data(), points1.data(), points1.size() * sizeof( Point ) );
    233235
    234236        return p;
     
    335337    QList<QPointF> points;
    336338    for ( int edge = 0; edge < NEdges; edge++ )
    337         points += cuttingPoints( ( Edge )edge, pos, radius );
     339        points += cuttingPoints( static_cast<Edge>(edge), pos, radius );
    338340
    339341    QVector<QwtInterval> intv;
     
    444446*/
    445447QPolygon QwtClipper::clipPolygon(
     448    const QRectF &clipRect, const QPolygon &polygon, bool closePolygon )
     449{
     450    const int minX = qCeil( clipRect.left() );
     451    const int maxX = qFloor( clipRect.right() );
     452    const int minY = qCeil( clipRect.top() );
     453    const int maxY = qFloor( clipRect.bottom() );
     454
     455    const QRect r( minX, minY, maxX - minX, maxY - minY );
     456
     457    QwtPolygonClipper<QPolygon, QRect, QPoint, int> clipper( r );
     458    return clipper.clipPolygon( polygon, closePolygon );
     459}
     460/*!
     461   Sutherland-Hodgman polygon clipping
     462
     463   \param clipRect Clip rectangle
     464   \param polygon Polygon
     465   \param closePolygon True, when the polygon is closed
     466
     467   \return Clipped polygon
     468*/
     469QPolygon QwtClipper::clipPolygon(
    446470    const QRect &clipRect, const QPolygon &polygon, bool closePolygon )
    447471{
     
    469493   Circle clipping
    470494
    471    clipCircle() devides a circle into intervals of angles representing arcs
     495   clipCircle() divides a circle into intervals of angles representing arcs
    472496   of the circle. When the circle is completely inside the clip rectangle
    473497   an interval [0.0, 2 * M_PI] is returned.
  • trunk/BNC/qwt/qwt_clipper.h

    r4271 r8127  
    2020
    2121/*!
    22   \brief Some clipping algos
     22  \brief Some clipping algorithms
    2323*/
    2424
     
    2828    static QPolygon clipPolygon( const QRect &,
    2929        const QPolygon &, bool closePolygon = false );
     30    static QPolygon clipPolygon( const QRectF &,
     31        const QPolygon &, bool closePolygon = false );
     32
    3033    static QPolygonF clipPolygonF( const QRectF &,
    3134        const QPolygonF &, bool closePolygon = false );
  • trunk/BNC/qwt/qwt_color_map.cpp

    r4271 r8127  
    1616{
    1717public:
    18     ColorStops()
    19     {
    20         _stops.reserve( 256 );
     18    ColorStops():
     19        d_doAlpha( false )
     20    {
     21        d_stops.reserve( 256 );
    2122    }
    2223
     
    3940        ColorStop( double p, const QColor &c ):
    4041            pos( p ),
    41             rgb( c.rgb() )
     42            rgb( c.rgba() )
    4243        {
    4344            r = qRed( rgb );
    4445            g = qGreen( rgb );
    4546            b = qBlue( rgb );
     47            a = qAlpha( rgb );
     48
     49            /*
     50                when mapping a value to rgb we will have to calcualate:
     51                   - const int v = int( ( s1.v0 + ratio * s1.vStep ) + 0.5 );
     52
     53                Thus adding 0.5 ( for rounding ) can be done in advance
     54             */
     55            r0 = r + 0.5;
     56            g0 = g + 0.5;
     57            b0 = b + 0.5;
     58            a0 = a + 0.5;
     59
     60            rStep = gStep = bStep = aStep = 0.0;
     61            posStep = 0.0;
     62        }
     63
     64        void updateSteps( const ColorStop &nextStop )
     65        {
     66            rStep = nextStop.r - r;
     67            gStep = nextStop.g - g;
     68            bStep = nextStop.b - b;
     69            aStep = nextStop.a - a;
     70            posStep = nextStop.pos - pos;
    4671        }
    4772
    4873        double pos;
    4974        QRgb rgb;
    50         int r, g, b;
     75        int r, g, b, a;
     76
     77        // precalculated values
     78        double rStep, gStep, bStep, aStep;
     79        double r0, g0, b0, a0;
     80        double posStep;
    5181    };
    5282
    5383    inline int findUpper( double pos ) const;
    54     QVector<ColorStop> _stops;
     84    QVector<ColorStop> d_stops;
     85    bool d_doAlpha;
    5586};
    5687
     
    6495
    6596    int index;
    66     if ( _stops.size() == 0 )
     97    if ( d_stops.size() == 0 )
    6798    {
    6899        index = 0;
    69         _stops.resize( 1 );
     100        d_stops.resize( 1 );
    70101    }
    71102    else
    72103    {
    73104        index = findUpper( pos );
    74         if ( index == _stops.size() ||
    75                 qAbs( _stops[index].pos - pos ) >= 0.001 )
    76         {
    77             _stops.resize( _stops.size() + 1 );
    78             for ( int i = _stops.size() - 1; i > index; i-- )
    79                 _stops[i] = _stops[i-1];
    80         }
    81     }
    82 
    83     _stops[index] = ColorStop( pos, color );
     105        if ( index == d_stops.size() ||
     106                qAbs( d_stops[index].pos - pos ) >= 0.001 )
     107        {
     108            d_stops.resize( d_stops.size() + 1 );
     109            for ( int i = d_stops.size() - 1; i > index; i-- )
     110                d_stops[i] = d_stops[i-1];
     111        }
     112    }
     113
     114    d_stops[index] = ColorStop( pos, color );
     115    if ( color.alpha() != 255 )
     116        d_doAlpha = true;
     117
     118    if ( index > 0 )
     119        d_stops[index-1].updateSteps( d_stops[index] );
     120
     121    if ( index < d_stops.size() - 1 )
     122        d_stops[index].updateSteps( d_stops[index+1] );
    84123}
    85124
    86125inline QVector<double> QwtLinearColorMap::ColorStops::stops() const
    87126{
    88     QVector<double> positions( _stops.size() );
    89     for ( int i = 0; i < _stops.size(); i++ )
    90         positions[i] = _stops[i].pos;
     127    QVector<double> positions( d_stops.size() );
     128    for ( int i = 0; i < d_stops.size(); i++ )
     129        positions[i] = d_stops[i].pos;
    91130    return positions;
    92131}
     
    95134{
    96135    int index = 0;
    97     int n = _stops.size();
    98 
    99     const ColorStop *stops = _stops.data();
     136    int n = d_stops.size();
     137
     138    const ColorStop *stops = d_stops.data();
    100139
    101140    while ( n > 0 )
     
    120159{
    121160    if ( pos <= 0.0 )
    122         return _stops[0].rgb;
     161        return d_stops[0].rgb;
    123162    if ( pos >= 1.0 )
    124         return _stops[ _stops.size() - 1 ].rgb;
     163        return d_stops[ d_stops.size() - 1 ].rgb;
    125164
    126165    const int index = findUpper( pos );
    127166    if ( mode == FixedColors )
    128167    {
    129         return _stops[index-1].rgb;
     168        return d_stops[index-1].rgb;
    130169    }
    131170    else
    132171    {
    133         const ColorStop &s1 = _stops[index-1];
    134         const ColorStop &s2 = _stops[index];
    135 
    136         const double ratio = ( pos - s1.pos ) / ( s2.pos - s1.pos );
    137 
    138         const int r = s1.r + qRound( ratio * ( s2.r - s1.r ) );
    139         const int g = s1.g + qRound( ratio * ( s2.g - s1.g ) );
    140         const int b = s1.b + qRound( ratio * ( s2.b - s1.b ) );
    141 
    142         return qRgb( r, g, b );
     172        const ColorStop &s1 = d_stops[index-1];
     173
     174        const double ratio = ( pos - s1.pos ) / ( s1.posStep );
     175
     176        const int r = int( s1.r0 + ratio * s1.rStep );
     177        const int g = int( s1.g0 + ratio * s1.gStep );
     178        const int b = int( s1.b0 + ratio * s1.bStep );
     179
     180        if ( d_doAlpha )
     181        {
     182            if ( s1.aStep )
     183            {
     184                const int a = int( s1.a0 + ratio * s1.aStep );
     185                return qRgba( r, g, b, a );
     186            }
     187            else
     188            {
     189                return qRgba( r, g, b, s1.a );
     190            }
     191        }
     192        else
     193        {
     194            return qRgb( r, g, b );
     195        }
    143196    }
    144197}
     
    205258   \param color1 Color used for the minimum value of the value interval
    206259   \param color2 Color used for the maximum value of the value interval
    207    \param format Preferred format of the coor map
     260   \param format Preferred format for the color map
    208261*/
    209262QwtLinearColorMap::QwtLinearColorMap( const QColor &color1,
     
    280333
    281334/*!
    282    Return all positions of color stops in increasing order
     335   \return Positions of color stops in increasing order
    283336*/
    284337QVector<double> QwtLinearColorMap::colorStops() const
     
    306359
    307360/*!
    308   Map a value of a given interval into a rgb value
     361  Map a value of a given interval into a RGB value
    309362
    310363  \param interval Range for all values
    311   \param value Value to map into a rgb value
     364  \param value Value to map into a RGB value
     365
     366  \return RGB value for value
    312367*/
    313368QRgb QwtLinearColorMap::rgb(
     
    315370{
    316371    if ( qIsNaN(value) )
    317         return qRgba(0, 0, 0, 0);
     372        return 0u;
    318373
    319374    const double width = interval.width();
    320 
    321     double ratio = 0.0;
    322     if ( width > 0.0 )
    323         ratio = ( value - interval.minValue() ) / width;
    324 
     375    if ( width <= 0.0 )
     376        return 0u;
     377
     378    const double ratio = ( value - interval.minValue() ) / width;
    325379    return d_data->colorStops.rgb( d_data->mode, ratio );
    326380}
    327381
    328382/*!
    329   Map a value of a given interval into a color index, between 0 and 255
     383  \brief Map a value of a given interval into a color index
    330384
    331385  \param interval Range for all values
    332386  \param value Value to map into a color index
     387
     388  \return Index, between 0 and 255
    333389*/
    334390unsigned char QwtLinearColorMap::colorIndex(
     
    341397
    342398    if ( value >= interval.maxValue() )
    343         return ( unsigned char )255;
     399        return 255;
    344400
    345401    const double ratio = ( value - interval.minValue() ) / width;
     
    347403    unsigned char index;
    348404    if ( d_data->mode == FixedColors )
    349         index = ( unsigned char )( ratio * 255 ); // always floor
     405        index = static_cast<unsigned char>( ratio * 255 ); // always floor
    350406    else
    351         index = ( unsigned char )qRound( ratio * 255 );
     407        index = static_cast<unsigned char>( ratio * 255 + 0.5 );
    352408
    353409    return index;
     
    359415    QColor color;
    360416    QRgb rgb;
     417    QRgb rgbMax;
    361418};
    362419
     
    370427{
    371428    d_data = new PrivateData;
     429    setColor( color );
     430}
     431
     432//! Destructor
     433QwtAlphaColorMap::~QwtAlphaColorMap()
     434{
     435    delete d_data;
     436}
     437
     438/*!
     439   Set the color
     440
     441   \param color Color
     442   \sa color()
     443*/
     444void QwtAlphaColorMap::setColor( const QColor &color )
     445{
    372446    d_data->color = color;
    373447    d_data->rgb = color.rgb() & qRgba( 255, 255, 255, 0 );
    374 }
    375 
    376 //! Destructor
    377 QwtAlphaColorMap::~QwtAlphaColorMap()
    378 {
    379     delete d_data;
    380 }
    381 
    382 /*!
    383    Set the color
    384 
    385    \param color Color
    386    \sa color()
    387 */
    388 void QwtAlphaColorMap::setColor( const QColor &color )
    389 {
    390     d_data->color = color;
    391     d_data->rgb = color.rgb();
     448    d_data->rgbMax = d_data->rgb | ( 255 << 24 );
    392449}
    393450
     
    407464
    408465  \param interval Range for all values
    409   \param value Value to map into a rgb value
    410   \return rgb value, with an alpha value
     466  \param value Value to map into a RGB value
     467  \return RGB value, with an alpha value
    411468*/
    412469QRgb QwtAlphaColorMap::rgb( const QwtInterval &interval, double value ) const
    413470{
     471    if ( qIsNaN(value) )
     472        return 0u;
     473
    414474    const double width = interval.width();
    415     if ( !qIsNaN(value) && width >= 0.0 )
    416     {
    417         const double ratio = ( value - interval.minValue() ) / width;
    418         int alpha = qRound( 255 * ratio );
    419         if ( alpha < 0 )
    420             alpha = 0;
    421         if ( alpha > 255 )
    422             alpha = 255;
    423 
    424         return d_data->rgb | ( alpha << 24 );
    425     }
    426     return d_data->rgb;
     475    if ( width <= 0.0 )
     476        return 0u;
     477
     478    if ( value <= interval.minValue() )
     479        return d_data->rgb;
     480
     481    if ( value >= interval.maxValue() )
     482        return d_data->rgbMax;
     483
     484    const double ratio = ( value - interval.minValue() ) / width;
     485    return d_data->rgb | ( qRound( 255 * ratio ) << 24 );
    427486}
    428487
  • trunk/BNC/qwt/qwt_color_map.h

    r4271 r8127  
    4141    enum Format
    4242    {
    43         //! The map is intended to map into QRgb values.
     43        //! The map is intended to map into RGB values.
    4444        RGB,
    4545
     
    5757
    5858    /*!
    59        Map a value of a given interval into a rgb value.
     59       Map a value of a given interval into a RGB value.
     60
    6061       \param interval Range for the values
    6162       \param value Value
    62        \return rgb value, corresponding to value
     63       \return RGB value, corresponding to value
    6364    */
    6465    virtual QRgb rgb( const QwtInterval &interval,
     
    6768    /*!
    6869       Map a value of a given interval into a color index
     70
    6971       \param interval Range for the values
    7072       \param value Value
     
    136138
    137139/*!
    138   \brief QwtAlphaColorMap variies the alpha value of a color
     140  \brief QwtAlphaColorMap varies the alpha value of a color
    139141*/
    140142class QWT_EXPORT QwtAlphaColorMap: public QwtColorMap
     
    178180    if ( d_format == RGB )
    179181    {
    180         return QColor( rgb( interval, value ) );
     182        return QColor::fromRgba( rgb( interval, value ) );
    181183    }
    182184    else
  • trunk/BNC/qwt/qwt_column_symbol.cpp

    r4271 r8127  
    1010#include "qwt_column_symbol.h"
    1111#include "qwt_math.h"
    12 #include "qwt_text.h"
    1312#include "qwt_painter.h"
    1413#include <qpainter.h>
    1514#include <qpalette.h>
    1615
    17 static void drawBox( QPainter *p, const QRectF &rect,
     16static void qwtDrawBox( QPainter *p, const QRectF &rect,
    1817    const QPalette &pal, double lw )
    1918{
     
    5857}
    5958
    60 static void drawPanel( QPainter *painter, const QRectF &rect,
     59static void qwtDrawPanel( QPainter *painter, const QRectF &rect,
    6160    const QPalette &pal, double lw )
    6261{
     
    125124
    126125    QPalette palette;
    127     QwtText label;
    128 
    129126    int lineWidth;
    130127};
     
    281278        case QwtColumnSymbol::Raised:
    282279        {
    283             ::drawPanel( painter, r, d_data->palette, d_data->lineWidth );
     280            qwtDrawPanel( painter, r, d_data->palette, d_data->lineWidth );
    284281            break;
    285282        }
    286283        case QwtColumnSymbol::Plain:
    287284        {
    288             ::drawBox( painter, r, d_data->palette, d_data->lineWidth );
     285            qwtDrawBox( painter, r, d_data->palette, d_data->lineWidth );
    289286            break;
    290287        }
  • trunk/BNC/qwt/qwt_column_symbol.h

    r4271 r8127  
    2323
    2424/*!
    25     \brief Directed rectangle representing bounding rectangle und orientation
     25    \brief Directed rectangle representing bounding rectangle and orientation
    2626    of a column.
    2727*/
  • trunk/BNC/qwt/qwt_compat.h

    r4271 r8127  
    1212
    1313#include "qwt_global.h"
     14#include "qwt_interval.h"
     15#include "qwt_point_3d.h"
    1416#include <qlist.h>
    1517#include <qvector.h>
  • trunk/BNC/qwt/qwt_curve_fitter.cpp

    r4271 r8127  
    247247public:
    248248    PrivateData():
    249         tolerance( 1.0 )
     249        tolerance( 1.0 ),
     250        chunkSize( 0 )
    250251    {
    251252    }
    252253
    253254    double tolerance;
     255    uint chunkSize;
    254256};
    255257
     
    288290 Assign the tolerance
    289291
    290  The tolerance is the maximum distance, that is accaptable
     292 The tolerance is the maximum distance, that is acceptable
    291293 between the original curve and the smoothed curve.
    292294
     
    313315
    314316/*!
     317 Limit the number of points passed to a run of the algorithm
     318
     319 The runtime of the Douglas Peucker algorithm increases non linear
     320 with the number of points. For a chunk size > 0 the polygon
     321 is split into pieces passed to the algorithm one by one.
     322
     323 \param numPoints Maximum for the number of points passed to the algorithm
     324
     325 \sa chunkSize()
     326*/
     327void QwtWeedingCurveFitter::setChunkSize( uint numPoints )
     328{
     329    if ( numPoints > 0 )
     330        numPoints = qMax( numPoints, 3U );
     331
     332    d_data->chunkSize = numPoints;
     333}
     334
     335/*!
     336 
     337  \return Maximum for the number of points passed to a run
     338          of the algorithm - or 0, when unlimited
     339  \sa setChunkSize()
     340*/
     341uint QwtWeedingCurveFitter::chunkSize() const
     342{
     343    return d_data->chunkSize;
     344}
     345
     346/*!
    315347  \param points Series of data points
    316348  \return Curve points
     
    318350QPolygonF QwtWeedingCurveFitter::fitCurve( const QPolygonF &points ) const
    319351{
     352    QPolygonF fittedPoints;
     353
     354    if ( d_data->chunkSize == 0 )
     355    {
     356        fittedPoints = simplify( points );
     357    }
     358    else
     359    {
     360        for ( int i = 0; i < points.size(); i += d_data->chunkSize )
     361        {
     362            const QPolygonF p = points.mid( i, d_data->chunkSize );
     363            fittedPoints += simplify( p );
     364        }
     365    }
     366
     367    return fittedPoints;
     368}
     369
     370QPolygonF QwtWeedingCurveFitter::simplify( const QPolygonF &points ) const
     371{
     372    const double toleranceSqr = d_data->tolerance * d_data->tolerance;
     373
    320374    QStack<Line> stack;
    321375    stack.reserve( 500 );
     
    325379
    326380    QVector<bool> usePoint( nPoints, false );
    327 
    328     double distToSegment;
    329381
    330382    stack.push( Line( 0, nPoints - 1 ) );
     
    343395        const double unitVecY = ( vecLength != 0.0 ) ? vecY / vecLength : 0.0;
    344396
    345         double maxDist = 0.0;
     397        double maxDistSqr = 0.0;
    346398        int nVertexIndexMaxDistance = r.from + 1;
    347399        for ( int i = r.from + 1; i < r.to; i++ )
     
    350402            const double fromVecX = p[i].x() - p[r.from].x();
    351403            const double fromVecY = p[i].y() - p[r.from].y();
    352             const double fromVecLength =
    353                 qSqrt( fromVecX * fromVecX + fromVecY * fromVecY );
    354 
     404
     405            double distToSegmentSqr;
    355406            if ( fromVecX * unitVecX + fromVecY * unitVecY < 0.0 )
    356407            {
    357                 distToSegment = fromVecLength;
    358             }
    359             if ( fromVecX * unitVecX + fromVecY * unitVecY < 0.0 )
    360             {
    361                 distToSegment = fromVecLength;
     408                distToSegmentSqr = fromVecX * fromVecX + fromVecY * fromVecY;
    362409            }
    363410            else
     
    365412                const double toVecX = p[i].x() - p[r.to].x();
    366413                const double toVecY = p[i].y() - p[r.to].y();
    367                 const double toVecLength = qSqrt( toVecX * toVecX + toVecY * toVecY );
     414                const double toVecLength = toVecX * toVecX + toVecY * toVecY;
     415
    368416                const double s = toVecX * ( -unitVecX ) + toVecY * ( -unitVecY );
    369417                if ( s < 0.0 )
    370                     distToSegment = toVecLength;
     418                {
     419                    distToSegmentSqr = toVecLength;
     420                }
    371421                else
    372422                {
    373                     distToSegment = qSqrt( qFabs( toVecLength * toVecLength - s * s ) );
     423                    distToSegmentSqr = qFabs( toVecLength - s * s );
    374424                }
    375425            }
    376426
    377             if ( maxDist < distToSegment )
     427            if ( maxDistSqr < distToSegmentSqr )
    378428            {
    379                 maxDist = distToSegment;
     429                maxDistSqr = distToSegmentSqr;
    380430                nVertexIndexMaxDistance = i;
    381431            }
    382432        }
    383         if ( maxDist <= d_data->tolerance )
     433        if ( maxDistSqr <= toleranceSqr )
    384434        {
    385435            usePoint[r.from] = true;
     
    393443    }
    394444
    395     int cnt = 0;
    396 
    397     QPolygonF stripped( nPoints );
     445    QPolygonF stripped;
    398446    for ( int i = 0; i < nPoints; i++ )
    399447    {
    400448        if ( usePoint[i] )
    401             stripped[cnt++] = p[i];
    402     }
    403     stripped.resize( cnt );
     449            stripped += p[i];
     450    }
     451
    404452    return stripped;
    405453}
  • trunk/BNC/qwt/qwt_curve_fitter.h

    r4271 r8127  
    100100  smoothed curve.
    101101
     102  The runtime of the algorithm increases non linear ( worst case O( n*n ) )
     103  and might be very slow for huge polygons. To avoid performance issues
     104  it might be useful to split the polygon ( setChunkSize() ) and to run the algorithm
     105  for these smaller parts. The disadvantage of having no interpolation
     106  at the borders is for most use cases irrelevant.
     107
    102108  The smoothed curve consists of a subset of the points that defined the
    103109  original curve.
     
    117123    double tolerance() const;
    118124
     125    void setChunkSize( uint );
     126    uint chunkSize() const;
     127
    119128    virtual QPolygonF fitCurve( const QPolygonF & ) const;
    120129
    121130private:
     131    virtual QPolygonF simplify( const QPolygonF & ) const;
     132
    122133    class Line;
    123134
  • trunk/BNC/qwt/qwt_dyngrid_layout.cpp

    r4271 r8127  
    1010#include "qwt_dyngrid_layout.h"
    1111#include "qwt_math.h"
    12 #include <qwidget.h>
     12#include <qvector.h>
    1313#include <qlist.h>
    1414
     
    2525    mutable QList<QLayoutItem*> itemList;
    2626
    27     uint maxCols;
     27    uint maxColumns;
    2828    uint numRows;
    29     uint numCols;
     29    uint numColumns;
    3030
    3131    Qt::Orientations expanding;
     
    8282{
    8383    d_data = new QwtDynGridLayout::PrivateData;
    84     d_data->maxCols = d_data->numRows = d_data->numCols = 0;
     84    d_data->maxColumns = d_data->numRows = d_data->numColumns = 0;
    8585    d_data->expanding = 0;
    8686}
     
    105105/*!
    106106  Limit the number of columns.
    107   \param maxCols upper limit, 0 means unlimited
    108   \sa maxCols()
    109 */
    110 void QwtDynGridLayout::setMaxCols( uint maxCols )
    111 {
    112     d_data->maxCols = maxCols;
    113 }
    114 
    115 /*!
    116   Return the upper limit for the number of columns.
     107  \param maxColumns upper limit, 0 means unlimited
     108  \sa maxColumns()
     109*/
     110void QwtDynGridLayout::setMaxColumns( uint maxColumns )
     111{
     112    d_data->maxColumns = maxColumns;
     113}
     114
     115/*!
     116  \brief Return the upper limit for the number of columns.
     117
    117118  0 means unlimited, what is the default.
    118   \sa setMaxCols()
    119 */
    120 
    121 uint QwtDynGridLayout::maxCols() const
    122 {
    123     return d_data->maxCols;
    124 }
    125 
    126 //! Adds item to the next free position.
    127 
     119
     120  \return Upper limit for the number of columns
     121  \sa setMaxColumns()
     122*/
     123uint QwtDynGridLayout::maxColumns() const
     124{
     125    return d_data->maxColumns;
     126}
     127
     128/*!
     129  \brief Add an item to the next free position.
     130  \param item Layout item
     131 */
    128132void QwtDynGridLayout::addItem( QLayoutItem *item )
    129133{
     
    135139  \return true if this layout is empty.
    136140*/
    137 
    138141bool QwtDynGridLayout::isEmpty() const
    139142{
     
    144147  \return number of layout items
    145148*/
    146 
    147149uint QwtDynGridLayout::itemCount() const
    148150{
     
    151153
    152154/*!
    153   Find the item at a spcific index
     155  Find the item at a specific index
    154156
    155157  \param index Index
     158  \return Item at a specific index
    156159  \sa takeAt()
    157160*/
     
    165168
    166169/*!
    167   Find the item at a spcific index and remove it from the layout
     170  Find the item at a specific index and remove it from the layout
    168171
    169172  \param index Index
     173  \return Layout item, removed from the layout
    170174  \sa itemAt()
    171175*/
     
    200204
    201205/*!
    202   Returns whether this layout can make use of more space than sizeHint().
     206  \brief Returns whether this layout can make use of more space than sizeHint().
     207
    203208  A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only
    204209  one dimension, while Qt::Vertical | Qt::Horizontal means that it wants
    205210  to grow in both dimensions.
     211
     212  \return Orientations, where the layout expands
    206213  \sa setExpandingDirections()
    207214*/
     
    212219
    213220/*!
    214   Reorganizes columns and rows and resizes managed widgets within
    215   the rectangle rect.
     221  Reorganizes columns and rows and resizes managed items within
     222  a rectangle.
    216223
    217224  \param rect Layout geometry
     
    224231        return;
    225232
    226     d_data->numCols = columnsForWidth( rect.width() );
    227     d_data->numRows = itemCount() / d_data->numCols;
    228     if ( itemCount() % d_data->numCols )
     233    d_data->numColumns = columnsForWidth( rect.width() );
     234    d_data->numRows = itemCount() / d_data->numColumns;
     235    if ( itemCount() % d_data->numColumns )
    229236        d_data->numRows++;
    230237
    231     QList<QRect> itemGeometries = layoutItems( rect, d_data->numCols );
     238    QList<QRect> itemGeometries = layoutItems( rect, d_data->numColumns );
    232239
    233240    int index = 0;
     
    235242        it != d_data->itemList.end(); ++it )
    236243    {
    237         QWidget *w = ( *it )->widget();
    238         if ( w )
    239         {
    240             w->setGeometry( itemGeometries[index] );
    241             index++;
    242         }
    243     }
    244 }
    245 
    246 /*!
    247   Calculate the number of columns for a given width. It tries to
    248   use as many columns as possible (limited by maxCols())
     244        ( *it )->setGeometry( itemGeometries[index] );
     245        index++;
     246    }
     247}
     248
     249/*!
     250  \brief Calculate the number of columns for a given width.
     251
     252  The calculation tries to use as many columns as possible
     253  ( limited by maxColumns() )
    249254
    250255  \param width Available width for all columns
    251   \sa maxCols(), setMaxCols()
    252 */
    253 
     256  \return Number of columns for a given width
     257
     258  \sa maxColumns(), setMaxColumns()
     259*/
    254260uint QwtDynGridLayout::columnsForWidth( int width ) const
    255261{
     
    257263        return 0;
    258264
    259     const int maxCols = ( d_data->maxCols > 0 ) ? d_data->maxCols : itemCount();
    260     if ( maxRowWidth( maxCols ) <= width )
    261         return maxCols;
    262 
    263     for ( int numCols = 2; numCols <= maxCols; numCols++ )
    264     {
    265         const int rowWidth = maxRowWidth( numCols );
     265    uint maxColumns = itemCount();
     266    if ( d_data->maxColumns > 0 )
     267        maxColumns = qMin( d_data->maxColumns, maxColumns );
     268
     269    if ( maxRowWidth( maxColumns ) <= width )
     270        return maxColumns;
     271
     272    for ( uint numColumns = 2; numColumns <= maxColumns; numColumns++ )
     273    {
     274        const int rowWidth = maxRowWidth( numColumns );
    266275        if ( rowWidth > width )
    267             return numCols - 1;
     276            return numColumns - 1;
    268277    }
    269278
     
    275284  columns.
    276285
    277   \param numCols Given number of columns
     286  \param numColumns Given number of columns
    278287  \param itemWidth Array of the width hints for all items
    279288*/
    280 int QwtDynGridLayout::maxRowWidth( int numCols ) const
     289int QwtDynGridLayout::maxRowWidth( int numColumns ) const
    281290{
    282291    int col;
    283292
    284     QVector<int> colWidth( numCols );
    285     for ( col = 0; col < numCols; col++ )
     293    QVector<int> colWidth( numColumns );
     294    for ( col = 0; col < numColumns; col++ )
    286295        colWidth[col] = 0;
    287296
     
    292301        index < d_data->itemSizeHints.count(); index++ )
    293302    {
    294         col = index % numCols;
     303        col = index % numColumns;
    295304        colWidth[col] = qMax( colWidth[col],
    296305            d_data->itemSizeHints[int( index )].width() );
    297306    }
    298307
    299     int rowWidth = 2 * margin() + ( numCols - 1 ) * spacing();
    300     for ( col = 0; col < numCols; col++ )
     308    int rowWidth = 2 * margin() + ( numColumns - 1 ) * spacing();
     309    for ( col = 0; col < numColumns; col++ )
    301310        rowWidth += colWidth[col];
    302311
     
    328337/*!
    329338  Calculate the geometries of the layout items for a layout
    330   with numCols columns and a given rect.
     339  with numColumns columns and a given rectangle.
    331340
    332341  \param rect Rect where to place the items
    333   \param numCols Number of columns
     342  \param numColumns Number of columns
    334343  \return item geometries
    335344*/
    336345
    337346QList<QRect> QwtDynGridLayout::layoutItems( const QRect &rect,
    338     uint numCols ) const
     347    uint numColumns ) const
    339348{
    340349    QList<QRect> itemGeometries;
    341     if ( numCols == 0 || isEmpty() )
     350    if ( numColumns == 0 || isEmpty() )
    342351        return itemGeometries;
    343352
    344     uint numRows = itemCount() / numCols;
    345     if ( numRows % itemCount() )
     353    uint numRows = itemCount() / numColumns;
     354    if ( numColumns % itemCount() )
    346355        numRows++;
    347356
     357    if ( numRows == 0 )
     358        return itemGeometries;
     359
    348360    QVector<int> rowHeight( numRows );
    349     QVector<int> colWidth( numCols );
    350 
    351     layoutGrid( numCols, rowHeight, colWidth );
     361    QVector<int> colWidth( numColumns );
     362
     363    layoutGrid( numColumns, rowHeight, colWidth );
    352364
    353365    bool expandH, expandV;
     
    356368
    357369    if ( expandH || expandV )
    358         stretchGrid( rect, numCols, rowHeight, colWidth );
    359 
    360     const int maxCols = d_data->maxCols;
    361     d_data->maxCols = numCols;
     370        stretchGrid( rect, numColumns, rowHeight, colWidth );
     371
     372    const int maxColumns = d_data->maxColumns;
     373    d_data->maxColumns = numColumns;
    362374    const QRect alignedRect = alignmentRect( rect );
    363     d_data->maxCols = maxCols;
     375    d_data->maxColumns = maxColumns;
    364376
    365377    const int xOffset = expandH ? 0 : alignedRect.x();
    366378    const int yOffset = expandV ? 0 : alignedRect.y();
    367379
    368     QVector<int> colX( numCols );
     380    QVector<int> colX( numColumns );
    369381    QVector<int> rowY( numRows );
    370382
     
    372384
    373385    rowY[0] = yOffset + margin();
    374     for ( int r = 1; r < ( int )numRows; r++ )
     386    for ( uint r = 1; r < numRows; r++ )
    375387        rowY[r] = rowY[r-1] + rowHeight[r-1] + xySpace;
    376388
    377389    colX[0] = xOffset + margin();
    378     for ( int c = 1; c < ( int )numCols; c++ )
     390    for ( uint c = 1; c < numColumns; c++ )
    379391        colX[c] = colX[c-1] + colWidth[c-1] + xySpace;
    380392
     
    382394    for ( int i = 0; i < itemCount; i++ )
    383395    {
    384         const int row = i / numCols;
    385         const int col = i % numCols;
     396        const int row = i / numColumns;
     397        const int col = i % numColumns;
    386398
    387399        QRect itemGeometry( colX[col], rowY[row],
     
    396408/*!
    397409  Calculate the dimensions for the columns and rows for a grid
    398   of numCols columns.
    399 
    400   \param numCols Number of columns.
     410  of numColumns columns.
     411
     412  \param numColumns Number of columns.
    401413  \param rowHeight Array where to fill in the calculated row heights.
    402414  \param colWidth Array where to fill in the calculated column widths.
    403415*/
    404416
    405 void QwtDynGridLayout::layoutGrid( uint numCols,
     417void QwtDynGridLayout::layoutGrid( uint numColumns,
    406418    QVector<int>& rowHeight, QVector<int>& colWidth ) const
    407419{
    408     if ( numCols <= 0 )
     420    if ( numColumns <= 0 )
    409421        return;
    410422
     
    412424        d_data->updateLayoutCache();
    413425
    414     for ( uint index = 0;
    415         index < ( uint )d_data->itemSizeHints.count(); index++ )
    416     {
    417         const int row = index / numCols;
    418         const int col = index % numCols;
     426    for ( int index = 0; index < d_data->itemSizeHints.count(); index++ )
     427    {
     428        const int row = index / numColumns;
     429        const int col = index % numColumns;
    419430
    420431        const QSize &size = d_data->itemSizeHints[int( index )];
     
    428439
    429440/*!
    430   \return true: QwtDynGridLayout implements heightForWidth.
     441  \return true: QwtDynGridLayout implements heightForWidth().
    431442  \sa heightForWidth()
    432443*/
     
    437448
    438449/*!
    439   \return The preferred height for this layout, given the width w.
     450  \return The preferred height for this layout, given a width.
    440451  \sa hasHeightForWidth()
    441452*/
     
    445456        return 0;
    446457
    447     const uint numCols = columnsForWidth( width );
    448     uint numRows = itemCount() / numCols;
    449     if ( itemCount() % numCols )
     458    const uint numColumns = columnsForWidth( width );
     459    uint numRows = itemCount() / numColumns;
     460    if ( itemCount() % numColumns )
    450461        numRows++;
    451462
    452463    QVector<int> rowHeight( numRows );
    453     QVector<int> colWidth( numCols );
    454 
    455     layoutGrid( numCols, rowHeight, colWidth );
     464    QVector<int> colWidth( numColumns );
     465
     466    layoutGrid( numColumns, rowHeight, colWidth );
    456467
    457468    int h = 2 * margin() + ( numRows - 1 ) * spacing();
    458     for ( int row = 0; row < ( int )numRows; row++ )
     469    for ( uint row = 0; row < numRows; row++ )
    459470        h += rowHeight[row];
    460471
     
    467478  rect. Rows and columns are stretched with the same factor.
    468479
     480  \param rect Bounding rectangle
     481  \param numColumns Number of columns
     482  \param rowHeight Array to be filled with the calculated row heights
     483  \param colWidth Array to be filled with the calculated column widths
     484
    469485  \sa setExpanding(), expanding()
    470486*/
    471487void QwtDynGridLayout::stretchGrid( const QRect &rect,
    472     uint numCols, QVector<int>& rowHeight, QVector<int>& colWidth ) const
    473 {
    474     if ( numCols == 0 || isEmpty() )
     488    uint numColumns, QVector<int>& rowHeight, QVector<int>& colWidth ) const
     489{
     490    if ( numColumns == 0 || isEmpty() )
    475491        return;
    476492
     
    481497    if ( expandH )
    482498    {
    483         int xDelta = rect.width() - 2 * margin() - ( numCols - 1 ) * spacing();
    484         for ( int col = 0; col < ( int )numCols; col++ )
     499        int xDelta = rect.width() - 2 * margin() - ( numColumns - 1 ) * spacing();
     500        for ( uint col = 0; col < numColumns; col++ )
    485501            xDelta -= colWidth[col];
    486502
    487503        if ( xDelta > 0 )
    488504        {
    489             for ( int col = 0; col < ( int )numCols; col++ )
     505            for ( uint col = 0; col < numColumns; col++ )
    490506            {
    491                 const int space = xDelta / ( numCols - col );
     507                const int space = xDelta / ( numColumns - col );
    492508                colWidth[col] += space;
    493509                xDelta -= space;
     
    498514    if ( expandV )
    499515    {
    500         uint numRows = itemCount() / numCols;
    501         if ( itemCount() % numCols )
     516        uint numRows = itemCount() / numColumns;
     517        if ( itemCount() % numColumns )
    502518            numRows++;
    503519
    504520        int yDelta = rect.height() - 2 * margin() - ( numRows - 1 ) * spacing();
    505         for ( int row = 0; row < ( int )numRows; row++ )
     521        for ( uint row = 0; row < numRows; row++ )
    506522            yDelta -= rowHeight[row];
    507523
    508524        if ( yDelta > 0 )
    509525        {
    510             for ( int row = 0; row < ( int )numRows; row++ )
     526            for ( uint row = 0; row < numRows; row++ )
    511527            {
    512528                const int space = yDelta / ( numRows - row );
     
    519535
    520536/*!
    521    Return the size hint. If maxCols() > 0 it is the size for
    522    a grid with maxCols() columns, otherwise it is the size for
     537   Return the size hint. If maxColumns() > 0 it is the size for
     538   a grid with maxColumns() columns, otherwise it is the size for
    523539   a grid with only one row.
    524540
    525    \sa maxCols(), setMaxCols()
     541   \return Size hint
     542   \sa maxColumns(), setMaxColumns()
    526543*/
    527544QSize QwtDynGridLayout::sizeHint() const
     
    530547        return QSize();
    531548
    532     const uint numCols = ( d_data->maxCols > 0 ) ? d_data->maxCols : itemCount();
    533     uint numRows = itemCount() / numCols;
    534     if ( itemCount() % numCols )
     549    uint numColumns = itemCount();
     550    if ( d_data->maxColumns > 0 )
     551        numColumns = qMin( d_data->maxColumns, numColumns );
     552
     553    uint numRows = itemCount() / numColumns;
     554    if ( itemCount() % numColumns )
    535555        numRows++;
    536556
    537557    QVector<int> rowHeight( numRows );
    538     QVector<int> colWidth( numCols );
    539 
    540     layoutGrid( numCols, rowHeight, colWidth );
     558    QVector<int> colWidth( numColumns );
     559
     560    layoutGrid( numColumns, rowHeight, colWidth );
    541561
    542562    int h = 2 * margin() + ( numRows - 1 ) * spacing();
    543     for ( int row = 0; row < ( int )numRows; row++ )
     563    for ( uint row = 0; row < numRows; row++ )
    544564        h += rowHeight[row];
    545565
    546     int w = 2 * margin() + ( numCols - 1 ) * spacing();
    547     for ( int col = 0; col < ( int )numCols; col++ )
     566    int w = 2 * margin() + ( numColumns - 1 ) * spacing();
     567    for ( uint col = 0; col < numColumns; col++ )
    548568        w += colWidth[col];
    549569
     
    553573/*!
    554574  \return Number of rows of the current layout.
    555   \sa numCols()
     575  \sa numColumns()
    556576  \warning The number of rows might change whenever the geometry changes
    557577*/
     
    566586  \warning The number of columns might change whenever the geometry changes
    567587*/
    568 uint QwtDynGridLayout::numCols() const
    569 {
    570     return d_data->numCols;
    571 }
     588uint QwtDynGridLayout::numColumns() const
     589{
     590    return d_data->numColumns;
     591}
  • trunk/BNC/qwt/qwt_dyngrid_layout.h

    r4271 r8127  
    2222  QwtDynGridLayout takes the space it gets, divides it up into rows and
    2323  columns, and puts each of the widgets it manages into the correct cell(s).
    24   It lays out as many number of columns as possible (limited by maxCols()).
     24  It lays out as many number of columns as possible (limited by maxColumns()).
    2525*/
    2626
     
    3636    virtual void invalidate();
    3737
    38     void setMaxCols( uint maxCols );
    39     uint maxCols() const;
     38    void setMaxColumns( uint maxCols );
     39    uint maxColumns() const;
    4040
    4141    uint numRows () const;
    42     uint numCols () const;
     42    uint numColumns () const;
    4343
    4444    virtual void addItem( QLayoutItem * );
  • trunk/BNC/qwt/qwt_event_pattern.cpp

    r4271 r8127  
    3838void QwtEventPattern::initMousePattern( int numButtons )
    3939{
    40     const int altButton = Qt::AltModifier;
    41     const int controlButton = Qt::ControlModifier;
    42     const int shiftButton = Qt::ShiftModifier;
    43 
    4440    d_mousePattern.resize( MousePatternCount );
    4541
     
    4945        {
    5046            setMousePattern( MouseSelect1, Qt::LeftButton );
    51             setMousePattern( MouseSelect2, Qt::LeftButton, controlButton );
    52             setMousePattern( MouseSelect3, Qt::LeftButton, altButton );
     47            setMousePattern( MouseSelect2, Qt::LeftButton, Qt::ControlModifier );
     48            setMousePattern( MouseSelect3, Qt::LeftButton, Qt::AltModifier );
    5349            break;
    5450        }
     
    5753            setMousePattern( MouseSelect1, Qt::LeftButton );
    5854            setMousePattern( MouseSelect2, Qt::RightButton );
    59             setMousePattern( MouseSelect3, Qt::LeftButton, altButton );
     55            setMousePattern( MouseSelect3, Qt::LeftButton, Qt::AltModifier );
    6056            break;
    6157        }
     
    6763        }
    6864    }
    69     for ( int i = 0; i < 3; i++ )
    70     {
    71         setMousePattern( MouseSelect4 + i,
    72                          d_mousePattern[MouseSelect1 + i].button,
    73                          d_mousePattern[MouseSelect1 + i].state | shiftButton );
    74     }
     65
     66    setMousePattern( MouseSelect4, d_mousePattern[MouseSelect1].button,
     67        d_mousePattern[MouseSelect1].modifiers | Qt::ShiftModifier );
     68
     69    setMousePattern( MouseSelect5, d_mousePattern[MouseSelect2].button,
     70        d_mousePattern[MouseSelect2].modifiers | Qt::ShiftModifier );
     71
     72    setMousePattern( MouseSelect6, d_mousePattern[MouseSelect3].button,
     73        d_mousePattern[MouseSelect3].modifiers | Qt::ShiftModifier );
    7574}
    7675
     
    103102  \param pattern Index of the pattern
    104103  \param button Button
    105   \param state State
     104  \param modifiers Keyboard modifiers
    106105
    107106  \sa QMouseEvent
    108107*/
    109 void QwtEventPattern::setMousePattern( uint pattern, int button, int state )
    110 {
    111     if ( pattern < ( uint )d_mousePattern.count() )
     108void QwtEventPattern::setMousePattern( MousePatternCode pattern,
     109    Qt::MouseButton button, Qt::KeyboardModifiers modifiers )
     110{
     111    if ( pattern >= 0 && pattern < MousePatternCount )
    112112    {
    113         d_mousePattern[int( pattern )].button = button;
    114         d_mousePattern[int( pattern )].state = state;
     113        d_mousePattern[ pattern ].button = button;
     114        d_mousePattern[ pattern ].modifiers = modifiers;
    115115    }
    116116}
     
    121121  \param pattern Index of the pattern
    122122  \param key Key
    123   \param state State
     123  \param modifiers Keyboard modifiers
    124124
    125125  \sa QKeyEvent
    126126*/
    127 void QwtEventPattern::setKeyPattern( uint pattern, int key, int state )
    128 {
    129     if ( pattern < ( uint )d_keyPattern.count() )
     127void QwtEventPattern::setKeyPattern( KeyPatternCode pattern,
     128    int key, Qt::KeyboardModifiers modifiers )
     129{
     130    if ( pattern >= 0 && pattern < KeyPatternCount )
    130131    {
    131         d_keyPattern[int( pattern )].key = key;
    132         d_keyPattern[int( pattern )].state = state;
     132        d_keyPattern[ pattern ].key = key;
     133        d_keyPattern[ pattern ].modifiers = modifiers;
    133134    }
    134135}
     
    146147}
    147148
    148 //! Return mouse patterns
     149//! \return Mouse pattern
    149150const QVector<QwtEventPattern::MousePattern> &
    150151QwtEventPattern::mousePattern() const
     
    153154}
    154155
    155 //! Return key patterns
     156//! \return Key pattern
    156157const QVector<QwtEventPattern::KeyPattern> &
    157158QwtEventPattern::keyPattern() const
     
    160161}
    161162
    162 //! Return ,ouse patterns
     163//! \return Mouse pattern
    163164QVector<QwtEventPattern::MousePattern> &QwtEventPattern::mousePattern()
    164165{
     
    166167}
    167168
    168 //! Return Key patterns
     169//! \return Key pattern
    169170QVector<QwtEventPattern::KeyPattern> &QwtEventPattern::keyPattern()
    170171{
     
    179180  are set.
    180181
    181   \param pattern Index of the event pattern
     182  \param code Index of the event pattern
    182183  \param event Mouse event
    183184  \return true if matches
     
    185186  \sa keyMatch()
    186187*/
    187 bool QwtEventPattern::mouseMatch( uint pattern,
     188bool QwtEventPattern::mouseMatch( MousePatternCode code,
    188189    const QMouseEvent *event ) const
    189190{
    190     bool ok = false;
    191 
    192     if ( event && pattern < ( uint )d_mousePattern.count() )
    193         ok = mouseMatch( d_mousePattern[int( pattern )], event );
    194 
    195     return ok;
     191    if ( code >= 0 && code < MousePatternCount )
     192        return mouseMatch( d_mousePattern[ code ], event );
     193
     194    return false;
    196195}
    197196
     
    213212    const QMouseEvent *event ) const
    214213{
    215     if ( event->button() != pattern.button )
     214    if ( event == NULL )
    216215        return false;
    217216
    218     const bool matched =
    219         ( event->modifiers() & Qt::KeyboardModifierMask ) ==
    220             ( int )( pattern.state & Qt::KeyboardModifierMask );
    221 
    222     return matched;
     217    const MousePattern mousePattern( event->button(), event->modifiers() );
     218    return mousePattern == pattern;
    223219}
    224220
     
    230226  are set.
    231227
    232   \param pattern Index of the event pattern
     228  \param code Index of the event pattern
    233229  \param event Key event
    234230  \return true if matches
     
    236232  \sa mouseMatch()
    237233*/
    238 bool QwtEventPattern::keyMatch( uint pattern,
     234bool QwtEventPattern::keyMatch( KeyPatternCode code,
    239235    const QKeyEvent *event ) const
    240236{
    241     bool ok = false;
    242 
    243     if ( event && pattern < ( uint )d_keyPattern.count() )
    244         ok = keyMatch( d_keyPattern[int( pattern )], event );
    245 
    246     return ok;
     237    if ( code >= 0 && code < KeyPatternCount )
     238        return keyMatch( d_keyPattern[ code ], event );
     239
     240    return false;
    247241}
    248242
     
    264258    const KeyPattern &pattern, const QKeyEvent *event ) const
    265259{
    266     if ( event->key() != pattern.key )
     260    if ( event == NULL )
    267261        return false;
    268262
    269     const bool matched =
    270         ( event->modifiers() & Qt::KeyboardModifierMask ) ==
    271             ( int )( pattern.state & Qt::KeyboardModifierMask );
    272 
    273     return matched;
    274 }
     263    const KeyPattern keyPattern( event->key(), event->modifiers() );
     264    return keyPattern == pattern;
     265}
  • trunk/BNC/qwt/qwt_event_pattern.h

    r4271 r8127  
    3333      \brief Symbolic mouse input codes
    3434
    35       The default initialization for 3 button mice is:
    36       - MouseSelect1\n
    37         Qt::LeftButton
    38       - MouseSelect2\n
    39         Qt::RightButton
    40       - MouseSelect3\n
    41         Qt::MidButton
    42       - MouseSelect4\n
    43         Qt::LeftButton + Qt::ShiftButton
    44       - MouseSelect5\n
    45         Qt::RightButton + Qt::ShiftButton
    46       - MouseSelect6\n
    47         Qt::MidButton + Qt::ShiftButton
    48 
    49       The default initialization for 2 button mice is:
    50       - MouseSelect1\n
    51         Qt::LeftButton
    52       - MouseSelect2\n
    53         Qt::RightButton
    54       - MouseSelect3\n
    55         Qt::LeftButton + Qt::AltButton
    56       - MouseSelect4\n
    57         Qt::LeftButton + Qt::ShiftButton
    58       - MouseSelect5\n
    59         Qt::RightButton + Qt::ShiftButton
    60       - MouseSelect6\n
    61         Qt::LeftButton + Qt::AltButton + Qt::ShiftButton
    62 
    63       The default initialization for 1 button mice is:
    64       - MouseSelect1\n
    65         Qt::LeftButton
    66       - MouseSelect2\n
    67         Qt::LeftButton + Qt::ControlButton
    68       - MouseSelect3\n
    69         Qt::LeftButton + Qt::AltButton
    70       - MouseSelect4\n
    71         Qt::LeftButton + Qt::ShiftButton
    72       - MouseSelect5\n
    73         Qt::LeftButton + Qt::ControlButton + Qt::ShiftButton
    74       - MouseSelect6\n
    75         Qt::LeftButton + Qt::AltButton + Qt::ShiftButton
    76 
    77       \sa initMousePattern()
     35      QwtEventPattern implements 3 different settings for
     36      mice with 1, 2, or 3 buttons that can be activated
     37      using initMousePattern(). The default setting is for
     38      3 button mice.
     39
     40      Individual settings can be configured using setMousePattern().
     41
     42      \sa initMousePattern(), setMousePattern(), setKeyPattern()
    7843    */
    79 
    8044    enum MousePatternCode
    8145    {
     46        /*!
     47          The default setting for 1, 2 and 3 button mice is:
     48
     49          - Qt::LeftButton
     50          - Qt::LeftButton
     51          - Qt::LeftButton
     52         */
    8253        MouseSelect1,
     54
     55        /*!
     56          The default setting for 1, 2 and 3 button mice is:
     57
     58          - Qt::LeftButton + Qt::ControlModifier
     59          - Qt::RightButton
     60          - Qt::RightButton
     61         */
    8362        MouseSelect2,
     63
     64        /*!
     65          The default setting for 1, 2 and 3 button mice is:
     66
     67          - Qt::LeftButton + Qt::AltModifier
     68          - Qt::LeftButton + Qt::AltModifier
     69          - Qt::MidButton
     70         */
    8471        MouseSelect3,
     72
     73        /*!
     74          The default setting for 1, 2 and 3 button mice is:
     75
     76          - Qt::LeftButton + Qt::ShiftModifier
     77          - Qt::LeftButton + Qt::ShiftModifier
     78          - Qt::LeftButton + Qt::ShiftModifier
     79         */
    8580        MouseSelect4,
     81
     82        /*!
     83          The default setting for 1, 2 and 3 button mice is:
     84
     85          - Qt::LeftButton + Qt::ControlButton | Qt::ShiftModifier
     86          - Qt::RightButton + Qt::ShiftModifier
     87          - Qt::RightButton + Qt::ShiftModifier
     88         */
    8689        MouseSelect5,
     90
     91        /*!
     92          The default setting for 1, 2 and 3 button mice is:
     93
     94          - Qt::LeftButton + Qt::AltModifier + Qt::ShiftModifier
     95          - Qt::LeftButton + Qt::AltModifier | Qt::ShiftModifier
     96          - Qt::MidButton + Qt::ShiftModifier
     97         */
    8798        MouseSelect6,
    8899
     100        //! Number of mouse patterns
    89101        MousePatternCount
    90102    };
     
    93105      \brief Symbolic keyboard input codes
    94106
    95       Default initialization:
    96       - KeySelect1\n
    97         Qt::Key_Return
    98       - KeySelect2\n
    99         Qt::Key_Space
    100       - KeyAbort\n
    101         Qt::Key_Escape
    102 
    103       - KeyLeft\n
    104         Qt::Key_Left
    105       - KeyRight\n
    106         Qt::Key_Right
    107       - KeyUp\n
    108         Qt::Key_Up
    109       - KeyDown\n
    110         Qt::Key_Down
    111 
    112       - KeyUndo\n
    113         Qt::Key_Minus
    114       - KeyRedo\n
    115         Qt::Key_Plus
    116       - KeyHome\n
    117         Qt::Key_Escape
     107      Individual settings can be configured using setKeyPattern()
     108
     109      \sa setKeyPattern(), setMousePattern()
    118110    */
    119111    enum KeyPatternCode
    120112    {
     113        //! Qt::Key_Return
    121114        KeySelect1,
     115
     116        //! Qt::Key_Space
    122117        KeySelect2,
     118
     119        //! Qt::Key_Escape
    123120        KeyAbort,
    124121
     122        //! Qt::Key_Left
    125123        KeyLeft,
     124
     125        //! Qt::Key_Right
    126126        KeyRight,
     127
     128        //! Qt::Key_Up
    127129        KeyUp,
     130
     131        //! Qt::Key_Down
    128132        KeyDown,
    129133
     134        //! Qt::Key_Plus
    130135        KeyRedo,
     136
     137        //! Qt::Key_Minus
    131138        KeyUndo,
     139
     140        //! Qt::Key_Escape
    132141        KeyHome,
    133142
     143        //! Number of key patterns
    134144        KeyPatternCount
    135145    };
     
    140150    public:
    141151        //! Constructor
    142         MousePattern( int btn = Qt::NoButton, int st = Qt::NoButton )
     152        MousePattern( Qt::MouseButton btn = Qt::NoButton,
     153                Qt::KeyboardModifiers modifierCodes = Qt::NoModifier ):
     154            button( btn ),
     155            modifiers( modifierCodes )
    143156        {
    144             button = btn;
    145             state = st;
    146157        }
    147158
    148         //! Button code
    149         int button;
    150 
    151         //! State
    152         int state;
     159        //! Button
     160        Qt::MouseButton button;
     161
     162        //! Keyboard modifier
     163        Qt::KeyboardModifiers modifiers;
    153164    };
    154165
     
    158169    public:
    159170        //! Constructor
    160         KeyPattern( int k = 0, int st = Qt::NoButton )
     171        KeyPattern( int keyCode = Qt::Key_unknown,
     172                Qt::KeyboardModifiers modifierCodes = Qt::NoModifier ):
     173            key( keyCode ),
     174            modifiers( modifierCodes )
    161175        {
    162             key = k;
    163             state = st;
    164176        }
    165177
     
    167179        int key;
    168180
    169         //! State
    170         int state;
     181        //! Modifiers
     182        Qt::KeyboardModifiers modifiers;
    171183    };
    172184
     
    177189    void initKeyPattern();
    178190
    179     void setMousePattern( uint pattern, int button, int state = Qt::NoButton );
    180     void setKeyPattern( uint pattern, int key, int state = Qt::NoButton );
     191    void setMousePattern( MousePatternCode, Qt::MouseButton button,
     192        Qt::KeyboardModifiers = Qt::NoModifier );
     193
     194    void setKeyPattern( KeyPatternCode, int keyCode,
     195        Qt::KeyboardModifiers modifierCodes = Qt::NoModifier );
    181196
    182197    void setMousePattern( const QVector<MousePattern> & );
     
    189204    QVector<KeyPattern> &keyPattern();
    190205
    191     bool mouseMatch( uint pattern, const QMouseEvent * ) const;
    192     bool keyMatch( uint pattern, const QKeyEvent * ) const;
     206    bool mouseMatch( MousePatternCode, const QMouseEvent * ) const;
     207    bool keyMatch( KeyPatternCode, const QKeyEvent * ) const;
    193208
    194209protected:
     
    213228    QwtEventPattern::MousePattern  b2 )
    214229{
    215     return b1.button == b2.button && b1.state == b2.state;
     230    return b1.button == b2.button && b1.modifiers == b2.modifiers;
    216231}
    217232
     
    220235   QwtEventPattern::KeyPattern  b2 )
    221236{
    222     return b1.key == b2.key && b1.state == b2.state;
     237    return b1.key == b2.key && b1.modifiers == b2.modifiers;
    223238}
    224239
  • trunk/BNC/qwt/qwt_global.h

    r4271 r8127  
    1515// QWT_VERSION is (major << 16) + (minor << 8) + patch.
    1616
    17 #define QWT_VERSION       0x060001
    18 #define QWT_VERSION_STR   "6.0.1"
    19 
    20 #if defined(Q_WS_WIN) || defined(Q_WS_S60)
     17#define QWT_VERSION       0x060104
     18#define QWT_VERSION_STR   "6.1.4"
    2119
    2220#if defined(_MSC_VER) /* MSVC Compiler */
    2321/* template-class specialization 'identifier' is already instantiated */
    2422#pragma warning(disable: 4660)
     23/* inherits via dominance */
     24#pragma warning(disable: 4250)
    2525#endif // _MSC_VER
    2626
     
    2828
    2929#if defined(QWT_MAKEDLL)     // create a Qwt DLL library
    30 #define QWT_EXPORT  __declspec(dllexport)
    31 #define QWT_TEMPLATEDLL
     30#define QWT_EXPORT Q_DECL_EXPORT
    3231#else                        // use a Qwt DLL library
    33 #define QWT_EXPORT  __declspec(dllimport)
     32#define QWT_EXPORT Q_DECL_IMPORT
    3433#endif
    3534
    3635#endif // QWT_DLL
    37 
    38 #endif // Q_WS_WIN || Q_WS_S60
    3936
    4037#ifndef QWT_EXPORT
     
    4239#endif
    4340
    44 // #define QWT_NO_COMPAT 1 // disable withdrawn functionality
    45 
    4641#endif
  • trunk/BNC/qwt/qwt_interval.cpp

    r4271 r8127  
    1313
    1414/*!
    15    \brief Normalize the limits of the interval
    16 
    17    If maxValue() < minValue() the limits will be inverted.
    18    \return Normalized interval
    19 
    20    \sa isValid(), inverted()
     15  \brief Normalize the limits of the interval
     16
     17  If maxValue() < minValue() the limits will be inverted.
     18  \return Normalized interval
     19
     20  \sa isValid(), inverted()
    2121*/
    2222QwtInterval QwtInterval::normalized() const
     
    3535
    3636/*!
    37    Invert the limits of the interval
    38    \return Inverted interval
    39    \sa normalized()
     37  Invert the limits of the interval
     38  \return Inverted interval
     39  \sa normalized()
    4040*/
    4141QwtInterval QwtInterval::inverted() const
     
    131131}
    132132
    133 //! Intersect 2 intervals
     133/*!
     134  \brief Intersect 2 intervals
     135 
     136  \param other Interval to be intersect with
     137  \return Intersection
     138 */
    134139QwtInterval QwtInterval::intersect( const QwtInterval &other ) const
    135140{
     
    193198}
    194199
    195 //! Unites this interval with the given interval.
    196 QwtInterval& QwtInterval::operator|=( const QwtInterval & interval )
    197 {
    198     *this = *this | interval;
     200/*!
     201  \brief Unite this interval with the given interval.
     202
     203  \param other Interval to be united with
     204  \return This interval
     205 */
     206QwtInterval& QwtInterval::operator|=( const QwtInterval &other )
     207{
     208    *this = *this | other;
    199209    return *this;
    200210}
    201211
    202 //! Intersects this interval with the given interval.
    203 QwtInterval& QwtInterval::operator&=( const QwtInterval & interval )
    204 {
    205     *this = *this & interval;
     212/*!
     213  \brief Intersect this interval with the given interval.
     214
     215  \param other Interval to be intersected with
     216  \return This interval
     217 */
     218QwtInterval& QwtInterval::operator&=( const QwtInterval &other )
     219{
     220    *this = *this & other;
    206221    return *this;
    207222}
    208223
    209224/*!
    210    Test if two intervals overlap
     225  \brief Test if two intervals overlap
     226
     227  \param other Interval
     228  \return True, when the intervals are intersecting
    211229*/
    212230bool QwtInterval::intersects( const QwtInterval &other ) const
     
    244262
    245263/*!
    246    Adjust the limit that is closer to value, so that value becomes
    247    the center of the interval.
    248 
    249    \param value Center
    250    \return Interval with value as center
     264  Adjust the limit that is closer to value, so that value becomes
     265  the center of the interval.
     266
     267  \param value Center
     268  \return Interval with value as center
    251269*/
    252270QwtInterval QwtInterval::symmetrize( double value ) const
     
    262280
    263281/*!
    264    Limit the interval, keeping the border modes
    265 
    266    \param lowerBound Lower limit
    267    \param upperBound Upper limit
    268 
    269    \return Limited interval
     282  Limit the interval, keeping the border modes
     283
     284  \param lowerBound Lower limit
     285  \param upperBound Upper limit
     286
     287  \return Limited interval
    270288*/
    271289QwtInterval QwtInterval::limited( double lowerBound, double upperBound ) const
     
    284302
    285303/*!
    286    Extend the interval
    287 
    288    If value is below minValue, value becomes the lower limit.
    289    If value is above maxValue, value becomes the upper limit.
    290 
    291    extend has no effect for invalid intervals
    292 
    293    \param value Value
    294    \sa isValid()
     304  \brief Extend the interval
     305
     306  If value is below minValue(), value becomes the lower limit.
     307  If value is above maxValue(), value becomes the upper limit.
     308
     309  extend() has no effect for invalid intervals
     310
     311  \param value Value
     312  \return extended interval
     313
     314  \sa isValid()
    295315*/
    296316QwtInterval QwtInterval::extend( double value ) const
     
    304324
    305325/*!
    306    Extend an interval
    307 
    308    \param value Value
    309    \return Reference of the extended interval
    310 
    311    \sa extend()
     326  Extend an interval
     327
     328  \param value Value
     329  \return Reference of the extended interval
     330
     331  \sa extend()
    312332*/
    313333QwtInterval& QwtInterval::operator|=( double value )
  • trunk/BNC/qwt/qwt_interval.h

    r4271 r8127  
    1212
    1313#include "qwt_global.h"
     14#include <qmetatype.h>
     15
    1416#ifndef QT_NO_DEBUG_STREAM
    1517#include <qdebug.h>
     
    200202
    201203/*!
    202    Return the width of an interval
    203    The width of invalid intervals is 0.0, otherwise the result is
    204    maxValue() - minValue().
    205 
    206    \sa isValid()
    207 */
    208 inline double QwtInterval::width() const
    209 {
    210     return isValid() ? ( d_maxValue - d_minValue ) : 0.0;
    211 }
    212 
    213 /*!
    214    Intersection of two intervals
    215    \sa intersect()
    216 */
    217 inline QwtInterval QwtInterval::operator&(
    218     const QwtInterval &interval ) const
    219 {
    220     return intersect( interval );
    221 }
    222 
    223 /*!
    224    Union of two intervals
    225    \sa unite()
    226 */
    227 inline QwtInterval QwtInterval::operator|(
    228     const QwtInterval &interval ) const
    229 {
    230     return unite( interval );
    231 }
    232 
    233 //! Compare two intervals
    234 inline bool QwtInterval::operator==( const QwtInterval &other ) const
    235 {
    236     return ( d_minValue == other.d_minValue ) &&
    237            ( d_maxValue == other.d_maxValue ) &&
    238            ( d_borderFlags == other.d_borderFlags );
    239 }
    240 
    241 //! Compare two intervals
    242 inline bool QwtInterval::operator!=( const QwtInterval &other ) const
    243 {
    244     return ( !( *this == other ) );
    245 }
    246 
    247 /*!
    248    Extend an interval
    249 
    250    \param value Value
    251    \return Extended interval
    252    \sa extend()
    253 */
    254 inline QwtInterval QwtInterval::operator|( double value ) const
    255 {
    256     return extend( value );
    257 }
    258 
    259 //! \return true, if isValid() && (minValue() >= maxValue())
    260 inline bool QwtInterval::isNull() const
    261 {
    262     return isValid() && d_minValue >= d_maxValue;
    263 }
    264 
    265 /*!
    266204   A interval is valid when minValue() <= maxValue().
    267205   In case of QwtInterval::ExcludeBorders it is true
    268206   when minValue() < maxValue()
     207
     208   \return True, when the interval is valid
    269209*/
    270210inline bool QwtInterval::isValid() const
     
    277217
    278218/*!
     219   \brief Return the width of an interval
     220
     221   The width of invalid intervals is 0.0, otherwise the result is
     222   maxValue() - minValue().
     223
     224   \return Interval width
     225   \sa isValid()
     226*/
     227inline double QwtInterval::width() const
     228{
     229    return isValid() ? ( d_maxValue - d_minValue ) : 0.0;
     230}
     231
     232/*!
     233   \brief Intersection of two intervals
     234 
     235   \param other Interval to intersect with
     236   \return Intersection of this and other
     237
     238   \sa intersect()
     239*/
     240inline QwtInterval QwtInterval::operator&(
     241    const QwtInterval &other ) const
     242{
     243    return intersect( other );
     244}
     245
     246/*!
     247   Union of two intervals
     248
     249   \param other Interval to unite with
     250   \return Union of this and other
     251
     252   \sa unite()
     253*/
     254inline QwtInterval QwtInterval::operator|(
     255    const QwtInterval &other ) const
     256{
     257    return unite( other );
     258}
     259
     260/*!
     261   \brief Compare two intervals
     262
     263   \param other Interval to compare with
     264   \return True, when this and other are equal
     265*/
     266inline bool QwtInterval::operator==( const QwtInterval &other ) const
     267{
     268    return ( d_minValue == other.d_minValue ) &&
     269           ( d_maxValue == other.d_maxValue ) &&
     270           ( d_borderFlags == other.d_borderFlags );
     271}
     272/*!
     273   \brief Compare two intervals
     274
     275   \param other Interval to compare with
     276   \return True, when this and other are not equal
     277*/
     278inline bool QwtInterval::operator!=( const QwtInterval &other ) const
     279{
     280    return ( !( *this == other ) );
     281}
     282
     283/*!
     284   Extend an interval
     285
     286   \param value Value
     287   \return Extended interval
     288   \sa extend()
     289*/
     290inline QwtInterval QwtInterval::operator|( double value ) const
     291{
     292    return extend( value );
     293}
     294
     295//! \return true, if isValid() && (minValue() >= maxValue())
     296inline bool QwtInterval::isNull() const
     297{
     298    return isValid() && d_minValue >= d_maxValue;
     299}
     300
     301/*!
    279302  Invalidate the interval
    280303
     
    289312
    290313Q_DECLARE_OPERATORS_FOR_FLAGS( QwtInterval::BorderFlags )
     314Q_DECLARE_METATYPE( QwtInterval )
    291315
    292316#ifndef QT_NO_DEBUG_STREAM
  • trunk/BNC/qwt/qwt_interval_symbol.cpp

    r4271 r8127  
    1515#if QT_VERSION < 0x040601
    1616#define qAtan2(y, x) ::atan2(y, x)
     17#define qFastSin(x) qSin(x)
     18#define qFastCos(x) qCos(x)
    1719#endif
    1820
     
    149151{
    150152    return d_data->brush;
     153}
     154
     155/*!
     156  Build and assign a pen
     157   
     158  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     159  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     160  to hide this incompatibility.
     161
     162  \param color Pen color
     163  \param width Pen width
     164  \param style Pen style
     165   
     166  \sa pen(), brush()
     167 */
     168void QwtIntervalSymbol::setPen( const QColor &color,
     169    qreal width, Qt::PenStyle style )
     170{   
     171    setPen( QPen( color, width, style ) );
    151172}
    152173
     
    232253                    double dw2 = sw / 2.0;
    233254
    234                     const double cx = qCos( angle ) * dw2;
    235                     const double sy = qSin( angle ) * dw2;
     255                    const double cx = qFastCos( angle ) * dw2;
     256                    const double sy = qFastSin( angle ) * dw2;
    236257
    237258                    QwtPainter::drawLine( painter,
     
    280301                    double dw2 = sw / 2.0;
    281302
    282                     const int cx = qCos( angle ) * dw2;
    283                     const int sy = qSin( angle ) * dw2;
     303                    const double cx = qFastCos( angle ) * dw2;
     304                    const double sy = qFastSin( angle ) * dw2;
    284305
    285306                    QPolygonF polygon;
  • trunk/BNC/qwt/qwt_interval_symbol.h

    r4271 r8127  
    6969    const QBrush& brush() const;
    7070
     71    void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
    7172    void setPen( const QPen & );
    7273    const QPen& pen() const;
  • trunk/BNC/qwt/qwt_legend.cpp

    r4271 r8127  
    99
    1010#include "qwt_legend.h"
    11 #include "qwt_legend_itemmanager.h"
    12 #include "qwt_legend_item.h"
     11#include "qwt_legend_label.h"
    1312#include "qwt_dyngrid_layout.h"
    1413#include "qwt_math.h"
     14#include "qwt_plot_item.h"
     15#include "qwt_painter.h"
    1516#include <qapplication.h>
    16 #include <qmap.h>
    1717#include <qscrollbar.h>
    1818#include <qscrollarea.h>
     19#include <qpainter.h>
     20#include <qstyle.h>
     21#include <qstyleoption.h>
     22
     23class QwtLegendMap
     24{
     25public:
     26    inline bool isEmpty() const { return d_entries.isEmpty(); }
     27
     28    void insert( const QVariant &, const QList<QWidget *> & );
     29    void remove( const QVariant & );
     30
     31    void removeWidget( const QWidget * );
     32
     33    QList<QWidget *> legendWidgets( const QVariant & ) const;
     34    QVariant itemInfo( const QWidget * ) const;
     35
     36private:
     37    // we don't know anything about itemInfo and therefore don't have
     38    // any key that can be used for a map or hashtab.
     39    // But a simple linear list is o.k. here, as we will never have
     40    // more than a few entries.
     41
     42    class Entry
     43    {
     44    public:
     45        QVariant itemInfo;
     46        QList<QWidget *> widgets;
     47    };
     48
     49    QList< Entry > d_entries;
     50};
     51
     52void QwtLegendMap::insert( const QVariant &itemInfo,
     53    const QList<QWidget *> &widgets )
     54{
     55    for ( int i = 0; i < d_entries.size(); i++ )
     56    {
     57        Entry &entry = d_entries[i];
     58        if ( entry.itemInfo == itemInfo )
     59        {
     60            entry.widgets = widgets;
     61            return;
     62        }
     63    }
     64
     65    Entry newEntry;
     66    newEntry.itemInfo = itemInfo;
     67    newEntry.widgets = widgets;
     68
     69    d_entries += newEntry;
     70}
     71
     72void QwtLegendMap::remove( const QVariant &itemInfo )
     73{
     74    for ( int i = 0; i < d_entries.size(); i++ )
     75    {
     76        Entry &entry = d_entries[i];
     77        if ( entry.itemInfo == itemInfo )
     78        {
     79            d_entries.removeAt( i );
     80            return;
     81        }
     82    }
     83}
     84
     85void QwtLegendMap::removeWidget( const QWidget *widget )
     86{
     87    QWidget *w = const_cast<QWidget *>( widget );
     88
     89    for ( int i = 0; i < d_entries.size(); i++ )
     90        d_entries[ i ].widgets.removeAll( w );
     91}
     92
     93QVariant QwtLegendMap::itemInfo( const QWidget *widget ) const
     94{
     95    if ( widget != NULL )
     96    {
     97        QWidget *w = const_cast<QWidget *>( widget );
     98
     99        for ( int i = 0; i < d_entries.size(); i++ )
     100        {
     101            const Entry &entry = d_entries[i];
     102            if ( entry.widgets.indexOf( w ) >= 0 )
     103                return entry.itemInfo;
     104        }
     105    }
     106
     107    return QVariant();
     108}
     109
     110QList<QWidget *> QwtLegendMap::legendWidgets( const QVariant &itemInfo ) const
     111{
     112    if ( itemInfo.isValid() )
     113    {
     114        for ( int i = 0; i < d_entries.size(); i++ )
     115        {
     116            const Entry &entry = d_entries[i];
     117            if ( entry.itemInfo == itemInfo )
     118                return entry.widgets;
     119        }
     120    }
     121
     122    return QList<QWidget *>();
     123}
    19124
    20125class QwtLegend::PrivateData
    21126{
    22127public:
    23     class LegendMap
    24     {
    25     public:
    26         void insert( const QwtLegendItemManager *, QWidget * );
    27 
    28         void remove( const QwtLegendItemManager * );
    29         void remove( QWidget * );
    30 
    31         void clear();
    32 
    33         uint count() const;
    34 
    35         inline const QWidget *find( const QwtLegendItemManager * ) const;
    36         inline QWidget *find( const QwtLegendItemManager * );
    37 
    38         inline const QwtLegendItemManager *find( const QWidget * ) const;
    39         inline QwtLegendItemManager *find( const QWidget * );
    40 
    41         const QMap<QWidget *, const QwtLegendItemManager *> &widgetMap() const;
    42         QMap<QWidget *, const QwtLegendItemManager *> &widgetMap();
    43 
    44     private:
    45         QMap<QWidget *, const QwtLegendItemManager *> d_widgetMap;
    46         QMap<const QwtLegendItemManager *, QWidget *> d_itemMap;
    47     };
    48 
    49     QwtLegend::LegendItemMode itemMode;
    50 
    51     LegendMap map;
     128    PrivateData():
     129        itemMode( QwtLegendData::ReadOnly ),
     130        view( NULL )
     131    {
     132    }
     133
     134    QwtLegendData::Mode itemMode;
     135    QwtLegendMap itemMap;
    52136
    53137    class LegendView;
     
    61145        QScrollArea( parent )
    62146    {
    63         setFocusPolicy( Qt::NoFocus );
    64 
    65147        contentsWidget = new QWidget( this );
    66148        contentsWidget->setObjectName( "QwtLegendViewContents" );
     
    77159    }
    78160
    79     virtual bool viewportEvent( QEvent *e )
    80     {
    81         bool ok = QScrollArea::viewportEvent( e );
    82 
    83         if ( e->type() == QEvent::Resize )
    84         {
    85             QEvent event( QEvent::LayoutRequest );
    86             QApplication::sendEvent( contentsWidget, &event );
     161    virtual bool event( QEvent *event )
     162    {
     163        if ( event->type() == QEvent::PolishRequest )
     164        {
     165            setFocusPolicy( Qt::NoFocus );
     166        }
     167
     168        if ( event->type() == QEvent::Resize )
     169        {
     170            // adjust the size to en/disable the scrollbars
     171            // before QScrollArea adjusts the viewport size
     172
     173            const QRect cr = contentsRect();
     174
     175            int w = cr.width();
     176            int h = contentsWidget->heightForWidth( cr.width() );
     177            if ( h > w )
     178            {
     179                w -= verticalScrollBar()->sizeHint().width();
     180                h = contentsWidget->heightForWidth( w );
     181            }
     182
     183            contentsWidget->resize( w, h );
     184        }
     185
     186        return QScrollArea::event( event );
     187    }
     188
     189    virtual bool viewportEvent( QEvent *event )
     190    {
     191        bool ok = QScrollArea::viewportEvent( event );
     192
     193        if ( event->type() == QEvent::Resize )
     194        {
     195            layoutContents();
    87196        }
    88197        return ok;
     
    112221    }
    113222
     223    void layoutContents()
     224    {
     225        const QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>(
     226            contentsWidget->layout() );
     227        if ( tl == NULL )
     228            return;
     229
     230        const QSize visibleSize = viewport()->contentsRect().size();
     231
     232        const int minW = int( tl->maxItemWidth() ) + 2 * tl->margin();
     233
     234        int w = qMax( visibleSize.width(), minW );
     235        int h = qMax( tl->heightForWidth( w ), visibleSize.height() );
     236
     237        const int vpWidth = viewportSize( w, h ).width();
     238        if ( w > vpWidth )
     239        {
     240            w = qMax( vpWidth, minW );
     241            h = qMax( tl->heightForWidth( w ), visibleSize.height() );
     242        }
     243
     244        contentsWidget->resize( w, h );
     245    }
     246
    114247    QWidget *contentsWidget;
    115248};
    116249
    117 void QwtLegend::PrivateData::LegendMap::insert(
    118     const QwtLegendItemManager *item, QWidget *widget )
    119 {
    120     d_itemMap.insert( item, widget );
    121     d_widgetMap.insert( widget, item );
    122 }
    123 
    124 void QwtLegend::PrivateData::LegendMap::remove( const QwtLegendItemManager *item )
    125 {
    126     QWidget *widget = d_itemMap[item];
    127     d_itemMap.remove( item );
    128     d_widgetMap.remove( widget );
    129 }
    130 
    131 void QwtLegend::PrivateData::LegendMap::remove( QWidget *widget )
    132 {
    133     const QwtLegendItemManager *item = d_widgetMap[widget];
    134     d_itemMap.remove( item );
    135     d_widgetMap.remove( widget );
    136 }
    137 
    138 void QwtLegend::PrivateData::LegendMap::clear()
    139 {
    140 
    141     /*
    142        We can't delete the widgets in the following loop, because
    143        we would get ChildRemoved events, changing d_itemMap, while
    144        we are iterating.
    145      */
    146 
    147     QList<const QWidget *> widgets;
    148 
    149     QMap<const QwtLegendItemManager *, QWidget *>::const_iterator it;
    150     for ( it = d_itemMap.begin(); it != d_itemMap.end(); ++it )
    151         widgets.append( it.value() );
    152 
    153     d_itemMap.clear();
    154     d_widgetMap.clear();
    155 
    156     for ( int i = 0; i < widgets.size(); i++ )
    157         delete widgets[i];
    158 }
    159 
    160 uint QwtLegend::PrivateData::LegendMap::count() const
    161 {
    162     return d_itemMap.count();
    163 }
    164 
    165 inline const QWidget *QwtLegend::PrivateData::LegendMap::find(
    166     const QwtLegendItemManager *item ) const
    167 {
    168     if ( !d_itemMap.contains( item ) )
    169         return NULL;
    170 
    171     return d_itemMap[item];
    172 }
    173 
    174 inline QWidget *QwtLegend::PrivateData::LegendMap::find(
    175     const QwtLegendItemManager *item )
    176 {
    177     if ( !d_itemMap.contains( item ) )
    178         return NULL;
    179 
    180     return d_itemMap[item];
    181 }
    182 
    183 inline const QwtLegendItemManager *QwtLegend::PrivateData::LegendMap::find(
    184     const QWidget *widget ) const
    185 {
    186     QWidget *w = const_cast<QWidget *>( widget );
    187     if ( !d_widgetMap.contains( w ) )
    188         return NULL;
    189 
    190     return d_widgetMap[w];
    191 }
    192 
    193 inline QwtLegendItemManager *QwtLegend::PrivateData::LegendMap::find(
    194     const QWidget *widget )
    195 {
    196     QWidget *w = const_cast<QWidget *>( widget );
    197     if ( !d_widgetMap.contains( w ) )
    198         return NULL;
    199 
    200     return const_cast<QwtLegendItemManager *>( d_widgetMap[w] );
    201 }
    202 
    203 inline const QMap<QWidget *, const QwtLegendItemManager *> &
    204 QwtLegend::PrivateData::LegendMap::widgetMap() const
    205 {
    206     return d_widgetMap;
    207 }
    208 
    209 inline QMap<QWidget *, const QwtLegendItemManager *> &
    210 QwtLegend::PrivateData::LegendMap::widgetMap()
    211 {
    212     return d_widgetMap;
    213 }
    214 
    215250/*!
    216251  Constructor
    217 
    218252  \param parent Parent widget
    219253*/
    220254QwtLegend::QwtLegend( QWidget *parent ):
    221     QFrame( parent )
     255    QwtAbstractLegend( parent )
    222256{
    223257    setFrameStyle( NoFrame );
    224258
    225259    d_data = new QwtLegend::PrivateData;
    226     d_data->itemMode = QwtLegend::ReadOnlyItem;
    227260
    228261    d_data->view = new QwtLegend::PrivateData::LegendView( this );
     
    247280}
    248281
    249 //! \sa LegendItemMode
    250 void QwtLegend::setItemMode( LegendItemMode mode )
     282/*!
     283  \brief Set the maximum number of entries in a row
     284
     285  F.e when the maximum is set to 1 all items are aligned
     286  vertically. 0 means unlimited
     287
     288  \param numColums Maximum number of entries in a row
     289
     290  \sa maxColumns(), QwtDynGridLayout::setMaxColumns()
     291 */
     292void QwtLegend::setMaxColumns( uint numColums )
     293{
     294    QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>(
     295        d_data->view->contentsWidget->layout() );
     296    if ( tl )
     297        tl->setMaxColumns( numColums );
     298}
     299
     300/*!
     301  \return Maximum number of entries in a row
     302  \sa setMaxColumns(), QwtDynGridLayout::maxColumns()
     303 */
     304uint QwtLegend::maxColumns() const
     305{
     306    uint maxCols = 0;
     307
     308    const QwtDynGridLayout *tl = qobject_cast<const QwtDynGridLayout *>(
     309        d_data->view->contentsWidget->layout() );
     310    if ( tl )
     311        maxCols = tl->maxColumns();
     312
     313    return maxCols;
     314}
     315
     316/*!
     317  \brief Set the default mode for legend labels
     318
     319  Legend labels will be constructed according to the
     320  attributes in a QwtLegendData object. When it doesn't
     321  contain a value for the QwtLegendData::ModeRole the
     322  label will be initialized with the default mode of the legend.
     323
     324  \param mode Default item mode
     325
     326  \sa itemMode(), QwtLegendData::value(), QwtPlotItem::legendData()
     327  \note Changing the mode doesn't have any effect on existing labels.
     328 */
     329void QwtLegend::setDefaultItemMode( QwtLegendData::Mode mode )
    251330{
    252331    d_data->itemMode = mode;
    253332}
    254333
    255 //! \sa LegendItemMode
    256 QwtLegend::LegendItemMode QwtLegend::itemMode() const
     334/*!
     335  \return Default item mode
     336  \sa setDefaultItemMode()
     337*/
     338QwtLegendData::Mode QwtLegend::defaultItemMode() const
    257339{
    258340    return d_data->itemMode;
     
    261343/*!
    262344  The contents widget is the only child of the viewport of
    263   the internal QScrollArea  and the parent widget of all legend items.
     345  the internal QScrollArea and the parent widget of all legend items.
    264346
    265347  \return Container widget of the legend items
     
    290372/*!
    291373  The contents widget is the only child of the viewport of
    292   the internal QScrollArea  and the parent widget of all legend items.
     374  the internal QScrollArea and the parent widget of all legend items.
    293375
    294376  \return Container widget of the legend items
     
    301383
    302384/*!
    303   Insert a new item for a plot item
    304   \param plotItem Plot item
    305   \param legendItem New legend item
    306   \note The parent of item will be changed to contentsWidget()
    307 */
    308 void QwtLegend::insert( const QwtLegendItemManager *plotItem, QWidget *legendItem )
    309 {
    310     if ( legendItem == NULL || plotItem == NULL )
    311         return;
    312 
    313     QWidget *contentsWidget = d_data->view->contentsWidget;
    314 
    315     if ( legendItem->parent() != contentsWidget )
    316         legendItem->setParent( contentsWidget );
    317 
    318     legendItem->show();
    319 
    320     d_data->map.insert( plotItem, legendItem );
    321 
    322     layoutContents();
    323 
    324     if ( contentsWidget->layout() )
    325     {
    326         contentsWidget->layout()->addWidget( legendItem );
    327 
     385  \brief Update the entries for an item
     386
     387  \param itemInfo Info for an item
     388  \param data List of legend entry attributes for the item
     389 */
     390void QwtLegend::updateLegend( const QVariant &itemInfo,
     391    const QList<QwtLegendData> &data )
     392{
     393    QList<QWidget *> widgetList = legendWidgets( itemInfo );
     394
     395    if ( widgetList.size() != data.size() )
     396    {
     397        QLayout *contentsLayout = d_data->view->contentsWidget->layout();
     398
     399        while ( widgetList.size() > data.size() )
     400        {
     401            QWidget *w = widgetList.takeLast();
     402
     403            contentsLayout->removeWidget( w );
     404
     405            // updates might be triggered by signals from the legend widget
     406            // itself. So we better don't delete it here.
     407
     408            w->hide();
     409            w->deleteLater();
     410        }
     411
     412        for ( int i = widgetList.size(); i < data.size(); i++ )
     413        {
     414            QWidget *widget = createWidget( data[i] );
     415
     416            if ( contentsLayout )
     417                contentsLayout->addWidget( widget );
     418
     419            if ( isVisible() )
     420            {
     421                // QLayout does a delayed show, with the effect, that
     422                // the size hint will be wrong, when applications
     423                // call replot() right after changing the list
     424                // of plot items. So we better do the show now.
     425
     426                widget->setVisible( true );
     427            }
     428
     429            widgetList += widget;
     430        }
     431
     432        if ( widgetList.isEmpty() )
     433        {
     434            d_data->itemMap.remove( itemInfo );
     435        }
     436        else
     437        {
     438            d_data->itemMap.insert( itemInfo, widgetList );
     439        }
     440
     441        updateTabOrder();
     442    }
     443   
     444    for ( int i = 0; i < data.size(); i++ )
     445        updateWidget( widgetList[i], data[i] );
     446}
     447
     448/*!
     449  \brief Create a widget to be inserted into the legend
     450
     451  The default implementation returns a QwtLegendLabel.
     452
     453  \param data Attributes of the legend entry
     454  \return Widget representing data on the legend
     455 
     456  \note updateWidget() will called soon after createWidget()
     457        with the same attributes.
     458 */
     459QWidget *QwtLegend::createWidget( const QwtLegendData &data ) const
     460{
     461    Q_UNUSED( data );
     462
     463    QwtLegendLabel *label = new QwtLegendLabel();
     464    label->setItemMode( defaultItemMode() );
     465
     466    connect( label, SIGNAL( clicked() ), SLOT( itemClicked() ) );
     467    connect( label, SIGNAL( checked( bool ) ), SLOT( itemChecked( bool ) ) );
     468
     469    return label;
     470}
     471
     472/*!
     473  \brief Update the widget
     474
     475  \param widget Usually a QwtLegendLabel
     476  \param data Attributes to be displayed
     477
     478  \sa createWidget()
     479  \note When widget is no QwtLegendLabel updateWidget() does nothing.
     480 */
     481void QwtLegend::updateWidget( QWidget *widget, const QwtLegendData &data )
     482{
     483    QwtLegendLabel *label = qobject_cast<QwtLegendLabel *>( widget );
     484    if ( label )
     485    {
     486        label->setData( data );
     487        if ( !data.value( QwtLegendData::ModeRole ).isValid() )
     488        {
     489            // use the default mode, when there is no specific
     490            // hint from the legend data
     491
     492            label->setItemMode( defaultItemMode() );
     493        }
     494    }
     495}
     496
     497void QwtLegend::updateTabOrder()
     498{
     499    QLayout *contentsLayout = d_data->view->contentsWidget->layout();
     500    if ( contentsLayout )
     501    {
    328502        // set tab focus chain
    329503
    330504        QWidget *w = NULL;
    331505
    332         for ( int i = 0; i < contentsWidget->layout()->count(); i++ )
    333         {
    334             QLayoutItem *item = contentsWidget->layout()->itemAt( i );
     506        for ( int i = 0; i < contentsLayout->count(); i++ )
     507        {
     508            QLayoutItem *item = contentsLayout->itemAt( i );
    335509            if ( w && item->widget() )
    336510                QWidget::setTabOrder( w, item->widget() );
     
    339513        }
    340514    }
    341     if ( parentWidget() && parentWidget()->layout() == NULL )
    342     {
    343         /*
    344            updateGeometry() doesn't post LayoutRequest in certain
    345            situations, like when we are hidden. But we want the
    346            parent widget notified, so it can show/hide the legend
    347            depending on its items.
    348          */
    349         QApplication::postEvent( parentWidget(),
    350             new QEvent( QEvent::LayoutRequest ) );
    351     }
    352 }
    353 
    354 /*!
    355   Find the widget that represents a plot item
    356 
    357   \param plotItem Plot item
    358   \return Widget on the legend, or NULL
    359 */
    360 QWidget *QwtLegend::find( const QwtLegendItemManager *plotItem ) const
    361 {
    362     return d_data->map.find( plotItem );
    363 }
    364 
    365 /*!
    366   Find the widget that represents a plot item
    367 
    368   \param legendItem Legend item
    369   \return Widget on the legend, or NULL
    370 */
    371 QwtLegendItemManager *QwtLegend::find( const QWidget *legendItem ) const
    372 {
    373     return d_data->map.find( legendItem );
    374 }
    375 
    376 /*!
    377    Find the corresponding item for a plotItem and remove it
    378    from the item list.
    379 
    380    \param plotItem Plot item
    381 */
    382 void QwtLegend::remove( const QwtLegendItemManager *plotItem )
    383 {
    384     QWidget *legendItem = d_data->map.find( plotItem );
    385     d_data->map.remove( legendItem );
    386     delete legendItem;
    387 }
    388 
    389 //! Remove all items.
    390 void QwtLegend::clear()
    391 {
    392     bool doUpdate = updatesEnabled();
    393     if ( doUpdate )
    394         setUpdatesEnabled( false );
    395 
    396     d_data->map.clear();
    397 
    398     if ( doUpdate )
    399         setUpdatesEnabled( true );
    400 
    401     update();
    402515}
    403516
     
    412525
    413526/*!
    414   \return The preferred height, for the width w.
     527  \return The preferred height, for a width.
    415528  \param width Width
    416529*/
     
    426539}
    427540
    428 /*!
    429   Adjust contents widget and item layout to the size of the viewport().
    430 */
    431 void QwtLegend::layoutContents()
    432 {
    433     const QSize visibleSize =
    434         d_data->view->viewport()->contentsRect().size();
    435 
    436     const QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>(
    437         d_data->view->contentsWidget->layout() );
    438     if ( tl )
    439     {
    440         const int minW = int( tl->maxItemWidth() ) + 2 * tl->margin();
    441 
    442         int w = qMax( visibleSize.width(), minW );
    443         int h = qMax( tl->heightForWidth( w ), visibleSize.height() );
    444 
    445         const int vpWidth = d_data->view->viewportSize( w, h ).width();
    446         if ( w > vpWidth )
    447         {
    448             w = qMax( vpWidth, minW );
    449             h = qMax( tl->heightForWidth( w ), visibleSize.height() );
    450         }
    451 
    452         d_data->view->contentsWidget->resize( w, h );
    453     }
    454 }
    455541
    456542/*!
     
    460546  \param object Object to be filtered
    461547  \param event Event
     548
     549  \return Forwarded to QwtAbstractLegend::eventFilter()
    462550*/
    463551bool QwtLegend::eventFilter( QObject *object, QEvent *event )
     
    474562                {
    475563                    QWidget *w = static_cast< QWidget * >( ce->child() );
    476                     d_data->map.remove( w );
     564                    d_data->itemMap.removeWidget( w );
    477565                }
    478566                break;
     
    480568            case QEvent::LayoutRequest:
    481569            {
    482                 layoutContents();
     570                d_data->view->layoutContents();
     571
     572                if ( parentWidget() && parentWidget()->layout() == NULL )
     573                {
     574                    /*
     575                       We want the parent widget ( usually QwtPlot ) to recalculate
     576                       its layout, when the contentsWidget has changed. But
     577                       because of the scroll view we have to forward the LayoutRequest
     578                       event manually.
     579
     580                       We don't use updateGeometry() because it doesn't post LayoutRequest
     581                       events when the legend is hidden. But we want the
     582                       parent widget notified, so it can show/hide the legend
     583                       depending on its items.
     584                     */
     585                    QApplication::postEvent( parentWidget(),
     586                        new QEvent( QEvent::LayoutRequest ) );
     587                }               
    483588                break;
    484589            }
     
    488593    }
    489594
    490     return QFrame::eventFilter( object, event );
    491 }
    492 
    493 
    494 //! Return true, if there are no legend items.
     595    return QwtAbstractLegend::eventFilter( object, event );
     596}
     597
     598/*!
     599  Called internally when the legend has been clicked on.
     600  Emits a clicked() signal.
     601*/
     602void QwtLegend::itemClicked()
     603{
     604    QWidget *w = qobject_cast<QWidget *>( sender() );
     605    if ( w )
     606    {
     607        const QVariant itemInfo = d_data->itemMap.itemInfo( w );
     608        if ( itemInfo.isValid() )
     609        {
     610            const QList<QWidget *> widgetList =
     611                d_data->itemMap.legendWidgets( itemInfo );
     612
     613            const int index = widgetList.indexOf( w );
     614            if ( index >= 0 )
     615                Q_EMIT clicked( itemInfo, index );
     616        }
     617    }
     618}
     619
     620/*!
     621  Called internally when the legend has been checked
     622  Emits a checked() signal.
     623*/
     624void QwtLegend::itemChecked( bool on )
     625{
     626    QWidget *w = qobject_cast<QWidget *>( sender() );
     627    if ( w )
     628    {
     629        const QVariant itemInfo = d_data->itemMap.itemInfo( w );
     630        if ( itemInfo.isValid() )
     631        {
     632            const QList<QWidget *> widgetList =
     633                d_data->itemMap.legendWidgets( itemInfo );
     634
     635            const int index = widgetList.indexOf( w );
     636            if ( index >= 0 )
     637                Q_EMIT checked( itemInfo, on, index );
     638        }
     639    }
     640}
     641
     642/*!
     643  Render the legend into a given rectangle.
     644
     645  \param painter Painter
     646  \param rect Bounding rectangle
     647  \param fillBackground When true, fill rect with the widget background
     648
     649  \sa renderLegend() is used by QwtPlotRenderer - not by QwtLegend itself
     650*/
     651void QwtLegend::renderLegend( QPainter *painter,
     652    const QRectF &rect, bool fillBackground ) const
     653{
     654    if ( d_data->itemMap.isEmpty() )
     655        return;
     656
     657    if ( fillBackground )
     658    {
     659        if ( autoFillBackground() ||
     660            testAttribute( Qt::WA_StyledBackground ) )
     661        {
     662            QwtPainter::drawBackgound( painter, rect, this );
     663        }
     664    }
     665
     666    const QwtDynGridLayout *legendLayout =
     667        qobject_cast<QwtDynGridLayout *>( contentsWidget()->layout() );
     668    if ( legendLayout == NULL )
     669        return;
     670
     671    int left, right, top, bottom;
     672    getContentsMargins( &left, &top, &right, &bottom );
     673
     674    QRect layoutRect;
     675    layoutRect.setLeft( qCeil( rect.left() ) + left );
     676    layoutRect.setTop( qCeil( rect.top() ) + top );
     677    layoutRect.setRight( qFloor( rect.right() ) - right );
     678    layoutRect.setBottom( qFloor( rect.bottom() ) - bottom );
     679
     680    uint numCols = legendLayout->columnsForWidth( layoutRect.width() );
     681    QList<QRect> itemRects =
     682        legendLayout->layoutItems( layoutRect, numCols );
     683
     684    int index = 0;
     685
     686    for ( int i = 0; i < legendLayout->count(); i++ )
     687    {
     688        QLayoutItem *item = legendLayout->itemAt( i );
     689        QWidget *w = item->widget();
     690        if ( w )
     691        {
     692            painter->save();
     693
     694            painter->setClipRect( itemRects[index], Qt::IntersectClip );
     695            renderItem( painter, w, itemRects[index], fillBackground );
     696
     697            index++;
     698            painter->restore();
     699        }
     700    }
     701}
     702
     703/*!
     704  Render a legend entry into a given rectangle.
     705
     706  \param painter Painter
     707  \param widget Widget representing a legend entry
     708  \param rect Bounding rectangle
     709  \param fillBackground When true, fill rect with the widget background
     710
     711  \note When widget is not derived from QwtLegendLabel renderItem
     712        does nothing beside the background
     713*/
     714void QwtLegend::renderItem( QPainter *painter,
     715    const QWidget *widget, const QRectF &rect, bool fillBackground ) const
     716{
     717    if ( fillBackground )
     718    {
     719        if ( widget->autoFillBackground() ||
     720            widget->testAttribute( Qt::WA_StyledBackground ) )
     721        {
     722            QwtPainter::drawBackgound( painter, rect, widget );
     723        }
     724    }
     725
     726    const QwtLegendLabel *label = qobject_cast<const QwtLegendLabel *>( widget );
     727    if ( label )
     728    {
     729        // icon
     730
     731        const QwtGraphic &icon = label->data().icon();
     732        const QSizeF sz = icon.defaultSize();
     733
     734        const QRectF iconRect( rect.x() + label->margin(),
     735            rect.center().y() - 0.5 * sz.height(),
     736            sz.width(), sz.height() );
     737
     738        icon.render( painter, iconRect, Qt::KeepAspectRatio );
     739
     740        // title
     741
     742        QRectF titleRect = rect;
     743        titleRect.setX( iconRect.right() + 2 * label->spacing() );
     744
     745        painter->setFont( label->font() );
     746        painter->setPen( label->palette().color( QPalette::Text ) );
     747        const_cast< QwtLegendLabel *>( label )->drawText( painter, titleRect );
     748    }
     749}
     750
     751/*!
     752  \return List of widgets associated to a item
     753  \param itemInfo Info about an item
     754  \sa legendWidget(), itemInfo(), QwtPlot::itemToInfo()
     755 */
     756QList<QWidget *> QwtLegend::legendWidgets( const QVariant &itemInfo ) const
     757{
     758    return d_data->itemMap.legendWidgets( itemInfo );
     759}
     760
     761/*!
     762  \return First widget in the list of widgets associated to an item
     763  \param itemInfo Info about an item
     764  \sa itemInfo(), QwtPlot::itemToInfo()
     765  \note Almost all types of items have only one widget
     766*/
     767QWidget *QwtLegend::legendWidget( const QVariant &itemInfo ) const
     768{
     769    const QList<QWidget *> list = d_data->itemMap.legendWidgets( itemInfo );
     770    if ( list.isEmpty() )
     771        return NULL;
     772
     773    return list[0];
     774}
     775
     776/*!
     777  Find the item that is associated to a widget
     778
     779  \param widget Widget on the legend
     780  \return Associated item info
     781  \sa legendWidget()
     782 */
     783QVariant QwtLegend::itemInfo( const QWidget *widget ) const
     784{
     785    return d_data->itemMap.itemInfo( widget );
     786}
     787
     788//! \return True, when no item is inserted
    495789bool QwtLegend::isEmpty() const
    496790{
    497     return d_data->map.count() == 0;
    498 }
    499 
    500 //! Return the number of legend items.
    501 uint QwtLegend::itemCount() const
    502 {
    503     return d_data->map.count();
    504 }
    505 
    506 //! Return a list of all legend items
    507 QList<QWidget *> QwtLegend::legendItems() const
    508 {
    509     const QMap<QWidget *, const QwtLegendItemManager *> &map =
    510         d_data->map.widgetMap();
    511 
    512     QList<QWidget *> list;
    513 
    514     QMap<QWidget *, const QwtLegendItemManager *>::const_iterator it;
    515     for ( it = map.begin(); it != map.end(); ++it )
    516         list += it.key();
    517 
    518     return list;
    519 }
     791    return d_data->itemMap.isEmpty();
     792}
     793
     794/*!
     795    Return the extent, that is needed for the scrollbars
     796
     797    \param orientation Orientation (
     798    \return The width of the vertical scrollbar for Qt::Horizontal and v.v.
     799 */
     800int QwtLegend::scrollExtent( Qt::Orientation orientation ) const
     801{
     802    int extent = 0;
     803
     804    if ( orientation == Qt::Horizontal )
     805        extent = verticalScrollBar()->sizeHint().width();
     806    else
     807        extent = horizontalScrollBar()->sizeHint().height();
     808
     809    return extent;
     810}
     811
  • trunk/BNC/qwt/qwt_legend.h

    r4271 r8127  
    1212
    1313#include "qwt_global.h"
    14 #include <qframe.h>
    15 #include <qlist.h>
     14#include "qwt_abstract_legend.h"
     15#include <qvariant.h>
    1616
    1717class QScrollBar;
    18 class QwtLegendItemManager;
    1918
    2019/*!
     
    2322  The QwtLegend widget is a tabular arrangement of legend items. Legend
    2423  items might be any type of widget, but in general they will be
    25   a QwtLegendItem.
     24  a QwtLegendLabel.
    2625
    27   \sa QwtLegendItem, QwtLegendItemManager QwtPlot
     26  \sa QwtLegendLabel, QwtPlotItem, QwtPlot
    2827*/
    2928
    30 class QWT_EXPORT QwtLegend : public QFrame
     29class QWT_EXPORT QwtLegend : public QwtAbstractLegend
    3130{
    3231    Q_OBJECT
    3332
    3433public:
    35     /*!
    36       \brief Interaction mode for the legend items
    37 
    38        The default is QwtLegend::ReadOnlyItem.
    39 
    40        \sa setItemMode(), itemMode(), QwtLegendItem::IdentifierMode
    41            QwtLegendItem::clicked(), QwtLegendItem::checked(),
    42            QwtPlot::legendClicked(), QwtPlot::legendChecked()
    43      */
    44 
    45     enum LegendItemMode
    46     {
    47         //! The legend item is not interactive, like a label
    48         ReadOnlyItem,
    49 
    50         //! The legend item is clickable, like a push button
    51         ClickableItem,
    52 
    53         //! The legend item is checkable, like a checkable button
    54         CheckableItem
    55     };
    56 
    5734    explicit QwtLegend( QWidget *parent = NULL );
    5835    virtual ~QwtLegend();
    5936
    60     void setItemMode( LegendItemMode );
    61     LegendItemMode itemMode() const;
     37    void setMaxColumns( uint numColums );
     38    uint maxColumns() const;
     39
     40    void setDefaultItemMode( QwtLegendData::Mode );
     41    QwtLegendData::Mode defaultItemMode() const;
    6242
    6343    QWidget *contentsWidget();
    6444    const QWidget *contentsWidget() const;
    6545
    66     void insert( const QwtLegendItemManager *, QWidget * );
    67     void remove( const QwtLegendItemManager * );
     46    QWidget *legendWidget( const QVariant &  ) const;
     47    QList<QWidget *> legendWidgets( const QVariant & ) const;
    6848
    69     QWidget *find( const QwtLegendItemManager * ) const;
    70     QwtLegendItemManager *find( const QWidget * ) const;
    71 
    72     virtual QList<QWidget *> legendItems() const;
    73 
    74     void clear();
    75 
    76     bool isEmpty() const;
    77     uint itemCount() const;
     49    QVariant itemInfo( const QWidget * ) const;
    7850
    7951    virtual bool eventFilter( QObject *, QEvent * );
     
    8557    QScrollBar *verticalScrollBar() const;
    8658
     59    virtual void renderLegend( QPainter *,
     60        const QRectF &, bool fillBackground ) const;
     61
     62    virtual void renderItem( QPainter *,
     63        const QWidget *, const QRectF &, bool fillBackground ) const;
     64
     65    virtual bool isEmpty() const;
     66    virtual int scrollExtent( Qt::Orientation ) const;
     67
     68Q_SIGNALS:
     69    /*!
     70      A signal which is emitted when the user has clicked on
     71      a legend label, which is in QwtLegendData::Clickable mode.
     72
     73      \param itemInfo Info for the item item of the
     74                      selected legend item
     75      \param index Index of the legend label in the list of widgets
     76                   that are associated with the plot item
     77
     78      \note clicks are disabled as default
     79      \sa setDefaultItemMode(), defaultItemMode(), QwtPlot::itemToInfo()
     80     */
     81    void clicked( const QVariant &itemInfo, int index );
     82
     83    /*!
     84      A signal which is emitted when the user has clicked on
     85      a legend label, which is in QwtLegendData::Checkable mode
     86
     87      \param itemInfo Info for the item of the
     88                      selected legend label
     89      \param index Index of the legend label in the list of widgets
     90                   that are associated with the plot item
     91      \param on True when the legend label is checked
     92
     93      \note clicks are disabled as default
     94      \sa setDefaultItemMode(), defaultItemMode(), QwtPlot::itemToInfo()
     95     */
     96    void checked( const QVariant &itemInfo, bool on, int index );
     97
     98public Q_SLOTS:
     99    virtual void updateLegend( const QVariant &,
     100        const QList<QwtLegendData> & );
     101
     102protected Q_SLOTS:
     103    void itemClicked();
     104    void itemChecked( bool );
     105
    87106protected:
    88     virtual void layoutContents();
     107    virtual QWidget *createWidget( const QwtLegendData & ) const;
     108    virtual void updateWidget( QWidget *widget, const QwtLegendData &data );
    89109
    90110private:
     111    void updateTabOrder();
     112
    91113    class PrivateData;
    92114    PrivateData *d_data;
  • trunk/BNC/qwt/qwt_magnifier.cpp

    r4271 r8127  
    1919        isEnabled( false ),
    2020        wheelFactor( 0.9 ),
    21         wheelButtonState( Qt::NoButton ),
     21        wheelModifiers( Qt::NoModifier ),
    2222        mouseFactor( 0.95 ),
    2323        mouseButton( Qt::RightButton ),
    24         mouseButtonState( Qt::NoButton ),
     24        mouseButtonModifiers( Qt::NoModifier ),
    2525        keyFactor( 0.9 ),
    2626        zoomInKey( Qt::Key_Plus ),
     27        zoomInKeyModifiers( Qt::NoModifier ),
    2728        zoomOutKey( Qt::Key_Minus ),
    28         zoomInKeyModifiers( Qt::NoModifier ),
    2929        zoomOutKeyModifiers( Qt::NoModifier ),
    3030        mousePressed( false )
     
    3535
    3636    double wheelFactor;
    37     int wheelButtonState;
     37    Qt::KeyboardModifiers wheelModifiers;
    3838
    3939    double mouseFactor;
    40     int mouseButton;
    41     int mouseButtonState;
     40
     41    Qt::MouseButton mouseButton;
     42    Qt::KeyboardModifiers mouseButtonModifiers;
    4243
    4344    double keyFactor;
     45
    4446    int zoomInKey;
     47    Qt::KeyboardModifiers zoomInKeyModifiers;
     48
    4549    int zoomOutKey;
    46     int zoomInKeyModifiers;
    47     int zoomOutKeyModifiers;
     50    Qt::KeyboardModifiers  zoomOutKeyModifiers;
    4851
    4952    bool mousePressed;
     
    109112   The wheel factor defines the ratio between the current range
    110113   on the parent widget and the zoomed range for each step of the wheel.
     114
     115   Use values > 1 for magnification (i.e. 2.0) and values < 1 for
     116   scaling down (i.e. 1/2.0 = 0.5). You can use this feature for
     117   inverting the direction of the wheel.
     118
    111119   The default value is 0.9.
    112120
     
    130138
    131139/*!
    132    Assign a mandatory button state for zooming in/out using the wheel.
    133    The default button state is Qt::NoButton.
    134 
    135    \param buttonState Button state
    136    \sa wheelButtonState()
    137 */
    138 void QwtMagnifier::setWheelButtonState( int buttonState )
    139 {
    140     d_data->wheelButtonState = buttonState;
    141 }
    142 
    143 /*!
    144    \return Wheel button state
    145    \sa setWheelButtonState()
    146 */
    147 int QwtMagnifier::wheelButtonState() const
    148 {
    149     return d_data->wheelButtonState;
     140   Assign keyboard modifiers for zooming in/out using the wheel.
     141   The default modifiers are Qt::NoModifiers.
     142
     143   \param modifiers Keyboard modifiers
     144   \sa wheelModifiers()
     145*/
     146void QwtMagnifier::setWheelModifiers( Qt::KeyboardModifiers modifiers )
     147{
     148    d_data->wheelModifiers = modifiers;
     149}
     150
     151/*!
     152   \return Wheel modifiers
     153   \sa setWheelModifiers()
     154*/
     155Qt::KeyboardModifiers QwtMagnifier::wheelModifiers() const
     156{
     157    return d_data->wheelModifiers;
    150158}
    151159
     
    179187
    180188   \param button Button
    181    \param buttonState Button state
     189   \param modifiers Keyboard modifiers
     190
    182191   \sa getMouseButton()
    183192*/
    184 void QwtMagnifier::setMouseButton( int button, int buttonState )
     193void QwtMagnifier::setMouseButton(
     194    Qt::MouseButton button, Qt::KeyboardModifiers modifiers )
    185195{
    186196    d_data->mouseButton = button;
    187     d_data->mouseButtonState = buttonState;
     197    d_data->mouseButtonModifiers = modifiers;
    188198}
    189199
    190200//! \sa setMouseButton()
    191201void QwtMagnifier::getMouseButton(
    192     int &button, int &buttonState ) const
     202    Qt::MouseButton &button, Qt::KeyboardModifiers &modifiers ) const
    193203{
    194204    button = d_data->mouseButton;
    195     buttonState = d_data->mouseButtonState;
     205    modifiers = d_data->mouseButtonModifiers;
    196206}
    197207
     
    229239   \sa getZoomInKey(), setZoomOutKey()
    230240*/
    231 void QwtMagnifier::setZoomInKey( int key, int modifiers )
     241void QwtMagnifier::setZoomInKey( int key,
     242    Qt::KeyboardModifiers modifiers )
    232243{
    233244    d_data->zoomInKey = key;
     
    235246}
    236247
    237 //! \sa setZoomInKey()
    238 void QwtMagnifier::getZoomInKey( int &key, int &modifiers ) const
     248/*!
     249   \brief Retrieve the settings of the zoom in key
     250
     251   \param key Key code, see Qt::Key
     252   \param modifiers Keyboard modifiers
     253
     254   \sa setZoomInKey()
     255*/
     256void QwtMagnifier::getZoomInKey( int &key,
     257    Qt::KeyboardModifiers &modifiers ) const
    239258{
    240259    key = d_data->zoomInKey;
     
    250269   \sa getZoomOutKey(), setZoomOutKey()
    251270*/
    252 void QwtMagnifier::setZoomOutKey( int key, int modifiers )
     271void QwtMagnifier::setZoomOutKey( int key,
     272    Qt::KeyboardModifiers modifiers )
    253273{
    254274    d_data->zoomOutKey = key;
     
    256276}
    257277
    258 //! \sa setZoomOutKey()
    259 void QwtMagnifier::getZoomOutKey( int &key, int &modifiers ) const
     278/*!
     279   \brief Retrieve the settings of the zoom out key
     280
     281   \param key Key code, see Qt::Key
     282   \param modifiers Keyboard modifiers
     283
     284   \sa setZoomOutKey()
     285*/
     286void QwtMagnifier::getZoomOutKey( int &key,
     287    Qt::KeyboardModifiers &modifiers ) const
    260288{
    261289    key = d_data->zoomOutKey;
     
    266294  \brief Event filter
    267295
    268   When isEnabled() the mouse events of the observed widget are filtered.
     296  When isEnabled() is true, the mouse events of the
     297  observed widget are filtered.
    269298
    270299  \param object Object to be filtered
    271300  \param event Event
     301
     302  \return Forwarded to QObject::eventFilter()
    272303
    273304  \sa widgetMousePressEvent(), widgetMouseReleaseEvent(),
     
    283314            case QEvent::MouseButtonPress:
    284315            {
    285                 widgetMousePressEvent( ( QMouseEvent * )event );
     316                widgetMousePressEvent( static_cast<QMouseEvent *>( event ) );
    286317                break;
    287318            }
    288319            case QEvent::MouseMove:
    289320            {
    290                 widgetMouseMoveEvent( ( QMouseEvent * )event );
     321                widgetMouseMoveEvent( static_cast<QMouseEvent *>( event ) );
    291322                break;
    292323            }
    293324            case QEvent::MouseButtonRelease:
    294325            {
    295                 widgetMouseReleaseEvent( ( QMouseEvent * )event );
     326                widgetMouseReleaseEvent( static_cast<QMouseEvent *>( event ) );
    296327                break;
    297328            }
    298329            case QEvent::Wheel:
    299330            {
    300                 widgetWheelEvent( ( QWheelEvent * )event );
     331                widgetWheelEvent( static_cast<QWheelEvent *>( event ) );
    301332                break;
    302333            }
    303334            case QEvent::KeyPress:
    304335            {
    305                 widgetKeyPressEvent( ( QKeyEvent * )event );
     336                widgetKeyPressEvent( static_cast<QKeyEvent *>( event ) );
    306337                break;
    307338            }
    308339            case QEvent::KeyRelease:
    309340            {
    310                 widgetKeyReleaseEvent( ( QKeyEvent * )event );
     341                widgetKeyReleaseEvent( static_cast<QKeyEvent *>( event ) );
    311342                break;
    312343            }
     
    325356void QwtMagnifier::widgetMousePressEvent( QMouseEvent *mouseEvent )
    326357{
    327     if ( ( mouseEvent->button() != d_data->mouseButton)
    328         || parentWidget() == NULL )
    329     {
     358    if ( parentWidget() == NULL )
    330359        return;
    331     }
    332 
    333     if ( ( mouseEvent->modifiers() & Qt::KeyboardModifierMask ) !=
    334         ( int )( d_data->mouseButtonState & Qt::KeyboardModifierMask ) )
     360
     361    if ( ( mouseEvent->button() != d_data->mouseButton ) ||
     362        ( mouseEvent->modifiers() != d_data->mouseButtonModifiers ) )
    335363    {
    336364        return;
     
    338366
    339367    d_data->hasMouseTracking = parentWidget()->hasMouseTracking();
     368
    340369    parentWidget()->setMouseTracking( true );
    341370    d_data->mousePos = mouseEvent->pos();
     
    393422void QwtMagnifier::widgetWheelEvent( QWheelEvent *wheelEvent )
    394423{
    395     if ( ( wheelEvent->modifiers() & Qt::KeyboardModifierMask ) !=
    396         ( int )( d_data->wheelButtonState & Qt::KeyboardModifierMask ) )
     424    if ( wheelEvent->modifiers() != d_data->wheelModifiers )
    397425    {
    398426        return;
     
    411439         */
    412440        double f = qPow( d_data->wheelFactor,
    413             qAbs( wheelEvent->delta() / 120 ) );
     441            qAbs( wheelEvent->delta() / 120.0 ) );
    414442
    415443        if ( wheelEvent->delta() > 0 )
     
    428456void QwtMagnifier::widgetKeyPressEvent( QKeyEvent *keyEvent )
    429457{
    430     const int key = keyEvent->key();
    431     const int state = keyEvent->modifiers();
    432 
    433     if ( key == d_data->zoomInKey &&
    434         state == d_data->zoomInKeyModifiers )
     458    if ( keyEvent->key() == d_data->zoomInKey &&
     459        keyEvent->modifiers() == d_data->zoomInKeyModifiers )
    435460    {
    436461        rescale( d_data->keyFactor );
    437462    }
    438     else if ( key == d_data->zoomOutKey &&
    439         state == d_data->zoomOutKeyModifiers )
     463    else if ( keyEvent->key() == d_data->zoomOutKey &&
     464        keyEvent->modifiers() == d_data->zoomOutKeyModifiers )
    440465    {
    441466        rescale( 1.0 / d_data->keyFactor );
     
    457482QWidget *QwtMagnifier::parentWidget()
    458483{
    459     if ( parent()->inherits( "QWidget" ) )
    460         return ( QWidget * )parent();
    461 
    462     return NULL;
     484    return qobject_cast<QWidget *>( parent() );
    463485}
    464486
     
    466488const QWidget *QwtMagnifier::parentWidget() const
    467489{
    468     if ( parent()->inherits( "QWidget" ) )
    469         return ( const QWidget * )parent();
    470 
    471     return NULL;
    472 }
    473 
     490    return qobject_cast<const QWidget *>( parent() );
     491}
     492
  • trunk/BNC/qwt/qwt_magnifier.h

    r4271 r8127  
    4343    double mouseFactor() const;
    4444
    45     void setMouseButton( int button, int buttonState = Qt::NoButton );
    46     void getMouseButton( int &button, int &buttonState ) const;
     45    void setMouseButton( Qt::MouseButton, Qt::KeyboardModifiers = Qt::NoModifier );
     46    void getMouseButton( Qt::MouseButton &, Qt::KeyboardModifiers & ) const;
    4747
    4848    // mouse wheel
     
    5050    double wheelFactor() const;
    5151
    52     void setWheelButtonState( int buttonState );
    53     int wheelButtonState() const;
     52    void setWheelModifiers( Qt::KeyboardModifiers );
     53    Qt::KeyboardModifiers wheelModifiers() const;
    5454
    5555    // keyboard
     
    5757    double keyFactor() const;
    5858
    59     void setZoomInKey( int key, int modifiers );
    60     void getZoomInKey( int &key, int &modifiers ) const;
     59    void setZoomInKey( int key, Qt::KeyboardModifiers = Qt::NoModifier );
     60    void getZoomInKey( int &key, Qt::KeyboardModifiers & ) const;
    6161
    62     void setZoomOutKey( int key, int modifiers );
    63     void getZoomOutKey( int &key, int &modifiers ) const;
     62    void setZoomOutKey( int key, Qt::KeyboardModifiers = Qt::NoModifier );
     63    void getZoomOutKey( int &key, Qt::KeyboardModifiers & ) const;
    6464
    6565    virtual bool eventFilter( QObject *, QEvent * );
  • trunk/BNC/qwt/qwt_math.cpp

    r4271 r8127  
    4444    return rv;
    4545}
     46
     47/*!
     48  \brief Normalize an angle to be int the range [0.0, 2 * PI[
     49  \param radians Angle in radians
     50  \return Normalized angle in radians
     51*/
     52double qwtNormalizeRadians( double radians )
     53{
     54    double a = ::fmod( radians, 2.0 * M_PI );
     55    if ( a < 0.0 )
     56        a += 2.0 * M_PI;
     57
     58    return a;
     59
     60}
     61
     62/*!
     63  \brief Normalize an angle to be int the range [0.0, 360.0[
     64  \param radians Angle in degrees
     65  \return Normalized angle in degrees
     66*/
     67double qwtNormalizeDegrees( double degrees )
     68{
     69    double a = ::fmod( degrees, 360.0 );
     70    if ( a < 0.0 )
     71        a += 360.0;
     72
     73    return a;
     74}
  • trunk/BNC/qwt/qwt_math.h

    r4271 r8127  
    2424#endif
    2525
    26 #include <qpoint.h>
    2726#include <qmath.h>
    2827#include "qwt_global.h"
    2928
    30 #ifndef LOG10_2
    31 #define LOG10_2     0.30102999566398119802  /* log10(2) */
    32 #endif
    33 
    34 #ifndef LOG10_3
    35 #define LOG10_3     0.47712125471966243540  /* log10(3) */
    36 #endif
    37 
    38 #ifndef LOG10_5
    39 #define LOG10_5     0.69897000433601885749  /* log10(5) */
    40 #endif
    41 
    42 #ifndef M_2PI
    43 #define M_2PI       6.28318530717958623200  /* 2 pi */
     29#ifndef M_PI_2
     30// For Qt <= 4.8.4 M_PI_2 is not known by MinGW-w64
     31// when compiling with -std=c++11
     32#define M_PI_2 (1.57079632679489661923)
    4433#endif
    4534
    4635#ifndef LOG_MIN
    47 //! Mininum value for logarithmic scales
     36//! Minimum value for logarithmic scales
    4837#define LOG_MIN 1.0e-100
    4938#endif
     
    5443#endif
    5544
    56 #ifndef M_E
    57 #define M_E            2.7182818284590452354   /* e */
    58 #endif
    59 
    60 #ifndef M_LOG2E
    61 #define M_LOG2E 1.4426950408889634074   /* log_2 e */
    62 #endif
    63 
    64 #ifndef M_LOG10E
    65 #define M_LOG10E    0.43429448190325182765  /* log_10 e */
    66 #endif
    67 
    68 #ifndef M_LN2
    69 #define M_LN2       0.69314718055994530942  /* log_e 2 */
    70 #endif
    71 
    72 #ifndef M_LN10
    73 #define M_LN10         2.30258509299404568402  /* log_e 10 */
    74 #endif
    75 
    76 #ifndef M_PI
    77 #define M_PI        3.14159265358979323846  /* pi */
    78 #endif
    79 
    80 #ifndef M_PI_2
    81 #define M_PI_2      1.57079632679489661923  /* pi/2 */
    82 #endif
    83 
    84 #ifndef M_PI_4
    85 #define M_PI_4      0.78539816339744830962  /* pi/4 */
    86 #endif
    87 
    88 #ifndef M_1_PI
    89 #define M_1_PI      0.31830988618379067154  /* 1/pi */
    90 #endif
    91 
    92 #ifndef M_2_PI
    93 #define M_2_PI      0.63661977236758134308  /* 2/pi */
    94 #endif
    95 
    96 #ifndef M_2_SQRTPI
    97 #define M_2_SQRTPI  1.12837916709551257390  /* 2/sqrt(pi) */
    98 #endif
    99 
    100 #ifndef M_SQRT2
    101 #define M_SQRT2 1.41421356237309504880  /* sqrt(2) */
    102 #endif
    103 
    104 #ifndef M_SQRT1_2
    105 #define M_SQRT1_2   0.70710678118654752440  /* 1/sqrt(2) */
    106 #endif
    107 
    10845QWT_EXPORT double qwtGetMin( const double *array, int size );
    10946QWT_EXPORT double qwtGetMax( const double *array, int size );
     47
     48QWT_EXPORT double qwtNormalizeRadians( double radians );
     49QWT_EXPORT double qwtNormalizeDegrees( double degrees );
    11050
    11151/*!
     
    162102}
    163103
    164 //! Like qRound, but without converting the result to an int
    165 inline double qwtRoundF(double d)
    166 {
    167     return ::floor( d + 0.5 );
     104//! Approximation of arc tangent ( error below 0,005 radians )
     105inline double qwtFastAtan( double x )
     106{
     107    if ( x < -1.0 )
     108        return -M_PI_2 - x / ( x * x + 0.28 );
     109
     110    if ( x > 1.0 )
     111        return M_PI_2 - x / ( x * x + 0.28 );
     112
     113    return x / ( 1.0 + x * x * 0.28 );
    168114}
    169115
    170 //! Like qFloor, but without converting the result to an int
    171 inline double qwtFloorF(double d)
    172 {
    173     return ::floor( d );
     116//! Approximation of arc tangent ( error below 0,005 radians )
     117inline double qwtFastAtan2( double y, double x )
     118{
     119    if ( x > 0 )
     120        return qwtFastAtan( y / x );
     121
     122    if ( x < 0 )
     123    {
     124        const double d = qwtFastAtan( y / x );
     125        return ( y >= 0 ) ? d + M_PI : d - M_PI;
     126    }
     127
     128    if ( y < 0.0 )
     129        return -M_PI_2;
     130
     131    if ( y > 0.0 )
     132        return M_PI_2;
     133
     134    return 0.0;
    174135}
    175136
    176 //! Like qCeil, but without converting the result to an int
    177 inline double qwtCeilF(double d)
    178 {
    179     return ::ceil( d );
     137//! Translate degrees into radians
     138inline double qwtRadians( double degrees )
     139{
     140    return degrees * M_PI / 180.0;
     141}
     142
     143//! Translate radians into degrees
     144inline double qwtDegrees( double degrees )
     145{
     146    return degrees * 180.0 / M_PI;
    180147}
    181148
  • trunk/BNC/qwt/qwt_matrix_raster_data.cpp

    r4271 r8127  
    2121    }
    2222
    23     inline double value(size_t row, size_t col) const
     23    inline double value(int row, int col) const
    2424    {
    2525        return values.data()[ row * numColumns + col ];
     
    2929
    3030    QVector<double> values;
    31     size_t numColumns;
    32     size_t numRows;
     31    int numColumns;
     32    int numRows;
    3333
    3434    double dx;
     
    5555   \sa resampleMode(), value()
    5656*/
    57 void QwtMatrixRasterData::setResampleMode(ResampleMode mode)
     57void QwtMatrixRasterData::setResampleMode( ResampleMode mode )
    5858{
    5959    d_data->resampleMode = mode;
     
    106106*/
    107107void QwtMatrixRasterData::setValueMatrix(
    108     const QVector<double> &values, size_t numColumns )
     108    const QVector<double> &values, int numColumns )
    109109{
    110110    d_data->values = values;
    111     d_data->numColumns = numColumns;
     111    d_data->numColumns = qMax( numColumns, 0 );
    112112    update();
    113113}
     
    123123
    124124/*!
     125  \brief Change a single value in the matrix
     126
     127  \param row Row index
     128  \param col Column index
     129  \param value New value
     130
     131  \sa value(), setValueMatrix()
     132*/
     133void QwtMatrixRasterData::setValue( int row, int col, double value )
     134{
     135    if ( row >= 0 && row < d_data->numRows &&
     136        col >= 0 && col < d_data->numColumns )
     137    {
     138        const int index = row * d_data->numColumns + col;
     139        d_data->values.data()[ index ] = value;
     140    }
     141}
     142
     143/*!
    125144   \return Number of columns of the value matrix
    126145   \sa valueMatrix(), numRows(), setValueMatrix()
    127146*/
    128 size_t QwtMatrixRasterData::numColumns() const
     147int QwtMatrixRasterData::numColumns() const
    129148{
    130149    return d_data->numColumns;
     
    135154   \sa valueMatrix(), numColumns(), setValueMatrix()
    136155*/
    137 size_t QwtMatrixRasterData::numRows() const
     156int QwtMatrixRasterData::numRows() const
    138157{
    139158    return d_data->numRows;
     
    141160
    142161/*!
    143    \brief Pixel hint
     162   \brief Calculate the pixel hint
     163
     164   pixelHint() returns the geometry of a pixel, that can be used
     165   to calculate the resolution and alignment of the plot item, that is
     166   representing the data.
    144167
    145168   - NearestNeighbour\n
     
    151174     to render in target device ( f.e. screen ) resolution.
    152175
     176   \param area Requested area, ignored
     177   \return Calculated hint
     178
    153179   \sa ResampleMode, setMatrix(), setInterval()
    154180*/
    155 QRectF QwtMatrixRasterData::pixelHint( const QRectF & ) const
    156 {
     181QRectF QwtMatrixRasterData::pixelHint( const QRectF &area ) const
     182{
     183    Q_UNUSED( area )
     184
    157185    QRectF rect;
    158186    if ( d_data->resampleMode == NearestNeighbour )
     
    199227            if ( col1 < 0 )
    200228                col1 = col2;
    201             else if ( col2 >= (int)d_data->numColumns )
     229            else if ( col2 >= static_cast<int>( d_data->numColumns ) )
    202230                col2 = col1;
    203231
    204232            if ( row1 < 0 )
    205233                row1 = row2;
    206             else if ( row2 >= (int)d_data->numRows )
     234            else if ( row2 >= static_cast<int>( d_data->numRows ) )
    207235                row2 = row1;
    208236
     
    230258        default:
    231259        {
    232             uint row = uint( (y - yInterval.minValue() ) / d_data->dy );
    233             uint col = uint( (x - xInterval.minValue() ) / d_data->dx );
     260            int row = int( (y - yInterval.minValue() ) / d_data->dy );
     261            int col = int( (x - xInterval.minValue() ) / d_data->dx );
    234262
    235263            // In case of intervals, where the maximum is included
  • trunk/BNC/qwt/qwt_matrix_raster_data.h

    r4271 r8127  
    5252
    5353    virtual void setInterval( Qt::Axis, const QwtInterval & );
    54     void setValueMatrix( const QVector<double> &values, size_t numColumns );
    55    
     54
     55    void setValueMatrix( const QVector<double> &values, int numColumns );
    5656    const QVector<double> valueMatrix() const;
    57     size_t numColumns() const;
    58     size_t numRows() const;
     57
     58    void setValue( int row, int col, double value );
     59
     60    int numColumns() const;
     61    int numRows() const;
    5962
    6063    virtual QRectF pixelHint( const QRectF & ) const;
  • trunk/BNC/qwt/qwt_null_paintdevice.cpp

    r4271 r8127  
    1616public:
    1717    PrivateData():
    18         size( 0, 0 )
    19     {
    20     }
    21 
    22     QSize size;
     18        mode( QwtNullPaintDevice::NormalMode )
     19    {
     20    }
     21
     22    QwtNullPaintDevice::Mode mode;
    2323};
    2424
     
    2626{
    2727public:
    28     PaintEngine( QPaintEngine::PaintEngineFeatures );
     28    PaintEngine();
    2929
    3030    virtual bool begin( QPaintDevice * );
     
    5555
    5656    virtual void drawTextItem(const QPointF &, const QTextItem &);
     57
    5758    virtual void drawTiledPixmap(const QRectF &,
    5859        const QPixmap &, const QPointF &s);
     60
    5961    virtual void drawImage(const QRectF &,
    6062        const QImage &, const QRectF &, Qt::ImageConversionFlags );
    6163
    6264private:
    63     QwtNullPaintDevice *d_device;
     65    QwtNullPaintDevice *nullDevice();
    6466};
    6567   
    66 QwtNullPaintDevice::PaintEngine::PaintEngine(
    67         QPaintEngine::PaintEngineFeatures features ):
    68     QPaintEngine( features ),
    69     d_device(NULL)
    70 {
    71 }
    72 
    73 bool QwtNullPaintDevice::PaintEngine::begin(
    74     QPaintDevice *device )
    75 {
    76     d_device = static_cast<QwtNullPaintDevice *>( device );
     68QwtNullPaintDevice::PaintEngine::PaintEngine():
     69    QPaintEngine( QPaintEngine::AllFeatures )
     70{
     71}
     72
     73bool QwtNullPaintDevice::PaintEngine::begin( QPaintDevice * )
     74{
     75    setActive( true );
    7776    return true;
    7877}
     
    8079bool QwtNullPaintDevice::PaintEngine::end()
    8180{
    82     d_device = NULL;
     81    setActive( false );
    8382    return true;
    8483}
    8584
    86 QPaintEngine::Type
    87 QwtNullPaintDevice::PaintEngine::type () const
     85QPaintEngine::Type QwtNullPaintDevice::PaintEngine::type() const
    8886{
    8987    return QPaintEngine::User;
     
    9391    const QRect *rects, int rectCount)
    9492{
    95     if ( d_device )
    96         d_device->drawRects( rects, rectCount );
     93    QwtNullPaintDevice *device = nullDevice();
     94    if ( device == NULL )
     95        return;
     96
     97    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     98    {
     99        QPaintEngine::drawRects( rects, rectCount );
     100        return;
     101    }
     102
     103    device->drawRects( rects, rectCount );
    97104}
    98105
     
    100107    const QRectF *rects, int rectCount)
    101108{
    102     if ( d_device )
    103         d_device->drawRects( rects, rectCount );
     109    QwtNullPaintDevice *device = nullDevice();
     110    if ( device == NULL )
     111        return;
     112
     113    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     114    {
     115        QPaintEngine::drawRects( rects, rectCount );
     116        return;
     117    }
     118
     119    device->drawRects( rects, rectCount );
    104120}
    105121
     
    107123    const QLine *lines, int lineCount)
    108124{
    109     if ( d_device )
    110         d_device->drawLines( lines, lineCount );
     125    QwtNullPaintDevice *device = nullDevice();
     126    if ( device == NULL )
     127        return;
     128
     129    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     130    {
     131        QPaintEngine::drawLines( lines, lineCount );
     132        return;
     133    }
     134
     135    device->drawLines( lines, lineCount );
    111136}
    112137
     
    114139    const QLineF *lines, int lineCount)
    115140{
    116     if ( d_device )
    117         d_device->drawLines( lines, lineCount );
     141    QwtNullPaintDevice *device = nullDevice();
     142    if ( device == NULL )
     143        return;
     144
     145    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     146    {
     147        QPaintEngine::drawLines( lines, lineCount );
     148        return;
     149    }
     150
     151    device->drawLines( lines, lineCount );
    118152}
    119153
     
    121155    const QRectF &rect)
    122156{
    123     if ( d_device )
    124         d_device->drawEllipse( rect );
     157    QwtNullPaintDevice *device = nullDevice();
     158    if ( device == NULL )
     159        return;
     160
     161    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     162    {
     163        QPaintEngine::drawEllipse( rect );
     164        return;
     165    }
     166
     167    device->drawEllipse( rect );
    125168}
    126169
     
    128171    const QRect &rect)
    129172{
    130     if ( d_device )
    131         d_device->drawEllipse( rect );
     173    QwtNullPaintDevice *device = nullDevice();
     174    if ( device == NULL )
     175        return;
     176
     177    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     178    {
     179        QPaintEngine::drawEllipse( rect );
     180        return;
     181    }
     182
     183    device->drawEllipse( rect );
    132184}
    133185
     
    136188    const QPainterPath &path)
    137189{
    138     if ( d_device )
    139         d_device->drawPath( path );
     190    QwtNullPaintDevice *device = nullDevice();
     191    if ( device == NULL )
     192        return;
     193
     194    device->drawPath( path );
    140195}
    141196
     
    143198    const QPointF *points, int pointCount)
    144199{
    145     if ( d_device )
    146         d_device->drawPoints( points, pointCount );
     200    QwtNullPaintDevice *device = nullDevice();
     201    if ( device == NULL )
     202        return;
     203
     204    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     205    {
     206        QPaintEngine::drawPoints( points, pointCount );
     207        return;
     208    }
     209
     210    device->drawPoints( points, pointCount );
    147211}
    148212
     
    150214    const QPoint *points, int pointCount)
    151215{
    152     if ( d_device )
    153         d_device->drawPoints( points, pointCount );
     216    QwtNullPaintDevice *device = nullDevice();
     217    if ( device == NULL )
     218        return;
     219
     220    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     221    {
     222        QPaintEngine::drawPoints( points, pointCount );
     223        return;
     224    }
     225
     226    device->drawPoints( points, pointCount );
    154227}
    155228
     
    157230    const QPointF *points, int pointCount, PolygonDrawMode mode)
    158231{
    159     if ( d_device )
    160         d_device->drawPolygon( points, pointCount, mode );
     232    QwtNullPaintDevice *device = nullDevice();
     233    if ( device == NULL )
     234        return;
     235
     236    if ( device->mode() == QwtNullPaintDevice::PathMode )
     237    {
     238        QPainterPath path;
     239
     240        if ( pointCount > 0 )
     241        {
     242            path.moveTo( points[0] );
     243            for ( int i = 1; i < pointCount; i++ )
     244                path.lineTo( points[i] );
     245
     246            if ( mode != PolylineMode )
     247                path.closeSubpath();
     248        }
     249
     250        device->drawPath( path );
     251        return;
     252    }
     253
     254    device->drawPolygon( points, pointCount, mode );
    161255}
    162256
     
    164258    const QPoint *points, int pointCount, PolygonDrawMode mode)
    165259{
    166     if ( d_device )
    167         d_device->drawPolygon( points, pointCount, mode );
     260    QwtNullPaintDevice *device = nullDevice();
     261    if ( device == NULL )
     262        return;
     263
     264    if ( device->mode() == QwtNullPaintDevice::PathMode )
     265    {
     266        QPainterPath path;
     267
     268        if ( pointCount > 0 )
     269        {
     270            path.moveTo( points[0] );
     271            for ( int i = 1; i < pointCount; i++ )
     272                path.lineTo( points[i] );
     273
     274            if ( mode != PolylineMode )
     275                path.closeSubpath();
     276        }
     277
     278        device->drawPath( path );
     279        return;
     280    }
     281
     282    device->drawPolygon( points, pointCount, mode );
    168283}
    169284
     
    171286    const QRectF &rect, const QPixmap &pm, const QRectF &subRect )
    172287{
    173     if ( d_device )
    174         d_device->drawPixmap( rect, pm, subRect );
     288    QwtNullPaintDevice *device = nullDevice();
     289    if ( device == NULL )
     290        return;
     291
     292    device->drawPixmap( rect, pm, subRect );
    175293}
    176294
     
    178296    const QPointF &pos, const QTextItem &textItem)
    179297{
    180     if ( d_device )
    181         d_device->drawTextItem( pos, textItem );
     298    QwtNullPaintDevice *device = nullDevice();
     299    if ( device == NULL )
     300        return;
     301
     302    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     303    {
     304        QPaintEngine::drawTextItem( pos, textItem );
     305        return;
     306    }
     307
     308    device->drawTextItem( pos, textItem );
    182309}
    183310
     
    186313    const QPointF &subRect)
    187314{
    188     if ( d_device )
    189         d_device->drawTiledPixmap( rect, pixmap, subRect );
     315    QwtNullPaintDevice *device = nullDevice();
     316    if ( device == NULL )
     317        return;
     318
     319    if ( device->mode() != QwtNullPaintDevice::NormalMode )
     320    {
     321        QPaintEngine::drawTiledPixmap( rect, pixmap, subRect );
     322        return;
     323    }   
     324
     325    device->drawTiledPixmap( rect, pixmap, subRect );
    190326}
    191327
     
    194330    const QRectF &subRect, Qt::ImageConversionFlags flags)
    195331{
    196     if ( d_device )
    197         d_device->drawImage( rect, image, subRect, flags );
     332    QwtNullPaintDevice *device = nullDevice();
     333    if ( device == NULL )
     334        return;
     335
     336    device->drawImage( rect, image, subRect, flags );
    198337}
    199338
     
    201340    const QPaintEngineState &state)
    202341{
    203     if ( d_device )
    204         d_device->updateState( state );
     342    QwtNullPaintDevice *device = nullDevice();
     343    if ( device == NULL )
     344        return;
     345
     346    device->updateState( state );
     347}
     348
     349inline QwtNullPaintDevice *QwtNullPaintDevice::PaintEngine::nullDevice()
     350{
     351    if ( !isActive() )
     352        return NULL;
     353
     354    return static_cast<QwtNullPaintDevice *>( paintDevice() );
    205355}
    206356
    207357//! Constructor
    208 QwtNullPaintDevice::QwtNullPaintDevice(
    209     QPaintEngine::PaintEngineFeatures features )
    210 {
    211     init( features );
    212 }
    213 
    214 //! Constructor
    215 QwtNullPaintDevice::QwtNullPaintDevice( const QSize &size,
    216     QPaintEngine::PaintEngineFeatures features )
    217 {
    218     init( features );
    219     d_data->size = size;
    220 }
    221 
    222 void QwtNullPaintDevice::init(
    223     QPaintEngine::PaintEngineFeatures features )
    224 {
    225     d_engine = new PaintEngine( features );
     358QwtNullPaintDevice::QwtNullPaintDevice():
     359    d_engine( NULL )
     360{
    226361    d_data = new PrivateData;
    227362}
     
    235370
    236371/*!
    237    Set the size of the paint device
    238 
    239    \param size Size
    240    \sa size()
     372    Set the render mode
     373
     374    \param mode New mode
     375    \sa mode()
     376 */
     377void QwtNullPaintDevice::setMode( Mode mode )
     378{
     379    d_data->mode = mode;
     380}
     381
     382/*!
     383    \return Render mode
     384    \sa setMode()
    241385*/
    242 void QwtNullPaintDevice::setSize( const QSize & size )
    243 {
    244     d_data->size = size;
    245 }
    246 
    247 /*!
    248     \return Size of the paint device
    249     \sa setSize()
    250 */
    251 QSize QwtNullPaintDevice::size() const
    252 {
    253     return d_data->size;
     386QwtNullPaintDevice::Mode QwtNullPaintDevice::mode() const
     387{
     388    return d_data->mode;
    254389}
    255390
     
    257392QPaintEngine *QwtNullPaintDevice::paintEngine() const
    258393{
     394    if ( d_engine == NULL )
     395    {
     396        QwtNullPaintDevice *that =
     397            const_cast< QwtNullPaintDevice * >( this );
     398
     399        that->d_engine = new PaintEngine();
     400    }
     401
    259402    return d_engine;
    260403}
     
    262405/*!
    263406    See QPaintDevice::metric()
    264     \sa setSize()
     407
     408    \param deviceMetric Type of metric
     409    \return Metric information for the given paint device metric.
     410
     411    \sa sizeMetrics()
    265412*/
    266 int QwtNullPaintDevice::metric( PaintDeviceMetric metric ) const
    267 {
    268     static QPixmap pm;
    269 
     413int QwtNullPaintDevice::metric( PaintDeviceMetric deviceMetric ) const
     414{
    270415    int value;
    271416
    272     switch ( metric )
     417    switch ( deviceMetric )
    273418    {
    274419        case PdmWidth:
    275             value = qMax( d_data->size.width(), 0 );
    276             break;
     420        {
     421            value = sizeMetrics().width();
     422            break;
     423        }
    277424        case PdmHeight:
    278             value = qMax( d_data->size.height(), 0 );
    279             break;
     425        {
     426            value = sizeMetrics().height();
     427            break;
     428        }
    280429        case PdmNumColors:
    281             value = 16777216;
    282             break;
     430        {
     431            value = 0xffffffff;
     432            break;
     433        }
    283434        case PdmDepth:
    284             value = 24;
    285             break;
     435        {
     436            value = 32;
     437            break;
     438        }
    286439        case PdmPhysicalDpiX:
     440        case PdmPhysicalDpiY:
    287441        case PdmDpiY:
    288         case PdmPhysicalDpiY:
     442        case PdmDpiX:
     443        {
     444            value = 72;
     445            break;
     446        }
    289447        case PdmWidthMM:
     448        {
     449            value = qRound( metric( PdmWidth ) * 25.4 / metric( PdmDpiX ) );
     450            break;
     451        }
    290452        case PdmHeightMM:
    291         case PdmDpiX:
     453        {
     454            value = qRound( metric( PdmHeight ) * 25.4 / metric( PdmDpiY ) );
     455            break;
     456        }
    292457        default:
    293458            value = 0;
  • trunk/BNC/qwt/qwt_null_paintdevice.h

    r4271 r8127  
    1919
    2020  Sometimes important layout/rendering geometries are not
    21   available or changable from the public Qt class interface.
     21  available or changeable from the public Qt class interface.
    2222  ( f.e hidden in the style implementation ).
    2323
    2424  QwtNullPaintDevice can be used to manipulate or filter out
    25   these informations by analyzing the stream of paint primitives.
     25  this information by analyzing the stream of paint primitives.
    2626
    2727  F.e. QwtNullPaintDevice is used by QwtPlotCanvas to identify
     
    3232{
    3333public:
    34     QwtNullPaintDevice( QPaintEngine::PaintEngineFeatures );
    35     QwtNullPaintDevice( const QSize &size,
    36         QPaintEngine::PaintEngineFeatures );
     34    /*!
     35      \brief Render mode
    3736
     37      \sa setMode(), mode()
     38     */
     39    enum Mode
     40    {
     41        /*!
     42           All vector graphic primitives are painted by
     43           the corresponding draw methods
     44         */
     45        NormalMode,
     46
     47        /*!
     48           Vector graphic primitives ( beside polygons ) are mapped to a QPainterPath
     49           and are painted by drawPath. In PathMode mode
     50           only a few draw methods are called:
     51
     52           - drawPath()
     53           - drawPixmap()
     54           - drawImage()
     55           - drawPolygon()
     56         */
     57        PolygonPathMode,
     58
     59        /*!
     60           Vector graphic primitives are mapped to a QPainterPath
     61           and are painted by drawPath. In PathMode mode
     62           only a few draw methods are called:
     63
     64           - drawPath()
     65           - drawPixmap()
     66           - drawImage()
     67         */
     68        PathMode
     69    };
     70
     71    QwtNullPaintDevice();
    3872    virtual ~QwtNullPaintDevice();
    3973
    40     void setSize( const QSize &);
    41     QSize size() const;
     74    void setMode( Mode );
     75    Mode mode() const;
    4276
    4377    virtual QPaintEngine *paintEngine() const;
     78
    4479    virtual int metric( PaintDeviceMetric metric ) const;
    4580
     
    77112    virtual void updateState( const QPaintEngineState &state );
    78113
     114protected:
     115    //! \return Size needed to implement metric()
     116    virtual QSize sizeMetrics() const = 0;
     117
    79118private:
    80     void init( QPaintEngine::PaintEngineFeatures );
    81 
    82119    class PaintEngine;
    83120    PaintEngine *d_engine;
  • trunk/BNC/qwt/qwt_painter.cpp

    r4271 r8127  
    2929#include <qdesktopwidget.h>
    3030
     31#if QT_VERSION >= 0x050000
     32#include <qwindow.h>
     33#endif
     34
     35#if QT_VERSION < 0x050000
     36
     37#ifdef Q_WS_X11
     38#include <qx11info_x11.h>
     39#endif
     40
     41#endif
     42
    3143bool QwtPainter::d_polylineSplitting = true;
    3244bool QwtPainter::d_roundingAlignment = true;
    3345
    34 static inline bool isClippingNeeded( const QPainter *painter, QRectF &clipRect )
     46static inline bool qwtIsClippingNeeded(
     47    const QPainter *painter, QRectF &clipRect )
    3548{
    3649    bool doClipping = false;
     
    5063}
    5164
    52 static inline void drawPolyline( QPainter *painter,
    53     const QPointF *points, int pointCount, bool polylineSplitting )
     65template <class T>
     66static inline void qwtDrawPolyline( QPainter *painter,
     67    const T *points, int pointCount, bool polylineSplitting )
    5468{
    5569    bool doSplit = false;
     
    7185    if ( doSplit )
    7286    {
    73         const int splitSize = 20;
     87        const int splitSize = 6;
     88
    7489        for ( int i = 0; i < pointCount; i += splitSize )
    7590        {
     
    7994    }
    8095    else
     96    {
    8197        painter->drawPolyline( points, pointCount );
    82 }
    83 
    84 static inline void unscaleFont( QPainter *painter )
     98    }
     99}
     100
     101static inline QSize qwtScreenResolution()
     102{
     103    static QSize screenResolution;
     104    if ( !screenResolution.isValid() )
     105    {
     106        QDesktopWidget *desktop = QApplication::desktop();
     107        if ( desktop )
     108        {
     109            screenResolution.setWidth( desktop->logicalDpiX() );
     110            screenResolution.setHeight( desktop->logicalDpiY() );
     111        }
     112    }
     113
     114    return screenResolution;
     115}
     116
     117static inline void qwtUnscaleFont( QPainter *painter )
    85118{
    86119    if ( painter->font().pixelSize() >= 0 )
    87120        return;
    88121
    89     static QSize screenResolution;
    90     if ( !screenResolution.isValid() )
    91     {
    92         QDesktopWidget *desktop = QApplication::desktop();
    93         if ( desktop )
    94         {
    95             screenResolution.setWidth( desktop->logicalDpiX() );
    96             screenResolution.setHeight( desktop->logicalDpiY() );
    97         }
    98     }
     122    const QSize screenResolution = qwtScreenResolution();
    99123
    100124    const QPaintDevice *pd = painter->device();
     
    107131        painter->setFont( pixelFont );
    108132    }
     133}
     134
     135/*!
     136  Check is the application is running with the X11 graphics system
     137  that has some special capabilities that can be used for incremental
     138  painting to a widget.
     139
     140  \return True, when the graphics system is X11
     141*/
     142bool QwtPainter::isX11GraphicsSystem()
     143{
     144    static int onX11 = -1;
     145    if ( onX11 < 0 )
     146    {
     147        QPixmap pm( 1, 1 );
     148        QPainter painter( &pm );
     149
     150        onX11 = ( painter.paintEngine()->type() == QPaintEngine::X11 ) ? 1 : 0;
     151    }
     152
     153    return onX11 == 1;
    109154}
    110155
     
    114159  beside QPaintEngine::Pdf and QPaintEngine::SVG.
    115160
     161  If we have an integer based paint engine it is also
     162  checked if the painter has a transformation matrix,
     163  that rotates or scales.
     164
    116165  \param  painter Painter
    117   \return true, when the paint engine is aligning
     166  \return true, when the painter is aligning
    118167
    119168  \sa setRoundingAlignment()
     
    131180            default:;
    132181        }
     182
     183        const QTransform tr = painter->transform();
     184        if ( tr.isRotating() || tr.isScaling() )
     185        {
     186            // we might have to check translations too
     187            return false;
     188        }
    133189    }
    134190
     
    139195  Enable whether coordinates should be rounded, before they are painted
    140196  to a paint engine that floors to integer values. For other paint engines
    141   this ( Pdf, SVG ), this flag has no effect.
    142   QwtPainter stores this flag only, the rounding itsself is done in
     197  ( PDF, SVG ) this flag has no effect.
     198  QwtPainter stores this flag only, the rounding itself is done in
    143199  the painting code ( f.e the plot items ).
    144200
     
    155211  \brief En/Disable line splitting for the raster paint engine
    156212
    157   The raster paint engine paints polylines of many points
    158   much faster when they are splitted in smaller chunks.
     213  In some Qt versions the raster paint engine paints polylines of many points
     214  much faster when they are split in smaller chunks: f.e all supported Qt versions
     215  >= Qt 5.0 when drawing an antialiased polyline with a pen width >=2.
     216
     217  The default setting is true.
    159218
    160219  \sa polylineSplitting()
     
    183242
    184243    QRectF clipRect;
    185     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     244    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    186245
    187246    if ( deviceClipping )
     
    214273
    215274    QRectF clipRect;
    216     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     275    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    217276
    218277    /*
    219       Performance of Qt4 is horrible for non trivial brushs. Without
    220       clipping expect minutes or hours for repainting large rects
     278      Performance of Qt4 is horrible for a non trivial brush. Without
     279      clipping expect minutes or hours for repainting large rectangles
    221280      (might result from zooming)
    222281    */
     
    232291    QRectF r = rect;
    233292    if ( deviceClipping )
    234         r = r.intersect( clipRect );
     293        r = r.intersected( clipRect );
    235294
    236295    if ( r.isValid() )
     
    243302{
    244303    QRectF clipRect;
    245     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     304    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    246305    if ( deviceClipping && !clipRect.contains( rect ) )
    247306        return;
     
    254313{
    255314    QRectF clipRect;
    256     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     315    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    257316
    258317    if ( deviceClipping && !clipRect.contains( rect ) )
     
    274333{
    275334    QRectF clipRect;
    276     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     335    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    277336
    278337    if ( deviceClipping && !clipRect.contains( pos ) )
     
    281340
    282341    painter->save();
    283     unscaleFont( painter );
     342    qwtUnscaleFont( painter );
    284343    painter->drawText( pos, text );
    285344    painter->restore();
     
    299358{
    300359    painter->save();
    301     unscaleFont( painter );
     360    qwtUnscaleFont( painter );
    302361    painter->drawText( rect, flags, text );
    303362    painter->restore();
     
    321380    painter->save();
    322381
    323     painter->setFont( txt->defaultFont() );
    324     unscaleFont( painter );
     382    QRectF unscaledRect = rect;
     383
     384    if ( painter->font().pixelSize() < 0 )
     385    {
     386        const QSize res = qwtScreenResolution();
     387
     388        const QPaintDevice *pd = painter->device();
     389        if ( pd->logicalDpiX() != res.width() ||
     390            pd->logicalDpiY() != res.height() )
     391        {
     392            QTransform transform;
     393            transform.scale( res.width() / double( pd->logicalDpiX() ),
     394                res.height() / double( pd->logicalDpiY() ));
     395
     396            painter->setWorldTransform( transform, true );
     397            unscaledRect = transform.inverted().mapRect(rect);
     398        }
     399    } 
    325400
    326401    txt->setDefaultFont( painter->font() );
    327     txt->setPageSize( QSizeF( rect.width(), QWIDGETSIZE_MAX ) );
     402    txt->setPageSize( QSizeF( unscaledRect.width(), QWIDGETSIZE_MAX ) );
    328403
    329404    QAbstractTextDocumentLayout* layout = txt->documentLayout();
    330405
    331406    const double height = layout->documentSize().height();
    332     double y = rect.y();
     407    double y = unscaledRect.y();
    333408    if ( flags & Qt::AlignBottom )
    334         y += ( rect.height() - height );
     409        y += ( unscaledRect.height() - height );
    335410    else if ( flags & Qt::AlignVCenter )
    336         y += ( rect.height() - height ) / 2;
     411        y += ( unscaledRect.height() - height ) / 2;
    337412
    338413    QAbstractTextDocumentLayout::PaintContext context;
    339414    context.palette.setColor( QPalette::Text, painter->pen().color() );
    340415
    341     painter->translate( rect.x(), y );
     416    painter->translate( unscaledRect.x(), y );
    342417    layout->draw( painter, context );
    343418
     
    354429{
    355430    QRectF clipRect;
    356     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     431    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    357432
    358433    if ( deviceClipping &&
     
    373448{
    374449    QRectF clipRect;
    375     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     450    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    376451
    377452    QPolygonF cpa = polygon;
     
    386461{
    387462    QRectF clipRect;
    388     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     463    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    389464
    390465    QPolygonF cpa = polygon;
     
    392467        cpa = QwtClipper::clipPolygonF( clipRect, cpa );
    393468
    394     ::drawPolyline( painter,
     469    qwtDrawPolyline<QPointF>( painter,
    395470        cpa.constData(), cpa.size(), d_polylineSplitting );
    396471}
     
    401476{
    402477    QRectF clipRect;
    403     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     478    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    404479
    405480    if ( deviceClipping )
    406481    {
    407482        QPolygonF polygon( pointCount );
    408         qMemCopy( polygon.data(), points, pointCount * sizeof( QPointF ) );
     483        ::memcpy( polygon.data(), points, pointCount * sizeof( QPointF ) );
    409484
    410485        polygon = QwtClipper::clipPolygonF( clipRect, polygon );
    411         ::drawPolyline( painter,
     486        qwtDrawPolyline<QPointF>( painter,
    412487            polygon.constData(), polygon.size(), d_polylineSplitting );
    413488    }
    414489    else
    415         ::drawPolyline( painter, points, pointCount, d_polylineSplitting );
     490    {
     491        qwtDrawPolyline<QPointF>( painter, points, pointCount, d_polylineSplitting );
     492    }
     493}
     494
     495//! Wrapper for QPainter::drawPolygon()
     496void QwtPainter::drawPolygon( QPainter *painter, const QPolygon &polygon )
     497{
     498    QRectF clipRect;
     499    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     500
     501    QPolygon cpa = polygon;
     502    if ( deviceClipping )
     503        cpa = QwtClipper::clipPolygon( clipRect, polygon );
     504
     505    painter->drawPolygon( cpa );
     506}
     507
     508//! Wrapper for QPainter::drawPolyline()
     509void QwtPainter::drawPolyline( QPainter *painter, const QPolygon &polygon )
     510{
     511    QRectF clipRect;
     512    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     513
     514    QPolygon cpa = polygon;
     515    if ( deviceClipping )
     516        cpa = QwtClipper::clipPolygon( clipRect, cpa );
     517
     518    qwtDrawPolyline<QPoint>( painter,
     519        cpa.constData(), cpa.size(), d_polylineSplitting );
     520}
     521
     522//! Wrapper for QPainter::drawPolyline()
     523void QwtPainter::drawPolyline( QPainter *painter,
     524    const QPoint *points, int pointCount )
     525{
     526    QRectF clipRect;
     527    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     528
     529    if ( deviceClipping )
     530    {
     531        QPolygon polygon( pointCount );
     532        ::memcpy( polygon.data(), points, pointCount * sizeof( QPoint ) );
     533
     534        polygon = QwtClipper::clipPolygon( clipRect, polygon );
     535        qwtDrawPolyline<QPoint>( painter,
     536            polygon.constData(), polygon.size(), d_polylineSplitting );
     537    }
     538    else
     539        qwtDrawPolyline<QPoint>( painter, points, pointCount, d_polylineSplitting );
    416540}
    417541
     
    420544{
    421545    QRectF clipRect;
    422     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     546    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    423547
    424548    if ( deviceClipping && !clipRect.contains( pos ) )
     
    426550
    427551    painter->drawPoint( pos );
     552}
     553
     554//! Wrapper for QPainter::drawPoint()
     555void QwtPainter::drawPoint( QPainter *painter, const QPoint &pos )
     556{
     557    QRectF clipRect;
     558    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     559
     560    if ( deviceClipping )
     561    {
     562        const int minX = qCeil( clipRect.left() );
     563        const int maxX = qFloor( clipRect.right() );
     564        const int minY = qCeil( clipRect.top() );
     565        const int maxY = qFloor( clipRect.bottom() );
     566
     567        if ( pos.x() < minX || pos.x() > maxX
     568            || pos.y() < minY || pos.y() > maxY )
     569        {
     570            return;
     571        }
     572    }
     573
     574    painter->drawPoint( pos );
     575}
     576
     577//! Wrapper for QPainter::drawPoints()
     578void QwtPainter::drawPoints( QPainter *painter,
     579    const QPoint *points, int pointCount )
     580{
     581    QRectF clipRect;
     582    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     583
     584    if ( deviceClipping )
     585    {
     586        const int minX = qCeil( clipRect.left() );
     587        const int maxX = qFloor( clipRect.right() );
     588        const int minY = qCeil( clipRect.top() );
     589        const int maxY = qFloor( clipRect.bottom() );
     590
     591        const QRect r( minX, minY, maxX - minX, maxY - minY );
     592
     593        QPolygon clippedPolygon( pointCount );
     594        QPoint *clippedData = clippedPolygon.data();
     595
     596        int numClippedPoints = 0;
     597        for ( int i = 0; i < pointCount; i++ )
     598        {
     599            if ( r.contains( points[i] ) )
     600                clippedData[ numClippedPoints++ ] = points[i];
     601        }
     602        painter->drawPoints( clippedData, numClippedPoints );
     603    }
     604    else
     605    {
     606        painter->drawPoints( points, pointCount );
     607    }
     608}
     609
     610//! Wrapper for QPainter::drawPoints()
     611void QwtPainter::drawPoints( QPainter *painter,
     612    const QPointF *points, int pointCount )
     613{
     614    QRectF clipRect;
     615    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     616
     617    if ( deviceClipping )
     618    {
     619        QPolygonF clippedPolygon( pointCount );
     620        QPointF *clippedData = clippedPolygon.data();
     621
     622        int numClippedPoints = 0;
     623        for ( int i = 0; i < pointCount; i++ )
     624        {
     625            if ( clipRect.contains( points[i] ) )
     626                clippedData[ numClippedPoints++ ] = points[i];
     627        }
     628        painter->drawPoints( clippedData, numClippedPoints );
     629    }
     630    else
     631    {
     632        painter->drawPoints( points, pointCount );
     633    }
    428634}
    429635
     
    471677
    472678//! Draw a focus rectangle on a widget using its style.
    473 void QwtPainter::drawFocusRect( QPainter *painter, QWidget *widget )
     679void QwtPainter::drawFocusRect( QPainter *painter, const QWidget *widget )
    474680{
    475681    drawFocusRect( painter, widget, widget->rect() );
     
    477683
    478684//! Draw a focus rectangle on a widget using its style.
    479 void QwtPainter::drawFocusRect( QPainter *painter, QWidget *widget,
     685void QwtPainter::drawFocusRect( QPainter *painter, const QWidget *widget,
    480686    const QRect &rect )
    481687{
     
    484690    opt.rect = rect;
    485691    opt.state |= QStyle::State_HasFocus;
    486 
    487     widget->style()->drawPrimitive( QStyle::PE_FrameFocusRect,
    488         &opt, painter, widget );
     692    opt.backgroundColor = widget->palette().color( widget->backgroundRole() );
     693
     694    widget->style()->drawPrimitive(
     695        QStyle::PE_FrameFocusRect, &opt, painter, widget );
    489696}
    490697
    491698/*!
    492   Draw a frame with rounded borders
     699  Draw a round frame
     700
     701  \param painter Painter
     702  \param rect Frame rectangle
     703  \param palette QPalette::WindowText is used for plain borders
     704                 QPalette::Dark and QPalette::Light for raised
     705                 or sunken borders
     706  \param lineWidth Line width
     707  \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow
     708*/
     709void QwtPainter::drawRoundFrame( QPainter *painter,
     710    const QRectF &rect, const QPalette &palette,
     711    int lineWidth, int frameStyle )
     712{
     713    enum Style
     714    {
     715        Plain,
     716        Sunken,
     717        Raised
     718    };
     719
     720    Style style = Plain;
     721    if ( (frameStyle & QFrame::Sunken) == QFrame::Sunken )
     722        style = Sunken;
     723    else if ( (frameStyle & QFrame::Raised) == QFrame::Raised )
     724        style = Raised;
     725
     726    const double lw2 = 0.5 * lineWidth;
     727    QRectF r = rect.adjusted( lw2, lw2, -lw2, -lw2 );
     728
     729    QBrush brush;
     730
     731    if ( style != Plain )
     732    {
     733        QColor c1 = palette.color( QPalette::Light );
     734        QColor c2 = palette.color( QPalette::Dark );
     735
     736        if ( style == Sunken )
     737            qSwap( c1, c2 );
     738
     739        QLinearGradient gradient( r.topLeft(), r.bottomRight() );
     740        gradient.setColorAt( 0.0, c1 );
     741#if 0
     742        gradient.setColorAt( 0.3, c1 );
     743        gradient.setColorAt( 0.7, c2 );
     744#endif
     745        gradient.setColorAt( 1.0, c2 );
     746
     747        brush = QBrush( gradient );
     748    }
     749    else // Plain
     750    {
     751        brush = palette.brush( QPalette::WindowText );
     752    }
     753
     754    painter->save();
     755
     756    painter->setPen( QPen( brush, lineWidth ) );
     757    painter->setBrush( Qt::NoBrush );
     758
     759    painter->drawEllipse( r );
     760
     761    painter->restore();
     762}
     763
     764/*!
     765  Draw a rectangular frame
     766
     767  \param painter Painter
     768  \param rect Frame rectangle
     769  \param palette Palette
     770  \param foregroundRole Foreground role used for QFrame::Plain
     771  \param frameWidth Frame width
     772  \param midLineWidth Used for QFrame::Box
     773  \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow
     774*/
     775void QwtPainter::drawFrame( QPainter *painter, const QRectF &rect,
     776    const QPalette &palette, QPalette::ColorRole foregroundRole,
     777    int frameWidth, int midLineWidth, int frameStyle )
     778{
     779    if ( frameWidth <= 0 || rect.isEmpty() )
     780        return;
     781
     782    const int shadow = frameStyle & QFrame::Shadow_Mask;
     783
     784    painter->save();
     785
     786    if ( shadow == QFrame::Plain )
     787    {
     788        const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
     789        const QRectF innerRect = outerRect.adjusted(
     790            frameWidth, frameWidth, -frameWidth, -frameWidth );
     791
     792        QPainterPath path;
     793        path.addRect( outerRect );
     794        path.addRect( innerRect );
     795
     796        painter->setPen( Qt::NoPen );
     797        painter->setBrush( palette.color( foregroundRole ) );
     798
     799        painter->drawPath( path );
     800    }
     801    else
     802    {
     803        const int shape = frameStyle & QFrame::Shape_Mask;
     804
     805        if ( shape == QFrame::Box )
     806        {
     807            const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
     808            const QRectF midRect1 = outerRect.adjusted(
     809                frameWidth, frameWidth, -frameWidth, -frameWidth );
     810            const QRectF midRect2 = midRect1.adjusted(
     811                midLineWidth, midLineWidth, -midLineWidth, -midLineWidth );
     812
     813            const QRectF innerRect = midRect2.adjusted(
     814                frameWidth, frameWidth, -frameWidth, -frameWidth );
     815
     816            QPainterPath path1;
     817            path1.moveTo( outerRect.bottomLeft() );
     818            path1.lineTo( outerRect.topLeft() );
     819            path1.lineTo( outerRect.topRight() );
     820            path1.lineTo( midRect1.topRight() );
     821            path1.lineTo( midRect1.topLeft() );
     822            path1.lineTo( midRect1.bottomLeft() );
     823
     824            QPainterPath path2;
     825            path2.moveTo( outerRect.bottomLeft() );
     826            path2.lineTo( outerRect.bottomRight() );
     827            path2.lineTo( outerRect.topRight() );
     828            path2.lineTo( midRect1.topRight() );
     829            path2.lineTo( midRect1.bottomRight() );
     830            path2.lineTo( midRect1.bottomLeft() );
     831
     832            QPainterPath path3;
     833            path3.moveTo( midRect2.bottomLeft() );
     834            path3.lineTo( midRect2.topLeft() );
     835            path3.lineTo( midRect2.topRight() );
     836            path3.lineTo( innerRect.topRight() );
     837            path3.lineTo( innerRect.topLeft() );
     838            path3.lineTo( innerRect.bottomLeft() );
     839
     840            QPainterPath path4;
     841            path4.moveTo( midRect2.bottomLeft() );
     842            path4.lineTo( midRect2.bottomRight() );
     843            path4.lineTo( midRect2.topRight() );
     844            path4.lineTo( innerRect.topRight() );
     845            path4.lineTo( innerRect.bottomRight() );
     846            path4.lineTo( innerRect.bottomLeft() );
     847
     848            QPainterPath path5;
     849            path5.addRect( midRect1 );
     850            path5.addRect( midRect2 );
     851
     852            painter->setPen( Qt::NoPen );
     853
     854            QBrush brush1 = palette.dark().color();
     855            QBrush brush2 = palette.light().color();
     856
     857            if ( shadow == QFrame::Raised )
     858                qSwap( brush1, brush2 );
     859
     860            painter->setBrush( brush1 );
     861            painter->drawPath( path1 );
     862            painter->drawPath( path4 );
     863
     864            painter->setBrush( brush2 );
     865            painter->drawPath( path2 );
     866            painter->drawPath( path3 );
     867
     868            painter->setBrush( palette.mid() );
     869            painter->drawPath( path5 );
     870        }
     871#if 0
     872        // qDrawWinPanel doesn't result in something nice
     873        // on a scalable document like PDF. Better draw a
     874        // Panel.
     875
     876        else if ( shape == QFrame::WinPanel )
     877        {
     878            painter->setRenderHint( QPainter::NonCosmeticDefaultPen, true );
     879            qDrawWinPanel ( painter, rect.toRect(), palette,
     880                frameStyle & QFrame::Sunken );
     881        }
     882        else if ( shape == QFrame::StyledPanel )
     883        {
     884        }
     885#endif
     886        else
     887        {
     888            const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
     889            const QRectF innerRect = outerRect.adjusted(
     890                frameWidth - 1.0, frameWidth - 1.0,
     891                -( frameWidth - 1.0 ), -( frameWidth - 1.0 ) );
     892
     893            QPainterPath path1;
     894            path1.moveTo( outerRect.bottomLeft() );
     895            path1.lineTo( outerRect.topLeft() );
     896            path1.lineTo( outerRect.topRight() );
     897            path1.lineTo( innerRect.topRight() );
     898            path1.lineTo( innerRect.topLeft() );
     899            path1.lineTo( innerRect.bottomLeft() );
     900
     901
     902            QPainterPath path2;
     903            path2.moveTo( outerRect.bottomLeft() );
     904            path2.lineTo( outerRect.bottomRight() );
     905            path2.lineTo( outerRect.topRight() );
     906            path2.lineTo( innerRect.topRight() );
     907            path2.lineTo( innerRect.bottomRight() );
     908            path2.lineTo( innerRect.bottomLeft() );
     909
     910            painter->setPen( Qt::NoPen );
     911
     912            QBrush brush1 = palette.dark().color();
     913            QBrush brush2 = palette.light().color();
     914
     915            if ( shadow == QFrame::Raised )
     916                qSwap( brush1, brush2 );
     917
     918            painter->setBrush( brush1 );
     919            painter->drawPath( path1 );
     920
     921            painter->setBrush( brush2 );
     922            painter->drawPath( path2 );
     923        }
     924
     925    }
     926
     927    painter->restore();
     928}
     929
     930/*!
     931  Draw a rectangular frame with rounded borders
    493932
    494933  \param painter Painter
     
    5671006
    5681007            QPen arcPen;
     1008            arcPen.setCapStyle( Qt::FlatCap );
    5691009            arcPen.setWidth( lineWidth );
    5701010
    5711011            QPen linePen;
     1012            linePen.setCapStyle( Qt::FlatCap );
    5721013            linePen.setWidth( lineWidth );
    5731014
     
    6601101
    6611102    QPixmap pixmap( devRect.size() );
     1103    pixmap.fill( Qt::transparent );
     1104
    6621105    QPainter pmPainter( &pixmap );
    6631106    pmPainter.translate( -devRect.x(), -devRect.y() );
     
    6731116
    6741117            if ( colorMap.format() == QwtColorMap::RGB )
    675                 c.setRgb( colorMap.rgb( interval, value ) );
     1118                c.setRgba( colorMap.rgb( interval, value ) );
    6761119            else
    6771120                c = colorTable[colorMap.colorIndex( interval, value )];
     
    6911134
    6921135            if ( colorMap.format() == QwtColorMap::RGB )
    693                 c.setRgb( colorMap.rgb( interval, value ) );
     1136                c.setRgba( colorMap.rgb( interval, value ) );
    6941137            else
    6951138                c = colorTable[colorMap.colorIndex( interval, value )];
     
    7031146    drawPixmap( painter, rect, pixmap );
    7041147}
     1148
     1149static inline void qwtFillRect( const QWidget *widget, QPainter *painter,
     1150    const QRect &rect, const QBrush &brush)
     1151{
     1152    if ( brush.style() == Qt::TexturePattern )
     1153    {
     1154        painter->save();
     1155
     1156        painter->setClipRect( rect );
     1157        painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
     1158
     1159        painter->restore();
     1160    }
     1161    else if ( brush.gradient() )
     1162    {
     1163        painter->save();
     1164
     1165        painter->setClipRect( rect );
     1166        painter->fillRect(0, 0, widget->width(),
     1167            widget->height(), brush);
     1168
     1169        painter->restore();
     1170    }
     1171    else
     1172    {
     1173        painter->fillRect(rect, brush);
     1174    }
     1175}
     1176
     1177/*!
     1178  Fill a pixmap with the content of a widget
     1179
     1180  In Qt >= 5.0 QPixmap::fill() is a nop, in Qt 4.x it is buggy
     1181  for backgrounds with gradients. Thus fillPixmap() offers
     1182  an alternative implementation.
     1183
     1184  \param widget Widget
     1185  \param pixmap Pixmap to be filled
     1186  \param offset Offset
     1187
     1188  \sa QPixmap::fill()
     1189 */
     1190void QwtPainter::fillPixmap( const QWidget *widget,
     1191    QPixmap &pixmap, const QPoint &offset )
     1192{
     1193    const QRect rect( offset, pixmap.size() );
     1194
     1195    QPainter painter( &pixmap );
     1196    painter.translate( -offset );
     1197
     1198    const QBrush autoFillBrush =
     1199        widget->palette().brush( widget->backgroundRole() );
     1200
     1201    if ( !( widget->autoFillBackground() && autoFillBrush.isOpaque() ) )
     1202    {
     1203        const QBrush bg = widget->palette().brush( QPalette::Window );
     1204        qwtFillRect( widget, &painter, rect, bg);
     1205    }
     1206
     1207    if ( widget->autoFillBackground() )
     1208        qwtFillRect( widget, &painter, rect, autoFillBrush);
     1209
     1210    if ( widget->testAttribute(Qt::WA_StyledBackground) )
     1211    {
     1212        painter.setClipRegion( rect );
     1213
     1214        QStyleOption opt;
     1215        opt.initFrom( widget );
     1216        widget->style()->drawPrimitive( QStyle::PE_Widget,
     1217            &opt, &painter, widget );
     1218    }
     1219}
     1220
     1221/*!
     1222  Fill rect with the background of a widget
     1223
     1224  \param painter Painter
     1225  \param rect Rectangle to be filled
     1226  \param widget Widget
     1227
     1228  \sa QStyle::PE_Widget, QWidget::backgroundRole()
     1229 */
     1230void QwtPainter::drawBackgound( QPainter *painter,
     1231    const QRectF &rect, const QWidget *widget )
     1232{
     1233    if ( widget->testAttribute( Qt::WA_StyledBackground ) )
     1234    {
     1235        QStyleOption opt;
     1236        opt.initFrom( widget );
     1237        opt.rect = rect.toAlignedRect();
     1238
     1239        widget->style()->drawPrimitive(
     1240            QStyle::PE_Widget, &opt, painter, widget);
     1241    }
     1242    else
     1243    {
     1244        const QBrush brush =
     1245            widget->palette().brush( widget->backgroundRole() );
     1246
     1247        painter->fillRect( rect, brush );
     1248    }
     1249}
     1250
     1251/*!
     1252  \return A pixmap that can be used as backing store
     1253
     1254  \param widget Widget, for which the backingstore is intended
     1255  \param size Size of the pixmap
     1256 */
     1257QPixmap QwtPainter::backingStore( QWidget *widget, const QSize &size )
     1258{
     1259    QPixmap pm;
     1260
     1261#define QWT_HIGH_DPI 1
     1262
     1263#if QT_VERSION >= 0x050000 && QWT_HIGH_DPI
     1264    qreal pixelRatio = 1.0;
     1265
     1266    if ( widget && widget->windowHandle() )
     1267    {
     1268#if QT_VERSION < 0x050100
     1269        pixelRatio = widget->windowHandle()->devicePixelRatio();
     1270#else
     1271        pixelRatio = widget->devicePixelRatio();
     1272#endif
     1273    }
     1274    else
     1275    {
     1276        if ( qApp )
     1277            pixelRatio = qApp->devicePixelRatio();
     1278    }
     1279
     1280    pm = QPixmap( size * pixelRatio );
     1281    pm.setDevicePixelRatio( pixelRatio );
     1282#else
     1283    Q_UNUSED( widget )
     1284    pm = QPixmap( size );
     1285#endif
     1286
     1287#if QT_VERSION < 0x050000
     1288#ifdef Q_WS_X11
     1289    if ( widget && isX11GraphicsSystem() )
     1290    {
     1291        if ( pm.x11Info().screen() != widget->x11Info().screen() )
     1292            pm.x11SetScreen( widget->x11Info().screen() );
     1293    }
     1294#endif
     1295#endif
     1296
     1297    return pm;
     1298}
     1299
  • trunk/BNC/qwt/qwt_painter.h

    r4271 r8127  
    1717#include <qpen.h>
    1818#include <qline.h>
     19#include <qpalette.h>
    1920
    2021class QPainter;
     
    3031class QwtInterval;
    3132
    32 class QPalette;
    3333class QTextDocument;
    3434class QPainterPath;
     
    7070    static void drawLine( QPainter *, const QLineF & );
    7171
    72     static void drawPolygon( QPainter *, const QPolygonF &pa );
    73     static void drawPolyline( QPainter *, const QPolygonF &pa );
     72    static void drawPolygon( QPainter *, const QPolygonF & );
     73    static void drawPolyline( QPainter *, const QPolygonF & );
    7474    static void drawPolyline( QPainter *, const QPointF *, int pointCount );
     75
     76    static void drawPolygon( QPainter *, const QPolygon & );
     77    static void drawPolyline( QPainter *, const QPolygon & );
     78    static void drawPolyline( QPainter *, const QPoint *, int pointCount );
     79
     80    static void drawPoint( QPainter *, const QPoint & );
     81    static void drawPoints( QPainter *, const QPolygon & );
     82    static void drawPoints( QPainter *, const QPoint *, int pointCount );
    7583
    7684    static void drawPoint( QPainter *, double x, double y );
    7785    static void drawPoint( QPainter *, const QPointF & );
     86    static void drawPoints( QPainter *, const QPolygonF & );
     87    static void drawPoints( QPainter *, const QPointF *, int pointCount );
    7888
    7989    static void drawPath( QPainter *, const QPainterPath & );
     
    8191    static void drawPixmap( QPainter *, const QRectF &, const QPixmap & );
    8292
     93    static void drawRoundFrame( QPainter *,
     94        const QRectF &, const QPalette &, int lineWidth, int frameStyle );
     95
    8396    static void drawRoundedFrame( QPainter *,
    8497        const QRectF &, double xRadius, double yRadius,
    8598        const QPalette &, int lineWidth, int frameStyle );
    8699
    87     static void drawFocusRect( QPainter *, QWidget * );
    88     static void drawFocusRect( QPainter *, QWidget *, const QRect & );
     100    static void drawFrame( QPainter *, const QRectF &rect,
     101        const QPalette &palette, QPalette::ColorRole foregroundRole,
     102        int lineWidth, int midLineWidth, int frameStyle );
     103
     104    static void drawFocusRect( QPainter *, const QWidget * );
     105    static void drawFocusRect( QPainter *, const QWidget *, const QRect & );
    89106
    90107    static void drawColorBar( QPainter *painter,
     
    93110
    94111    static bool isAligning( QPainter *painter );
     112    static bool isX11GraphicsSystem();
     113
     114    static void fillPixmap( const QWidget *,
     115        QPixmap &, const QPoint &offset = QPoint() );
     116
     117    static void drawBackgound( QPainter *painter,
     118        const QRectF &rect, const QWidget *widget );
     119
     120    static QPixmap backingStore( QWidget *, const QSize & );
    95121
    96122private:
     
    103129{
    104130    QwtPainter::drawPoint( painter, QPointF( x, y ) );
     131}
     132
     133//! Wrapper for QPainter::drawPoints()
     134inline void QwtPainter::drawPoints( QPainter *painter, const QPolygon &polygon )
     135{
     136    drawPoints( painter, polygon.data(), polygon.size() );
     137}
     138
     139//! Wrapper for QPainter::drawPoints()
     140inline void QwtPainter::drawPoints( QPainter *painter, const QPolygonF &polygon )
     141{
     142    drawPoints( painter, polygon.data(), polygon.size() );
    105143}
    106144
     
    119157
    120158/*!
    121   Returns whether line splitting for the raster paint engine is enabled.
     159  \return True, when line splitting for the raster paint engine is enabled.
    122160  \sa setPolylineSplitting()
    123161*/
     
    128166
    129167/*!
    130   Returns whether coordinates should be rounded, before they are painted
    131   to a paint engine that floors to integer values. For other paint engines
    132   this ( Pdf, SVG ), this flag has no effect.
     168  Check whether coordinates should be rounded, before they are painted
     169  to a paint engine that rounds to integer values. For other paint engines
     170  ( PDF, SVG ), this flag has no effect.
    133171
     172  \return True, when rounding is enabled
    134173  \sa setRoundingAlignment(), isAligning()
    135174*/
  • trunk/BNC/qwt/qwt_panner.cpp

    r4271 r8127  
    1010#include "qwt_panner.h"
    1111#include "qwt_picker.h"
     12#include "qwt_painter.h"
    1213#include <qpainter.h>
    1314#include <qpixmap.h>
     
    2324    for ( int i = 0; i < children.size(); i++ )
    2425    {
    25         QObject *obj = children[i];
    26         if ( obj->inherits( "QwtPicker" ) )
    27         {
    28             QwtPicker *picker = ( QwtPicker * )obj;
    29             if ( picker->isEnabled() )
    30                 pickers += picker;
    31         }
     26        QwtPicker *picker = qobject_cast<QwtPicker *>( children[i] );
     27        if ( picker && picker->isEnabled() )
     28            pickers += picker;
    3229    }
    3330
     
    4037    PrivateData():
    4138        button( Qt::LeftButton ),
    42         buttonState( Qt::NoButton ),
     39        buttonModifiers( Qt::NoModifier ),
    4340        abortKey( Qt::Key_Escape ),
    44         abortKeyState( Qt::NoButton ),
     41        abortKeyModifiers( Qt::NoModifier ),
    4542#ifndef QT_NO_CURSOR
    4643        cursor( NULL ),
     
    6158    }
    6259
    63     int button;
    64     int buttonState;
     60    Qt::MouseButton button;
     61    Qt::KeyboardModifiers  buttonModifiers;
     62
    6563    int abortKey;
    66     int abortKeyState;
     64    Qt::KeyboardModifiers abortKeyModifiers;
    6765
    6866    QPoint initialPos;
     
    106104
    107105/*!
    108    Change the mouse button
    109    The defaults are Qt::LeftButton and Qt::NoButton
    110 */
    111 void QwtPanner::setMouseButton( int button, int buttonState )
     106   Change the mouse button and modifiers used for panning
     107   The defaults are Qt::LeftButton and Qt::NoModifier
     108*/
     109void QwtPanner::setMouseButton( Qt::MouseButton button,
     110    Qt::KeyboardModifiers modifiers )
    112111{
    113112    d_data->button = button;
    114     d_data->buttonState = buttonState;
    115 }
    116 
    117 //! Get the mouse button
    118 void QwtPanner::getMouseButton( int &button, int &buttonState ) const
     113    d_data->buttonModifiers = modifiers;
     114}
     115
     116//! Get mouse button and modifiers used for panning
     117void QwtPanner::getMouseButton( Qt::MouseButton &button,
     118    Qt::KeyboardModifiers &modifiers ) const
    119119{
    120120    button = d_data->button;
    121     buttonState = d_data->buttonState;
     121    modifiers = d_data->buttonModifiers;
    122122}
    123123
    124124/*!
    125125   Change the abort key
    126    The defaults are Qt::Key_Escape and Qt::NoButton
     126   The defaults are Qt::Key_Escape and Qt::NoModifiers
    127127
    128128   \param key Key ( See Qt::Keycode )
    129    \param state State
    130 */
    131 void QwtPanner::setAbortKey( int key, int state )
     129   \param modifiers Keyboard modifiers
     130*/
     131void QwtPanner::setAbortKey( int key,
     132    Qt::KeyboardModifiers modifiers )
    132133{
    133134    d_data->abortKey = key;
    134     d_data->abortKeyState = state;
    135 }
    136 
    137 //! Get the abort key
    138 void QwtPanner::getAbortKey( int &key, int &state ) const
     135    d_data->abortKeyModifiers = modifiers;
     136}
     137
     138//! Get the abort key and modifiers
     139void QwtPanner::getAbortKey( int &key,
     140    Qt::KeyboardModifiers &modifiers ) const
    139141{
    140142    key = d_data->abortKey;
    141     state = d_data->abortKeyState;
     143    modifiers = d_data->abortKeyModifiers;
    142144}
    143145
     
    223225
    224226/*!
    225    Return true if a orientatio is enabled
     227   \return True if an orientation is enabled
    226228   \sa orientations(), setOrientations()
    227229*/
     
    257259
    258260    QPixmap pm( size() );
    259     pm.fill( parentWidget(), 0, 0 );
     261    QwtPainter::fillPixmap( parentWidget(), pm );
    260262
    261263    QPainter painter( &pm );
     
    298300/*!
    299301  Grab the widget into a pixmap.
     302  \return Grabbed pixmap
    300303*/
    301304QPixmap QwtPanner::grab() const
    302305{
     306#if QT_VERSION >= 0x050000
     307    return parentWidget()->grab( parentWidget()->rect() );
     308#else
    303309    return QPixmap::grabWidget( parentWidget() );
     310#endif
    304311}
    305312
     
    307314  \brief Event filter
    308315
    309   When isEnabled() the mouse events of the observed widget are filtered.
     316  When isEnabled() is true mouse events of the
     317  observed widget are filtered.
    310318
    311319  \param object Object to be filtered
    312320  \param event Event
    313321
     322  \return Always false, beside for paint events for the
     323          parent widget.
     324
    314325  \sa widgetMousePressEvent(), widgetMouseReleaseEvent(),
    315326      widgetMouseMoveEvent()
     
    324335        case QEvent::MouseButtonPress:
    325336        {
    326             widgetMousePressEvent( ( QMouseEvent * )event );
     337            widgetMousePressEvent( static_cast<QMouseEvent *>( event ) );
    327338            break;
    328339        }
    329340        case QEvent::MouseMove:
    330341        {
    331             widgetMouseMoveEvent( ( QMouseEvent * )event );
     342            widgetMouseMoveEvent( static_cast<QMouseEvent *>( event ) );
    332343            break;
    333344        }
    334345        case QEvent::MouseButtonRelease:
    335346        {
    336             widgetMouseReleaseEvent( ( QMouseEvent * )event );
     347            widgetMouseReleaseEvent( static_cast<QMouseEvent *>( event ) );
    337348            break;
    338349        }
    339350        case QEvent::KeyPress:
    340351        {
    341             widgetKeyPressEvent( ( QKeyEvent * )event );
     352            widgetKeyPressEvent( static_cast<QKeyEvent *>( event ) );
    342353            break;
    343354        }
    344355        case QEvent::KeyRelease:
    345356        {
    346             widgetKeyReleaseEvent( ( QKeyEvent * )event );
     357            widgetKeyReleaseEvent( static_cast<QKeyEvent *>( event ) );
    347358            break;
    348359        }
     
    368379void QwtPanner::widgetMousePressEvent( QMouseEvent *mouseEvent )
    369380{
    370     if ( mouseEvent->button() != d_data->button )
     381    if ( ( mouseEvent->button() != d_data->button )
     382        || ( mouseEvent->modifiers() != d_data->buttonModifiers ) )
     383    {
    371384        return;
     385    }
    372386
    373387    QWidget *w = parentWidget();
     
    375389        return;
    376390
    377     if ( ( mouseEvent->modifiers() & Qt::KeyboardModifierMask ) !=
    378         ( int )( d_data->buttonState & Qt::KeyboardModifierMask ) )
    379     {
    380         return;
    381     }
    382 
    383391#ifndef QT_NO_CURSOR
    384392    showCursor( true );
     
    391399    // We don't want to grab the picker !
    392400    QVector<QwtPicker *> pickers = qwtActivePickers( parentWidget() );
    393     for ( int i = 0; i < ( int )pickers.size(); i++ )
     401    for ( int i = 0; i < pickers.size(); i++ )
    394402        pickers[i]->setEnabled( false );
    395403
     
    397405    d_data->contentsMask = contentsMask();
    398406
    399     for ( int i = 0; i < ( int )pickers.size(); i++ )
     407    for ( int i = 0; i < pickers.size(); i++ )
    400408        pickers[i]->setEnabled( true );
    401409
     
    472480void QwtPanner::widgetKeyPressEvent( QKeyEvent *keyEvent )
    473481{
    474     if ( keyEvent->key() == d_data->abortKey )
    475     {
    476         const bool matched =
    477             ( keyEvent->modifiers() & Qt::KeyboardModifierMask ) ==
    478                 ( int )( d_data->abortKeyState & Qt::KeyboardModifierMask );
    479         if ( matched )
    480         {
    481             hide();
    482 #ifndef QT_NO_CURSOR
    483             showCursor( false );
    484 #endif
    485             d_data->pixmap = QPixmap();
    486         }
     482    if ( ( keyEvent->key() == d_data->abortKey )
     483        && ( keyEvent->modifiers() == d_data->abortKeyModifiers ) )
     484    {
     485        hide();
     486
     487#ifndef QT_NO_CURSOR
     488        showCursor( false );
     489#endif
     490        d_data->pixmap = QPixmap();
    487491    }
    488492}
  • trunk/BNC/qwt/qwt_panner.h

    r4271 r8127  
    4444    bool isEnabled() const;
    4545
    46     void setMouseButton( int button, int buttonState = Qt::NoButton );
    47     void getMouseButton( int &button, int &buttonState ) const;
    48     void setAbortKey( int key, int state = Qt::NoButton );
    49     void getAbortKey( int &key, int &state ) const;
     46    void setMouseButton( Qt::MouseButton,
     47        Qt::KeyboardModifiers = Qt::NoModifier );
     48    void getMouseButton( Qt::MouseButton &button,
     49        Qt::KeyboardModifiers & ) const;
     50
     51    void setAbortKey( int key, Qt::KeyboardModifiers = Qt::NoModifier );
     52    void getAbortKey( int &key, Qt::KeyboardModifiers & ) const;
    5053
    5154    void setCursor( const QCursor & );
  • trunk/BNC/qwt/qwt_picker.cpp

    r4271 r8127  
    1212#include "qwt_painter.h"
    1313#include "qwt_math.h"
     14#include "qwt_widget_overlay.h"
    1415#include <qapplication.h>
    1516#include <qevent.h>
     
    2223#include <qmath.h>
    2324
    24 class QwtPicker::PickerWidget: public QWidget
     25static inline QRegion qwtMaskRegion( const QRect &r, int penWidth )
     26{
     27    const int pw = qMax( penWidth, 1 );
     28    const int pw2 = penWidth / 2;
     29
     30    int x1 = r.left() - pw2;
     31    int x2 = r.right() + 1 + pw2 + ( pw % 2 );
     32
     33    int y1 = r.top() - pw2;
     34    int y2 = r.bottom() + 1 + pw2 + ( pw % 2 );
     35
     36    QRegion region;
     37
     38    region += QRect( x1, y1, x2 - x1, pw );
     39    region += QRect( x1, y1, pw, y2 - y1 );
     40    region += QRect( x1, y2 - pw, x2 - x1, pw );
     41    region += QRect( x2 - pw, y1, pw, y2 - y1 );
     42
     43    return region;
     44}
     45
     46static inline QRegion qwtMaskRegion( const QLine &l, int penWidth )
     47{
     48    const int pw = qMax( penWidth, 1 );
     49    const int pw2 = penWidth / 2;
     50
     51    QRegion region;
     52
     53    if ( l.x1() == l.x2() )
     54    {
     55        region += QRect( l.x1() - pw2, l.y1(),
     56            pw, l.y2() ).normalized();
     57    }
     58    else if ( l.y1() == l.y2() )
     59    {
     60        region += QRect( l.x1(), l.y1() - pw2,
     61            l.x2(), pw ).normalized();
     62    }
     63
     64    return region;
     65}
     66
     67class QwtPickerRubberband: public QwtWidgetOverlay
    2568{
    2669public:
    27     enum Type
    28     {
    29         RubberBand,
    30         Text
    31     };
    32 
    33     PickerWidget( QwtPicker *, QWidget *, Type );
    34     void updateMask();
    35 
    36     /*
    37        For a tracker text with a background we can use the background
    38        rect as mask. Also for "regular" Qt widgets >= 4.3.0 we
    39        don't need to mask the text anymore.
    40      */
    41     bool d_hasTextMask;
     70    QwtPickerRubberband( QwtPicker *, QWidget * );
    4271
    4372protected:
    44     virtual void paintEvent( QPaintEvent * );
     73    virtual void drawOverlay( QPainter * ) const;
     74    virtual QRegion maskHint() const;
    4575
    4676    QwtPicker *d_picker;
    47     Type d_type;
    4877};
    4978
     79class QwtPickerTracker: public QwtWidgetOverlay
     80{                                 
     81public:
     82    QwtPickerTracker( QwtPicker *, QWidget * );
     83   
     84protected:
     85    virtual void drawOverlay( QPainter * ) const;
     86    virtual QRegion maskHint() const;
     87   
     88    QwtPicker *d_picker;
     89}; 
     90
     91
    5092class QwtPicker::PrivateData
    5193{
    5294public:
     95    PrivateData():
     96        enabled( false ),
     97        stateMachine( NULL ),
     98        resizeMode( QwtPicker::Stretch ),
     99        rubberBand( QwtPicker::NoRubberBand ),
     100        trackerMode( QwtPicker::AlwaysOff ),
     101        isActive( false ),
     102        trackerPosition( -1, -1 ),
     103        mouseTracking( false ),
     104        openGL( false )
     105    {
     106    }
     107       
    53108    bool enabled;
    54109
     
    70125    bool mouseTracking; // used to save previous value
    71126
    72     /*
    73       On X11 the widget below the picker widgets gets paint events
    74       with a region that is the bounding rect of the mask, if it is complex.
    75       In case of (f.e) a CrossRubberBand and a text this creates complete
    76       repaints of the widget. So we better use two different widgets.
    77      */
    78 
    79     QPointer<PickerWidget> rubberBandWidget;
    80     QPointer<PickerWidget> trackerWidget;
     127    QPointer< QwtPickerRubberband > rubberBandOverlay;
     128    QPointer< QwtPickerTracker> trackerOverlay;
     129
     130    bool openGL;
    81131};
    82132
    83 QwtPicker::PickerWidget::PickerWidget(
    84         QwtPicker *picker, QWidget *parent, Type type ):
    85     QWidget( parent ),
    86     d_hasTextMask( false ),
    87     d_picker( picker ),
    88     d_type( type )
    89 {
    90     setAttribute( Qt::WA_TransparentForMouseEvents );
    91     setAttribute( Qt::WA_NoSystemBackground );
    92     setFocusPolicy( Qt::NoFocus );
    93 }
    94 
    95 void QwtPicker::PickerWidget::updateMask()
    96 {
    97     QRegion mask;
    98 
    99     if ( d_type == RubberBand )
    100     {
    101         QBitmap bm( width(), height() );
    102         bm.fill( Qt::color0 );
    103 
    104         QPainter painter( &bm );
    105         QPen pen = d_picker->rubberBandPen();
    106         pen.setColor( Qt::color1 );
    107         painter.setPen( pen );
    108 
    109         d_picker->drawRubberBand( &painter );
    110 
    111         mask = QRegion( bm );
    112     }
    113     if ( d_type == Text )
    114     {
    115         d_hasTextMask = parentWidget()->testAttribute( Qt::WA_PaintOnScreen );
    116 
    117         if ( d_hasTextMask )
    118         {
    119             const QwtText label = d_picker->trackerText(
    120                 d_picker->trackerPosition() );
    121 
    122             if ( label.testPaintAttribute( QwtText::PaintBackground )
    123                 && label.backgroundBrush().style() != Qt::NoBrush )
    124             {
    125                 if ( label.backgroundBrush().color().alpha() > 0 )
    126                 {
    127                     // We don't need a text mask, when we have a background
    128                     d_hasTextMask = false;
    129                 }
    130             }
    131         }
    132 
    133         if ( d_hasTextMask )
    134         {
    135             QBitmap bm( width(), height() );
    136             bm.fill( Qt::color0 );
    137 
    138             QPainter painter( &bm );
    139             painter.setFont( font() );
    140 
    141             QPen pen = d_picker->trackerPen();
    142             pen.setColor( Qt::color1 );
    143             painter.setPen( pen );
    144 
    145             d_picker->drawTracker( &painter );
    146 
    147             mask = QRegion( bm );
    148         }
    149         else
    150         {
    151             mask = d_picker->trackerRect( font() );
    152         }
    153     }
    154 
    155     QWidget *w = parentWidget();
    156     if ( w && !w->testAttribute( Qt::WA_PaintOnScreen ) )
    157     {
    158         // The parent widget gets an update for its complete rectangle
    159         // when the mask is changed in visible state.
    160         // With this hide/show we only get an update for the
    161         // previous mask.
    162 
    163         hide();
    164     }
    165     setMask( mask );
    166     setVisible( !mask.isEmpty() );
    167 }
    168 
    169 void QwtPicker::PickerWidget::paintEvent( QPaintEvent *e )
    170 {
    171     QPainter painter( this );
    172     painter.setClipRegion( e->region() );
    173 
    174     if ( d_type == RubberBand )
    175     {
    176         painter.setPen( d_picker->rubberBandPen() );
    177         d_picker->drawRubberBand( &painter );
    178     }
    179 
    180     if ( d_type == Text )
    181     {
    182         /*
    183            If we have a text mask we simply fill the region of
    184            the mask. This gives better results for antialiased fonts.
    185          */
    186         if ( d_hasTextMask )
    187         {
    188             painter.fillRect( e->rect(),
    189                 QBrush( d_picker->trackerPen().color() ) );
    190         }
    191         else
    192         {
    193             painter.setPen( d_picker->trackerPen() );
    194             d_picker->drawTracker( &painter );
    195         }
    196     }
     133QwtPickerRubberband::QwtPickerRubberband(
     134        QwtPicker *picker, QWidget *parent ):
     135    QwtWidgetOverlay( parent ),
     136    d_picker( picker )
     137{
     138    setMaskMode( QwtWidgetOverlay::MaskHint );
     139}
     140
     141QRegion QwtPickerRubberband::maskHint() const
     142{
     143    return d_picker->rubberBandMask();
     144}
     145
     146void QwtPickerRubberband::drawOverlay( QPainter *painter ) const
     147{
     148    painter->setPen( d_picker->rubberBandPen() );
     149    d_picker->drawRubberBand( painter );
     150}
     151
     152QwtPickerTracker::QwtPickerTracker(
     153        QwtPicker *picker, QWidget *parent ):
     154    QwtWidgetOverlay( parent ),
     155    d_picker( picker )
     156{
     157    setMaskMode( QwtWidgetOverlay::MaskHint );
     158}
     159
     160QRegion QwtPickerTracker::maskHint() const
     161{
     162    return d_picker->trackerRect( font() );
     163}
     164
     165void QwtPickerTracker::drawOverlay( QPainter *painter ) const
     166{
     167    painter->setPen( d_picker->trackerPen() );
     168    d_picker->drawTracker( painter );
    197169}
    198170
     
    201173
    202174  Creates an picker that is enabled, but without a state machine.
    203   rubberband and tracker are disabled.
     175  rubber band and tracker are disabled.
    204176
    205177  \param parent Parent widget, that will be observed
     
    215187  Constructor
    216188
    217   \param rubberBand Rubberband style
     189  \param rubberBand Rubber band style
    218190  \param trackerMode Tracker mode
    219191  \param parent Parent widget, that will be observed
     
    230202{
    231203    setMouseTracking( false );
     204
    232205    delete d_data->stateMachine;
    233     delete d_data->rubberBandWidget;
    234     delete d_data->trackerWidget;
     206    delete d_data->rubberBandOverlay;
     207    delete d_data->trackerOverlay;
     208
    235209    delete d_data;
    236210}
    237211
    238 //! Init the picker, used by the constructors
     212//! Initialize the picker - used by the constructors
    239213void QwtPicker::init( QWidget *parent,
    240214    RubberBand rubberBand, DisplayMode trackerMode )
     
    242216    d_data = new PrivateData;
    243217
    244     d_data->rubberBandWidget = NULL;
    245     d_data->trackerWidget = NULL;
    246 
    247218    d_data->rubberBand = rubberBand;
    248     d_data->enabled = false;
    249     d_data->resizeMode = Stretch;
    250     d_data->trackerMode = AlwaysOff;
    251     d_data->isActive = false;
    252     d_data->trackerPosition = QPoint( -1, -1 );
    253     d_data->mouseTracking = false;
    254 
    255     d_data->stateMachine = NULL;
    256219
    257220    if ( parent )
     
    260223            parent->setFocusPolicy( Qt::WheelFocus );
    261224
     225        d_data->openGL = parent->inherits( "QGLWidget" );
    262226        d_data->trackerFont = parent->font();
    263227        d_data->mouseTracking = parent->hasMouseTracking();
     228
    264229        setEnabled( true );
    265230    }
     231
    266232    setTrackerMode( trackerMode );
    267233}
     
    326292
    327293/*!
    328   Set the rubberband style
    329 
    330   \param rubberBand Rubberband style
     294  Set the rubber band style
     295
     296  \param rubberBand Rubber band style
    331297         The default value is NoRubberBand.
    332298
     
    339305
    340306/*!
    341   \return Rubberband style
     307  \return Rubber band style
    342308  \sa setRubberBand(), RubberBand, rubberBandPen()
    343309*/
     
    500466  Set the pen for the rubberband
    501467
    502   \param pen Rubberband pen
     468  \param pen Rubber band pen
    503469  \sa rubberBandPen(), setRubberBand()
    504470*/
     
    513479
    514480/*!
    515   \return Rubberband pen
     481  \return Rubber band pen
    516482  \sa setRubberBandPen(), rubberBand()
    517483*/
     
    553519
    554520/*!
    555    Draw a rubberband, depending on rubberBand()
    556 
    557    \param painter Painter, initialized with clip rect
    558 
    559    \sa rubberBand(), RubberBand
    560 */
    561 
    562 void QwtPicker::drawRubberBand( QPainter *painter ) const
    563 {
     521  Calculate the mask for the rubber band overlay
     522
     523  \return Region for the mask
     524  \sa QWidget::setMask()
     525 */
     526QRegion QwtPicker::rubberBandMask() const
     527{
     528    QRegion mask;
     529
    564530    if ( !isActive() || rubberBand() == NoRubberBand ||
    565531        rubberBandPen().style() == Qt::NoPen )
    566532    {
    567         return;
    568     }
    569 
    570     const QRect &pRect = pickRect();
     533        return mask;
     534    }
     535
    571536    const QPolygon pa = adjustedPoints( d_data->pickedPoints );
    572537
     
    583548        {
    584549            if ( pa.count() < 1 )
     550                return mask;
     551
     552            const QPoint pos = pa[0];
     553            const int pw = rubberBandPen().width();
     554
     555            const QRect pRect = pickArea().boundingRect().toRect();
     556            switch ( rubberBand() )
     557            {
     558                case VLineRubberBand:
     559                {
     560                    mask += qwtMaskRegion( QLine( pos.x(), pRect.top(),
     561                        pos.x(), pRect.bottom() ), pw );
     562                    break;
     563                }
     564                case HLineRubberBand:
     565                {
     566                    mask += qwtMaskRegion( QLine( pRect.left(), pos.y(),
     567                        pRect.right(), pos.y() ), pw );
     568                    break;
     569                }
     570                case CrossRubberBand:
     571                {
     572                    mask += qwtMaskRegion( QLine( pos.x(), pRect.top(),
     573                        pos.x(), pRect.bottom() ), pw );
     574                    mask += qwtMaskRegion( QLine( pRect.left(), pos.y(),
     575                        pRect.right(), pos.y() ), pw );
     576                    break;
     577                }
     578                default:
     579                    break;
     580            }
     581            break;
     582        }
     583        case QwtPickerMachine::RectSelection:
     584        {
     585            if ( pa.count() < 2 )
     586                return mask;
     587
     588            const int pw = rubberBandPen().width();
     589
     590            switch ( rubberBand() )
     591            {
     592                case RectRubberBand:
     593                {
     594                    const QRect r = QRect( pa.first(), pa.last() );
     595                    mask = qwtMaskRegion( r.normalized(), pw );
     596                    break;
     597                }
     598                case EllipseRubberBand:
     599                {
     600                    const QRect r = QRect( pa.first(), pa.last() );
     601                    mask += r.adjusted( -pw, -pw, pw, pw );
     602                    break;
     603                }
     604                default:
     605                    break;
     606            }
     607            break;
     608        }
     609        case QwtPickerMachine::PolygonSelection:
     610        {
     611            const int pw = rubberBandPen().width();
     612            if ( pw <= 1 )
     613            {
     614                // because of the join style we better
     615                // return a mask for a pen width <= 1 only
     616
     617                const int off = 2 * pw;
     618                const QRect r = pa.boundingRect();
     619                mask += r.adjusted( -off, -off, off, off );
     620            }
     621            break;
     622        }
     623        default:
     624            break;
     625    }
     626
     627    return mask;
     628}
     629
     630/*!
     631   Draw a rubber band, depending on rubberBand()
     632
     633   \param painter Painter, initialized with a clip region
     634
     635   \sa rubberBand(), RubberBand
     636*/
     637
     638void QwtPicker::drawRubberBand( QPainter *painter ) const
     639{
     640    if ( !isActive() || rubberBand() == NoRubberBand ||
     641        rubberBandPen().style() == Qt::NoPen )
     642    {
     643        return;
     644    }
     645
     646    const QPolygon pa = adjustedPoints( d_data->pickedPoints );
     647
     648    QwtPickerMachine::SelectionType selectionType =
     649        QwtPickerMachine::NoSelection;
     650
     651    if ( d_data->stateMachine )
     652        selectionType = d_data->stateMachine->selectionType();
     653
     654    switch ( selectionType )
     655    {
     656        case QwtPickerMachine::NoSelection:
     657        case QwtPickerMachine::PointSelection:
     658        {
     659            if ( pa.count() < 1 )
    585660                return;
    586661
    587662            const QPoint pos = pa[0];
    588663
     664            const QRect pRect = pickArea().boundingRect().toRect();
    589665            switch ( rubberBand() )
    590666            {
    591667                case VLineRubberBand:
     668                {
    592669                    QwtPainter::drawLine( painter, pos.x(),
    593670                        pRect.top(), pos.x(), pRect.bottom() );
    594671                    break;
    595 
     672                }
    596673                case HLineRubberBand:
     674                {
    597675                    QwtPainter::drawLine( painter, pRect.left(),
    598676                        pos.y(), pRect.right(), pos.y() );
    599677                    break;
    600 
     678                }
    601679                case CrossRubberBand:
     680                {
    602681                    QwtPainter::drawLine( painter, pos.x(),
    603682                        pRect.top(), pos.x(), pRect.bottom() );
     
    605684                        pos.y(), pRect.right(), pos.y() );
    606685                    break;
     686                }
    607687                default:
    608688                    break;
     
    615695                return;
    616696
    617             const QPoint p1 = pa[0];
    618             const QPoint p2 = pa[int( pa.count() - 1 )];
    619 
    620             const QRect rect = QRect( p1, p2 ).normalized();
     697            const QRect rect = QRect( pa.first(), pa.last() ).normalized();
    621698            switch ( rubberBand() )
    622699            {
    623700                case EllipseRubberBand:
     701                {
    624702                    QwtPainter::drawEllipse( painter, rect );
    625703                    break;
     704                }
    626705                case RectRubberBand:
     706                {
    627707                    QwtPainter::drawRect( painter, rect );
    628708                    break;
     709                }
    629710                default:
    630711                    break;
     
    694775    return adjusted;
    695776}\endverbatim\n
     777
     778  \param points Selected points
     779  \return Selected points unmodified
    696780*/
    697781QPolygon QwtPicker::adjustedPoints( const QPolygon &points ) const
     
    773857    textRect.moveTopLeft( QPoint( x, y ) );
    774858
    775     int right = qMin( textRect.right(), pickRect().right() - margin );
    776     int bottom = qMin( textRect.bottom(), pickRect().bottom() - margin );
     859    const QRect pickRect = pickArea().boundingRect().toRect();
     860
     861    int right = qMin( textRect.right(), pickRect.right() - margin );
     862    int bottom = qMin( textRect.bottom(), pickRect.bottom() - margin );
    777863    textRect.moveBottomRight( QPoint( right, bottom ) );
    778864
    779     int left = qMax( textRect.left(), pickRect().left() + margin );
    780     int top = qMax( textRect.top(), pickRect().top() + margin );
     865    int left = qMax( textRect.left(), pickRect.left() + margin );
     866    int top = qMax( textRect.top(), pickRect.top() + margin );
    781867    textRect.moveTopLeft( QPoint( left, top ) );
    782868
     
    787873  \brief Event filter
    788874
    789   When isEnabled() == true all events of the observed widget are filtered.
     875  When isEnabled() is true all events of the observed widget are filtered.
    790876  Mouse and keyboard events are translated into widgetMouse- and widgetKey-
    791877  and widgetWheel-events. Paint and Resize events are handled to keep
    792   rubberband and tracker up to date.
     878  rubber band and tracker up to date.
    793879
    794880  \param object Object to be filtered
    795881  \param event Event
     882
     883  \return Always false.
    796884
    797885  \sa widgetEnterEvent(), widgetLeaveEvent(),
     
    809897            case QEvent::Resize:
    810898            {
    811                 const QResizeEvent *re = ( QResizeEvent * )event;
     899                const QResizeEvent *re = static_cast<QResizeEvent *>( event );
     900
     901                /*
     902                   Adding/deleting additional event filters inside of an event filter
     903                   is not safe dues to the implementation in Qt ( changing alist while iterating ).
     904                   So we create the overlays in a way, that they don't install en event filter
     905                   ( parent set to NULL ) and do the resizing here.
     906                 */
     907                if ( d_data->trackerOverlay )
     908                    d_data->trackerOverlay->resize( re->size() );
     909
     910                if ( d_data->rubberBandOverlay )
     911                    d_data->rubberBandOverlay->resize( re->size() );
     912
    812913                if ( d_data->resizeMode == Stretch )
    813914                    stretchSelection( re->oldSize(), re->size() );
    814915
    815                 if ( d_data->rubberBandWidget )
    816                     d_data->rubberBandWidget->resize( re->size() );
    817 
    818                 if ( d_data->trackerWidget )
    819                     d_data->trackerWidget->resize( re->size() );
     916                updateDisplay();
    820917                break;
    821918            }
    822919            case QEvent::Enter:
     920            {
    823921                widgetEnterEvent( event );
    824922                break;
     923            }
    825924            case QEvent::Leave:
     925            {
    826926                widgetLeaveEvent( event );
    827927                break;
     928            }
    828929            case QEvent::MouseButtonPress:
    829                 widgetMousePressEvent( ( QMouseEvent * )event );
     930            {
     931                widgetMousePressEvent( static_cast<QMouseEvent *>( event ) );
    830932                break;
     933            }
    831934            case QEvent::MouseButtonRelease:
    832                 widgetMouseReleaseEvent( ( QMouseEvent * )event );
     935            {
     936                widgetMouseReleaseEvent( static_cast<QMouseEvent *>( event ) );
    833937                break;
     938            }
    834939            case QEvent::MouseButtonDblClick:
    835                 widgetMouseDoubleClickEvent( ( QMouseEvent * )event );
     940            {
     941                widgetMouseDoubleClickEvent( static_cast<QMouseEvent *>( event ) );
    836942                break;
     943            }
    837944            case QEvent::MouseMove:
    838                 widgetMouseMoveEvent( ( QMouseEvent * )event );
     945            {
     946                widgetMouseMoveEvent( static_cast<QMouseEvent *>( event ) );
    839947                break;
     948            }
    840949            case QEvent::KeyPress:
    841                 widgetKeyPressEvent( ( QKeyEvent * )event );
     950            {
     951                widgetKeyPressEvent( static_cast<QKeyEvent *>( event ) );
    842952                break;
     953            }
    843954            case QEvent::KeyRelease:
    844                 widgetKeyReleaseEvent( ( QKeyEvent * )event );
     955            {
     956                widgetKeyReleaseEvent( static_cast<QKeyEvent *>( event ) );
    845957                break;
     958            }
    846959            case QEvent::Wheel:
    847                 widgetWheelEvent( ( QWheelEvent * )event );
     960            {
     961                widgetWheelEvent( static_cast<QWheelEvent *>( event ) );
    848962                break;
     963            }
    849964            default:
    850965                break;
     
    879994void QwtPicker::widgetMouseMoveEvent( QMouseEvent *mouseEvent )
    880995{
    881     if ( pickRect().contains( mouseEvent->pos() ) )
     996    if ( pickArea().contains( mouseEvent->pos() ) )
    882997        d_data->trackerPosition = mouseEvent->pos();
    883998    else
     
    9231038
    9241039/*!
    925   Handle a mouse relase event for the observed widget.
     1040  Handle a mouse release event for the observed widget.
    9261041
    9271042  \param mouseEvent Mouse event
     
    9641079void QwtPicker::widgetWheelEvent( QWheelEvent *wheelEvent )
    9651080{
    966     if ( pickRect().contains( wheelEvent->pos() ) )
     1081    if ( pickArea().contains( wheelEvent->pos() ) )
    9671082        d_data->trackerPosition = wheelEvent->pos();
    9681083    else
     
    10141129    if ( dx != 0 || dy != 0 )
    10151130    {
    1016         const QRect rect = pickRect();
     1131        const QRect rect = pickArea().boundingRect().toRect();
    10171132        const QPoint pos = parentWidget()->mapFromGlobal( QCursor::pos() );
    10181133
     
    10481163  Passes an event to the state machine and executes the resulting
    10491164  commands. Append and Move commands use the current position
    1050   of the cursor (QCursor::pos()).
     1165  of the cursor ( QCursor::pos() ).
    10511166
    10521167  \param event Event
     
    11771292
    11781293/*!
    1179    Reset the state machine and terminate (end(false)) the selection
     1294   Reset the state machine and terminate ( end(false) ) the selection
    11801295*/
    11811296void QwtPicker::reset()
     
    11891304
    11901305/*!
    1191   Append a point to the selection and update rubberband and tracker.
     1306  Append a point to the selection and update rubber band and tracker.
    11921307  The appended() signal is emitted.
    11931308
     
    12591374
    12601375/*!
    1261   \brief Validate and fixup the selection
     1376  \brief Validate and fix up the selection
    12621377
    12631378  Accepts all selections unmodified
    12641379
    1265   \param selection Selection to validate and fixup
     1380  \param selection Selection to validate and fix up
    12661381  \return true, when accepted, false otherwise
    12671382*/
     
    13591474  \return parentWidget()->contentsRect()
    13601475*/
    1361 QRect QwtPicker::pickRect() const
    1362 {
     1476QPainterPath QwtPicker::pickArea() const
     1477{
     1478    QPainterPath path;
     1479
    13631480    const QWidget *widget = parentWidget();
    13641481    if ( widget )
    1365         return widget->contentsRect();
    1366 
    1367     return QRect();
    1368 }
    1369 
    1370 //! Update the state of rubberband and tracker label
     1482        path.addRect( widget->contentsRect() );
     1483
     1484    return path;
     1485}
     1486
     1487//! Update the state of rubber band and tracker label
    13711488void QwtPicker::updateDisplay()
    13721489{
     
    13751492    bool showRubberband = false;
    13761493    bool showTracker = false;
     1494
    13771495    if ( w && w->isVisible() && d_data->enabled )
    13781496    {
     
    13861504            ( trackerMode() == ActiveOnly && isActive() ) )
    13871505        {
    1388             if ( trackerPen() != Qt::NoPen )
     1506            if ( trackerPen() != Qt::NoPen
     1507                && !trackerRect( QFont() ).isEmpty() )
     1508            {
    13891509                showTracker = true;
    1390         }
    1391     }
    1392 
    1393     QPointer<PickerWidget> &rw = d_data->rubberBandWidget;
     1510            }
     1511        }
     1512    }
     1513
     1514    QPointer< QwtPickerRubberband > &rw = d_data->rubberBandOverlay;
    13941515    if ( showRubberband )
    13951516    {
    13961517        if ( rw.isNull() )
    13971518        {
    1398             rw = new PickerWidget( this, w, PickerWidget::RubberBand );
     1519            rw = new QwtPickerRubberband( this, NULL ); // NULL -> no extra event filter
     1520            rw->setObjectName( "PickerRubberBand" );
     1521            rw->setParent( w );
    13991522            rw->resize( w->size() );
    14001523        }
    1401         rw->updateMask();
    1402         rw->update(); // Needed, when the mask doesn't change
     1524
     1525        if ( d_data->rubberBand <= RectRubberBand )
     1526            rw->setMaskMode( QwtWidgetOverlay::MaskHint );
     1527        else
     1528            rw->setMaskMode( QwtWidgetOverlay::AlphaMask );
     1529
     1530        rw->updateOverlay();
    14031531    }
    14041532    else
    1405         delete rw;
    1406 
    1407     QPointer<PickerWidget> &tw = d_data->trackerWidget;
     1533    {
     1534        if ( d_data->openGL )
     1535        {
     1536            // Qt 4.8 crashes for a delete
     1537            if ( !rw.isNull() )
     1538            {
     1539                rw->hide();
     1540                rw->deleteLater();
     1541                rw = NULL;
     1542            }
     1543        }
     1544        else
     1545        {
     1546            delete rw;
     1547        }
     1548    }
     1549
     1550    QPointer< QwtPickerTracker > &tw = d_data->trackerOverlay;
    14081551    if ( showTracker )
    14091552    {
    14101553        if ( tw.isNull() )
    14111554        {
    1412             tw = new PickerWidget( this, w, PickerWidget::Text );
     1555            tw = new QwtPickerTracker( this, NULL ); // NULL -> no extra event filter
     1556            tw->setObjectName( "PickerTracker" );
     1557            tw->setParent( w );
    14131558            tw->resize( w->size() );
    14141559        }
    14151560        tw->setFont( d_data->trackerFont );
    1416         tw->updateMask();
    1417         tw->update(); // Needed, when the mask doesn't change
     1561        tw->updateOverlay();
    14181562    }
    14191563    else
    1420         delete tw;
    1421 }
    1422 
    1423 //! \return Widget displaying the rubberband
    1424 const QWidget *QwtPicker::rubberBandWidget() const
    1425 {
    1426     return d_data->rubberBandWidget;
    1427 }
    1428 
    1429 //! \return Widget displaying the tracker text
    1430 const QWidget *QwtPicker::trackerWidget() const
    1431 {
    1432     return d_data->trackerWidget;
    1433 }
    1434 
     1564    {
     1565        if ( d_data->openGL )
     1566        {
     1567            // Qt 4.8 crashes for a delete
     1568            if ( !tw.isNull() )
     1569            {
     1570                tw->hide();
     1571                tw->deleteLater();
     1572                tw = NULL;
     1573            }
     1574        }
     1575        else
     1576        {
     1577            delete tw;
     1578        }
     1579    }
     1580}
     1581
     1582//! \return Overlay displaying the rubber band
     1583const QwtWidgetOverlay *QwtPicker::rubberBandOverlay() const
     1584{
     1585    return d_data->rubberBandOverlay;
     1586}
     1587
     1588//! \return Overlay displaying the tracker text
     1589const QwtWidgetOverlay *QwtPicker::trackerOverlay() const
     1590{
     1591    return d_data->trackerOverlay;
     1592}
     1593
  • trunk/BNC/qwt/qwt_picker.h

    r4271 r8127  
    1818#include <qfont.h>
    1919#include <qrect.h>
     20#include <qpainterpath.h>
    2021
    2122class QWidget;
     
    2425class QKeyEvent;
    2526class QwtPickerMachine;
     27class QwtWidgetOverlay;
    2628
    2729/*!
     
    4850
    4951  QwtPicker translates the picked points into a selection using the
    50   adjustedPoints method. adjustedPoints is intended to be reimplemented
    51   to fixup the selection according to application specific requirements.
     52  adjustedPoints() method. adjustedPoints() is intended to be reimplemented
     53  to fix up the selection according to application specific requirements.
    5254  (F.e. when an application accepts rectangles of a fixed aspect ratio only.)
    5355
    5456  Optionally QwtPicker support the process of collecting points by a
    55   rubberband and tracker displaying a text for the current mouse
     57  rubber band and tracker displaying a text for the current mouse
    5658  position.
    5759
     
    7981
    8082  The picker is active (isActive()), between begin() and end().
    81   In active state the rubberband is displayed, and the tracker is visible
     83  In active state the rubber band is displayed, and the tracker is visible
    8284  in case of trackerMode is ActiveOnly or AlwaysOn.
    8385
     
    9597    Q_OBJECT
    9698
    97     Q_ENUMS( RubberBand )
    98     Q_ENUMS( DisplayMode )
    99     Q_ENUMS( ResizeMode )
     99    Q_ENUMS( RubberBand DisplayMode ResizeMode )
    100100
    101101    Q_PROPERTY( bool isEnabled READ isEnabled WRITE setEnabled )
     
    111111public:
    112112    /*!
    113       Rubberband style
     113      Rubber band style
    114114
    115115      The default value is QwtPicker::NoRubberBand.
     
    122122        NoRubberBand = 0,
    123123
    124         //! A horizontal line ( only for QwtPicker::PointSelection )
     124        //! A horizontal line ( only for QwtPickerMachine::PointSelection )
    125125        HLineRubberBand,
    126126
    127         //! A vertical line ( only for QwtPicker::PointSelection )
     127        //! A vertical line ( only for QwtPickerMachine::PointSelection )
    128128        VLineRubberBand,
    129129
    130         //! A crosshair ( only for QwtPicker::PointSelection )
     130        //! A crosshair ( only for QwtPickerMachine::PointSelection )
    131131        CrossRubberBand,
    132132
    133         //! A rectangle ( only for QwtPicker::RectSelection )
     133        //! A rectangle ( only for QwtPickerMachine::RectSelection )
    134134        RectRubberBand,
    135135
    136         //! An ellipse ( only for QwtPicker::RectSelection )
     136        //! An ellipse ( only for QwtPickerMachine::RectSelection )
    137137        EllipseRubberBand,
    138138
    139         //! A polygon ( only for QwtPicker::&PolygonSelection )
     139        //! A polygon ( only for QwtPickerMachine::PolygonSelection )
    140140        PolygonRubberBand,
    141141
     
    216216    const QWidget *parentWidget() const;
    217217
    218     virtual QRect pickRect() const;
     218    virtual QPainterPath pickArea() const;
    219219
    220220    virtual void drawRubberBand( QPainter * ) const;
    221221    virtual void drawTracker( QPainter * ) const;
     222
     223    virtual QRegion rubberBandMask() const;
    222224
    223225    virtual QwtText trackerText( const QPoint &pos ) const;
     
    269271      selection has been removed.
    270272
     273      \param pos Position of the point, that has been removed
    271274      \sa remove(), appended()
    272275    */
     
    310313    virtual void updateDisplay();
    311314
    312     const QWidget *rubberBandWidget() const;
    313     const QWidget *trackerWidget() const;
     315    const QwtWidgetOverlay *rubberBandOverlay() const;
     316    const QwtWidgetOverlay *trackerOverlay() const;
    314317
    315318    const QPolygon &pickedPoints() const;
     
    320323    void setMouseTracking( bool );
    321324
    322     class PickerWidget;
    323325    class PrivateData;
    324326    PrivateData *d_data;
  • trunk/BNC/qwt/qwt_picker_machine.cpp

    r4271 r8127  
    9898//! Transition
    9999QList<QwtPickerMachine::Command> QwtPickerClickPointMachine::transition(
    100     const QwtEventPattern &eventPattern, const QEvent *e )
    101 {
    102     QList<QwtPickerMachine::Command> cmdList;
    103 
    104     switch ( e->type() )
     100    const QwtEventPattern &eventPattern, const QEvent *event )
     101{
     102    QList<QwtPickerMachine::Command> cmdList;
     103
     104    switch ( event->type() )
    105105    {
    106106        case QEvent::MouseButtonPress:
    107107        {
    108             if ( eventPattern.mouseMatch(
    109                 QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
     108            if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1,
     109                static_cast<const QMouseEvent *>( event ) ) )
    110110            {
    111111                cmdList += Begin;
     
    117117        case QEvent::KeyPress:
    118118        {
    119             if ( eventPattern.keyMatch(
    120                 QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
    121             {
    122                 cmdList += Begin;
    123                 cmdList += Append;
    124                 cmdList += End;
     119            const QKeyEvent *keyEvent = static_cast<const QKeyEvent *> ( event );
     120            if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, keyEvent ) )
     121            {
     122                if ( !keyEvent->isAutoRepeat() )
     123                {
     124                    cmdList += Begin;
     125                    cmdList += Append;
     126                    cmdList += End;
     127                }
    125128            }
    126129            break;
     
    141144//! Transition
    142145QList<QwtPickerMachine::Command> QwtPickerDragPointMachine::transition(
    143     const QwtEventPattern &eventPattern, const QEvent *e )
    144 {
    145     QList<QwtPickerMachine::Command> cmdList;
    146 
    147     switch ( e->type() )
     146    const QwtEventPattern &eventPattern, const QEvent *event )
     147{
     148    QList<QwtPickerMachine::Command> cmdList;
     149
     150    switch ( event->type() )
    148151    {
    149152        case QEvent::MouseButtonPress:
    150153        {
    151             if ( eventPattern.mouseMatch(
    152                 QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
     154            if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1,
     155                static_cast<const QMouseEvent *>( event ) ) )
    153156            {
    154157                if ( state() == 0 )
     
    179182        case QEvent::KeyPress:
    180183        {
    181             if ( eventPattern.keyMatch(
    182                 QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
    183             {
    184                 if ( state() == 0 )
    185                 {
    186                     cmdList += Begin;
    187                     cmdList += Append;
    188                     setState( 1 );
    189                 }
    190                 else
    191                 {
    192                     cmdList += End;
    193                     setState( 0 );
     184            const QKeyEvent *keyEvent = static_cast<const QKeyEvent *> ( event );
     185            if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, keyEvent ) )
     186            {
     187                if ( !keyEvent->isAutoRepeat() )
     188                {
     189                    if ( state() == 0 )
     190                    {
     191                        cmdList += Begin;
     192                        cmdList += Append;
     193                        setState( 1 );
     194                    }
     195                    else
     196                    {
     197                        cmdList += End;
     198                        setState( 0 );
     199                    }
    194200                }
    195201            }
     
    211217//! Transition
    212218QList<QwtPickerMachine::Command> QwtPickerClickRectMachine::transition(
    213     const QwtEventPattern &eventPattern, const QEvent *e )
    214 {
    215     QList<QwtPickerMachine::Command> cmdList;
    216 
    217     switch ( e->type() )
     219    const QwtEventPattern &eventPattern, const QEvent *event )
     220{
     221    QList<QwtPickerMachine::Command> cmdList;
     222
     223    switch ( event->type() )
    218224    {
    219225        case QEvent::MouseButtonPress:
    220226        {
    221             if ( eventPattern.mouseMatch(
    222                 QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
     227            if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1,
     228                static_cast<const QMouseEvent *>( event ) ) )
    223229            {
    224230                switch ( state() )
     
    243249                }
    244250            }
     251            break;
    245252        }
    246253        case QEvent::MouseMove:
     
    253260        case QEvent::MouseButtonRelease:
    254261        {
    255             if ( eventPattern.mouseMatch(
    256                 QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
     262            if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1,
     263                static_cast<const QMouseEvent *>( event ) ) )
    257264            {
    258265                if ( state() == 1 )
     
    266273        case QEvent::KeyPress:
    267274        {
    268             if ( eventPattern.keyMatch(
    269                 QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
     275            const QKeyEvent *keyEvent = static_cast<const QKeyEvent *> ( event );
     276            if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, keyEvent ) )
     277            {
     278                if ( !keyEvent->isAutoRepeat() )
     279                {
     280                    if ( state() == 0 )
     281                    {
     282                        cmdList += Begin;
     283                        cmdList += Append;
     284                        setState( 1 );
     285                    }
     286                    else
     287                    {
     288                        if ( state() == 1 )
     289                        {
     290                            cmdList += Append;
     291                            setState( 2 );
     292                        }
     293                        else if ( state() == 2 )
     294                        {
     295                            cmdList += End;
     296                            setState( 0 );
     297                        }
     298                    }
     299                }
     300            }
     301            break;
     302        }
     303        default:
     304            break;
     305    }
     306
     307    return cmdList;
     308}
     309
     310//! Constructor
     311QwtPickerDragRectMachine::QwtPickerDragRectMachine():
     312    QwtPickerMachine( RectSelection )
     313{
     314}
     315
     316//! Transition
     317QList<QwtPickerMachine::Command> QwtPickerDragRectMachine::transition(
     318    const QwtEventPattern &eventPattern, const QEvent *event )
     319{
     320    QList<QwtPickerMachine::Command> cmdList;
     321
     322    switch ( event->type() )
     323    {
     324        case QEvent::MouseButtonPress:
     325        {
     326            if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1,
     327                static_cast<const QMouseEvent *>( event ) ) )
    270328            {
    271329                if ( state() == 0 )
     
    273331                    cmdList += Begin;
    274332                    cmdList += Append;
     333                    cmdList += Append;
     334                    setState( 2 );
     335                }
     336            }
     337            break;
     338        }
     339        case QEvent::MouseMove:
     340        case QEvent::Wheel:
     341        {
     342            if ( state() != 0 )
     343                cmdList += Move;
     344            break;
     345        }
     346        case QEvent::MouseButtonRelease:
     347        {
     348            if ( state() == 2 )
     349            {
     350                cmdList += End;
     351                setState( 0 );
     352            }
     353            break;
     354        }
     355        case QEvent::KeyPress:
     356        {
     357            if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1,
     358                static_cast<const QKeyEvent *> ( event ) ) )
     359            {
     360                if ( state() == 0 )
     361                {
     362                    cmdList += Begin;
     363                    cmdList += Append;
     364                    cmdList += Append;
     365                    setState( 2 );
     366                }
     367                else
     368                {
     369                    cmdList += End;
     370                    setState( 0 );
     371                }
     372            }
     373            break;
     374        }
     375        default:
     376            break;
     377    }
     378
     379    return cmdList;
     380}
     381
     382//! Constructor
     383QwtPickerPolygonMachine::QwtPickerPolygonMachine():
     384    QwtPickerMachine( PolygonSelection )
     385{
     386}
     387
     388//! Transition
     389QList<QwtPickerMachine::Command> QwtPickerPolygonMachine::transition(
     390    const QwtEventPattern &eventPattern, const QEvent *event )
     391{
     392    QList<QwtPickerMachine::Command> cmdList;
     393
     394    switch ( event->type() )
     395    {
     396        case QEvent::MouseButtonPress:
     397        {
     398            if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1,
     399                static_cast<const QMouseEvent *>( event ) ) )
     400            {
     401                if ( state() == 0 )
     402                {
     403                    cmdList += Begin;
     404                    cmdList += Append;
     405                    cmdList += Append;
    275406                    setState( 1 );
    276407                }
    277408                else
    278409                {
     410                    cmdList += Append;
     411                }
     412            }
     413            if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect2,
     414                static_cast<const QMouseEvent *>( event ) ) )
     415            {
     416                if ( state() == 1 )
     417                {
     418                    cmdList += End;
     419                    setState( 0 );
     420                }
     421            }
     422            break;
     423        }
     424        case QEvent::MouseMove:
     425        case QEvent::Wheel:
     426        {
     427            if ( state() != 0 )
     428                cmdList += Move;
     429            break;
     430        }
     431        case QEvent::KeyPress:
     432        {
     433            const QKeyEvent *keyEvent = static_cast<const QKeyEvent *> ( event );
     434            if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1, keyEvent ) )
     435            {
     436                if ( !keyEvent->isAutoRepeat() )
     437                {
     438                    if ( state() == 0 )
     439                    {
     440                        cmdList += Begin;
     441                        cmdList += Append;
     442                        cmdList += Append;
     443                        setState( 1 );
     444                    }
     445                    else
     446                    {
     447                        cmdList += Append;
     448                    }
     449                }
     450            }
     451            else if ( eventPattern.keyMatch( QwtEventPattern::KeySelect2, keyEvent ) )
     452            {
     453                if ( !keyEvent->isAutoRepeat() )
     454                {
    279455                    if ( state() == 1 )
    280                     {
    281                         cmdList += Append;
    282                         setState( 2 );
    283                     }
    284                     else if ( state() == 2 )
    285456                    {
    286457                        cmdList += End;
     
    299470
    300471//! Constructor
    301 QwtPickerDragRectMachine::QwtPickerDragRectMachine():
    302     QwtPickerMachine( RectSelection )
    303 {
    304 }
    305 
    306 //! Transition
    307 QList<QwtPickerMachine::Command> QwtPickerDragRectMachine::transition(
    308     const QwtEventPattern &eventPattern, const QEvent *e )
    309 {
    310     QList<QwtPickerMachine::Command> cmdList;
    311 
    312     switch ( e->type() )
     472QwtPickerDragLineMachine::QwtPickerDragLineMachine():
     473    QwtPickerMachine( PolygonSelection )
     474{
     475}
     476
     477//! Transition
     478QList<QwtPickerMachine::Command> QwtPickerDragLineMachine::transition(
     479    const QwtEventPattern &eventPattern, const QEvent *event )
     480{
     481    QList<QwtPickerMachine::Command> cmdList;
     482
     483    switch( event->type() )
    313484    {
    314485        case QEvent::MouseButtonPress:
    315486        {
    316             if ( eventPattern.mouseMatch(
    317                 QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
     487            if ( eventPattern.mouseMatch( QwtEventPattern::MouseSelect1,
     488                static_cast<const QMouseEvent *>( event ) ) )
    318489            {
    319490                if ( state() == 0 )
     
    322493                    cmdList += Append;
    323494                    cmdList += Append;
    324                     setState( 2 );
     495                    setState( 1 );
     496                }
     497            }
     498            break;
     499        }
     500        case QEvent::KeyPress:
     501        {
     502            if ( eventPattern.keyMatch( QwtEventPattern::KeySelect1,
     503                static_cast<const QKeyEvent *> ( event ) ) )
     504            {
     505                if ( state() == 0 )
     506                {
     507                    cmdList += Begin;
     508                    cmdList += Append;
     509                    cmdList += Append;
     510                    setState( 1 );
     511                }
     512                else
     513                {
     514                    cmdList += End;
     515                    setState( 0 );
    325516                }
    326517            }
     
    332523            if ( state() != 0 )
    333524                cmdList += Move;
     525
    334526            break;
    335527        }
    336528        case QEvent::MouseButtonRelease:
    337529        {
    338             if ( state() == 2 )
     530            if ( state() != 0 )
    339531            {
    340532                cmdList += End;
    341533                setState( 0 );
    342534            }
    343             break;
    344         }
    345         case QEvent::KeyPress:
    346         {
    347             if ( eventPattern.keyMatch(
    348                 QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
    349             {
    350                 if ( state() == 0 )
    351                 {
    352                     cmdList += Begin;
    353                     cmdList += Append;
    354                     cmdList += Append;
    355                     setState( 2 );
    356                 }
    357                 else
    358                 {
    359                     cmdList += End;
    360                     setState( 0 );
    361                 }
    362             }
    363             break;
    364         }
    365         default:
    366             break;
    367     }
    368 
    369     return cmdList;
    370 }
    371 
    372 //! Constructor
    373 QwtPickerPolygonMachine::QwtPickerPolygonMachine():
    374     QwtPickerMachine( PolygonSelection )
    375 {
    376 }
    377 
    378 //! Transition
    379 QList<QwtPickerMachine::Command> QwtPickerPolygonMachine::transition(
    380     const QwtEventPattern &eventPattern, const QEvent *e )
    381 {
    382     QList<QwtPickerMachine::Command> cmdList;
    383 
    384     switch ( e->type() )
    385     {
    386         case QEvent::MouseButtonPress:
    387         {
    388             if ( eventPattern.mouseMatch(
    389                 QwtEventPattern::MouseSelect1, ( const QMouseEvent * )e ) )
    390             {
    391                 if ( state() == 0 )
    392                 {
    393                     cmdList += Begin;
    394                     cmdList += Append;
    395                     cmdList += Append;
    396                     setState( 1 );
    397                 }
    398                 else
    399                 {
    400                     cmdList += End;
    401                     setState( 0 );
    402                 }
    403             }
    404             if ( eventPattern.mouseMatch(
    405                 QwtEventPattern::MouseSelect2, ( const QMouseEvent * )e ) )
    406             {
    407                 if ( state() == 1 )
    408                     cmdList += Append;
    409             }
    410             break;
    411         }
    412         case QEvent::MouseMove:
    413         case QEvent::Wheel:
    414         {
    415             if ( state() != 0 )
    416                 cmdList += Move;
    417             break;
    418         }
    419         case QEvent::KeyPress:
    420         {
    421             if ( eventPattern.keyMatch(
    422                 QwtEventPattern::KeySelect1, ( const QKeyEvent * )e ) )
    423             {
    424                 if ( state() == 0 )
    425                 {
    426                     cmdList += Begin;
    427                     cmdList += Append;
    428                     cmdList += Append;
    429                     setState( 1 );
    430                 }
    431                 else
    432                 {
    433                     cmdList += End;
    434                     setState( 0 );
    435                 }
    436             }
    437             else if ( eventPattern.keyMatch(
    438                 QwtEventPattern::KeySelect2, ( const QKeyEvent * )e ) )
    439             {
    440                 if ( state() == 1 )
    441                     cmdList += Append;
    442             }
    443             break;
    444         }
    445         default:
    446             break;
    447     }
    448 
    449     return cmdList;
    450 }
     535        }
     536        default:
     537            break;
     538    }
     539
     540    return cmdList;
     541}
  • trunk/BNC/qwt/qwt_picker_machine.h

    r4271 r8127  
    169169
    170170/*!
     171  \brief A state machine for line selections
     172   
     173  Pressing QwtEventPattern::MouseSelect1 selects
     174  the first point, releasing it the second point.
     175  Pressing QwtEventPattern::KeySelect1 also selects the
     176  first point, a second press selects the second point and terminates
     177  the selection.
     178
     179  A common use case of QwtPickerDragLineMachine are pickers for
     180  distance measurements.
     181 
     182  \sa QwtEventPattern::MousePatternCode, QwtEventPattern::KeyPatternCode
     183*/             
     184                   
     185class QWT_EXPORT QwtPickerDragLineMachine: public QwtPickerMachine
     186{
     187public:
     188    QwtPickerDragLineMachine();
     189
     190    virtual QList<Command> transition(
     191        const QwtEventPattern &, const QEvent * );
     192};
     193
     194/*!
    171195  \brief A state machine for polygon selections
    172196
  • trunk/BNC/qwt/qwt_plot.cpp

    r4271 r8127  
    1515#include "qwt_text_label.h"
    1616#include "qwt_legend.h"
    17 #include "qwt_dyngrid_layout.h"
     17#include "qwt_legend_data.h"
    1818#include "qwt_plot_canvas.h"
     19#include <qmath.h>
    1920#include <qpainter.h>
    2021#include <qpointer.h>
     
    2324#include <qevent.h>
    2425
     26static inline void qwtEnableLegendItems( QwtPlot *plot, bool on )
     27{
     28    if ( on )
     29    {
     30        QObject::connect(
     31            plot, SIGNAL( legendDataChanged(
     32                const QVariant &, const QList<QwtLegendData> & ) ),
     33            plot, SLOT( updateLegendItems(
     34                const QVariant &, const QList<QwtLegendData> & ) ) );
     35    }
     36    else
     37    {
     38        QObject::disconnect(
     39            plot, SIGNAL( legendDataChanged(
     40                const QVariant &, const QList<QwtLegendData> & ) ),
     41            plot, SLOT( updateLegendItems(
     42                const QVariant &, const QList<QwtLegendData> & ) ) );
     43    }
     44}
     45
     46static void qwtSetTabOrder(
     47    QWidget *first, QWidget *second, bool withChildren )
     48{
     49    QList<QWidget *> tabChain;
     50    tabChain += first;
     51    tabChain += second;
     52
     53    if ( withChildren )
     54    {
     55        QList<QWidget *> children = second->findChildren<QWidget *>();
     56
     57        QWidget *w = second->nextInFocusChain();
     58        while ( children.contains( w ) )
     59        {
     60            children.removeAll( w );
     61
     62            tabChain += w;
     63            w = w->nextInFocusChain();
     64        }
     65    }
     66
     67    for ( int i = 0; i < tabChain.size() - 1; i++ )
     68    {
     69        QWidget *from = tabChain[i];
     70        QWidget *to = tabChain[i+1];
     71
     72        const Qt::FocusPolicy policy1 = from->focusPolicy();
     73        const Qt::FocusPolicy policy2 = to->focusPolicy();
     74
     75        QWidget *proxy1 = from->focusProxy();
     76        QWidget *proxy2 = to->focusProxy();
     77
     78        from->setFocusPolicy( Qt::TabFocus );
     79        from->setFocusProxy( NULL);
     80
     81        to->setFocusPolicy( Qt::TabFocus );
     82        to->setFocusProxy( NULL);
     83
     84        QWidget::setTabOrder( from, to );
     85
     86        from->setFocusPolicy( policy1 );
     87        from->setFocusProxy( proxy1);
     88
     89        to->setFocusPolicy( policy2 );
     90        to->setFocusProxy( proxy2 );
     91    }
     92}
     93
    2594class QwtPlot::PrivateData
    2695{
    2796public:
    28     QPointer<QwtTextLabel> lblTitle;
    29     QPointer<QwtPlotCanvas> canvas;
    30     QPointer<QwtLegend> legend;
     97    QPointer<QwtTextLabel> titleLabel;
     98    QPointer<QwtTextLabel> footerLabel;
     99    QPointer<QWidget> canvas;
     100    QPointer<QwtAbstractLegend> legend;
    31101    QwtPlotLayout *layout;
    32102
     
    58128QwtPlot::~QwtPlot()
    59129{
     130    setAutoReplot( false );
    60131    detachItems( QwtPlotItem::Rtti_PlotItem, autoDelete() );
    61132
     
    76147    d_data->autoReplot = false;
    77148
    78     d_data->lblTitle = new QwtTextLabel( title, this );
    79     d_data->lblTitle->setObjectName( "QwtPlotTitle" );
    80 
    81     d_data->lblTitle->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) );
     149    // title
     150    d_data->titleLabel = new QwtTextLabel( this );
     151    d_data->titleLabel->setObjectName( "QwtPlotTitle" );
     152    d_data->titleLabel->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) );
    82153
    83154    QwtText text( title );
    84155    text.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap );
    85     d_data->lblTitle->setText( text );
    86 
     156    d_data->titleLabel->setText( text );
     157
     158    // footer
     159    d_data->footerLabel = new QwtTextLabel( this );
     160    d_data->footerLabel->setObjectName( "QwtPlotFooter" );
     161
     162    QwtText footer;
     163    footer.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap );
     164    d_data->footerLabel->setText( footer );
     165
     166    // legend
    87167    d_data->legend = NULL;
    88168
     169    // axis
    89170    initAxesData();
    90171
     172    // canvas
    91173    d_data->canvas = new QwtPlotCanvas( this );
    92174    d_data->canvas->setObjectName( "QwtPlotCanvas" );
    93     d_data->canvas->setFrameStyle( QFrame::Panel | QFrame::Sunken );
    94     d_data->canvas->setLineWidth( 2 );
    95 
    96     updateTabOrder();
     175    d_data->canvas->installEventFilter( this );
    97176
    98177    setSizePolicy( QSizePolicy::MinimumExpanding,
     
    100179
    101180    resize( 200, 200 );
     181
     182    QList<QWidget *> focusChain;
     183    focusChain << this << d_data->titleLabel << axisWidget( xTop )
     184        << axisWidget( yLeft ) << d_data->canvas << axisWidget( yRight )
     185        << axisWidget( xBottom ) << d_data->footerLabel;
     186
     187    for ( int i = 0; i < focusChain.size() - 1; i++ )
     188        qwtSetTabOrder( focusChain[i], focusChain[i+1], false );
     189
     190    qwtEnableLegendItems( this, true );
     191}
     192
     193/*!
     194  \brief Set the drawing canvas of the plot widget
     195
     196  QwtPlot invokes methods of the canvas as meta methods ( see QMetaObject ).
     197  In opposite to using conventional C++ techniques like virtual methods
     198  they allow to use canvas implementations that are derived from
     199  QWidget or QGLWidget.
     200
     201  The following meta methods could be implemented:
     202
     203  - replot()
     204    When the canvas doesn't offer a replot method, QwtPlot calls
     205    update() instead.
     206
     207  - borderPath()
     208    The border path is necessary to clip the content of the canvas
     209    When the canvas doesn't have any special border ( f.e rounded corners )
     210    it is o.k. not to implement this method.
     211
     212  The default canvas is a QwtPlotCanvas
     213
     214  \param canvas Canvas Widget
     215  \sa canvas()
     216 */
     217void QwtPlot::setCanvas( QWidget *canvas )
     218{
     219    if ( canvas == d_data->canvas )
     220        return;
     221
     222    delete d_data->canvas;
     223    d_data->canvas = canvas;
     224
     225    if ( canvas )
     226    {
     227        canvas->setParent( this );
     228        canvas->installEventFilter( this );
     229
     230        if ( isVisible() )
     231            canvas->show();
     232    }
    102233}
    103234
     
    105236  \brief Adds handling of layout requests
    106237  \param event Event
     238
     239  \return See QFrame::event()
    107240*/
    108241bool QwtPlot::event( QEvent *event )
     
    122255}
    123256
     257/*!
     258  \brief Event filter
     259
     260  The plot handles the following events for the canvas:
     261
     262  - QEvent::Resize
     263    The canvas margins might depend on its size
     264
     265  - QEvent::ContentsRectChange
     266    The layout needs to be recalculated
     267
     268  \param object Object to be filtered
     269  \param event Event
     270
     271  \return See QFrame::eventFilter()
     272
     273  \sa updateCanvasMargins(), updateLayout()
     274*/
     275bool QwtPlot::eventFilter( QObject *object, QEvent *event )
     276{
     277    if ( object == d_data->canvas )
     278    {
     279        if ( event->type() == QEvent::Resize )
     280        {
     281            updateCanvasMargins();
     282        }
     283        else if ( event->type() == QEvent::ContentsRectChange )
     284        {
     285            updateLayout();
     286        }
     287    }
     288
     289    return QFrame::eventFilter( object, event );
     290}
     291
    124292//! Replots the plot if autoReplot() is \c true.
    125293void QwtPlot::autoRefresh()
     
    164332void QwtPlot::setTitle( const QString &title )
    165333{
    166     if ( title != d_data->lblTitle->text().text() )
    167     {
    168         d_data->lblTitle->setText( title );
     334    if ( title != d_data->titleLabel->text().text() )
     335    {
     336        d_data->titleLabel->setText( title );
    169337        updateLayout();
    170338    }
     
    177345void QwtPlot::setTitle( const QwtText &title )
    178346{
    179     if ( title != d_data->lblTitle->text() )
    180     {
    181         d_data->lblTitle->setText( title );
     347    if ( title != d_data->titleLabel->text() )
     348    {
     349        d_data->titleLabel->setText( title );
    182350        updateLayout();
    183351    }
    184352}
    185353
    186 //! \return the plot's title
     354//! \return Title of the plot
    187355QwtText QwtPlot::title() const
    188356{
    189     return d_data->lblTitle->text();
    190 }
    191 
    192 //! \return the plot's title
     357    return d_data->titleLabel->text();
     358}
     359
     360//! \return Title label widget.
     361QwtTextLabel *QwtPlot::titleLabel()
     362{
     363    return d_data->titleLabel;
     364}
     365
     366//! \return Title label widget.
     367const QwtTextLabel *QwtPlot::titleLabel() const
     368{
     369    return d_data->titleLabel;
     370}
     371
     372/*!
     373  Change the text the footer
     374  \param text New text of the footer
     375*/
     376void QwtPlot::setFooter( const QString &text )
     377{
     378    if ( text != d_data->footerLabel->text().text() )
     379    {
     380        d_data->footerLabel->setText( text );
     381        updateLayout();
     382    }
     383}
     384
     385/*!
     386  Change the text the footer
     387  \param text New text of the footer
     388*/
     389void QwtPlot::setFooter( const QwtText &text )
     390{
     391    if ( text != d_data->footerLabel->text() )
     392    {
     393        d_data->footerLabel->setText( text );
     394        updateLayout();
     395    }
     396}
     397
     398//! \return Text of the footer
     399QwtText QwtPlot::footer() const
     400{
     401    return d_data->footerLabel->text();
     402}
     403
     404//! \return Footer label widget.
     405QwtTextLabel *QwtPlot::footerLabel()
     406{
     407    return d_data->footerLabel;
     408}
     409
     410//! \return Footer label widget.
     411const QwtTextLabel *QwtPlot::footerLabel() const
     412{
     413    return d_data->footerLabel;
     414}
     415
     416/*!
     417   \brief Assign a new plot layout
     418
     419   \param layout Layout()
     420   \sa plotLayout()
     421 */
     422void QwtPlot::setPlotLayout( QwtPlotLayout *layout )
     423{
     424    if ( layout != d_data->layout )
     425    {
     426        delete d_data->layout;
     427        d_data->layout = layout;
     428
     429        updateLayout();
     430    }
     431}
     432
     433//! \return the plot's layout
    193434QwtPlotLayout *QwtPlot::plotLayout()
    194435{
     
    196437}
    197438
    198 //! \return the plot's titel label.
     439//! \return the plot's layout
    199440const QwtPlotLayout *QwtPlot::plotLayout() const
    200441{
    201442    return d_data->layout;
    202 }
    203 
    204 //! \return the plot's titel label.
    205 QwtTextLabel *QwtPlot::titleLabel()
    206 {
    207     return d_data->lblTitle;
    208 }
    209 
    210 /*!
    211   \return the plot's titel label.
    212 */
    213 const QwtTextLabel *QwtPlot::titleLabel() const
    214 {
    215     return d_data->lblTitle;
    216443}
    217444
     
    220447  \sa insertLegend()
    221448*/
    222 QwtLegend *QwtPlot::legend()
     449QwtAbstractLegend *QwtPlot::legend()
    223450{
    224451    return d_data->legend;
     
    229456  \sa insertLegend()
    230457*/
    231 const QwtLegend *QwtPlot::legend() const
     458const QwtAbstractLegend *QwtPlot::legend() const
    232459{
    233460    return d_data->legend;
     
    238465  \return the plot's canvas
    239466*/
    240 QwtPlotCanvas *QwtPlot::canvas()
     467QWidget *QwtPlot::canvas()
    241468{
    242469    return d_data->canvas;
     
    246473  \return the plot's canvas
    247474*/
    248 const QwtPlotCanvas *QwtPlot::canvas() const
     475const QWidget *QwtPlot::canvas() const
    249476{
    250477    return d_data->canvas;
     
    252479
    253480/*!
    254   Return sizeHint
     481  \return Size hint for the plot widget
    255482  \sa minimumSizeHint()
    256483*/
    257 
    258484QSize QwtPlot::sizeHint() const
    259485{
     
    316542  be refreshed explicitly in order to make changes visible.
    317543
    318   \sa setAutoReplot()
    319   \warning Calls canvas()->repaint, take care of infinite recursions
     544  \sa updateAxes(), setAutoReplot()
    320545*/
    321546void QwtPlot::replot()
     
    333558    QApplication::sendPostedEvents( this, QEvent::LayoutRequest );
    334559
    335     d_data->canvas->replot();
     560    if ( d_data->canvas )
     561    {
     562        const bool ok = QMetaObject::invokeMethod(
     563            d_data->canvas, "replot", Qt::DirectConnection );
     564        if ( !ok )
     565        {
     566            // fallback, when canvas has no a replot method
     567            d_data->canvas->update( d_data->canvas->contentsRect() );
     568        }
     569    }
    336570
    337571    setAutoReplot( doAutoReplot );
     
    347581
    348582    QRect titleRect = d_data->layout->titleRect().toRect();
     583    QRect footerRect = d_data->layout->footerRect().toRect();
    349584    QRect scaleRect[QwtPlot::axisCnt];
    350585    for ( int axisId = 0; axisId < axisCnt; axisId++ )
     
    353588    QRect canvasRect = d_data->layout->canvasRect().toRect();
    354589
    355     //
    356590    // resize and show the visible widgets
    357     //
    358     if ( !d_data->lblTitle->text().isEmpty() )
    359     {
    360         d_data->lblTitle->setGeometry( titleRect );
    361         if ( !d_data->lblTitle->isVisibleTo( this ) )
    362             d_data->lblTitle->show();
     591
     592    if ( !d_data->titleLabel->text().isEmpty() )
     593    {
     594        d_data->titleLabel->setGeometry( titleRect );
     595        if ( !d_data->titleLabel->isVisibleTo( this ) )
     596            d_data->titleLabel->show();
    363597    }
    364598    else
    365         d_data->lblTitle->hide();
     599        d_data->titleLabel->hide();
     600
     601    if ( !d_data->footerLabel->text().isEmpty() )
     602    {
     603        d_data->footerLabel->setGeometry( footerRect );
     604        if ( !d_data->footerLabel->isVisibleTo( this ) )
     605            d_data->footerLabel->show();
     606    }
     607    else
     608    {
     609        d_data->footerLabel->hide();
     610    }
    366611
    367612    for ( int axisId = 0; axisId < axisCnt; axisId++ )
    368613    {
     614        QwtScaleWidget* scaleWidget = axisWidget( axisId );
     615
    369616        if ( axisEnabled( axisId ) )
    370617        {
    371             axisWidget( axisId )->setGeometry( scaleRect[axisId] );
    372 
     618            if ( scaleRect[axisId] != scaleWidget->geometry() )
     619            {
     620                scaleWidget->setGeometry( scaleRect[axisId] );
     621
     622                int startDist, endDist;
     623                scaleWidget->getBorderDistHint( startDist, endDist );
     624                scaleWidget->setBorderDist( startDist, endDist );
     625            }
     626
     627#if 1
    373628            if ( axisId == xBottom || axisId == xTop )
    374629            {
     630                // do we need this code any longer ???
     631
    375632                QRegion r( scaleRect[axisId] );
    376633                if ( axisEnabled( yLeft ) )
    377                     r = r.subtract( QRegion( scaleRect[yLeft] ) );
     634                    r = r.subtracted( QRegion( scaleRect[yLeft] ) );
    378635                if ( axisEnabled( yRight ) )
    379                     r = r.subtract( QRegion( scaleRect[yRight] ) );
    380                 r.translate( -d_data->layout->scaleRect( axisId ).x(),
     636                    r = r.subtracted( QRegion( scaleRect[yRight] ) );
     637                r.translate( -scaleRect[ axisId ].x(),
    381638                    -scaleRect[axisId].y() );
    382639
    383                 axisWidget( axisId )->setMask( r );
     640                scaleWidget->setMask( r );
    384641            }
    385             if ( !axisWidget( axisId )->isVisibleTo( this ) )
    386                 axisWidget( axisId )->show();
     642#endif
     643            if ( !scaleWidget->isVisibleTo( this ) )
     644                scaleWidget->show();
    387645        }
    388646        else
    389             axisWidget( axisId )->hide();
    390     }
    391 
    392     if ( d_data->legend &&
    393         d_data->layout->legendPosition() != ExternalLegend )
    394     {
    395         if ( d_data->legend->itemCount() > 0 )
     647        {
     648            scaleWidget->hide();
     649        }
     650    }
     651
     652    if ( d_data->legend )
     653    {
     654        if ( d_data->legend->isEmpty() )
     655        {
     656            d_data->legend->hide();
     657        }
     658        else
    396659        {
    397660            d_data->legend->setGeometry( legendRect );
    398661            d_data->legend->show();
    399662        }
    400         else
    401             d_data->legend->hide();
    402663    }
    403664
     
    406667
    407668/*!
    408    Update the focus tab order
    409 
    410    The order is changed so that the canvas will be in front of the
    411    first legend item, or behind the last legend item - depending
    412    on the position of the legend.
    413 */
    414 
    415 void QwtPlot::updateTabOrder()
    416 {
    417     if ( d_data->canvas->focusPolicy() == Qt::NoFocus )
    418         return;
    419     if ( d_data->legend.isNull()
    420         || d_data->layout->legendPosition() == ExternalLegend
    421         || d_data->legend->legendItems().count() == 0 )
    422     {
    423         return;
    424     }
    425 
    426     // Depending on the position of the legend the
    427     // tab order will be changed that the canvas is
    428     // next to the last legend item, or before
    429     // the first one.
    430 
    431     const bool canvasFirst =
    432         d_data->layout->legendPosition() == QwtPlot::BottomLegend ||
    433         d_data->layout->legendPosition() == QwtPlot::RightLegend;
    434 
    435     QWidget *previous = NULL;
    436 
    437     QWidget *w = d_data->canvas;
    438     while ( ( w = w->nextInFocusChain() ) != d_data->canvas )
    439     {
    440         bool isLegendItem = false;
    441         if ( w->focusPolicy() != Qt::NoFocus
    442             && w->parent() && w->parent() == d_data->legend->contentsWidget() )
    443         {
    444             isLegendItem = true;
    445         }
    446 
    447         if ( canvasFirst )
    448         {
    449             if ( isLegendItem )
    450                 break;
    451 
    452             previous = w;
    453         }
    454         else
    455         {
    456             if ( isLegendItem )
    457                 previous = w;
    458             else
    459             {
    460                 if ( previous )
    461                     break;
    462             }
    463         }
    464     }
    465 
    466     if ( previous && previous != d_data->canvas )
    467         setTabOrder( previous, d_data->canvas );
     669  \brief Calculate the canvas margins
     670
     671  \param maps QwtPlot::axisCnt maps, mapping between plot and paint device coordinates
     672  \param canvasRect Bounding rectangle where to paint
     673  \param left Return parameter for the left margin
     674  \param top Return parameter for the top margin
     675  \param right Return parameter for the right margin
     676  \param bottom Return parameter for the bottom margin
     677
     678  Plot items might indicate, that they need some extra space
     679  at the borders of the canvas by the QwtPlotItem::Margins flag.
     680
     681  updateCanvasMargins(), QwtPlotItem::getCanvasMarginHint()
     682 */
     683void QwtPlot::getCanvasMarginsHint(
     684    const QwtScaleMap maps[], const QRectF &canvasRect,
     685    double &left, double &top, double &right, double &bottom) const
     686{
     687    left = top = right = bottom = -1.0;
     688
     689    const QwtPlotItemList& itmList = itemList();
     690    for ( QwtPlotItemIterator it = itmList.begin();
     691        it != itmList.end(); ++it )
     692    {
     693        const QwtPlotItem *item = *it;
     694        if ( item->testItemAttribute( QwtPlotItem::Margins ) )
     695        {
     696            double m[ QwtPlot::axisCnt ];
     697            item->getCanvasMarginHint(
     698                maps[ item->xAxis() ], maps[ item->yAxis() ],
     699                canvasRect, m[yLeft], m[xTop], m[yRight], m[xBottom] );
     700
     701            left = qMax( left, m[yLeft] );
     702            top = qMax( top, m[xTop] );
     703            right = qMax( right, m[yRight] );
     704            bottom = qMax( bottom, m[xBottom] );
     705        }
     706    }
     707}
     708
     709/*!
     710  \brief Update the canvas margins
     711
     712  Plot items might indicate, that they need some extra space
     713  at the borders of the canvas by the QwtPlotItem::Margins flag.
     714
     715  getCanvasMarginsHint(), QwtPlotItem::getCanvasMarginHint()
     716 */
     717void QwtPlot::updateCanvasMargins()
     718{
     719    QwtScaleMap maps[axisCnt];
     720    for ( int axisId = 0; axisId < axisCnt; axisId++ )
     721        maps[axisId] = canvasMap( axisId );
     722
     723    double margins[axisCnt];
     724    getCanvasMarginsHint( maps, canvas()->contentsRect(),
     725        margins[yLeft], margins[xTop], margins[yRight], margins[xBottom] );
     726   
     727    bool doUpdate = false;
     728    for ( int axisId = 0; axisId < axisCnt; axisId++ )
     729    {
     730        if ( margins[axisId] >= 0.0 )
     731        {
     732            const int m = qCeil( margins[axisId] );
     733            plotLayout()->setCanvasMargin( m, axisId);
     734            doUpdate = true;
     735        }
     736    }
     737
     738    if ( doUpdate )
     739        updateLayout();
    468740}
    469741
     
    488760/*!
    489761  Redraw the canvas items.
     762
    490763  \param painter Painter used for drawing
    491764  \param canvasRect Bounding rectangle where to paint
    492   \param map QwtPlot::axisCnt maps, mapping between plot and paint device coordinates
     765  \param maps QwtPlot::axisCnt maps, mapping between plot and paint device coordinates
     766
     767  \note Usually canvasRect is contentsRect() of the plot canvas.
     768        Due to a bug in Qt this rectangle might be wrong for certain
     769        frame styles ( f.e QFrame::Box ) and it might be necessary to
     770        fix the margins manually using QWidget::setContentsMargins()
    493771*/
    494772
    495773void QwtPlot::drawItems( QPainter *painter, const QRectF &canvasRect,
    496         const QwtScaleMap map[axisCnt] ) const
     774        const QwtScaleMap maps[axisCnt] ) const
    497775{
    498776    const QwtPlotItemList& itmList = itemList();
     
    507785            painter->setRenderHint( QPainter::Antialiasing,
    508786                item->testRenderHint( QwtPlotItem::RenderAntialiased ) );
     787            painter->setRenderHint( QPainter::HighQualityAntialiasing,
     788                item->testRenderHint( QwtPlotItem::RenderAntialiased ) );
    509789
    510790            item->draw( painter,
    511                 map[item->xAxis()], map[item->yAxis()],
     791                maps[item->xAxis()], maps[item->yAxis()],
    512792                canvasRect );
    513793
     
    532812    map.setTransformation( axisScaleEngine( axisId )->transformation() );
    533813
    534     const QwtScaleDiv *sd = axisScaleDiv( axisId );
    535     map.setScaleInterval( sd->lowerBound(), sd->upperBound() );
     814    const QwtScaleDiv &sd = axisScaleDiv( axisId );
     815    map.setScaleInterval( sd.lowerBound(), sd.upperBound() );
    536816
    537817    if ( axisEnabled( axisId ) )
     
    553833    else
    554834    {
    555         int margin = 0;
    556         if ( !plotLayout()->alignCanvasToScales() )
    557             margin = plotLayout()->canvasMargin( axisId );
    558 
    559835        const QRect &canvasRect = d_data->canvas->contentsRect();
    560836        if ( axisId == yLeft || axisId == yRight )
    561837        {
    562             map.setPaintInterval( canvasRect.bottom() - margin,
    563                 canvasRect.top() + margin );
     838            int top = 0;
     839            if ( !plotLayout()->alignCanvasToScale( xTop ) )
     840                top = plotLayout()->canvasMargin( xTop );
     841
     842            int bottom = 0;
     843            if ( !plotLayout()->alignCanvasToScale( xBottom ) )
     844                bottom = plotLayout()->canvasMargin( xBottom );
     845
     846            map.setPaintInterval( canvasRect.bottom() - bottom,
     847                canvasRect.top() + top );
    564848        }
    565849        else
    566850        {
    567             map.setPaintInterval( canvasRect.left() + margin,
    568                 canvasRect.right() - margin );
    569         }
    570     }
     851            int left = 0;
     852            if ( !plotLayout()->alignCanvasToScale( yLeft ) )
     853                left = plotLayout()->canvasMargin( yLeft );
     854
     855            int right = 0;
     856            if ( !plotLayout()->alignCanvasToScale( yRight ) )
     857                right = plotLayout()->canvasMargin( yRight );
     858
     859            map.setPaintInterval( canvasRect.left() + left,
     860                canvasRect.right() - right );
     861        }
     862    }
     863
    571864    return map;
    572865}
     
    575868  \brief Change the background of the plotting area
    576869
    577   Sets brush to QPalette::Window of all colorgroups of
     870  Sets brush to QPalette::Window of all color groups of
    578871  the palette of the canvas. Using canvas()->setPalette()
    579872  is a more powerful way to set these colors.
     
    585878{
    586879    QPalette pal = d_data->canvas->palette();
    587 
    588     for ( int i = 0; i < QPalette::NColorGroups; i++ )
    589         pal.setBrush( ( QPalette::ColorGroup )i, QPalette::Window, brush );
     880    pal.setBrush( QPalette::Window, brush );
    590881
    591882    canvas()->setPalette( pal );
     
    606897
    607898/*!
    608   \brief Change the border width of the plotting area
    609 
    610   Nothing else than canvas()->setLineWidth(w),
    611   left for compatibility only.
    612 
    613   \param width New border width
    614 */
    615 void QwtPlot::setCanvasLineWidth( int width )
    616 {
    617     canvas()->setLineWidth( width );
    618     updateLayout();
    619 }
    620 
    621 /*!
    622   Nothing else than: canvas()->lineWidth(),
    623   left for compatibility only.
    624 
    625   \return the border width of the plotting area
    626 */
    627 int QwtPlot::canvasLineWidth() const
    628 {
    629     return canvas()->lineWidth();
    630 }
    631 
    632 /*!
    633899  \return \c true if the specified axis exists, otherwise \c false
    634900  \param axisId axis index
     
    637903{
    638904    return ( ( axisId >= QwtPlot::yLeft ) && ( axisId < QwtPlot::axisCnt ) );
    639 }
    640 
    641 /*!
    642   Called internally when the legend has been clicked on.
    643   Emits a legendClicked() signal.
    644 */
    645 void QwtPlot::legendItemClicked()
    646 {
    647     if ( d_data->legend && sender()->isWidgetType() )
    648     {
    649         QwtPlotItem *plotItem =
    650             ( QwtPlotItem* )d_data->legend->find( ( QWidget * )sender() );
    651         if ( plotItem )
    652             Q_EMIT legendClicked( plotItem );
    653     }
    654 }
    655 
    656 /*!
    657   Called internally when the legend has been checked
    658   Emits a legendClicked() signal.
    659 */
    660 void QwtPlot::legendItemChecked( bool on )
    661 {
    662     if ( d_data->legend && sender()->isWidgetType() )
    663     {
    664         QwtPlotItem *plotItem =
    665             ( QwtPlotItem* )d_data->legend->find( ( QWidget * )sender() );
    666         if ( plotItem )
    667             Q_EMIT legendChecked( plotItem, on );
    668     }
    669905}
    670906
     
    677913  with a best fit number of columns from left to right.
    678914
    679   If pos != QwtPlot::ExternalLegend the plot widget will become
    680   parent of the legend. It will be deleted when the plot is deleted,
    681   or another legend is set with insertLegend().
     915  insertLegend() will set the plot widget as parent for the legend.
     916  The legend will be deleted in the destructor of the plot or when
     917  another legend is inserted.
     918
     919  Legends, that are not inserted into the layout of the plot widget
     920  need to connect to the legendDataChanged() signal. Calling updateLegend()
     921  initiates this signal for an initial update. When the application code
     922  wants to implement its own layout this also needs to be done for
     923  rendering plots to a document ( see QwtPlotRenderer ).
    682924
    683925  \param legend Legend
    684926  \param pos The legend's position. For top/left position the number
    685              of colums will be limited to 1, otherwise it will be set to
     927             of columns will be limited to 1, otherwise it will be set to
    686928             unlimited.
    687929
    688   \param ratio Ratio between legend and the bounding rect
    689                of title, canvas and axes. The legend will be shrinked
     930  \param ratio Ratio between legend and the bounding rectangle
     931               of title, canvas and axes. The legend will be shrunk
    690932               if it would need more space than the given ratio.
    691933               The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
     
    696938      QwtPlotLayout::setLegendPosition()
    697939*/
    698 void QwtPlot::insertLegend( QwtLegend *legend,
     940void QwtPlot::insertLegend( QwtAbstractLegend *legend,
    699941    QwtPlot::LegendPosition pos, double ratio )
    700942{
     
    710952        if ( d_data->legend )
    711953        {
    712             if ( pos != ExternalLegend )
    713             {
    714                 if ( d_data->legend->parent() != this )
    715                     d_data->legend->setParent( this );
    716             }
    717 
    718             const QwtPlotItemList& itmList = itemList();
    719             for ( QwtPlotItemIterator it = itmList.begin();
    720                 it != itmList.end(); ++it )
    721             {
    722                 ( *it )->updateLegend( d_data->legend );
    723             }
    724 
    725             QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>(
    726                 d_data->legend->contentsWidget()->layout() );
    727             if ( tl )
     954            connect( this,
     955                SIGNAL( legendDataChanged(
     956                    const QVariant &, const QList<QwtLegendData> & ) ),
     957                d_data->legend,
     958                SLOT( updateLegend(
     959                    const QVariant &, const QList<QwtLegendData> & ) )
     960            );
     961
     962            if ( d_data->legend->parent() != this )
     963                d_data->legend->setParent( this );
     964
     965            qwtEnableLegendItems( this, false );
     966            updateLegend();
     967            qwtEnableLegendItems( this, true );
     968
     969            QwtLegend *lgd = qobject_cast<QwtLegend *>( legend );
     970            if ( lgd )
    728971            {
    729972                switch ( d_data->layout->legendPosition() )
     
    731974                    case LeftLegend:
    732975                    case RightLegend:
    733                         tl->setMaxCols( 1 ); // 1 column: align vertical
     976                    {
     977                        if ( lgd->maxColumns() == 0     )
     978                            lgd->setMaxColumns( 1 ); // 1 column: align vertical
    734979                        break;
     980                    }
    735981                    case TopLegend:
    736982                    case BottomLegend:
    737                         tl->setMaxCols( 0 ); // unlimited
     983                    {
     984                        lgd->setMaxColumns( 0 ); // unlimited
    738985                        break;
    739                     case ExternalLegend:
     986                    }
     987                    default:
    740988                        break;
    741989                }
    742990            }
    743         }
    744         updateTabOrder();
     991
     992            QWidget *previousInChain = NULL;
     993            switch ( d_data->layout->legendPosition() )
     994            {
     995                case LeftLegend:
     996                {
     997                    previousInChain = axisWidget( QwtPlot::xTop );
     998                    break;
     999                }
     1000                case TopLegend:
     1001                {
     1002                    previousInChain = this;
     1003                    break;
     1004                }
     1005                case RightLegend:
     1006                {
     1007                    previousInChain = axisWidget( QwtPlot::yRight );
     1008                    break;
     1009                }
     1010                case BottomLegend:
     1011                {
     1012                    previousInChain = footerLabel();
     1013                    break;
     1014                }
     1015            }
     1016
     1017            if ( previousInChain )
     1018                qwtSetTabOrder( previousInChain, legend, true );
     1019        }
    7451020    }
    7461021
    7471022    updateLayout();
    7481023}
     1024
     1025/*!
     1026  Emit legendDataChanged() for all plot item
     1027
     1028  \sa QwtPlotItem::legendData(), legendDataChanged()
     1029 */
     1030void QwtPlot::updateLegend()
     1031{
     1032    const QwtPlotItemList& itmList = itemList();
     1033    for ( QwtPlotItemIterator it = itmList.begin();
     1034        it != itmList.end(); ++it )
     1035    {
     1036        updateLegend( *it );
     1037    }
     1038}
     1039
     1040/*!
     1041  Emit legendDataChanged() for a plot item
     1042
     1043  \param plotItem Plot item
     1044  \sa QwtPlotItem::legendData(), legendDataChanged()
     1045 */
     1046void QwtPlot::updateLegend( const QwtPlotItem *plotItem )
     1047{
     1048    if ( plotItem == NULL )
     1049        return;
     1050
     1051    QList<QwtLegendData> legendData;
     1052
     1053    if ( plotItem->testItemAttribute( QwtPlotItem::Legend ) )
     1054        legendData = plotItem->legendData();
     1055
     1056    const QVariant itemInfo = itemToInfo( const_cast< QwtPlotItem *>( plotItem) );
     1057    Q_EMIT legendDataChanged( itemInfo, legendData );
     1058}
     1059
     1060/*!
     1061  \brief Update all plot items interested in legend attributes
     1062
     1063  Call QwtPlotItem::updateLegend(), when the QwtPlotItem::LegendInterest
     1064  flag is set.
     1065
     1066  \param itemInfo Info about the plot item
     1067  \param legendData Entries to be displayed for the plot item ( usually 1 )
     1068
     1069  \sa QwtPlotItem::LegendInterest,
     1070      QwtPlotLegendItem, QwtPlotItem::updateLegend()
     1071 */
     1072void QwtPlot::updateLegendItems( const QVariant &itemInfo,
     1073    const QList<QwtLegendData> &legendData )
     1074{
     1075    QwtPlotItem *plotItem = infoToItem( itemInfo );
     1076    if ( plotItem )
     1077    {
     1078        const QwtPlotItemList& itmList = itemList();
     1079        for ( QwtPlotItemIterator it = itmList.begin();
     1080            it != itmList.end(); ++it )
     1081        {
     1082            QwtPlotItem *item = *it;
     1083            if ( item->testItemInterest( QwtPlotItem::LegendInterest ) )
     1084                item->updateLegend( plotItem, legendData );
     1085        }
     1086    }
     1087}
     1088
     1089/*!
     1090  \brief Attach/Detach a plot item
     1091
     1092  \param plotItem Plot item
     1093  \param on When true attach the item, otherwise detach it
     1094 */
     1095void QwtPlot::attachItem( QwtPlotItem *plotItem, bool on )
     1096{
     1097    if ( plotItem->testItemInterest( QwtPlotItem::LegendInterest ) )
     1098    {
     1099        // plotItem is some sort of legend
     1100
     1101        const QwtPlotItemList& itmList = itemList();
     1102        for ( QwtPlotItemIterator it = itmList.begin();
     1103            it != itmList.end(); ++it )
     1104        {
     1105            QwtPlotItem *item = *it;
     1106
     1107            QList<QwtLegendData> legendData;
     1108            if ( on && item->testItemAttribute( QwtPlotItem::Legend ) )
     1109            {
     1110                legendData = item->legendData();
     1111                plotItem->updateLegend( item, legendData );
     1112            }
     1113        }
     1114    }
     1115
     1116    if ( on )
     1117        insertItem( plotItem );
     1118    else
     1119        removeItem( plotItem );
     1120
     1121    Q_EMIT itemAttached( plotItem, on );
     1122
     1123    if ( plotItem->testItemAttribute( QwtPlotItem::Legend ) )
     1124    {
     1125        // the item wants to be represented on the legend
     1126
     1127        if ( on )
     1128        {
     1129            updateLegend( plotItem );
     1130        }
     1131        else
     1132        {
     1133            const QVariant itemInfo = itemToInfo( plotItem );
     1134            Q_EMIT legendDataChanged( itemInfo, QList<QwtLegendData>() );
     1135        }
     1136    }
     1137
     1138    autoRefresh();
     1139}
     1140
     1141/*!
     1142  \brief Build an information, that can be used to identify
     1143         a plot item on the legend.
     1144
     1145  The default implementation simply wraps the plot item
     1146  into a QVariant object. When overloading itemToInfo()
     1147  usually infoToItem() needs to reimplemeted too.
     1148
     1149\code
     1150    QVariant itemInfo;
     1151    qVariantSetValue( itemInfo, plotItem );
     1152\endcode
     1153
     1154  \param plotItem Plot item
     1155  \return Plot item embedded in a QVariant
     1156  \sa infoToItem()
     1157 */
     1158QVariant QwtPlot::itemToInfo( QwtPlotItem *plotItem ) const
     1159{
     1160    QVariant itemInfo;
     1161    qVariantSetValue( itemInfo, plotItem );
     1162
     1163    return itemInfo;
     1164}
     1165
     1166/*!
     1167  \brief Identify the plot item according to an item info object,
     1168         that has bee generated from itemToInfo().
     1169
     1170  The default implementation simply tries to unwrap a QwtPlotItem
     1171  pointer:
     1172
     1173\code
     1174    if ( itemInfo.canConvert<QwtPlotItem *>() )
     1175        return qvariant_cast<QwtPlotItem *>( itemInfo );
     1176\endcode
     1177  \param itemInfo Plot item
     1178  \return A plot item, when successful, otherwise a NULL pointer.
     1179  \sa itemToInfo()
     1180*/
     1181QwtPlotItem *QwtPlot::infoToItem( const QVariant &itemInfo ) const
     1182{
     1183    if ( itemInfo.canConvert<QwtPlotItem *>() )
     1184        return qvariant_cast<QwtPlotItem *>( itemInfo );
     1185
     1186    return NULL;
     1187}
     1188
     1189
  • trunk/BNC/qwt/qwt_plot.h

    r4271 r8127  
    1717#include "qwt_interval.h"
    1818#include <qframe.h>
     19#include <qlist.h>
     20#include <qvariant.h>
    1921
    2022class QwtPlotLayout;
    21 class QwtLegend;
     23class QwtAbstractLegend;
    2224class QwtScaleWidget;
    2325class QwtScaleEngine;
     
    2527class QwtScaleDraw;
    2628class QwtTextLabel;
    27 class QwtPlotCanvas;
    2829
    2930/*!
     
    3637  from QwtPlotItem.
    3738  A plot can have up to four axes, with each plot item attached to an x- and
    38   a y axis. The scales at the axes can be explicitely set (QwtScaleDiv), or
     39  a y axis. The scales at the axes can be explicitly set (QwtScaleDiv), or
    3940  are calculated from the plot items, using algorithms (QwtScaleEngine) which
    4041  can be configured separately for each axis.
     42
     43  The simpleplot example is a good starting point to see how to set up a
     44  plot widget.
    4145
    4246  \image html plot.png
     
    5660QwtPlotCurve *curve2 = new QwtPlotCurve("Curve 2");
    5761
    58 // copy the data into the curves
     62// connect or copy the data to the curves
    5963curve1->setData(...);
    6064curve2->setData(...);
     
    7175{
    7276    Q_OBJECT
     77
     78    Q_PROPERTY( QBrush canvasBackground
     79        READ canvasBackground WRITE setCanvasBackground )
     80    Q_PROPERTY( bool autoReplot READ autoReplot WRITE setAutoReplot )
     81
     82#if 0
     83    // This property is intended to configure the plot
     84    // widget from a special dialog in the deigner plugin.
     85    // Disabled until such a dialog has been implemented.
     86
    7387    Q_PROPERTY( QString propertiesDocument
    7488        READ grabProperties WRITE applyProperties )
     89#endif
    7590
    7691public:
     
    98113
    99114        \sa insertLegend()
    100         \note In case of ExternalLegend, the legend is not
    101               handled by QwtPlotRenderer
    102115     */
    103116    enum LegendPosition
     
    109122        RightLegend,
    110123
    111         //! The legend will be below QwtPlot::xBottom axis.
     124        //! The legend will be below the footer
    112125        BottomLegend,
    113126
    114         //! The legend will be between QwtPlot::xTop axis and the title.
    115         TopLegend,
    116 
    117         /*!
    118           External means that only the content of the legend
    119           will be handled by QwtPlot, but not its geometry.
    120           This type can be used to have a legend in an
    121           external window ( or on the canvas ).
    122          */
    123         ExternalLegend
     127        //! The legend will be above the title
     128        TopLegend
    124129    };
    125130
    126131    explicit QwtPlot( QWidget * = NULL );
    127     explicit QwtPlot( const QwtText &title, QWidget *p = NULL );
     132    explicit QwtPlot( const QwtText &title, QWidget * = NULL );
    128133
    129134    virtual ~QwtPlot();
     
    132137    QString grabProperties() const;
    133138
    134     void setAutoReplot( bool tf = true );
     139    void setAutoReplot( bool = true );
    135140    bool autoReplot() const;
    136141
    137142    // Layout
     143
     144    void setPlotLayout( QwtPlotLayout * );
    138145
    139146    QwtPlotLayout *plotLayout();
     
    149156    const QwtTextLabel *titleLabel() const;
    150157
     158    // Footer
     159
     160    void setFooter( const QString & );
     161    void setFooter( const QwtText &t );
     162    QwtText footer() const;
     163
     164    QwtTextLabel *footerLabel();
     165    const QwtTextLabel *footerLabel() const;
     166
    151167    // Canvas
    152168
    153     QwtPlotCanvas *canvas();
    154     const QwtPlotCanvas *canvas() const;
     169    void setCanvas( QWidget * );
     170
     171    QWidget *canvas();
     172    const QWidget *canvas() const;
    155173
    156174    void setCanvasBackground( const QBrush & );
    157175    QBrush canvasBackground() const;
    158 
    159     void setCanvasLineWidth( int w );
    160     int canvasLineWidth() const;
    161176
    162177    virtual QwtScaleMap canvasMap( int axisId ) const;
     
    187202    QwtInterval axisInterval( int axisId ) const;
    188203
    189     const QwtScaleDiv *axisScaleDiv( int axisId ) const;
    190     QwtScaleDiv *axisScaleDiv( int axisId );
     204    const QwtScaleDiv &axisScaleDiv( int axisId ) const;
    191205
    192206    const QwtScaleDraw *axisScaleDraw( int axisId ) const;
     
    211225    // Legend
    212226
    213     void insertLegend( QwtLegend *, LegendPosition = QwtPlot::RightLegend,
    214         double ratio = -1.0 );
    215 
    216     QwtLegend *legend();
    217     const QwtLegend *legend() const;
     227    void insertLegend( QwtAbstractLegend *,
     228        LegendPosition = QwtPlot::RightLegend, double ratio = -1.0 );
     229
     230    QwtAbstractLegend *legend();
     231    const QwtAbstractLegend *legend() const;
     232
     233    void updateLegend();
     234    void updateLegend( const QwtPlotItem * );
    218235
    219236    // Misc
     
    226243
    227244    void updateAxes();
     245    void updateCanvasMargins();
     246
     247    virtual void getCanvasMarginsHint(
     248        const QwtScaleMap maps[], const QRectF &canvasRect,
     249        double &left, double &top, double &right, double &bottom) const;
    228250
    229251    virtual bool event( QEvent * );
     252    virtual bool eventFilter( QObject *, QEvent * );
    230253
    231254    virtual void drawItems( QPainter *, const QRectF &,
    232255        const QwtScaleMap maps[axisCnt] ) const;
    233256
     257    virtual QVariant itemToInfo( QwtPlotItem * ) const;
     258    virtual QwtPlotItem *infoToItem( const QVariant & ) const;
     259
    234260Q_SIGNALS:
    235261    /*!
    236       A signal which is emitted when the user has clicked on
    237       a legend item, which is in QwtLegend::ClickableItem mode.
    238 
    239       \param plotItem Corresponding plot item of the
    240                  selected legend item
    241 
    242       \note clicks are disabled as default
    243       \sa QwtLegend::setItemMode(), QwtLegend::itemMode()
     262      A signal indicating, that an item has been attached/detached
     263
     264      \param plotItem Plot item
     265      \param on Attached/Detached
    244266     */
    245     void legendClicked( QwtPlotItem *plotItem );
     267    void itemAttached( QwtPlotItem *plotItem, bool on );
    246268
    247269    /*!
    248       A signal which is emitted when the user has clicked on
    249       a legend item, which is in QwtLegend::CheckableItem mode
    250 
    251       \param plotItem Corresponding plot item of the
    252                  selected legend item
    253       \param on True when the legen item is checked
    254 
    255       \note clicks are disabled as default
    256       \sa QwtLegend::setItemMode(), QwtLegend::itemMode()
     270      A signal with the attributes how to update
     271      the legend entries for a plot item.
     272
     273      \param itemInfo Info about a plot item, build from itemToInfo()
     274      \param data Attributes of the entries ( usually <= 1 ) for
     275                  the plot item.
     276
     277      \sa itemToInfo(), infoToItem(), QwtAbstractLegend::updateLegend()
    257278     */
    258 
    259     void legendChecked( QwtPlotItem *plotItem, bool on );
     279    void legendDataChanged( const QVariant &itemInfo,
     280        const QList<QwtLegendData> &data );
    260281
    261282public Q_SLOTS:
     
    263284    void autoRefresh();
    264285
    265 protected Q_SLOTS:
    266     virtual void legendItemClicked();
    267     virtual void legendItemChecked( bool );
    268 
    269286protected:
    270287    static bool axisValid( int axisId );
    271288
    272     virtual void updateTabOrder();
    273 
    274289    virtual void resizeEvent( QResizeEvent *e );
    275290
     291private Q_SLOTS:
     292    void updateLegendItems( const QVariant &itemInfo,
     293        const QList<QwtLegendData> &data );
     294
    276295private:
     296    friend class QwtPlotItem;
     297    void attachItem( QwtPlotItem *, bool );
     298
    277299    void initAxesData();
    278300    void deleteAxesData();
  • trunk/BNC/qwt/qwt_plot_axis.cpp

    r4271 r8127  
    2727    int maxMinor;
    2828
     29    bool isValid;
     30
    2931    QwtScaleDiv scaleDiv;
    3032    QwtScaleEngine *scaleEngine;
     
    5456    d_axisData[xBottom]->scaleWidget->setObjectName( "QwtPlotAxisXBottom" );
    5557
     58#if 1
     59    // better find the font sizes from the application font
    5660    QFont fscl( fontInfo().family(), 10 );
    5761    QFont fttl( fontInfo().family(), 12, QFont::Bold );
     62#endif
    5863
    5964    for ( axisId = 0; axisId < axisCnt; axisId++ )
    6065    {
    6166        AxisData &d = *d_axisData[axisId];
     67
     68        d.scaleEngine = new QwtLinearScaleEngine;
     69
     70        d.scaleWidget->setTransformation(
     71            d.scaleEngine->transformation() );
    6272
    6373        d.scaleWidget->setFont( fscl );
     
    7787        d.maxMajor = 8;
    7888
    79         d.scaleEngine = new QwtLinearScaleEngine;
    80 
    81         d.scaleDiv.invalidate();
     89
     90        d.isValid = false;
    8291    }
    8392
     
    99108
    100109/*!
    101   \return specified axis, or NULL if axisId is invalid.
    102   \param axisId axis index
     110  \return Scale widget of the specified axis, or NULL if axisId is invalid.
     111  \param axisId Axis index
    103112*/
    104113const QwtScaleWidget *QwtPlot::axisWidget( int axisId ) const
     
    111120
    112121/*!
    113   \return specified axis, or NULL if axisId is invalid.
    114   \param axisId axis index
     122  \return Scale widget of the specified axis, or NULL if axisId is invalid.
     123  \param axisId Axis index
    115124*/
    116125QwtScaleWidget *QwtPlot::axisWidget( int axisId )
     
    123132
    124133/*!
    125    Change the scale engine for an axis
    126 
    127   \param axisId axis index
     134  Change the scale engine for an axis
     135
     136  \param axisId Axis index
    128137  \param scaleEngine Scale engine
    129138
     
    139148        d.scaleEngine = scaleEngine;
    140149
    141         d.scaleDiv.invalidate();
     150        d_axisData[axisId]->scaleWidget->setTransformation(
     151            scaleEngine->transformation() );
     152
     153        d.isValid = false;
    142154
    143155        autoRefresh();
     
    146158
    147159/*!
    148   \param axisId axis index
     160  \param axisId Axis index
    149161  \return Scale engine for a specific axis
    150162*/
     
    158170
    159171/*!
    160   \param axisId axis index
     172  \param axisId Axis index
    161173  \return Scale engine for a specific axis
    162174*/
     
    169181}
    170182/*!
    171   \return \c true if autoscaling is enabled
    172   \param axisId axis index
     183  \return \c True, if autoscaling is enabled
     184  \param axisId Axis index
    173185*/
    174186bool QwtPlot::axisAutoScale( int axisId ) const
     
    182194
    183195/*!
    184   \return \c true if a specified axis is enabled
    185   \param axisId axis index
     196  \return \c True, if a specified axis is enabled
     197  \param axisId Axis index
    186198*/
    187199bool QwtPlot::axisEnabled( int axisId ) const
     
    194206
    195207/*!
    196   \return the font of the scale labels for a specified axis
    197   \param axisId axis index
     208  \return The font of the scale labels for a specified axis
     209  \param axisId Axis index
    198210*/
    199211QFont QwtPlot::axisFont( int axisId ) const
     
    207219
    208220/*!
    209   \return the maximum number of major ticks for a specified axis
    210   \param axisId axis index
    211   \sa setAxisMaxMajor()
     221  \return The maximum number of major ticks for a specified axis
     222  \param axisId Axis index
     223  \sa setAxisMaxMajor(), QwtScaleEngine::divideScale()
    212224*/
    213225int QwtPlot::axisMaxMajor( int axisId ) const
     
    221233/*!
    222234  \return the maximum number of minor ticks for a specified axis
    223   \param axisId axis index
    224   \sa setAxisMaxMinor()
     235  \param axisId Axis index
     236  \sa setAxisMaxMinor(), QwtScaleEngine::divideScale()
    225237*/
    226238int QwtPlot::axisMaxMinor( int axisId ) const
     
    235247  \brief Return the scale division of a specified axis
    236248
    237   axisScaleDiv(axisId)->lowerBound(), axisScaleDiv(axisId)->upperBound()
     249  axisScaleDiv(axisId).lowerBound(), axisScaleDiv(axisId).upperBound()
    238250  are the current limits of the axis scale.
    239251
    240   \param axisId axis index
     252  \param axisId Axis index
    241253  \return Scale division
    242254
    243   \sa QwtScaleDiv, setAxisScaleDiv()
    244 */
    245 const QwtScaleDiv *QwtPlot::axisScaleDiv( int axisId ) const
     255  \sa QwtScaleDiv, setAxisScaleDiv(), QwtScaleEngine::divideScale()
     256*/
     257const QwtScaleDiv &QwtPlot::axisScaleDiv( int axisId ) const
     258{
     259    return d_axisData[axisId]->scaleDiv;
     260}
     261
     262/*!
     263  \brief Return the scale draw of a specified axis
     264
     265  \param axisId Axis index
     266  \return Specified scaleDraw for axis, or NULL if axis is invalid.
     267*/
     268const QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId ) const
    246269{
    247270    if ( !axisValid( axisId ) )
    248271        return NULL;
    249272
    250     return &d_axisData[axisId]->scaleDiv;
    251 }
    252 
    253 /*!
    254   \brief Return the scale division of a specified axis
    255 
    256   axisScaleDiv(axisId)->lowerBound(), axisScaleDiv(axisId)->upperBound()
    257   are the current limits of the axis scale.
    258 
    259   \param axisId axis index
    260   \return Scale division
    261 
    262   \sa QwtScaleDiv, setAxisScaleDiv()
    263 */
    264 QwtScaleDiv *QwtPlot::axisScaleDiv( int axisId )
     273    return axisWidget( axisId )->scaleDraw();
     274}
     275
     276/*!
     277  \brief Return the scale draw of a specified axis
     278
     279  \param axisId Axis index
     280  \return Specified scaleDraw for axis, or NULL if axis is invalid.
     281*/
     282QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId )
    265283{
    266284    if ( !axisValid( axisId ) )
    267285        return NULL;
    268286
    269     return &d_axisData[axisId]->scaleDiv;
    270 }
    271 
    272 /*!
    273   \returns the scale draw of a specified axis
    274   \param axisId axis index
    275   \return specified scaleDraw for axis, or NULL if axis is invalid.
    276   \sa QwtScaleDraw
    277 */
    278 const QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId ) const
    279 {
    280     if ( !axisValid( axisId ) )
    281         return NULL;
    282 
    283287    return axisWidget( axisId )->scaleDraw();
    284288}
    285289
    286290/*!
    287   \returns the scale draw of a specified axis
    288   \param axisId axis index
    289   \return specified scaleDraw for axis, or NULL if axis is invalid.
    290   \sa QwtScaleDraw
    291 */
    292 QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId )
    293 {
    294     if ( !axisValid( axisId ) )
    295         return NULL;
    296 
    297     return axisWidget( axisId )->scaleDraw();
    298 }
    299 
    300 /*!
    301    Return the step size parameter, that has been set
    302    in setAxisScale. This doesn't need to be the step size
    303    of the current scale.
    304 
    305   \param axisId axis index
     291  \brief Return the step size parameter that has been set in setAxisScale.
     292
     293  This doesn't need to be the step size of the current scale.
     294
     295  \param axisId Axis index
    306296  \return step size parameter value
    307297
    308    \sa setAxisScale()
     298   \sa setAxisScale(), QwtScaleEngine::divideScale()
    309299*/
    310300double QwtPlot::axisStepSize( int axisId ) const
     
    321311  This is only a convenience function for axisScaleDiv( axisId )->interval();
    322312 
    323   \param axisId axis index
     313  \param axisId Axis index
    324314  \return Scale interval
    325315
     
    335325
    336326/*!
    337   \return the title of a specified axis
    338   \param axisId axis index
     327  \return Title of a specified axis
     328  \param axisId Axis index
    339329*/
    340330QwtText QwtPlot::axisTitle( int axisId ) const
     
    355345
    356346  Only xBottom and yLeft are enabled by default.
    357   \param axisId axis index
     347
     348  \param axisId Axis index
    358349  \param tf \c true (enabled) or \c false (disabled)
    359350*/
     
    370361  Transform the x or y coordinate of a position in the
    371362  drawing region into a value.
    372   \param axisId axis index
     363
     364  \param axisId Axis index
    373365  \param pos position
     366
     367  \return Position as axis coordinate
     368
    374369  \warning The position can be an x or a y coordinate,
    375370           depending on the specified axis.
     
    386381/*!
    387382  \brief Transform a value into a coordinate in the plotting region
    388   \param axisId axis index
     383
     384  \param axisId Axis index
    389385  \param value value
    390   \return X or y coordinate in the plotting region corresponding
     386  \return X or Y coordinate in the plotting region corresponding
    391387          to the value.
    392388*/
     
    401397/*!
    402398  \brief Change the font of an axis
    403   \param axisId axis index
    404   \param f font
     399
     400  \param axisId Axis index
     401  \param font Font
    405402  \warning This function changes the font of the tick labels,
    406403           not of the axis title.
    407404*/
    408 void QwtPlot::setAxisFont( int axisId, const QFont &f )
    409 {
    410     if ( axisValid( axisId ) )
    411         axisWidget( axisId )->setFont( f );
     405void QwtPlot::setAxisFont( int axisId, const QFont &font )
     406{
     407    if ( axisValid( axisId ) )
     408        axisWidget( axisId )->setFont( font );
    412409}
    413410
     
    418415  after a fixed scale has been set. Autoscaling is enabled by default.
    419416
    420   \param axisId axis index
     417  \param axisId Axis index
    421418  \param on On/Off
    422419  \sa setAxisScale(), setAxisScaleDiv(), updateAxes()
     
    436433/*!
    437434  \brief Disable autoscaling and specify a fixed scale for a selected axis.
    438   \param axisId axis index
    439   \param min
    440   \param max minimum and maximum of the scale
     435
     436  In updateAxes() the scale engine calculates a scale division from the
     437  specified parameters, that will be assigned to the scale widget. So
     438  updates of the scale widget usually happen delayed with the next replot.
     439
     440  \param axisId Axis index
     441  \param min Minimum of the scale
     442  \param max Maximum of the scale
    441443  \param stepSize Major step size. If <code>step == 0</code>, the step size is
    442             calculated automatically using the maxMajor setting.
    443   \sa setAxisMaxMajor(), setAxisAutoScale(), axisStepSize()
     444                  calculated automatically using the maxMajor setting.
     445
     446  \sa setAxisMaxMajor(), setAxisAutoScale(), axisStepSize(), QwtScaleEngine::divideScale()
    444447*/
    445448void QwtPlot::setAxisScale( int axisId, double min, double max, double stepSize )
     
    450453
    451454        d.doAutoScale = false;
    452         d.scaleDiv.invalidate();
     455        d.isValid = false;
    453456
    454457        d.minValue = min;
     
    462465/*!
    463466  \brief Disable autoscaling and specify a fixed scale for a selected axis.
    464   \param axisId axis index
     467
     468  The scale division will be stored locally only until the next call
     469  of updateAxes(). So updates of the scale widget usually happen delayed with
     470  the next replot.
     471
     472  \param axisId Axis index
    465473  \param scaleDiv Scale division
     474
    466475  \sa setAxisScale(), setAxisAutoScale()
    467476*/
     
    474483        d.doAutoScale = false;
    475484        d.scaleDiv = scaleDiv;
     485        d.isValid = true;
    476486
    477487        autoRefresh();
     
    481491/*!
    482492  \brief Set a scale draw
    483   \param axisId axis index
    484   \param scaleDraw object responsible for drawing scales.
     493
     494  \param axisId Axis index
     495  \param scaleDraw Object responsible for drawing scales.
    485496
    486497  By passing scaleDraw it is possible to extend QwtScaleDraw
     
    505516/*!
    506517  Change the alignment of the tick labels
    507   \param axisId axis index
     518
     519  \param axisId Axis index
    508520  \param alignment Or'd Qt::AlignmentFlags see <qnamespace.h>
     521
    509522  \sa QwtScaleDraw::setLabelAlignment()
    510523*/
     
    517530/*!
    518531  Rotate all tick labels
    519   \param axisId axis index
     532
     533  \param axisId Axis index
    520534  \param rotation Angle in degrees. When changing the label rotation,
    521535                  the label alignment might be adjusted too.
     536
    522537  \sa QwtScaleDraw::setLabelRotation(), setAxisLabelAlignment()
    523538*/
     
    531546  Set the maximum number of minor scale intervals for a specified axis
    532547
    533   \param axisId axis index
    534   \param maxMinor maximum number of minor steps
     548  \param axisId Axis index
     549  \param maxMinor Maximum number of minor steps
     550
    535551  \sa axisMaxMinor()
    536552*/
     
    545561        {
    546562            d.maxMinor = maxMinor;
    547             d.scaleDiv.invalidate();
     563            d.isValid = false;
    548564            autoRefresh();
    549565        }
     
    554570  Set the maximum number of major scale intervals for a specified axis
    555571
    556   \param axisId axis index
    557   \param maxMajor maximum number of major steps
     572  \param axisId Axis index
     573  \param maxMajor Maximum number of major steps
     574
    558575  \sa axisMaxMajor()
    559576*/
     
    568585        {
    569586            d.maxMajor = maxMajor;
    570             d.scaleDiv.invalidate();
     587            d.isValid = false;
    571588            autoRefresh();
    572589        }
     
    576593/*!
    577594  \brief Change the title of a specified axis
    578   \param axisId axis index
     595
     596  \param axisId Axis index
    579597  \param title axis title
    580598*/
     
    587605/*!
    588606  \brief Change the title of a specified axis
    589   \param axisId axis index
    590   \param title axis title
     607
     608  \param axisId Axis index
     609  \param title Axis title
    591610*/
    592611void QwtPlot::setAxisTitle( int axisId, const QwtText &title )
     
    596615}
    597616
    598 //! Rebuild the scales
     617/*!
     618  \brief Rebuild the axes scales
     619
     620  In case of autoscaling the boundaries of a scale are calculated
     621  from the bounding rectangles of all plot items, having the
     622  QwtPlotItem::AutoScale flag enabled ( QwtScaleEngine::autoScale() ).
     623  Then a scale division is calculated ( QwtScaleEngine::didvideScale() )
     624  and assigned to scale widget.
     625
     626  When the scale boundaries have been assigned with setAxisScale() a
     627  scale division is calculated ( QwtScaleEngine::didvideScale() )
     628  for this interval and assigned to the scale widget.
     629
     630  When the scale has been set explicitly by setAxisScaleDiv() the
     631  locally stored scale division gets assigned to the scale widget.
     632
     633  The scale widget indicates modifications by emitting a
     634  QwtScaleWidget::scaleDivChanged() signal.
     635
     636  updateAxes() is usually called by replot().
     637
     638  \sa setAxisAutoScale(), setAxisScale(), setAxisScaleDiv(), replot()
     639      QwtPlotItem::boundingRect()
     640 */
    599641void QwtPlot::updateAxes()
    600642{
     
    620662        {
    621663            const QRectF rect = item->boundingRect();
    622             intv[item->xAxis()] |= QwtInterval( rect.left(), rect.right() );
    623             intv[item->yAxis()] |= QwtInterval( rect.top(), rect.bottom() );
     664
     665            if ( rect.width() >= 0.0 )
     666                intv[item->xAxis()] |= QwtInterval( rect.left(), rect.right() );
     667
     668            if ( rect.height() >= 0.0 )
     669                intv[item->yAxis()] |= QwtInterval( rect.top(), rect.bottom() );
    624670        }
    625671    }
     
    637683        if ( d.doAutoScale && intv[axisId].isValid() )
    638684        {
    639             d.scaleDiv.invalidate();
     685            d.isValid = false;
    640686
    641687            minValue = intv[axisId].minValue();
     
    645691                minValue, maxValue, stepSize );
    646692        }
    647         if ( !d.scaleDiv.isValid() )
     693        if ( !d.isValid )
    648694        {
    649695            d.scaleDiv = d.scaleEngine->divideScale(
    650696                minValue, maxValue,
    651697                d.maxMajor, d.maxMinor, stepSize );
     698            d.isValid = true;
    652699        }
    653700
    654701        QwtScaleWidget *scaleWidget = axisWidget( axisId );
    655         scaleWidget->setScaleDiv(
    656             d.scaleEngine->transformation(), d.scaleDiv );
     702        scaleWidget->setScaleDiv( d.scaleDiv );
    657703
    658704        int startDist, endDist;
     
    664710    {
    665711        QwtPlotItem *item = *it;
    666         item->updateScaleDiv( *axisScaleDiv( item->xAxis() ),
    667             *axisScaleDiv( item->yAxis() ) );
    668     }
    669 }
    670 
     712        if ( item->testItemInterest( QwtPlotItem::ScaleInterest ) )
     713        {
     714            item->updateScaleDiv( axisScaleDiv( item->xAxis() ),
     715                axisScaleDiv( item->yAxis() ) );
     716        }
     717    }
     718}
     719
  • trunk/BNC/qwt/qwt_plot_canvas.cpp

    r4271 r8127  
    1818#include <qpaintengine.h>
    1919#include <qevent.h>
    20 #include <qbitmap.h>
    21 #ifdef Q_WS_X11
    22 #include <qx11info_x11.h>
    23 #endif
    2420
    2521class QwtStyleSheetRecorder: public QwtNullPaintDevice
     
    2723public:
    2824    QwtStyleSheetRecorder( const QSize &size ):
    29         QwtNullPaintDevice( QPaintEngine::AllFeatures )
    30     {
    31         setSize( size );
     25        d_size( size )
     26    {
    3227    }
    3328
     
    5651    virtual void drawPath( const QPainterPath &path )
    5752    {
    58         const QRectF rect( QPointF( 0.0, 0.0 ) , size() );
     53        const QRectF rect( QPointF( 0.0, 0.0 ), d_size );
    5954        if ( path.controlPointRect().contains( rect.center() ) )
    6055        {
     
    117112    }
    118113
     114protected:
     115    virtual QSize sizeMetrics() const
     116    {
     117        return d_size;
     118    }
     119
    119120private:
    120121    void alignCornerRects( const QRectF &rect )
     
    154155
    155156private:
     157    const QSize d_size;
     158
    156159    QPen d_pen;
    157160    QBrush d_brush;
     
    159162};
    160163
    161 static void qwtDrawBackground( QPainter *painter, QWidget *widget )
    162 {
     164static void qwtDrawBackground( QPainter *painter, QwtPlotCanvas *canvas )
     165{
     166    painter->save();
     167
     168    const QPainterPath borderClip = canvas->borderPath( canvas->rect() );
     169    if ( !borderClip.isEmpty() )
     170        painter->setClipPath( borderClip, Qt::IntersectClip );
     171
    163172    const QBrush &brush =
    164         widget->palette().brush( widget->backgroundRole() );
     173        canvas->palette().brush( canvas->backgroundRole() );
    165174
    166175    if ( brush.style() == Qt::TexturePattern )
    167176    {
    168         QPixmap pm( widget->size() );
    169         pm.fill( widget, 0, 0 );
     177        QPixmap pm( canvas->size() );
     178        QwtPainter::fillPixmap( canvas, pm );
    170179        painter->drawPixmap( 0, 0, pm );
    171180    }
     
    176185        if ( brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode )
    177186        {
    178             rects += widget->rect();
     187            rects += canvas->rect();
    179188        }
    180189        else
     
    215224            }
    216225           
    217             QImage image( widget->size(), format );
     226            QImage image( canvas->size(), format );
    218227
    219228            QPainter p( &image );
     
    229238        else
    230239        {
    231             painter->save();
    232 
    233240            painter->setPen( Qt::NoPen );
    234241            painter->setBrush( brush );
    235242
    236243            painter->drawRects( rects );
    237 
    238             painter->restore();
    239244        }
    240245    }
    241246    else
    242247    {
    243         painter->save();
    244 
    245248        painter->setPen( Qt::NoPen );
    246249        painter->setBrush( brush );
     
    248251        painter->drawRects( painter->clipRegion().rects() );
    249252
    250         painter->restore();
    251     }
     253    }
     254
     255    painter->restore();
    252256}
    253257
     
    256260    if ( path.elementCount() == 4 )
    257261    {
    258         QPainterPath::Element &el0 =
    259             const_cast<QPainterPath::Element &>( path.elementAt(0) );
    260         QPainterPath::Element &el2 =
    261             const_cast<QPainterPath::Element &>( path.elementAt(3) );
    262 
    263         qSwap( el0.x, el2.x );
    264         qSwap( el0.y, el2.y );
     262        QPainterPath::Element el0 = path.elementAt(0);
     263        QPainterPath::Element el3 = path.elementAt(3);
     264
     265        path.setElementPositionAt( 0, el3.x, el3.y );
     266        path.setElementPositionAt( 3, el0.x, el0.y );
    265267    }
    266268}
     
    439441        {
    440442            QPixmap pm( rect.size() );
    441             pm.fill( bgWidget, widget->mapTo( bgWidget, rect.topLeft() ) );
     443            QwtPainter::fillPixmap( bgWidget, pm, widget->mapTo( bgWidget, rect.topLeft() ) );
    442444            painter->drawPixmap( rect, pm );
    443445        }
     
    468470        if ( radius > 0.0 )
    469471        {
    470             QSize sz( radius, radius );
     472            QSizeF sz( radius, radius );
    471473
    472474            rects += QRectF( r.topLeft(), sz );
     
    519521};
    520522
    521 //! Sets a cross cursor, enables QwtPlotCanvas::BackingStore
    522 
     523/*!
     524  \brief Constructor
     525
     526  \param plot Parent plot widget
     527  \sa QwtPlot::setCanvas()
     528*/
    523529QwtPlotCanvas::QwtPlotCanvas( QwtPlot *plot ):
    524530    QFrame( plot )
    525531{
     532    setFrameStyle( QFrame::Panel | QFrame::Sunken );
     533    setLineWidth( 2 );
     534
    526535    d_data = new PrivateData;
    527536
     
    545554QwtPlot *QwtPlotCanvas::plot()
    546555{
    547     return qobject_cast<QwtPlot *>( parentWidget() );
     556    return qobject_cast<QwtPlot *>( parent() );
    548557}
    549558
     
    551560const QwtPlot *QwtPlotCanvas::plot() const
    552561{
    553     return qobject_cast<const QwtPlot *>( parentWidget() );
     562    return qobject_cast<const QwtPlot *>( parent() );
    554563}
    555564
     
    583592                if ( isVisible() )
    584593                {
     594#if QT_VERSION >= 0x050000
     595                    *d_data->backingStore = grab( rect() );
     596#else
    585597                    *d_data->backingStore =
    586598                        QPixmap::grabWidget( this, rect() );
     599#endif
    587600                }
    588601            }
     
    610623
    611624/*!
    612   Test wether a paint attribute is enabled
     625  Test whether a paint attribute is enabled
    613626
    614627  \param attribute Paint attribute
    615   \return true if the attribute is enabled
     628  \return true, when attribute is enabled
    616629  \sa setPaintAttribute()
    617630*/
     
    676689/*!
    677690  Qt event handler for QEvent::PolishRequest and QEvent::StyleChange
     691
    678692  \param event Qt Event
     693  \return See QFrame::event()
    679694*/
    680695bool QwtPlotCanvas::event( QEvent *event )
     
    716731        if ( bs.size() != size() )
    717732        {
    718             bs = QPixmap( size() );
    719 
    720 #ifdef Q_WS_X11
    721             if ( bs.x11Info().screen() != x11Info().screen() )
    722                 bs.x11SetScreen( x11Info().screen() );
    723 #endif
     733            bs = QwtPainter::backingStore( this, size() );
    724734
    725735            if ( testAttribute(Qt::WA_StyledBackground) )
     
    734744                if ( d_data->borderRadius <= 0.0 )
    735745                {
    736                     bs.fill( this, 0, 0 );
     746                    QwtPainter::fillPixmap( this, bs );
    737747                    p.begin( &bs );
    738748                    drawCanvas( &p, false );
     
    771781            {
    772782                if ( autoFillBackground() )
     783                {
     784                    qwtFillBackground( &painter, this );
    773785                    qwtDrawBackground( &painter, this );
     786                }
     787            }
     788            else
     789            {
     790                if ( borderRadius() > 0.0 )
     791                {
     792                    QPainterPath clipPath;
     793                    clipPath.addRect( rect() );
     794                    clipPath = clipPath.subtracted( borderPath( rect() ) );
     795
     796                    painter.save();
     797
     798                    painter.setClipPath( clipPath, Qt::IntersectClip );
     799                    qwtFillBackground( &painter, this );
     800                    qwtDrawBackground( &painter, this );
     801
     802                    painter.restore();
     803                }
    774804            }
    775805
     
    838868            painter->setBrush( palette().brush( backgroundRole() ) );
    839869
    840             if ( d_data->borderRadius > 0.0 )
     870            if ( d_data->borderRadius > 0.0 && ( rect() == frameRect() ) )
    841871            {
    842872                if ( frameWidth() > 0 )
     
    853883            else
    854884            {
    855                 painter->drawRect( contentsRect() );
     885                painter->drawRect( rect() );
    856886            }
    857887        }
     
    870900    {
    871901        if ( d_data->borderRadius > 0.0 )
    872             painter->setClipPath( borderPath( rect() ), Qt::IntersectClip );
     902            painter->setClipPath( borderPath( frameRect() ), Qt::IntersectClip );
    873903        else
    874904            painter->setClipRect( contentsRect(), Qt::IntersectClip );
     
    892922
    893923  \param painter Painter
    894   \sa setBorderRadius(), QFrame::drawFrame()
     924  \sa setBorderRadius()
    895925*/
    896926void QwtPlotCanvas::drawBorder( QPainter *painter )
     
    900930        if ( frameWidth() > 0 )
    901931        {
    902             QwtPainter::drawRoundedFrame( painter, QRectF( rect() ),
     932            QwtPainter::drawRoundedFrame( painter, QRectF( frameRect() ),
    903933                d_data->borderRadius, d_data->borderRadius,
    904934                palette(), frameWidth(), frameStyle() );
     
    907937    else
    908938    {
     939#if QT_VERSION >= 0x040500
     940#if QT_VERSION < 0x050000
     941        QStyleOptionFrameV3 opt;
     942#else
     943        QStyleOptionFrame opt;
     944#endif
     945        opt.init(this);
     946
     947        int frameShape  = frameStyle() & QFrame::Shape_Mask;
     948        int frameShadow = frameStyle() & QFrame::Shadow_Mask;
     949
     950        opt.frameShape = QFrame::Shape( int( opt.frameShape ) | frameShape );
     951#if 0
     952        opt.rect = frameRect();
     953#endif
     954
     955        switch (frameShape)
     956        {
     957            case QFrame::Box:
     958            case QFrame::HLine:
     959            case QFrame::VLine:
     960            case QFrame::StyledPanel:
     961            case QFrame::Panel:
     962            {
     963                opt.lineWidth = lineWidth();
     964                opt.midLineWidth = midLineWidth();
     965                break;
     966            }
     967            default:
     968            {
     969                opt.lineWidth = frameWidth();
     970                break;
     971            }
     972        }
     973   
     974        if ( frameShadow == Sunken )
     975            opt.state |= QStyle::State_Sunken;
     976        else if ( frameShadow == Raised )
     977            opt.state |= QStyle::State_Raised;
     978
     979        style()->drawControl(QStyle::CE_ShapedFrame, &opt, painter, this);
     980#else
    909981        drawFrame( painter );
     982#endif
    910983    }
    911984}
     
    9501023}
    9511024
    952 //! Update the cached informations about the current style sheet
     1025//! Update the cached information about the current style sheet
    9531026void QwtPlotCanvas::updateStyleSheetInfo()
    9541027{
     
    10271100    return QPainterPath();
    10281101}
    1029 
    1030 /*!
    1031    Calculate a mask, that can be used to clip away the border frame
    1032 
    1033    \param size Size including the frame
    1034 */
    1035 QBitmap QwtPlotCanvas::borderMask( const QSize &size ) const
    1036 {
    1037     const QRect r( 0, 0, size.width(), size.height() );
    1038 
    1039     const QPainterPath path = borderPath( r );
    1040     if ( path.isEmpty() )
    1041         return QBitmap();
    1042 
    1043     QImage image( size, QImage::Format_ARGB32_Premultiplied );
    1044     image.fill( Qt::color0 );
    1045 
    1046     QPainter painter( &image );
    1047     painter.setClipPath( path );
    1048     painter.fillRect( r, Qt::color1 );
    1049 
    1050     // now erase the frame
    1051 
    1052     painter.setCompositionMode( QPainter::CompositionMode_DestinationOut );
    1053 
    1054     if ( testAttribute(Qt::WA_StyledBackground ) )
    1055     {
    1056         QStyleOptionFrame opt;
    1057         opt.initFrom(this);
    1058         opt.rect = r;
    1059         style()->drawPrimitive( QStyle::PE_Frame, &opt, &painter, this );
    1060     }
    1061     else
    1062     {
    1063         if ( d_data->borderRadius > 0 && frameWidth() > 0 )
    1064         {
    1065             painter.setPen( QPen( Qt::color1, frameWidth() ) );
    1066             painter.setBrush( Qt::NoBrush );
    1067             painter.setRenderHint( QPainter::Antialiasing, true );
    1068 
    1069             painter.drawPath( path );
    1070         }
    1071     }
    1072 
    1073     painter.end();
    1074 
    1075     const QImage mask = image.createMaskFromColor(
    1076         QColor( Qt::color1 ).rgb(), Qt::MaskOutColor );
    1077 
    1078     return QBitmap::fromImage( mask );
    1079 }
  • trunk/BNC/qwt/qwt_plot_canvas.h

    r4271 r8127  
    1313#include "qwt_global.h"
    1414#include <qframe.h>
    15 #include <qpen.h>
    1615#include <qpainterpath.h>
    17 #include <qbitmap.h>
    1816
    1917class QwtPlot;
     
    2220/*!
    2321  \brief Canvas of a QwtPlot.
    24   \sa QwtPlot
     22 
     23   Canvas is the widget where all plot items are displayed
     24
     25  \sa QwtPlot::setCanvas(), QwtPlotGLCanvas
    2526*/
    2627class QWT_EXPORT QwtPlotCanvas : public QFrame
    2728{
    2829    Q_OBJECT
     30
     31    Q_PROPERTY( double borderRadius READ borderRadius WRITE setBorderRadius )
    2932
    3033public:
     
    4447
    4548          Using a backing store might improve the performance
    46           significantly, when workin with widget overlays ( like rubberbands ).
     49          significantly, when working with widget overlays ( like rubber bands ).
    4750          Disabling the cache might improve the performance for
    4851          incremental paints (using QwtPlotDirectPainter ).
     
    7881
    7982          When HackStyledBackground is enabled the plot canvas tries
    80           to seperate the background from the background border
    81           by reverse engeneering to paint the background before and
     83          to separate the background from the background border
     84          by reverse engineering to paint the background before and
    8285          the border after the plot items. In this order the border
    83           gets prefectly antialiased and you can avoid some pixel
     86          gets perfectly antialiased and you can avoid some pixel
    8487          artifacts in the corners.
    8588         */
     
    100103    /*!
    101104      \brief Focus indicator
    102 
    103       - NoFocusIndicator\n
    104         Don't paint a focus indicator
    105 
    106       - CanvasFocusIndicator\n
    107         The focus is related to the complete canvas.
    108         Paint the focus indicator using paintFocus()
    109 
    110       - ItemFocusIndicator\n
    111         The focus is related to an item (curve, point, ...) on
    112         the canvas. It is up to the application to display a
    113         focus indication using f.e. highlighting.
    114 
    115       \sa setFocusIndicator(), focusIndicator(), paintFocus()
     105      The default setting is NoFocusIndicator
     106      \sa setFocusIndicator(), focusIndicator(), drawFocusIndicator()
    116107    */
    117108
    118109    enum FocusIndicator
    119110    {
     111        //! Don't paint a focus indicator
    120112        NoFocusIndicator,
     113
     114        /*!
     115          The focus is related to the complete canvas.
     116          Paint the focus indicator using drawFocusIndicator()
     117         */
    121118        CanvasFocusIndicator,
     119
     120        /*!
     121          The focus is related to an item (curve, point, ...) on
     122          the canvas. It is up to the application to display a
     123          focus indication using f.e. highlighting.
     124         */
    122125        ItemFocusIndicator
    123126    };
    124127
    125     explicit QwtPlotCanvas( QwtPlot * );
     128    explicit QwtPlotCanvas( QwtPlot * = NULL );
    126129    virtual ~QwtPlotCanvas();
    127130
     
    135138    double borderRadius() const;
    136139
    137     QPainterPath borderPath( const QRect &rect ) const;
    138     QBitmap borderMask( const QSize & ) const;
    139 
    140140    void setPaintAttribute( PaintAttribute, bool on = true );
    141141    bool testPaintAttribute( PaintAttribute ) const;
     
    144144    void invalidateBackingStore();
    145145
     146    virtual bool event( QEvent * );
     147
     148    Q_INVOKABLE QPainterPath borderPath( const QRect & ) const;
     149
     150public Q_SLOTS:
    146151    void replot();
    147 
    148     virtual bool event( QEvent * );
    149152
    150153protected:
  • trunk/BNC/qwt/qwt_plot_curve.cpp

    r4271 r8127  
    99
    1010#include "qwt_plot_curve.h"
     11#include "qwt_point_data.h"
    1112#include "qwt_math.h"
    1213#include "qwt_clipper.h"
    1314#include "qwt_painter.h"
    14 #include "qwt_legend.h"
    15 #include "qwt_legend_item.h"
    1615#include "qwt_scale_map.h"
    1716#include "qwt_plot.h"
    18 #include "qwt_plot_canvas.h"
    1917#include "qwt_curve_fitter.h"
    2018#include "qwt_symbol.h"
     19#include "qwt_point_mapper.h"
    2120#include <qpainter.h>
    2221#include <qpixmap.h>
     
    2423#include <qmath.h>
    2524
    26 static int verifyRange( int size, int &i1, int &i2 )
     25static void qwtUpdateLegendIconSize( QwtPlotCurve *curve )
     26{
     27    if ( curve->symbol() &&
     28        curve->testLegendAttribute( QwtPlotCurve::LegendShowSymbol ) )
     29    {
     30        QSize sz = curve->symbol()->boundingRect().size();
     31        sz += QSize( 2, 2 ); // margin
     32
     33        if ( curve->testLegendAttribute( QwtPlotCurve::LegendShowLine ) )
     34        {
     35            // Avoid, that the line is completely covered by the symbol
     36
     37            int w = qCeil( 1.5 * sz.width() );
     38            if ( w % 2 )
     39                w++;
     40
     41            sz.setWidth( qMax( 8, w ) );
     42        }
     43
     44        curve->setLegendIconSize( sz );
     45    }
     46}
     47
     48static int qwtVerifyRange( int size, int &i1, int &i2 )
    2749{
    2850    if ( size < 1 )
     
    4668        symbol( NULL ),
    4769        attributes( 0 ),
    48         paintAttributes( QwtPlotCurve::ClipPolygons ),
     70        paintAttributes(
     71            QwtPlotCurve::ClipPolygons | QwtPlotCurve::FilterPoints ),
    4972        legendAttributes( 0 )
    5073    {
     
    79102*/
    80103QwtPlotCurve::QwtPlotCurve( const QwtText &title ):
    81     QwtPlotSeriesItem<QPointF>( title )
     104    QwtPlotSeriesItem( title )
    82105{
    83106    init();
     
    89112*/
    90113QwtPlotCurve::QwtPlotCurve( const QString &title ):
    91     QwtPlotSeriesItem<QPointF>( QwtText( title ) )
     114    QwtPlotSeriesItem( QwtText( title ) )
    92115{
    93116    init();
     
    107130
    108131    d_data = new PrivateData;
    109     d_series = new QwtPointSeriesData();
     132    setData( new QwtPointSeriesData() );
    110133
    111134    setZ( 20.0 );
     
    134157
    135158/*!
    136     \brief Return the current paint attributes
     159    \return True, when attribute is enabled
    137160    \sa setPaintAttribute()
    138161*/
     
    143166
    144167/*!
    145   Specify an attribute how to draw the legend identifier
     168  Specify an attribute how to draw the legend icon
    146169
    147170  \param attribute Attribute
    148171  \param on On/Off
    149   /sa testLegendAttribute()
     172  /sa testLegendAttribute(). legendIcon()
    150173*/
    151174void QwtPlotCurve::setLegendAttribute( LegendAttribute attribute, bool on )
    152175{
    153     if ( on )
    154         d_data->legendAttributes |= attribute;
    155     else
    156         d_data->legendAttributes &= ~attribute;
    157 }
    158 
    159 /*!
    160     \brief Return the current paint attributes
    161     \sa setLegendAttribute()
     176    if ( on != testLegendAttribute( attribute ) )
     177    {
     178        if ( on )
     179            d_data->legendAttributes |= attribute;
     180        else
     181            d_data->legendAttributes &= ~attribute;
     182
     183        qwtUpdateLegendIconSize( this );
     184        legendChanged();
     185    }
     186}
     187
     188/*!
     189  \return True, when attribute is enabled
     190  \sa setLegendAttribute()
    162191*/
    163192bool QwtPlotCurve::testLegendAttribute( LegendAttribute attribute ) const
     
    177206    {
    178207        d_data->style = style;
     208
     209        legendChanged();
    179210        itemChanged();
    180211    }
     
    182213
    183214/*!
    184     Return the current style
    185     \sa setStyle()
     215  \return Style of the curve
     216  \sa setStyle()
    186217*/
    187218QwtPlotCurve::CurveStyle QwtPlotCurve::style() const
     
    191222
    192223/*!
    193   Assign a symbol
     224  \brief Assign a symbol
     225
     226  The curve will take the ownership of the symbol, hence the previously
     227  set symbol will be delete by setting a new one. If \p symbol is
     228  \c NULL no symbol will be drawn.
    194229
    195230  \param symbol Symbol
    196231  \sa symbol()
    197232*/
    198 void QwtPlotCurve::setSymbol( const QwtSymbol *symbol )
     233void QwtPlotCurve::setSymbol( QwtSymbol *symbol )
    199234{
    200235    if ( symbol != d_data->symbol )
     
    202237        delete d_data->symbol;
    203238        d_data->symbol = symbol;
     239
     240        qwtUpdateLegendIconSize( this );
     241
     242        legendChanged();
    204243        itemChanged();
    205244    }
     
    216255
    217256/*!
     257  Build and assign a pen
     258
     259  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     260  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     261  to hide this incompatibility.
     262
     263  \param color Pen color
     264  \param width Pen width
     265  \param style Pen style
     266
     267  \sa pen(), brush()
     268 */
     269void QwtPlotCurve::setPen( const QColor &color, qreal width, Qt::PenStyle style )
     270{
     271    setPen( QPen( color, width, style ) );
     272}
     273
     274/*!
    218275  Assign a pen
    219276
     
    226283    {
    227284        d_data->pen = pen;
     285
     286        legendChanged();
    228287        itemChanged();
    229288    }
     
    259318    {
    260319        d_data->brush = brush;
     320
     321        legendChanged();
    261322        itemChanged();
    262323    }
     
    278339  \param xMap Maps x-values into pixel coordinates.
    279340  \param yMap Maps y-values into pixel coordinates.
    280   \param canvasRect Contents rect of the canvas
     341  \param canvasRect Contents rectangle of the canvas
    281342  \param from Index of the first point to be painted
    282343  \param to Index of the last point to be painted. If to < 0 the
     
    289350    const QRectF &canvasRect, int from, int to ) const
    290351{
    291     if ( !painter || dataSize() <= 0 )
     352    const size_t numSamples = dataSize();
     353
     354    if ( !painter || numSamples <= 0 )
    292355        return;
    293356
    294357    if ( to < 0 )
    295         to = dataSize() - 1;
    296 
    297     if ( verifyRange( dataSize(), from, to ) > 0 )
     358        to = numSamples - 1;
     359
     360    if ( qwtVerifyRange( numSamples, from, to ) > 0 )
    298361    {
    299362        painter->save();
     
    326389  \param xMap x map
    327390  \param yMap y map
    328   \param canvasRect Contents rect of the canvas
     391  \param canvasRect Contents rectangle of the canvas
    329392  \param from index of the first point to be painted
    330393  \param to index of the last point to be painted
     
    371434  \param xMap x map
    372435  \param yMap y map
    373   \param canvasRect Contents rect of the canvas
     436  \param canvasRect Contents rectangle of the canvas
    374437  \param from index of the first point to be painted
    375438  \param to index of the last point to be painted
     
    382445    const QRectF &canvasRect, int from, int to ) const
    383446{
    384     int size = to - from + 1;
    385     if ( size <= 0 )
     447    if ( from > to )
    386448        return;
    387449
    388450    const bool doAlign = QwtPainter::roundingAlignment( painter );
    389 
    390     QPolygonF polyline( size );
    391 
    392     QPointF *points = polyline.data();
    393     for ( int i = from; i <= to; i++ )
    394     {
    395         const QPointF sample = d_series->sample( i );
    396 
    397         double x = xMap.transform( sample.x() );
    398         double y = yMap.transform( sample.y() );
    399         if ( doAlign )
    400         {
    401             x = qRound( x );
    402             y = qRound( y );
    403         }
    404 
    405         points[i - from].rx() = x;
    406         points[i - from].ry() = y;
    407     }
    408 
    409     if ( ( d_data->attributes & Fitted ) && d_data->curveFitter )
    410         polyline = d_data->curveFitter->fitCurve( polyline );
    411 
     451    const bool doFit = ( d_data->attributes & Fitted ) && d_data->curveFitter;
     452    const bool doFill = ( d_data->brush.style() != Qt::NoBrush )
     453            && ( d_data->brush.color().alpha() > 0 );
     454
     455    QRectF clipRect;
    412456    if ( d_data->paintAttributes & ClipPolygons )
    413457    {
    414458        qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
    415         const QPolygonF clipped = QwtClipper::clipPolygonF(
    416             canvasRect.adjusted(-pw, -pw, pw, pw), polyline, false );
    417 
    418         QwtPainter::drawPolyline( painter, clipped );
     459        clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);
     460    }
     461
     462    bool doIntegers = false;
     463
     464#if QT_VERSION < 0x040800
     465
     466    // For Qt <= 4.7 the raster paint engine is significantly faster
     467    // for rendering QPolygon than for QPolygonF. So let's
     468    // see if we can use it.
     469
     470    if ( painter->paintEngine()->type() == QPaintEngine::Raster )
     471    {
     472        // In case of filling or fitting performance doesn't count
     473        // because both operations are much more expensive
     474        // then drawing the polyline itself
     475
     476        if ( !doFit && !doFill )
     477            doIntegers = true;
     478    }
     479#endif
     480
     481    const bool noDuplicates = d_data->paintAttributes & FilterPoints;
     482
     483    QwtPointMapper mapper;
     484    mapper.setFlag( QwtPointMapper::RoundPoints, doAlign );
     485    mapper.setFlag( QwtPointMapper::WeedOutPoints, noDuplicates );
     486    mapper.setBoundingRect( canvasRect );
     487
     488    if ( doIntegers )
     489    {
     490        QPolygon polyline = mapper.toPolygon(
     491            xMap, yMap, data(), from, to );
     492
     493        if ( d_data->paintAttributes & ClipPolygons )
     494        {
     495            polyline = QwtClipper::clipPolygon(
     496                clipRect.toAlignedRect(), polyline, false );
     497        }
     498
     499        QwtPainter::drawPolyline( painter, polyline );
    419500    }
    420501    else
    421502    {
    422         QwtPainter::drawPolyline( painter, polyline );
    423     }
    424 
    425     if ( d_data->brush.style() != Qt::NoBrush )
    426         fillCurve( painter, xMap, yMap, canvasRect, polyline );
     503        QPolygonF polyline = mapper.toPolygonF( xMap, yMap, data(), from, to );
     504
     505        if ( doFit )
     506            polyline = d_data->curveFitter->fitCurve( polyline );
     507
     508        if ( doFill )
     509        {
     510            if ( painter->pen().style() != Qt::NoPen )
     511            {
     512                // here we are wasting memory for the filled copy,
     513                // do polygon clipping twice etc .. TODO
     514
     515                QPolygonF filled = polyline;
     516                fillCurve( painter, xMap, yMap, canvasRect, filled );
     517                filled.clear();
     518
     519                if ( d_data->paintAttributes & ClipPolygons )
     520                {
     521                    polyline = QwtClipper::clipPolygonF(
     522                        clipRect, polyline, false );
     523                }
     524
     525                QwtPainter::drawPolyline( painter, polyline );
     526            }
     527            else
     528            {
     529                fillCurve( painter, xMap, yMap, canvasRect, polyline );
     530            }
     531        }
     532        else
     533        {
     534            if ( d_data->paintAttributes & ClipPolygons )
     535            {
     536                polyline = QwtClipper::clipPolygonF(
     537                    clipRect, polyline, false );
     538            }
     539
     540            QwtPainter::drawPolyline( painter, polyline );
     541        }
     542    }
    427543}
    428544
     
    433549  \param xMap x map
    434550  \param yMap y map
    435   \param canvasRect Contents rect of the canvas
     551  \param canvasRect Contents rectangle of the canvas
    436552  \param from index of the first point to be painted
    437553  \param to index of the last point to be painted
     
    458574    const Qt::Orientation o = orientation();
    459575
     576    const QwtSeriesData<QPointF> *series = data();
     577
    460578    for ( int i = from; i <= to; i++ )
    461579    {
    462         const QPointF sample = d_series->sample( i );
     580        const QPointF sample = series->sample( i );
    463581        double xi = xMap.transform( sample.x() );
    464582        double yi = yMap.transform( sample.y() );
     
    484602  \param xMap x map
    485603  \param yMap y map
    486   \param canvasRect Contents rect of the canvas
     604  \param canvasRect Contents rectangle of the canvas
    487605  \param from index of the first point to be painted
    488606  \param to index of the last point to be painted
     
    494612    const QRectF &canvasRect, int from, int to ) const
    495613{
    496     const bool doFill = d_data->brush.style() != Qt::NoBrush;
     614    const QColor color = painter->pen().color();
     615
     616    if ( painter->pen().style() == Qt::NoPen || color.alpha() == 0 )
     617    {
     618        return;
     619    }
     620
     621    const bool doFill = ( d_data->brush.style() != Qt::NoBrush )
     622            && ( d_data->brush.color().alpha() > 0 );
    497623    const bool doAlign = QwtPainter::roundingAlignment( painter );
    498624
    499     QPolygonF polyline;
     625    QwtPointMapper mapper;
     626    mapper.setBoundingRect( canvasRect );
     627    mapper.setFlag( QwtPointMapper::RoundPoints, doAlign );
     628
     629    if ( d_data->paintAttributes & FilterPoints )
     630    {
     631        if ( ( color.alpha() == 255 )
     632            && !( painter->renderHints() & QPainter::Antialiasing ) )
     633        {
     634            mapper.setFlag( QwtPointMapper::WeedOutPoints, true );
     635        }
     636    }
     637
    500638    if ( doFill )
    501         polyline.resize( to - from + 1 );
    502 
    503     QPointF *points = polyline.data();
    504 
    505     for ( int i = from; i <= to; i++ )
    506     {
    507         const QPointF sample = d_series->sample( i );
    508         double xi = xMap.transform( sample.x() );
    509         double yi = yMap.transform( sample.y() );
     639    {
     640        mapper.setFlag( QwtPointMapper::WeedOutPoints, false );
     641
     642        QPolygonF points = mapper.toPointsF(
     643            xMap, yMap, data(), from, to );
     644
     645        QwtPainter::drawPoints( painter, points );
     646        fillCurve( painter, xMap, yMap, canvasRect, points );
     647    }
     648    else if ( d_data->paintAttributes & ImageBuffer )
     649    {
     650        const QImage image = mapper.toImage( xMap, yMap,
     651            data(), from, to, d_data->pen,
     652            painter->testRenderHint( QPainter::Antialiasing ),
     653            renderThreadCount() );
     654
     655        painter->drawImage( canvasRect.toAlignedRect(), image );
     656    }
     657    else if ( d_data->paintAttributes & MinimizeMemory )
     658    {
     659        const QwtSeriesData<QPointF> *series = data();
     660
     661        for ( int i = from; i <= to; i++ )
     662        {
     663            const QPointF sample = series->sample( i );
     664
     665            double xi = xMap.transform( sample.x() );
     666            double yi = yMap.transform( sample.y() );
     667
     668            if ( doAlign )
     669            {
     670                xi = qRound( xi );
     671                yi = qRound( yi );
     672            }
     673
     674            QwtPainter::drawPoint( painter, QPointF( xi, yi ) );
     675        }
     676    }
     677    else
     678    {
    510679        if ( doAlign )
    511680        {
    512             xi = qRound( xi );
    513             yi = qRound( yi );
    514         }
    515 
    516         QwtPainter::drawPoint( painter, QPointF( xi, yi ) );
    517 
    518         if ( doFill )
    519         {
    520             points[i - from].rx() = xi;
    521             points[i - from].ry() = yi;
    522         }
    523     }
    524 
    525     if ( doFill )
    526         fillCurve( painter, xMap, yMap, canvasRect, polyline );
     681            const QPolygon points = mapper.toPoints(
     682                xMap, yMap, data(), from, to );
     683
     684            QwtPainter::drawPoints( painter, points );
     685        }
     686        else
     687        {
     688            const QPolygonF points = mapper.toPointsF(
     689                xMap, yMap, data(), from, to );
     690
     691            QwtPainter::drawPoints( painter, points );
     692        }
     693    }
    527694}
    528695
     
    535702  \param xMap x map
    536703  \param yMap y map
    537   \param canvasRect Contents rect of the canvas
     704  \param canvasRect Contents rectangle of the canvas
    538705  \param from index of the first point to be painted
    539706  \param to index of the last point to be painted
     
    555722        inverted = !inverted;
    556723
     724    const QwtSeriesData<QPointF> *series = data();
     725
    557726    int i, ip;
    558727    for ( i = from, ip = 0; i <= to; i++, ip += 2 )
    559728    {
    560         const QPointF sample = d_series->sample( i );
     729        const QPointF sample = series->sample( i );
    561730        double xi = xMap.transform( sample.x() );
    562731        double yi = yMap.transform( sample.y() );
     
    590759    if ( d_data->paintAttributes & ClipPolygons )
    591760    {
     761        qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
     762        const QRectF clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);
     763       
    592764        const QPolygonF clipped = QwtClipper::clipPolygonF(
    593             canvasRect, polygon, false );
     765            clipRect, polygon, false );
    594766
    595767        QwtPainter::drawPolyline( painter, clipped );
     
    678850  \param xMap x map
    679851  \param yMap y map
    680   \param canvasRect Contents rect of the canvas
     852  \param canvasRect Contents rectangle of the canvas
    681853  \param polygon Polygon - will be modified !
    682854
     
    733905    if ( orientation() == Qt::Vertical )
    734906    {
    735         if ( yMap.transformation()->type() == QwtScaleTransformation::Log10 )
    736         {
    737             if ( baseline < QwtScaleMap::LogMin )
    738                 baseline = QwtScaleMap::LogMin;
    739         }
     907        if ( yMap.transformation() )
     908            baseline = yMap.transformation()->bounded( baseline );
    740909
    741910        double refY = yMap.transform( baseline );
     
    748917    else
    749918    {
    750         if ( xMap.transformation()->type() == QwtScaleTransformation::Log10 )
    751         {
    752             if ( baseline < QwtScaleMap::LogMin )
    753                 baseline = QwtScaleMap::LogMin;
    754         }
     919        if ( xMap.transformation() )
     920            baseline = xMap.transformation()->bounded( baseline );
    755921
    756922        double refX = xMap.transform( baseline );
     
    770936  \param xMap x map
    771937  \param yMap y map
    772   \param canvasRect Contents rect of the canvas
     938  \param canvasRect Contents rectangle of the canvas
    773939  \param from Index of the first point to be painted
    774940  \param to Index of the last point to be painted
     
    780946    const QRectF &canvasRect, int from, int to ) const
    781947{
    782     const bool doAlign = QwtPainter::roundingAlignment( painter );
    783 
    784     bool usePixmap = testPaintAttribute( CacheSymbols );
    785     if ( usePixmap && !doAlign )
    786     {
    787         // Don't use the pixmap, when the paint device
    788         // could generate scalable vectors
    789 
    790         usePixmap = false;
    791     }
    792 
    793     if ( usePixmap )
    794     {
    795         QPixmap pm( symbol.boundingSize() );
    796         pm.fill( Qt::transparent );
    797 
    798         const double pw2 = 0.5 * pm.width();
    799         const double ph2 = 0.5 * pm.height();
    800 
    801         QPainter p( &pm );
    802         p.setRenderHints( painter->renderHints() );
    803         symbol.drawSymbol( &p, QPointF( pw2, ph2 ) );
    804         p.end();
    805 
    806         for ( int i = from; i <= to; i++ )
    807         {
    808             const QPointF sample = d_series->sample( i );
    809 
    810             double xi = xMap.transform( sample.x() );
    811             double yi = yMap.transform( sample.y() );
    812             if ( doAlign )
    813             {
    814                 xi = qRound( xi );
    815                 yi = qRound( yi );
    816             }
    817 
    818             if ( canvasRect.contains( xi, yi ) )
    819             {
    820                 const int left = qCeil( xi ) - pw2;
    821                 const int top = qCeil( yi ) - ph2;
    822 
    823                 painter->drawPixmap( left, top, pm );
    824             }
    825         }
    826     }
    827     else
    828     {
    829         const int chunkSize = 500;
    830 
    831         for ( int i = from; i <= to; i += chunkSize )
    832         {
    833             const int n = qMin( chunkSize, to - i + 1 );
    834 
    835             QPolygonF points;
    836             for ( int j = 0; j < n; j++ )
    837             {
    838                 const QPointF sample = d_series->sample( i + j );
    839 
    840                 const double xi = xMap.transform( sample.x() );
    841                 const double yi = yMap.transform( sample.y() );
    842 
    843                 if ( canvasRect.contains( xi, yi ) )
    844                     points += QPointF( xi, yi );
    845             }
    846 
    847             if ( points.size() > 0 )
    848                 symbol.drawSymbols( painter, points );
    849         }
     948    QwtPointMapper mapper;
     949    mapper.setFlag( QwtPointMapper::RoundPoints,
     950        QwtPainter::roundingAlignment( painter ) );
     951    mapper.setFlag( QwtPointMapper::WeedOutPoints,
     952        testPaintAttribute( QwtPlotCurve::FilterPoints ) );
     953    mapper.setBoundingRect( canvasRect );
     954
     955    const int chunkSize = 500;
     956
     957    for ( int i = from; i <= to; i += chunkSize )
     958    {
     959        const int n = qMin( chunkSize, to - i + 1 );
     960
     961        const QPolygonF points = mapper.toPointsF( xMap, yMap,
     962            data(), i, i + n - 1 );
     963
     964        if ( points.size() > 0 )
     965            symbol.drawSymbols( painter, points );
    850966    }
    851967}
     
    856972  The baseline is needed for filling the curve with a brush or
    857973  the Sticks drawing style.
    858   The interpretation of the baseline depends on the CurveType.
    859   With QwtPlotCurve::Yfx, the baseline is interpreted as a horizontal line
    860   at y = baseline(), with QwtPlotCurve::Yfy, it is interpreted as a vertical
     974
     975  The interpretation of the baseline depends on the orientation().
     976  With Qt::Horizontal, the baseline is interpreted as a horizontal line
     977  at y = baseline(), with Qt::Vertical, it is interpreted as a vertical
    861978  line at x = baseline().
    862979
     
    864981
    865982  \param value Value of the baseline
    866   \sa baseline(), setBrush(), setStyle(), setStyle()
     983  \sa baseline(), setBrush(), setStyle(), QwtPlotAbstractSeriesItem::orientation()
    867984*/
    868985void QwtPlotCurve::setBaseline( double value )
     
    8891006  \param pos Position, where to look for the closest curve point
    8901007  \param dist If dist != NULL, closestPoint() returns the distance between
    891               the position and the clostest curve point
     1008              the position and the closest curve point
    8921009  \return Index of the closest curve point, or -1 if none can be found
    8931010          ( f.e when the curve has no points )
     
    8971014int QwtPlotCurve::closestPoint( const QPoint &pos, double *dist ) const
    8981015{
    899     if ( plot() == NULL || dataSize() <= 0 )
     1016    const size_t numSamples = dataSize();
     1017
     1018    if ( plot() == NULL || numSamples <= 0 )
    9001019        return -1;
     1020
     1021    const QwtSeriesData<QPointF> *series = data();
    9011022
    9021023    const QwtScaleMap xMap = plot()->canvasMap( xAxis() );
     
    9061027    double dmin = 1.0e10;
    9071028
    908     for ( uint i = 0; i < dataSize(); i++ )
    909     {
    910         const QPointF sample = d_series->sample( i );
     1029    for ( uint i = 0; i < numSamples; i++ )
     1030    {
     1031        const QPointF sample = series->sample( i );
    9111032
    9121033        const double cx = xMap.transform( sample.x() ) - pos.x();
     
    9271048
    9281049/*!
    929    \brief Update the widget that represents the item on the legend
    930 
    931    \param legend Legend
    932    \sa drawLegendIdentifier(), legendItem(), QwtPlotItem::Legend
    933 */
    934 void QwtPlotCurve::updateLegend( QwtLegend *legend ) const
    935 {
    936     if ( legend && testItemAttribute( QwtPlotItem::Legend )
    937         && ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol )
    938         && d_data->symbol
    939         && d_data->symbol->style() != QwtSymbol::NoSymbol )
    940     {
    941         QWidget *lgdItem = legend->find( this );
    942         if ( lgdItem == NULL )
    943         {
    944             lgdItem = legendItem();
    945             if ( lgdItem )
    946                 legend->insert( this, lgdItem );
    947         }
    948 
    949         QwtLegendItem *l = qobject_cast<QwtLegendItem *>( lgdItem );
    950         if ( l )
    951         {
    952             QSize sz = d_data->symbol->boundingSize();
    953             sz += QSize( 2, 2 ); // margin
    954 
    955             if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine )
     1050   \return Icon representing the curve on the legend
     1051
     1052   \param index Index of the legend entry
     1053                ( ignored as there is only one )
     1054   \param size Icon size
     1055
     1056   \sa QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData()
     1057 */
     1058QwtGraphic QwtPlotCurve::legendIcon( int index,
     1059    const QSizeF &size ) const
     1060{
     1061    Q_UNUSED( index );
     1062
     1063    if ( size.isEmpty() )
     1064        return QwtGraphic();
     1065
     1066    QwtGraphic graphic;
     1067    graphic.setDefaultSize( size );
     1068    graphic.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
     1069
     1070    QPainter painter( &graphic );
     1071    painter.setRenderHint( QPainter::Antialiasing,
     1072        testRenderHint( QwtPlotItem::RenderAntialiased ) );
     1073
     1074    if ( d_data->legendAttributes == 0 ||
     1075        d_data->legendAttributes & QwtPlotCurve::LegendShowBrush )
     1076    {
     1077        QBrush brush = d_data->brush;
     1078
     1079        if ( brush.style() == Qt::NoBrush &&
     1080            d_data->legendAttributes == 0 )
     1081        {
     1082            if ( style() != QwtPlotCurve::NoCurve )
    9561083            {
    957                 // Avoid, that the line is completely covered by the symbol
    958 
    959                 int w = qCeil( 1.5 * sz.width() );
    960                 if ( w % 2 )
    961                     w++;
    962 
    963                 sz.setWidth( qMax( 8, w ) );
     1084                brush = QBrush( pen().color() );
    9641085            }
    965 
    966             l->setIdentifierSize( sz );
    967         }
    968     }
    969 
    970     QwtPlotItem::updateLegend( legend );
    971 }
    972 
    973 /*!
    974   \brief Draw the identifier representing the curve on the legend
    975 
    976   \param painter Painter
    977   \param rect Bounding rectangle for the identifier
    978 
    979   \sa setLegendAttribute(), QwtPlotItem::Legend
    980 */
    981 void QwtPlotCurve::drawLegendIdentifier(
    982     QPainter *painter, const QRectF &rect ) const
    983 {
    984     if ( rect.isEmpty() )
    985         return;
    986 
    987     const int dim = qMin( rect.width(), rect.height() );
    988 
    989     QSize size( dim, dim );
    990 
    991     QRectF r( 0, 0, size.width(), size.height() );
    992     r.moveCenter( rect.center() );
    993 
    994     if ( d_data->legendAttributes == 0 )
    995     {
    996         QBrush brush = d_data->brush;
    997         if ( brush.style() == Qt::NoBrush )
    998         {
    999             if ( style() != QwtPlotCurve::NoCurve )
    1000                 brush = QBrush( pen().color() );
    10011086            else if ( d_data->symbol &&
    10021087                ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
     
    10051090            }
    10061091        }
     1092
    10071093        if ( brush.style() != Qt::NoBrush )
    1008             painter->fillRect( r, brush );
    1009     }
    1010     if ( d_data->legendAttributes & QwtPlotCurve::LegendShowBrush )
    1011     {
    1012         if ( d_data->brush.style() != Qt::NoBrush )
    1013             painter->fillRect( r, d_data->brush );
    1014     }
     1094        {
     1095            QRectF r( 0, 0, size.width(), size.height() );
     1096            painter.fillRect( r, brush );
     1097        }
     1098    }
     1099
    10151100    if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine )
    10161101    {
    10171102        if ( pen() != Qt::NoPen )
    10181103        {
    1019             painter->setPen( pen() );
    1020             QwtPainter::drawLine( painter, rect.left(), rect.center().y(),
    1021                                   rect.right() - 1.0, rect.center().y() );
    1022         }
    1023     }
     1104            QPen pn = pen();
     1105            pn.setCapStyle( Qt::FlatCap );
     1106
     1107            painter.setPen( pn );
     1108
     1109            const double y = 0.5 * size.height();
     1110            QwtPainter::drawLine( &painter, 0.0, y, size.width(), y );
     1111        }
     1112    }
     1113
    10241114    if ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol )
    10251115    {
    1026         if ( d_data->symbol &&
    1027             ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
    1028         {
    1029             QSize symbolSize = d_data->symbol->boundingSize();
    1030             symbolSize -= QSize( 2, 2 );
    1031 
    1032             // scale the symbol size down if it doesn't fit into rect.
    1033 
    1034             double xRatio = 1.0;
    1035             if ( rect.width() < symbolSize.width() )
    1036                 xRatio = rect.width() / symbolSize.width();
    1037             double yRatio = 1.0;
    1038             if ( rect.height() < symbolSize.height() )
    1039                 yRatio = rect.height() / symbolSize.height();
    1040 
    1041             const double ratio = qMin( xRatio, yRatio );
    1042 
    1043             painter->save();
    1044             painter->scale( ratio, ratio );
    1045 
    1046             d_data->symbol->drawSymbol( painter, rect.center() / ratio );
    1047 
    1048             painter->restore();
    1049         }
    1050     }
    1051 }
    1052 
    1053 /*!
    1054   Initialize data with an array of points (explicitly shared).
     1116        if ( d_data->symbol )
     1117        {
     1118            QRectF r( 0, 0, size.width(), size.height() );
     1119            d_data->symbol->drawSymbol( &painter, r );
     1120        }
     1121    }
     1122
     1123    return graphic;
     1124}
     1125
     1126/*!
     1127  Initialize data with an array of points.
    10551128
    10561129  \param samples Vector of points
     1130  \note QVector is implicitly shared
     1131  \note QPolygonF is derived from QVector<QPointF>
    10571132*/
    10581133void QwtPlotCurve::setSamples( const QVector<QPointF> &samples )
    10591134{
    1060     delete d_series;
    1061     d_series = new QwtPointSeriesData( samples );
    1062     itemChanged();
     1135    setData( new QwtPointSeriesData( samples ) );
     1136}
     1137
     1138/*!
     1139  Assign a series of points
     1140
     1141  setSamples() is just a wrapper for setData() without any additional
     1142  value - beside that it is easier to find for the developer.
     1143
     1144  \param data Data
     1145  \warning The item takes ownership of the data object, deleting
     1146           it when its not used anymore.
     1147*/
     1148void QwtPlotCurve::setSamples( QwtSeriesData<QPointF> *data )
     1149{
     1150    setData( data );
    10631151}
    10641152
     
    10821170    const double *xData, const double *yData, int size )
    10831171{
    1084     delete d_series;
    1085     d_series = new QwtCPointerData( xData, yData, size );
    1086     itemChanged();
     1172    setData( new QwtCPointerData( xData, yData, size ) );
    10871173}
    10881174
     
    11011187    const double *xData, const double *yData, int size )
    11021188{
    1103     delete d_series;
    1104     d_series = new QwtPointArrayData( xData, yData, size );
    1105     itemChanged();
     1189    setData( new QwtPointArrayData( xData, yData, size ) );
    11061190}
    11071191
     
    11171201    const QVector<double> &yData )
    11181202{
    1119     delete d_series;
    1120     d_series = new QwtPointArrayData( xData, yData );
    1121     itemChanged();
    1122 }
     1203    setData( new QwtPointArrayData( xData, yData ) );
     1204}
     1205
    11231206#endif // !QWT_NO_COMPAT
    11241207
  • trunk/BNC/qwt/qwt_plot_curve.h

    r4271 r8127  
    5353  \sa QwtPointSeriesData, QwtSymbol, QwtScaleMap
    5454*/
    55 class QWT_EXPORT QwtPlotCurve: public QwtPlotSeriesItem<QPointF>
     55class QWT_EXPORT QwtPlotCurve:
     56    public QwtPlotSeriesItem, public QwtSeriesStore<QPointF>
    5657{
    5758public:
     
    120121          interpolate/smooth the curve, before it is painted.
    121122
    122           \note Curve fitting requires temorary memory
     123          \note Curve fitting requires temporary memory
    123124          for calculating coefficients and additional points.
    124125          If painting in QwtPlotCurve::Fitted mode is slow it might be better
     
    135136
    136137        \sa setLegendAttribute(), testLegendAttribute(),
    137             drawLegendIdentifier()
     138            QwtPlotItem::legendData(), legendIcon()
    138139     */
    139140
     
    169170    /*!
    170171        Attributes to modify the drawing algorithm.
    171         The default setting enables ClipPolygons
     172        The default setting enables ClipPolygons | FilterPoints
    172173
    173174        \sa setPaintAttribute(), testPaintAttribute()
     
    183184
    184185        /*!
    185           Paint the symbol to a QPixmap and paint the pixmap
    186           instead rendering the symbol for each point. The flag has
    187           no effect, when the curve is not painted to the canvas
    188           ( f.e when exporting the plot to a PDF document ).
    189          */
    190         CacheSymbols = 0x02
     186          Tries to reduce the data that has to be painted, by sorting out
     187          duplicates, or paintings outside the visible area. Might have a
     188          notable impact on curves with many close points.
     189          Only a couple of very basic filtering algorithms are implemented.
     190         */
     191        FilterPoints = 0x02,
     192
     193        /*!
     194          Minimize memory usage that is temporarily needed for the
     195          translated points, before they get painted.
     196          This might slow down the performance of painting
     197         */
     198        MinimizeMemory = 0x04,
     199
     200        /*!
     201          Render the points to a temporary image and paint the image.
     202          This is a very special optimization for Dots style, when
     203          having a huge amount of points.
     204          With a reasonable number of points QPainter::drawPoints()
     205          will be faster.
     206         */
     207        ImageBuffer = 0x08
    191208    };
    192209
     
    213230#endif
    214231    void setSamples( const QVector<QPointF> & );
     232    void setSamples( QwtSeriesData<QPointF> * );
    215233
    216234    int closestPoint( const QPoint &pos, double *dist = NULL ) const;
     
    224242    bool testCurveAttribute( CurveAttribute ) const;
    225243
     244    void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
    226245    void setPen( const QPen & );
    227246    const QPen &pen() const;
     
    230249    const QBrush &brush() const;
    231250
    232     void setBaseline( double ref );
     251    void setBaseline( double );
    233252    double baseline() const;
    234253
     
    236255    CurveStyle style() const;
    237256
    238     void setSymbol( const QwtSymbol *s );
     257    void setSymbol( QwtSymbol * );
    239258    const QwtSymbol *symbol() const;
    240259
     
    246265        const QRectF &canvasRect, int from, int to ) const;
    247266
    248     virtual void updateLegend( QwtLegend * ) const;
    249     virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const;
     267    virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
    250268
    251269protected:
     
    261279        const QRectF &canvasRect, int from, int to ) const;
    262280
    263     void drawLines( QPainter *p,
    264         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    265         const QRectF &canvasRect, int from, int to ) const;
    266 
    267     void drawSticks( QPainter *p,
    268         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    269         const QRectF &canvasRect, int from, int to ) const;
    270 
    271     void drawDots( QPainter *p,
    272         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    273         const QRectF &canvasRect, int from, int to ) const;
    274 
    275     void drawSteps( QPainter *p,
     281    virtual void drawLines( QPainter *p,
     282        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
     283        const QRectF &canvasRect, int from, int to ) const;
     284
     285    virtual void drawSticks( QPainter *p,
     286        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
     287        const QRectF &canvasRect, int from, int to ) const;
     288
     289    virtual void drawDots( QPainter *p,
     290        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
     291        const QRectF &canvasRect, int from, int to ) const;
     292
     293    virtual void drawSteps( QPainter *p,
    276294        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    277295        const QRectF &canvasRect, int from, int to ) const;
  • trunk/BNC/qwt/qwt_plot_dict.cpp

    r4271 r8127  
    6464
    6565   Auto deletion is enabled.
    66    \sa setAutoDelete(), attachItem()
     66   \sa setAutoDelete(), QwtPlotItem::attach()
    6767*/
    6868QwtPlotDict::QwtPlotDict()
     
    7575   Destructor
    7676
    77    If autoDelete is on, all attached items will be deleted
    78    \sa setAutoDelete(), autoDelete(), attachItem()
     77   If autoDelete() is on, all attached items will be deleted
     78   \sa setAutoDelete(), autoDelete(), QwtPlotItem::attach()
    7979*/
    8080QwtPlotDict::~QwtPlotDict()
     
    9090   in the destructor of QwtPlotDict. The default value is on.
    9191
    92    \sa autoDelete(), attachItem()
     92   \sa autoDelete(), insertItem()
    9393*/
    9494void QwtPlotDict::setAutoDelete( bool autoDelete )
     
    9999/*!
    100100   \return true if auto deletion is enabled
    101    \sa setAutoDelete(), attachItem()
     101   \sa setAutoDelete(), insertItem()
    102102*/
    103103bool QwtPlotDict::autoDelete() const
     
    107107
    108108/*!
    109    Attach/Detach a plot item
     109  Insert a plot item
    110110
    111    Attached items will be deleted in the destructor,
    112    if auto deletion is enabled (default). Manually detached
    113    items are not deleted.
     111  \param item PlotItem
     112  \sa removeItem()
     113 */
     114void QwtPlotDict::insertItem( QwtPlotItem *item )
     115{
     116    d_data->itemList.insertItem( item );
     117}
    114118
    115    \param item Plot item to attach/detach
    116    \ on If true attach, else detach the item
     119/*!
     120  Remove a plot item
    117121
    118    \sa setAutoDelete(), ~QwtPlotDict()
    119 */
    120 void QwtPlotDict::attachItem( QwtPlotItem *item, bool on )
     122  \param item PlotItem
     123  \sa insertItem()
     124 */
     125void QwtPlotDict::removeItem( QwtPlotItem *item )
    121126{
    122     if ( on )
    123         d_data->itemList.insertItem( item );
    124     else
    125         d_data->itemList.removeItem( item );
     127    d_data->itemList.removeItem( item );
    126128}
    127129
     
    168170/*!
    169171  \return List of all attached plot items of a specific type.
     172  \param rtti See QwtPlotItem::RttiValues
    170173  \sa QwtPlotItem::rtti()
    171174*/
  • trunk/BNC/qwt/qwt_plot_dict.h

    r4271 r8127  
    2727  If autoDelete() is enabled, all attached items will be deleted
    2828  in the destructor of the dictionary.
     29  QwtPlotDict can be used to get access to all QwtPlotItem items - or all
     30  items of a specific type -  that are currently on the plot.
    2931
    3032  \sa QwtPlotItem::attach(), QwtPlotItem::detach(), QwtPlotItem::z()
     
    4547        bool autoDelete = true );
    4648
     49protected:
     50    void insertItem( QwtPlotItem * );
     51    void removeItem( QwtPlotItem * );
     52
    4753private:
    48     friend class QwtPlotItem;
    49 
    50     void attachItem( QwtPlotItem *, bool );
    51 
    5254    class PrivateData;
    5355    PrivateData *d_data;
  • trunk/BNC/qwt/qwt_plot_directpainter.cpp

    r4271 r8127  
    1818#include <qpixmap.h>
    1919
    20 static inline void renderItem(
     20static inline void qwtRenderItem(
    2121    QPainter *painter, const QRect &canvasRect,
    22     QwtPlotAbstractSeriesItem *seriesItem, int from, int to )
     22    QwtPlotSeriesItem *seriesItem, int from, int to )
    2323{
    2424    // A minor performance improvement is possible
     
    3232        seriesItem->testRenderHint( QwtPlotItem::RenderAntialiased ) );
    3333    seriesItem->drawSeries( painter, xMap, yMap, canvasRect, from, to );
     34}
     35
     36static inline bool qwtHasBackingStore( const QwtPlotCanvas *canvas )
     37{
     38    return canvas->testPaintAttribute( QwtPlotCanvas::BackingStore )
     39        && canvas->backingStore() && !canvas->backingStore()->isNull();
    3440}
    3541
     
    4046        attributes( 0 ),
    4147        hasClipping(false),
    42         seriesItem( NULL )
     48        seriesItem( NULL ),
     49        from( 0 ),
     50        to( 0 )
    4351    {
    4452    }
     
    5159    QPainter painter;
    5260
    53     QwtPlotAbstractSeriesItem *seriesItem;
     61    QwtPlotSeriesItem *seriesItem;
    5462    int from;
    5563    int to;
     
    92100
    93101/*!
    94   Check if a attribute is set.
    95 
     102  \return True, when attribute is enabled
    96103  \param attribute Attribute to be tested
    97104  \sa Attribute, setAttribute()
     
    152159
    153160  When observing an measurement while it is running, new points have to be
    154   added to an existing seriesItem. drawSeries can be used to display them avoiding
     161  added to an existing seriesItem. drawSeries() can be used to display them avoiding
    155162  a complete redraw of the canvas.
    156163
     
    165172*/
    166173void QwtPlotDirectPainter::drawSeries(
    167     QwtPlotAbstractSeriesItem *seriesItem, int from, int to )
     174    QwtPlotSeriesItem *seriesItem, int from, int to )
    168175{
    169176    if ( seriesItem == NULL || seriesItem->plot() == NULL )
    170177        return;
    171178
    172     QwtPlotCanvas *canvas = seriesItem->plot()->canvas();
     179    QWidget *canvas = seriesItem->plot()->canvas();
    173180    const QRect canvasRect = canvas->contentsRect();
    174181
    175     const bool hasBackingStore =
    176         canvas->testPaintAttribute( QwtPlotCanvas::BackingStore )
    177         && canvas->backingStore() && !canvas->backingStore()->isNull();
    178 
    179     if ( hasBackingStore )
    180     {
    181         QPainter painter( const_cast<QPixmap *>( canvas->backingStore() ) );
    182         painter.translate( -canvasRect.x(), -canvasRect.y() );
     182    QwtPlotCanvas *plotCanvas = qobject_cast<QwtPlotCanvas *>( canvas );
     183
     184    if ( plotCanvas && qwtHasBackingStore( plotCanvas ) )
     185    {
     186        QPainter painter( const_cast<QPixmap *>( plotCanvas->backingStore() ) );
    183187
    184188        if ( d_data->hasClipping )
    185189            painter.setClipRegion( d_data->clipRegion );
    186190
    187         renderItem( &painter, canvasRect, seriesItem, from, to );
     191        qwtRenderItem( &painter, canvasRect, seriesItem, from, to );
     192
     193        painter.end();
    188194
    189195        if ( testAttribute( QwtPlotDirectPainter::FullRepaint ) )
    190196        {
    191             canvas->repaint();
     197            plotCanvas->repaint();
    192198            return;
    193199        }
     
    195201
    196202    bool immediatePaint = true;
    197     if ( !canvas->testAttribute( Qt::WA_WState_InPaintEvent ) &&
    198         !canvas->testAttribute( Qt::WA_PaintOutsidePaintEvent ) )
    199     {
    200         immediatePaint = false;
     203    if ( !canvas->testAttribute( Qt::WA_WState_InPaintEvent ) )
     204    {
     205#if QT_VERSION < 0x050000
     206        if ( !canvas->testAttribute( Qt::WA_PaintOutsidePaintEvent ) )
     207#endif
     208            immediatePaint = false;
    201209    }
    202210
    203211    if ( immediatePaint )
    204212    {
    205         QwtPlotCanvas *canvas = seriesItem->plot()->canvas();
    206213        if ( !d_data->painter.isActive() )
    207214        {
     
    223230        }
    224231
    225         renderItem( &d_data->painter, canvasRect, seriesItem, from, to );
     232        qwtRenderItem( &d_data->painter, canvasRect, seriesItem, from, to );
    226233
    227234        if ( d_data->attributes & QwtPlotDirectPainter::AtomicPainter )
     
    260267    if ( d_data->painter.isActive() )
    261268    {
    262         QWidget *w = ( QWidget * )d_data->painter.device();
     269        QWidget *w = static_cast<QWidget *>( d_data->painter.device() );
    263270        if ( w )
    264271            w->removeEventFilter( this );
     
    279286            const QPaintEvent *pe = static_cast< QPaintEvent *>( event );
    280287
    281             QwtPlotCanvas *canvas = d_data->seriesItem->plot()->canvas();
     288            QWidget *canvas = d_data->seriesItem->plot()->canvas();
    282289
    283290            QPainter painter( canvas );
    284291            painter.setClipRegion( pe->region() );
    285292
    286             bool copyCache = testAttribute( CopyBackingStore )
    287                 && canvas->testPaintAttribute( QwtPlotCanvas::BackingStore );
    288 
    289             if ( copyCache )
     293            bool doCopyCache = testAttribute( CopyBackingStore );
     294
     295            if ( doCopyCache )
    290296            {
    291                 // is something valid in the cache ?
    292                 copyCache = ( canvas->backingStore() != NULL )
    293                     && !canvas->backingStore()->isNull();
     297                QwtPlotCanvas *plotCanvas =
     298                    qobject_cast<QwtPlotCanvas *>( canvas );
     299                if ( plotCanvas )
     300                {
     301                    doCopyCache = qwtHasBackingStore( plotCanvas );
     302                    if ( doCopyCache )
     303                    {
     304                        painter.drawPixmap( plotCanvas->rect().topLeft(),
     305                            *plotCanvas->backingStore() );
     306                    }
     307                }
    294308            }
    295309
    296             if ( copyCache )
     310            if ( !doCopyCache )
    297311            {
    298                 painter.drawPixmap(
    299                     canvas->contentsRect().topLeft(),
    300                     *canvas->backingStore() );
    301             }
    302             else
    303             {
    304                 renderItem( &painter, canvas->contentsRect(),
     312                qwtRenderItem( &painter, canvas->contentsRect(),
    305313                    d_data->seriesItem, d_data->from, d_data->to );
    306314            }
  • trunk/BNC/qwt/qwt_plot_directpainter.h

    r4271 r8127  
    1515
    1616class QRegion;
    17 class QwtPlotAbstractSeriesItem;
     17class QwtPlotSeriesItem;
    1818
    1919/*!
     
    5555
    5656        /*!
    57           When FullRepaint is set the plot canvas is explicitely repainted
     57          When FullRepaint is set the plot canvas is explicitly repainted
    5858          after the samples have been rendered.
    5959         */
     
    6464          has to paint to the backing store and the widget. In certain
    6565          situations/environments it might be faster to paint to
    66           the backing store only and then copy the backingstore to the canvas.
     66          the backing store only and then copy the backing store to the canvas.
    6767          This flag can also be useful for settings, where Qt fills the
    6868          the clip region with the widget background.
     
    8686    QRegion clipRegion() const;
    8787
    88     void drawSeries( QwtPlotAbstractSeriesItem *, int from, int to );
     88    void drawSeries( QwtPlotSeriesItem *, int from, int to );
    8989    void reset();
    9090
  • trunk/BNC/qwt/qwt_plot_grid.cpp

    r4271 r8127  
    3636    QwtScaleDiv yScaleDiv;
    3737
    38     QPen majPen;
    39     QPen minPen;
     38    QPen majorPen;
     39    QPen minorPen;
    4040};
    4141
     
    4545{
    4646    d_data = new PrivateData;
     47
     48    setItemInterest( QwtPlotItem::ScaleInterest, true );
    4749    setZ( 10.0 );
    4850}
     
    6163
    6264/*!
    63   \brief Enable or disable vertical gridlines
    64   \param tf Enable (true) or disable
    65 
    66   \sa Minor gridlines can be enabled or disabled with
     65  \brief Enable or disable vertical grid lines
     66  \param on Enable (true) or disable
     67
     68  \sa Minor grid lines can be enabled or disabled with
    6769      enableXMin()
    6870*/
    69 void QwtPlotGrid::enableX( bool tf )
    70 {
    71     if ( d_data->xEnabled != tf )
    72     {
    73         d_data->xEnabled = tf;
    74         itemChanged();
    75     }
    76 }
    77 
    78 /*!
    79   \brief Enable or disable horizontal gridlines
    80   \param tf Enable (true) or disable
    81   \sa Minor gridlines can be enabled or disabled with enableYMin()
    82 */
    83 void QwtPlotGrid::enableY( bool tf )
    84 {
    85     if ( d_data->yEnabled != tf )
    86     {
    87         d_data->yEnabled = tf;
    88         itemChanged();
    89     }
    90 }
    91 
    92 /*!
    93   \brief Enable or disable  minor vertical gridlines.
    94   \param tf Enable (true) or disable
     71void QwtPlotGrid::enableX( bool on )
     72{
     73    if ( d_data->xEnabled != on )
     74    {
     75        d_data->xEnabled = on;
     76
     77        legendChanged();
     78        itemChanged();
     79    }
     80}
     81
     82/*!
     83  \brief Enable or disable horizontal grid lines
     84  \param on Enable (true) or disable
     85  \sa Minor grid lines can be enabled or disabled with enableYMin()
     86*/
     87void QwtPlotGrid::enableY( bool on )
     88{
     89    if ( d_data->yEnabled != on )
     90    {
     91        d_data->yEnabled = on;
     92
     93        legendChanged();
     94        itemChanged();
     95    }
     96}
     97
     98/*!
     99  \brief Enable or disable  minor vertical grid lines.
     100  \param on Enable (true) or disable
    95101  \sa enableX()
    96102*/
    97 void QwtPlotGrid::enableXMin( bool tf )
    98 {
    99     if ( d_data->xMinEnabled != tf )
    100     {
    101         d_data->xMinEnabled = tf;
    102         itemChanged();
    103     }
    104 }
    105 
    106 /*!
    107   \brief Enable or disable minor horizontal gridlines
    108   \param tf Enable (true) or disable
     103void QwtPlotGrid::enableXMin( bool on )
     104{
     105    if ( d_data->xMinEnabled != on )
     106    {
     107        d_data->xMinEnabled = on;
     108
     109        legendChanged();
     110        itemChanged();
     111    }
     112}
     113
     114/*!
     115  \brief Enable or disable minor horizontal grid lines
     116  \param on Enable (true) or disable
    109117  \sa enableY()
    110118*/
    111 void QwtPlotGrid::enableYMin( bool tf )
    112 {
    113     if ( d_data->yMinEnabled != tf )
    114     {
    115         d_data->yMinEnabled = tf;
     119void QwtPlotGrid::enableYMin( bool on )
     120{
     121    if ( d_data->yMinEnabled != on )
     122    {
     123        d_data->yMinEnabled = on;
     124
     125        legendChanged();
    116126        itemChanged();
    117127    }
     
    147157
    148158/*!
    149   Assign a pen for both major and minor gridlines
     159  Build and assign a pen for both major and minor grid lines
     160
     161  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     162  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     163  to hide this incompatibility.
     164
     165  \param color Pen color
     166  \param width Pen width
     167  \param style Pen style
     168
     169  \sa pen(), brush()
     170 */
     171void QwtPlotGrid::setPen( const QColor &color, qreal width, Qt::PenStyle style )
     172{
     173    setPen( QPen( color, width, style ) );
     174}
     175
     176/*!
     177  Assign a pen for both major and minor grid lines
    150178
    151179  \param pen Pen
    152   \sa setMajPen(), setMinPen()
     180  \sa setMajorPen(), setMinorPen()
    153181*/
    154182void QwtPlotGrid::setPen( const QPen &pen )
    155183{
    156     if ( d_data->majPen != pen || d_data->minPen != pen )
    157     {
    158         d_data->majPen = pen;
    159         d_data->minPen = pen;
    160         itemChanged();
    161     }
    162 }
    163 
    164 /*!
    165   Assign a pen for the major gridlines
     184    if ( d_data->majorPen != pen || d_data->minorPen != pen )
     185    {
     186        d_data->majorPen = pen;
     187        d_data->minorPen = pen;
     188
     189        legendChanged();
     190        itemChanged();
     191    }
     192}
     193
     194/*!
     195  Build and assign a pen for both major grid lines
     196
     197  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     198  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     199  to hide this incompatibility.
     200
     201  \param color Pen color
     202  \param width Pen width
     203  \param style Pen style
     204
     205  \sa pen(), brush()
     206 */
     207void QwtPlotGrid::setMajorPen( const QColor &color, qreal width, Qt::PenStyle style )
     208{
     209    setMajorPen( QPen( color, width, style ) );
     210}
     211
     212/*!
     213  Assign a pen for the major grid lines
    166214
    167215  \param pen Pen
    168   \sa majPen(), setMinPen(), setPen()
    169 */
    170 void QwtPlotGrid::setMajPen( const QPen &pen )
    171 {
    172     if ( d_data->majPen != pen )
    173     {
    174         d_data->majPen = pen;
    175         itemChanged();
    176     }
    177 }
    178 
    179 /*!
    180   Assign a pen for the minor gridlines
     216  \sa majorPen(), setMinorPen(), setPen()
     217*/
     218void QwtPlotGrid::setMajorPen( const QPen &pen )
     219{
     220    if ( d_data->majorPen != pen )
     221    {
     222        d_data->majorPen = pen;
     223
     224        legendChanged();
     225        itemChanged();
     226    }
     227}
     228
     229/*!
     230  Build and assign a pen for the minor grid lines
     231
     232  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     233  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     234  to hide this incompatibility.
     235
     236  \param color Pen color
     237  \param width Pen width
     238  \param style Pen style
     239
     240  \sa pen(), brush()
     241 */
     242void QwtPlotGrid::setMinorPen( const QColor &color, qreal width, Qt::PenStyle style )
     243{
     244    setMinorPen( QPen( color, width, style ) );
     245}
     246
     247/*!
     248  Assign a pen for the minor grid lines
    181249
    182250  \param pen Pen
    183   \sa minPen(), setMajPen(), setPen()
    184 */
    185 void QwtPlotGrid::setMinPen( const QPen &pen )
    186 {
    187     if ( d_data->minPen != pen )
    188     {
    189         d_data->minPen = pen;
     251  \sa minorPen(), setMajorPen(), setPen()
     252*/
     253void QwtPlotGrid::setMinorPen( const QPen &pen )
     254{
     255    if ( d_data->minorPen != pen )
     256    {
     257        d_data->minorPen = pen;
     258
     259        legendChanged();
    190260        itemChanged();
    191261    }
     
    196266
    197267  The grid is drawn into the bounding rectangle such that
    198   gridlines begin and end at the rectangle's borders. The X and Y
     268  grid lines begin and end at the rectangle's borders. The X and Y
    199269  maps are used to map the scale divisions into the drawing region
    200270  screen.
     271
    201272  \param painter  Painter
    202273  \param xMap X axis map
    203274  \param yMap Y axis
    204   \param canvasRect Contents rect of the plot canvas
     275  \param canvasRect Contents rectangle of the plot canvas
    205276*/
    206277void QwtPlotGrid::draw( QPainter *painter,
     
    208279    const QRectF &canvasRect ) const
    209280{
    210     //  draw minor gridlines
    211     QPen minPen = d_data->minPen;
    212     minPen.setCapStyle( Qt::FlatCap );
    213 
    214     painter->setPen( minPen );
     281    //  draw minor grid lines
     282    QPen minorPen = d_data->minorPen;
     283    minorPen.setCapStyle( Qt::FlatCap );
     284
     285    painter->setPen( minorPen );
    215286
    216287    if ( d_data->xEnabled && d_data->xMinEnabled )
     
    230301    }
    231302
    232     //  draw major gridlines
    233     QPen majPen = d_data->majPen;
    234     majPen.setCapStyle( Qt::FlatCap );
    235 
    236     painter->setPen( majPen );
     303    //  draw major grid lines
     304    QPen majorPen = d_data->majorPen;
     305    majorPen.setCapStyle( Qt::FlatCap );
     306
     307    painter->setPen( majorPen );
    237308
    238309    if ( d_data->xEnabled )
     
    286357
    287358/*!
    288   \return the pen for the major gridlines
    289   \sa setMajPen(), setMinPen(), setPen()
    290 */
    291 const QPen &QwtPlotGrid::majPen() const
    292 {
    293     return d_data->majPen;
    294 }
    295 
    296 /*!
    297   \return the pen for the minor gridlines
    298   \sa setMinPen(), setMajPen(), setPen()
    299 */
    300 const QPen &QwtPlotGrid::minPen() const
    301 {
    302     return d_data->minPen;
    303 }
    304 
    305 /*!
    306   \return true if vertical gridlines are enabled
     359  \return the pen for the major grid lines
     360  \sa setMajorPen(), setMinorPen(), setPen()
     361*/
     362const QPen &QwtPlotGrid::majorPen() const
     363{
     364    return d_data->majorPen;
     365}
     366
     367/*!
     368  \return the pen for the minor grid lines
     369  \sa setMinorPen(), setMajorPen(), setPen()
     370*/
     371const QPen &QwtPlotGrid::minorPen() const
     372{
     373    return d_data->minorPen;
     374}
     375
     376/*!
     377  \return true if vertical grid lines are enabled
    307378  \sa enableX()
    308379*/
     
    313384
    314385/*!
    315   \return true if minor vertical gridlines are enabled
     386  \return true if minor vertical grid lines are enabled
    316387  \sa enableXMin()
    317388*/
     
    322393
    323394/*!
    324   \return true if horizontal gridlines are enabled
     395  \return true if horizontal grid lines are enabled
    325396  \sa enableY()
    326397*/
     
    331402
    332403/*!
    333   \return true if minor horizontal gridlines are enabled
     404  \return true if minor horizontal grid lines are enabled
    334405  \sa enableYMin()
    335406*/
  • trunk/BNC/qwt/qwt_plot_grid.h

    r4271 r8127  
    2525  The QwtPlotGrid class can be used to draw a coordinate grid.
    2626  A coordinate grid consists of major and minor vertical
    27   and horizontal gridlines. The locations of the gridlines
     27  and horizontal grid lines. The locations of the grid lines
    2828  are determined by the X and Y scale divisions which can
    2929  be assigned with setXDiv() and setYDiv().
     
    5858    const QwtScaleDiv &yScaleDiv() const;
    5959
    60     void setPen( const QPen &p );
     60    void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
     61    void setPen( const QPen & );
    6162
    62     void setMajPen( const QPen &p );
    63     const QPen& majPen() const;
     63    void setMajorPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
     64    void setMajorPen( const QPen & );
     65    const QPen& majorPen() const;
    6466
    65     void setMinPen( const QPen &p );
    66     const QPen& minPen() const;
     67    void setMinorPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
     68    void setMinorPen( const QPen &p );
     69    const QPen& minorPen() const;
    6770
    6871    virtual void draw( QPainter *p,
  • trunk/BNC/qwt/qwt_plot_histogram.cpp

    r4271 r8127  
    1010#include "qwt_plot_histogram.h"
    1111#include "qwt_plot.h"
    12 #include "qwt_legend.h"
    13 #include "qwt_legend_item.h"
    1412#include "qwt_painter.h"
    1513#include "qwt_column_symbol.h"
     
    1816#include <qpainter.h>
    1917
    20 static inline bool isCombinable( const QwtInterval &d1,
     18static inline bool qwtIsCombinable( const QwtInterval &d1,
    2119    const QwtInterval &d2 )
    2220{
     
    6361  \param title Title of the histogram.
    6462*/
    65 
    6663QwtPlotHistogram::QwtPlotHistogram( const QwtText &title ):
    67     QwtPlotSeriesItem<QwtIntervalSample>( title )
     64    QwtPlotSeriesItem( title )
    6865{
    6966    init();
     
    7572*/
    7673QwtPlotHistogram::QwtPlotHistogram( const QString &title ):
    77     QwtPlotSeriesItem<QwtIntervalSample>( title )
     74    QwtPlotSeriesItem( title )
    7875{
    7976    init();
     
    9087{
    9188    d_data = new PrivateData();
    92     d_series = new QwtIntervalSeriesData();
     89    setData( new QwtIntervalSeriesData() );
    9390
    9491    setItemAttribute( QwtPlotItem::AutoScale, true );
     
    109106    {
    110107        d_data->style = style;
     108
     109        legendChanged();
    111110        itemChanged();
    112111    }
     
    114113
    115114/*!
    116     Return the current style
     115    \return Style of the histogram
    117116    \sa HistogramStyle, setStyle()
    118117*/
     
    121120    return d_data->style;
    122121}
     122
     123/*!
     124  Build and assign a pen
     125   
     126  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     127  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     128  to hide this incompatibility.
     129   
     130  \param color Pen color
     131  \param width Pen width
     132  \param style Pen style
     133   
     134  \sa pen(), brush()
     135 */
     136void QwtPlotHistogram::setPen( const QColor &color, qreal width, Qt::PenStyle style )
     137{   
     138    setPen( QPen( color, width, style ) );
     139}   
    123140
    124141/*!
     
    133150    {
    134151        d_data->pen = pen;
     152
     153        legendChanged();
    135154        itemChanged();
    136155    }
     
    157176    {
    158177        d_data->brush = brush;
     178
     179        legendChanged();
    159180        itemChanged();
    160181    }
     
    181202
    182203  \note In applications, where different intervals need to be displayed
    183         in a different way ( f.e different colors or even using differnt symbols)
     204        in a different way ( f.e different colors or even using different symbols)
    184205        it is recommended to overload drawColumn().
    185206*/
     
    190211        delete d_data->symbol;
    191212        d_data->symbol = symbol;
     213
     214        legendChanged();
    192215        itemChanged();
    193216    }
     
    238261QRectF QwtPlotHistogram::boundingRect() const
    239262{
    240     QRectF rect = d_series->boundingRect();
     263    QRectF rect = data()->boundingRect();
    241264    if ( !rect.isValid() )
    242265        return rect;
     
    276299    const QVector<QwtIntervalSample> &samples )
    277300{
    278     delete d_series;
    279     d_series = new QwtIntervalSeriesData( samples );
    280     itemChanged();
     301    setData( new QwtIntervalSeriesData( samples ) );
     302}
     303
     304/*!
     305  Assign a series of samples
     306   
     307  setSamples() is just a wrapper for setData() without any additional
     308  value - beside that it is easier to find for the developer.
     309   
     310  \param data Data
     311  \warning The item takes ownership of the data object, deleting
     312           it when its not used anymore.
     313*/
     314void QwtPlotHistogram::setSamples(
     315    QwtSeriesData<QwtIntervalSample> *data )
     316{
     317    setData( data );
    281318}
    282319
     
    287324  \param xMap Maps x-values into pixel coordinates.
    288325  \param yMap Maps y-values into pixel coordinates.
    289   \param canvasRect Contents rect of the canvas
     326  \param canvasRect Contents rectangle of the canvas
    290327  \param from Index of the first sample to be painted
    291328  \param to Index of the last sample to be painted. If to < 0 the
     
    350387    for ( int i = from; i <= to; i++ )
    351388    {
    352         const QwtIntervalSample sample = d_series->sample( i );
     389        const QwtIntervalSample sample = this->sample( i );
    353390
    354391        if ( !sample.interval.isValid() )
     
    361398        if ( previous.interval.isValid() )
    362399        {
    363             if ( !isCombinable( previous.interval, sample.interval ) )
     400            if ( !qwtIsCombinable( previous.interval, sample.interval ) )
    364401                flushPolygon( painter, v0, polygon );
    365402        }
     
    426463    painter->setBrush( d_data->brush );
    427464
     465    const QwtSeriesData<QwtIntervalSample> *series = data();
     466
    428467    for ( int i = from; i <= to; i++ )
    429468    {
    430         const QwtIntervalSample sample = d_series->sample( i );
     469        const QwtIntervalSample sample = series->sample( i );
    431470        if ( !sample.interval.isNull() )
    432471        {
     
    458497    painter->setBrush( Qt::NoBrush );
    459498
     499    const QwtSeriesData<QwtIntervalSample> *series = data();
     500
    460501    for ( int i = from; i <= to; i++ )
    461502    {
    462         const QwtIntervalSample sample = d_series->sample( i );
     503        const QwtIntervalSample sample = series->sample( i );
    463504        if ( !sample.interval.isNull() )
    464505        {
     
    532573            polygon += QPointF( baseLine, polygon.first().y() );
    533574        }
     575
    534576        QwtPainter::drawPolygon( painter, polygon );
    535         polygon.resize( polygon.size() - 2 );
     577
     578        polygon.pop_back();
     579        polygon.pop_back();
    536580    }
    537581    if ( d_data->pen.style() != Qt::NoPen )
     
    601645
    602646  \note In applications, where different intervals need to be displayed
    603         in a different way ( f.e different colors or even using differnt symbols)
     647        in a different way ( f.e different colors or even using different symbols)
    604648        it is recommended to overload drawColumn().
    605649*/
     
    630674
    631675/*!
    632   Draw a plain rectangle without pen using the brush() as identifier
    633 
    634   \param painter Painter
    635   \param rect Bounding rectangle for the identifier
    636 */
    637 void QwtPlotHistogram::drawLegendIdentifier(
    638     QPainter *painter, const QRectF &rect ) const
    639 {
    640     const double dim = qMin( rect.width(), rect.height() );
    641 
    642     QSizeF size( dim, dim );
    643 
    644     QRectF r( 0, 0, size.width(), size.height() );
    645     r.moveCenter( rect.center() );
    646 
    647     painter->fillRect( r, d_data->brush );
    648 }
     676  A plain rectangle without pen using the brush()
     677
     678  \param index Index of the legend entry
     679                ( ignored as there is only one )
     680  \param size Icon size
     681  \return A graphic displaying the icon
     682   
     683  \sa QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData()
     684*/
     685QwtGraphic QwtPlotHistogram::legendIcon( int index,
     686    const QSizeF &size ) const
     687{
     688    Q_UNUSED( index );
     689    return defaultIcon( d_data->brush, size );
     690}
  • trunk/BNC/qwt/qwt_plot_histogram.h

    r4271 r8127  
    3333        While "image histograms" can be displayed by a QwtPlotCurve there
    3434        is no applicable plot item for a "color histogram" yet.
     35
     36  \sa QwtPlotBarChart, QwtPlotMultiBarChart
    3537*/
    3638
    37 class QWT_EXPORT QwtPlotHistogram: public QwtPlotSeriesItem<QwtIntervalSample>
     39class QWT_EXPORT QwtPlotHistogram:
     40    public QwtPlotSeriesItem, public QwtSeriesStore<QwtIntervalSample>
    3841{
    3942public:
     
    8083    virtual int rtti() const;
    8184
     85    void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
    8286    void setPen( const QPen & );
    8387    const QPen &pen() const;
     
    8791
    8892    void setSamples( const QVector<QwtIntervalSample> & );
     93    void setSamples( QwtSeriesData<QwtIntervalSample> * );
    8994
    9095    void setBaseline( double reference );
     
    103108    virtual QRectF boundingRect() const;
    104109
    105     virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const;
     110    virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
    106111
    107112protected:
  • trunk/BNC/qwt/qwt_plot_intervalcurve.cpp

    r4271 r8127  
    1313#include "qwt_clipper.h"
    1414#include "qwt_painter.h"
     15#include <string.h>
    1516
    1617#include <qpainter.h>
     
    2425
    2526    const bool isOffScreen = ( y < yMin ) || ( y > yMax )
    26         || ( x1 < xMin && x2 < xMin ) || ( x1 > yMax && x2 > xMax );
     27        || ( x1 < xMin && x2 < xMin ) || ( x1 > xMax && x2 > xMax );
    2728
    2829    return !isOffScreen;
     
    4647public:
    4748    PrivateData():
    48         style( Tube ),
     49        style( QwtPlotIntervalCurve::Tube ),
    4950        symbol( NULL ),
    5051        pen( Qt::black ),
     
    5354        paintAttributes = QwtPlotIntervalCurve::ClipPolygons;
    5455        paintAttributes |= QwtPlotIntervalCurve::ClipSymbol;
    55    
     56
    5657        pen.setCapStyle( Qt::FlatCap );
    5758    }
     
    6263    }
    6364
    64     CurveStyle style;
     65    QwtPlotIntervalCurve::CurveStyle style;
    6566    const QwtIntervalSymbol *symbol;
    6667
     
    7677*/
    7778QwtPlotIntervalCurve::QwtPlotIntervalCurve( const QwtText &title ):
    78     QwtPlotSeriesItem<QwtIntervalSample>( title )
     79    QwtPlotSeriesItem( title )
    7980{
    8081    init();
     
    8687*/
    8788QwtPlotIntervalCurve::QwtPlotIntervalCurve( const QString &title ):
    88     QwtPlotSeriesItem<QwtIntervalSample>( QwtText( title ) )
     89    QwtPlotSeriesItem( QwtText( title ) )
    8990{
    9091    init();
     
    104105
    105106    d_data = new PrivateData;
    106     d_series = new QwtIntervalSeriesData();
     107    setData( new QwtIntervalSeriesData() );
    107108
    108109    setZ( 19.0 );
     
    122123  \sa testPaintAttribute()
    123124*/
    124 void QwtPlotIntervalCurve::setPaintAttribute( 
     125void QwtPlotIntervalCurve::setPaintAttribute(
    125126    PaintAttribute attribute, bool on )
    126127{
     
    132133
    133134/*!
    134     \brief Return the current paint attributes
     135    \return True, when attribute is enabled
    135136    \sa PaintAttribute, setPaintAttribute()
    136137*/
    137 bool QwtPlotIntervalCurve::testPaintAttribute( 
     138bool QwtPlotIntervalCurve::testPaintAttribute(
    138139    PaintAttribute attribute ) const
    139140{
     
    148149    const QVector<QwtIntervalSample> &samples )
    149150{
    150     delete d_series;
    151     d_series = new QwtIntervalSeriesData( samples );
    152     itemChanged();
     151    setData( new QwtIntervalSeriesData( samples ) );
     152}
     153
     154/*!
     155  Assign a series of samples
     156   
     157  setSamples() is just a wrapper for setData() without any additional
     158  value - beside that it is easier to find for the developer.
     159   
     160  \param data Data
     161  \warning The item takes ownership of the data object, deleting
     162           it when its not used anymore.
     163*/
     164void QwtPlotIntervalCurve::setSamples(
     165    QwtSeriesData<QwtIntervalSample> *data )
     166{
     167    setData( data );
    153168}
    154169
     
    164179    {
    165180        d_data->style = style;
     181
     182        legendChanged();
    166183        itemChanged();
    167184    }
     
    169186
    170187/*!
    171     \brief Return the current style
     188    \return Style of the curve
    172189    \sa setStyle()
    173190*/
     
    189206        delete d_data->symbol;
    190207        d_data->symbol = symbol;
     208
     209        legendChanged();
    191210        itemChanged();
    192211    }
     
    201220    return d_data->symbol;
    202221}
     222
     223/*!
     224  Build and assign a pen
     225   
     226  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     227  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     228  to hide this incompatibility.
     229   
     230  \param color Pen color
     231  \param width Pen width
     232  \param style Pen style
     233   
     234  \sa pen(), brush()
     235 */
     236void QwtPlotIntervalCurve::setPen( const QColor &color, qreal width, Qt::PenStyle style )
     237{   
     238    setPen( QPen( color, width, style ) );
     239}   
    203240
    204241/*!
     
    212249    {
    213250        d_data->pen = pen;
     251
     252        legendChanged();
    214253        itemChanged();
    215254    }
     
    217256
    218257/*!
    219     \brief Return the pen used to draw the lines
     258    \return Pen used to draw the lines
    220259    \sa setPen(), brush()
    221260*/
     
    238277    {
    239278        d_data->brush = brush;
     279
     280        legendChanged();
    240281        itemChanged();
    241282    }
     
    257298QRectF QwtPlotIntervalCurve::boundingRect() const
    258299{
    259     QRectF rect = QwtPlotSeriesItem<QwtIntervalSample>::boundingRect();
     300    QRectF rect = QwtPlotSeriesItem::boundingRect();
    260301    if ( rect.isValid() && orientation() == Qt::Vertical )
    261302        rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() );
     
    270311  \param xMap Maps x-values into pixel coordinates.
    271312  \param yMap Maps y-values into pixel coordinates.
    272   \param canvasRect Contents rect of the canvas
     313  \param canvasRect Contents rectangle of the canvas
    273314  \param from Index of the first sample to be painted
    274315  \param to Index of the last sample to be painted. If to < 0 the
     
    304345        ( d_data->symbol->style() != QwtIntervalSymbol::NoSymbol ) )
    305346    {
    306         drawSymbols( painter, *d_data->symbol, 
     347        drawSymbols( painter, *d_data->symbol,
    307348            xMap, yMap, canvasRect, from, to );
    308349    }
     
    319360  \param xMap Maps x-values into pixel coordinates.
    320361  \param yMap Maps y-values into pixel coordinates.
    321   \param canvasRect Contents rect of the canvas
     362  \param canvasRect Contents rectangle of the canvas
    322363  \param from Index of the first sample to be painted
    323364  \param to Index of the last sample to be painted. If to < 0 the
     
    388429        {
    389430            const qreal m = 1.0;
    390             const QPolygonF p = QwtClipper::clipPolygonF( 
    391                 canvasRect.adjusted(-m, -m, m, m), polygon, true );
     431            const QPolygonF p = QwtClipper::clipPolygonF(
     432               canvasRect.adjusted( -m, -m, m, m ), polygon, true );
    392433
    393434            QwtPainter::drawPolygon( painter, p );
     
    406447        if ( d_data->paintAttributes & ClipPolygons )
    407448        {
    408             qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
    409             const QRectF clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);
     449            qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF() );
     450            const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw );
    410451
    411452            QPolygonF p;
    412453
    413454            p.resize( size );
    414             qMemCopy( p.data(), points, size * sizeof( QPointF ) );
    415             p = QwtClipper::clipPolygonF( canvasRect, p );
     455            ::memcpy( p.data(), points, size * sizeof( QPointF ) );
     456            p = QwtClipper::clipPolygonF( clipRect, p );
    416457            QwtPainter::drawPolyline( painter, p );
    417458
    418459            p.resize( size );
    419             qMemCopy( p.data(), points + size, size * sizeof( QPointF ) );
    420             p = QwtClipper::clipPolygonF( canvasRect, p );
     460            ::memcpy( p.data(), points + size, size * sizeof( QPointF ) );
     461            p = QwtClipper::clipPolygonF( clipRect, p );
    421462            QwtPainter::drawPolyline( painter, p );
    422463        }
     
    438479  \param xMap x map
    439480  \param yMap y map
    440   \param canvasRect Contents rect of the canvas
     481  \param canvasRect Contents rectangle of the canvas
    441482  \param from Index of the first sample to be painted
    442483  \param to Index of the last sample to be painted
     
    457498    painter->setBrush( symbol.brush() );
    458499
    459     const QRectF &tr = QwtScaleMap::invTransform( xMap, yMap, canvasRect);
     500    const QRectF tr = QwtScaleMap::invTransform( xMap, yMap, canvasRect );
    460501
    461502    const double xMin = tr.left();
     
    464505    const double yMax = tr.bottom();
    465506
    466     const bool doClip = d_data->paintAttributes & ClipPolygons;
     507    const bool doClip = d_data->paintAttributes & ClipSymbol;
    467508
    468509    for ( int i = from; i <= to; i++ )
     
    500541
    501542/*!
    502   In case of Tibe stale() a plain rectangle is painted without a pen filled
    503   the brush(). If a symbol is assigned it is painted cebtered into rect.
    504 
    505   \param painter Painter
    506   \param rect Bounding rectangle for the identifier
    507 */
    508 
    509 void QwtPlotIntervalCurve::drawLegendIdentifier(
    510     QPainter *painter, const QRectF &rect ) const
    511 {
    512     const double dim = qMin( rect.width(), rect.height() );
    513 
    514     QSizeF size( dim, dim );
    515 
    516     QRectF r( 0, 0, size.width(), size.height() );
    517     r.moveCenter( rect.center() );
     543  \return Icon for the legend
     544
     545  In case of Tube style() the icon is a plain rectangle filled with the brush().
     546  If a symbol is assigned it is scaled to size.
     547
     548  \param index Index of the legend entry
     549               ( ignored as there is only one )
     550  \param size Icon size
     551   
     552  \sa QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData()
     553*/
     554QwtGraphic QwtPlotIntervalCurve::legendIcon(
     555    int index, const QSizeF &size ) const
     556{
     557    Q_UNUSED( index );
     558
     559    if ( size.isEmpty() )
     560        return QwtGraphic();
     561
     562    QwtGraphic icon;
     563    icon.setDefaultSize( size );
     564    icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
     565
     566    QPainter painter( &icon );
     567    painter.setRenderHint( QPainter::Antialiasing,
     568        testRenderHint( QwtPlotItem::RenderAntialiased ) );
    518569
    519570    if ( d_data->style == Tube )
    520571    {
    521         painter->fillRect( r, d_data->brush );
     572        QRectF r( 0, 0, size.width(), size.height() );
     573        painter.fillRect( r, d_data->brush );
    522574    }
    523575
     
    529581        pen.setCapStyle( Qt::FlatCap );
    530582
    531         painter->setPen( pen );
    532         painter->setBrush( d_data->symbol->brush() );
     583        painter.setPen( pen );
     584        painter.setBrush( d_data->symbol->brush() );
    533585
    534586        if ( orientation() == Qt::Vertical )
    535587        {
    536             d_data->symbol->draw( painter, orientation(),
    537                 QPointF( r.center().x(), r.top() ),
    538                 QPointF( r.center().x(), r.bottom() - 1 ) );
     588            const double x = 0.5 * size.width();
     589
     590            d_data->symbol->draw( &painter, orientation(),
     591                QPointF( x, 0 ), QPointF( x, size.height() - 1.0 ) );
    539592        }
    540593        else
    541594        {
    542             d_data->symbol->draw( painter, orientation(),
    543                 QPointF( r.left(), r.center().y() ),
    544                 QPointF( r.right() - 1, r.center().y() ) );
    545         }
    546     }
    547 }
     595            const double y = 0.5 * size.height();
     596
     597            d_data->symbol->draw( &painter, orientation(),
     598                QPointF( 0.0, y ), QPointF( size.width() - 1.0, y ) );
     599        }
     600    }
     601
     602    return icon;
     603}
  • trunk/BNC/qwt/qwt_plot_intervalcurve.h

    r4271 r8127  
    2323  The representation depends on the style() and an optional symbol()
    2424  that is displayed for each interval. QwtPlotIntervalCurve might be used
    25   to disply error bars or the area between 2 curves.
     25  to display error bars or the area between 2 curves.
    2626*/
    27 
    28 class QWT_EXPORT QwtPlotIntervalCurve: public QwtPlotSeriesItem<QwtIntervalSample>
     27class QWT_EXPORT QwtPlotIntervalCurve:
     28    public QwtPlotSeriesItem, public QwtSeriesStore<QwtIntervalSample>
    2929{
    3030public:
     
    3535        \sa setStyle(), style()
    3636    */
    37 
    3837    enum CurveStyle
    3938    {
     
    8988
    9089    void setSamples( const QVector<QwtIntervalSample> & );
     90    void setSamples( QwtSeriesData<QwtIntervalSample> * );
    9191
     92    void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
    9293    void setPen( const QPen & );
    9394    const QPen &pen() const;
     
    107108
    108109    virtual QRectF boundingRect() const;
    109     virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const;
     110
     111    virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
    110112
    111113protected:
  • trunk/BNC/qwt/qwt_plot_item.cpp

    r4271 r8127  
    1111#include "qwt_text.h"
    1212#include "qwt_plot.h"
    13 #include "qwt_legend.h"
    14 #include "qwt_legend_item.h"
     13#include "qwt_legend_data.h"
    1514#include "qwt_scale_div.h"
     15#include "qwt_graphic.h"
    1616#include <qpainter.h>
    1717
     
    2323        isVisible( true ),
    2424        attributes( 0 ),
     25        interests( 0 ),
    2526        renderHints( 0 ),
     27        renderThreadCount( 1 ),
    2628        z( 0.0 ),
    2729        xAxis( QwtPlot::xBottom ),
    28         yAxis( QwtPlot::yLeft )
     30        yAxis( QwtPlot::yLeft ),
     31        legendIconSize( 8, 8 )
    2932    {
    3033    }
     
    3336
    3437    bool isVisible;
     38
    3539    QwtPlotItem::ItemAttributes attributes;
     40    QwtPlotItem::ItemInterests interests;
     41
    3642    QwtPlotItem::RenderHints renderHints;
     43    uint renderThreadCount;
     44
    3745    double z;
    3846
     
    4149
    4250    QwtText title;
     51    QSize legendIconSize;
    4352};
    4453
     
    7685        return;
    7786
    78     // remove the item from the previous plot
    79 
    8087    if ( d_data->plot )
    81     {
    82         if ( d_data->plot->legend() )
    83             d_data->plot->legend()->remove( this );
    84 
    8588        d_data->plot->attachItem( this, false );
    8689
    87         if ( d_data->plot->autoReplot() )
    88             d_data->plot->update();
    89     }
    90 
    9190    d_data->plot = plot;
    9291
    9392    if ( d_data->plot )
    94     {
    95         // insert the item into the current plot
    96 
    9793        d_data->plot->attachItem( this, true );
    98         itemChanged();
    99     }
    10094}
    10195
     
    191185    {
    192186        d_data->title = title;
    193         itemChanged();
     187
     188        legendChanged();
     189#if 0
     190        itemChanged();
     191#endif
    194192    }
    195193}
     
    210208   \param on true/false
    211209
    212    \sa testItemAttribute(), ItemAttribute
     210   \sa testItemAttribute(), ItemInterest
    213211*/
    214212void QwtPlotItem::setItemAttribute( ItemAttribute attribute, bool on )
    215213{
    216     if ( bool( d_data->attributes & attribute ) != on )
     214    if ( d_data->attributes.testFlag( attribute ) != on )
    217215    {
    218216        if ( on )
     
    221219            d_data->attributes &= ~attribute;
    222220
     221        if ( attribute == QwtPlotItem::Legend )
     222            legendChanged();
     223
    223224        itemChanged();
    224225    }
     
    230231   \param attribute Attribute type
    231232   \return true/false
    232    \sa setItemAttribute(), ItemAttribute
     233   \sa setItemAttribute(), ItemInterest
    233234*/
    234235bool QwtPlotItem::testItemAttribute( ItemAttribute attribute ) const
    235236{
    236     return ( d_data->attributes & attribute );
     237    return d_data->attributes.testFlag( attribute );
     238}
     239
     240/*!
     241   Toggle an item interest
     242
     243   \param interest Interest type
     244   \param on true/false
     245
     246   \sa testItemInterest(), ItemAttribute
     247*/
     248void QwtPlotItem::setItemInterest( ItemInterest interest, bool on )
     249{
     250    if ( d_data->interests.testFlag( interest ) != on )
     251    {
     252        if ( on )
     253            d_data->interests |= interest;
     254        else
     255            d_data->interests &= ~interest;
     256
     257        itemChanged();
     258    }
     259}
     260
     261/*!
     262   Test an item interest
     263
     264   \param interest Interest type
     265   \return true/false
     266   \sa setItemInterest(), ItemAttribute
     267*/
     268bool QwtPlotItem::testItemInterest( ItemInterest interest ) const
     269{
     270    return d_data->interests.testFlag( interest );
    237271}
    238272
     
    247281void QwtPlotItem::setRenderHint( RenderHint hint, bool on )
    248282{
    249     if ( ( ( d_data->renderHints & hint ) != 0 ) != on )
     283    if ( d_data->renderHints.testFlag( hint ) != on )
    250284    {
    251285        if ( on )
     
    267301bool QwtPlotItem::testRenderHint( RenderHint hint ) const
    268302{
    269     return ( d_data->renderHints & hint );
    270 }
     303    return d_data->renderHints.testFlag( hint );
     304}
     305
     306/*!
     307   On multi core systems rendering of certain plot item
     308   ( f.e QwtPlotRasterItem ) can be done in parallel in
     309   several threads.
     310
     311   The default setting is set to 1.
     312
     313   \param numThreads Number of threads to be used for rendering.
     314                     If numThreads is set to 0, the system specific
     315                     ideal thread count is used.
     316
     317   The default thread count is 1 ( = no additional threads )
     318*/
     319void QwtPlotItem::setRenderThreadCount( uint numThreads )
     320{
     321    d_data->renderThreadCount = numThreads;
     322}
     323
     324/*!
     325   \return Number of threads to be used for rendering.
     326           If numThreads() is set to 0, the system specific
     327           ideal thread count is used.
     328*/
     329uint QwtPlotItem::renderThreadCount() const
     330{
     331    return d_data->renderThreadCount;
     332}
     333
     334/*!
     335   Set the size of the legend icon
     336
     337   The default setting is 8x8 pixels
     338
     339   \param size Size
     340   \sa legendIconSize(), legendIcon()
     341*/
     342void QwtPlotItem::setLegendIconSize( const QSize &size )
     343{
     344    if ( d_data->legendIconSize != size )
     345    {
     346        d_data->legendIconSize = size;
     347        legendChanged();
     348    }
     349}
     350
     351/*!
     352   \return Legend icon size
     353   \sa setLegendIconSize(), legendIcon()
     354*/
     355QSize QwtPlotItem::legendIconSize() const
     356{
     357    return d_data->legendIconSize;
     358}
     359
     360/*!
     361   \return Icon representing the item on the legend
     362
     363   The default implementation returns an invalid icon
     364
     365   \param index Index of the legend entry
     366                ( usually there is only one )
     367   \param size Icon size
     368
     369   \sa setLegendIconSize(), legendData()
     370 */
     371QwtGraphic QwtPlotItem::legendIcon(
     372    int index, const QSizeF &size ) const
     373{
     374    Q_UNUSED( index )
     375    Q_UNUSED( size )
     376
     377    return QwtGraphic();
     378}
     379
     380/*!
     381   \brief Return a default icon from a brush
     382
     383   The default icon is a filled rectangle used
     384   in several derived classes as legendIcon().
     385
     386   \param brush Fill brush
     387   \param size Icon size
     388
     389   \return A filled rectangle
     390 */
     391QwtGraphic QwtPlotItem::defaultIcon(
     392    const QBrush &brush, const QSizeF &size ) const
     393{   
     394    QwtGraphic icon;
     395    if ( !size.isEmpty() )
     396    {
     397        icon.setDefaultSize( size );
     398       
     399        QRectF r( 0, 0, size.width(), size.height() );
     400       
     401        QPainter painter( &icon );
     402        painter.fillRect( r, brush );
     403    }   
     404   
     405    return icon;
     406}   
    271407
    272408//! Show the item
     
    307443
    308444/*!
    309    Update the legend and call QwtPlot::autoRefresh for the
     445   Update the legend and call QwtPlot::autoRefresh() for the
    310446   parent plot.
    311447
    312    \sa updateLegend()
     448   \sa QwtPlot::legendChanged(), QwtPlot::autoRefresh()
    313449*/
    314450void QwtPlotItem::itemChanged()
    315451{
    316452    if ( d_data->plot )
    317     {
    318         if ( d_data->plot->legend() )
    319             updateLegend( d_data->plot->legend() );
    320 
    321453        d_data->plot->autoRefresh();
    322     }
     454}
     455
     456/*!
     457   Update the legend of the parent plot.
     458   \sa QwtPlot::updateLegend(), itemChanged()
     459*/
     460void QwtPlotItem::legendChanged()
     461{
     462    if ( testItemAttribute( QwtPlotItem::Legend ) && d_data->plot )
     463        d_data->plot->updateLegend( this );
    323464}
    324465
     
    326467   Set X and Y axis
    327468
    328    The item will painted according to the coordinates its Axes.
    329 
    330    \param xAxis X Axis
    331    \param yAxis Y Axis
    332 
    333    \sa setXAxis(), setYAxis(), xAxis(), yAxis()
     469   The item will painted according to the coordinates of its Axes.
     470
     471   \param xAxis X Axis ( QwtPlot::xBottom or QwtPlot::xTop )
     472   \param yAxis Y Axis ( QwtPlot::yLeft or QwtPlot::yRight )
     473
     474   \sa setXAxis(), setYAxis(), xAxis(), yAxis(), QwtPlot::Axis
    334475*/
    335476void QwtPlotItem::setAxes( int xAxis, int yAxis )
     
    349490   The item will painted according to the coordinates its Axes.
    350491
    351    \param axis X Axis
    352    \sa setAxes(), setYAxis(), xAxis()
     492   \param axis X Axis ( QwtPlot::xBottom or QwtPlot::xTop )
     493   \sa setAxes(), setYAxis(), xAxis(), QwtPlot::Axis
    353494*/
    354495void QwtPlotItem::setXAxis( int axis )
     
    366507   The item will painted according to the coordinates its Axes.
    367508
    368    \param axis Y Axis
    369    \sa setAxes(), setXAxis(), yAxis()
     509   \param axis Y Axis ( QwtPlot::yLeft or QwtPlot::yRight )
     510   \sa setAxes(), setXAxis(), yAxis(), QwtPlot::Axis
    370511*/
    371512void QwtPlotItem::setYAxis( int axis )
     
    392533/*!
    393534   \return An invalid bounding rect: QRectF(1.0, 1.0, -2.0, -2.0)
     535   \note A width or height < 0.0 is ignored by the autoscaler
    394536*/
    395537QRectF QwtPlotItem::boundingRect() const
     
    399541
    400542/*!
    401    \brief Allocate the widget that represents the item on the legend
    402 
    403    The default implementation returns a QwtLegendItem(), but an item
    404    could be represented by any type of widget,
    405    by overloading legendItem() and updateLegend().
    406 
    407    \return QwtLegendItem()
    408    \sa updateLegend() QwtLegend()
    409 */
    410 QWidget *QwtPlotItem::legendItem() const
    411 {
    412     QwtLegendItem *item = new QwtLegendItem;
    413     if ( d_data->plot )
    414     {
    415         QObject::connect( item, SIGNAL( clicked() ),
    416             d_data->plot, SLOT( legendItemClicked() ) );
    417         QObject::connect( item, SIGNAL( checked( bool ) ),
    418             d_data->plot, SLOT( legendItemChecked( bool ) ) );
    419     }
    420     return item;
    421 }
    422 
    423 /*!
    424    \brief Update the widget that represents the item on the legend
    425 
    426    updateLegend() is called from itemChanged() to adopt the widget
    427    representing the item on the legend to its new configuration.
    428 
    429    The default implementation updates a QwtLegendItem(),
    430    but an item could be represented by any type of widget,
    431    by overloading legendItem() and updateLegend().
    432 
    433    \param legend Legend
    434 
    435    \sa legendItem(), itemChanged(), QwtLegend()
    436 */
    437 void QwtPlotItem::updateLegend( QwtLegend *legend ) const
    438 {
    439     if ( legend == NULL )
    440         return;
    441 
    442     QWidget *lgdItem = legend->find( this );
    443     if ( testItemAttribute( QwtPlotItem::Legend ) )
    444     {
    445         if ( lgdItem == NULL )
    446         {
    447             lgdItem = legendItem();
    448             if ( lgdItem )
    449                 legend->insert( this, lgdItem );
    450         }
    451 
    452         QwtLegendItem *label = qobject_cast<QwtLegendItem *>( lgdItem );
    453         if ( label )
    454         {
    455             // paint the identifier
    456             const QSize sz = label->identifierSize();
    457 
    458             QPixmap identifier( sz.width(), sz.height() );
    459             identifier.fill( Qt::transparent );
    460 
    461             QPainter painter( &identifier );
    462             painter.setRenderHint( QPainter::Antialiasing,
    463                 testRenderHint( QwtPlotItem::RenderAntialiased ) );
    464             drawLegendIdentifier( &painter,
    465                 QRect( 0, 0, sz.width(), sz.height() ) );
    466             painter.end();
    467 
    468             const bool doUpdate = label->updatesEnabled();
    469             if ( doUpdate )
    470                 label->setUpdatesEnabled( false );
    471 
    472             label->setText( title() );
    473             label->setIdentifier( identifier );
    474             label->setItemMode( legend->itemMode() );
    475 
    476             if ( doUpdate )
    477                 label->setUpdatesEnabled( true );
    478 
    479             label->update();
    480         }
    481     }
    482     else
    483     {
    484         if ( lgdItem )
    485         {
    486             lgdItem->hide();
    487             lgdItem->deleteLater();
    488         }
    489     }
     543   \brief Calculate a hint for the canvas margin
     544
     545   When the QwtPlotItem::Margins flag is enabled the plot item
     546   indicates, that it needs some margins at the borders of the canvas.
     547   This is f.e. used by bar charts to reserve space for displaying
     548   the bars.
     549
     550   The margins are in target device coordinates ( pixels on screen )
     551
     552   \param xMap Maps x-values into pixel coordinates.
     553   \param yMap Maps y-values into pixel coordinates.
     554   \param canvasRect Contents rectangle of the canvas in painter coordinates
     555   \param left Returns the left margin
     556   \param top Returns the top margin
     557   \param right Returns the right margin
     558   \param bottom Returns the bottom margin
     559
     560   \return The default implementation returns 0 for all margins
     561
     562   \sa QwtPlot::getCanvasMarginsHint(), QwtPlot::updateCanvasMargins()
     563 */
     564void QwtPlotItem::getCanvasMarginHint( const QwtScaleMap &xMap,
     565    const QwtScaleMap &yMap, const QRectF &canvasRect,
     566    double &left, double &top, double &right, double &bottom ) const
     567{
     568    Q_UNUSED( xMap );
     569    Q_UNUSED( yMap );
     570    Q_UNUSED( canvasRect );
     571
     572    // use QMargins, when we don't need to support Qt < 4.6 anymore
     573    left = top = right = bottom = 0.0;
     574}
     575
     576/*!
     577   \brief Return all information, that is needed to represent
     578          the item on the legend
     579
     580   Most items are represented by one entry on the legend
     581   showing an icon and a text, but f.e. QwtPlotMultiBarChart
     582   displays one entry for each bar.
     583
     584   QwtLegendData is basically a list of QVariants that makes it
     585   possible to overload and reimplement legendData() to
     586   return almost any type of information, that is understood
     587   by the receiver that acts as the legend.
     588
     589   The default implementation returns one entry with
     590   the title() of the item and the legendIcon().
     591
     592   \return Data, that is needed to represent the item on the legend
     593   \sa title(), legendIcon(), QwtLegend, QwtPlotLegendItem
     594 */
     595QList<QwtLegendData> QwtPlotItem::legendData() const
     596{
     597    QwtLegendData data;
     598
     599    QwtText label = title();
     600    label.setRenderFlags( label.renderFlags() & Qt::AlignLeft );
     601           
     602    QVariant titleValue;
     603    qVariantSetValue( titleValue, label );
     604    data.setValue( QwtLegendData::TitleRole, titleValue );
     605       
     606    const QwtGraphic graphic = legendIcon( 0, legendIconSize() );
     607    if ( !graphic.isNull() )
     608    {   
     609        QVariant iconValue;
     610        qVariantSetValue( iconValue, graphic );
     611        data.setValue( QwtLegendData::IconRole, iconValue );
     612    }   
     613       
     614    QList<QwtLegendData> list;
     615    list += data;
     616
     617    return list;
    490618}
    491619
     
    498626   updateScaleDiv()
    499627
     628   updateScaleDiv() is only called when the ScaleInterest interest
     629   is enabled. The default implementation does nothing.
     630
    500631   \param xScaleDiv Scale division of the x-axis
    501632   \param yScaleDiv Scale division of the y-axis
    502633
    503    \sa QwtPlot::updateAxes()
     634   \sa QwtPlot::updateAxes(), ScaleInterest
    504635*/
    505636void QwtPlotItem::updateScaleDiv( const QwtScaleDiv &xScaleDiv,
     
    511642
    512643/*!
    513    \brief Calculate the bounding scale rect of 2 maps
    514 
    515    \param xMap X map
    516    \param yMap X map
    517 
    518    \return Bounding scale rect of the scale maps, normalized
     644   \brief Update the item to changes of the legend info
     645
     646   Plot items that want to display a legend ( not those, that want to
     647   be displayed on a legend ! ) will have to implement updateLegend().
     648
     649   updateLegend() is only called when the LegendInterest interest
     650   is enabled. The default implementation does nothing.
     651
     652   \param item Plot item to be displayed on a legend
     653   \param data Attributes how to display item on the legend
     654
     655   \sa QwtPlotLegendItem
     656
     657   \note Plot items, that want to be displayed on a legend
     658         need to enable the QwtPlotItem::Legend flag and to implement
     659         legendData() and legendIcon()
     660 */
     661void QwtPlotItem::updateLegend( const QwtPlotItem *item,
     662    const QList<QwtLegendData> &data )
     663{
     664    Q_UNUSED( item );
     665    Q_UNUSED( data );
     666}
     667
     668/*!
     669   \brief Calculate the bounding scale rectangle of 2 maps
     670
     671   \param xMap Maps x-values into pixel coordinates.
     672   \param yMap Maps y-values into pixel coordinates.
     673
     674   \return Bounding scale rect of the scale maps, not normalized
    519675*/
    520676QRectF QwtPlotItem::scaleRect( const QwtScaleMap &xMap,
     
    526682
    527683/*!
    528    \brief Calculate the bounding paint rect of 2 maps
    529 
    530    \param xMap X map
    531    \param yMap X map
    532 
    533    \return Bounding paint rect of the scale maps, normalized
     684   \brief Calculate the bounding paint rectangle of 2 maps
     685
     686   \param xMap Maps x-values into pixel coordinates.
     687   \param yMap Maps y-values into pixel coordinates.
     688
     689   \return Bounding paint rectangle of the scale maps, not normalized
    534690*/
    535691QRectF QwtPlotItem::paintRect( const QwtScaleMap &xMap,
  • trunk/BNC/qwt/qwt_plot_item.h

    r4271 r8127  
    1212
    1313#include "qwt_global.h"
    14 #include "qwt_legend_itemmanager.h"
    1514#include "qwt_text.h"
     15#include "qwt_legend_data.h"
     16#include "qwt_graphic.h"
    1617#include <qrect.h>
    17 
    18 class QString;
     18#include <qlist.h>
     19#include <qmetatype.h>
     20
    1921class QPainter;
    20 class QWidget;
    21 class QwtPlot;
    22 class QwtLegend;
    2322class QwtScaleMap;
    2423class QwtScaleDiv;
     24class QwtPlot;
    2525
    2626/*!
     
    5151
    5252  Depending on the QwtPlotItem::ItemAttribute flags, an item is included
    53   into autoscaling or has an entry on the legnd.
     53  into autoscaling or has an entry on the legend.
    5454
    5555  Before misusing the existing item classes it might be better to
     
    6262*/
    6363
    64 class QWT_EXPORT QwtPlotItem: public QwtLegendItemManager
     64class QWT_EXPORT QwtPlotItem
    6565{
    6666public:
     
    7373    enum RttiValues
    7474    {
     75        //! Unspecific value, that can be used, when it doesn't matter
    7576        Rtti_PlotItem = 0,
    7677
     78        //! For QwtPlotGrid
    7779        Rtti_PlotGrid,
     80
     81        //! For QwtPlotScaleItem
    7882        Rtti_PlotScale,
     83
     84        //! For QwtPlotLegendItem
     85        Rtti_PlotLegend,
     86
     87        //! For QwtPlotMarker
    7988        Rtti_PlotMarker,
     89
     90        //! For QwtPlotCurve
    8091        Rtti_PlotCurve,
     92
     93        //! For QwtPlotSpectroCurve
    8194        Rtti_PlotSpectroCurve,
     95
     96        //! For QwtPlotIntervalCurve
    8297        Rtti_PlotIntervalCurve,
     98
     99        //! For QwtPlotHistogram
    83100        Rtti_PlotHistogram,
     101
     102        //! For QwtPlotSpectrogram
    84103        Rtti_PlotSpectrogram,
     104
     105        //! For QwtPlotSvgItem
    85106        Rtti_PlotSVG,
    86107
     108        //! For QwtPlotTradingCurve
     109        Rtti_PlotTradingCurve,
     110
     111        //! For QwtPlotBarChart
     112        Rtti_PlotBarChart,
     113
     114        //! For QwtPlotMultiBarChart
     115        Rtti_PlotMultiBarChart,
     116
     117        //! For QwtPlotShapeItem
     118        Rtti_PlotShape,
     119
     120        //! For QwtPlotTextLabel
     121        Rtti_PlotTextLabel,
     122
     123        //! For QwtPlotZoneItem
     124        Rtti_PlotZone,
     125
     126        /*!
     127           Values >= Rtti_PlotUserItem are reserved for plot items
     128           not implemented in the Qwt library.
     129         */
    87130        Rtti_PlotUserItem = 1000
    88131    };
    89132
    90133    /*!
    91        Plot Item Attributes
    92        \sa setItemAttribute(), testItemAttribute()
     134       \brief Plot Item Attributes
     135
     136       Various aspects of a plot widget depend on the attributes of
     137       the attached plot items. If and how a single plot item
     138       participates in these updates depends on its attributes.
     139       
     140       \sa setItemAttribute(), testItemAttribute(), ItemInterest
    93141     */
    94142    enum ItemAttribute
     
    98146
    99147        /*!
    100          The boundingRect() of the item is included in the
    101          autoscaling calculation.
    102          */
    103         AutoScale = 0x02
     148           The boundingRect() of the item is included in the
     149           autoscaling calculation as long as its width or height
     150           is >= 0.0.
     151         */
     152        AutoScale = 0x02,
     153
     154        /*!
     155           The item needs extra space to display something outside
     156           its bounding rectangle.
     157           \sa getCanvasMarginHint()
     158         */
     159        Margins = 0x04
    104160    };
    105161
    106162    //! Plot Item Attributes
    107163    typedef QFlags<ItemAttribute> ItemAttributes;
     164
     165    /*!
     166       \brief Plot Item Interests
     167
     168       Plot items might depend on the situation of the corresponding
     169       plot widget. By enabling an interest the plot item will be
     170       notified, when the corresponding attribute of the plot widgets
     171       has changed.
     172
     173       \sa setItemAttribute(), testItemAttribute(), ItemInterest
     174     */
     175    enum ItemInterest
     176    {
     177        /*!
     178           The item is interested in updates of the scales
     179           \sa updateScaleDiv()
     180         */
     181        ScaleInterest = 0x01,
     182
     183        /*!
     184           The item is interested in updates of the legend ( of other items )
     185           This flag is intended for items, that want to implement a legend
     186           for displaying entries of other plot item.
     187
     188           \note If the plot item wants to be represented on a legend
     189                 enable QwtPlotItem::Legend instead.
     190
     191           \sa updateLegend()
     192         */
     193        LegendInterest = 0x02
     194    };
     195
     196    //! Plot Item Interests
     197    typedef QFlags<ItemInterest> ItemInterests;
    108198
    109199    //! Render hints
     
    111201    {
    112202        //! Enable antialiasing
    113         RenderAntialiased = 1
     203        RenderAntialiased = 0x1
    114204    };
    115205
     
    134224    bool testItemAttribute( ItemAttribute ) const;
    135225
     226    void setItemInterest( ItemInterest, bool on = true );
     227    bool testItemInterest( ItemInterest ) const;
     228
    136229    void setRenderHint( RenderHint, bool on = true );
    137230    bool testRenderHint( RenderHint ) const;
     231
     232    void setRenderThreadCount( uint numThreads );
     233    uint renderThreadCount() const;
     234
     235    void setLegendIconSize( const QSize & );
     236    QSize legendIconSize() const;
    138237
    139238    double z() const;
     
    154253
    155254    virtual void itemChanged();
     255    virtual void legendChanged();
    156256
    157257    /*!
     
    169269    virtual QRectF boundingRect() const;
    170270
    171     virtual void updateLegend( QwtLegend * ) const;
     271    virtual void getCanvasMarginHint(
     272        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
     273        const QRectF &canvasSize,
     274        double &left, double &top, double &right, double &bottom) const;
     275
    172276    virtual void updateScaleDiv(
    173277        const QwtScaleDiv&, const QwtScaleDiv& );
    174278
    175     virtual QWidget *legendItem() const;
     279    virtual void updateLegend( const QwtPlotItem *,
     280        const QList<QwtLegendData> & );
    176281
    177282    QRectF scaleRect( const QwtScaleMap &, const QwtScaleMap & ) const;
    178283    QRectF paintRect( const QwtScaleMap &, const QwtScaleMap & ) const;
     284
     285    virtual QList<QwtLegendData> legendData() const;
     286
     287    virtual QwtGraphic legendIcon( int index, const QSizeF  & ) const;
     288
     289protected:
     290    QwtGraphic defaultIcon( const QBrush &, const QSizeF & ) const;
    179291
    180292private:
     
    188300
    189301Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::ItemAttributes )
     302Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::ItemInterests )
    190303Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotItem::RenderHints )
    191304
     305Q_DECLARE_METATYPE( QwtPlotItem * )
     306
    192307#endif
  • trunk/BNC/qwt/qwt_plot_layout.cpp

    r4271 r8127  
    1111#include "qwt_text.h"
    1212#include "qwt_text_label.h"
    13 #include "qwt_plot_canvas.h"
    1413#include "qwt_scale_widget.h"
    15 #include "qwt_legend.h"
     14#include "qwt_abstract_legend.h"
    1615#include <qscrollbar.h>
    1716#include <qmath.h>
     
    2524    {
    2625        int frameWidth;
    27         int vScrollBarWidth;
    28         int hScrollBarHeight;
     26        int hScrollExtent;
     27        int vScrollExtent;
    2928        QSize hint;
    3029    } legend;
     
    3534        int frameWidth;
    3635    } title;
     36
     37    struct t_footerData
     38    {
     39        QwtText text;
     40        int frameWidth;
     41    } footer;
    3742
    3843    struct t_scaleData
     
    4449        int end;
    4550        int baseLineOffset;
    46         int tickOffset;
     51        double tickOffset;
    4752        int dimWithoutTitle;
    4853    } scale[QwtPlot::axisCnt];
     
    5055    struct t_canvasData
    5156    {
    52         int frameWidth;
     57        int contentsMargins[ QwtPlot::axisCnt ];
     58
    5359    } canvas;
    5460};
     
    5763  Extract all layout relevant data from the plot components
    5864*/
    59 
    6065void QwtPlotLayout::LayoutData::init( const QwtPlot *plot, const QRectF &rect )
    6166{
    6267    // legend
    6368
    64     if ( plot->plotLayout()->legendPosition() != QwtPlot::ExternalLegend
    65         && plot->legend() )
     69    if ( plot->legend() )
    6670    {
    6771        legend.frameWidth = plot->legend()->frameWidth();
    68         legend.vScrollBarWidth =
    69             plot->legend()->verticalScrollBar()->sizeHint().width();
    70         legend.hScrollBarHeight =
    71             plot->legend()->horizontalScrollBar()->sizeHint().height();
     72        legend.hScrollExtent =
     73            plot->legend()->scrollExtent( Qt::Horizontal );
     74        legend.vScrollExtent =
     75            plot->legend()->scrollExtent( Qt::Vertical );
    7276
    7377        const QSize hint = plot->legend()->sizeHint();
    7478
    75         int w = qMin( hint.width(), qFloor( rect.width() ) );
     79        const int w = qMin( hint.width(), qFloor( rect.width() ) );
     80
    7681        int h = plot->legend()->heightForWidth( w );
    77         if ( h == 0 )
     82        if ( h <= 0 )
    7883            h = hint.height();
    79 
    80         if ( h > rect.height() )
    81             w += legend.vScrollBarWidth;
    8284
    8385        legend.hint = QSize( w, h );
     
    99101    }
    100102
     103    // footer
     104
     105    footer.frameWidth = 0;
     106    footer.text = QwtText();
     107
     108    if ( plot->footerLabel() )
     109    {
     110        const QwtTextLabel *label = plot->footerLabel();
     111        footer.text = label->text();
     112        if ( !( footer.text.testPaintAttribute( QwtText::PaintUsingTextFont ) ) )
     113            footer.text.setFont( label->font() );
     114
     115        footer.frameWidth = plot->footerLabel()->frameWidth();
     116    }
     117
    101118    // scales
    102119
     
    140157            scale[axis].end = 0;
    141158            scale[axis].baseLineOffset = 0;
    142             scale[axis].tickOffset = 0;
     159            scale[axis].tickOffset = 0.0;
    143160            scale[axis].dimWithoutTitle = 0;
    144161        }
     
    147164    // canvas
    148165
    149     canvas.frameWidth = plot->canvas()->frameWidth();
     166    plot->canvas()->getContentsMargins(
     167        &canvas.contentsMargins[ QwtPlot::yLeft ],
     168        &canvas.contentsMargins[ QwtPlot::xTop ],
     169        &canvas.contentsMargins[ QwtPlot::yRight ],
     170        &canvas.contentsMargins[ QwtPlot::xBottom ] );
    150171}
    151172
     
    154175public:
    155176    PrivateData():
    156         spacing( 5 ),
    157         alignCanvasToScales( false )
     177        spacing( 5 )
    158178    {
    159179    }
    160180
    161181    QRectF titleRect;
     182    QRectF footerRect;
    162183    QRectF legendRect;
    163184    QRectF scaleRect[QwtPlot::axisCnt];
     
    170191    unsigned int spacing;
    171192    unsigned int canvasMargin[QwtPlot::axisCnt];
    172     bool alignCanvasToScales;
     193    bool alignCanvasToScales[QwtPlot::axisCnt];
    173194};
    174195
     
    183204    setLegendPosition( QwtPlot::BottomLegend );
    184205    setCanvasMargin( 4 );
     206    setAlignCanvasToScales( false );
    185207
    186208    invalidate();
     
    203225  \sa canvasMargin()
    204226
    205   \warning The margin will have no effect when alignCanvasToScales is true
     227  \warning The margin will have no effect when alignCanvasToScale() is true
    206228*/
    207229
     
    221243
    222244/*!
     245    \param axisId Axis index
    223246    \return Margin around the scale tick borders
    224247    \sa setCanvasMargin()
    225248*/
    226 int QwtPlotLayout::canvasMargin( int axis ) const
    227 {
    228     if ( axis < 0 || axis >= QwtPlot::axisCnt )
     249int QwtPlotLayout::canvasMargin( int axisId ) const
     250{
     251    if ( axisId < 0 || axisId >= QwtPlot::axisCnt )
    229252        return 0;
    230253
    231     return d_data->canvasMargin[axis];
     254    return d_data->canvasMargin[axisId];
     255}
     256
     257/*!
     258  \brief Set the align-canvas-to-axis-scales flag for all axes
     259
     260  \param on True/False
     261  \sa setAlignCanvasToScale(), alignCanvasToScale()
     262*/
     263void QwtPlotLayout::setAlignCanvasToScales( bool on )
     264{
     265    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
     266        d_data->alignCanvasToScales[axis] = on;
    232267}
    233268
    234269/*!
    235270  Change the align-canvas-to-axis-scales setting. The canvas may:
     271
    236272  - extend beyond the axis scale ends to maximize its size,
    237273  - align with the axis scale ends to control its size.
    238274
    239   \param alignCanvasToScales New align-canvas-to-axis-scales setting
    240 
    241   \sa setCanvasMargin()
    242   \note In this context the term 'scale' means the backbone of a scale.
    243   \warning In case of alignCanvasToScales == true canvasMargin will have
    244            no effect
    245 */
    246 void QwtPlotLayout::setAlignCanvasToScales( bool alignCanvasToScales )
    247 {
    248     d_data->alignCanvasToScales = alignCanvasToScales;
     275  The axisId parameter is somehow confusing as it identifies a border
     276  of the plot and not the axes, that are aligned. F.e when QwtPlot::yLeft
     277  is set, the left end of the the x-axes ( QwtPlot::xTop, QwtPlot::xBottom )
     278  is aligned.
     279
     280  \param axisId Axis index
     281  \param on New align-canvas-to-axis-scales setting
     282
     283  \sa setCanvasMargin(), alignCanvasToScale(), setAlignCanvasToScales()
     284  \warning In case of on == true canvasMargin() will have no effect
     285*/
     286void QwtPlotLayout::setAlignCanvasToScale( int axisId, bool on )
     287{
     288    if ( axisId >= 0 && axisId < QwtPlot::axisCnt )
     289        d_data->alignCanvasToScales[axisId] = on;
    249290}
    250291
     
    254295  - align with the axis scale ends to control its size.
    255296
     297  \param axisId Axis index
    256298  \return align-canvas-to-axis-scales setting
    257   \sa setAlignCanvasToScales, setCanvasMargin()
    258   \note In this context the term 'scale' means the backbone of a scale.
    259 */
    260 bool QwtPlotLayout::alignCanvasToScales() const
    261 {
    262     return d_data->alignCanvasToScales;
     299  \sa setAlignCanvasToScale(), setAlignCanvasToScale(), setCanvasMargin()
     300*/
     301bool QwtPlotLayout::alignCanvasToScale( int axisId ) const
     302{
     303    if ( axisId < 0 || axisId >= QwtPlot::axisCnt )
     304        return false;
     305
     306    return d_data->alignCanvasToScales[ axisId ];
    263307}
    264308
     
    267311  between the plot components.
    268312
    269   \param spacing new spacing
    270   \sa setMargin(), spacing()
     313  \param spacing New spacing
     314  \sa setCanvasMargin(), spacing()
    271315*/
    272316void QwtPlotLayout::setSpacing( int spacing )
     
    276320
    277321/*!
    278   \return spacing
     322  \return Spacing
    279323  \sa margin(), setSpacing()
    280324*/
     
    287331  \brief Specify the position of the legend
    288332  \param pos The legend's position.
    289   \param ratio Ratio between legend and the bounding rect
    290                of title, canvas and axes. The legend will be shrinked
     333  \param ratio Ratio between legend and the bounding rectangle
     334               of title, footer, canvas and axes. The legend will be shrunk
    291335               if it would need more space than the given ratio.
    292336               The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
     
    318362            d_data->legendPos = pos;
    319363            break;
    320         case QwtPlot::ExternalLegend:
    321             d_data->legendRatio = ratio; // meaningless
    322             d_data->legendPos = pos;
    323364        default:
    324365            break;
     
    351392/*!
    352393  Specify the relative size of the legend in the plot
    353   \param ratio Ratio between legend and the bounding rect
    354                of title, canvas and axes. The legend will be shrinked
     394  \param ratio Ratio between legend and the bounding rectangle
     395               of title, footer, canvas and axes. The legend will be shrunk
    355396               if it would need more space than the given ratio.
    356397               The ratio is limited to ]0.0 .. 1.0]. In case of <= 0.0
     
    373414
    374415/*!
     416  \brief Set the geometry for the title
     417
     418  This method is intended to be used from derived layouts
     419  overloading activate()
     420
     421  \sa titleRect(), activate()
     422 */
     423void QwtPlotLayout::setTitleRect( const QRectF &rect )
     424{
     425    d_data->titleRect = rect;
     426}
     427
     428/*!
    375429  \return Geometry for the title
    376430  \sa activate(), invalidate()
    377431*/
    378 
    379 const QRectF &QwtPlotLayout::titleRect() const
     432QRectF QwtPlotLayout::titleRect() const
    380433{
    381434    return d_data->titleRect;
     435}
     436
     437/*!
     438  \brief Set the geometry for the footer
     439
     440  This method is intended to be used from derived layouts
     441  overloading activate()
     442
     443  \sa footerRect(), activate()
     444 */
     445void QwtPlotLayout::setFooterRect( const QRectF &rect )
     446{
     447    d_data->footerRect = rect;
     448}
     449
     450/*!
     451  \return Geometry for the footer
     452  \sa activate(), invalidate()
     453*/
     454QRectF QwtPlotLayout::footerRect() const
     455{
     456    return d_data->footerRect;
     457}
     458
     459/*!
     460  \brief Set the geometry for the legend
     461
     462  This method is intended to be used from derived layouts
     463  overloading activate()
     464
     465  \param rect Rectangle for the legend
     466
     467  \sa legendRect(), activate()
     468 */
     469void QwtPlotLayout::setLegendRect( const QRectF &rect )
     470{
     471    d_data->legendRect = rect;
    382472}
    383473
     
    386476  \sa activate(), invalidate()
    387477*/
    388 
    389 const QRectF &QwtPlotLayout::legendRect() const
     478QRectF QwtPlotLayout::legendRect() const
    390479{
    391480    return d_data->legendRect;
     481}
     482
     483/*!
     484  \brief Set the geometry for an axis
     485
     486  This method is intended to be used from derived layouts
     487  overloading activate()
     488
     489  \param axis Axis index
     490  \param rect Rectangle for the scale
     491
     492  \sa scaleRect(), activate()
     493 */
     494void QwtPlotLayout::setScaleRect( int axis, const QRectF &rect )
     495{
     496    if ( axis >= 0 && axis < QwtPlot::axisCnt )
     497        d_data->scaleRect[axis] = rect;
    392498}
    393499
     
    397503  \sa activate(), invalidate()
    398504*/
    399 
    400 const QRectF &QwtPlotLayout::scaleRect( int axis ) const
     505QRectF QwtPlotLayout::scaleRect( int axis ) const
    401506{
    402507    if ( axis < 0 || axis >= QwtPlot::axisCnt )
     
    409514
    410515/*!
     516  \brief Set the geometry for the canvas
     517
     518  This method is intended to be used from derived layouts
     519  overloading activate()
     520
     521  \sa canvasRect(), activate()
     522 */
     523void QwtPlotLayout::setCanvasRect( const QRectF &rect )
     524{
     525    d_data->canvasRect = rect;
     526}
     527
     528/*!
    411529  \return Geometry for the canvas
    412530  \sa activate(), invalidate()
    413531*/
    414 
    415 const QRectF &QwtPlotLayout::canvasRect() const
     532QRectF QwtPlotLayout::canvasRect() const
    416533{
    417534    return d_data->canvasRect;
     
    424541void QwtPlotLayout::invalidate()
    425542{
    426     d_data->titleRect = d_data->legendRect = d_data->canvasRect = QRect();
     543    d_data->titleRect = d_data->footerRect
     544        = d_data->legendRect = d_data->canvasRect = QRect();
     545
    427546    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
    428547        d_data->scaleRect[axis] = QRect();
     
    430549
    431550/*!
    432   \brief Return a minimum size hint
     551  \return Minimum size hint
     552  \param plot Plot widget
     553
    433554  \sa QwtPlot::minimumSizeHint()
    434555*/
     
    453574    int canvasBorder[QwtPlot::axisCnt];
    454575
     576    int fw;
     577    plot->canvas()->getContentsMargins( &fw, NULL, NULL, NULL );
     578
    455579    int axis;
    456580    for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
     
    467591            sd.tickOffset = scl->margin();
    468592            if ( scl->scaleDraw()->hasComponent( QwtAbstractScaleDraw::Ticks ) )
    469                 sd.tickOffset += scl->scaleDraw()->maxTickLength();
    470         }
    471 
    472         canvasBorder[axis] = plot->canvas()->frameWidth() +
    473             d_data->canvasMargin[axis] + 1;
    474 
     593                sd.tickOffset += qCeil( scl->scaleDraw()->maxTickLength() );
     594        }
     595
     596        canvasBorder[axis] = fw + d_data->canvasMargin[axis] + 1;
    475597    }
    476598
     
    524646    }
    525647
    526     const QwtPlotCanvas *canvas = plot->canvas();
     648    const QWidget *canvas = plot->canvas();
     649
     650    int left, top, right, bottom;
     651    canvas->getContentsMargins( &left, &top, &right, &bottom );
     652
    527653    const QSize minCanvasSize = canvas->minimumSize();
    528654
    529655    int w = scaleData[QwtPlot::yLeft].w + scaleData[QwtPlot::yRight].w;
    530656    int cw = qMax( scaleData[QwtPlot::xBottom].w, scaleData[QwtPlot::xTop].w )
    531         + 2 * ( canvas->frameWidth() + 1 );
     657        + left + 1 + right + 1;
    532658    w += qMax( cw, minCanvasSize.width() );
    533659
    534660    int h = scaleData[QwtPlot::xBottom].h + scaleData[QwtPlot::xTop].h;
    535661    int ch = qMax( scaleData[QwtPlot::yLeft].h, scaleData[QwtPlot::yRight].h )
    536         + 2 * ( canvas->frameWidth() + 1 );
     662        + top + 1 + bottom + 1;
    537663    h += qMax( ch, minCanvasSize.height() );
    538664
    539     const QwtTextLabel *title = plot->titleLabel();
    540     if ( title && !title->text().isEmpty() )
    541     {
    542         // If only QwtPlot::yLeft or QwtPlot::yRight is showing,
    543         // we center on the plot canvas.
    544         const bool centerOnCanvas = !( plot->axisEnabled( QwtPlot::yLeft )
    545             && plot->axisEnabled( QwtPlot::yRight ) );
    546 
    547         int titleW = w;
    548         if ( centerOnCanvas )
    549         {
    550             titleW -= scaleData[QwtPlot::yLeft].w
    551                 + scaleData[QwtPlot::yRight].w;
    552         }
    553 
    554         int titleH = title->heightForWidth( titleW );
    555         if ( titleH > titleW ) // Compensate for a long title
    556         {
    557             w = titleW = titleH;
     665    const QwtTextLabel *labels[2];
     666    labels[0] = plot->titleLabel();
     667    labels[1] = plot->footerLabel();
     668
     669    for ( int i = 0; i < 2; i++ )
     670    {
     671        const QwtTextLabel *label   = labels[i];
     672        if ( label && !label->text().isEmpty() )
     673        {
     674            // If only QwtPlot::yLeft or QwtPlot::yRight is showing,
     675            // we center on the plot canvas.
     676            const bool centerOnCanvas = !( plot->axisEnabled( QwtPlot::yLeft )
     677                && plot->axisEnabled( QwtPlot::yRight ) );
     678
     679            int labelW = w;
    558680            if ( centerOnCanvas )
    559681            {
    560                 w += scaleData[QwtPlot::yLeft].w
     682                labelW -= scaleData[QwtPlot::yLeft].w
    561683                    + scaleData[QwtPlot::yRight].w;
    562684            }
    563685
    564             titleH = title->heightForWidth( titleW );
    565         }
    566         h += titleH + d_data->spacing;
     686            int labelH = label->heightForWidth( labelW );
     687            if ( labelH > labelW ) // Compensate for a long title
     688            {
     689                w = labelW = labelH;
     690                if ( centerOnCanvas )
     691                {
     692                    w += scaleData[QwtPlot::yLeft].w
     693                        + scaleData[QwtPlot::yRight].w;
     694                }
     695
     696                labelH = label->heightForWidth( labelW );
     697            }
     698            h += labelH + d_data->spacing;
     699        }
    567700    }
    568701
    569702    // Compute the legend contribution
    570703
    571     const QwtLegend *legend = plot->legend();
    572     if ( d_data->legendPos != QwtPlot::ExternalLegend
    573         && legend && !legend->isEmpty() )
     704    const QwtAbstractLegend *legend = plot->legend();
     705    if ( legend && !legend->isEmpty() )
    574706    {
    575707        if ( d_data->legendPos == QwtPlot::LeftLegend
     
    583715
    584716            if ( legendH > h )
    585                 legendW += legend->verticalScrollBar()->sizeHint().height();
     717                legendW += legend->scrollExtent( Qt::Horizontal );
    586718
    587719            if ( d_data->legendRatio < 1.0 )
     
    610742/*!
    611743  Find the geometry for the legend
     744
    612745  \param options Options how to layout the legend
    613746  \param rect Rectangle where to place the legend
     747
    614748  \return Geometry for the legend
    615749  \sa Options
     
    637771                // space for the vertical scrollbar.
    638772
    639                 dim += d_data->layoutData.legend.vScrollBarWidth;
     773                dim += d_data->layoutData.legend.hScrollExtent;
    640774            }
    641775        }
     
    644778    {
    645779        dim = qMin( hint.height(), int( rect.height() * d_data->legendRatio ) );
    646         dim = qMax( dim, d_data->layoutData.legend.hScrollBarHeight );
     780        dim = qMax( dim, d_data->layoutData.legend.vScrollExtent );
    647781    }
    648782
     
    664798            legendRect.setHeight( dim );
    665799            break;
    666         case QwtPlot::ExternalLegend:
    667             break;
    668800    }
    669801
     
    673805/*!
    674806  Align the legend to the canvas
     807
    675808  \param canvasRect Geometry of the canvas
    676809  \param legendRect Maximum geometry for the legend
     810
    677811  \return Geometry for the aligned legend
    678812*/
     
    708842
    709843  \param options Options how to layout the legend
    710   \param rect Bounding rect for title, axes and canvas.
     844  \param rect Bounding rectangle for title, footer, axes and canvas.
    711845  \param dimTitle Expanded height of the title widget
     846  \param dimFooter Expanded height of the footer widget
    712847  \param dimAxis Expanded heights of the axis in axis orientation.
    713848
    714849  \sa Options
    715850*/
    716 void QwtPlotLayout::expandLineBreaks( int options, const QRectF &rect,
    717     int &dimTitle, int dimAxis[QwtPlot::axisCnt] ) const
    718 {
    719     dimTitle = 0;
     851void QwtPlotLayout::expandLineBreaks( Options options, const QRectF &rect,
     852    int &dimTitle, int &dimFooter, int dimAxis[QwtPlot::axisCnt] ) const
     853{
     854    dimTitle = dimFooter = 0;
    720855    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
    721856        dimAxis[axis] = 0;
     
    725860    {
    726861        backboneOffset[axis] = 0;
    727         if ( !d_data->alignCanvasToScales )
     862        if ( !( options & IgnoreFrames ) )
     863            backboneOffset[axis] += d_data->layoutData.canvas.contentsMargins[ axis ];
     864
     865        if ( !d_data->alignCanvasToScales[axis] )
    728866            backboneOffset[axis] += d_data->canvasMargin[axis];
    729         if ( !( options & IgnoreFrames ) )
    730             backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
    731867    }
    732868
     
    744880        // axis ... . So we loop as long until no size changes.
    745881
    746         if ( !d_data->layoutData.title.text.isEmpty() )
    747         {
    748             int w = rect.width();
     882        if ( !( ( options & IgnoreTitle ) ||
     883            d_data->layoutData.title.text.isEmpty() ) )
     884        {
     885            double w = rect.width();
    749886
    750887            if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
     
    766903        }
    767904
     905        if ( !( ( options & IgnoreFooter ) ||
     906            d_data->layoutData.footer.text.isEmpty() ) )
     907        {
     908            double w = rect.width();
     909
     910            if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
     911                != d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
     912            {
     913                // center to the canvas
     914                w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight];
     915            }
     916
     917            int d = qCeil( d_data->layoutData.footer.text.heightForWidth( w ) );
     918            if ( !( options & IgnoreFrames ) )
     919                d += 2 * d_data->layoutData.footer.frameWidth;
     920
     921            if ( d > dimFooter )
     922            {
     923                dimFooter = d;
     924                done = false;
     925            }
     926        }
     927
    768928        for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
    769929        {
     
    773933            if ( scaleData.isEnabled )
    774934            {
    775                 int length;
     935                double length;
    776936                if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
    777937                {
     
    804964                        length += qMin(
    805965                            d_data->layoutData.scale[QwtPlot::xBottom].tickOffset,
    806                             scaleData.start - backboneOffset[QwtPlot::xBottom] );
     966                            double( scaleData.start - backboneOffset[QwtPlot::xBottom] ) );
    807967                    }
    808968                    if ( dimAxis[QwtPlot::xTop] > 0 )
     
    810970                        length += qMin(
    811971                            d_data->layoutData.scale[QwtPlot::xTop].tickOffset,
    812                             scaleData.end - backboneOffset[QwtPlot::xTop] );
     972                            double( scaleData.end - backboneOffset[QwtPlot::xTop] ) );
    813973                    }
    814974
     
    820980                if ( !scaleData.scaleWidget->title().isEmpty() )
    821981                {
    822                     d += scaleData.scaleWidget->titleHeightForWidth( length );
     982                    d += scaleData.scaleWidget->titleHeightForWidth( qFloor( length ) );
    823983                }
    824984
     
    838998  the empty corners.
    839999
     1000  \param options Layout options
     1001  \param canvasRect Geometry of the canvas ( IN/OUT )
     1002  \param scaleRect Geometries of the scales ( IN/OUT )
     1003
    8401004  \sa Options
    8411005*/
    8421006
    843 void QwtPlotLayout::alignScales( int options,
     1007void QwtPlotLayout::alignScales( Options options,
    8441008    QRectF &canvasRect, QRectF scaleRect[QwtPlot::axisCnt] ) const
    8451009{
     
    8481012    {
    8491013        backboneOffset[axis] = 0;
    850         if ( !d_data->alignCanvasToScales )
     1014
     1015        if ( !d_data->alignCanvasToScales[axis] )
     1016        {
    8511017            backboneOffset[axis] += d_data->canvasMargin[axis];
     1018        }
     1019
    8521020        if ( !( options & IgnoreFrames ) )
    853             backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
     1021        {
     1022            backboneOffset[axis] +=
     1023                d_data->layoutData.canvas.contentsMargins[axis];
     1024        }
    8541025    }
    8551026
     
    8721043            if ( leftScaleRect.isValid() )
    8731044            {
    874                 const int dx = leftOffset + leftScaleRect.width();
    875                 if ( d_data->alignCanvasToScales && dx < 0 )
     1045                const double dx = leftOffset + leftScaleRect.width();
     1046                if ( d_data->alignCanvasToScales[QwtPlot::yLeft] && dx < 0.0 )
    8761047                {
    8771048                    /*
     
    8791050                      of the left scale.
    8801051                     */
    881                     canvasRect.setLeft( qMax( canvasRect.left(),
    882                         axisRect.left() - dx ) );
     1052                    const double cLeft = canvasRect.left(); // qreal -> double
     1053                    canvasRect.setLeft( qMax( cLeft, axisRect.left() - dx ) );
    8831054                }
    8841055                else
     
    8911062            else
    8921063            {
    893                 if ( d_data->alignCanvasToScales && leftOffset < 0 )
     1064                if ( d_data->alignCanvasToScales[QwtPlot::yLeft] && leftOffset < 0 )
    8941065                {
    8951066                    canvasRect.setLeft( qMax( canvasRect.left(),
     
    9091080            if ( rightScaleRect.isValid() )
    9101081            {
    911                 const int dx = rightOffset + rightScaleRect.width();
    912                 if ( d_data->alignCanvasToScales && dx < 0 )
     1082                const double dx = rightOffset + rightScaleRect.width();
     1083                if ( d_data->alignCanvasToScales[QwtPlot::yRight] && dx < 0 )
    9131084                {
    9141085                    /*
     
    9161087                      of the right scale.
    9171088                     */
    918                     canvasRect.setRight( qMin( canvasRect.right(),
    919                         axisRect.right() + dx ) );
     1089                    const double cRight = canvasRect.right(); // qreal -> double
     1090                    canvasRect.setRight( qMin( cRight, axisRect.right() + dx ) );
    9201091                }   
    9211092
     
    9261097            else
    9271098            {
    928                 if ( d_data->alignCanvasToScales && rightOffset < 0 )
     1099                if ( d_data->alignCanvasToScales[QwtPlot::yRight] && rightOffset < 0 )
    9291100                {
    9301101                    canvasRect.setRight( qMin( canvasRect.right(),
     
    9461117            if ( bottomScaleRect.isValid() )
    9471118            {
    948                 const int dy = bottomOffset + bottomScaleRect.height();
    949                 if ( d_data->alignCanvasToScales && dy < 0 )
     1119                const double dy = bottomOffset + bottomScaleRect.height();
     1120                if ( d_data->alignCanvasToScales[QwtPlot::xBottom] && dy < 0 )
    9501121                {
    9511122                    /*
     
    9531124                      of the bottom scale.
    9541125                     */
    955                     canvasRect.setBottom( qMin( canvasRect.bottom(),
    956                         axisRect.bottom() + dy ) );
     1126                    const double cBottom = canvasRect.bottom(); // qreal -> double
     1127                    canvasRect.setBottom( qMin( cBottom, axisRect.bottom() + dy ) );
    9571128                }
    9581129                else
     
    9661137            else
    9671138            {
    968                 if ( d_data->alignCanvasToScales && bottomOffset < 0 )
     1139                if ( d_data->alignCanvasToScales[QwtPlot::xBottom] && bottomOffset < 0 )
    9691140                {
    9701141                    canvasRect.setBottom( qMin( canvasRect.bottom(),
     
    9831154            if ( topScaleRect.isValid() )
    9841155            {
    985                 const int dy = topOffset + topScaleRect.height();
    986                 if ( d_data->alignCanvasToScales && dy < 0 )
     1156                const double dy = topOffset + topScaleRect.height();
     1157                if ( d_data->alignCanvasToScales[QwtPlot::xTop] && dy < 0 )
    9871158                {
    9881159                    /*
     
    9901161                      of the top scale.
    9911162                     */
    992                     canvasRect.setTop( qMax( canvasRect.top(),
    993                         axisRect.top() - dy ) );
     1163                    const double cTop = canvasRect.top(); // qreal -> double
     1164                    canvasRect.setTop( qMax( cTop, axisRect.top() - dy ) );
    9941165                }
    9951166                else
     
    10031174            else
    10041175            {
    1005                 if ( d_data->alignCanvasToScales && topOffset < 0 )
     1176                if ( d_data->alignCanvasToScales[QwtPlot::xTop] && topOffset < 0 )
    10061177                {
    10071178                    canvasRect.setTop( qMax( canvasRect.top(),
     
    10171188    }
    10181189
    1019     if ( d_data->alignCanvasToScales )
    1020     {
    1021         /*
    1022           The canvas has been aligned to the scale with largest
    1023           border distances. Now we have to realign the other scale.
    1024          */
    1025 
    1026         int fw = 0;
    1027         if ( !( options & IgnoreFrames ) )
    1028             fw = d_data->layoutData.canvas.frameWidth;
    1029 
    1030         for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
    1031         {
    1032             if ( !scaleRect[axis].isValid() )
    1033                 continue;
    1034 
    1035             if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
    1036             {
    1037                 scaleRect[axis].setLeft( canvasRect.left() + fw
    1038                     - d_data->layoutData.scale[axis].start );
    1039                 scaleRect[axis].setRight( canvasRect.right() - fw - 1
    1040                     + d_data->layoutData.scale[axis].end );
    1041             }   
    1042             else
    1043             {
    1044                 scaleRect[axis].setTop( canvasRect.top() + fw
    1045                     - d_data->layoutData.scale[axis].start );
    1046                 scaleRect[axis].setBottom( canvasRect.bottom() - fw - 1
    1047                     + d_data->layoutData.scale[axis].end );
    1048             }
    1049         }
    1050 
    1051         if ( scaleRect[QwtPlot::xTop].isValid() )
    1052             scaleRect[QwtPlot::xTop].setBottom( canvasRect.top() );
    1053         if ( scaleRect[QwtPlot::xBottom].isValid() )
    1054             scaleRect[QwtPlot::xBottom].setTop( canvasRect.bottom() );
    1055         if ( scaleRect[QwtPlot::yLeft].isValid() )
    1056             scaleRect[QwtPlot::yLeft].setRight( canvasRect.left() );
    1057         if ( scaleRect[QwtPlot::yRight].isValid() )
    1058             scaleRect[QwtPlot::yRight].setLeft( canvasRect.right() );
     1190    /*
     1191      The canvas has been aligned to the scale with largest
     1192      border distances. Now we have to realign the other scale.
     1193     */
     1194
     1195
     1196    for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
     1197    {
     1198        QRectF &sRect = scaleRect[axis];
     1199
     1200        if ( !sRect.isValid() )
     1201            continue;
     1202
     1203        if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
     1204        {
     1205            if ( d_data->alignCanvasToScales[QwtPlot::yLeft] )
     1206            {
     1207                double y = canvasRect.left() - d_data->layoutData.scale[axis].start;
     1208                if ( !( options & IgnoreFrames ) )
     1209                    y += d_data->layoutData.canvas.contentsMargins[ QwtPlot::yLeft ];
     1210
     1211                sRect.setLeft( y );
     1212            }
     1213            if ( d_data->alignCanvasToScales[QwtPlot::yRight] )
     1214            {
     1215                double y = canvasRect.right() - 1 + d_data->layoutData.scale[axis].end;
     1216                if ( !( options & IgnoreFrames ) )
     1217                    y -= d_data->layoutData.canvas.contentsMargins[ QwtPlot::yRight ];
     1218
     1219                sRect.setRight( y );
     1220            }
     1221
     1222            if ( d_data->alignCanvasToScales[ axis ] )
     1223            {
     1224                if ( axis == QwtPlot::xTop )
     1225                    sRect.setBottom( canvasRect.top() );
     1226                else
     1227                    sRect.setTop( canvasRect.bottom() );
     1228            }
     1229        }
     1230        else
     1231        {
     1232            if ( d_data->alignCanvasToScales[QwtPlot::xTop] )
     1233            {
     1234                double x = canvasRect.top() - d_data->layoutData.scale[axis].start;
     1235                if ( !( options & IgnoreFrames ) )
     1236                    x += d_data->layoutData.canvas.contentsMargins[ QwtPlot::xTop ];
     1237
     1238                sRect.setTop( x );
     1239            }
     1240            if ( d_data->alignCanvasToScales[QwtPlot::xBottom] )
     1241            {
     1242                double x = canvasRect.bottom() - 1 + d_data->layoutData.scale[axis].end;
     1243                if ( !( options & IgnoreFrames ) )
     1244                    x -= d_data->layoutData.canvas.contentsMargins[ QwtPlot::xBottom ];
     1245
     1246                sRect.setBottom( x );
     1247            }
     1248
     1249            if ( d_data->alignCanvasToScales[ axis ] )
     1250            {
     1251                if ( axis == QwtPlot::yLeft )
     1252                    sRect.setRight( canvasRect.left() );
     1253                else
     1254                    sRect.setLeft( canvasRect.right() );
     1255            }
     1256        }
    10591257    }
    10601258}
     
    10641262
    10651263  \param plot Plot to be layout
    1066   \param plotRect Rect where to place the components
     1264  \param plotRect Rectangle where to place the components
    10671265  \param options Layout options
    10681266
    1069   \sa invalidate(), titleRect(),
     1267  \sa invalidate(), titleRect(), footerRect()
    10701268      legendRect(), scaleRect(), canvasRect()
    10711269*/
     
    10771275    QRectF rect( plotRect );  // undistributed rest of the plot rect
    10781276
    1079     // We extract all layout relevant data from the widgets,
    1080     // filter them through pfilter and save them to d_data->layoutData.
     1277    // We extract all layout relevant parameters from the widgets,
     1278    // and save them to d_data->layoutData.
    10811279
    10821280    d_data->layoutData.init( plot, rect );
    10831281
    10841282    if ( !( options & IgnoreLegend )
    1085         && d_data->legendPos != QwtPlot::ExternalLegend
    10861283        && plot->legend() && !plot->legend()->isEmpty() )
    10871284    {
     
    10911288
    10921289        const QRegion region( rect.toRect() );
    1093         rect = region.subtract( d_data->legendRect.toRect() ).boundingRect();
     1290        rect = region.subtracted( d_data->legendRect.toRect() ).boundingRect();
    10941291
    10951292        switch ( d_data->legendPos )
     
    11071304                rect.setBottom( rect.bottom() - d_data->spacing );
    11081305                break;
    1109             case QwtPlot::ExternalLegend:
    1110                 break; // suppress compiler warning
    11111306        }
    11121307    }
     
    11251320     |   |   Axis    |   |
    11261321     +---+-----------+---+
     1322     |      Footer       |
     1323     +---+-----------+---+
    11271324    */
    11281325
    1129     // axes and title include text labels. The height of each
     1326    // title, footer and axes include text labels. The height of each
    11301327    // label depends on its line breaks, that depend on the width
    11311328    // for the label. A line break in a horizontal text will reduce
    11321329    // the available width for vertical texts and vice versa.
    1133     // expandLineBreaks finds the height/width for title and axes
     1330    // expandLineBreaks finds the height/width for title, footer and axes
    11341331    // including all line breaks.
    11351332
    1136     int dimTitle, dimAxes[QwtPlot::axisCnt];
    1137     expandLineBreaks( options, rect, dimTitle, dimAxes );
     1333    int dimTitle, dimFooter, dimAxes[QwtPlot::axisCnt];
     1334    expandLineBreaks( options, rect, dimTitle, dimFooter, dimAxes );
    11381335
    11391336    if ( dimTitle > 0 )
    11401337    {
    1141         d_data->titleRect = QRect( rect.x(), rect.y(),
    1142             rect.width(), dimTitle );
     1338        d_data->titleRect.setRect(
     1339            rect.left(), rect.top(), rect.width(), dimTitle );
     1340
     1341        rect.setTop( d_data->titleRect.bottom() + d_data->spacing );
    11431342
    11441343        if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
     
    11481347            // the title centered to the canvas
    11491348
    1150             d_data->titleRect.setX( rect.x() + dimAxes[QwtPlot::yLeft] );
     1349            d_data->titleRect.setX( rect.left() + dimAxes[QwtPlot::yLeft] );
    11511350            d_data->titleRect.setWidth( rect.width()
    11521351                - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight] );
    11531352        }
    1154 
    1155         // subtract title
    1156         rect.setTop( rect.top() + dimTitle + d_data->spacing );
     1353    }
     1354
     1355    if ( dimFooter > 0 )
     1356    {
     1357        d_data->footerRect.setRect(
     1358            rect.left(), rect.bottom() - dimFooter, rect.width(), dimFooter );
     1359
     1360        rect.setBottom( d_data->footerRect.top() - d_data->spacing );
     1361
     1362        if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
     1363            d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
     1364        {
     1365            // if only one of the y axes is missing we align
     1366            // the footer centered to the canvas
     1367
     1368            d_data->footerRect.setX( rect.left() + dimAxes[QwtPlot::yLeft] );
     1369            d_data->footerRect.setWidth( rect.width()
     1370                - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight] );
     1371        }
    11571372    }
    11581373
  • trunk/BNC/qwt/qwt_plot_layout.h

    r4271 r8127  
    2020  or by QwtPlot::print() to render its content to a QPaintDevice like
    2121  a QPrinter, QPixmap/QImage or QSvgRenderer.
     22
     23  \sa QwtPlot::setPlotLayout()
    2224*/
    2325
     
    4446
    4547        //! Ignore the legend.
    46         IgnoreLegend = 0x08
     48        IgnoreLegend = 0x08,
     49
     50        //! Ignore the title.
     51        IgnoreTitle = 0x10,
     52
     53        //! Ignore the footer.
     54        IgnoreFooter = 0x20
    4755    };
    4856
     
    5765
    5866    void setAlignCanvasToScales( bool );
    59     bool alignCanvasToScales() const;
     67
     68    void setAlignCanvasToScale( int axisId, bool );
     69    bool alignCanvasToScale( int axisId ) const;
    6070
    6171    void setSpacing( int );
     
    7686    virtual void invalidate();
    7787
    78     const QRectF &titleRect() const;
    79     const QRectF &legendRect() const;
    80     const QRectF &scaleRect( int axis ) const;
    81     const QRectF &canvasRect() const;
     88    QRectF titleRect() const;
     89    QRectF footerRect() const;
     90    QRectF legendRect() const;
     91    QRectF scaleRect( int axis ) const;
     92    QRectF canvasRect() const;
    8293
    8394    class LayoutData;
     
    8596protected:
    8697
     98    void setTitleRect( const QRectF & );
     99    void setFooterRect( const QRectF & );
     100    void setLegendRect( const QRectF & );
     101    void setScaleRect( int axis, const QRectF & );
     102    void setCanvasRect( const QRectF & );
     103
    87104    QRectF layoutLegend( Options options, const QRectF & ) const;
    88105    QRectF alignLegend( const QRectF &canvasRect,
    89106        const QRectF &legendRect ) const;
    90107
    91     void expandLineBreaks( int options, const QRectF &rect,
    92         int &dimTitle, int dimAxes[QwtPlot::axisCnt] ) const;
     108    void expandLineBreaks( Options options, const QRectF &rect,
     109        int &dimTitle, int &dimFooter, int dimAxes[QwtPlot::axisCnt] ) const;
    93110
    94     void alignScales( int options, QRectF &canvasRect,
     111    void alignScales( Options options, QRectF &canvasRect,
    95112        QRectF scaleRect[QwtPlot::axisCnt] ) const;
    96113
  • trunk/BNC/qwt/qwt_plot_magnifier.cpp

    r4271 r8127  
    99
    1010#include "qwt_plot.h"
    11 #include "qwt_plot_canvas.h"
    1211#include "qwt_scale_div.h"
    1312#include "qwt_plot_magnifier.h"
     
    3029   \param canvas Plot canvas to be magnified
    3130*/
    32 QwtPlotMagnifier::QwtPlotMagnifier( QwtPlotCanvas *canvas ):
     31QwtPlotMagnifier::QwtPlotMagnifier( QWidget *canvas ):
    3332    QwtMagnifier( canvas )
    3433{
     
    7675
    7776//! Return observed plot canvas
    78 QwtPlotCanvas *QwtPlotMagnifier::canvas()
     77QWidget *QwtPlotMagnifier::canvas()
    7978{
    80     return qobject_cast<QwtPlotCanvas *>( parent() );
     79    return parentWidget();
    8180}
    8281
    8382//! Return Observed plot canvas
    84 const QwtPlotCanvas *QwtPlotMagnifier::canvas() const
     83const QWidget *QwtPlotMagnifier::canvas() const
    8584{
    86     return qobject_cast<const QwtPlotCanvas *>( parent() );
     85    return parentWidget();
    8786}
    8887
     
    9089QwtPlot *QwtPlotMagnifier::plot()
    9190{
    92     QwtPlotCanvas *w = canvas();
     91    QWidget *w = canvas();
    9392    if ( w )
    94         return w->plot();
     93        w = w->parentWidget();
    9594
    96     return NULL;
     95    return qobject_cast<QwtPlot *>( w );
    9796}
    9897
     
    10099const QwtPlot *QwtPlotMagnifier::plot() const
    101100{
    102     const QwtPlotCanvas *w = canvas();
     101    const QWidget *w = canvas();
    103102    if ( w )
    104         return w->plot();
     103        w = w->parentWidget();
    105104
    106     return NULL;
     105    return qobject_cast<const QwtPlot *>( w );
    107106}
    108107
     
    113112void QwtPlotMagnifier::rescale( double factor )
    114113{
     114    QwtPlot* plt = plot();
     115    if ( plt == NULL )
     116        return;
     117
    115118    factor = qAbs( factor );
    116119    if ( factor == 1.0 || factor == 0.0 )
     
    118121
    119122    bool doReplot = false;
    120     QwtPlot* plt = plot();
    121123
    122124    const bool autoReplot = plt->autoReplot();
     
    125127    for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
    126128    {
    127         const QwtScaleDiv *scaleDiv = plt->axisScaleDiv( axisId );
    128         if ( isAxisEnabled( axisId ) && scaleDiv->isValid() )
     129        if ( isAxisEnabled( axisId ) )
    129130        {
    130             const double center =
    131                 scaleDiv->lowerBound() + scaleDiv->range() / 2;
    132             const double width_2 = scaleDiv->range() / 2 * factor;
     131            const QwtScaleMap scaleMap = plt->canvasMap( axisId );
    133132
    134             plt->setAxisScale( axisId, center - width_2, center + width_2 );
     133            double v1 = scaleMap.s1();
     134            double v2 = scaleMap.s2();
     135
     136            if ( scaleMap.transformation() )
     137            {
     138                // the coordinate system of the paint device is always linear
     139
     140                v1 = scaleMap.transform( v1 ); // scaleMap.p1()
     141                v2 = scaleMap.transform( v2 ); // scaleMap.p2()
     142            }
     143
     144            const double center = 0.5 * ( v1 + v2 );
     145            const double width_2 = 0.5 * ( v2 - v1 ) * factor;
     146
     147            v1 = center - width_2;
     148            v2 = center + width_2;
     149
     150            if ( scaleMap.transformation() )
     151            {
     152                v1 = scaleMap.invTransform( v1 );
     153                v2 = scaleMap.invTransform( v2 );
     154            }
     155
     156            plt->setAxisScale( axisId, v1, v2 );
    135157            doReplot = true;
    136158        }
  • trunk/BNC/qwt/qwt_plot_magnifier.h

    r4271 r8127  
    1414#include "qwt_magnifier.h"
    1515
    16 class QwtPlotCanvas;
    1716class QwtPlot;
    1817
     
    3332
    3433public:
    35     explicit QwtPlotMagnifier( QwtPlotCanvas * );
     34    explicit QwtPlotMagnifier( QWidget * );
    3635    virtual ~QwtPlotMagnifier();
    3736
     
    3938    bool isAxisEnabled( int axis ) const;
    4039
    41     QwtPlotCanvas *canvas();
    42     const QwtPlotCanvas *canvas() const;
     40    QWidget *canvas();
     41    const QWidget *canvas() const;
    4342
    4443    QwtPlot *plot();
  • trunk/BNC/qwt/qwt_plot_marker.cpp

    r4271 r8127  
    1414#include "qwt_text.h"
    1515#include "qwt_math.h"
    16 #include "qwt_legend.h"
    17 #include "qwt_legend_item.h"
    1816#include <qpainter.h>
    1917
     
    5149
    5250//! Sets alignment to Qt::AlignCenter, and style to QwtPlotMarker::NoLine
    53 QwtPlotMarker::QwtPlotMarker():
    54     QwtPlotItem( QwtText( "Marker" ) )
     51QwtPlotMarker::QwtPlotMarker( const QString &title ):
     52    QwtPlotItem( QwtText( title ) )
     53{
     54    d_data = new PrivateData;
     55    setZ( 30.0 );
     56}
     57
     58//! Sets alignment to Qt::AlignCenter, and style to QwtPlotMarker::NoLine
     59QwtPlotMarker::QwtPlotMarker( const QwtText &title ):
     60    QwtPlotItem( title )
    5561{
    5662    d_data = new PrivateData;
     
    123129  \param xMap x Scale Map
    124130  \param yMap y Scale Map
    125   \param canvasRect Contents rect of the canvas in painter coordinates
     131  \param canvasRect Contents rectangle of the canvas in painter coordinates
    126132*/
    127133void QwtPlotMarker::draw( QPainter *painter,
     
    140146        ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
    141147    {
    142         d_data->symbol->drawSymbol( painter, pos );
     148        const QSizeF sz = d_data->symbol->size();
     149
     150        const QRectF clipRect = canvasRect.adjusted(
     151            -sz.width(), -sz.height(), sz.width(), sz.height() );
     152
     153        if ( clipRect.contains( pos ) )
     154            d_data->symbol->drawSymbol( painter, pos );
    143155    }
    144156
     
    150162
    151163  \param painter Painter
    152   \param canvasRect Contents rect of the canvas in painter coordinates
     164  \param canvasRect Contents rectangle of the canvas in painter coordinates
    153165  \param pos Position of the marker, translated into widget coordinates
    154166
     
    190202
    191203  \param painter Painter
    192   \param canvasRect Contents rect of the canvas in painter coordinates
     204  \param canvasRect Contents rectangle of the canvas in painter coordinates
    193205  \param pos Position of the marker, translated into widget coordinates
    194206
     
    334346    {
    335347        d_data->style = style;
     348
     349        legendChanged();
    336350        itemChanged();
    337351    }
     
    358372        delete d_data->symbol;
    359373        d_data->symbol = symbol;
     374
     375        if ( symbol )
     376            setLegendIconSize( symbol->boundingRect().size() );
     377
     378        legendChanged();
    360379        itemChanged();
    361380    }
     
    373392/*!
    374393  \brief Set the label
    375   \param label label text
     394  \param label Label text
    376395  \sa label()
    377396*/
     
    484503}
    485504
     505/*!
     506  Build and assign a line pen
     507   
     508  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     509  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     510  to hide this incompatibility.
     511   
     512  \param color Pen color
     513  \param width Pen width
     514  \param style Pen style
     515   
     516  \sa pen(), brush()
     517 */
     518void QwtPlotMarker::setLinePen( const QColor &color, qreal width, Qt::PenStyle style )
     519{   
     520    setLinePen( QPen( color, width, style ) );
     521}
     522
    486523/*!
    487524  Specify a pen for the line.
     
    495532    {
    496533        d_data->pen = pen;
     534
     535        legendChanged();
    497536        itemChanged();
    498537    }
     
    514553
    515554/*!
    516    \brief Update the widget that represents the item on the legend
    517 
    518    \param legend Legend
    519    \sa drawLegendIdentifier(), legendItem(), itemChanged(), QwtLegend()
    520 
    521    \note In the default setting QwtPlotItem::Legend is disabled
    522 */
    523 void QwtPlotMarker::updateLegend( QwtLegend *legend ) const
    524 {
    525     if ( legend && testItemAttribute( QwtPlotItem::Legend )
    526         && d_data->symbol && d_data->symbol->style() != QwtSymbol::NoSymbol )
    527     {
    528         QWidget *lgdItem = legend->find( this );
    529         if ( lgdItem == NULL )
    530         {
    531             lgdItem = legendItem();
    532             if ( lgdItem )
    533                 legend->insert( this, lgdItem );
    534         }
    535 
    536         QwtLegendItem *l = qobject_cast<QwtLegendItem *>( lgdItem );
    537         if ( l )
    538             l->setIdentifierSize( d_data->symbol->boundingSize() );
    539     }
    540 
    541     QwtPlotItem::updateLegend( legend );
    542 }
    543 
    544 /*!
    545   \brief Draw the identifier representing the marker on the legend
    546 
    547   \param painter Painter
    548   \param rect Bounding rectangle for the identifier
    549 
    550   \sa updateLegend(), QwtPlotItem::Legend
    551 */
    552 void QwtPlotMarker::drawLegendIdentifier(
    553     QPainter *painter, const QRectF &rect ) const
    554 {
    555     if ( rect.isEmpty() )
    556         return;
    557 
    558     painter->save();
    559     painter->setClipRect( rect, Qt::IntersectClip );
     555   \return Icon representing the marker on the legend
     556
     557   \param index Index of the legend entry
     558                ( usually there is only one )
     559   \param size Icon size
     560
     561   \sa setLegendIconSize(), legendData()
     562*/
     563QwtGraphic QwtPlotMarker::legendIcon( int index,
     564    const QSizeF &size ) const
     565{
     566    Q_UNUSED( index );
     567
     568    if ( size.isEmpty() )
     569        return QwtGraphic();
     570
     571    QwtGraphic icon;
     572    icon.setDefaultSize( size );
     573    icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
     574
     575    QPainter painter( &icon );
     576    painter.setRenderHint( QPainter::Antialiasing,
     577        testRenderHint( QwtPlotItem::RenderAntialiased ) );
    560578
    561579    if ( d_data->style != QwtPlotMarker::NoLine )
    562580    {
    563         painter->setPen( d_data->pen );
     581        painter.setPen( d_data->pen );
    564582
    565583        if ( d_data->style == QwtPlotMarker::HLine ||
    566584            d_data->style == QwtPlotMarker::Cross )
    567585        {
    568             QwtPainter::drawLine( painter, rect.left(), rect.center().y(),
    569                 rect.right(), rect.center().y() );
     586            const double y = 0.5 * size.height();
     587
     588            QwtPainter::drawLine( &painter,
     589                0.0, y, size.width(), y );
    570590        }
    571591
     
    573593            d_data->style == QwtPlotMarker::Cross )
    574594        {
    575             QwtPainter::drawLine( painter, rect.center().x(), rect.top(),
    576                 rect.center().x(), rect.bottom() );
     595            const double x = 0.5 * size.width();
     596
     597            QwtPainter::drawLine( &painter,
     598                x, 0.0, x, size.height() );
    577599        }
    578600    }
    579601
    580     if ( d_data->symbol && d_data->symbol->style() != QwtSymbol::NoSymbol )
    581     {
    582         QSize symbolSize = d_data->symbol->boundingSize();
    583         symbolSize -= QSize( 2, 2 );
    584 
    585         // scale the symbol size down if it doesn't fit into rect.
    586 
    587         double xRatio = 1.0;
    588         if ( rect.width() < symbolSize.width() )
    589             xRatio = rect.width() / symbolSize.width();
    590         double yRatio = 1.0;
    591         if ( rect.height() < symbolSize.height() )
    592             yRatio = rect.height() / symbolSize.height();
    593 
    594         const double ratio = qMin( xRatio, yRatio );
    595 
    596         painter->scale( ratio, ratio );
    597         d_data->symbol->drawSymbol( painter, rect.center() / ratio );
    598     }
    599 
    600     painter->restore();
    601 }
    602 
     602    if ( d_data->symbol )
     603    {
     604        const QRect r( 0.0, 0.0, size.width(), size.height() );
     605        d_data->symbol->drawSymbol( &painter, r );
     606    }
     607
     608    return icon;
     609}
     610
  • trunk/BNC/qwt/qwt_plot_marker.h

    r4271 r8127  
    2929  be drawn around a center point inside a bounding rectangle.
    3030
    31   The QwtPlotMarker::setSymbol() member assigns a symbol to the marker.
     31  The setSymbol() member assigns a symbol to the marker.
    3232  The symbol is drawn at the specified point.
    3333
     
    4040  left above the center point if the alignment was set to
    4141  Qt::AlignLeft | Qt::AlignTop.
     42
     43  \note QwtPlotTextLabel is intended to align a text label
     44        according to the geometry of canvas
     45        ( unrelated to plot coordinates )
    4246*/
    4347
     
    6569    };
    6670
    67     explicit QwtPlotMarker();
     71    explicit QwtPlotMarker( const QString &title = QString::null );
     72    explicit QwtPlotMarker( const QwtText &title );
     73
    6874    virtual ~QwtPlotMarker();
    6975
     
    8288    LineStyle lineStyle() const;
    8389
     90    void setLinePen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
    8491    void setLinePen( const QPen &p );
    8592    const QPen &linePen() const;
     
    106113    virtual QRectF boundingRect() const;
    107114
    108     virtual void updateLegend( QwtLegend * ) const;
    109     virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const;
     115    virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
    110116
    111117protected:
  • trunk/BNC/qwt/qwt_plot_panner.cpp

    r4271 r8127  
    1111#include "qwt_scale_div.h"
    1212#include "qwt_plot.h"
    13 #include "qwt_plot_canvas.h"
     13#include "qwt_painter.h"
     14#include <qbitmap.h>
     15#include <qstyle.h>
     16#include <qstyleoption.h>
     17
     18static QBitmap qwtBorderMask( const QWidget *canvas, const QSize &size )
     19{
     20    const QRect r( 0, 0, size.width(), size.height() );
     21
     22    QPainterPath borderPath;
     23
     24    ( void )QMetaObject::invokeMethod(
     25        const_cast< QWidget *>( canvas ), "borderPath", Qt::DirectConnection,
     26        Q_RETURN_ARG( QPainterPath, borderPath ), Q_ARG( QRect, r ) );
     27
     28    if ( borderPath.isEmpty() )
     29    {
     30        if ( canvas->contentsRect() == canvas->rect() )
     31            return QBitmap();
     32
     33        QBitmap mask( size );
     34        mask.fill( Qt::color0 );
     35
     36        QPainter painter( &mask );
     37        painter.fillRect( canvas->contentsRect(), Qt::color1 );
     38
     39        return mask;
     40    }
     41
     42    QImage image( size, QImage::Format_ARGB32_Premultiplied );
     43    image.fill( Qt::color0 );
     44
     45    QPainter painter( &image );
     46    painter.setClipPath( borderPath );
     47    painter.fillRect( r, Qt::color1 );
     48
     49    // now erase the frame
     50
     51    painter.setCompositionMode( QPainter::CompositionMode_DestinationOut );
     52
     53    if ( canvas->testAttribute(Qt::WA_StyledBackground ) )
     54    {
     55        QStyleOptionFrame opt;
     56        opt.initFrom(canvas);
     57        opt.rect = r;
     58        canvas->style()->drawPrimitive( QStyle::PE_Frame, &opt, &painter, canvas );
     59    }
     60    else
     61    {
     62        const QVariant borderRadius = canvas->property( "borderRadius" );
     63        const QVariant frameWidth = canvas->property( "frameWidth" );
     64
     65        if ( borderRadius.type() == QVariant::Double
     66            && frameWidth.type() == QVariant::Int )
     67        {
     68            const double br = borderRadius.toDouble();
     69            const int fw = frameWidth.toInt();
     70       
     71            if ( br > 0.0 && fw > 0 )
     72            {
     73                painter.setPen( QPen( Qt::color1, fw ) );
     74                painter.setBrush( Qt::NoBrush );
     75                painter.setRenderHint( QPainter::Antialiasing, true );
     76
     77                painter.drawPath( borderPath );
     78            }
     79        }
     80    }
     81
     82    painter.end();
     83
     84    const QImage mask = image.createMaskFromColor(
     85        QColor( Qt::color1 ).rgb(), Qt::MaskOutColor );
     86
     87    return QBitmap::fromImage( mask );
     88}
    1489
    1590class QwtPlotPanner::PrivateData
     
    26101
    27102/*!
    28   \brief Create a plot panner
     103  \brief A panner for the canvas of a QwtPlot
    29104
    30105  The panner is enabled for all axes
     
    34109  \sa setAxisEnabled()
    35110*/
    36 QwtPlotPanner::QwtPlotPanner( QwtPlotCanvas *canvas ):
     111QwtPlotPanner::QwtPlotPanner( QWidget *canvas ):
    37112    QwtPanner( canvas )
    38113{
     
    83158
    84159//! Return observed plot canvas
    85 QwtPlotCanvas *QwtPlotPanner::canvas()
    86 {
    87     return qobject_cast<QwtPlotCanvas *>( parentWidget() );
     160QWidget *QwtPlotPanner::canvas()
     161{
     162    return parentWidget();
    88163}
    89164
    90165//! Return Observed plot canvas
    91 const QwtPlotCanvas *QwtPlotPanner::canvas() const
    92 {
    93     return qobject_cast<const QwtPlotCanvas *>( parentWidget() );
     166const QWidget *QwtPlotPanner::canvas() const
     167{
     168    return parentWidget();
    94169}
    95170
     
    97172QwtPlot *QwtPlotPanner::plot()
    98173{
    99     QwtPlotCanvas *w = canvas();
     174    QWidget *w = canvas();
    100175    if ( w )
    101         return w->plot();
    102 
    103     return NULL;
     176        w = w->parentWidget();
     177
     178    return qobject_cast<QwtPlot *>( w );
    104179}
    105180
     
    107182const QwtPlot *QwtPlotPanner::plot() const
    108183{
    109     const QwtPlotCanvas *w = canvas();
     184    const QWidget *w = canvas();
    110185    if ( w )
    111         return w->plot();
    112 
    113     return NULL;
     186        w = w->parentWidget();
     187
     188    return qobject_cast<const QwtPlot *>( w );
    114189}
    115190
     
    141216        const QwtScaleMap map = plot->canvasMap( axis );
    142217
    143         const double p1 = map.transform( plot->axisScaleDiv( axis )->lowerBound() );
    144         const double p2 = map.transform( plot->axisScaleDiv( axis )->upperBound() );
     218        const double p1 = map.transform( plot->axisScaleDiv( axis ).lowerBound() );
     219        const double p2 = map.transform( plot->axisScaleDiv( axis ).upperBound() );
    145220
    146221        double d1, d2;
     
    164239
    165240/*!
    166     Calculate a mask from the border mask of the canvas
    167     \sa QwtPlotCanvas::borderMask()
     241   Calculate a mask from the border path of the canvas
     242
     243   \return Mask as bitmap
     244   \sa QwtPlotCanvas::borderPath()
    168245*/
    169246QBitmap QwtPlotPanner::contentsMask() const
    170247{
    171248    if ( canvas() )
    172         return canvas()->borderMask( size() );
     249        return qwtBorderMask( canvas(), size() );
    173250
    174251    return QwtPanner::contentsMask();
    175252}
     253
     254/*!
     255   \return Pixmap with the content of the canvas
     256 */
     257QPixmap QwtPlotPanner::grab() const
     258{   
     259    const QWidget *cv = canvas();
     260    if ( cv && cv->inherits( "QGLWidget" ) )
     261    {
     262        // we can't grab from a QGLWidget
     263
     264        QPixmap pm( cv->size() );
     265        QwtPainter::fillPixmap( cv, pm );
     266
     267        QPainter painter( &pm );
     268        const_cast<QwtPlot *>( plot() )->drawCanvas( &painter );
     269
     270        return pm;
     271    }
     272
     273    return QwtPanner::grab();
     274}   
     275
  • trunk/BNC/qwt/qwt_plot_panner.h

    r4271 r8127  
    1414#include "qwt_panner.h"
    1515
    16 class QwtPlotCanvas;
    1716class QwtPlot;
    1817
     
    2019  \brief QwtPlotPanner provides panning of a plot canvas
    2120
    22   QwtPlotPanner is a panner for a QwtPlotCanvas, that
     21  QwtPlotPanner is a panner for a plot canvas, that
    2322  adjusts the scales of the axes after dropping
    2423  the canvas on its new position.
     
    3534
    3635public:
    37     explicit QwtPlotPanner( QwtPlotCanvas * );
     36    explicit QwtPlotPanner( QWidget * );
    3837    virtual ~QwtPlotPanner();
    3938
    40     QwtPlotCanvas *canvas();
    41     const QwtPlotCanvas *canvas() const;
     39    QWidget *canvas();
     40    const QWidget *canvas() const;
    4241
    4342    QwtPlot *plot();
     
    5251protected:
    5352    virtual QBitmap contentsMask() const;
     53    virtual QPixmap grab() const;
    5454
    5555private:
  • trunk/BNC/qwt/qwt_plot_picker.cpp

    r4271 r8127  
    2828*/
    2929
    30 QwtPlotPicker::QwtPlotPicker( QwtPlotCanvas *canvas ):
     30QwtPlotPicker::QwtPlotPicker( QWidget *canvas ):
    3131    QwtPicker( canvas ),
    3232    d_xAxis( -1 ),
     
    6666  \sa QwtPlot::autoReplot(), QwtPlot::replot(), scaleRect()
    6767*/
    68 QwtPlotPicker::QwtPlotPicker( int xAxis, int yAxis, QwtPlotCanvas *canvas ):
     68QwtPlotPicker::QwtPlotPicker( int xAxis, int yAxis, QWidget *canvas ):
    6969    QwtPicker( canvas ),
    7070    d_xAxis( xAxis ),
     
    7878  \param xAxis X axis of the picker
    7979  \param yAxis Y axis of the picker
    80   \param rubberBand Rubberband style
     80  \param rubberBand Rubber band style
    8181  \param trackerMode Tracker mode
    8282  \param canvas Plot canvas to observe, also the parent object
     
    8989QwtPlotPicker::QwtPlotPicker( int xAxis, int yAxis,
    9090        RubberBand rubberBand, DisplayMode trackerMode,
    91         QwtPlotCanvas *canvas ):
     91        QWidget *canvas ):
    9292    QwtPicker( rubberBand, trackerMode, canvas ),
    9393    d_xAxis( xAxis ),
     
    101101}
    102102
    103 //! Return observed plot canvas
    104 QwtPlotCanvas *QwtPlotPicker::canvas()
    105 {
    106     return qobject_cast<QwtPlotCanvas *>( parentWidget() );
    107 }
    108 
    109 //! Return Observed plot canvas
    110 const QwtPlotCanvas *QwtPlotPicker::canvas() const
    111 {
    112     return qobject_cast<const QwtPlotCanvas *>( parentWidget() );
    113 }
    114 
    115 //! Return plot widget, containing the observed plot canvas
     103//! \return Observed plot canvas
     104QWidget *QwtPlotPicker::canvas()
     105{
     106    return parentWidget();
     107}
     108
     109//! \return Observed plot canvas
     110const QWidget *QwtPlotPicker::canvas() const
     111{
     112    return parentWidget();
     113}
     114
     115//! \return Plot widget, containing the observed plot canvas
    116116QwtPlot *QwtPlotPicker::plot()
    117117{
    118     QwtPlotCanvas *w = canvas();
     118    QWidget *w = canvas();
    119119    if ( w )
    120         return w->plot();
    121 
    122     return NULL;
    123 }
    124 
    125 //! Return plot widget, containing the observed plot canvas
     120        w = w->parentWidget();
     121
     122    return qobject_cast<QwtPlot *>( w );
     123}
     124
     125//! \return Plot widget, containing the observed plot canvas
    126126const QwtPlot *QwtPlotPicker::plot() const
    127127{
    128     const QwtPlotCanvas *w = canvas();
     128    const QWidget *w = canvas();
    129129    if ( w )
    130         return w->plot();
    131 
    132     return NULL;
    133 }
    134 
    135 /*!
    136   Return normalized bounding rect of the axes
    137 
     130        w = w->parentWidget();
     131
     132    return qobject_cast<const QwtPlot *>( w );
     133}
     134
     135/*!
     136  \return Normalized bounding rectangle of the axes
    138137  \sa QwtPlot::autoReplot(), QwtPlot::replot().
    139138*/
     
    144143    if ( plot() )
    145144    {
    146         const QwtScaleDiv *xs = plot()->axisScaleDiv( xAxis() );
    147         const QwtScaleDiv *ys = plot()->axisScaleDiv( yAxis() );
    148 
    149         if ( xs && ys )
    150         {
    151             rect = QRectF( xs->lowerBound(), ys->lowerBound(),
    152                 xs->range(), ys->range() );
    153             rect = rect.normalized();
    154         }
     145        const QwtScaleDiv &xs = plot()->axisScaleDiv( xAxis() );
     146        const QwtScaleDiv &ys = plot()->axisScaleDiv( yAxis() );
     147
     148        rect = QRectF( xs.lowerBound(), ys.lowerBound(),
     149            xs.range(), ys.range() );
     150        rect = rect.normalized();
    155151    }
    156152
     
    231227
    232228/*!
    233   Append a point to the selection and update rubberband and tracker.
     229  Append a point to the selection and update rubber band and tracker.
    234230
    235231  \param pos Additional point
     
    265261  \param ok If true, complete the selection and emit selected signals
    266262            otherwise discard the selection.
    267   \return true if the selection is accepted, false otherwise
     263  \return True if the selection has been accepted, false otherwise
    268264*/
    269265
     
    278274        return false;
    279275
    280     const QPolygon pa = selection();
    281     if ( pa.count() == 0 )
     276    const QPolygon points = selection();
     277    if ( points.count() == 0 )
    282278        return false;
    283279
     
    292288        case QwtPickerMachine::PointSelection:
    293289        {
    294             const QPointF pos = invTransform( pa[0] );
     290            const QPointF pos = invTransform( points.first() );
    295291            Q_EMIT selected( pos );
    296292            break;
     
    298294        case QwtPickerMachine::RectSelection:
    299295        {
    300             if ( pa.count() >= 2 )
     296            if ( points.count() >= 2 )
    301297            {
    302                 const QPoint p1 = pa[0];
    303                 const QPoint p2 = pa[int( pa.count() - 1 )];
     298                const QPoint p1 = points.first();
     299                const QPoint p2 = points.last();
    304300
    305301                const QRect rect = QRect( p1, p2 ).normalized();
     
    310306        case QwtPickerMachine::PolygonSelection:
    311307        {
    312             QVector<QPointF> dpa( pa.count() );
    313             for ( int i = 0; i < int( pa.count() ); i++ )
    314                 dpa[i] = invTransform( pa[i] );
     308            QVector<QPointF> dpa( points.count() );
     309            for ( int i = 0; i < points.count(); i++ )
     310                dpa[i] = invTransform( points[i] );
    315311
    316312            Q_EMIT selected( dpa );
  • trunk/BNC/qwt/qwt_plot_picker.h

    r4271 r8127  
    1212
    1313#include "qwt_global.h"
    14 #include "qwt_plot_canvas.h"
    1514#include "qwt_picker.h"
    1615#include <qvector.h>
     
    2322  QwtPlotPicker is a QwtPicker tailored for selections on
    2423  a plot canvas. It is set to a x-Axis and y-Axis and
    25   translates all pixel coordinates into this coodinate system.
     24  translates all pixel coordinates into this coordinate system.
    2625*/
    2726
     
    3130
    3231public:
    33     explicit QwtPlotPicker( QwtPlotCanvas * );
     32    explicit QwtPlotPicker( QWidget *canvas );
    3433    virtual ~QwtPlotPicker();
    3534
    36     explicit QwtPlotPicker( int xAxis, int yAxis, QwtPlotCanvas * );
     35    explicit QwtPlotPicker( int xAxis, int yAxis, QWidget * );
    3736
    3837    explicit QwtPlotPicker( int xAxis, int yAxis,
    39         RubberBand rubberBand, DisplayMode trackerMode,
    40         QwtPlotCanvas * );
     38        RubberBand rubberBand, DisplayMode trackerMode, QWidget * );
    4139
    4240    virtual void setAxis( int xAxis, int yAxis );
     
    4846    const QwtPlot *plot() const;
    4947
    50     QwtPlotCanvas *canvas();
    51     const QwtPlotCanvas *canvas() const;
     48    QWidget *canvas();
     49    const QWidget *canvas() const;
    5250
    5351Q_SIGNALS:
    5452
    5553    /*!
    56       A signal emitted in case of selectionFlags() & PointSelection.
     54      A signal emitted in case of QwtPickerMachine::PointSelection.
    5755      \param pos Selected point
    5856    */
     
    6058
    6159    /*!
    62       A signal emitted in case of selectionFlags() & RectSelection.
     60      A signal emitted in case of QwtPickerMachine::RectSelection.
    6361      \param rect Selected rectangle
    6462    */
  • trunk/BNC/qwt/qwt_plot_rasteritem.cpp

    r4271 r8127  
    99
    1010#include "qwt_plot_rasteritem.h"
    11 #include "qwt_legend.h"
    12 #include "qwt_legend_item.h"
    1311#include "qwt_scale_map.h"
    1412#include "qwt_painter.h"
     
    1715#include <qpainter.h>
    1816#include <qpaintengine.h>
     17#include <qmath.h>
     18#if QT_VERSION >= 0x040400
     19#include <qthread.h>
     20#include <qfuture.h>
     21#include <qtconcurrentrun.h>
     22#endif
    1923#include <float.h>
    2024
     
    3034
    3135    int alpha;
     36
    3237    QwtPlotRasterItem::PaintAttributes paintAttributes;
    3338
     
    186191                }
    187192
    188                 const quint32 *line1 = (const quint32 *) image.scanLine( y1 );
     193                const quint32 *line1 =
     194                    reinterpret_cast<const quint32 *>( image.scanLine( y1 ) );
    189195
    190196                for ( int x1 = 0; x1 < w; x1++ )
     
    217223                    for ( int y2 = yy1; y2 < yy2; y2++ )
    218224                    {
    219                         quint32 *line2 = ( quint32 *) expanded.scanLine( y2 );
     225                        quint32 *line2 = reinterpret_cast<quint32 *>(
     226                            expanded.scanLine( y2 ) );
     227
    220228                        for ( int x2 = xx1; x2 < xx2; x2++ )
    221229                            line2[x2] = rgb;
     
    297305}   
    298306
    299 static QRectF expandToPixels(const QRectF &rect, const QRectF &pixelRect)
     307static QRectF qwtExpandToPixels(const QRectF &rect, const QRectF &pixelRect)
    300308{
    301309    const double pw = pixelRect.width();
     
    316324}
    317325
    318 static void transformMaps( const QTransform &tr,
     326static void qwtTransformMaps( const QTransform &tr,
    319327    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    320328    QwtScaleMap &xxMap, QwtScaleMap &yyMap )
     
    330338}
    331339
    332 static void adjustMaps( QwtScaleMap &xMap, QwtScaleMap &yMap,
     340static void qwtAdjustMaps( QwtScaleMap &xMap, QwtScaleMap &yMap,
    333341    const QRectF &area, const QRectF &paintRect)
    334342{
     
    351359}
    352360
    353 static bool useCache( QwtPlotRasterItem::CachePolicy policy,
     361static bool qwtUseCache( QwtPlotRasterItem::CachePolicy policy,
    354362    const QPainter *painter )
    355363{
     
    377385}
    378386
    379 static QImage toRgba( const QImage& image, int alpha )
    380 {
    381     if ( alpha < 0 || alpha >= 255 )
    382         return image;
    383 
    384     QImage alphaImage( image.size(), QImage::Format_ARGB32 );
    385 
     387static void qwtToRgba( const QImage* from, QImage* to, 
     388    const QRect& tile, int alpha )
     389{
    386390    const QRgb mask1 = qRgba( 0, 0, 0, alpha );
    387391    const QRgb mask2 = qRgba( 255, 255, 255, 0 );
    388392    const QRgb mask3 = qRgba( 0, 0, 0, 255 );
    389393
    390     const int w = image.size().width();
    391     const int h = image.size().height();
    392 
    393     if ( image.depth() == 8 )
    394     {
    395         for ( int y = 0; y < h; y++ )
    396         {
    397             QRgb* alphaLine = ( QRgb* )alphaImage.scanLine( y );
    398             const unsigned char *line = image.scanLine( y );
    399 
    400             for ( int x = 0; x < w; x++ )
    401                 *alphaLine++ = ( image.color( *line++ ) & mask2 ) | mask1;
    402         }
    403     }
    404     else if ( image.depth() == 32 )
    405     {
    406         for ( int y = 0; y < h; y++ )
    407         {
    408             QRgb* alphaLine = ( QRgb* )alphaImage.scanLine( y );
    409             const QRgb* line = ( const QRgb* ) image.scanLine( y );
    410 
    411             for ( int x = 0; x < w; x++ )
     394    const int y0 = tile.top();
     395    const int y1 = tile.bottom();
     396    const int x0 = tile.left();
     397    const int x1 = tile.right();
     398
     399    if ( from->depth() == 8 )
     400    {
     401        for ( int y = y0; y <= y1; y++ )
     402        {
     403            QRgb *alphaLine = reinterpret_cast<QRgb *>( to->scanLine( y ) );
     404            const unsigned char *line = from->scanLine( y );
     405
     406            for ( int x = x0; x <= x1; x++ )
     407                *alphaLine++ = ( from->color( *line++ ) & mask2 ) | mask1;
     408        }
     409    }
     410    else if ( from->depth() == 32 )
     411    {
     412        for ( int y = y0; y <= y1; y++ )
     413        {
     414            QRgb *alphaLine = reinterpret_cast<QRgb *>( to->scanLine( y ) );
     415            const QRgb *line = reinterpret_cast<const QRgb *>( from->scanLine( y ) );
     416
     417            for ( int x = x0; x <= x1; x++ )
    412418            {
    413419                const QRgb rgb = *line++;
     
    419425        }
    420426    }
    421 
    422     return alphaImage;
    423427}
    424428
     
    469473
    470474/*!
    471     \brief Return the current paint attributes
     475    \return True, when attribute is enabled
    472476    \sa PaintAttribute, setPaintAttribute()
    473477*/
     
    572576
    573577   Width and height of the hint need to be the horizontal 
    574    and vertical distances between 2 neighboured points.
     578   and vertical distances between 2 neighbored points.
    575579   The center of the hint has to be the position of any point
    576580   ( it doesn't matter which one ).
     
    602606  \param xMap X-Scale Map
    603607  \param yMap Y-Scale Map
    604   \param canvasRect Contents rect of the plot canvas
     608  \param canvasRect Contents rectangle of the plot canvas
    605609*/
    606610void QwtPlotRasterItem::draw( QPainter *painter,
     
    611615        return;
    612616
    613     const bool doCache = useCache( d_data->cache.policy, painter );
     617    const bool doCache = qwtUseCache( d_data->cache.policy, painter );
    614618
    615619    const QwtInterval xInterval = interval( Qt::XAxis );
     
    617621
    618622    /*
    619         Scaling a rastered image always results in a loss of
     623        Scaling an image always results in a loss of
    620624        precision/quality. So we always render the image in
    621625        paint device resolution.
     
    623627
    624628    QwtScaleMap xxMap, yyMap;
    625     transformMaps( painter->transform(), xMap, yMap, xxMap, yyMap );
     629    qwtTransformMaps( painter->transform(), xMap, yMap, xxMap, yyMap );
    626630
    627631    QRectF paintRect = painter->transform().mapRect( canvasRect );
     
    644648    if ( !pixelRect.isEmpty() )
    645649    {
    646         const QRectF r = QwtScaleMap::invTransform(
    647             xxMap, yyMap, QRectF(0, 0, 1, 1) ).normalized();
    648 
    649         if ( r.width() > pixelRect.width() &&
    650             r.height() > pixelRect.height() )
     650        // one pixel of the target device in plot coordinates
     651        const double dx = qAbs( xxMap.invTransform( 1 ) - xxMap.invTransform( 0 ) );
     652        const double dy = qAbs( yyMap.invTransform( 1 ) - yyMap.invTransform( 0 ) );
     653
     654        if ( dx > pixelRect.width() && dy > pixelRect.height() )
    651655        {
    652656            /*
     
    657661            pixelRect = QRectF();
    658662        }
     663        else
     664        {
     665            /*
     666              If only one dimension is of the data pixel is higher
     667              we expand the pixel rect to the resolution of the target device.
     668             */
     669
     670            if ( dx > pixelRect.width() )
     671                pixelRect.setWidth( dx );
     672
     673            if ( dy > pixelRect.height() )
     674                pixelRect.setHeight( dy );
     675        }
    659676    }
    660677
     
    667684
    668685            paintRect = qwtAlignRect(paintRect);
    669             adjustMaps(xxMap, yyMap, area, paintRect);
     686            qwtAdjustMaps(xxMap, yyMap, area, paintRect);
    670687        }
    671688
     
    701718
    702719        // align the area to the data pixels
    703         QRectF imageArea = expandToPixels(area, pixelRect);
     720        QRectF imageArea = qwtExpandToPixels(area, pixelRect);
    704721
    705722        if ( imageArea.right() == xInterval.maxValue() &&
     
    717734        imageSize.setWidth( qRound( imageArea.width() / pixelRect.width() ) );
    718735        imageSize.setHeight( qRound( imageArea.height() / pixelRect.height() ) );
     736
    719737        image = compose(xxMap, yyMap,
    720738            imageArea, paintRect, imageSize, doCache );
     739
    721740        if ( image.isNull() )
    722741            return;
     
    760779
    761780/*!
    762    \return Bounding rect of the data
     781   \return Bounding rectangle of the data
    763782   \sa QwtPlotRasterItem::interval()
    764783*/
     
    844863
    845864    if ( d_data->alpha >= 0 && d_data->alpha < 255 )
    846         image = toRgba( image, d_data->alpha );
     865    {
     866        QImage alphaImage( image.size(), QImage::Format_ARGB32 );
     867
     868#if QT_VERSION >= 0x040400 && !defined(QT_NO_QFUTURE)
     869        uint numThreads = renderThreadCount();
     870
     871        if ( numThreads <= 0 )
     872            numThreads = QThread::idealThreadCount();
     873
     874        if ( numThreads <= 0 )
     875            numThreads = 1;
     876
     877        const int numRows = image.height() / numThreads;
     878
     879        QList< QFuture<void> > futures;
     880        for ( uint i = 0; i < numThreads; i++ )
     881        {
     882            QRect tile( 0, i * numRows, image.width(), numRows );
     883            if ( i == numThreads - 1 )
     884            {
     885                tile.setHeight( image.height() - i * numRows );
     886                qwtToRgba( &image, &alphaImage, tile, d_data->alpha );
     887            }
     888            else
     889            {
     890                futures += QtConcurrent::run(
     891                    &qwtToRgba, &image, &alphaImage, tile, d_data->alpha );
     892            }
     893        }
     894        for ( int i = 0; i < futures.size(); i++ )
     895            futures[i].waitForFinished();
     896#else
     897        const QRect tile( 0, 0, image.width(), image.height() );
     898        qwtToRgba( &image, &alphaImage, tile, d_data->alpha );
     899#endif
     900        image = alphaImage;
     901    }
    847902
    848903    return image;
     
    857912   \param imageSize Image size
    858913   \param pixelSize Width/Height of a data pixel
     914
     915   \return Calculated scale map
    859916*/
    860917QwtScaleMap QwtPlotRasterItem::imageMap(
  • trunk/BNC/qwt/qwt_plot_rasteritem.h

    r4271 r8127  
    3939public:
    4040    /*!
    41       - NoCache\n
    42         renderImage() is called, whenever the item has to be repainted
    43       - PaintCache\n
    44         renderImage() is called, whenever the image cache is not valid,
    45         or the scales, or the size of the canvas has changed. This type
    46         of cache is only useful for improving the performance of hide/show
    47         operations. All other situations are already handled by the
    48         plot canvas cache.
    49 
     41      \brief Cache policy
    5042      The default policy is NoCache
    5143     */
    5244    enum CachePolicy
    5345    {
     46        /*!
     47          renderImage() is called each time the item has to be repainted
     48         */
    5449        NoCache,
     50
     51        /*!
     52          renderImage() is called, whenever the image cache is not valid,
     53          or the scales, or the size of the canvas has changed.
     54
     55          This type of cache is useful for improving the performance
     56          of hide/show operations or manipulations of the alpha value.
     57          All other situations are handled by the canvas backing store.
     58         */
    5559        PaintCache
    5660    };
     
    118122      \param area Requested area for the image in scale coordinates
    119123      \param imageSize Requested size of the image
     124   
     125      \return Rendered image
    120126     */
    121127    virtual QImage renderImage( const QwtScaleMap &xMap,
  • trunk/BNC/qwt/qwt_plot_renderer.cpp

    r4271 r8127  
    1111#include "qwt_plot.h"
    1212#include "qwt_painter.h"
    13 #include "qwt_plot_canvas.h"
    1413#include "qwt_plot_layout.h"
    15 #include "qwt_legend.h"
    16 #include "qwt_legend_item.h"
    17 #include "qwt_dyngrid_layout.h"
     14#include "qwt_abstract_legend.h"
    1815#include "qwt_scale_widget.h"
    1916#include "qwt_scale_engine.h"
     
    2522#include <qtransform.h>
    2623#include <qprinter.h>
     24#include <qprintdialog.h>
     25#include <qfiledialog.h>
     26#include <qfileinfo.h>
    2727#include <qstyle.h>
    2828#include <qstyleoption.h>
    2929#include <qimagewriter.h>
    30 #include <qfileinfo.h>
    3130#ifndef QWT_NO_SVG
    3231#ifdef QT_SVG_LIB
     
    3534#endif
    3635
     36static QPainterPath qwtCanvasClip(
     37    const QWidget* canvas, const QRectF &canvasRect )
     38{
     39    // The clip region is calculated in integers
     40    // To avoid too much rounding errors better
     41    // calculate it in target device resolution
     42
     43    int x1 = qCeil( canvasRect.left() );
     44    int x2 = qFloor( canvasRect.right() );
     45    int y1 = qCeil( canvasRect.top() );
     46    int y2 = qFloor( canvasRect.bottom() );
     47
     48    const QRect r( x1, y1, x2 - x1 - 1, y2 - y1 - 1 );
     49
     50    QPainterPath clipPath;
     51
     52    ( void ) QMetaObject::invokeMethod(
     53        const_cast< QWidget *>( canvas ), "borderPath",
     54        Qt::DirectConnection,
     55        Q_RETURN_ARG( QPainterPath, clipPath ), Q_ARG( QRect, r ) );
     56
     57    return clipPath;
     58}
     59
    3760class QwtPlotRenderer::PrivateData
    3861{
    3962public:
    4063    PrivateData():
    41         discardFlags( QwtPlotRenderer::DiscardBackground ),
     64        discardFlags( QwtPlotRenderer::DiscardNone ),
    4265        layoutFlags( QwtPlotRenderer::DefaultLayout )
    4366    {
     
    4770    QwtPlotRenderer::LayoutFlags layoutFlags;
    4871};
    49 
    50 static void qwtRenderBackground( QPainter *painter,
    51     const QRectF &rect, const QWidget *widget )
    52 {
    53     if ( widget->testAttribute( Qt::WA_StyledBackground ) )
    54     {
    55         QStyleOption opt;
    56         opt.initFrom( widget );
    57         opt.rect = rect.toAlignedRect();
    58 
    59         widget->style()->drawPrimitive(
    60             QStyle::PE_Widget, &opt, painter, widget);
    61     }
    62     else
    63     {
    64         const QBrush brush =
    65             widget->palette().brush( widget->backgroundRole() );
    66 
    67         painter->fillRect( rect, brush );
    68     }
    69 }
    7072
    7173/*!
     
    102104
    103105/*!
    104   Check if a flag is set.
    105 
     106  \return True, if flag is enabled.
    106107  \param flag Flag to be tested
    107108  \sa DiscardFlag, setDiscardFlag(), setDiscardFlags(), discardFlags()
     
    149150
    150151/*!
    151   Check if a flag is set.
    152 
     152  \return True, if flag is enabled.
    153153  \param flag Flag to be tested
    154154  \sa LayoutFlag, setLayoutFlag(), setLayoutFlags(), layoutFlags()
     
    182182  Render a plot to a file
    183183
    184   The format of the document will be autodetected from the
    185   suffix of the filename.
     184  The format of the document will be auto-detected from the
     185  suffix of the file name.
    186186
    187187  \param plot Plot widget
     
    239239
    240240    const QString fmt = format.toLower();
    241     if ( fmt == "pdf" || fmt == "ps" )
     241    if ( fmt == "pdf" )
    242242    {
    243243#ifndef QT_NO_PRINTER
    244244        QPrinter printer;
     245        printer.setOutputFormat( QPrinter::PdfFormat );
     246        printer.setColorMode( QPrinter::Color );
    245247        printer.setFullPage( true );
    246248        printer.setPaperSize( sizeMM, QPrinter::Millimeter );
    247249        printer.setDocName( title );
    248250        printer.setOutputFileName( fileName );
    249         printer.setOutputFormat( ( format == "pdf" )
    250             ? QPrinter::PdfFormat : QPrinter::PostScriptFormat );
    251251        printer.setResolution( resolution );
    252252
    253253        QPainter painter( &printer );
    254254        render( plot, &painter, documentRect );
     255#endif
     256    }
     257    else if ( fmt == "ps" )
     258    {
     259#if QT_VERSION < 0x050000
     260#ifndef QT_NO_PRINTER
     261        QPrinter printer;
     262        printer.setOutputFormat( QPrinter::PostScriptFormat );
     263        printer.setColorMode( QPrinter::Color );
     264        printer.setFullPage( true );
     265        printer.setPaperSize( sizeMM, QPrinter::Millimeter );
     266        printer.setDocName( title );
     267        printer.setOutputFileName( fileName );
     268        printer.setResolution( resolution );
     269
     270        QPainter painter( &printer );
     271        render( plot, &painter, documentRect );
     272#endif
    255273#endif
    256274    }
     
    393411    QPainter *painter, const QRectF &plotRect ) const
    394412{
    395     int axisId;
    396 
    397413    if ( painter == 0 || !painter->isActive() ||
    398414            !plotRect.isValid() || plot->size().isNull() )
     415    {
    399416        return;
     417    }
    400418
    401419    if ( !( d_data->discardFlags & DiscardBackground ) )
    402         qwtRenderBackground( painter, plotRect, plot );
     420        QwtPainter::drawBackgound( painter, plotRect, plot );
    403421
    404422    /*
     
    412430        double( painter->device()->logicalDpiY() ) / plot->logicalDpiY() );
    413431
    414     painter->save();
     432    QRectF layoutRect = transform.inverted().mapRect( plotRect );
     433
     434    if ( !( d_data->discardFlags & DiscardBackground ) )
     435    {
     436        // subtract the contents margins
     437
     438        int left, top, right, bottom;
     439        plot->getContentsMargins( &left, &top, &right, &bottom );
     440        layoutRect.adjust( left, top, -right, -bottom );
     441    }
     442
     443    QwtPlotLayout *layout = plot->plotLayout();
    415444
    416445    int baseLineDists[QwtPlot::axisCnt];
    417     if ( d_data->layoutFlags & FrameWithScales )
    418     {
    419         for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
     446    int canvasMargins[QwtPlot::axisCnt];
     447
     448    for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
     449    {
     450        canvasMargins[ axisId ] = layout->canvasMargin( axisId );
     451
     452        if ( d_data->layoutFlags & FrameWithScales )
    420453        {
    421454            QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
     
    425458                scaleWidget->setMargin( 0 );
    426459            }
    427         }
    428     }
    429     // Calculate the layout for the print.
    430 
    431     QwtPlotLayout::Options layoutOptions =
    432         QwtPlotLayout::IgnoreScrollbars | QwtPlotLayout::IgnoreFrames;
     460
     461            if ( !plot->axisEnabled( axisId ) )
     462            {
     463                int left = 0;
     464                int right = 0;
     465                int top = 0;
     466                int bottom = 0;
     467
     468                // When we have a scale the frame is painted on
     469                // the position of the backbone - otherwise we
     470                // need to introduce a margin around the canvas
     471
     472                switch( axisId )
     473                {
     474                    case QwtPlot::yLeft:
     475                        layoutRect.adjust( 1, 0, 0, 0 );
     476                        break;
     477                    case QwtPlot::yRight:
     478                        layoutRect.adjust( 0, 0, -1, 0 );
     479                        break;
     480                    case QwtPlot::xTop:
     481                        layoutRect.adjust( 0, 1, 0, 0 );
     482                        break;
     483                    case QwtPlot::xBottom:
     484                        layoutRect.adjust( 0, 0, 0, -1 );
     485                        break;
     486                    default:
     487                        break;
     488                }
     489                layoutRect.adjust( left, top, right, bottom );
     490            }
     491        }
     492    }
     493
     494    // Calculate the layout for the document.
     495
     496    QwtPlotLayout::Options layoutOptions = QwtPlotLayout::IgnoreScrollbars;
     497
     498    if ( ( d_data->layoutFlags & FrameWithScales ) ||
     499        ( d_data->discardFlags & DiscardCanvasFrame ) )
     500    {
     501        layoutOptions |= QwtPlotLayout::IgnoreFrames;
     502    }
     503
     504
    433505    if ( d_data->discardFlags & DiscardLegend )
    434506        layoutOptions |= QwtPlotLayout::IgnoreLegend;
    435507
    436     const QRectF layoutRect = transform.inverted().mapRect( plotRect );
    437     plot->plotLayout()->activate( plot, layoutRect, layoutOptions );
    438 
     508    if ( d_data->discardFlags & DiscardTitle )
     509        layoutOptions |= QwtPlotLayout::IgnoreTitle;
     510
     511    if ( d_data->discardFlags & DiscardFooter )
     512        layoutOptions |= QwtPlotLayout::IgnoreFooter;
     513
     514    layout->activate( plot, layoutRect, layoutOptions );
     515
     516    // canvas
     517
     518    QwtScaleMap maps[QwtPlot::axisCnt];
     519    buildCanvasMaps( plot, layout->canvasRect(), maps );
     520    if ( updateCanvasMargins( plot, layout->canvasRect(), maps ) )
     521    {
     522        // recalculate maps and layout, when the margins
     523        // have been changed
     524
     525        layout->activate( plot, layoutRect, layoutOptions );
     526        buildCanvasMaps( plot, layout->canvasRect(), maps );
     527    }
     528
     529    // now start painting
     530
     531    painter->save();
    439532    painter->setWorldTransform( transform, true );
    440533
    441     // canvas
    442 
    443     QwtScaleMap maps[QwtPlot::axisCnt];
    444     buildCanvasMaps( plot, plot->plotLayout()->canvasRect(), maps );
    445     renderCanvas( plot, painter, plot->plotLayout()->canvasRect(), maps );
     534    renderCanvas( plot, painter, layout->canvasRect(), maps );
    446535
    447536    if ( !( d_data->discardFlags & DiscardTitle )
    448537        && ( !plot->titleLabel()->text().isEmpty() ) )
    449538    {
    450         renderTitle( plot, painter, plot->plotLayout()->titleRect() );
     539        renderTitle( plot, painter, layout->titleRect() );
     540    }
     541
     542    if ( !( d_data->discardFlags & DiscardFooter )
     543        && ( !plot->footerLabel()->text().isEmpty() ) )
     544    {
     545        renderFooter( plot, painter, layout->footerRect() );
    451546    }
    452547
     
    454549        && plot->legend() && !plot->legend()->isEmpty() )
    455550    {
    456         renderLegend( plot, painter, plot->plotLayout()->legendRect() );
    457     }
    458 
    459     for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
     551        renderLegend( plot, painter, layout->legendRect() );
     552    }
     553
     554    for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
    460555    {
    461556        QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
     
    468563
    469564            renderScale( plot, painter, axisId, startDist, endDist,
    470                 baseDist, plot->plotLayout()->scaleRect( axisId ) );
    471         }
    472     }
    473 
    474 
    475     plot->plotLayout()->invalidate();
    476 
    477     // reset all widgets with their original attributes.
    478     if ( d_data->layoutFlags & FrameWithScales )
    479     {
    480         // restore the previous base line dists
    481 
    482         for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
     565                baseDist, layout->scaleRect( axisId ) );
     566        }
     567    }
     568
     569    painter->restore();
     570
     571    // restore all setting to their original attributes.
     572    for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
     573    {
     574        if ( d_data->layoutFlags & FrameWithScales )
    483575        {
    484576            QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
     
    486578                scaleWidget->setMargin( baseLineDists[axisId] );
    487579        }
    488     }
    489 
    490     painter->restore();
     580
     581        layout->setCanvasMargin( canvasMargins[axisId] );
     582    }
     583
     584    layout->invalidate();
     585
    491586}
    492587
     
    511606
    512607/*!
    513   Render the legend into a given rectangle.
     608  Render the footer into a given rectangle.
    514609
    515610  \param plot Plot widget
     
    517612  \param rect Bounding rectangle
    518613*/
     614void QwtPlotRenderer::renderFooter( const QwtPlot *plot,
     615    QPainter *painter, const QRectF &rect ) const
     616{
     617    painter->setFont( plot->footerLabel()->font() );
     618
     619    const QColor color = plot->footerLabel()->palette().color(
     620            QPalette::Active, QPalette::Text );
     621
     622    painter->setPen( color );
     623    plot->footerLabel()->text().draw( painter, rect );
     624}
     625
     626
     627/*!
     628  Render the legend into a given rectangle.
     629
     630  \param plot Plot widget
     631  \param painter Painter
     632  \param rect Bounding rectangle
     633*/
    519634void QwtPlotRenderer::renderLegend( const QwtPlot *plot,
    520635    QPainter *painter, const QRectF &rect ) const
    521636{
    522     if ( !plot->legend() || plot->legend()->isEmpty() )
    523         return;
    524 
    525     if ( !( d_data->discardFlags & DiscardBackground ) )
    526     {
    527         if ( plot->legend()->autoFillBackground() ||
    528             plot->legend()->testAttribute( Qt::WA_StyledBackground ) )
    529         {
    530             qwtRenderBackground( painter, rect, plot->legend() );
    531         }
    532     }
    533 
    534     const QwtDynGridLayout *legendLayout = qobject_cast<QwtDynGridLayout *>(
    535         plot->legend()->contentsWidget()->layout() );
    536     if ( legendLayout == NULL )
    537         return;
    538 
    539     uint numCols = legendLayout->columnsForWidth( rect.width() );
    540     QList<QRect> itemRects =
    541         legendLayout->layoutItems( rect.toRect(), numCols );
    542 
    543     int index = 0;
    544 
    545     for ( int i = 0; i < legendLayout->count(); i++ )
    546     {
    547         QLayoutItem *item = legendLayout->itemAt( i );
    548         QWidget *w = item->widget();
    549         if ( w )
    550         {
    551             painter->save();
    552 
    553             painter->setClipRect( itemRects[index] );
    554             renderLegendItem( plot, painter, w, itemRects[index] );
    555 
    556             index++;
    557             painter->restore();
    558         }
    559     }
    560 }
    561 
    562 /*!
    563   Render the legend item into a given rectangle.
    564 
    565   \param plot Plot widget
    566   \param painter Painter
    567   \param widget Widget representing a legend item
    568   \param rect Bounding rectangle
    569 
    570   \note When widget is not derived from QwtLegendItem renderLegendItem
    571         does nothing and needs to be overloaded
    572 */
    573 void QwtPlotRenderer::renderLegendItem( const QwtPlot *plot,
    574     QPainter *painter, const QWidget *widget, const QRectF &rect ) const
    575 {
    576     if ( !( d_data->discardFlags & DiscardBackground ) )
    577     {
    578         if ( widget->autoFillBackground() ||
    579             widget->testAttribute( Qt::WA_StyledBackground ) )
    580         {
    581             qwtRenderBackground( painter, rect, widget );
    582         }
    583     }
    584 
    585     const QwtLegendItem *item = qobject_cast<const QwtLegendItem *>( widget );
    586     if ( item )
    587     {
    588         const QSize sz = item->identifierSize();
    589 
    590         const QRectF identifierRect( rect.x() + item->margin(),
    591             rect.center().y() - 0.5 * sz.height(), sz.width(), sz.height() );
    592 
    593         QwtLegendItemManager *itemManger = plot->legend()->find( item );
    594         if ( itemManger )
    595         {
    596             painter->save();
    597             painter->setClipRect( identifierRect, Qt::IntersectClip );
    598             itemManger->drawLegendIdentifier( painter, identifierRect );
    599             painter->restore();
    600         }
    601 
    602         // Label
    603 
    604         QRectF titleRect = rect;
    605         titleRect.setX( identifierRect.right() + 2 * item->spacing() );
    606 
    607         painter->setFont( item->font() );
    608         item->text().draw( painter, titleRect );
     637    if ( plot->legend() )
     638    {
     639        bool fillBackground = !( d_data->discardFlags & DiscardBackground );
     640        plot->legend()->renderLegend( painter, rect, fillBackground );
    609641    }
    610642}
     
    635667    {
    636668        scaleWidget->drawColorBar( painter, scaleWidget->colorBarRect( rect ) );
    637 
    638         const int off = scaleWidget->colorBarWidth() + scaleWidget->spacing();
    639         if ( scaleWidget->scaleDraw()->orientation() == Qt::Horizontal )
    640             baseDist += off;
    641         else
    642             baseDist += off;
     669        baseDist += scaleWidget->colorBarWidth() + scaleWidget->spacing();
    643670    }
    644671
     
    720747    const QwtScaleMap *map ) const
    721748{
    722     painter->save();
    723 
    724     QPainterPath clipPath;
     749    const QWidget *canvas = plot->canvas();
    725750
    726751    QRectF r = canvasRect.adjusted( 0.0, 0.0, -1.0, -1.0 );
     
    728753    if ( d_data->layoutFlags & FrameWithScales )
    729754    {
     755        painter->save();
     756
    730757        r.adjust( -1.0, -1.0, 1.0, 1.0 );
    731758        painter->setPen( QPen( Qt::black ) );
     
    734761        {
    735762            const QBrush bgBrush =
    736                 plot->canvas()->palette().brush( plot->backgroundRole() );
     763                canvas->palette().brush( plot->backgroundRole() );
    737764            painter->setBrush( bgBrush );
    738765        }
    739766
    740767        QwtPainter::drawRect( painter, r );
     768
     769        painter->restore();
     770        painter->save();
     771
     772        painter->setClipRect( canvasRect );
     773        plot->drawItems( painter, canvasRect, map );
     774
     775        painter->restore();
     776    }
     777    else if ( canvas->testAttribute( Qt::WA_StyledBackground ) )
     778    {
     779        QPainterPath clipPath;
     780
     781        painter->save();
     782
     783        if ( !( d_data->discardFlags & DiscardCanvasBackground ) )
     784        {
     785            QwtPainter::drawBackgound( painter, r, canvas );
     786            clipPath = qwtCanvasClip( canvas, canvasRect );
     787        }
     788
     789        painter->restore();
     790        painter->save();
     791
     792        if ( clipPath.isEmpty() )
     793            painter->setClipRect( canvasRect );
     794        else
     795            painter->setClipPath( clipPath );
     796
     797        plot->drawItems( painter, canvasRect, map );
     798
     799        painter->restore();
    741800    }
    742801    else
    743802    {
     803        QPainterPath clipPath;
     804
     805        int frameWidth = 0;
     806
     807        if ( !( d_data->discardFlags & DiscardCanvasFrame ) )
     808        {
     809            const QVariant fw = canvas->property( "frameWidth" );
     810            if ( fw.type() == QVariant::Int )
     811                frameWidth = fw.toInt();
     812
     813            clipPath = qwtCanvasClip( canvas, canvasRect );
     814        }
     815
     816        QRectF innerRect = canvasRect.adjusted(
     817            frameWidth, frameWidth, -frameWidth, -frameWidth );
     818
     819        painter->save();
     820
     821        if ( clipPath.isEmpty() )
     822        {
     823            painter->setClipRect( innerRect );
     824        }
     825        else
     826        {
     827            painter->setClipPath( clipPath );
     828        }
     829
    744830        if ( !( d_data->discardFlags & DiscardCanvasBackground ) )
    745831        {
    746             qwtRenderBackground( painter, r, plot->canvas() );
    747 
    748             if ( plot->canvas()->testAttribute( Qt::WA_StyledBackground ) )
     832            QwtPainter::drawBackgound( painter, innerRect, canvas );
     833        }
     834
     835        plot->drawItems( painter, innerRect, map );
     836
     837        painter->restore();
     838
     839        if ( frameWidth > 0 )
     840        {
     841            painter->save();
     842
     843            const int frameStyle =
     844                canvas->property( "frameShadow" ).toInt() |
     845                canvas->property( "frameShape" ).toInt();
     846
     847            const int frameWidth = canvas->property( "frameWidth" ).toInt();
     848
     849
     850            const QVariant borderRadius = canvas->property( "borderRadius" );
     851            if ( borderRadius.type() == QVariant::Double
     852                && borderRadius.toDouble() > 0.0 )
    749853            {
    750                 // The clip region is calculated in integers
    751                 // To avoid too much rounding errors better
    752                 // calculate it in target device resolution
    753                 // TODO ...
    754 
    755                 int x1 = qCeil( canvasRect.left() );
    756                 int x2 = qFloor( canvasRect.right() );
    757                 int y1 = qCeil( canvasRect.top() );
    758                 int y2 = qFloor( canvasRect.bottom() );
    759 
    760                 clipPath = plot->canvas()->borderPath(
    761                     QRect( x1, y1, x2 - x1 - 1, y2 - y1 - 1 ) );
     854                const double r = borderRadius.toDouble();
     855
     856                QwtPainter::drawRoundedFrame( painter, canvasRect,
     857                    r, r, canvas->palette(), frameWidth, frameStyle );
    762858            }
    763         }
    764     }
    765 
    766     painter->restore();
    767 
    768     painter->save();
    769 
    770     if ( clipPath.isEmpty() )
    771         painter->setClipRect( canvasRect );
    772     else
    773         painter->setClipPath( clipPath );
    774 
    775     plot->drawItems( painter, canvasRect, map );
    776 
    777     painter->restore();
     859            else
     860            {
     861                const int midLineWidth = canvas->property( "midLineWidth" ).toInt();
     862
     863                QwtPainter::drawFrame( painter, canvasRect,
     864                    canvas->palette(), canvas->foregroundRole(),
     865                    frameWidth, midLineWidth, frameStyle );
     866            }
     867            painter->restore();
     868        }
     869    }
    778870}
    779871
     
    793885            plot->axisScaleEngine( axisId )->transformation() );
    794886
    795         const QwtScaleDiv &scaleDiv = *plot->axisScaleDiv( axisId );
     887        const QwtScaleDiv &scaleDiv = plot->axisScaleDiv( axisId );
    796888        maps[axisId].setScaleInterval(
    797889            scaleDiv.lowerBound(), scaleDiv.upperBound() );
     
    802894            const int sDist = plot->axisWidget( axisId )->startBorderDist();
    803895            const int eDist = plot->axisWidget( axisId )->endBorderDist();
    804             const QRectF &scaleRect = plot->plotLayout()->scaleRect( axisId );
     896            const QRectF scaleRect = plot->plotLayout()->scaleRect( axisId );
    805897
    806898            if ( axisId == QwtPlot::xTop || axisId == QwtPlot::xBottom )
     
    817909        else
    818910        {
    819             int margin = plot->plotLayout()->canvasMargin( axisId );
     911            int margin = 0;
     912            if ( !plot->plotLayout()->alignCanvasToScale( axisId ) )
     913                margin = plot->plotLayout()->canvasMargin( axisId );
     914
    820915            if ( axisId == QwtPlot::yLeft || axisId == QwtPlot::yRight )
    821916            {
     
    832927    }
    833928}
     929
     930bool QwtPlotRenderer::updateCanvasMargins( QwtPlot *plot,
     931    const QRectF &canvasRect, const QwtScaleMap maps[] ) const
     932{
     933    double margins[QwtPlot::axisCnt];
     934    plot->getCanvasMarginsHint( maps, canvasRect,
     935        margins[QwtPlot::yLeft], margins[QwtPlot::xTop],
     936        margins[QwtPlot::yRight], margins[QwtPlot::xBottom] );
     937
     938    bool marginsChanged = false;
     939    for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
     940    {
     941        if ( margins[axisId] >= 0.0 )
     942        {
     943            const int m = qCeil( margins[axisId] );
     944            plot->plotLayout()->setCanvasMargin( m, axisId);
     945            marginsChanged = true;
     946        }
     947    }
     948
     949    return marginsChanged;
     950}
     951
     952/*!
     953   \brief Execute a file dialog and render the plot to the selected file
     954
     955   \param plot Plot widget
     956   \param documentName Default document name
     957   \param sizeMM Size for the document in millimeters.
     958   \param resolution Resolution in dots per Inch (dpi)
     959
     960   \return True, when exporting was successful
     961   \sa renderDocument()
     962*/
     963bool QwtPlotRenderer::exportTo( QwtPlot *plot, const QString &documentName,
     964     const QSizeF &sizeMM, int resolution )
     965{       
     966    if ( plot == NULL )
     967        return false;
     968   
     969    QString fileName = documentName;
     970
     971    // What about translation
     972
     973#ifndef QT_NO_FILEDIALOG
     974    const QList<QByteArray> imageFormats =
     975        QImageWriter::supportedImageFormats();
     976       
     977    QStringList filter;
     978#ifndef QT_NO_PRINTER
     979    filter += QString( "PDF " ) + tr( "Documents" ) + " (*.pdf)";
     980#endif
     981#ifndef QWT_NO_SVG
     982    filter += QString( "SVG " ) + tr( "Documents" ) + " (*.svg)";
     983#endif
     984#ifndef QT_NO_PRINTER
     985    filter += QString( "Postscript " ) + tr( "Documents" ) + " (*.ps)";
     986#endif
     987   
     988    if ( imageFormats.size() > 0 )
     989    {
     990        QString imageFilter( tr( "Images" ) );
     991        imageFilter += " (";
     992        for ( int i = 0; i < imageFormats.size(); i++ )
     993        {
     994            if ( i > 0 )
     995                imageFilter += " ";
     996            imageFilter += "*.";
     997            imageFilter += imageFormats[i];
     998        }   
     999        imageFilter += ")";
     1000       
     1001        filter += imageFilter;
     1002    }   
     1003   
     1004    fileName = QFileDialog::getSaveFileName(
     1005        NULL, tr( "Export File Name" ), fileName,
     1006        filter.join( ";;" ), NULL, QFileDialog::DontConfirmOverwrite );
     1007#endif 
     1008    if ( fileName.isEmpty() )
     1009        return false;
     1010
     1011    renderDocument( plot, fileName, sizeMM, resolution );
     1012
     1013    return true;
     1014}   
  • trunk/BNC/qwt/qwt_plot_renderer.h

    r4271 r8127  
    1313#include "qwt_global.h"
    1414#include <qobject.h>
     15#include <qsize.h>
    1516
    1617class QwtPlot;
    1718class QwtScaleMap;
    18 class QSizeF;
    1919class QRectF;
    2020class QPainter;
     
    5656
    5757        //! Don't render the background of the canvas
    58         DiscardCanvasBackground = 0x08
     58        DiscardCanvasBackground = 0x08,
     59
     60        //! Don't render the footer of the plot
     61        DiscardFooter           = 0x10,
     62
     63        /*!
     64            Don't render the frame of the canvas
     65
     66            \note This flag has no effect when using
     67                  style sheets, where the frame is part
     68                  of the background
     69         */
     70        DiscardCanvasFrame           = 0x20
     71
    5972    };
    6073
     
    6881    enum LayoutFlag
    6982    {
    70         //! Use the default layout without margins and frames
     83        //! Use the default layout as on screen
    7184        DefaultLayout   = 0x00,
    72 
    73         //! Render all frames of the plot
    74         KeepFrames      = 0x01,
    7585
    7686        /*!
     
    7888          where the scale ticks are aligned to.
    7989         */
    80         FrameWithScales = 0x02
     90        FrameWithScales = 0x01
    8191    };
    8292
     
    99109    LayoutFlags layoutFlags() const;
    100110
    101     void renderDocument( QwtPlot *, const QString &format,
     111    void renderDocument( QwtPlot *, const QString &fileName,
    102112        const QSizeF &sizeMM, int resolution = 85 );
    103113
    104114    void renderDocument( QwtPlot *,
    105         const QString &title, const QString &format,
     115        const QString &fileName, const QString &format,
    106116        const QSizeF &sizeMM, int resolution = 85 );
    107117
     
    123133        QPainter *, const QRectF &rect ) const;
    124134
    125     virtual void renderLegendItem( const QwtPlot *,
    126         QPainter *, const QWidget *, const QRectF & ) const;
     135    virtual void renderTitle( const QwtPlot *,
     136        QPainter *, const QRectF & ) const;
    127137
    128     virtual void renderTitle( const QwtPlot *,
     138    virtual void renderFooter( const QwtPlot *,
    129139        QPainter *, const QRectF & ) const;
    130140
     
    140150        const QwtPlot *, QPainter *, const QRectF & ) const;
    141151
    142 protected:
     152    bool exportTo( QwtPlot *, const QString &documentName,
     153        const QSizeF &sizeMM = QSizeF( 300, 200 ), int resolution = 85 );
     154
     155private:
    143156    void buildCanvasMaps( const QwtPlot *,
    144157        const QRectF &, QwtScaleMap maps[] ) const;
     158
     159    bool updateCanvasMargins( QwtPlot *,
     160        const QRectF &, const QwtScaleMap maps[] ) const;
    145161
    146162private:
  • trunk/BNC/qwt/qwt_plot_rescaler.cpp

    r4271 r8127  
    1010#include "qwt_plot_rescaler.h"
    1111#include "qwt_plot.h"
    12 #include "qwt_plot_canvas.h"
    1312#include "qwt_scale_div.h"
    1413#include "qwt_interval.h"
     14#include "qwt_plot_canvas.h"
    1515#include <qevent.h>
    1616#include <qalgorithms.h>
     
    5959   \sa setRescalePolicy(), setReferenceAxis()
    6060*/
    61 QwtPlotRescaler::QwtPlotRescaler( QwtPlotCanvas *canvas,
     61QwtPlotRescaler::QwtPlotRescaler( QWidget *canvas,
    6262        int referenceAxis, RescalePolicy policy ):
    6363    QObject( canvas )
     
    179179
    180180/*!
    181   Return direction in which an axis should be expanded
     181  \return Direction in which an axis should be expanded
    182182
    183183  \param axis Axis index ( see QwtPlot::AxisId )
     
    224224
    225225/*!
    226   Return aspect ratio between an axis and the reference axis.
     226  \return Aspect ratio between an axis and the reference axis.
    227227
    228228  \param axis Axis index ( see QwtPlot::AxisId )
     
    241241
    242242  In Fitting mode, the hint is used as minimal interval
    243   taht always needs to be displayed.
     243  that always needs to be displayed.
    244244
    245245  \param axis Axis, see QwtPlot::Axis
     
    268268
    269269//! \return plot canvas
    270 QwtPlotCanvas *QwtPlotRescaler::canvas()
    271 {
    272     return qobject_cast<QwtPlotCanvas *>( parent() );
     270QWidget *QwtPlotRescaler::canvas()
     271{
     272    return qobject_cast<QWidget *>( parent() );
    273273}
    274274
    275275//! \return plot canvas
    276 const QwtPlotCanvas *QwtPlotRescaler::canvas() const
    277 {
    278     return qobject_cast<const QwtPlotCanvas *>( parent() );
     276const QWidget *QwtPlotRescaler::canvas() const
     277{
     278    return qobject_cast<const QWidget *>( parent() );
    279279}
    280280
     
    282282QwtPlot *QwtPlotRescaler::plot()
    283283{
    284     QwtPlotCanvas *w = canvas();
     284    QWidget *w = canvas();
    285285    if ( w )
    286         return w->plot();
    287 
    288     return NULL;
     286        w = w->parentWidget();
     287
     288    return qobject_cast<QwtPlot *>( w );
    289289}
    290290
     
    292292const QwtPlot *QwtPlotRescaler::plot() const
    293293{
    294     const QwtPlotCanvas *w = canvas();
     294    const QWidget *w = canvas();
    295295    if ( w )
    296         return w->plot();
    297 
    298     return NULL;
     296        w = w->parentWidget();
     297
     298    return qobject_cast<const QwtPlot *>( w );
    299299}
    300300
    301301//!  Event filter for the plot canvas
    302 bool QwtPlotRescaler::eventFilter( QObject *o, QEvent *e )
    303 {
    304     if ( o && o == canvas() )
    305     {
    306         switch ( e->type() )
     302bool QwtPlotRescaler::eventFilter( QObject *object, QEvent *event )
     303{
     304    if ( object && object == canvas() )
     305    {
     306        switch ( event->type() )
    307307        {
    308308            case QEvent::Resize:
    309                 canvasResizeEvent( ( QResizeEvent * )e );
     309            {
     310                canvasResizeEvent( static_cast<QResizeEvent *>( event ) );
    310311                break;
     312            }
    311313            case QEvent::PolishRequest:
     314            {
    312315                rescale();
    313316                break;
     317            }
    314318            default:;
    315319        }
     
    327331void QwtPlotRescaler::canvasResizeEvent( QResizeEvent* event )
    328332{
    329     const int fw = 2 * canvas()->frameWidth();
    330     const QSize newSize = event->size() - QSize( fw, fw );
    331     const QSize oldSize = event->oldSize() - QSize( fw, fw );
     333    int left, top, right, bottom;
     334    canvas()->getContentsMargins( &left, &top, &right, &bottom );
     335
     336    const QSize marginSize( left + right, top + bottom );
     337
     338    const QSize newSize = event->size() - marginSize;
     339    const QSize oldSize = event->oldSize() - marginSize;
    332340
    333341    rescale( oldSize, newSize );
     
    433441
    434442/*!
    435    Synchronize an axis scale according to the scale of the reference axis
     443  Synchronize an axis scale according to the scale of the reference axis
    436444
    437445  \param axis Axis index ( see QwtPlot::AxisId )
    438446  \param reference Interval of the reference axis
    439447  \param size Size of the canvas
     448
     449  \return New interval for axis
    440450*/
    441451QwtInterval QwtPlotRescaler::syncScale( int axis,
     
    467477
    468478/*!
    469   Return orientation of an axis
     479  \return Orientation of an axis
    470480  \param axis Axis index ( see QwtPlot::AxisId )
    471481*/
     
    479489
    480490/*!
    481   Return interval of an axis
    482   \param axis Axis index ( see QwtPlot::AxisId )
     491  \param axis Axis index ( see QwtPlot::AxisId )
     492  \return Normalized interval of an axis
    483493*/
    484494QwtInterval QwtPlotRescaler::interval( int axis ) const
     
    487497        return QwtInterval();
    488498
    489     const QwtPlot *plt = plot();
    490 
    491     const double v1 = plt->axisScaleDiv( axis )->lowerBound();
    492     const double v2 = plt->axisScaleDiv( axis )->upperBound();
    493 
    494     return QwtInterval( v1, v2 ).normalized();
     499    return plot()->axisScaleDiv( axis ).interval().normalized();
    495500}
    496501
     
    584589            double v2 = intervals[axis].maxValue();
    585590
    586             if ( plt->axisScaleDiv( axis )->lowerBound() >
    587                 plt->axisScaleDiv( axis )->upperBound() )
    588             {
     591            if ( !plt->axisScaleDiv( axis ).isIncreasing() )
    589592                qSwap( v1, v2 );
    590             }
    591593
    592594            if ( d_data->inReplot >= 1 )
    593             {
    594                 d_data->axisData[axis].scaleDiv = *plt->axisScaleDiv( axis );
    595             }
     595                d_data->axisData[axis].scaleDiv = plt->axisScaleDiv( axis );
    596596
    597597            if ( d_data->inReplot >= 2 )
     
    610610    }
    611611
    612     const bool immediatePaint =
    613         plt->canvas()->testPaintAttribute( QwtPlotCanvas::ImmediatePaint );
    614     plt->canvas()->setPaintAttribute( QwtPlotCanvas::ImmediatePaint, false );
     612    QwtPlotCanvas *canvas = qobject_cast<QwtPlotCanvas *>( plt->canvas() );
     613
     614    bool immediatePaint = false;
     615    if ( canvas )
     616    {
     617        immediatePaint = canvas->testPaintAttribute( QwtPlotCanvas::ImmediatePaint );
     618        canvas->setPaintAttribute( QwtPlotCanvas::ImmediatePaint, false );
     619    }
    615620
    616621    plt->setAutoReplot( doReplot );
     
    620625    d_data->inReplot--;
    621626
    622     plt->canvas()->setPaintAttribute(
    623         QwtPlotCanvas::ImmediatePaint, immediatePaint );
    624 }
     627    if ( canvas && immediatePaint )
     628    {
     629        canvas->setPaintAttribute( QwtPlotCanvas::ImmediatePaint, true );
     630    }
     631}
  • trunk/BNC/qwt/qwt_plot_rescaler.h

    r4271 r8127  
    1616#include <qobject.h>
    1717
    18 class QwtPlotCanvas;
    1918class QwtPlot;
    2019class QResizeEvent;
     
    2322    \brief QwtPlotRescaler takes care of fixed aspect ratios for plot scales
    2423
    25     QwtPlotRescaler autoadjusts the axes of a QwtPlot according
     24    QwtPlotRescaler auto adjusts the axes of a QwtPlot according
    2625    to fixed aspect ratios.
    2726*/
     
    4645
    4746        /*!
    48           The interval of the reference axis will be shrinked/expanded,
     47          The interval of the reference axis will be shrunk/expanded,
    4948          when the geometry of the canvas changes. All other axes
    5049          will be adjusted according to their aspect ratio.
     
    7877    };
    7978
    80     explicit QwtPlotRescaler( QwtPlotCanvas *,
     79    explicit QwtPlotRescaler( QWidget *canvas,
    8180        int referenceAxis = QwtPlot::xBottom,
    8281        RescalePolicy = Expanding );
     
    104103    QwtInterval intervalHint( int axis ) const;
    105104
    106     QwtPlotCanvas *canvas();
    107     const QwtPlotCanvas *canvas() const;
     105    QWidget *canvas();
     106    const QWidget *canvas() const;
    108107
    109108    QwtPlot *plot();
  • trunk/BNC/qwt/qwt_plot_scaleitem.cpp

    r4271 r8127  
    1010#include "qwt_plot_scaleitem.h"
    1111#include "qwt_plot.h"
    12 #include "qwt_plot_canvas.h"
    1312#include "qwt_scale_map.h"
    1413#include "qwt_interval.h"
     
    3231    }
    3332
    34     void updateBorders( const QRectF &,
    35         const QwtScaleMap &, const QwtScaleMap & );
     33    QwtInterval scaleInterval( const QRectF &,
     34        const QwtScaleMap &, const QwtScaleMap & ) const;
    3635
    3736    QPalette palette;
     
    4140    bool scaleDivFromAxis;
    4241    QwtScaleDraw *scaleDraw;
    43     QRectF canvasRectCache;
    4442};
    4543
    46 void QwtPlotScaleItem::PrivateData::updateBorders( const QRectF &canvasRect,
    47     const QwtScaleMap &xMap, const QwtScaleMap &yMap )
    48 {
    49     canvasRectCache = canvasRect;
    50 
     44QwtInterval QwtPlotScaleItem::PrivateData::scaleInterval( const QRectF &canvasRect,
     45    const QwtScaleMap &xMap, const QwtScaleMap &yMap ) const
     46{
    5147    QwtInterval interval;
    5248    if ( scaleDraw->orientation() == Qt::Horizontal )
     
    6157    }
    6258
    63     QwtScaleDiv scaleDiv = scaleDraw->scaleDiv();
    64     scaleDiv.setInterval( interval );
    65     scaleDraw->setScaleDiv( scaleDiv );
    66 }
     59    return interval;
     60}
     61
    6762/*!
    6863   \brief Constructor for scale item at the position pos.
     
    8479    d_data->scaleDraw->setAlignment( alignment );
    8580
     81    setItemInterest( QwtPlotItem::ScaleInterest, true );
    8682    setZ( 11.0 );
    8783}
     
    137133            if ( plt )
    138134            {
    139                 updateScaleDiv( *plt->axisScaleDiv( xAxis() ),
    140                     *plt->axisScaleDiv( yAxis() ) );
     135                updateScaleDiv( plt->axisScaleDiv( xAxis() ),
     136                    plt->axisScaleDiv( yAxis() ) );
    141137                itemChanged();
    142138            }
     
    164160    {
    165161        d_data->palette = palette;
     162
     163        legendChanged();
    166164        itemChanged();
    167165    }
     
    223221    if ( plt )
    224222    {
    225         updateScaleDiv( *plt->axisScaleDiv( xAxis() ),
    226             *plt->axisScaleDiv( yAxis() ) );
     223        updateScaleDiv( plt->axisScaleDiv( xAxis() ),
     224            plt->axisScaleDiv( yAxis() ) );
    227225    }
    228226
     
    282280
    283281   If distance is >= 0 the scale will be aligned to a
    284    border of the contents rect of the canvas. If
     282   border of the contents rectangle of the canvas. If
    285283   alignment() is QwtScaleDraw::LeftScale, the scale will
    286284   be aligned to the right border, if it is QwtScaleDraw::TopScale
     
    348346    const QRectF &canvasRect ) const
    349347{
     348    QwtScaleDraw *sd = d_data->scaleDraw;
     349
    350350    if ( d_data->scaleDivFromAxis )
    351351    {
    352         if ( canvasRect != d_data->canvasRectCache )
    353             d_data->updateBorders( canvasRect, xMap, yMap );
     352        const QwtInterval interval =
     353            d_data->scaleInterval( canvasRect, xMap, yMap );
     354
     355        if ( interval != sd->scaleDiv().interval() )
     356        {
     357            QwtScaleDiv scaleDiv = sd->scaleDiv();
     358            scaleDiv.setInterval( interval );
     359            sd->setScaleDiv( scaleDiv );
     360        }
    354361    }
    355362
     
    358365    painter->setPen( pen );
    359366
    360     QwtScaleDraw *sd = d_data->scaleDraw;
    361367    if ( sd->orientation() == Qt::Horizontal )
    362368    {
     
    382388        sd->move( canvasRect.left(), y );
    383389        sd->setLength( canvasRect.width() - 1 );
    384         sd->setTransformation( xMap.transformation()->copy() );
     390
     391        QwtTransform *transform = NULL;
     392        if ( xMap.transformation() )
     393            transform = xMap.transformation()->copy();
     394
     395        sd->setTransformation( transform );
    385396    }
    386397    else // == Qt::Vertical
     
    405416        sd->move( x, canvasRect.top() );
    406417        sd->setLength( canvasRect.height() - 1 );
    407         sd->setTransformation( yMap.transformation()->copy() );
     418
     419        QwtTransform *transform = NULL;
     420        if ( yMap.transformation() )
     421            transform = yMap.transformation()->copy();
     422
     423        sd->setTransformation( transform );
    408424    }
    409425
     
    428444    const QwtScaleDiv& yScaleDiv )
    429445{
    430     QwtScaleDraw *sd = d_data->scaleDraw;
    431     if ( d_data->scaleDivFromAxis && sd )
    432     {
    433         sd->setScaleDiv(
    434             sd->orientation() == Qt::Horizontal ? xScaleDiv : yScaleDiv );
     446    QwtScaleDraw *scaleDraw = d_data->scaleDraw;
     447
     448    if ( d_data->scaleDivFromAxis && scaleDraw )
     449    {
     450        const QwtScaleDiv &scaleDiv =
     451            scaleDraw->orientation() == Qt::Horizontal ? xScaleDiv : yScaleDiv;
    435452
    436453        const QwtPlot *plt = plot();
    437454        if ( plt != NULL )
    438455        {
    439             d_data->updateBorders( plt->canvas()->contentsRect(),
    440                 plt->canvasMap( xAxis() ), plt->canvasMap( yAxis() ) );
    441         }
    442     }
    443 }
     456            const QRectF canvasRect = plt->canvas()->contentsRect();
     457
     458            const QwtInterval interval = d_data->scaleInterval(
     459                canvasRect, plt->canvasMap( xAxis() ), plt->canvasMap( yAxis() ) );
     460
     461            QwtScaleDiv sd = scaleDiv;
     462            sd.setInterval( interval );
     463
     464            if ( sd != scaleDraw->scaleDiv() )
     465            {
     466                // the internal label cache of QwtScaleDraw
     467                // is cleared here, so better avoid pointless
     468                // assignments.
     469
     470                scaleDraw->setScaleDiv( sd );
     471            }
     472        }
     473        else
     474        {
     475            scaleDraw->setScaleDiv( scaleDiv );
     476        }
     477    }
     478}
  • trunk/BNC/qwt/qwt_plot_seriesitem.cpp

    r4271 r8127  
    1010#include "qwt_plot_seriesitem.h"
    1111
    12 class QwtPlotAbstractSeriesItem::PrivateData
     12class QwtPlotSeriesItem::PrivateData
    1313{
    1414public:
     
    2525  \param title Title of the curve
    2626*/
    27 QwtPlotAbstractSeriesItem::QwtPlotAbstractSeriesItem( const QwtText &title ):
     27QwtPlotSeriesItem::QwtPlotSeriesItem( const QwtText &title ):
    2828    QwtPlotItem( title )
    2929{
    3030    d_data = new PrivateData();
     31    setItemInterest( QwtPlotItem::ScaleInterest, true );
    3132}
    3233
     
    3536  \param title Title of the curve
    3637*/
    37 QwtPlotAbstractSeriesItem::QwtPlotAbstractSeriesItem( const QString &title ):
     38QwtPlotSeriesItem::QwtPlotSeriesItem( const QString &title ):
    3839    QwtPlotItem( QwtText( title ) )
    3940{
     
    4243
    4344//! Destructor
    44 QwtPlotAbstractSeriesItem::~QwtPlotAbstractSeriesItem()
     45QwtPlotSeriesItem::~QwtPlotSeriesItem()
    4546{
    4647    delete d_data;
     
    5657  \sa orientation()
    5758*/
    58 void QwtPlotAbstractSeriesItem::setOrientation( Qt::Orientation orientation )
     59void QwtPlotSeriesItem::setOrientation( Qt::Orientation orientation )
    5960{
    6061    if ( d_data->orientation != orientation )
    6162    {
    6263        d_data->orientation = orientation;
     64
     65        legendChanged();
    6366        itemChanged();
    6467    }
     
    6972  \sa setOrientation()
    7073*/
    71 Qt::Orientation QwtPlotAbstractSeriesItem::orientation() const
     74Qt::Orientation QwtPlotSeriesItem::orientation() const
    7275{
    7376    return d_data->orientation;
     
    8083  \param xMap Maps x-values into pixel coordinates.
    8184  \param yMap Maps y-values into pixel coordinates.
    82   \param canvasRect Contents rect of the canvas
     85  \param canvasRect Contents rectangle of the canvas
    8386*/
    84 void QwtPlotAbstractSeriesItem::draw( QPainter *painter,
     87void QwtPlotSeriesItem::draw( QPainter *painter,
    8588        const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    8689        const QRectF &canvasRect ) const
     
    8992}
    9093
     94QRectF QwtPlotSeriesItem::boundingRect() const
     95{
     96    return dataRect();
     97}
     98
     99void QwtPlotSeriesItem::updateScaleDiv(
     100    const QwtScaleDiv &xScaleDiv, const QwtScaleDiv &yScaleDiv )
     101{   
     102    const QRectF rect = QRectF(
     103        xScaleDiv.lowerBound(), yScaleDiv.lowerBound(),
     104        xScaleDiv.range(), yScaleDiv.range() );
     105       
     106    setRectOfInterest( rect );
     107}   
     108
     109void QwtPlotSeriesItem::dataChanged()
     110{
     111    itemChanged();
     112}
  • trunk/BNC/qwt/qwt_plot_seriesitem.h

    r4271 r8127  
    1515#include "qwt_scale_div.h"
    1616#include "qwt_series_data.h"
     17#include "qwt_series_store.h"
    1718
    1819/*!
    1920  \brief Base class for plot items representing a series of samples
    2021*/
    21 class QWT_EXPORT QwtPlotAbstractSeriesItem: public QwtPlotItem
     22class QWT_EXPORT QwtPlotSeriesItem: public QwtPlotItem,
     23    public virtual QwtAbstractSeriesStore
    2224{
    2325public:
    24     explicit QwtPlotAbstractSeriesItem( const QString &title = QString::null );
    25     explicit QwtPlotAbstractSeriesItem( const QwtText &title );
     26    explicit QwtPlotSeriesItem( const QString &title = QString::null );
     27    explicit QwtPlotSeriesItem( const QwtText &title );
    2628
    27     virtual ~QwtPlotAbstractSeriesItem();
     29    virtual ~QwtPlotSeriesItem();
    2830
    2931    void setOrientation( Qt::Orientation );
     
    4042      \param xMap Maps x-values into pixel coordinates.
    4143      \param yMap Maps y-values into pixel coordinates.
    42       \param canvasRect Contents rect of the canvas
     44      \param canvasRect Contents rectangle of the canvas
    4345      \param from Index of the first point to be painted
    4446      \param to Index of the last point to be painted. If to < 0 the
     
    4951        const QRectF &canvasRect, int from, int to ) const = 0;
    5052
     53    virtual QRectF boundingRect() const;
     54
     55    virtual void updateScaleDiv(
     56        const QwtScaleDiv &, const QwtScaleDiv & );
     57
     58protected:
     59    virtual void dataChanged();
     60
    5161private:
    5262    class PrivateData;
     
    5464};
    5565
    56 /*!
    57   \brief Class template for plot items representing a series of samples
    58 */
    59 template <typename T>
    60 class QwtPlotSeriesItem: public QwtPlotAbstractSeriesItem
    61 {
    62 public:
    63     explicit QwtPlotSeriesItem<T>( const QString &title = QString::null );
    64     explicit QwtPlotSeriesItem<T>( const QwtText &title );
    65 
    66     virtual ~QwtPlotSeriesItem<T>();
    67 
    68     void setData( QwtSeriesData<T> * );
    69 
    70     QwtSeriesData<T> *data();
    71     const QwtSeriesData<T> *data() const;
    72 
    73     size_t dataSize() const;
    74     T sample( int index ) const;
    75 
    76     virtual QRectF boundingRect() const;
    77     virtual void updateScaleDiv( const QwtScaleDiv &,
    78                                  const QwtScaleDiv & );
    79 
    80 protected:
    81     //! Series
    82     QwtSeriesData<T> *d_series;
    83 };
    84 
    85 /*!
    86   Constructor
    87   \param title Title of the series item
    88 */
    89 template <typename T>
    90 QwtPlotSeriesItem<T>::QwtPlotSeriesItem( const QString &title ):
    91     QwtPlotAbstractSeriesItem( QwtText( title ) ),
    92     d_series( NULL )
    93 {
    94 }
    95 
    96 /*!
    97   Constructor
    98   \param title Title of the series item
    99 */
    100 template <typename T>
    101 QwtPlotSeriesItem<T>::QwtPlotSeriesItem( const QwtText &title ):
    102     QwtPlotAbstractSeriesItem( title ),
    103     d_series( NULL )
    104 {
    105 }
    106 
    107 //! Destructor
    108 template <typename T>
    109 QwtPlotSeriesItem<T>::~QwtPlotSeriesItem()
    110 {
    111     delete d_series;
    112 }
    113 
    114 //! \return the the curve data
    115 template <typename T>
    116 inline QwtSeriesData<T> *QwtPlotSeriesItem<T>::data()
    117 {
    118     return d_series;
    119 }
    120 
    121 //! \return the the curve data
    122 template <typename T>
    123 inline const QwtSeriesData<T> *QwtPlotSeriesItem<T>::data() const
    124 {
    125     return d_series;
    126 }
    127 
    128 /*!
    129     \param index Index
    130     \return Sample at position index
    131 */
    132 template <typename T>
    133 inline T QwtPlotSeriesItem<T>::sample( int index ) const
    134 {
    135     return d_series ? d_series->sample( index ) : T();
    136 }
    137 
    138 /*!
    139   Assign a series of samples
    140 
    141   \param data Data
    142   \warning The item takes ownership of the data object, deleting
    143            it when its not used anymore.
    144 */
    145 template <typename T>
    146 void QwtPlotSeriesItem<T>::setData( QwtSeriesData<T> *data )
    147 {
    148     if ( d_series != data )
    149     {
    150         delete d_series;
    151         d_series = data;
    152         itemChanged();
    153     }
    154 }
    155 
    156 /*!
    157   Return the size of the data arrays
    158   \sa setData()
    159 */
    160 template <typename T>
    161 size_t QwtPlotSeriesItem<T>::dataSize() const
    162 {
    163     if ( d_series == NULL )
    164         return 0;
    165 
    166     return d_series->size();
    167 }
    168 
    169 /*!
    170   \return Bounding rectangle of the data.
    171   If there is no bounding rect, like for empty data the rectangle is invalid.
    172 
    173   \sa QwtSeriesData<T>::boundingRect(), QRectF::isValid()
    174 */
    175 template <typename T>
    176 QRectF QwtPlotSeriesItem<T>::boundingRect() const
    177 {
    178     if ( d_series == NULL )
    179         return QRectF( 1.0, 1.0, -2.0, -2.0 ); // invalid
    180 
    181     return d_series->boundingRect();
    182 }
    183 
    184 /*!
    185    Update the rect of interest according to the current scale ranges
    186 
    187    \param xScaleDiv Scale division of the x-axis
    188    \param yScaleDiv Scale division of the y-axis
    189 
    190    \sa QwtSeriesData<T>::setRectOfInterest()
    191 */
    192 template <typename T>
    193 void QwtPlotSeriesItem<T>::updateScaleDiv(
    194     const QwtScaleDiv &xScaleDiv, const QwtScaleDiv &yScaleDiv )
    195 {
    196     const QRectF rect = QRectF(
    197         xScaleDiv.lowerBound(), yScaleDiv.lowerBound(),
    198         xScaleDiv.range(), yScaleDiv.range() );
    199 
    200     d_series->setRectOfInterest( rect );
    201 }
    202 
    20366#endif
  • trunk/BNC/qwt/qwt_plot_spectrocurve.cpp

    r4271 r8127  
    4242*/
    4343QwtPlotSpectroCurve::QwtPlotSpectroCurve( const QwtText &title ):
    44     QwtPlotSeriesItem<QwtPoint3D>( title )
     44    QwtPlotSeriesItem( title )
    4545{
    4646    init();
     
    5252*/
    5353QwtPlotSpectroCurve::QwtPlotSpectroCurve( const QString &title ):
    54     QwtPlotSeriesItem<QwtPoint3D>( QwtText( title ) )
     54    QwtPlotSeriesItem( QwtText( title ) )
    5555{
    5656    init();
     
    7272
    7373    d_data = new PrivateData;
    74     d_series = new QwtPoint3DSeriesData();
     74    setData( new QwtPoint3DSeriesData() );
    7575
    7676    setZ( 20.0 );
     
    9999
    100100/*!
    101     \brief Return the current paint attributes
     101    \return True, when attribute is enabled
    102102    \sa PaintAttribute, setPaintAttribute()
    103103*/
     
    113113void QwtPlotSpectroCurve::setSamples( const QVector<QwtPoint3D> &samples )
    114114{
    115     delete d_series;
    116     d_series = new QwtPoint3DSeriesData( samples );
    117     itemChanged();
    118 }
     115    setData( new QwtPoint3DSeriesData( samples ) );
     116}
     117
     118/*!
     119  Assign a series of samples
     120   
     121  setSamples() is just a wrapper for setData() without any additional
     122  value - beside that it is easier to find for the developer.
     123   
     124  \param data Data
     125  \warning The item takes ownership of the data object, deleting
     126           it when its not used anymore.
     127*/
     128void QwtPlotSpectroCurve::setSamples(
     129    QwtSeriesData<QwtPoint3D> *data )
     130{
     131    setData( data );
     132
    119133
    120134/*!
     
    137151    }
    138152
     153    legendChanged();
    139154    itemChanged();
    140155}
     
    162177    {
    163178        d_data->colorRange = interval;
     179
     180        legendChanged();
    164181        itemChanged();
    165182    }
     
    189206    {
    190207        d_data->penWidth = penWidth;
     208
     209        legendChanged();
    191210        itemChanged();
    192211    }
     
    208227  \param xMap Maps x-values into pixel coordinates.
    209228  \param yMap Maps y-values into pixel coordinates.
    210   \param canvasRect Contents rect of the canvas
     229  \param canvasRect Contents rectangle of the canvas
    211230  \param from Index of the first sample to be painted
    212231  \param to Index of the last sample to be painted. If to < 0 the
     
    228247        from = 0;
    229248
    230     if ( from >= to )
     249    if ( from > to )
    231250        return;
    232251
     
    240259  \param xMap Maps x-values into pixel coordinates.
    241260  \param yMap Maps y-values into pixel coordinates.
    242   \param canvasRect Contents rect of the canvas
     261  \param canvasRect Contents rectangle of the canvas
    243262  \param from Index of the first sample to be painted
    244263  \param to Index of the last sample to be painted. If to < 0 the
     
    260279        d_data->colorTable = d_data->colorMap->colorTable( d_data->colorRange );
    261280
     281    const QwtSeriesData<QwtPoint3D> *series = data();
     282
    262283    for ( int i = from; i <= to; i++ )
    263284    {
    264         const QwtPoint3D sample = d_series->sample( i );
     285        const QwtPoint3D sample = series->sample( i );
    265286
    266287        double xi = xMap.transform( sample.x() );
     
    283304                d_data->colorRange, sample.z() );
    284305
    285             painter->setPen( QPen( QColor( rgb ), d_data->penWidth ) );
     306            painter->setPen( QPen( QColor::fromRgba( rgb ), d_data->penWidth ) );
    286307        }
    287308        else
     
    290311                d_data->colorRange, sample.z() );
    291312
    292             painter->setPen( QPen( QColor( d_data->colorTable[index] ),
     313            painter->setPen( QPen( QColor::fromRgba( d_data->colorTable[index] ),
    293314                d_data->penWidth ) );
    294315        }
  • trunk/BNC/qwt/qwt_plot_spectrocurve.h

    r4271 r8127  
    2222           mapped to a color.
    2323*/
    24 class QWT_EXPORT QwtPlotSpectroCurve: public QwtPlotSeriesItem<QwtPoint3D>
     24class QWT_EXPORT QwtPlotSpectroCurve:
     25    public QwtPlotSeriesItem, QwtSeriesStore<QwtPoint3D>
    2526{
    2627public:
     
    4647
    4748    void setSamples( const QVector<QwtPoint3D> & );
     49    void setSamples( QwtSeriesData<QwtPoint3D> * );
     50
    4851
    4952    void setColorMap( QwtColorMap * );
  • trunk/BNC/qwt/qwt_plot_spectrogram.cpp

    r4271 r8127  
    2424#endif
    2525
     26#define DEBUG_RENDER 0
     27
     28#if DEBUG_RENDER
     29#include <QElapsedTimer>
     30#endif
     31
    2632class QwtPlotSpectrogram::PrivateData
    2733{
    2834public:
    2935    PrivateData():
    30         data( NULL ),
    31         renderThreadCount( 1 )
     36        data( NULL )
    3237    {
    3338        colorMap = new QwtLinearColorMap();
     
    3540
    3641        conrecFlags = QwtRasterData::IgnoreAllVerticesOnLevel;
     42#if 0
    3743        conrecFlags |= QwtRasterData::IgnoreOutOfRange;
     44#endif
    3845    }
    3946    ~PrivateData()
     
    4653    QwtColorMap *colorMap;
    4754    DisplayModes displayMode;
    48 
    49     uint renderThreadCount;
    5055
    5156    QList<double> contourLevels;
     
    108113    }
    109114
     115    legendChanged();
    110116    itemChanged();
    111117}
     
    123129
    124130/*!
    125    Rendering an image from the raster data can often be done
    126    parallel on a multicore system.
    127 
    128    \param numThreads Number of threads to be used for rendering.
    129                      If numThreads is set to 0, the system specific
    130                      ideal thread count is used.
    131 
    132    The default thread count is 1 ( = no additional threads )
    133 
    134    \warning Rendering in multiple threads is only supported for Qt >= 4.4
    135    \sa renderThreadCount(), renderImage(), renderTile()
    136 */
    137 void QwtPlotSpectrogram::setRenderThreadCount( uint numThreads )
    138 {
    139     d_data->renderThreadCount = numThreads;
    140 }
    141 
    142 /*!
    143    \return Number of threads to be used for rendering.
    144            If numThreads is set to 0, the system specific
    145            ideal thread count is used.
    146 
    147    \warning Rendering in multiple threads is only supported for Qt >= 4.4
    148    \sa setRenderThreadCount(), renderImage(), renderTile()
    149 */
    150 uint QwtPlotSpectrogram::renderThreadCount() const
    151 {
    152     return d_data->renderThreadCount;
    153 }
    154 
    155 /*!
    156131  Change the color map
    157132
     
    173148
    174149    invalidateCache();
     150
     151    legendChanged();
    175152    itemChanged();
    176153}
     
    183160{
    184161    return d_data->colorMap;
     162}
     163
     164/*!
     165  Build and assign the default pen for the contour lines
     166   
     167  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     168  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     169  to hide this incompatibility.
     170   
     171  \param color Pen color
     172  \param width Pen width
     173  \param style Pen style
     174   
     175  \sa pen(), brush()
     176 */
     177void QwtPlotSpectrogram::setDefaultContourPen(
     178    const QColor &color, qreal width, Qt::PenStyle style )
     179{   
     180    setDefaultContourPen( QPen( color, width, style ) );
    185181}
    186182
     
    200196    {
    201197        d_data->defaultContourPen = pen;
     198
     199        legendChanged();
    202200        itemChanged();
    203201    }
     
    266264   \return true, is enabled
    267265
     266   The default setting enables QwtRasterData::IgnoreAllVerticesOnLevel
     267
    268268   \sa setConrecClag(), renderContourLines(),
    269269       QwtRasterData::contourLines()
     
    288288    d_data->contourLevels = levels;
    289289    qSort( d_data->contourLevels );
     290
     291    legendChanged();
    290292    itemChanged();
    291293}
    292294
    293295/*!
    294    \brief Return the levels of the contour lines.
     296   \return Levels of the contour lines.
    295297
    296298   The levels are sorted in increasing order.
     
    384386   \brief Render an image from data and color map.
    385387
    386    For each pixel of rect the value is mapped into a color.
     388   For each pixel of area the value is mapped into a color.
    387389
    388390  \param xMap X-Scale Map
     
    421423    d_data->data->initRaster( area, image.size() );
    422424
     425#if DEBUG_RENDER
     426        QElapsedTimer time;
     427        time.start();
     428#endif
     429
    423430#if QT_VERSION >= 0x040400 && !defined(QT_NO_QFUTURE)
    424     uint numThreads = d_data->renderThreadCount;
     431    uint numThreads = renderThreadCount();
    425432
    426433    if ( numThreads <= 0 )
     
    456463#endif
    457464
     465#if DEBUG_RENDER
     466    const qint64 elapsed = time.elapsed();
     467    qDebug() << "renderImage" << imageSize << elapsed;
     468#endif
     469
    458470    d_data->data->discardRaster();
    459471
     
    486498            const double ty = yMap.invTransform( y );
    487499
    488             QRgb *line = ( QRgb * )image->scanLine( y );
     500            QRgb *line = reinterpret_cast<QRgb *>( image->scanLine( y ) );
    489501            line += tile.left();
    490502
     
    521533   \brief Return the raster to be used by the CONREC contour algorithm.
    522534
    523    A larger size will improve the precisision of the CONREC algorithm,
     535   A larger size will improve the precision of the CONREC algorithm,
    524536   but will slow down the time that is needed to calculate the lines.
    525537
     
    527539   the resolution depending on pixelSize().
    528540
    529    \param area Rect, where to calculate the contour lines
    530    \param rect Rect in pixel coordinates, where to paint the contour lines
     541   \param area Rectangle, where to calculate the contour lines
     542   \param rect Rectangle in pixel coordinates, where to paint the contour lines
    531543   \return Raster to be used by the CONREC contour algorithm.
    532544
     
    556568   \param rect Rectangle, where to calculate the contour lines
    557569   \param raster Raster, used by the CONREC algorithm
     570   \return Calculated contour lines
    558571
    559572   \sa contourLevels(), setConrecFlag(),
     
    586599    if ( d_data->data == NULL )
    587600        return;
    588 
    589     const QwtInterval intensityRange = d_data->data->interval( Qt::ZAxis );
    590601
    591602    const int numLevels = d_data->contourLevels.size();
     
    622633  \param xMap Maps x-values into pixel coordinates.
    623634  \param yMap Maps y-values into pixel coordinates.
    624   \param canvasRect Contents rect of the canvas in painter coordinates
     635  \param canvasRect Contents rectangle of the canvas in painter coordinates
    625636
    626637  \sa setDisplayMode(), renderImage(),
  • trunk/BNC/qwt/qwt_plot_spectrogram.h

    r4271 r8127  
    2121  \brief A plot item, which displays a spectrogram
    2222
    23   A spectrogram displays threedimenional data, where the 3rd dimension
     23  A spectrogram displays 3-dimensional data, where the 3rd dimension
    2424  ( the intensity ) is displayed using colors. The colors are calculated
    2525  from the values using a color map.
     26
     27  On multi-core systems the performance of the image composition
     28  can often be improved by dividing the area into tiles - each of them
     29  rendered in a different thread ( see QwtPlotItem::setRenderThreadCount() ).
    2630
    2731  In ContourMode contour lines are painted for the contour levels.
     
    2933  \image html spectrogram3.png
    3034
    31   \sa QwtRasterData, QwtColorMap
     35  \sa QwtRasterData, QwtColorMap, QwtPlotItem::setRenderThreadCount()
    3236*/
    3337
     
    5559    virtual ~QwtPlotSpectrogram();
    5660
    57     void setRenderThreadCount( uint numThreads );
    58     uint renderThreadCount() const;
    59 
    6061    void setDisplayMode( DisplayMode, bool on = true );
    6162    bool testDisplayMode( DisplayMode ) const;
     
    7172    virtual QRectF pixelHint( const QRectF & ) const;
    7273
     74    void setDefaultContourPen( const QColor &,
     75        qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
    7376    void setDefaultContourPen( const QPen & );
    7477    QPen defaultContourPen() const;
  • trunk/BNC/qwt/qwt_plot_svgitem.cpp

    r4621 r8127  
    1010#include "qwt_plot_svgitem.h"
    1111#include "qwt_scale_map.h"
    12 #include "qwt_legend.h"
    13 #include "qwt_legend_item.h"
    1412#include "qwt_painter.h"
    1513#include <qpainter.h>
     
    6664{
    6765    d_data = new PrivateData();
     66    d_data->boundingRect = QwtPlotItem::boundingRect();
    6867
    6968    setItemAttribute( QwtPlotItem::AutoScale, true );
     
    9291    d_data->boundingRect = rect;
    9392    const bool ok = d_data->renderer.load( fileName );
     93
     94    legendChanged();
    9495    itemChanged();
     96
    9597    return ok;
    9698}
     
    109111    d_data->boundingRect = rect;
    110112    const bool ok = d_data->renderer.load( data );
     113
     114    legendChanged();
    111115    itemChanged();
     116
    112117    return ok;
    113118}
    114119
    115 //! Bounding rect of the item
     120//! Bounding rectangle of the item
    116121QRectF QwtPlotSvgItem::boundingRect() const
    117122{
     
    161166
    162167  \param painter Painter
    163   \param viewBox View Box, see QSvgRenderer::viewBox
    164   \param rect Traget rectangle on the paint device
     168  \param viewBox View Box, see QSvgRenderer::viewBox()
     169  \param rect Target rectangle on the paint device
    165170*/
    166171void QwtPlotSvgItem::render( QPainter *painter,
     
    185190
    186191/*!
    187   Calculate the viewBox from an rect and boundingRect().
     192  Calculate the view box from rect and boundingRect().
    188193
    189194  \param rect Rectangle in scale coordinates
    190   \return viewBox View Box, see QSvgRenderer::viewBox
     195  \return View box, see QSvgRenderer::viewBox()
    191196*/
    192197QRectF QwtPlotSvgItem::viewBox( const QRectF &rect ) const
  • trunk/BNC/qwt/qwt_plot_xml.cpp

    r4271 r8127  
    2929  from a specific editor in the Qwt designer plugin.
    3030
     31  \return QString::null
    3132  \warning The plot editor has never been implemented.
    3233*/
  • trunk/BNC/qwt/qwt_plot_zoomer.cpp

    r4271 r8127  
    1010#include "qwt_plot_zoomer.h"
    1111#include "qwt_plot.h"
    12 #include "qwt_plot_canvas.h"
    1312#include "qwt_scale_div.h"
    1413#include "qwt_picker_machine.h"
    1514#include <qalgorithms.h>
     15
     16static QwtInterval qwtExpandedZoomInterval( double v1, double v2,
     17    double minRange, const QwtTransform* transform )
     18{
     19    double min = v1;
     20    double max = v2;
     21
     22    if ( max - min < minRange )
     23    {
     24        min = 0.5 * ( min + max - minRange );
     25        max = min + minRange;
     26
     27        if ( transform )
     28        {
     29            // f.e the logarithmic scale doesn't allow values
     30            // outside [QwtLogTransform::LogMin/QwtLogTransform::LogMax]
     31
     32            double minBounded = transform->bounded( min );
     33            double maxBounded = transform->bounded( max );
     34
     35            if ( minBounded != min )
     36            {
     37                maxBounded = transform->bounded( minBounded + minRange );
     38            }
     39            else if ( maxBounded != max )
     40            {
     41                minBounded = transform->bounded( maxBounded - minRange );
     42            }
     43
     44            min = minBounded;
     45            max = maxBounded;
     46        }
     47    }
     48
     49    return QwtInterval( min, max );
     50}
     51
     52static QRectF qwtExpandedZoomRect( const QRectF &zoomRect, const QSizeF &minSize,
     53    const QwtTransform* transformX, const QwtTransform* transformY )
     54{
     55    QRectF r = zoomRect;
     56
     57    if ( minSize.width() > r.width() )
     58    {
     59        const QwtInterval intv = qwtExpandedZoomInterval(
     60            r.left(), r.right(), minSize.width(), transformX );
     61
     62        r.setLeft( intv.minValue() );
     63        r.setRight( intv.maxValue() );
     64    }
     65
     66    if ( minSize.height() > r.height() )
     67    {
     68        const QwtInterval intv = qwtExpandedZoomInterval(
     69            zoomRect.top(), zoomRect.bottom(), minSize.height(), transformY );
     70
     71        r.setTop( intv.minValue() );
     72        r.setBottom( intv.maxValue() );
     73    }
     74
     75    return r;
     76}
    1677
    1778class QwtPlotZoomer::PrivateData
     
    3394
    3495  The zoomer is initialized with a QwtPickerDragRectMachine,
    35   the tracker mode is set to QwtPicker::ActiveOnly and the rubberband
     96  the tracker mode is set to QwtPicker::ActiveOnly and the rubber band
    3697  is set to QwtPicker::RectRubberBand
    3798
    3899  \param canvas Plot canvas to observe, also the parent object
    39   \param doReplot Call replot for the attached plot before initializing
     100  \param doReplot Call QwtPlot::replot() for the attached plot before initializing
    40101                  the zoomer with its scales. This might be necessary,
    41102                  when the plot is in a state with pending scale changes.
     
    43104  \sa QwtPlot::autoReplot(), QwtPlot::replot(), setZoomBase()
    44105*/
    45 QwtPlotZoomer::QwtPlotZoomer( QwtPlotCanvas *canvas, bool doReplot ):
     106QwtPlotZoomer::QwtPlotZoomer( QWidget *canvas, bool doReplot ):
    46107    QwtPlotPicker( canvas )
    47108{
     
    54115
    55116  The zoomer is initialized with a QwtPickerDragRectMachine,
    56   the tracker mode is set to QwtPicker::ActiveOnly and the rubberband
     117  the tracker mode is set to QwtPicker::ActiveOnly and the rubber band
    57118  is set to QwtPicker;;RectRubberBand
    58119
     
    60121  \param yAxis Y axis of the zoomer
    61122  \param canvas Plot canvas to observe, also the parent object
    62   \param doReplot Call replot for the attached plot before initializing
     123  \param doReplot Call QwtPlot::replot() for the attached plot before initializing
    63124                  the zoomer with its scales. This might be necessary,
    64125                  when the plot is in a state with pending scale changes.
     
    68129
    69130QwtPlotZoomer::QwtPlotZoomer( int xAxis, int yAxis,
    70         QwtPlotCanvas *canvas, bool doReplot ):
     131        QWidget *canvas, bool doReplot ):
    71132    QwtPlotPicker( xAxis, yAxis, canvas )
    72133{
     
    141202
    142203/*!
    143   Return the zoom stack. zoomStack()[0] is the zoom base,
    144   zoomStack()[1] the first zoomed rectangle.
     204  \return The zoom stack. zoomStack()[0] is the zoom base,
     205          zoomStack()[1] the first zoomed rectangle.
    145206
    146207  \sa setZoomStack(), zoomRectIndex()
     
    163224  Reinitialized the zoom stack with scaleRect() as base.
    164225
    165   \param doReplot Call replot for the attached plot before initializing
     226  \param doReplot Call QwtPlot::replot() for the attached plot before initializing
    166227                  the zoomer with its scales. This might be necessary,
    167228                  when the plot is in a state with pending scale changes.
     
    189250
    190251  base is united with the current scaleRect() and the zoom stack is
    191   reinitalized with it as zoom base. plot is zoomed to scaleRect().
     252  reinitialized with it as zoom base. plot is zoomed to scaleRect().
    192253
    193254  \param base Zoom base
     
    218279
    219280/*!
    220   Rectangle at the current position on the zoom stack.
    221 
     281  \return Rectangle at the current position on the zoom stack.
    222282  \sa zoomRectIndex(), scaleRect().
    223283*/
     
    239299
    240300  Clears all rectangles above the current position of the
    241   zoom stack and pushs the normalized rect on it.
     301  zoom stack and pushes the normalized rectangle on it.
    242302
    243303  \note If the maximal stack depth is reached, zoom is ignored.
     
    275335
    276336  Activate a rectangle on the zoom stack with an offset relative
    277   to the current position. Negative values of offest will zoom out,
     337  to the current position. Negative values of offset will zoom out,
    278338  positive zoom in. A value of 0 zooms out to the zoom base.
    279339
     
    344404  Adjust the observed plot to zoomRect()
    345405
    346   \note Initiates QwtPlot::replot
     406  \note Initiates QwtPlot::replot()
    347407*/
    348408
     
    361421        double x1 = rect.left();
    362422        double x2 = rect.right();
    363         if ( plt->axisScaleDiv( xAxis() )->lowerBound() >
    364             plt->axisScaleDiv( xAxis() )->upperBound() )
    365         {
     423        if ( !plt->axisScaleDiv( xAxis() ).isIncreasing() )
    366424            qSwap( x1, x2 );
    367         }
    368425
    369426        plt->setAxisScale( xAxis(), x1, x2 );
     
    371428        double y1 = rect.top();
    372429        double y2 = rect.bottom();
    373         if ( plt->axisScaleDiv( yAxis() )->lowerBound() >
    374             plt->axisScaleDiv( yAxis() )->upperBound() )
    375         {
     430        if ( !plt->axisScaleDiv( yAxis() ).isIncreasing() )
    376431            qSwap( y1, y2 );
    377         }
     432
    378433        plt->setAxisScale( yAxis(), y1, y2 );
    379434
     
    495550  \brief Check and correct a selected rectangle
    496551
    497   Reject rectangles with a hight or width < 2, otherwise
     552  Reject rectangles with a height or width < 2, otherwise
    498553  expand the selected rectangle to a minimum size of 11x11
    499554  and accept it.
    500555
    501   \return true If rect is accepted, or has been changed
    502           to a accepted rectangle.
     556  \return true If the rectangle is accepted, or has been changed
     557          to an accepted one.
    503558*/
    504559
     
    573628  if accepted.
    574629
     630  \param ok If true, complete the selection and emit selected signals
     631            otherwise discard the selection.
     632
    575633  \sa accept(), minZoomSize()
     634  \return True if the selection has been accepted, false otherwise
    576635*/
    577636bool QwtPlotZoomer::end( bool ok )
     
    592651    rect = rect.normalized();
    593652
    594     QRectF zoomRect = invTransform( rect ).normalized();
    595 
    596     const QSizeF minSize = minZoomSize();
    597     if ( minSize.isValid() )
    598     {
    599         const QPointF center = zoomRect.center();
    600         zoomRect.setSize( zoomRect.size().expandedTo( minZoomSize() ) );
    601         zoomRect.moveCenter( center );
    602     }
     653    const QwtScaleMap xMap = plot->canvasMap( xAxis() );
     654    const QwtScaleMap yMap = plot->canvasMap( yAxis() );
     655
     656    QRectF zoomRect = QwtScaleMap::invTransform( xMap, yMap, rect ).normalized();
     657
     658    zoomRect = qwtExpandedZoomRect( zoomRect, minZoomSize(),
     659        xMap.transformation(), yMap.transformation() );
    603660
    604661    zoom( zoomRect );
  • trunk/BNC/qwt/qwt_plot_zoomer.h

    r4271 r8127  
    1818  \brief QwtPlotZoomer provides stacked zooming for a plot widget
    1919
    20   QwtPlotZoomer offers rubberband selections on the plot canvas,
    21   translating the selected rectangles into plot coordinates and
    22   adjusting the axes to them. Zooming can repeated as often as
    23   possible, limited only by maxStackDepth() or minZoomSize().
    24   Each rectangle is pushed on a stack.
     20  QwtPlotZoomer selects rectangles from user inputs ( mouse or keyboard )
     21  translates them into plot coordinates and adjusts the axes to them.
     22  The selection is supported by a rubber band and optionally by displaying
     23  the coordinates of the current mouse position.
    2524
    26   Zoom rectangles can be selected depending on selectionFlags() using the
    27   mouse or keyboard (QwtEventPattern, QwtPickerMachine).
    28   QwtEventPattern::MouseSelect3,QwtEventPattern::KeyUndo,
    29   or QwtEventPattern::MouseSelect6,QwtEventPattern::KeyRedo
    30   walk up and down the zoom stack.
    31   QwtEventPattern::MouseSelect2 or QwtEventPattern::KeyHome unzoom to
    32   the initial size.
     25  Zooming can be repeated as often as possible, limited only by
     26  maxStackDepth() or minZoomSize().  Each rectangle is pushed on a stack.
     27
     28  The default setting how to select rectangles is
     29  a QwtPickerDragRectMachine with the following bindings:
     30
     31  - QwtEventPattern::MouseSelect1\n
     32    The first point of the zoom rectangle is selected by a mouse press,
     33    the second point from the position, where the mouse is released.
     34
     35  - QwtEventPattern::KeySelect1\n
     36    The first key press selects the first, the second key press
     37    selects the second point.
     38
     39  - QwtEventPattern::KeyAbort\n
     40    Discard the selection in the state, where the first point
     41    is selected.
     42
     43  To traverse the zoom stack the following bindings are used:
     44
     45  - QwtEventPattern::MouseSelect3, QwtEventPattern::KeyUndo\n
     46    Zoom out one position on the zoom stack
     47   
     48  - QwtEventPattern::MouseSelect6, QwtEventPattern::KeyRedo\n
     49    Zoom in one position on the zoom stack
     50
     51  - QwtEventPattern::MouseSelect2, QwtEventPattern::KeyHome\n
     52    Zoom to the zoom base
     53
     54  The setKeyPattern() and setMousePattern() functions can be used
     55  to configure the zoomer actions. The following example
     56  shows, how to configure the 'I' and 'O' keys for zooming in and out
     57  one position on the zoom stack. The "Home" key is used to
     58  "unzoom" the plot.
     59
     60  \code
     61   zoomer = new QwtPlotZoomer( plot );
     62   zoomer->setKeyPattern( QwtEventPattern::KeyRedo, Qt::Key_I, Qt::ShiftModifier );
     63   zoomer->setKeyPattern( QwtEventPattern::KeyUndo, Qt::Key_O, Qt::ShiftModifier );
     64   zoomer->setKeyPattern( QwtEventPattern::KeyHome, Qt::Key_Home );
     65  \endcode
    3366
    3467  QwtPlotZoomer is tailored for plots with one x and y axis, but it is
    35   allowed to attach a second QwtPlotZoomer for the other axes.
     68  allowed to attach a second QwtPlotZoomer ( without rubber band and tracker )
     69  for the other axes.
    3670
    3771  \note The realtime example includes an derived zoomer class that adds
    3872        scrollbars to the plot canvas.
     73
     74  \sa QwtPlotPanner, QwtPlotMagnifier
    3975*/
    4076
     
    4379    Q_OBJECT
    4480public:
    45     explicit QwtPlotZoomer( QwtPlotCanvas *, bool doReplot = true );
     81    explicit QwtPlotZoomer( QWidget *, bool doReplot = true );
    4682    explicit QwtPlotZoomer( int xAxis, int yAxis,
    47                             QwtPlotCanvas *, bool doReplot = true );
     83                            QWidget *, bool doReplot = true );
    4884
    4985    virtual ~QwtPlotZoomer();
  • trunk/BNC/qwt/qwt_point_3d.h

    r4271 r8127  
    103103
    104104/*!
    105     Returns true if the point is null; otherwise returns false.
     105    \return True if the point is null; otherwise returns false.
    106106
    107107    A point is considered to be null if x, y and z-coordinates
     
    110110inline bool QwtPoint3D::isNull() const
    111111{
    112     return d_x == 0.0 && d_y == 0.0 && d_z == 0;
     112    return d_x == 0.0 && d_y == 0.0 && d_z == 0.0;
    113113}
    114114
    115 //! Returns the x-coordinate of the point.
     115//! \return The x-coordinate of the point.
    116116inline double QwtPoint3D::x() const
    117117{
     
    119119}
    120120
    121 //! Returns the y-coordinate of the point.
     121//! \return The y-coordinate of the point.
    122122inline double QwtPoint3D::y() const
    123123{
     
    125125}
    126126
    127 //! Returns the z-coordinate of the point.
     127//! \return The z-coordinate of the point.
    128128inline double QwtPoint3D::z() const
    129129{
     
    131131}
    132132
    133 //! Returns a reference to the x-coordinate of the point.
     133//! \return A reference to the x-coordinate of the point.
    134134inline double &QwtPoint3D::rx()
    135135{
     
    137137}
    138138
    139 //! Returns a reference to the y-coordinate of the point.
     139//! \return A reference to the y-coordinate of the point.
    140140inline double &QwtPoint3D::ry()
    141141{
     
    143143}
    144144
    145 //! Returns a reference to the z-coordinate of the point.
     145//! \return A reference to the z-coordinate of the point.
    146146inline double &QwtPoint3D::rz()
    147147{
     
    168168
    169169/*!
    170    Rounds 2D point, where the z coordinate is dropped.
     170   \return 2D point, where the z coordinate is dropped.
    171171*/
    172172inline QPointF QwtPoint3D::toPoint() const
     
    175175}
    176176
    177 //! Returns true if this point and other are equal; otherwise returns false.
     177//! \return True, if this point and other are equal; otherwise returns false.
    178178inline bool QwtPoint3D::operator==( const QwtPoint3D &other ) const
    179179{
     
    181181}
    182182
    183 //! Returns true if this rect and other are different; otherwise returns false.
     183//! \return True if this rect and other are different; otherwise returns false.
    184184inline bool QwtPoint3D::operator!=( const QwtPoint3D &other ) const
    185185{
  • trunk/BNC/qwt/qwt_point_polar.cpp

    r4271 r8127  
    3939   Convert and return values in Cartesian coordinates
    4040
     41   \return Converted point in Cartesian coordinates
     42
    4143   \note Invalid or null points will be returned as QPointF(0.0, 0.0)
    4244   \sa isValid(), isNull()
     
    5456
    5557/*!
    56     Returns true if point1 is equal to point2; otherwise returns false.
     58    \brief Compare 2 points
    5759
    5860    Two points are equal to each other if radius and
    5961    azimuth-coordinates are the same. Points are not equal, when
    6062    the azimuth differs, but other.azimuth() == azimuth() % (2 * PI).
     63
     64    \return True if the point is equal to other; otherwise return false.
    6165
    6266    \sa normalized()
     
    6872
    6973/*!
    70     Returns true if point1 is not equal to point2; otherwise returns false.
     74    Compare 2 points
    7175
    7276    Two points are equal to each other if radius and
     
    7478    the azimuth differs, but other.azimuth() == azimuth() % (2 * PI).
    7579
     80    \return True if the point is not equal to other; otherwise return false.
    7681    \sa normalized()
    7782*/
     
    8691   When the radius is < 0.0 it is set to 0.0. The azimuth is
    8792   a value >= 0.0 and < 2 * M_PI.
     93
     94   \return Normalized point
    8895*/
    8996QwtPointPolar QwtPointPolar::normalized() const
  • trunk/BNC/qwt/qwt_point_polar.h

    r4331 r8127  
    6363/*!
    6464    Constructs a null point, with a radius and azimuth set to 0.0.
    65     \sa QPointF::isNull
     65    \sa QPointF::isNull()
    6666*/
    6767inline QwtPointPolar::QwtPointPolar():
     
    195195}
    196196
     197inline QwtPointPolar qwtFastPos2Polar( const QPointF &pos )
     198{
     199    return QwtPointPolar( qwtFastAtan2( pos.y(), pos.x() ),
     200        qSqrt( qwtSqr( pos.x() ) + qwtSqr( pos.y() ) ) );
     201}
     202
    197203#endif
  • trunk/BNC/qwt/qwt_raster_data.cpp

    r4271 r8127  
    1010#include "qwt_raster_data.h"
    1111#include "qwt_point_3d.h"
     12#include <qnumeric.h>
    1213
    1314class QwtRasterData::ContourPlane
     
    9495        case 6:
    9596            // e(-1,1,0), e(1,0,-1)
    96             line[0] = vertex[1].toPoint();
     97            line[0] = vertex[2].toPoint();
    9798            line[1] = intersection( vertex[0], vertex[1] );
    9899            break;
     
    181182  \brief Initialize a raster
    182183
    183   Before the composition of an image QwtPlotSpectrogram calls initRaster,
     184  Before the composition of an image QwtPlotSpectrogram calls initRaster(),
    184185  announcing the area and its resolution that will be requested.
    185186
    186187  The default implementation does nothing, but for data sets that
    187   are stored in files, it might be good idea to reimplement initRaster,
     188  are stored in files, it might be good idea to reimplement initRaster(),
    188189  where the data is resampled and loaded into memory.
    189190
     
    221222   
    222223   Width and height of the hint need to be the horizontal 
    223    and vertical distances between 2 neighboured points.
     224   and vertical distances between 2 neighbored points.
    224225   The center of the hint has to be the position of any point
    225226   ( it doesn't matter which one ).
     
    247248/*!
    248249   Calculate contour lines
     250
     251   \param rect Bounding rectangle for the contour lines
     252   \param raster Number of data pixels of the raster data
     253   \param levels List of limits, where to insert contour lines
     254   \param flags Flags to customize the contouring algorithm
     255
     256   \return Calculated contour lines
    249257
    250258   An adaption of CONREC, a simple contouring algorithm.
     
    337345                if ( z > zMax )
    338346                    zMax = z;
     347            }
     348
     349            if ( qIsNaN( zSum ) )
     350            {
     351                // one of the points is NaN
     352                continue;
    339353            }
    340354
  • trunk/BNC/qwt/qwt_raster_data.h

    r4271 r8127  
    3939    enum ConrecFlag
    4040    {
    41         //! Ignore all verices on the same level
     41        //! Ignore all vertices on the same level
    4242        IgnoreAllVerticesOnLevel = 0x01,
    4343
  • trunk/BNC/qwt/qwt_round_scale_draw.cpp

    r4271 r8127  
    1212#include "qwt_scale_div.h"
    1313#include "qwt_scale_map.h"
     14#include "qwt_math.h"
    1415#include <qpen.h>
    1516#include <qpainter.h>
     
    2122public:
    2223    PrivateData():
    23         center( 50, 50 ),
    24         radius( 50 ),
    25         startAngle( -135 * 16 ),
    26         endAngle( 135 * 16 )
     24        center( 50.0, 50.0 ),
     25        radius( 50.0 ),
     26        startAngle( -135.0 ),
     27        endAngle( 135.0 )
    2728    {
    2829    }
     
    6465  \sa moveCenter()
    6566*/
    66 void QwtRoundScaleDraw::setRadius( int radius )
     67void QwtRoundScaleDraw::setRadius( double radius )
    6768{
    6869    d_data->radius = radius;
     
    7475  Radius is the radius of the backbone without ticks and labels.
    7576
     77  \return Radius of the scale
    7678  \sa setRadius(), extent()
    7779*/
    78 int QwtRoundScaleDraw::radius() const
     80double QwtRoundScaleDraw::radius() const
    7981{
    8082    return d_data->radius;
     
    110112  <li>The angle range is limited to [-360, 360] degrees. Angles exceeding
    111113      this range will be clipped.
    112   <li>For angles more than 359 degrees above or below min(angle1, angle2),
     114  <li>For angles more or equal than 360 degrees above or below min(angle1, angle2),
    113115      scale marks will not be drawn.
    114   <li>If you need a counterclockwise scale, use QwtScaleDiv::setRange
     116  <li>If you need a counterclockwise scale, use QwtScaleDiv::setInterval()
    115117  </ul>
    116118*/
    117119void QwtRoundScaleDraw::setAngleRange( double angle1, double angle2 )
    118120{
     121#if 0
    119122    angle1 = qBound( -360.0, angle1, 360.0 );
    120123    angle2 = qBound( -360.0, angle2, 360.0 );
    121 
    122     d_data->startAngle = angle1 * 16.0;
    123     d_data->endAngle = angle2 * 16.0;
     124#endif
     125
     126    d_data->startAngle = angle1;
     127    d_data->endAngle = angle2;
    124128
    125129    if ( d_data->startAngle == d_data->endAngle )
     
    142146void QwtRoundScaleDraw::drawLabel( QPainter *painter, double value ) const
    143147{
     148    const double tval = scaleMap().transform( value );
     149    if ( ( tval >= d_data->startAngle + 360.0 )
     150        || ( tval <= d_data->startAngle - 360.0 ) )
     151    {
     152        return;
     153    }
     154
    144155    const QwtText label = tickLabel( painter->font(), value );
    145156    if ( label.isEmpty() )
    146157        return;
    147158
    148     const double tval = scaleMap().transform( value );
    149     if ( ( tval > d_data->startAngle + 359 * 16 )
    150         || ( tval < d_data->startAngle - 359 * 16 ) )
    151     {
    152         return;
    153     }
    154 
    155159    double radius = d_data->radius;
    156160    if ( hasComponent( QwtAbstractScaleDraw::Ticks ) ||
     
    164168
    165169    const QSizeF sz = label.textSize( painter->font() );
    166     const double arc = tval / 16.0 / 360.0 * 2 * M_PI;
     170    const double arc = qwtRadians( tval );
    167171
    168172    const double x = d_data->center.x() +
    169173        ( radius + sz.width() / 2.0 ) * qSin( arc );
    170174    const double y = d_data->center.y() -
    171         ( radius + sz.height() / 2.0 ) * cos( arc );
     175        ( radius + sz.height() / 2.0 ) * qCos( arc );
    172176
    173177    const QRectF r( x - sz.width() / 2, y - sz.height() / 2,
     
    196200    const double radius = d_data->radius;
    197201
    198     if ( ( tval <= d_data->startAngle + 359 * 16 )
    199         || ( tval >= d_data->startAngle - 359 * 16 ) )
    200     {
    201         const double arc = double( tval ) / 16.0 * M_PI / 180.0;
     202    if ( ( tval < d_data->startAngle + 360.0 )
     203        && ( tval > d_data->startAngle - 360.0 ) )
     204    {
     205        const double arc = qwtRadians( tval );
    202206
    203207        const double sinArc = qSin( arc );
     
    221225void QwtRoundScaleDraw::drawBackbone( QPainter *painter ) const
    222226{
    223     const double a1 = qMin( scaleMap().p1(), scaleMap().p2() ) - 90 * 16;
    224     const double a2 = qMax( scaleMap().p1(), scaleMap().p2() ) - 90 * 16;
     227    const double deg1 = scaleMap().p1();
     228    const double deg2 = scaleMap().p2();
     229
     230    const int a1 = qRound( qMin( deg1, deg2 ) - 90 );
     231    const int a2 = qRound( qMax( deg1, deg2 ) - 90 );
    225232
    226233    const double radius = d_data->radius;
     
    228235    const double y = d_data->center.y() - radius;
    229236
    230     painter->drawArc( x, y, 2 * radius, 2 * radius,
    231         -a2, a2 - a1 + 1 );          // counterclockwise
     237    painter->drawArc( QRectF( x, y, 2 * radius, 2 * radius ),
     238        -a2 * 16, ( a2 - a1 + 1 ) * 16 );          // counterclockwise
    232239}
    233240
     
    240247
    241248   \param font Font used for painting the labels
     249   \return Calculated extent
    242250
    243251   \sa setMinimumExtent(), minimumExtent()
    244    \warning The implemented algo is not too smart and
     252   \warning The implemented algorithm is not too smart and
    245253            calculates only an upper limit, that might be a
    246254            few pixels too large
     
    260268                continue;
    261269
    262             const QwtText label = tickLabel( font, value );
    263             if ( label.isEmpty() )
    264                 continue;
    265 
    266270            const double tval = scaleMap().transform( value );
    267             if ( ( tval < d_data->startAngle + 360 * 16 )
    268                 && ( tval > d_data->startAngle - 360 * 16 ) )
     271            if ( ( tval < d_data->startAngle + 360 )
     272                && ( tval > d_data->startAngle - 360 ) )
    269273            {
    270                 const double arc = tval / 16.0 / 360.0 * 2 * M_PI;
     274                const QwtText label = tickLabel( font, value );
     275                if ( label.isEmpty() )
     276                    continue;
     277
     278                const double arc = qwtRadians( tval );
    271279
    272280                const QSizeF sz = label.textSize( font );
     
    290298    if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
    291299    {
    292         const double pw = qMax( 1, penWidth() );  // penwidth can be zero
     300        const double pw = qMax( 1, penWidth() );  // pen width can be zero
    293301        d += pw;
    294302    }
  • trunk/BNC/qwt/qwt_round_scale_draw.h

    r4271 r8127  
    1515#include <qpoint.h>
    1616
    17 class QPen;
    18 
    1917/*!
    2018  \brief A class for drawing round scales
    2119
    2220  QwtRoundScaleDraw can be used to draw round scales.
    23   The circle segment can be adjusted by QwtRoundScaleDraw::setAngleRange().
     21  The circle segment can be adjusted by setAngleRange().
    2422  The geometry of the scale can be specified with
    25   QwtRoundScaleDraw::moveCenter() and QwtRoundScaleDraw::setRadius().
     23  moveCenter() and setRadius().
    2624
    2725  After a scale division has been specified as a QwtScaleDiv object
     
    3634    virtual ~QwtRoundScaleDraw();
    3735
    38     void setRadius( int radius );
    39     int radius() const;
     36    void setRadius( double radius );
     37    double radius() const;
    4038
    4139    void moveCenter( double x, double y );
     
    4846
    4947protected:
    50     virtual void drawTick( QPainter *p, double val, double len ) const;
    51     virtual void drawBackbone( QPainter *p ) const;
    52     virtual void drawLabel( QPainter *p, double val ) const;
     48    virtual void drawTick( QPainter *, double val, double len ) const;
     49    virtual void drawBackbone( QPainter * ) const;
     50    virtual void drawLabel( QPainter *, double val ) const;
    5351
    5452private:
  • trunk/BNC/qwt/qwt_sampling_thread.h

    r4271 r8127  
    88  \brief A thread collecting samples at regular intervals.
    99
    10   Contiounous signals are converted into a discrete signal by
     10  Continuous signals are converted into a discrete signal by
    1111  collecting samples at regular intervals. A discrete signal
    1212  can be displayed by a QwtPlotSeriesItem on a QwtPlot widget.
    1313
    14   QwtSamplingThread starts a thread calling perodically sample(),
     14  QwtSamplingThread starts a thread calling periodically sample(),
    1515  to collect and store ( or emit ) a single sample.
    1616
     
    3939       Collect a sample
    4040
    41        \param elapsed Time since the thread was started in miliseconds
     41       \param elapsed Time since the thread was started in milliseconds
    4242     */
    4343    virtual void sample( double elapsed ) = 0;
  • trunk/BNC/qwt/qwt_scale_div.cpp

    r4271 r8127  
    1010#include "qwt_scale_div.h"
    1111#include "qwt_math.h"
    12 #include "qwt_interval.h"
    1312#include <qalgorithms.h>
    1413
    15 //! Construct an invalid QwtScaleDiv instance.
    16 QwtScaleDiv::QwtScaleDiv():
    17     d_lowerBound( 0.0 ),
    18     d_upperBound( 0.0 ),
    19     d_isValid( false )
    20 {
    21 }
    22 
    23 /*!
    24   Construct QwtScaleDiv instance.
     14/*!
     15  Construct a division without ticks
     16
     17  \param lowerBound First boundary
     18  \param upperBound Second boundary
     19
     20  \note lowerBound might be greater than upperBound for inverted scales
     21 */
     22QwtScaleDiv::QwtScaleDiv( double lowerBound, double upperBound ):
     23    d_lowerBound( lowerBound ),
     24    d_upperBound( upperBound )
     25{
     26}
     27
     28/*!
     29  Construct a scale division
    2530
    2631  \param interval Interval
     
    3035        QList<double> ticks[NTickTypes] ):
    3136    d_lowerBound( interval.minValue() ),
    32     d_upperBound( interval.maxValue() ),
    33     d_isValid( true )
     37    d_upperBound( interval.maxValue() )
    3438{
    3539    for ( int i = 0; i < NTickTypes; i++ )
     
    3842
    3943/*!
    40   Construct QwtScaleDiv instance.
    41 
    42   \param lowerBound First interval limit
    43   \param upperBound Second interval limit
     44  Construct a scale division
     45
     46  \param lowerBound First boundary
     47  \param upperBound Second boundary
    4448  \param ticks List of major, medium and minor ticks
    45 */
    46 QwtScaleDiv::QwtScaleDiv(
    47         double lowerBound, double upperBound,
     49
     50  \note lowerBound might be greater than upperBound for inverted scales
     51*/
     52QwtScaleDiv::QwtScaleDiv( double lowerBound, double upperBound,
    4853        QList<double> ticks[NTickTypes] ):
    4954    d_lowerBound( lowerBound ),
    50     d_upperBound( upperBound ),
    51     d_isValid( true )
     55    d_upperBound( upperBound )
    5256{
    5357    for ( int i = 0; i < NTickTypes; i++ )
     
    5660
    5761/*!
     62  Construct a scale division
     63
     64  \param lowerBound First boundary
     65  \param upperBound Second boundary
     66  \param minorTicks List of minor ticks
     67  \param mediumTicks List medium ticks
     68  \param majorTicks List of major ticks
     69
     70  \note lowerBound might be greater than upperBound for inverted scales
     71*/
     72QwtScaleDiv::QwtScaleDiv( double lowerBound, double upperBound,
     73        const QList<double> &minorTicks,
     74        const QList<double> &mediumTicks,
     75        const QList<double> &majorTicks ):
     76    d_lowerBound( lowerBound ),
     77    d_upperBound( upperBound )
     78{
     79    d_ticks[ MinorTick ] = minorTicks;
     80    d_ticks[ MediumTick ] = mediumTicks;
     81    d_ticks[ MajorTick ] = majorTicks;
     82}
     83
     84/*!
     85  Change the interval
     86
     87  \param lowerBound First boundary
     88  \param upperBound Second boundary
     89
     90  \note lowerBound might be greater than upperBound for inverted scales
     91*/
     92void QwtScaleDiv::setInterval( double lowerBound, double upperBound )
     93{
     94    d_lowerBound = lowerBound;
     95    d_upperBound = upperBound;
     96}
     97
     98/*!
    5899   Change the interval
     100
    59101   \param interval Interval
    60102*/
    61103void QwtScaleDiv::setInterval( const QwtInterval &interval )
    62104{
    63     setInterval( interval.minValue(), interval.maxValue() );
     105    d_lowerBound = interval.minValue();
     106    d_upperBound = interval.maxValue();
     107}
     108
     109/*!
     110  \return lowerBound -> upperBound
     111*/
     112QwtInterval QwtScaleDiv::interval() const
     113{
     114    return QwtInterval( d_lowerBound, d_upperBound );
     115}
     116
     117/*!
     118  Set the first boundary
     119
     120  \param lowerBound First boundary
     121  \sa lowerBiound(), setUpperBound()
     122 */
     123void QwtScaleDiv::setLowerBound( double lowerBound  )
     124{
     125    d_lowerBound = lowerBound;
     126}
     127
     128/*!
     129  \return First boundary
     130  \sa upperBound()
     131*/
     132double QwtScaleDiv::lowerBound() const
     133{
     134    return d_lowerBound;
     135}   
     136
     137/*!
     138  Set the second boundary
     139
     140  \param upperBound Second boundary
     141  \sa upperBound(), setLowerBound()
     142 */
     143void QwtScaleDiv::setUpperBound( double upperBound  )
     144{
     145    d_upperBound = upperBound;
     146}
     147
     148/*!
     149  \return upper bound
     150  \sa lowerBound()
     151*/
     152double QwtScaleDiv::upperBound() const
     153{
     154    return d_upperBound;
     155}
     156
     157/*!
     158  \return upperBound() - lowerBound()
     159*/
     160double QwtScaleDiv::range() const
     161{
     162    return d_upperBound - d_lowerBound;
    64163}
    65164
     
    71170{
    72171    if ( d_lowerBound != other.d_lowerBound ||
    73         d_upperBound != other.d_upperBound ||
    74         d_isValid != other.d_isValid )
     172        d_upperBound != other.d_upperBound )
    75173    {
    76174        return false;
     
    88186/*!
    89187  \brief Inequality
    90   \return true if this instance is not equal to s
    91 */
    92 bool QwtScaleDiv::operator!=( const QwtScaleDiv &s ) const
    93 {
    94     return ( !( *this == s ) );
    95 }
    96 
    97 //! Invalidate the scale division
    98 void QwtScaleDiv::invalidate()
    99 {
    100     d_isValid = false;
    101 
    102     // detach arrays
    103     for ( int i = 0; i < NTickTypes; i++ )
    104         d_ticks[i].clear();
    105 
    106     d_lowerBound = d_upperBound = 0;
    107 }
    108 
    109 //! Check if the scale division is valid
    110 bool QwtScaleDiv::isValid() const
    111 {
    112     return d_isValid;
     188  \return true if this instance is not equal to other
     189*/
     190bool QwtScaleDiv::operator!=( const QwtScaleDiv &other ) const
     191{
     192    return ( !( *this == other ) );
     193}
     194
     195//! Check if the scale division is empty( lowerBound() == upperBound() )
     196bool QwtScaleDiv::isEmpty() const
     197{
     198    return ( d_lowerBound == d_upperBound );
     199}
     200
     201//! Check if the scale division is increasing( lowerBound() <= upperBound() )
     202bool QwtScaleDiv::isIncreasing() const
     203{
     204    return d_lowerBound <= d_upperBound;
    113205}
    114206
     
    121213bool QwtScaleDiv::contains( double value ) const
    122214{
    123     if ( !d_isValid )
    124         return false;
    125 
    126215    const double min = qMin( d_lowerBound, d_upperBound );
    127216    const double max = qMax( d_lowerBound, d_upperBound );
     
    130219}
    131220
    132 //! Invert the scale divison
     221/*!
     222   Invert the scale division
     223   \sa inverted()
     224 */
    133225void QwtScaleDiv::invert()
    134226{
     
    142234        const int size2 = size / 2;
    143235
    144         for ( int i = 0; i < size2; i++ )
    145             qSwap( ticks[i], ticks[size - 1 - i] );
     236        for ( int j = 0; j < size2; j++ )
     237            qSwap( ticks[j], ticks[size - 1 - j] );
    146238    }
     239}
     240
     241/*!
     242  \return A scale division with inverted boundaries and ticks
     243  \sa invert()
     244 */
     245QwtScaleDiv QwtScaleDiv::inverted() const
     246{
     247    QwtScaleDiv other = *this;
     248    other.invert();
     249
     250    return other;
     251}
     252
     253/*!
     254   Return a scale division with an interval [lowerBound, upperBound]
     255   where all ticks outside this interval are removed
     256
     257   \param lowerBound Lower bound
     258   \param upperBound Upper bound
     259
     260   \return Scale division with all ticks inside of the given interval
     261
     262   \note lowerBound might be greater than upperBound for inverted scales
     263*/
     264QwtScaleDiv QwtScaleDiv::bounded(
     265    double lowerBound, double upperBound ) const
     266{
     267    const double min = qMin( lowerBound, upperBound );
     268    const double max = qMax( lowerBound, upperBound );
     269
     270    QwtScaleDiv sd;
     271    sd.setInterval( lowerBound, upperBound );
     272
     273    for ( int tickType = 0; tickType < QwtScaleDiv::NTickTypes; tickType++ )
     274    {
     275        const QList<double> &ticks = d_ticks[ tickType ];
     276
     277        QList<double> boundedTicks;
     278        for ( int i = 0; i < ticks.size(); i++ )
     279        {
     280            const double tick = ticks[i];
     281            if ( tick >= min && tick <= max )
     282                boundedTicks += tick;
     283        }
     284
     285        sd.setTicks( tickType, boundedTicks );
     286    }
     287
     288    return sd;
     289
    147290}
    148291
     
    155298void QwtScaleDiv::setTicks( int type, const QList<double> &ticks )
    156299{
    157     if ( type >= 0 || type < NTickTypes )
     300    if ( type >= 0 && type < NTickTypes )
    158301        d_ticks[type] = ticks;
    159302}
     
    163306
    164307   \param type MinorTick, MediumTick or MajorTick
    165 */
    166 const QList<double> &QwtScaleDiv::ticks( int type ) const
    167 {
    168     if ( type >= 0 || type < NTickTypes )
     308   \return Tick list
     309*/
     310QList<double> QwtScaleDiv::ticks( int type ) const
     311{
     312    if ( type >= 0 && type < NTickTypes )
    169313        return d_ticks[type];
    170314
    171     static QList<double> noTicks;
    172     return noTicks;
    173 }
     315    return QList<double>();
     316}
     317
     318#ifndef QT_NO_DEBUG_STREAM
     319
     320QDebug operator<<( QDebug debug, const QwtScaleDiv &scaleDiv )
     321{
     322    debug << scaleDiv.lowerBound() << "<->" << scaleDiv.upperBound();
     323    debug << "Major: " << scaleDiv.ticks( QwtScaleDiv::MajorTick );
     324    debug << "Medium: " << scaleDiv.ticks( QwtScaleDiv::MediumTick );
     325    debug << "Minor: " << scaleDiv.ticks( QwtScaleDiv::MinorTick );
     326
     327    return debug;
     328}
     329
     330#endif
     331
  • trunk/BNC/qwt/qwt_scale_div.h

    r4271 r8127  
    1515#include <qlist.h>
    1616
    17 class QwtInterval;
     17#ifndef QT_NO_DEBUG_STREAM
     18#include <qdebug.h>
     19#endif
    1820
    1921/*!
    2022  \brief A class representing a scale division
    2123
    22   A scale division consists of its limits and 3 list
    23   of tick values qualified as major, medium and minor ticks.
     24  A Qwt scale is defined by its boundaries and 3 list
     25  for the positions of the major, medium and minor ticks.
    2426
    25   In most cases scale divisions are calculated by a QwtScaleEngine.
     27  The upperBound() might be smaller than the lowerBound()
     28  to indicate inverted scales.
    2629
    27   \sa subDivideInto(), subDivide()
     30  Scale divisions can be calculated from a QwtScaleEngine.
     31
     32  \sa QwtScaleEngine::divideScale(), QwtPlot::setAxisScaleDiv(),
     33      QwtAbstractSlider::setScaleDiv()
    2834*/
    2935
     
    5056    };
    5157
    52     explicit QwtScaleDiv();
     58    explicit QwtScaleDiv( double lowerBound = 0.0,
     59        double upperBound = 0.0 );
     60
    5361    explicit QwtScaleDiv( const QwtInterval &, QList<double>[NTickTypes] );
    54     explicit QwtScaleDiv(
    55         double lowerBound, double upperBound, QList<double>[NTickTypes] );
    5662
    57     bool operator==( const QwtScaleDiv &s ) const;
    58     bool operator!=( const QwtScaleDiv &s ) const;
     63    explicit QwtScaleDiv( double lowerBound, double upperBound,
     64        QList<double>[NTickTypes] );
     65
     66    explicit QwtScaleDiv( double lowerBound, double upperBound,
     67        const QList<double> &minorTicks, const QList<double> &mediumTicks,
     68        const QList<double> &majorTicks );
     69
     70    bool operator==( const QwtScaleDiv & ) const;
     71    bool operator!=( const QwtScaleDiv & ) const;
    5972
    6073    void setInterval( double lowerBound, double upperBound );
     
    6275    QwtInterval interval() const;
    6376
     77    void setLowerBound( double );
    6478    double lowerBound() const;
     79
     80    void setUpperBound( double );
    6581    double upperBound() const;
     82
    6683    double range() const;
    6784
    68     bool contains( double v ) const;
     85    bool contains( double value ) const;
    6986
    70     void setTicks( int type, const QList<double> & );
    71     const QList<double> &ticks( int type ) const;
     87    void setTicks( int tickType, const QList<double> & );
     88    QList<double> ticks( int tickType ) const;
    7289
    73     void invalidate();
    74     bool isValid() const;
     90    bool isEmpty() const;
     91    bool isIncreasing() const;
    7592
    7693    void invert();
     94    QwtScaleDiv inverted() const;
     95
     96    QwtScaleDiv bounded( double lowerBound, double upperBound ) const;
    7797
    7898private:
     
    80100    double d_upperBound;
    81101    QList<double> d_ticks[NTickTypes];
    82 
    83     bool d_isValid;
    84102};
    85103
    86 Q_DECLARE_TYPEINFO(QwtScaleDiv, Q_MOVABLE_TYPE);
     104Q_DECLARE_TYPEINFO( QwtScaleDiv, Q_MOVABLE_TYPE );
    87105
    88 /*!
    89    Change the interval
    90    \param lowerBound lower bound
    91    \param upperBound upper bound
    92 */
    93 inline void QwtScaleDiv::setInterval( double lowerBound, double upperBound )
    94 {
    95     d_lowerBound = lowerBound;
    96     d_upperBound = upperBound;
    97 }
     106#ifndef QT_NO_DEBUG_STREAM
     107QWT_EXPORT QDebug operator<<( QDebug, const QwtScaleDiv & );
     108#endif
    98109
    99 /*!
    100   \return lowerBound -> upperBound
    101 */
    102 inline QwtInterval QwtScaleDiv::interval() const
    103 {
    104     return QwtInterval( d_lowerBound, d_upperBound );
    105 }
    106 
    107 /*!
    108   \return lower bound
    109   \sa upperBound()
    110 */
    111 inline double QwtScaleDiv::lowerBound() const
    112 {
    113     return d_lowerBound;
    114 }
    115 
    116 /*!
    117   \return upper bound
    118   \sa lowerBound()
    119 */
    120 inline double QwtScaleDiv::upperBound() const
    121 {
    122     return d_upperBound;
    123 }
    124 
    125 /*!
    126   \return upperBound() - lowerBound()
    127 */
    128 inline double QwtScaleDiv::range() const
    129 {
    130     return d_upperBound - d_lowerBound;
    131 }
    132110#endif
  • trunk/BNC/qwt/qwt_scale_draw.cpp

    r4271 r8127  
    1717#include <qmath.h>
    1818
     19#if QT_VERSION < 0x040601
     20#define qFastSin(x) qSin(x)
     21#define qFastCos(x) qCos(x)
     22#endif
     23
    1924class QwtScaleDraw::PrivateData
    2025{
     
    5964   Return alignment of the scale
    6065   \sa setAlignment()
     66   \return Alignment of the scale
    6167*/
    6268QwtScaleDraw::Alignment QwtScaleDraw::alignment() const
     
    6773/*!
    6874   Set the alignment of the scale
     75
     76   \param align Alignment of the scale
    6977
    7078   The default alignment is QwtScaleDraw::BottomScale
     
    8189  TopScale, BottomScale are horizontal (Qt::Horizontal) scales,
    8290  LeftScale, RightScale are vertical (Qt::Vertical) scales.
     91
     92  \return Orientation of the scale
    8393
    8494  \sa alignment()
     
    108118  \param end End border distance
    109119*/
    110 void QwtScaleDraw::getBorderDistHint( const QFont &font,
    111                                       int &start, int &end ) const
     120void QwtScaleDraw::getBorderDistHint(
     121    const QFont &font, int &start, int &end ) const
    112122{
    113123    start = 0;
    114     end = 0;
     124    end = 1.0;
    115125
    116126    if ( !hasComponent( QwtAbstractScaleDraw::Labels ) )
     
    189199
    190200    const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
    191     if ( ticks.count() == 0 )
     201    if ( ticks.isEmpty() )
    192202        return 0;
    193203
     
    200210    if ( vertical )
    201211    {
    202         bRect2.setRect( -bRect2.bottom(), 0, bRect2.height(), bRect2.width() );
    203     }
    204     int maxDist = 0;
     212        bRect2.setRect( -bRect2.bottom(), 0.0, bRect2.height(), bRect2.width() );
     213    }
     214
     215    double maxDist = 0.0;
    205216
    206217    for ( int i = 1; i < ticks.count(); i++ )
     
    210221        if ( vertical )
    211222        {
    212             bRect2.setRect( -bRect2.bottom(), 0,
     223            bRect2.setRect( -bRect2.bottom(), 0.0,
    213224                bRect2.height(), bRect2.width() );
    214225        }
    215226
    216         int dist = fm.leading(); // space between the labels
     227        double dist = fm.leading(); // space between the labels
    217228        if ( bRect1.right() > 0 )
    218229            dist += bRect1.right();
     
    224235    }
    225236
    226     double angle = labelRotation() / 180.0 * M_PI;
     237    double angle = qwtRadians( labelRotation() );
    227238    if ( vertical )
    228239        angle += M_PI / 2;
    229240
    230     if ( qSin( angle ) == 0.0 )
    231         return maxDist;
     241    const double sinA = qFastSin( angle ); // qreal -> double
     242    if ( qFuzzyCompare( sinA + 1.0, 1.0 ) )
     243        return qCeil( maxDist );
    232244
    233245    const int fmHeight = fm.ascent() - 2;
     
    235247    // The distance we need until there is
    236248    // the height of the label font. This height is needed
    237     // for the neighbour labal.
    238 
    239     int labelDist = qFloor( fmHeight / qSin( angle ) * qCos( angle ) );
     249    // for the neighbored label.
     250
     251    double labelDist = fmHeight / qFastSin( angle ) * qFastCos( angle );
    240252    if ( labelDist < 0 )
    241253        labelDist = -labelDist;
    242254
    243     // The cast above floored labelDist. We want to ceil.
    244     labelDist++;
    245 
    246255    // For text orientations close to the scale orientation
    247256
     
    255264        labelDist = fmHeight;
    256265
    257     return labelDist;
     266    return qCeil( labelDist );
    258267}
    259268
     
    267276
    268277   \param font Font used for painting the labels
     278   \return Extent
    269279
    270280   \sa minLength()
     
    292302    if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
    293303    {
    294         const double pw = qMax( 1, penWidth() );  // penwidth can be zero
     304        const double pw = qMax( 1, penWidth() );  // pen width can be zero
    295305        d += pw;
    296306    }
     
    304314
    305315   \param font Font used for painting the labels
     316   \return Minimum length that is needed to draw the scale
    306317
    307318   \sa extent()
     
    337348   Find the position, where to paint a label
    338349
    339    The position has a distance of majTickLength() + spacing() + 1
    340    from the backbone. The direction depends on the alignment()
     350   The position has a distance that depends on the length of the ticks
     351   in direction of the alignment().
    341352
    342353   \param value Value
     354   \return Position, where to paint a label
    343355*/
    344356QPointF QwtScaleDraw::labelPosition( double value ) const
     
    391403   \param painter Painter
    392404   \param value Value of the tick
    393    \param len Lenght of the tick
     405   \param len Length of the tick
    394406
    395407   \sa drawBackbone(), drawLabel()
     
    597609  overlapping labels.
    598610
     611  \param length Length of the backbone
     612
    599613  \sa move(), minLabelDist()
    600614*/
    601615void QwtScaleDraw::setLength( double length )
    602616{
     617#if 1
    603618    if ( length >= 0 && length < 10 )
    604619        length = 10;
     620
     621    // why should we accept negative lengths ???
    605622    if ( length < 0 && length > -10 )
    606623        length = -10;
     624#else
     625    length = qMax( length, 10 );
     626#endif
    607627
    608628    d_data->len = length;
     
    648668
    649669/*!
    650   Find the bounding rect for the label. The coordinates of
    651   the rect are absolute coordinates ( calculated from pos() ).
     670  \brief Find the bounding rectangle for the label.
     671
     672  The coordinates of the rectangle are absolute ( calculated from pos() ).
    652673  in direction of the tick.
    653674
     
    655676  \param value Value
    656677
     678  \return Bounding rectangle
    657679  \sa labelRect()
    658680*/
     
    677699   \param size Size of the label
    678700
     701   \return Transformation matrix
    679702   \sa setLabelAlignment(), setLabelRotation()
    680703*/
     
    740763
    741764/*!
    742   Find the bounding rect for the label. The coordinates of
    743   the rect are relative to spacing + ticklength from the backbone
     765  Find the bounding rectangle for the label. The coordinates of
     766  the rectangle are relative to spacing + tick length from the backbone
    744767  in direction of the tick.
    745768
    746769  \param font Font used for painting
    747770  \param value Value
     771
     772   \return Bounding rectangle that is needed to draw a label
    748773*/
    749774QRectF QwtScaleDraw::labelRect( const QFont &font, double value ) const
     
    769794   \param font Label font
    770795   \param value Value
     796
     797   \return Size that is needed to draw a label
    771798*/
    772799QSizeF QwtScaleDraw::labelSize( const QFont &font, double value ) const
     
    805832  \brief Change the label flags
    806833
    807   Labels are aligned to the point ticklength + spacing away from the backbone.
     834  Labels are aligned to the point tick length + spacing away from the backbone.
    808835
    809836  The alignment is relative to the orientation of the label text.
     
    824851           The alignment of the label is not the alignment
    825852           of the scale and is not the alignment of the flags
    826            (QwtText::flags()) returned from QwtAbstractScaleDraw::label().
     853           ( QwtText::flags() ) returned from QwtAbstractScaleDraw::label().
    827854*/
    828855
     
    847874int QwtScaleDraw::maxLabelWidth( const QFont &font ) const
    848875{
    849     int maxWidth = 0;
     876    double maxWidth = 0.0;
    850877
    851878    const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
     
    855882        if ( scaleDiv().contains( v ) )
    856883        {
    857             const int w = labelSize( font, ticks[i] ).width();
     884            const double w = labelSize( font, ticks[i] ).width();
    858885            if ( w > maxWidth )
    859886                maxWidth = w;
     
    861888    }
    862889
    863     return maxWidth;
     890    return qCeil( maxWidth );
    864891}
    865892
     
    870897int QwtScaleDraw::maxLabelHeight( const QFont &font ) const
    871898{
    872     int maxHeight = 0;
     899    double maxHeight = 0.0;
    873900
    874901    const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
     
    878905        if ( scaleDiv().contains( v ) )
    879906        {
    880             const int h = labelSize( font, ticks[i] ).height();
     907            const double h = labelSize( font, ticks[i] ).height();
    881908            if ( h > maxHeight )
    882909                maxHeight = h;
     
    884911    }
    885912
    886     return maxHeight;
     913    return qCeil( maxHeight );
    887914}
    888915
  • trunk/BNC/qwt/qwt_scale_draw.h

    r4271 r8127  
    2929  the scale can be drawn with the QwtAbstractScaleDraw::draw() member.
    3030*/
    31 
    3231class QWT_EXPORT QwtScaleDraw: public QwtAbstractScaleDraw
    3332{
     
    108107/*!
    109108   Move the position of the scale
     109
     110   \param x X coordinate
     111   \param y Y coordinate
     112
    110113   \sa move(const QPointF &)
    111114*/
  • trunk/BNC/qwt/qwt_scale_engine.cpp

    r4271 r8127  
    1313#include <qalgorithms.h>
    1414#include <qmath.h>
     15#include <float.h>
     16#include <limits>
    1517
    1618#if QT_VERSION < 0x040601
     
    1921#endif
    2022
     23static inline double qwtLog( double base, double value )
     24{
     25    return log( value ) / log( base );
     26}
     27
     28static inline QwtInterval qwtLogInterval( double base, const QwtInterval &interval )
     29{
     30    return QwtInterval( qwtLog( base, interval.minValue() ),
     31            qwtLog( base, interval.maxValue() ) );
     32}
     33
     34static inline QwtInterval qwtPowInterval( double base, const QwtInterval &interval )
     35{
     36    return QwtInterval( qPow( base, interval.minValue() ),
     37            qPow( base, interval.maxValue() ) );
     38}
     39
     40static inline long double qwtIntervalWidthL( const QwtInterval &interval )
     41{
     42    if ( !interval.isValid() )
     43        return 0.0;
     44
     45    return static_cast<long double>( interval.maxValue() )
     46        - static_cast<long double>( interval.minValue() );
     47}
     48
     49#if 1
     50
     51// this version often doesn't find the best ticks: f.e for 15: 5, 10
     52static double qwtStepSize( double intervalSize, int maxSteps, uint base )
     53{
     54    const double minStep =
     55        QwtScaleArithmetic::divideInterval( intervalSize, maxSteps, base );
     56
     57    if ( minStep != 0.0 )
     58    {
     59        // # ticks per interval
     60        const int numTicks = qCeil( qAbs( intervalSize / minStep ) ) - 1;
     61
     62        // Do the minor steps fit into the interval?
     63        if ( qwtFuzzyCompare( ( numTicks +  1 ) * qAbs( minStep ),
     64            qAbs( intervalSize ), intervalSize ) > 0 )
     65        {
     66            // The minor steps doesn't fit into the interval
     67            return 0.5 * intervalSize;
     68        }
     69    }
     70
     71    return minStep;
     72}
     73
     74#else
     75
     76static double qwtStepSize( double intervalSize, int maxSteps, uint base )
     77{
     78    if ( maxSteps <= 0 )
     79        return 0.0;
     80
     81    if ( maxSteps > 2 )
     82    {
     83        for ( int numSteps = maxSteps; numSteps > 1; numSteps-- )
     84        {
     85            const double stepSize = intervalSize / numSteps;
     86
     87            const double p = ::floor( ::log( stepSize ) / ::log( base ) );
     88            const double fraction = qPow( base, p );
     89
     90            for ( uint n = base; n > 1; n /= 2 )
     91            {
     92                if ( qFuzzyCompare( stepSize, n * fraction ) )
     93                    return stepSize;
     94
     95                if ( n == 3 && ( base % 2 ) == 0 )
     96                {
     97                    if ( qFuzzyCompare( stepSize, 2 * fraction ) )
     98                        return stepSize;
     99                }
     100            }
     101        }
     102    }
     103
     104    return intervalSize * 0.5;
     105}
     106
     107#endif
     108
    21109static const double _eps = 1.0e-6;
    22110
     
    24112  Ceil a value, relative to an interval
    25113
    26   \param value Value to ceil
     114  \param value Value to be ceiled
    27115  \param intervalSize Interval size
     116
     117  \return Rounded value
    28118
    29119  \sa floorEps()
     
    35125
    36126    value = ( value - eps ) / intervalSize;
    37     return qwtCeilF( value ) * intervalSize;
     127    return ::ceil( value ) * intervalSize;
    38128}
    39129
     
    41131  Floor a value, relative to an interval
    42132
    43   \param value Value to floor
     133  \param value Value to be floored
    44134  \param intervalSize Interval size
    45135
     136  \return Rounded value
    46137  \sa floorEps()
    47138*/
     
    51142
    52143    value = ( value + eps ) / intervalSize;
    53     return qwtFloorF( value ) * intervalSize;
     144    return ::floor( value ) * intervalSize;
    54145}
    55146
     
    72163
    73164/*!
    74   Find the smallest value out of {1,2,5}*10^n with an integer number n
    75   which is greater than or equal to x
    76 
    77   \param x Input value
    78 */
    79 double QwtScaleArithmetic::ceil125( double x )
    80 {
    81     if ( x == 0.0 )
     165  Calculate a step size for a given interval
     166
     167  \param intervalSize Interval size
     168  \param numSteps Number of steps
     169  \param base Base for the division ( usually 10 )
     170
     171  \return Calculated step size
     172 */
     173double QwtScaleArithmetic::divideInterval(
     174    double intervalSize, int numSteps, uint base )
     175{
     176    if ( numSteps <= 0 )
    82177        return 0.0;
    83178
    84     const double sign = ( x > 0 ) ? 1.0 : -1.0;
    85     const double lx = ::log10( qFabs( x ) );
    86     const double p10 = qwtFloorF( lx );
    87 
    88     double fr = qPow( 10.0, lx - p10 );
    89     if ( fr <= 1.0 )
    90         fr = 1.0;
    91     else if ( fr <= 2.0 )
    92         fr = 2.0;
    93     else if ( fr <= 5.0 )
    94         fr = 5.0;
    95     else
    96         fr = 10.0;
    97 
    98     return sign * fr * qPow( 10.0, p10 );
    99 }
    100 
    101 /*!
    102   \brief Find the largest value out of {1,2,5}*10^n with an integer number n
    103   which is smaller than or equal to x
    104 
    105   \param x Input value
    106 */
    107 double QwtScaleArithmetic::floor125( double x )
    108 {
    109     if ( x == 0.0 )
     179    const double v = QwtScaleArithmetic::divideEps( intervalSize, numSteps );
     180    if ( v == 0.0 )
    110181        return 0.0;
    111182
    112     double sign = ( x > 0 ) ? 1.0 : -1.0;
    113     const double lx = ::log10( qFabs( x ) );
    114     const double p10 = qwtFloorF( lx );
    115 
    116     double fr = qPow( 10.0, lx - p10 );
    117     if ( fr >= 10.0 )
    118         fr = 10.0;
    119     else if ( fr >= 5.0 )
    120         fr = 5.0;
    121     else if ( fr >= 2.0 )
    122         fr = 2.0;
    123     else
    124         fr = 1.0;
    125 
    126     return sign * fr * qPow( 10.0, p10 );
     183    const double lx = qwtLog( base, qFabs( v ) );
     184    const double p = ::floor( lx );
     185
     186    const double fraction = qPow( base, lx - p );
     187
     188    uint n = base;
     189    while ( ( n > 1 ) && ( fraction <= n / 2 ) )
     190        n /= 2;
     191
     192    double stepSize = n * qPow( base, p );
     193    if ( v < 0 )
     194        stepSize = -stepSize;
     195
     196    return stepSize;
    127197}
    128198
     
    134204        lowerMargin( 0.0 ),
    135205        upperMargin( 0.0 ),
    136         referenceValue( 0.0 )
    137     {
    138     }
    139 
    140     QwtScaleEngine::Attributes attributes;       // scale attributes
    141 
    142     double lowerMargin;      // margins
     206        referenceValue( 0.0 ),
     207        base( 10 ),
     208        transform( NULL )
     209    {
     210    }
     211
     212    ~PrivateData()
     213    {
     214        delete transform;
     215    }
     216
     217    QwtScaleEngine::Attributes attributes;
     218
     219    double lowerMargin;
    143220    double upperMargin;
    144221
    145     double referenceValue; // reference value
    146 
     222    double referenceValue;
     223
     224    uint base;
     225
     226    QwtTransform* transform;
    147227};
    148228
    149 //! Constructor
    150 QwtScaleEngine::QwtScaleEngine()
     229/*!
     230  Constructor
     231
     232  \param base Base of the scale engine
     233  \sa setBase()
     234 */
     235QwtScaleEngine::QwtScaleEngine( uint base )
    151236{
    152237    d_data = new PrivateData;
     238    setBase( base );
    153239}
    154240
     
    158244{
    159245    delete d_data;
     246}
     247
     248/*!
     249   Assign a transformation
     250
     251   \param transform Transformation
     252
     253   The transformation object is used as factory for clones
     254   that are returned by transformation()
     255
     256   The scale engine takes ownership of the transformation.
     257
     258   \sa QwtTransform::copy(), transformation()
     259
     260 */
     261void QwtScaleEngine::setTransformation( QwtTransform *transform )
     262{
     263    if ( transform != d_data->transform )
     264    {
     265        delete d_data->transform;
     266        d_data->transform = transform;
     267    }
     268}
     269
     270/*!
     271   Create and return a clone of the transformation
     272   of the engine. When the engine has no special transformation
     273   NULL is returned, indicating no transformation.
     274
     275   \return A clone of the transfomation
     276   \sa setTransformation()
     277 */
     278QwtTransform *QwtScaleEngine::transformation() const
     279{
     280    QwtTransform *transform = NULL;
     281    if ( d_data->transform )
     282        transform = d_data->transform->copy();
     283
     284    return transform;
    160285}
    161286
     
    193318
    194319  \warning
    195   \li QwtLog10ScaleEngine measures the margins in decades.
     320  \li QwtLogScaleEngine measures the margins in decades.
    196321
    197322  \sa upperMargin(), lowerMargin()
     
    215340    double intervalSize, int numSteps ) const
    216341{
    217     if ( numSteps <= 0 )
    218         return 0.0;
    219 
    220     double v = QwtScaleArithmetic::divideEps( intervalSize, numSteps );
    221     return QwtScaleArithmetic::ceil125( v );
     342    return QwtScaleArithmetic::divideInterval(
     343        intervalSize, numSteps, d_data->base );
    222344}
    223345
     
    228350  \param value Value
    229351
    230   \sa QwtScaleArithmetic::compareEps()
     352  \return True, when the value is inside the interval
    231353*/
    232354bool QwtScaleEngine::contains(
     
    275397
    276398/*!
    277   \brief Build an interval for a value
     399  \brief Build an interval around a value
    278400
    279401  In case of v == 0.0 the interval is [-0.5, 0.5],
    280402  otherwide it is [0.5 * v, 1.5 * v]
    281 */
    282 
    283 QwtInterval QwtScaleEngine::buildInterval( double v ) const
    284 {
    285     const double delta = ( v == 0.0 ) ? 0.5 : qAbs( 0.5 * v );
    286     return QwtInterval( v - delta, v + delta );
     403
     404  \param value Initial value
     405  \return Calculated interval
     406*/
     407
     408QwtInterval QwtScaleEngine::buildInterval( double value ) const
     409{
     410    const double delta = ( value == 0.0 ) ? 0.5 : qAbs( 0.5 * value );
     411
     412    if ( DBL_MAX - delta < value )
     413        return QwtInterval( DBL_MAX - delta, DBL_MAX );
     414
     415    if ( -DBL_MAX + delta > value )
     416        return QwtInterval( -DBL_MAX, -DBL_MAX + delta );
     417
     418    return QwtInterval( value - delta, value + delta );
    287419}
    288420
     
    304436
    305437/*!
    306   Check if a attribute is set.
     438  \return True, if attribute is enabled.
    307439
    308440  \param attribute Attribute to be tested
     
    326458
    327459/*!
    328   Return the scale attributes
     460  \return Scale attributes
    329461  \sa Attribute, setAttributes(), testAttribute()
    330462*/
     
    349481
    350482/*!
    351  \return the reference value
    352  \sa setReference(), setAttribute()
     483  \return the reference value
     484  \sa setReference(), setAttribute()
    353485*/
    354486double QwtScaleEngine::reference() const
     
    358490
    359491/*!
    360   Return a transformation, for linear scales
    361 */
    362 QwtScaleTransformation *QwtLinearScaleEngine::transformation() const
    363 {
    364     return new QwtScaleTransformation( QwtScaleTransformation::Linear );
    365 }
    366 
    367 /*!
    368     Align and divide an interval
    369 
    370    \param maxNumSteps Max. number of steps
    371    \param x1 First limit of the interval (In/Out)
    372    \param x2 Second limit of the interval (In/Out)
    373    \param stepSize Step size (Out)
    374 
    375    \sa setAttribute()
     492  Set the base of the scale engine
     493
     494  While a base of 10 is what 99.9% of all applications need
     495  certain scales might need a different base: f.e 2
     496
     497  The default setting is 10
     498
     499  \param base Base of the engine
     500
     501  \sa base()
     502 */
     503void QwtScaleEngine::setBase( uint base )
     504{
     505    d_data->base = qMax( base, 2U );
     506}
     507
     508/*!
     509  \return base Base of the scale engine
     510  \sa setBase()
     511 */
     512uint QwtScaleEngine::base() const
     513{
     514    return d_data->base;
     515}
     516
     517/*!
     518  Constructor
     519
     520  \param base Base of the scale engine
     521  \sa setBase()
     522 */
     523QwtLinearScaleEngine::QwtLinearScaleEngine( uint base ):
     524    QwtScaleEngine( base )
     525{
     526}
     527
     528//! Destructor
     529QwtLinearScaleEngine::~QwtLinearScaleEngine()
     530{
     531}
     532
     533/*!
     534  Align and divide an interval
     535
     536  \param maxNumSteps Max. number of steps
     537  \param x1 First limit of the interval (In/Out)
     538  \param x2 Second limit of the interval (In/Out)
     539  \param stepSize Step size (Out)
     540
     541  \sa setAttribute()
    376542*/
    377543void QwtLinearScaleEngine::autoScale( int maxNumSteps,
     
    393559        interval = buildInterval( interval.minValue() );
    394560
    395     stepSize = divideInterval( interval.width(), qMax( maxNumSteps, 1 ) );
     561    stepSize = QwtScaleArithmetic::divideInterval(
     562        interval.width(), qMax( maxNumSteps, 1 ), base() );
    396563
    397564    if ( !testAttribute( QwtScaleEngine::Floating ) )
     
    409576
    410577/*!
    411    \brief Calculate a scale division
     578   \brief Calculate a scale division for an interval
    412579
    413580   \param x1 First interval limit
    414581   \param x2 Second interval limit
    415    \param maxMajSteps Maximum for the number of major steps
    416    \param maxMinSteps Maximum number of minor steps
    417    \param stepSize Step size. If stepSize == 0, the scaleEngine
     582   \param maxMajorSteps Maximum for the number of major steps
     583   \param maxMinorSteps Maximum number of minor steps
     584   \param stepSize Step size. If stepSize == 0, the engine
    418585                   calculates one.
    419586
    420    \sa QwtScaleEngine::stepSize(), QwtScaleEngine::subDivide()
     587   \return Calculated scale division
    421588*/
    422589QwtScaleDiv QwtLinearScaleEngine::divideScale( double x1, double x2,
    423     int maxMajSteps, int maxMinSteps, double stepSize ) const
     590    int maxMajorSteps, int maxMinorSteps, double stepSize ) const
    424591{
    425592    QwtInterval interval = QwtInterval( x1, x2 ).normalized();
     593
     594    if ( qwtIntervalWidthL( interval ) > std::numeric_limits<double>::max() )
     595    {
     596        qWarning() << "QwtLinearScaleEngine::divideScale: overflow";
     597        return QwtScaleDiv();
     598    }
     599
    426600    if ( interval.width() <= 0 )
    427601        return QwtScaleDiv();
     
    430604    if ( stepSize == 0.0 )
    431605    {
    432         if ( maxMajSteps < 1 )
    433             maxMajSteps = 1;
    434 
    435         stepSize = divideInterval( interval.width(), maxMajSteps );
     606        if ( maxMajorSteps < 1 )
     607            maxMajorSteps = 1;
     608
     609        stepSize = QwtScaleArithmetic::divideInterval(
     610            interval.width(), maxMajorSteps, base() );
    436611    }
    437612
     
    441616    {
    442617        QList<double> ticks[QwtScaleDiv::NTickTypes];
    443         buildTicks( interval, stepSize, maxMinSteps, ticks );
     618        buildTicks( interval, stepSize, maxMinorSteps, ticks );
    444619
    445620        scaleDiv = QwtScaleDiv( interval, ticks );
     
    457632   \param interval Interval
    458633   \param stepSize Step size
    459    \param maxMinSteps Maximum number of minor steps
     634   \param maxMinorSteps Maximum number of minor steps
    460635   \param ticks Arrays to be filled with the calculated ticks
    461636
     
    463638*/
    464639void QwtLinearScaleEngine::buildTicks(
    465     const QwtInterval& interval, double stepSize, int maxMinSteps,
     640    const QwtInterval& interval, double stepSize, int maxMinorSteps,
    466641    QList<double> ticks[QwtScaleDiv::NTickTypes] ) const
    467642{
    468     const QwtInterval boundingInterval =
    469         align( interval, stepSize );
     643    const QwtInterval boundingInterval = align( interval, stepSize );
    470644
    471645    ticks[QwtScaleDiv::MajorTick] =
    472646        buildMajorTicks( boundingInterval, stepSize );
    473647
    474     if ( maxMinSteps > 0 )
    475     {
    476         buildMinorTicks( ticks[QwtScaleDiv::MajorTick], maxMinSteps, stepSize,
     648    if ( maxMinorSteps > 0 )
     649    {
     650        buildMinorTicks( ticks[QwtScaleDiv::MajorTick], maxMinorSteps, stepSize,
    477651            ticks[QwtScaleDiv::MinorTick], ticks[QwtScaleDiv::MediumTick] );
    478652    }
     
    522696
    523697   \param majorTicks Major ticks
    524    \param maxMinSteps Maximum number of minor steps
     698   \param maxMinorSteps Maximum number of minor steps
    525699   \param stepSize Step size
    526700   \param minorTicks Array to be filled with the calculated minor ticks
     
    530704void QwtLinearScaleEngine::buildMinorTicks(
    531705    const QList<double>& majorTicks,
    532     int maxMinSteps, double stepSize,
     706    int maxMinorSteps, double stepSize,
    533707    QList<double> &minorTicks,
    534708    QList<double> &mediumTicks ) const
    535709{
    536     double minStep = divideInterval( stepSize, maxMinSteps );
     710    double minStep = qwtStepSize( stepSize, maxMinorSteps, base() );
    537711    if ( minStep == 0.0 )
    538712        return;
    539713
    540714    // # ticks per interval
    541     int numTicks = qCeil( qAbs( stepSize / minStep ) ) - 1;
    542 
    543     // Do the minor steps fit into the interval?
    544     if ( qwtFuzzyCompare( ( numTicks +  1 ) * qAbs( minStep ),
    545         qAbs( stepSize ), stepSize ) > 0 )
    546     {
    547         numTicks = 1;
    548         minStep = stepSize * 0.5;
    549     }
     715    const int numTicks = qCeil( qAbs( stepSize / minStep ) ) - 1;
    550716
    551717    int medIndex = -1;
     
    588754    const QwtInterval &interval, double stepSize ) const
    589755{
    590     double x1 = QwtScaleArithmetic::floorEps( interval.minValue(), stepSize );
    591     if ( qwtFuzzyCompare( interval.minValue(), x1, stepSize ) == 0 )
    592         x1 = interval.minValue();
    593 
    594     double x2 = QwtScaleArithmetic::ceilEps( interval.maxValue(), stepSize );
    595     if ( qwtFuzzyCompare( interval.maxValue(), x2, stepSize ) == 0 )
    596         x2 = interval.maxValue();
     756    double x1 = interval.minValue();
     757    double x2 = interval.maxValue();
     758
     759    // when there is no rounding beside some effect, when
     760    // calculating with doubles, we keep the original value
     761
     762    const double eps = 0.000000000001; // since Qt 4.8: qFuzzyIsNull
     763    if ( -DBL_MAX + stepSize <= x1 )
     764    {
     765        const double x = QwtScaleArithmetic::floorEps( x1, stepSize );
     766        if ( qAbs(x) <= eps || !qFuzzyCompare( x1, x ) )
     767            x1 = x;
     768    }
     769
     770    if ( DBL_MAX - stepSize >= x2 )
     771    {
     772        const double x = QwtScaleArithmetic::ceilEps( x2, stepSize );
     773        if ( qAbs(x) <= eps || !qFuzzyCompare( x2, x ) )
     774            x2 = x;
     775    }
    597776
    598777    return QwtInterval( x1, x2 );
     
    600779
    601780/*!
    602   Return a transformation, for logarithmic (base 10) scales
    603 */
    604 QwtScaleTransformation *QwtLog10ScaleEngine::transformation() const
    605 {
    606     return new QwtScaleTransformation( QwtScaleTransformation::Log10 );
     781  Constructor
     782
     783  \param base Base of the scale engine
     784  \sa setBase()
     785 */
     786QwtLogScaleEngine::QwtLogScaleEngine( uint base ):
     787    QwtScaleEngine( base )
     788{
     789    setTransformation( new QwtLogTransform() );
     790}
     791
     792//! Destructor
     793QwtLogScaleEngine::~QwtLogScaleEngine()
     794{
    607795}
    608796
     
    617805   \sa QwtScaleEngine::setAttribute()
    618806*/
    619 void QwtLog10ScaleEngine::autoScale( int maxNumSteps,
    620                                      double &x1, double &x2, double &stepSize ) const
     807void QwtLogScaleEngine::autoScale( int maxNumSteps,
     808    double &x1, double &x2, double &stepSize ) const
    621809{
    622810    if ( x1 > x2 )
    623811        qSwap( x1, x2 );
    624812
    625     QwtInterval interval( x1 / qPow( 10.0, lowerMargin() ),
    626         x2 * qPow( 10.0, upperMargin() ) );
    627 
    628     if ( interval.maxValue() / interval.minValue() < 10.0 )
    629     {
    630         // scale width is less than one decade -> build linear scale
     813    const double logBase = base();
     814
     815    QwtInterval interval( x1 / qPow( logBase, lowerMargin() ),
     816        x2 * qPow( logBase, upperMargin() ) );
     817
     818    if ( interval.maxValue() / interval.minValue() < logBase )
     819    {
     820        // scale width is less than one step -> try to build a linear scale
    631821
    632822        QwtLinearScaleEngine linearScaler;
     
    636826
    637827        linearScaler.autoScale( maxNumSteps, x1, x2, stepSize );
    638         stepSize = ::log10( stepSize );
    639 
    640         return;
     828
     829        QwtInterval linearInterval = QwtInterval( x1, x2 ).normalized();
     830        linearInterval = linearInterval.limited( LOG_MIN, LOG_MAX );
     831
     832        if ( linearInterval.maxValue() / linearInterval.minValue() < logBase )
     833        {
     834            // the aligned scale is still less than one step
     835
     836#if 1
     837            // this code doesn't make any sense, but for compatibility
     838            // reasons we keep it until 6.2. But it will be ignored
     839            // in divideScale
     840
     841            if ( stepSize < 0.0 )
     842                stepSize = -qwtLog( logBase, qAbs( stepSize ) );
     843            else
     844                stepSize = qwtLog( logBase, stepSize );
     845#endif
     846
     847            return;
     848        }
    641849    }
    642850
     
    660868        interval = buildInterval( interval.minValue() );
    661869
    662     stepSize = divideInterval( log10( interval ).width(), qMax( maxNumSteps, 1 ) );
     870    stepSize = divideInterval( qwtLogInterval( logBase, interval ).width(),
     871        qMax( maxNumSteps, 1 ) );
    663872    if ( stepSize < 1.0 )
    664873        stepSize = 1.0;
     
    678887
    679888/*!
    680    \brief Calculate a scale division
     889   \brief Calculate a scale division for an interval
    681890
    682891   \param x1 First interval limit
    683892   \param x2 Second interval limit
    684    \param maxMajSteps Maximum for the number of major steps
    685    \param maxMinSteps Maximum number of minor steps
    686    \param stepSize Step size. If stepSize == 0, the scaleEngine
     893   \param maxMajorSteps Maximum for the number of major steps
     894   \param maxMinorSteps Maximum number of minor steps
     895   \param stepSize Step size. If stepSize == 0, the engine
    687896                   calculates one.
    688897
    689    \sa QwtScaleEngine::stepSize(), QwtLog10ScaleEngine::subDivide()
    690 */
    691 QwtScaleDiv QwtLog10ScaleEngine::divideScale( double x1, double x2,
    692     int maxMajSteps, int maxMinSteps, double stepSize ) const
     898   \return Calculated scale division
     899*/
     900QwtScaleDiv QwtLogScaleEngine::divideScale( double x1, double x2,
     901    int maxMajorSteps, int maxMinorSteps, double stepSize ) const
    693902{
    694903    QwtInterval interval = QwtInterval( x1, x2 ).normalized();
     
    698907        return QwtScaleDiv();
    699908
    700     if ( interval.maxValue() / interval.minValue() < 10.0 )
     909    const double logBase = base();
     910
     911    if ( interval.maxValue() / interval.minValue() < logBase )
    701912    {
    702913        // scale width is less than one decade -> build linear scale
     
    707918        linearScaler.setMargins( lowerMargin(), upperMargin() );
    708919
    709         if ( stepSize != 0.0 )
    710             stepSize = qPow( 10.0, stepSize );
    711 
    712920        return linearScaler.divideScale( x1, x2,
    713             maxMajSteps, maxMinSteps, stepSize );
     921            maxMajorSteps, maxMinorSteps, 0.0 );
    714922    }
    715923
     
    717925    if ( stepSize == 0.0 )
    718926    {
    719         if ( maxMajSteps < 1 )
    720             maxMajSteps = 1;
    721 
    722         stepSize = divideInterval( log10( interval ).width(), maxMajSteps );
     927        if ( maxMajorSteps < 1 )
     928            maxMajorSteps = 1;
     929
     930        stepSize = divideInterval(
     931            qwtLogInterval( logBase, interval ).width(), maxMajorSteps );
    723932        if ( stepSize < 1.0 )
    724933            stepSize = 1.0; // major step must be >= 1 decade
     
    729938    {
    730939        QList<double> ticks[QwtScaleDiv::NTickTypes];
    731         buildTicks( interval, stepSize, maxMinSteps, ticks );
     940        buildTicks( interval, stepSize, maxMinorSteps, ticks );
    732941
    733942        scaleDiv = QwtScaleDiv( interval, ticks );
     
    744953
    745954   \param interval Interval
    746    \param maxMinSteps Maximum number of minor steps
     955   \param maxMinorSteps Maximum number of minor steps
    747956   \param stepSize Step size
    748957   \param ticks Arrays to be filled with the calculated ticks
     
    750959   \sa buildMajorTicks(), buildMinorTicks
    751960*/
    752 void QwtLog10ScaleEngine::buildTicks(
    753     const QwtInterval& interval, double stepSize, int maxMinSteps,
     961void QwtLogScaleEngine::buildTicks(
     962    const QwtInterval& interval, double stepSize, int maxMinorSteps,
    754963    QList<double> ticks[QwtScaleDiv::NTickTypes] ) const
    755964{
     
    759968        buildMajorTicks( boundingInterval, stepSize );
    760969
    761     if ( maxMinSteps > 0 )
    762     {
    763         ticks[QwtScaleDiv::MinorTick] = buildMinorTicks(
    764             ticks[QwtScaleDiv::MajorTick], maxMinSteps, stepSize );
     970    if ( maxMinorSteps > 0 )
     971    {
     972        buildMinorTicks( ticks[QwtScaleDiv::MajorTick], maxMinorSteps, stepSize,
     973            ticks[QwtScaleDiv::MinorTick], ticks[QwtScaleDiv::MediumTick] );
    765974    }
    766975
     
    777986   \return Calculated ticks
    778987*/
    779 QList<double> QwtLog10ScaleEngine::buildMajorTicks(
     988QList<double> QwtLogScaleEngine::buildMajorTicks(
    780989    const QwtInterval &interval, double stepSize ) const
    781990{
    782     double width = log10( interval ).width();
     991    double width = qwtLogInterval( base(), interval ).width();
    783992
    784993    int numTicks = qRound( width / stepSize ) + 1;
     
    8061015
    8071016   \param majorTicks Major ticks
    808    \param maxMinSteps Maximum number of minor steps
     1017   \param maxMinorSteps Maximum number of minor steps
    8091018   \param stepSize Step size
    810 */
    811 QList<double> QwtLog10ScaleEngine::buildMinorTicks(
     1019   \param minorTicks Array to be filled with the calculated minor ticks
     1020   \param mediumTicks Array to be filled with the calculated medium ticks
     1021*/
     1022void QwtLogScaleEngine::buildMinorTicks(
    8121023    const QList<double> &majorTicks,
    813     int maxMinSteps, double stepSize ) const
    814 {
    815     if ( stepSize < 1.1 )          // major step width is one decade
    816     {
    817         if ( maxMinSteps < 1 )
    818             return QList<double>();
    819 
    820         int k0, kstep, kmax;
    821 
    822         if ( maxMinSteps >= 8 )
     1024    int maxMinorSteps, double stepSize,
     1025    QList<double> &minorTicks,
     1026    QList<double> &mediumTicks ) const
     1027{
     1028    const double logBase = base();
     1029
     1030    if ( stepSize < 1.1 )          // major step width is one base
     1031    {
     1032        double minStep = divideInterval( stepSize, maxMinorSteps + 1 );
     1033        if ( minStep == 0.0 )
     1034            return;
     1035       
     1036        const int numSteps = qRound( stepSize / minStep );
     1037
     1038        int mediumTickIndex = -1;
     1039        if ( ( numSteps > 2 ) && ( numSteps % 2 == 0 ) )
     1040            mediumTickIndex = numSteps / 2;
     1041
     1042        for ( int i = 0; i < majorTicks.count() - 1; i++ )
    8231043        {
    824             k0 = 2;
    825             kmax = 9;
    826             kstep = 1;
     1044            const double v = majorTicks[i];
     1045            const double s = logBase / numSteps;
     1046
     1047            if ( s >= 1.0 )
     1048            {
     1049                if ( !qFuzzyCompare( s, 1.0 ) )
     1050                    minorTicks += v * s;
     1051
     1052                for ( int j = 2; j < numSteps; j++ )
     1053                {
     1054                    minorTicks += v * j * s;
     1055                }
     1056            }
     1057            else
     1058            {
     1059                for ( int j = 1; j < numSteps; j++ )
     1060                {
     1061                    const double tick = v + j * v * ( logBase - 1 ) / numSteps;
     1062                    if ( j == mediumTickIndex )
     1063                        mediumTicks += tick;
     1064                    else
     1065                        minorTicks += tick;
     1066                }
     1067            }
    8271068        }
    828         else if ( maxMinSteps >= 4 )
     1069    }
     1070    else
     1071    {
     1072        double minStep = divideInterval( stepSize, maxMinorSteps );
     1073        if ( minStep == 0.0 )
     1074            return;
     1075
     1076        if ( minStep < 1.0 )
     1077            minStep = 1.0;
     1078
     1079        // # subticks per interval
     1080        int numTicks = qRound( stepSize / minStep ) - 1;
     1081
     1082        // Do the minor steps fit into the interval?
     1083        if ( qwtFuzzyCompare( ( numTicks +  1 ) * minStep,
     1084            stepSize, stepSize ) > 0 )
    8291085        {
    830             k0 = 2;
    831             kmax = 8;
    832             kstep = 2;
     1086            numTicks = 0;
    8331087        }
    834         else if ( maxMinSteps >= 2 )
    835         {
    836             k0 = 2;
    837             kmax = 5;
    838             kstep = 3;
    839         }
    840         else
    841         {
    842             k0 = 5;
    843             kmax = 5;
    844             kstep = 1;
    845         }
    846 
    847         QList<double> minorTicks;
     1088
     1089        if ( numTicks < 1 )
     1090            return;
     1091
     1092        int mediumTickIndex = -1;
     1093        if ( ( numTicks > 2 ) && ( numTicks % 2 ) )
     1094            mediumTickIndex = numTicks / 2;
     1095
     1096        // substep factor = base^substeps
     1097        const qreal minFactor = qMax( qPow( logBase, minStep ), qreal( logBase ) );
    8481098
    8491099        for ( int i = 0; i < majorTicks.count(); i++ )
    8501100        {
    851             const double v = majorTicks[i];
    852             for ( int k = k0; k <= kmax; k += kstep )
    853                 minorTicks += v * double( k );
    854         }
    855 
    856         return minorTicks;
    857     }
    858     else  // major step > one decade
    859     {
    860         double minStep = divideInterval( stepSize, maxMinSteps );
    861         if ( minStep == 0.0 )
    862             return QList<double>();
    863 
    864         if ( minStep < 1.0 )
    865             minStep = 1.0;
    866 
    867         // # subticks per interval
    868         int nMin = qRound( stepSize / minStep ) - 1;
    869 
    870         // Do the minor steps fit into the interval?
    871 
    872         if ( qwtFuzzyCompare( ( nMin +  1 ) * minStep,
    873             qAbs( stepSize ), stepSize ) > 0 )
    874         {
    875             nMin = 0;
    876         }
    877 
    878         if ( nMin < 1 )
    879             return QList<double>();      // no subticks
    880 
    881         // substep factor = 10^substeps
    882         const qreal minFactor = qMax( qPow( 10.0, minStep ), qreal( 10.0 ) );
    883 
    884         QList<double> minorTicks;
    885         for ( int i = 0; i < majorTicks.count(); i++ )
    886         {
    887             double val = majorTicks[i];
    888             for ( int k = 0; k < nMin; k++ )
     1101            double tick = majorTicks[i];
     1102            for ( int j = 0; j < numTicks; j++ )
    8891103            {
    890                 val *= minFactor;
    891                 minorTicks += val;
     1104                tick *= minFactor;
     1105
     1106                if ( j == mediumTickIndex )
     1107                    mediumTicks += tick;
     1108                else
     1109                    minorTicks += tick;
    8921110            }
    8931111        }
    894         return minorTicks;
    8951112    }
    8961113}
     
    9071124  \return Aligned interval
    9081125*/
    909 QwtInterval QwtLog10ScaleEngine::align(
     1126QwtInterval QwtLogScaleEngine::align(
    9101127    const QwtInterval &interval, double stepSize ) const
    9111128{
    912     const QwtInterval intv = log10( interval );
     1129    const QwtInterval intv = qwtLogInterval( base(), interval );
    9131130
    9141131    double x1 = QwtScaleArithmetic::floorEps( intv.minValue(), stepSize );
     
    9201137        x2 = interval.maxValue();
    9211138
    922     return pow10( QwtInterval( x1, x2 ) );
    923 }
    924 
    925 /*!
    926   Return the interval [log10(interval.minValue(), log10(interval.maxValue]
    927 */
    928 
    929 QwtInterval QwtLog10ScaleEngine::log10( const QwtInterval &interval ) const
    930 {
    931     return QwtInterval( ::log10( interval.minValue() ),
    932             ::log10( interval.maxValue() ) );
    933 }
    934 
    935 /*!
    936   Return the interval [pow10(interval.minValue(), pow10(interval.maxValue]
    937 */
    938 QwtInterval QwtLog10ScaleEngine::pow10( const QwtInterval &interval ) const
    939 {
    940     return QwtInterval( qPow( 10.0, interval.minValue() ),
    941             qPow( 10.0, interval.maxValue() ) );
    942 }
     1139    return qwtPowInterval( base(), QwtInterval( x1, x2 ) );
     1140}
  • trunk/BNC/qwt/qwt_scale_engine.h

    r4271 r8127  
    1515#include "qwt_interval.h"
    1616
    17 class QwtScaleTransformation;
     17class QwtTransform;
    1818
    1919/*!
     
    2828    static double divideEps( double interval, double steps );
    2929
    30     static double ceil125( double x );
    31     static double floor125( double x );
     30    static double divideInterval( double interval,
     31        int numSteps, uint base );
    3232};
    3333
     
    4040  The layout of the scale can be varied with setAttribute().
    4141
    42   Qwt offers implementations for logarithmic (log10)
    43   and linear scales. Contributions for other types of scale engines
    44   (date/time, log2 ... ) are welcome.
     42  Qwt offers implementations for logarithmic and linear scales.
    4543*/
    4644
     
    8179    typedef QFlags<Attribute> Attributes;
    8280
    83     explicit QwtScaleEngine();
     81    explicit QwtScaleEngine( uint base = 10 );
    8482    virtual ~QwtScaleEngine();
     83
     84    void setBase( uint base );
     85    uint base() const;
    8586
    8687    void setAttribute( Attribute, bool on = true );
     
    113114      \param x1 First interval limit
    114115      \param x2 Second interval limit
    115       \param maxMajSteps Maximum for the number of major steps
    116       \param maxMinSteps Maximum number of minor steps
     116      \param maxMajorSteps Maximum for the number of major steps
     117      \param maxMinorSteps Maximum number of minor steps
    117118      \param stepSize Step size. If stepSize == 0.0, the scaleEngine
    118119                   calculates one.
     120
     121      \return Calculated scale division
    119122    */
    120123    virtual QwtScaleDiv divideScale( double x1, double x2,
    121         int maxMajSteps, int maxMinSteps,
     124        int maxMajorSteps, int maxMinorSteps,
    122125        double stepSize = 0.0 ) const = 0;
    123126
    124     //! \return a transformation
    125     virtual QwtScaleTransformation *transformation() const = 0;
     127    void setTransformation( QwtTransform * );
     128    QwtTransform *transformation() const;
    126129
    127130protected:
    128131    bool contains( const QwtInterval &, double val ) const;
    129132    QList<double> strip( const QList<double>&, const QwtInterval & ) const;
     133
    130134    double divideInterval( double interval, int numSteps ) const;
    131135
     
    147151{
    148152public:
     153    QwtLinearScaleEngine( uint base = 10 );
     154    virtual ~QwtLinearScaleEngine();
     155
    149156    virtual void autoScale( int maxSteps,
    150157        double &x1, double &x2, double &stepSize ) const;
     
    154161                                     double stepSize = 0.0 ) const;
    155162
    156     virtual QwtScaleTransformation *transformation() const;
    157163
    158164protected:
     
    166172        const QwtInterval &interval, double stepSize ) const;
    167173
    168     void buildMinorTicks(
    169         const QList<double>& majorTicks,
    170         int maxMinMark, double step,
    171         QList<double> &, QList<double> & ) const;
    172 };
    173 
    174 /*!
    175   \brief A scale engine for logarithmic (base 10) scales
     174    void buildMinorTicks( const QList<double>& majorTicks,
     175        int maxMinorSteps, double stepSize,
     176        QList<double> &minorTicks, QList<double> &mediumTicks ) const;
     177};
     178
     179/*!
     180  \brief A scale engine for logarithmic scales
    176181
    177182  The step size is measured in *decades*
     
    183188*/
    184189
    185 class QWT_EXPORT QwtLog10ScaleEngine: public QwtScaleEngine
    186 {
    187 public:
     190class QWT_EXPORT QwtLogScaleEngine: public QwtScaleEngine
     191{
     192public:
     193    QwtLogScaleEngine( uint base = 10 );
     194    virtual ~QwtLogScaleEngine();
     195
    188196    virtual void autoScale( int maxSteps,
    189197        double &x1, double &x2, double &stepSize ) const;
     
    193201        double stepSize = 0.0 ) const;
    194202
    195     virtual QwtScaleTransformation *transformation() const;
    196 
    197203protected:
    198     QwtInterval log10( const QwtInterval& ) const;
    199     QwtInterval pow10( const QwtInterval& ) const;
    200 
    201204    QwtInterval align( const QwtInterval&, double stepSize ) const;
    202205
     
    208211        const QwtInterval &interval, double stepSize ) const;
    209212
    210     QList<double> buildMinorTicks(
    211         const QList<double>& majorTicks,
    212         int maxMinMark, double step ) const;
     213    void buildMinorTicks( const QList<double>& majorTicks,
     214        int maxMinorSteps, double stepSize,
     215        QList<double> &minorTicks, QList<double> &mediumTicks ) const;
    213216};
    214217
  • trunk/BNC/qwt/qwt_scale_map.cpp

    r4271 r8127  
    99
    1010#include "qwt_scale_map.h"
     11#include "qwt_math.h"
    1112#include <qrect.h>
    12 #include <qalgorithms.h>
    13 #include <qmath.h>
    1413#include <qdebug.h>
    15 
    16 #if QT_VERSION < 0x040601
    17 #define qExp(x) ::exp(x)
    18 #endif
    19 
    20 //! Smallest allowed value for logarithmic scales: 1.0e-150
    21 QT_STATIC_CONST_IMPL double QwtScaleMap::LogMin = 1.0e-150;
    22 
    23 //! Largest allowed value for logarithmic scales: 1.0e150
    24 QT_STATIC_CONST_IMPL double QwtScaleMap::LogMax = 1.0e150;
    25 
    26 //! Constructor for a linear transformation
    27 QwtScaleTransformation::QwtScaleTransformation( Type type ):
    28     d_type( type )
    29 {
    30 }
    31 
    32 //! Destructor
    33 QwtScaleTransformation::~QwtScaleTransformation()
    34 {
    35 }
    36 
    37 //! Create a clone of the transformation
    38 QwtScaleTransformation *QwtScaleTransformation::copy() const
    39 {
    40     return new QwtScaleTransformation( d_type );
    41 }
    42 
    43 /*!
    44   \brief Transform a value from the coordinate system of a scale
    45          into the coordinate system of the paint device
    46 
    47   \param s  Value related to the coordinate system of the scale
    48   \param s1 First border of the coordinate system of the scale
    49   \param s2 Second border of the coordinate system of the scale
    50   \param p1 First border of the coordinate system of the paint device
    51   \param p2 Second border of the coordinate system of the paint device
    52   \return
    53   <dl>
    54   <dt>linear mapping:<dd>p1 + (p2 - p1) / (s2 - s1) * (s - s1);</dd>
    55   </dl>
    56   <dl>
    57   <dt>log10 mapping: <dd>p1 + (p2 - p1) / log(s2 / s1) * log(s / s1);</dd>
    58   </dl>
    59 */
    60 
    61 double QwtScaleTransformation::xForm(
    62     double s, double s1, double s2, double p1, double p2 ) const
    63 {
    64     if ( d_type == Log10 )
    65         return p1 + ( p2 - p1 ) / log( s2 / s1 ) * log( s / s1 );
    66     else
    67         return p1 + ( p2 - p1 ) / ( s2 - s1 ) * ( s - s1 );
    68 }
    69 
    70 /*!
    71   \brief Transform a value from the coordinate system of the paint device
    72          into the coordinate system of a scale.
    73 
    74   \param p Value related to the coordinate system of the paint device
    75   \param p1 First border of the coordinate system of the paint device
    76   \param p2 Second border of the coordinate system of the paint device
    77   \param s1 First border of the coordinate system of the scale
    78   \param s2 Second border of the coordinate system of the scale
    79   \return
    80   <dl>
    81   <dt>linear mapping:<dd>s1 + ( s2 - s1 ) / ( p2 - p1 ) * ( p - p1 );</dd>
    82   </dl>
    83   <dl>
    84   <dt>log10 mapping:<dd>exp((p - p1) / (p2 - p1) * log(s2 / s1)) * s1;</dd>
    85   </dl>
    86 */
    87 
    88 double QwtScaleTransformation::invXForm( double p, double p1, double p2,
    89     double s1, double s2 ) const
    90 {
    91     if ( d_type == Log10 )
    92         return qExp( ( p - p1 ) / ( p2 - p1 ) * log( s2 / s1 ) ) * s1;
    93     else
    94         return s1 + ( s2 - s1 ) / ( p2 - p1 ) * ( p - p1 );
    95 }
    9614
    9715/*!
     
    10523    d_p1( 0.0 ),
    10624    d_p2( 1.0 ),
    107     d_cnv( 1.0 )
    108 {
    109     d_transformation = new QwtScaleTransformation(
    110         QwtScaleTransformation::Linear );
     25    d_cnv( 1.0 ),
     26    d_ts1( 0.0 ),
     27    d_transform( NULL )
     28{
    11129}
    11230
     
    11735    d_p1( other.d_p1 ),
    11836    d_p2( other.d_p2 ),
    119     d_cnv( other.d_cnv )
    120 {
    121     d_transformation = other.d_transformation->copy();
     37    d_cnv( other.d_cnv ),
     38    d_ts1( other.d_ts1 ),
     39    d_transform( NULL )
     40{
     41    if ( other.d_transform )
     42        d_transform = other.d_transform->copy();
    12243}
    12344
     
    12748QwtScaleMap::~QwtScaleMap()
    12849{
    129     delete d_transformation;
     50    delete d_transform;
    13051}
    13152
     
    13859    d_p2 = other.d_p2;
    13960    d_cnv = other.d_cnv;
    140 
    141     delete d_transformation;
    142     d_transformation = other.d_transformation->copy();
     61    d_ts1 = other.d_ts1;
     62
     63    delete d_transform;
     64    d_transform = NULL;
     65
     66    if ( other.d_transform )
     67        d_transform = other.d_transform->copy();
    14368
    14469    return *this;
     
    14873   Initialize the map with a transformation
    14974*/
    150 void QwtScaleMap::setTransformation(
    151     QwtScaleTransformation *transformation )
    152 {
    153     if ( transformation == NULL )
    154         return;
    155 
    156     if ( transformation != d_transformation )
     75void QwtScaleMap::setTransformation( QwtTransform *transform )
     76{
     77    if ( transform != d_transform )
    15778    {
    158         delete d_transformation;
    159         d_transformation = transformation;
     79        delete d_transform;
     80        d_transform = transform;
    16081    }
    16182
     
    16485
    16586//! Get the transformation
    166 const QwtScaleTransformation *QwtScaleMap::transformation() const
    167 {
    168     return d_transformation;
     87const QwtTransform *QwtScaleMap::transformation() const
     88{
     89    return d_transform;
    16990}
    17091
     
    17394  \param s1 first border
    17495  \param s2 second border
    175   \warning logarithmic scales might be aligned to [LogMin, LogMax]
     96  \warning scales might be aligned to
     97           transformation depending boundaries
    17698*/
    17799void QwtScaleMap::setScaleInterval( double s1, double s2 )
    178100{
    179     if ( d_transformation->type() == QwtScaleTransformation::Log10 )
    180     {
    181         if ( s1 < LogMin )
    182             s1 = LogMin;
    183         else if ( s1 > LogMax )
    184             s1 = LogMax;
    185 
    186         if ( s2 < LogMin )
    187             s2 = LogMin;
    188         else if ( s2 > LogMax )
    189             s2 = LogMax;
    190     }
    191 
    192101    d_s1 = s1;
    193102    d_s2 = s2;
    194103
    195     if ( d_transformation->type() != QwtScaleTransformation::Other )
    196         newFactor();
     104    if ( d_transform )
     105    {
     106        d_s1 = d_transform->bounded( d_s1 );
     107        d_s2 = d_transform->bounded( d_s2 );
     108    }
     109
     110    updateFactor();
    197111}
    198112
     
    207121    d_p2 = p2;
    208122
    209     if ( d_transformation->type() != QwtScaleTransformation::Other )
    210         newFactor();
    211 }
    212 
    213 /*!
    214   \brief Re-calculate the conversion factor.
    215 */
    216 void QwtScaleMap::newFactor()
    217 {
    218     d_cnv = 0.0;
    219 
    220     switch ( d_transformation->type() )
     123    updateFactor();
     124}
     125
     126void QwtScaleMap::updateFactor()
     127{
     128    d_ts1 = d_s1;
     129    double ts2 = d_s2;
     130
     131    if ( d_transform )
    221132    {
    222         case QwtScaleTransformation::Linear:
    223         {
    224             if ( d_s2 != d_s1 )
    225                 d_cnv = ( d_p2 - d_p1 ) / ( d_s2 - d_s1 );
    226             break;
    227         }
    228         case QwtScaleTransformation::Log10:
    229         {
    230             if ( d_s1 != 0 )
    231                 d_cnv = ( d_p2 - d_p1 ) / log( d_s2 / d_s1 );
    232             break;
    233         }
    234         default:;
     133        d_ts1 = d_transform->transform( d_ts1 );
     134        ts2 = d_transform->transform( ts2 );
    235135    }
     136
     137    d_cnv = 1.0;
     138    if ( d_ts1 != ts2 )
     139        d_cnv = ( d_p2 - d_p1 ) / ( ts2 - d_ts1 );
    236140}
    237141
     
    334238{
    335239    debug.nospace() << "QwtScaleMap("
    336         << static_cast<int>( map.transformation()->type() )
     240        << map.transformation()
    337241        << ", s:" << map.s1() << "->" << map.s2()
    338242        << ", p:" << map.p1() << "->" << map.p2()
  • trunk/BNC/qwt/qwt_scale_map.h

    r4271 r8127  
    1212
    1313#include "qwt_global.h"
    14 #include "qwt_math.h"
     14#include "qwt_transform.h"
     15#include <qrect.h>
     16
    1517#ifndef QT_NO_DEBUG_STREAM
    1618#include <qdebug.h>
     
    1820
    1921class QRectF;
    20 
    21 /*!
    22    \brief A transformation between coordinate systems
    23 
    24    QwtScaleTransformation offers transformations from the coordinate system
    25    of a scale into the linear coordinate system of a paint device
    26    and vice versa.
    27 */
    28 class QWT_EXPORT QwtScaleTransformation
    29 {
    30 public:
    31     //! Transformation type
    32     enum Type
    33     {
    34         //! Transformation between 2 linear scales
    35         Linear,
    36 
    37         //! Transformation between a linear and a logarithmic ( base 10 ) scale
    38         Log10,
    39 
    40         //! Any other type of transformation
    41         Other
    42     };
    43 
    44     QwtScaleTransformation( Type type );
    45     virtual ~QwtScaleTransformation();
    46 
    47     virtual double xForm( double x, double s1, double s2,
    48         double p1, double p2 ) const;
    49     virtual double invXForm( double x, double p1, double p2,
    50         double s1, double s2 ) const;
    51 
    52     Type type() const;
    53 
    54     virtual QwtScaleTransformation *copy() const;
    55 
    56 private:
    57     QwtScaleTransformation();
    58     QwtScaleTransformation &operator=( const QwtScaleTransformation );
    59 
    60     const Type d_type;
    61 };
    62 
    63 //! \return Transformation type
    64 inline QwtScaleTransformation::Type QwtScaleTransformation::type() const
    65 {
    66     return d_type;
    67 }
    6822
    6923/*!
     
    8438    QwtScaleMap &operator=( const QwtScaleMap & );
    8539
    86     void setTransformation( QwtScaleTransformation * );
    87     const QwtScaleTransformation *transformation() const;
     40    void setTransformation( QwtTransform * );
     41    const QwtTransform *transformation() const;
    8842
    8943    void setPaintInterval( double p1, double p2 );
     
    10256    double sDist() const;
    10357
    104     QT_STATIC_CONST double LogMin;
    105     QT_STATIC_CONST double LogMax;
    106 
    10758    static QRectF transform( const QwtScaleMap &,
    10859        const QwtScaleMap &, const QRectF & );
     
    11869
    11970private:
    120     void newFactor();
     71    void updateFactor();
    12172
    12273    double d_s1, d_s2;     // scale interval boundaries
     
    12475
    12576    double d_cnv;       // conversion factor
     77    double d_ts1;
    12678
    127     QwtScaleTransformation *d_transformation;
     79    QwtTransform *d_transform;
    12880};
    12981
     
    181133
    182134  \param s Value relative to the coordinates of the scale
     135  \return Transformed value
     136
     137  \sa invTransform()
    183138*/
    184139inline double QwtScaleMap::transform( double s ) const
    185140{
    186     // try to inline code from QwtScaleTransformation
     141    if ( d_transform )
     142        s = d_transform->transform( s );
    187143
    188     if ( d_transformation->type() == QwtScaleTransformation::Linear )
    189         return d_p1 + ( s - d_s1 ) * d_cnv;
    190 
    191     if ( d_transformation->type() == QwtScaleTransformation::Log10 )
    192         return d_p1 + log( s / d_s1 ) * d_cnv;
    193 
    194     return d_transformation->xForm( s, d_s1, d_s2, d_p1, d_p2 );
     144    return d_p1 + ( s - d_ts1 ) * d_cnv;
    195145}
    196146
     
    200150
    201151  \param p Value relative to the coordinates of the paint device
     152  \return Transformed value
     153
    202154  \sa transform()
    203155*/
    204156inline double QwtScaleMap::invTransform( double p ) const
    205157{
    206     return d_transformation->invXForm( p, d_p1, d_p2, d_s1, d_s2 );
     158    double s = d_ts1 + ( p - d_p1 ) / d_cnv;
     159    if ( d_transform )
     160        s = d_transform->invTransform( s );
     161
     162    return s;
    207163}
    208164
  • trunk/BNC/qwt/qwt_scale_widget.cpp

    r4271 r8127  
    1515#include "qwt_scale_div.h"
    1616#include "qwt_text.h"
     17#include "qwt_scale_engine.h"
    1718#include <qpainter.h>
    1819#include <qevent.h>
     
    107108    d_data->scaleDraw->setLength( 10 );
    108109
     110    d_data->scaleDraw->setScaleDiv(
     111        QwtLinearScaleEngine().divideScale( 0.0, 100.0, 10, 5 ) );
     112
    109113    d_data->colorBar.colorMap = new QwtLinearColorMap();
    110114    d_data->colorBar.isEnabled = false;
     
    202206void QwtScaleWidget::setAlignment( QwtScaleDraw::Alignment alignment )
    203207{
     208    if ( d_data->scaleDraw )
     209        d_data->scaleDraw->setAlignment( alignment );
     210
    204211    if ( !testAttribute( Qt::WA_WState_OwnSizePolicy ) )
    205212    {
     
    208215        if ( d_data->scaleDraw->orientation() == Qt::Vertical )
    209216            policy.transpose();
     217
    210218        setSizePolicy( policy );
    211219
     
    213221    }
    214222
    215     if ( d_data->scaleDraw )
    216         d_data->scaleDraw->setAlignment( alignment );
    217223    layoutScale();
    218224}
     
    305311/*!
    306312  Set a scale draw
    307   sd has to be created with new and will be deleted in
     313
     314  scaleDraw has to be created with new and will be deleted in
    308315  ~QwtScaleWidget() or the next call of setScaleDraw().
    309 
    310   \param sd ScaleDraw object
     316  scaleDraw will be initialized with the attributes of
     317  the previous scaleDraw object.
     318
     319  \param scaleDraw ScaleDraw object
    311320  \sa scaleDraw()
    312321*/
    313 void QwtScaleWidget::setScaleDraw( QwtScaleDraw *sd )
    314 {
    315     if ( sd == NULL || sd == d_data->scaleDraw )
     322void QwtScaleWidget::setScaleDraw( QwtScaleDraw *scaleDraw )
     323{
     324    if ( ( scaleDraw == NULL ) || ( scaleDraw == d_data->scaleDraw ) )
    316325        return;
    317326
    318     if ( d_data->scaleDraw )
    319         sd->setAlignment( d_data->scaleDraw->alignment() );
     327    const QwtScaleDraw* sd = d_data->scaleDraw;
     328    if ( sd )
     329    {
     330        scaleDraw->setAlignment( sd->alignment() );
     331        scaleDraw->setScaleDiv( sd->scaleDiv() );
     332
     333        QwtTransform *transform = NULL;
     334        if ( sd->scaleMap().transformation() )
     335            transform = sd->scaleMap().transformation()->copy();
     336
     337        scaleDraw->setTransformation( transform );
     338    }
    320339
    321340    delete d_data->scaleDraw;
    322     d_data->scaleDraw = sd;
     341    d_data->scaleDraw = scaleDraw;
    323342
    324343    layoutScale();
     
    326345
    327346/*!
    328     scaleDraw of this scale
     347    \return scaleDraw of this scale
    329348    \sa setScaleDraw(), QwtScaleDraw::setScaleDraw()
    330349*/
     
    335354
    336355/*!
    337     scaleDraw of this scale
     356    \return scaleDraw of this scale
    338357    \sa QwtScaleDraw::setScaleDraw()
    339358*/
     
    436455
    437456  \param rect Bounding rectangle for all components of the scale
    438   \return Rectabgle for the color bar
     457  \return Rectangle for the color bar
    439458*/
    440459QRectF QwtScaleWidget::colorBarRect( const QRectF& rect ) const
     
    490509
    491510/*!
    492   Event handler for resize event
     511  Event handler for resize events
    493512  \param event Resize event
    494513*/
     
    501520/*!
    502521  Recalculate the scale's geometry and layout based on
    503   the current rect and fonts.
     522  the current geometry and fonts.
    504523
    505524  \param update_geometry Notify the layout system and call update
     
    646665    QwtText title = d_data->title;
    647666    title.setRenderFlags( flags );
    648     title.draw( painter, QRect( 0, 0, r.width(), r.height() ) );
     667    title.draw( painter, QRectF( 0.0, 0.0, r.width(), r.height() ) );
    649668
    650669    painter->restore();
     
    713732int QwtScaleWidget::titleHeightForWidth( int width ) const
    714733{
    715     return d_data->title.heightForWidth( width, font() );
     734    return qCeil( d_data->title.heightForWidth( width, font() ) );
    716735}
    717736
     
    749768  is returned.
    750769
     770  \param start Return parameter for the border width at
     771               the beginning of the scale
     772  \param end Return parameter for the border width at the
     773             end of the scale
     774
    751775  \warning
    752776  <ul> <li>The minimum border distance depends on the font.</ul>
     
    784808  the widget borders.
    785809
     810  \param start Return parameter for the border width at
     811               the beginning of the scale
     812  \param end Return parameter for the border width at the
     813             end of the scale
     814
    786815  \sa setMinBorderDist(), getBorderDistHint()
    787816*/
     
    797826  The scale division determines where to set the tick marks.
    798827
    799   \param transformation Transformation, needed to translate between
    800                         scale and pixal values
    801828  \param scaleDiv Scale Division
    802829  \sa For more information about scale divisions, see QwtScaleDiv.
    803830*/
    804 void QwtScaleWidget::setScaleDiv(
    805     QwtScaleTransformation *transformation,
    806     const QwtScaleDiv &scaleDiv )
     831void QwtScaleWidget::setScaleDiv( const QwtScaleDiv &scaleDiv )
    807832{
    808833    QwtScaleDraw *sd = d_data->scaleDraw;
    809     if ( sd->scaleDiv() != scaleDiv ||
    810         sd->scaleMap().transformation()->type() != transformation->type() )
    811     {
    812         sd->setTransformation( transformation );
     834    if ( sd->scaleDiv() != scaleDiv )
     835    {
    813836        sd->setScaleDiv( scaleDiv );
    814837        layoutScale();
     
    816839        Q_EMIT scaleDivChanged();
    817840    }
    818     else
    819     {
    820         /*
    821           The transformation doesn't anything different as the
    822           previous one. So we better throw it silently away instead of
    823           initiating heavy updates
    824          */
    825 
    826         delete transformation;
    827     }
     841}
     842
     843/*!
     844  Set the transformation
     845
     846  \param transformation Transformation
     847  \sa QwtAbstractScaleDraw::scaleDraw(), QwtScaleMap
     848 */
     849void QwtScaleWidget::setTransformation( QwtTransform *transformation )
     850{
     851    d_data->scaleDraw->setTransformation( transformation );
     852    layoutScale();
    828853}
    829854
  • trunk/BNC/qwt/qwt_scale_widget.h

    r4271 r8127  
    2020
    2121class QPainter;
    22 class QwtScaleTransformation;
     22class QwtTransform;
    2323class QwtScaleDiv;
    2424class QwtColorMap;
     
    5454
    5555Q_SIGNALS:
    56     //! Signal emitted, whenever the scale divison changes
     56    //! Signal emitted, whenever the scale division changes
    5757    void scaleDivChanged();
    5858
     
    8080    int spacing() const;
    8181
    82     void setScaleDiv( QwtScaleTransformation *, const QwtScaleDiv &sd );
     82    void setScaleDiv( const QwtScaleDiv &sd );
     83    void setTransformation( QwtTransform * );
    8384
    8485    void setScaleDraw( QwtScaleDraw * );
  • trunk/BNC/qwt/qwt_series_data.cpp

    r4271 r8127  
    3434static inline QRectF qwtBoundingRect( const QwtSetSample &sample )
    3535{
    36     double minX = sample.set[0];
    37     double maxX = sample.set[0];
    38 
    39     for ( int i = 1; i < ( int )sample.set.size(); i++ )
     36    double minY = sample.set[0];
     37    double maxY = sample.set[0];
     38
     39    for ( int i = 1; i < sample.set.size(); i++ )
    4040    {
    41         if ( sample.set[i] < minX )
    42             minX = sample.set[i];
    43         if ( sample.set[i] > maxX )
    44             maxX = sample.set[i];
     41        if ( sample.set[i] < minY )
     42            minY = sample.set[i];
     43        if ( sample.set[i] > maxY )
     44            maxY = sample.set[i];
    4545    }
    4646
    47     double minY = sample.value;
    48     double maxY = sample.value;
     47    double minX = sample.value;
     48    double maxX = sample.value;
    4949
    5050    return QRectF( minX, minY, maxX - minX, maxY - minY );
    5151}
    5252
    53 /*!
    54   \brief Calculate the bounding rect of a series subset
     53static inline QRectF qwtBoundingRect( const QwtOHLCSample &sample )
     54{
     55    const QwtInterval interval = sample.boundingInterval();
     56    return QRectF( interval.minValue(), sample.time, interval.width(), 0.0 );
     57}
     58
     59/*!
     60  \brief Calculate the bounding rectangle of a series subset
    5561
    5662  Slow implementation, that iterates over the series.
     
    6470
    6571template <class T>
    66 QRectF qwtBoundingRectT( 
     72QRectF qwtBoundingRectT(
    6773    const QwtSeriesData<T>& series, int from, int to )
    6874{
     
    106112
    107113/*!
    108   \brief Calculate the bounding rect of a series subset
    109 
    110   Slow implementation, that iterates over the series.
    111 
    112   \param series Series
    113   \param from Index of the first sample, <= 0 means from the beginning
    114   \param to Index of the last sample, < 0 means to the end
    115 
    116   \return Bounding rectangle
    117 */
    118 QRectF qwtBoundingRect( 
     114  \brief Calculate the bounding rectangle of a series subset
     115
     116  Slow implementation, that iterates over the series.
     117
     118  \param series Series
     119  \param from Index of the first sample, <= 0 means from the beginning
     120  \param to Index of the last sample, < 0 means to the end
     121
     122  \return Bounding rectangle
     123*/
     124QRectF qwtBoundingRect(
    119125    const QwtSeriesData<QPointF> &series, int from, int to )
    120126{
     
    123129
    124130/*!
    125   \brief Calculate the bounding rect of a series subset
    126 
    127   Slow implementation, that iterates over the series.
    128 
    129   \param series Series
    130   \param from Index of the first sample, <= 0 means from the beginning
    131   \param to Index of the last sample, < 0 means to the end
    132 
    133   \return Bounding rectangle
    134 */
    135 QRectF qwtBoundingRect( 
     131  \brief Calculate the bounding rectangle of a series subset
     132
     133  Slow implementation, that iterates over the series.
     134
     135  \param series Series
     136  \param from Index of the first sample, <= 0 means from the beginning
     137  \param to Index of the last sample, < 0 means to the end
     138
     139  \return Bounding rectangle
     140*/
     141QRectF qwtBoundingRect(
    136142    const QwtSeriesData<QwtPoint3D> &series, int from, int to )
    137143{
     
    140146
    141147/*!
    142   \brief Calculate the bounding rect of a series subset
     148  \brief Calculate the bounding rectangle of a series subset
    143149
    144150  The horizontal coordinates represent the azimuth, the
     
    153159  \return Bounding rectangle
    154160*/
    155 QRectF qwtBoundingRect( 
     161QRectF qwtBoundingRect(
    156162    const QwtSeriesData<QwtPointPolar> &series, int from, int to )
    157163{
     
    160166
    161167/*!
    162   \brief Calculate the bounding rect of a series subset
    163 
    164   Slow implementation, that iterates over the series.
    165 
    166   \param series Series
    167   \param from Index of the first sample, <= 0 means from the beginning
    168   \param to Index of the last sample, < 0 means to the end
    169 
    170   \return Bounding rectangle
    171 */
    172 QRectF qwtBoundingRect( 
     168  \brief Calculate the bounding rectangle of a series subset
     169
     170  Slow implementation, that iterates over the series.
     171
     172  \param series Series
     173  \param from Index of the first sample, <= 0 means from the beginning
     174  \param to Index of the last sample, < 0 means to the end
     175
     176  \return Bounding rectangle
     177*/
     178QRectF qwtBoundingRect(
    173179    const QwtSeriesData<QwtIntervalSample>& series, int from, int to )
    174180{
     
    177183
    178184/*!
    179   \brief Calculate the bounding rect of a series subset
    180 
    181   Slow implementation, that iterates over the series.
    182 
    183   \param series Series
    184   \param from Index of the first sample, <= 0 means from the beginning
    185   \param to Index of the last sample, < 0 means to the end
    186 
    187   \return Bounding rectangle
    188 */
    189 QRectF qwtBoundingRect(
     185  \brief Calculate the bounding rectangle of a series subset
     186
     187  Slow implementation, that iterates over the series.
     188
     189  \param series Series
     190  \param from Index of the first sample, <= 0 means from the beginning
     191  \param to Index of the last sample, < 0 means to the end
     192
     193  \return Bounding rectangle
     194*/
     195QRectF qwtBoundingRect(
     196    const QwtSeriesData<QwtOHLCSample>& series, int from, int to )
     197{
     198    return qwtBoundingRectT<QwtOHLCSample>( series, from, to );
     199}
     200
     201/*!
     202  \brief Calculate the bounding rectangle of a series subset
     203
     204  Slow implementation, that iterates over the series.
     205
     206  \param series Series
     207  \param from Index of the first sample, <= 0 means from the beginning
     208  \param to Index of the last sample, < 0 means to the end
     209
     210  \return Bounding rectangle
     211*/
     212QRectF qwtBoundingRect(
    190213    const QwtSeriesData<QwtSetSample>& series, int from, int to )
    191214{
     
    204227
    205228/*!
    206   \brief Calculate the bounding rect
     229  \brief Calculate the bounding rectangle
    207230
    208231  The bounding rectangle is calculated once by iterating over all
     
    230253
    231254/*!
    232   \brief Calculate the bounding rect
     255  \brief Calculate the bounding rectangle
    233256
    234257  The bounding rectangle is calculated once by iterating over all
     
    256279
    257280/*!
    258   \brief Calculate the bounding rect
     281  \brief Calculate the bounding rectangle
    259282
    260283  The bounding rectangle is calculated once by iterating over all
     
    282305
    283306/*!
    284   \brief Calculate the bounding rect
     307  \brief Calculate the bounding rectangle
    285308
    286309  The bounding rectangle is calculated once by iterating over all
     
    298321
    299322/*!
    300   Constructor
    301 
    302   \param x Array of x values
    303   \param y Array of y values
    304 
    305   \sa QwtPlotCurve::setData(), QwtPlotCurve::setSamples()
    306 */
    307 QwtPointArrayData::QwtPointArrayData(
    308         const QVector<double> &x, const QVector<double> &y ):
    309     d_x( x ),
    310     d_y( y )
    311 {
    312 }
    313 
    314 /*!
    315   Constructor
    316 
    317   \param x Array of x values
    318   \param y Array of y values
    319   \param size Size of the x and y arrays
    320   \sa QwtPlotCurve::setData(), QwtPlotCurve::setSamples()
    321 */
    322 QwtPointArrayData::QwtPointArrayData( const double *x,
    323         const double *y, size_t size )
    324 {
    325     d_x.resize( size );
    326     qMemCopy( d_x.data(), x, size * sizeof( double ) );
    327 
    328     d_y.resize( size );
    329     qMemCopy( d_y.data(), y, size * sizeof( double ) );
    330 }
    331 
    332 /*!
    333   \brief Calculate the bounding rect
    334 
    335   The bounding rectangle is calculated once by iterating over all
    336   points and is stored for all following requests.
    337 
    338   \return Bounding rectangle
    339 */
    340 QRectF QwtPointArrayData::boundingRect() const
    341 {
    342     if ( d_boundingRect.width() < 0 )
    343         d_boundingRect = qwtBoundingRect( *this );
    344 
    345     return d_boundingRect;
    346 }
    347 
    348 //! \return Size of the data set
    349 size_t QwtPointArrayData::size() const
    350 {
    351     return qMin( d_x.size(), d_y.size() );
    352 }
    353 
    354 /*!
    355   Return the sample at position i
    356 
    357   \param i Index
    358   \return Sample at position i
    359 */
    360 QPointF QwtPointArrayData::sample( size_t i ) const
    361 {
    362     return QPointF( d_x[int( i )], d_y[int( i )] );
    363 }
    364 
    365 //! \return Array of the x-values
    366 const QVector<double> &QwtPointArrayData::xData() const
    367 {
    368     return d_x;
    369 }
    370 
    371 //! \return Array of the y-values
    372 const QVector<double> &QwtPointArrayData::yData() const
    373 {
    374     return d_y;
    375 }
    376 
    377 /*!
    378   Constructor
    379 
    380   \param x Array of x values
    381   \param y Array of y values
    382   \param size Size of the x and y arrays
    383 
    384   \warning The programmer must assure that the memory blocks referenced
    385            by the pointers remain valid during the lifetime of the
    386            QwtPlotCPointer object.
    387 
    388   \sa QwtPlotCurve::setData(), QwtPlotCurve::setRawSamples()
    389 */
    390 QwtCPointerData::QwtCPointerData(
    391         const double *x, const double *y, size_t size ):
    392     d_x( x ),
    393     d_y( y ),
    394     d_size( size )
    395 {
    396 }
    397 
    398 /*!
    399   \brief Calculate the bounding rect
    400 
    401   The bounding rectangle is calculated once by iterating over all
    402   points and is stored for all following requests.
    403 
    404   \return Bounding rectangle
    405 */
    406 QRectF QwtCPointerData::boundingRect() const
    407 {
    408     if ( d_boundingRect.width() < 0 )
    409         d_boundingRect = qwtBoundingRect( *this );
    410 
    411     return d_boundingRect;
    412 }
    413 
    414 //! \return Size of the data set
    415 size_t QwtCPointerData::size() const
    416 {
    417     return d_size;
    418 }
    419 
    420 /*!
    421   Return the sample at position i
    422 
    423   \param i Index
    424   \return Sample at position i
    425 */
    426 QPointF QwtCPointerData::sample( size_t i ) const
    427 {
    428     return QPointF( d_x[int( i )], d_y[int( i )] );
    429 }
    430 
    431 //! \return Array of the x-values
    432 const double *QwtCPointerData::xData() const
    433 {
    434     return d_x;
    435 }
    436 
    437 //! \return Array of the y-values
    438 const double *QwtCPointerData::yData() const
    439 {
    440     return d_y;
    441 }
    442 
    443 /*!
    444    Constructor
    445 
    446    \param size Number of points
    447    \param interval Bounding interval for the points
    448 
    449    \sa setInterval(), setSize()
    450 */
    451 QwtSyntheticPointData::QwtSyntheticPointData(
    452         size_t size, const QwtInterval &interval ):
    453     d_size( size ),
    454     d_interval( interval )
    455 {
    456 }
    457 
    458 /*!
    459   Change the number of points
    460 
    461   \param size Number of points
    462   \sa size(), setInterval()
    463 */
    464 void QwtSyntheticPointData::setSize( size_t size )
    465 {
    466     d_size = size;
    467 }
    468 
    469 /*!
    470   \return Number of points
    471   \sa setSize(), interval()
    472 */
    473 size_t QwtSyntheticPointData::size() const
    474 {
    475     return d_size;
    476 }
    477 
    478 /*!
    479    Set the bounding interval
    480 
    481    \param interval Interval
    482    \sa interval(), setSize()
    483 */
    484 void QwtSyntheticPointData::setInterval( const QwtInterval &interval )
    485 {
    486     d_interval = interval.normalized();
    487 }
    488 
    489 /*!
    490    \return Bounding interval
    491    \sa setInterval(), size()
    492 */
    493 QwtInterval QwtSyntheticPointData::interval() const
    494 {
    495     return d_interval;
    496 }
    497 
    498 /*!
    499    Set a the "rect of interest"
    500 
    501    QwtPlotSeriesItem defines the current area of the plot canvas
    502    as "rect of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).
    503 
    504    If interval().isValid() == false the x values are calculated
    505    in the interval rect.left() -> rect.right().
    506 
    507    \sa rectOfInterest()
    508 */
    509 void QwtSyntheticPointData::setRectOfInterest( const QRectF &rect )
    510 {
    511     d_rectOfInterest = rect;
    512     d_intervalOfInterest = QwtInterval(
    513         rect.left(), rect.right() ).normalized();
    514 }
    515 
    516 /*!
    517    \return "rect of interest"
    518    \sa setRectOfInterest()
    519 */
    520 QRectF QwtSyntheticPointData::rectOfInterest() const
    521 {
    522     return d_rectOfInterest;
    523 }
    524 
    525 /*!
    526   \brief Calculate the bounding rect
    527 
    528   This implementation iterates over all points, what could often
    529   be implemented much faster using the characteristics of the series.
    530   When there are many points it is recommended to overload and
    531   reimplement this method using the characteristics of the series
    532   ( if possible ).
    533 
    534   \return Bounding rectangle
    535 */
    536 QRectF QwtSyntheticPointData::boundingRect() const
    537 {
    538     if ( d_size == 0 ||
    539         !( d_interval.isValid() || d_intervalOfInterest.isValid() ) )
    540     {
    541         return QRectF(1.0, 1.0, -2.0, -2.0); // something invalid
    542     }
    543 
    544     return qwtBoundingRect( *this );
    545 }
    546 
    547 /*!
    548    Calculate the point from an index
    549 
    550    \param index Index
    551    \return QPointF(x(index), y(x(index)));
    552 
    553    \warning For invalid indices ( index < 0 || index >= size() )
    554             (0, 0) is returned.
    555 */
    556 QPointF QwtSyntheticPointData::sample( size_t index ) const
    557 {
    558     if ( index >= d_size )
    559         return QPointF( 0, 0 );
    560 
    561     const double xValue = x( index );
    562     const double yValue = y( xValue );
    563 
    564     return QPointF( xValue, yValue );
    565 }
    566 
    567 /*!
    568    Calculate a x-value from an index
    569 
    570    x values are calculated by deviding an interval into
    571    equidistant steps. If !interval().isValid() the
    572    interval is calculated from the "rect of interest".
    573 
    574    \sa interval(), rectOfInterest(), y()
    575 */
    576 double QwtSyntheticPointData::x( uint index ) const
    577 {
    578     const QwtInterval &interval = d_interval.isValid() ?
    579         d_interval : d_intervalOfInterest;
    580 
    581     if ( !interval.isValid() || d_size == 0 || index >= d_size )
    582         return 0.0;
    583 
    584     const double dx = interval.width() / d_size;
    585     return interval.minValue() + index * dx;
    586 }
     323   Constructor
     324   \param samples Samples
     325*/
     326QwtTradingChartData::QwtTradingChartData(
     327        const QVector<QwtOHLCSample> &samples ):
     328    QwtArraySeriesData<QwtOHLCSample>( samples )
     329{
     330}
     331
     332/*!
     333  \brief Calculate the bounding rectangle
     334
     335  The bounding rectangle is calculated once by iterating over all
     336  points and is stored for all following requests.
     337
     338  \return Bounding rectangle
     339*/
     340QRectF QwtTradingChartData::boundingRect() const
     341{
     342    if ( d_boundingRect.width() < 0.0 )
     343        d_boundingRect = qwtBoundingRect( *this );
     344
     345    return d_boundingRect;
     346}
  • trunk/BNC/qwt/qwt_series_data.h

    r4271 r8127  
    1212
    1313#include "qwt_global.h"
    14 #include "qwt_interval.h"
     14#include "qwt_samples.h"
    1515#include "qwt_point_3d.h"
    1616#include "qwt_point_polar.h"
     
    1818#include <qrect.h>
    1919
    20 //! \brief A sample of the types (x1-x2, y) or (x, y1-y2)
    21 class QWT_EXPORT QwtIntervalSample
    22 {
    23 public:
    24     QwtIntervalSample();
    25     QwtIntervalSample( double, const QwtInterval & );
    26     QwtIntervalSample( double value, double min, double max );
    27 
    28     bool operator==( const QwtIntervalSample & ) const;
    29     bool operator!=( const QwtIntervalSample & ) const;
    30 
    31     //! Value
    32     double value;
    33 
    34     //! Interval
    35     QwtInterval interval;
    36 };
    37 
    38 /*!
    39   Constructor
    40   The value is set to 0.0, the interval is invalid
    41 */
    42 inline QwtIntervalSample::QwtIntervalSample():
    43     value( 0.0 )
    44 {
    45 }
    46 
    47 //! Constructor
    48 inline QwtIntervalSample::QwtIntervalSample(
    49         double v, const QwtInterval &intv ):
    50     value( v ),
    51     interval( intv )
    52 {
    53 }
    54 
    55 //! Constructor
    56 inline QwtIntervalSample::QwtIntervalSample(
    57         double v, double min, double max ):
    58     value( v ),
    59     interval( min, max )
    60 {
    61 }
    62 
    63 //! Compare operator
    64 inline bool QwtIntervalSample::operator==(
    65     const QwtIntervalSample &other ) const
    66 {
    67     return value == other.value && interval == other.interval;
    68 }
    69 
    70 //! Compare operator
    71 inline bool QwtIntervalSample::operator!=(
    72     const QwtIntervalSample &other ) const
    73 {
    74     return !( *this == other );
    75 }
    76 
    77 //! \brief A sample of the types (x1...xn, y) or (x, y1..yn)
    78 class QWT_EXPORT QwtSetSample
    79 {
    80 public:
    81     QwtSetSample();
    82     bool operator==( const QwtSetSample &other ) const;
    83     bool operator!=( const QwtSetSample &other ) const;
    84 
    85     //! value
    86     double value;
    87 
    88     //! Vector of values associated to value
    89     QVector<double> set;
    90 };
    91 
    92 /*!
    93   Constructor
    94   The value is set to 0.0
    95 */
    96 inline QwtSetSample::QwtSetSample():
    97     value( 0.0 )
    98 {
    99 }
    100 
    101 //! Compare operator
    102 inline bool QwtSetSample::operator==( const QwtSetSample &other ) const
    103 {
    104     return value == other.value && set == other.set;
    105 }
    106 
    107 //! Compare operator
    108 inline bool QwtSetSample::operator!=( const QwtSetSample &other ) const
    109 {
    110     return !( *this == other );
    111 }
    112 
    11320/*!
    11421   \brief Abstract interface for iterating over samples
     
    11825   needs to be displayed, without having to copy it, it is recommended
    11926   to implement an individual data access.
     27
     28   A subclass of QwtSeriesData<QPointF> must implement:
     29
     30   - size()\n
     31     Should return number of data points.
     32
     33   - sample()\n
     34     Should return values x and y values of the sample at specific position
     35     as QPointF object.
     36
     37   - boundingRect()\n
     38     Should return the bounding rectangle of the data series.
     39     It is used for autoscaling and might help certain algorithms for displaying
     40     the data. You can use qwtBoundingRect() for an implementation
     41     but often it is possible to implement a more efficient algorithm
     42     depending on the characteristics of the series.
     43     The member d_boundingRect is intended for caching the calculated rectangle.
     44   
    12045*/
    12146template <typename T>
     
    12348{
    12449public:
     50    //! Constructor
    12551    QwtSeriesData();
     52
     53    //! Destructor
    12654    virtual ~QwtSeriesData();
    12755
     
    14472       qwtBoundingRect(...) offers slow implementations iterating
    14573       over the samples. For large sets it is recommended to implement
    146        something faster f.e. by caching the bounding rect.
     74       something faster f.e. by caching the bounding rectangle.
     75
     76       \return Bounding rectangle
    14777     */
    14878    virtual QRectF boundingRect() const = 0;
    14979
    150     virtual void setRectOfInterest( const QRectF & );
     80    /*!
     81       Set a the "rect of interest"
     82
     83       QwtPlotSeriesItem defines the current area of the plot canvas
     84       as "rectangle of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).
     85       It can be used to implement different levels of details.
     86
     87       The default implementation does nothing.
     88   
     89       \param rect Rectangle of interest
     90    */
     91    virtual void setRectOfInterest( const QRectF &rect );
    15192
    15293protected:
     
    15899};
    159100
    160 //! Constructor
    161101template <typename T>
    162102QwtSeriesData<T>::QwtSeriesData():
     
    165105}
    166106
    167 //! Destructor
    168107template <typename T>
    169108QwtSeriesData<T>::~QwtSeriesData()
     
    171110}
    172111
    173 /*!
    174    Set a the "rect of interest"
    175 
    176    QwtPlotSeriesItem defines the current area of the plot canvas
    177    as "rect of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).
    178    It can be used to implement different levels of details.
    179 
    180    The default implementation does nothing.
    181 */
    182112template <typename T>
    183113void QwtSeriesData<T>::setRectOfInterest( const QRectF & )
     
    195125{
    196126public:
     127    //! Constructor
    197128    QwtArraySeriesData();
    198     QwtArraySeriesData( const QVector<T> & );
    199 
    200     void setSamples( const QVector<T> & );
     129
     130    /*!
     131       Constructor
     132       \param samples Array of samples
     133    */
     134    QwtArraySeriesData( const QVector<T> &samples );
     135
     136    /*!
     137      Assign an array of samples
     138      \param samples Array of samples
     139    */
     140    void setSamples( const QVector<T> &samples );
     141
     142    //! \return Array of samples
    201143    const QVector<T> samples() const;
    202144
     145    //! \return Number of samples
    203146    virtual size_t size() const;
    204     virtual T sample( size_t ) const;
     147
     148    /*!
     149      \return Sample at a specific position
     150
     151      \param index Index
     152      \return Sample at position index
     153    */
     154    virtual T sample( size_t index ) const;
    205155
    206156protected:
     
    209159};
    210160
    211 //! Constructor
    212161template <typename T>
    213162QwtArraySeriesData<T>::QwtArraySeriesData()
     
    215164}
    216165
    217 /*!
    218    Constructor
    219    \param samples Array of samples
    220 */
    221166template <typename T>
    222167QwtArraySeriesData<T>::QwtArraySeriesData( const QVector<T> &samples ):
     
    225170}
    226171
    227 /*!
    228   Assign an array of samples
    229   \param samples Array of samples
    230 */
    231172template <typename T>
    232173void QwtArraySeriesData<T>::setSamples( const QVector<T> &samples )
     
    236177}
    237178
    238 //! \return Array of samples
    239179template <typename T>
    240180const QVector<T> QwtArraySeriesData<T>::samples() const
     
    243183}
    244184
    245 //! \return Number of samples
    246185template <typename T>
    247186size_t QwtArraySeriesData<T>::size() const
     
    250189}
    251190
    252 /*!
    253   Return a sample
    254   \param i Index
    255   \return Sample at position i
    256 */
    257191template <typename T>
    258192T QwtArraySeriesData<T>::sample( size_t i ) const
    259193{
    260     return d_samples[i];
     194    return d_samples[ static_cast<int>( i ) ];
    261195}
    262196
     
    301235
    302236/*!
    303   \brief Interface for iterating over two QVector<double> objects.
     237    Interface for iterating over an array of OHLC samples
    304238*/
    305 class QWT_EXPORT QwtPointArrayData: public QwtSeriesData<QPointF>
    306 {
    307 public:
    308     QwtPointArrayData( const QVector<double> &x, const QVector<double> &y );
    309     QwtPointArrayData( const double *x, const double *y, size_t size );
    310 
    311     virtual QRectF boundingRect() const;
    312 
    313     virtual size_t size() const;
    314     virtual QPointF sample( size_t i ) const;
    315 
    316     const QVector<double> &xData() const;
    317     const QVector<double> &yData() const;
    318 
    319 private:
    320     QVector<double> d_x;
    321     QVector<double> d_y;
    322 };
     239class QWT_EXPORT QwtTradingChartData: public QwtArraySeriesData<QwtOHLCSample>
     240{
     241public:
     242    QwtTradingChartData(
     243        const QVector<QwtOHLCSample> & = QVector<QwtOHLCSample>() );
     244
     245    virtual QRectF boundingRect() const;
     246};
     247
     248QWT_EXPORT QRectF qwtBoundingRect(
     249    const QwtSeriesData<QPointF> &, int from = 0, int to = -1 );
     250
     251QWT_EXPORT QRectF qwtBoundingRect(
     252    const QwtSeriesData<QwtPoint3D> &, int from = 0, int to = -1 );
     253
     254QWT_EXPORT QRectF qwtBoundingRect(
     255    const QwtSeriesData<QwtPointPolar> &, int from = 0, int to = -1 );
     256
     257QWT_EXPORT QRectF qwtBoundingRect(
     258    const QwtSeriesData<QwtIntervalSample> &, int from = 0, int to = -1 );
     259
     260QWT_EXPORT QRectF qwtBoundingRect(
     261    const QwtSeriesData<QwtSetSample> &, int from = 0, int to = -1 );
     262
     263QWT_EXPORT QRectF qwtBoundingRect(
     264    const QwtSeriesData<QwtOHLCSample> &, int from = 0, int to = -1 );
    323265
    324266/*!
    325   \brief Data class containing two pointers to memory blocks of doubles.
    326  */
    327 class QWT_EXPORT QwtCPointerData: public QwtSeriesData<QPointF>
    328 {
    329 public:
    330     QwtCPointerData( const double *x, const double *y, size_t size );
    331 
    332     virtual QRectF boundingRect() const;
    333     virtual size_t size() const;
    334     virtual QPointF sample( size_t i ) const;
    335 
    336     const double *xData() const;
    337     const double *yData() const;
    338 
    339 private:
    340     const double *d_x;
    341     const double *d_y;
    342     size_t d_size;
    343 };
    344 
    345 /*!
    346   \brief Synthetic point data
    347 
    348   QwtSyntheticPointData provides a fixed number of points for an interval.
    349   The points are calculated in equidistant steps in x-direction.
    350 
    351   If the interval is invalid, the points are calculated for
    352   the "rect of interest", what normally is the displayed area on the
    353   plot canvas. In this mode you get different levels of detail, when
    354   zooming in/out.
     267    Binary search for a sorted series of samples
     268
     269    qwtUpperSampleIndex returns the index of sample that is the upper bound
     270    of value. Is the the value smaller than the smallest value the return
     271    value will be 0. Is the value greater or equal than the largest
     272    value the return value will be -1.
    355273
    356274  \par Example
    357 
    358   The following example shows how to implement a sinus curve.
     275    The following example shows finds a point of curve from an x
     276    coordinate
    359277
    360278  \verbatim
    361 #include <cmath>
    362279#include <qwt_series_data.h>
    363280#include <qwt_plot_curve.h>
    364 #include <qwt_plot.h>
    365 #include <qapplication.h>
    366 
    367 class SinusData: public QwtSyntheticPointData
    368 {
    369 public:
    370     SinusData():
    371         QwtSyntheticPointData(100)
     281
     282struct compareX
     283{
     284    inline bool operator()( const double x, const QPointF &pos ) const
    372285    {
     286        return ( x < pos.x() );
    373287    }
    374     virtual double y(double x) const
     288};
     289
     290QLineF curveLineAt( const QwtPlotCurve *curve, double x )
     291{
     292    int index = qwtUpperSampleIndex<QPointF>(
     293        *curve->data(), x, compareX() );
     294           
     295    if ( index == -1 &&
     296        x == curve->sample( curve->dataSize() - 1 ).x() )
     297    {   
     298        // the last sample is excluded from qwtUpperSampleIndex
     299        index = curve->dataSize() - 1;
     300    }
     301
     302    QLineF line; // invalid
     303    if ( index > 0 )
    375304    {
    376         return qSin(x);
     305        line.setP1( curve->sample( index - 1 ) );
     306        line.setP2( curve->sample( index ) );
    377307    }
    378 };
    379 
    380 int main(int argc, char **argv)
    381 {
    382     QApplication a(argc, argv);
    383 
    384     QwtPlot plot;
    385     plot.setAxisScale(QwtPlot::xBottom, 0.0, 10.0);
    386     plot.setAxisScale(QwtPlot::yLeft, -1.0, 1.0);
    387 
    388     QwtPlotCurve *curve = new QwtPlotCurve("y = sin(x)");
    389     curve->setData(SinusData());
    390     curve->attach(&plot);
    391 
    392     plot.show();
    393     return a.exec();
    394 }
    395    \endverbatim
    396 */
    397 class QWT_EXPORT QwtSyntheticPointData: public QwtSeriesData<QPointF>
    398 {
    399 public:
    400     QwtSyntheticPointData( size_t size,
    401         const QwtInterval & = QwtInterval() );
    402 
    403     void setSize( size_t size );
    404     size_t size() const;
    405 
    406     void setInterval( const QwtInterval& );
    407     QwtInterval interval() const;
    408 
    409     virtual QRectF boundingRect() const;
    410     virtual QPointF sample( size_t i ) const;
    411 
    412     /*!
    413        Calculate a y value for a x value
    414 
    415        \param x x value
    416        \return Corresponding y value
    417      */
    418     virtual double y( double x ) const = 0;
    419     virtual double x( uint index ) const;
    420 
    421     virtual void setRectOfInterest( const QRectF & );
    422     QRectF rectOfInterest() const;
    423 
    424 private:
    425     size_t d_size;
    426     QwtInterval d_interval;
    427     QRectF d_rectOfInterest;
    428     QwtInterval d_intervalOfInterest;
    429 };
    430 
    431 QWT_EXPORT QRectF qwtBoundingRect(
    432     const QwtSeriesData<QPointF> &, int from = 0, int to = -1 );
    433 QWT_EXPORT QRectF qwtBoundingRect(
    434     const QwtSeriesData<QwtPoint3D> &, int from = 0, int to = -1 );
    435 QWT_EXPORT QRectF qwtBoundingRect(
    436     const QwtSeriesData<QwtPointPolar> &, int from = 0, int to = -1 );
    437 QWT_EXPORT QRectF qwtBoundingRect(
    438     const QwtSeriesData<QwtIntervalSample> &, int from = 0, int to = -1 );
    439 QWT_EXPORT QRectF qwtBoundingRect(
    440     const QwtSeriesData<QwtSetSample> &, int from = 0, int to = -1 );
    441 
    442 #endif
     308
     309    return line;
     310}
     311
     312\endverbatim
     313
     314
     315    \param series Series of samples
     316    \param value Value
     317    \param lessThan Compare operation
     318
     319    \note The samples must be sorted according to the order specified
     320          by the lessThan object
     321
     322of the range [begin, end) and returns the position of the one-past-the-last occurrence of value. If no such item is found, returns the position where the item should be inserted.
     323 */
     324template <typename T, typename LessThan>
     325inline int qwtUpperSampleIndex( const QwtSeriesData<T> &series,
     326    double value, LessThan lessThan  )
     327{
     328    const int indexMax = series.size() - 1;
     329
     330    if ( indexMax < 0 || !lessThan( value, series.sample( indexMax ) )  )
     331        return -1;
     332
     333    int indexMin = 0;
     334    int n = indexMax;
     335
     336    while ( n > 0 )
     337    {
     338        const int half = n >> 1;
     339        const int indexMid = indexMin + half;
     340
     341        if ( lessThan( value, series.sample( indexMid ) ) )
     342        {
     343            n = half;
     344        }
     345        else
     346        {
     347            indexMin = indexMid + 1;
     348            n -= half + 1;
     349        }
     350    }
     351
     352    return indexMin;
     353}
     354
     355#endif
  • trunk/BNC/qwt/qwt_spline.cpp

    r4271 r8127  
    6969/*!
    7070   Copy constructor
    71    \param other Spline used for initilization
     71   \param other Spline used for initialization
    7272*/
    7373QwtSpline::QwtSpline( const QwtSpline& other )
     
    7878/*!
    7979   Assignment operator
    80    \param other Spline used for initilization
     80   \param other Spline used for initialization
     81   \return *this
    8182*/
    8283QwtSpline &QwtSpline::operator=( const QwtSpline & other )
     
    153154
    154155/*!
    155    Return points passed by setPoints
     156   \return Points, that have been by setPoints()
    156157*/
    157158QPolygonF QwtSpline::points() const
     
    197198  Calculate the interpolated function value corresponding
    198199  to a given argument x.
     200
     201  \param x Coordinate
     202  \return Interpolated coordinate
    199203*/
    200204double QwtSpline::value( double x ) const
  • trunk/BNC/qwt/qwt_symbol.cpp

    r4271 r8127  
    1010#include "qwt_symbol.h"
    1111#include "qwt_painter.h"
     12#include "qwt_graphic.h"
    1213#include <qapplication.h>
    1314#include <qpainter.h>
     15#include <qpainterpath.h>
     16#include <qpixmap.h>
     17#include <qpaintengine.h>
    1418#include <qmath.h>
     19#ifndef QWT_NO_SVG
     20#include <qsvgrenderer.h>
     21#endif
    1522
    1623namespace QwtTriangle
     
    2330        Down
    2431    };
     32}
     33
     34static QwtGraphic qwtPathGraphic( const QPainterPath &path,
     35    const QPen &pen, const QBrush& brush )
     36{
     37    QwtGraphic graphic;
     38    graphic.setRenderHint( QwtGraphic::RenderPensUnscaled );
     39
     40    QPainter painter( &graphic );
     41    painter.setPen( pen );
     42    painter.setBrush( brush );
     43    painter.drawPath( path );
     44    painter.end();
     45
     46    return graphic;
     47}
     48
     49static inline QRectF qwtScaledBoundingRect(
     50    const QwtGraphic &graphic, const QSizeF size )
     51{
     52    QSizeF scaledSize = size;
     53    if ( scaledSize.isEmpty() )
     54        scaledSize = graphic.defaultSize();
     55       
     56    const QSizeF sz = graphic.controlPointRect().size();
     57
     58    double sx = 1.0;
     59    if ( sz.width() > 0.0 )
     60        sx = scaledSize.width() / sz.width();
     61   
     62    double sy = 1.0;
     63    if ( sz.height() > 0.0 )
     64        sy = scaledSize.height() / sz.height();
     65
     66    return graphic.scaledBoundingRect( sx, sy );
     67}
     68
     69static inline void qwtDrawPixmapSymbols( QPainter *painter,
     70    const QPointF *points, int numPoints, const QwtSymbol &symbol )
     71{
     72    QSize size = symbol.size();
     73    if ( size.isEmpty() )
     74        size = symbol.pixmap().size();
     75
     76    const QTransform transform = painter->transform();
     77    if ( transform.isScaling() )
     78    {
     79        const QRect r( 0, 0, size.width(), size.height() );
     80        size = transform.mapRect( r ).size();
     81    }
     82
     83    QPixmap pm = symbol.pixmap();
     84    if ( pm.size() != size )
     85        pm = pm.scaled( size );
     86   
     87    QPointF pinPoint( 0.5 * size.width(), 0.5 * size.height() );
     88    if ( symbol.isPinPointEnabled() )
     89        pinPoint = symbol.pinPoint();
     90
     91    painter->resetTransform();
     92
     93    for ( int i = 0; i < numPoints; i++ )
     94    {
     95        const QPointF pos = transform.map( points[i] ) - pinPoint;
     96
     97        QwtPainter::drawPixmap( painter,
     98            QRect( pos.toPoint(), pm.size() ), pm );
     99    }
     100}
     101
     102#ifndef QWT_NO_SVG
     103
     104static inline void qwtDrawSvgSymbols( QPainter *painter,
     105    const QPointF *points, int numPoints,
     106    QSvgRenderer *renderer, const QwtSymbol &symbol )
     107{
     108    if ( renderer == NULL || !renderer->isValid() )
     109        return;
     110
     111    const QRectF viewBox = renderer->viewBoxF();
     112    if ( viewBox.isEmpty() )
     113        return;
     114
     115    QSizeF sz = symbol.size();
     116    if ( !sz.isValid() )
     117        sz = viewBox.size();
     118
     119    const double sx = sz.width() / viewBox.width();
     120    const double sy = sz.height() / viewBox.height();
     121
     122    QPointF pinPoint = viewBox.center();
     123    if ( symbol.isPinPointEnabled() )
     124        pinPoint = symbol.pinPoint();
     125
     126    const double dx = sx * ( pinPoint.x() - viewBox.left() );
     127    const double dy = sy * ( pinPoint.y() - viewBox.top() );
     128
     129    for ( int i = 0; i < numPoints; i++ )
     130    {
     131        const double x = points[i].x() - dx;
     132        const double y = points[i].y() - dy;
     133
     134        renderer->render( painter,
     135            QRectF( x, y, sz.width(), sz.height() ) );
     136    }
     137}
     138
     139#endif
     140
     141static inline void qwtDrawGraphicSymbols( QPainter *painter,
     142    const QPointF *points, int numPoints, const QwtGraphic &graphic,
     143    const QwtSymbol &symbol )
     144{
     145    const QRectF pointRect = graphic.controlPointRect();
     146    if ( pointRect.isEmpty() )
     147        return;
     148
     149    double sx = 1.0;
     150    double sy = 1.0;
     151
     152    const QSize sz = symbol.size();
     153    if ( sz.isValid() )
     154    {
     155        sx = sz.width() / pointRect.width();
     156        sy = sz.height() / pointRect.height();
     157    }
     158
     159    QPointF pinPoint = pointRect.center();
     160    if ( symbol.isPinPointEnabled() )
     161        pinPoint = symbol.pinPoint();
     162
     163    const QTransform transform = painter->transform();
     164
     165    for ( int i = 0; i < numPoints; i++ )
     166    {
     167        QTransform tr = transform;
     168        tr.translate( points[i].x(), points[i].y() );
     169        tr.scale( sx, sy );
     170        tr.translate( -pinPoint.x(), -pinPoint.y() );
     171
     172        painter->setTransform( tr );
     173
     174        graphic.render( painter );
     175    }
     176
     177    painter->setTransform( transform );
    25178}
    26179
     
    623776        size( sz ),
    624777        brush( br ),
    625         pen( pn )
    626     {
    627     }
    628 
    629     bool operator==( const PrivateData &other ) const
    630     {
    631         return ( style == other.style )
    632             && ( size == other.size )
    633             && ( brush == other.brush )
    634             && ( pen == other.pen );
    635     }
    636 
     778        pen( pn ),
     779        isPinPointEnabled( false )
     780    {
     781        cache.policy = QwtSymbol::AutoCache;
     782#ifndef QWT_NO_SVG
     783        svg.renderer = NULL;
     784#endif
     785    }
     786
     787    ~PrivateData()
     788    {
     789#ifndef QWT_NO_SVG
     790        delete svg.renderer;
     791#endif
     792    }
    637793
    638794    Style style;
     
    640796    QBrush brush;
    641797    QPen pen;
     798
     799    bool isPinPointEnabled;
     800    QPointF pinPoint;
     801
     802    struct Path
     803    {
     804        QPainterPath path;
     805        QwtGraphic graphic;
     806
     807    } path;
     808
     809    struct Pixmap
     810    {
     811        QPixmap pixmap;
     812
     813    } pixmap;
     814
     815    struct Graphic
     816    {
     817        QwtGraphic graphic;
     818
     819    } graphic;
     820
     821#ifndef QWT_NO_SVG
     822    struct SVG
     823    {
     824        QSvgRenderer *renderer;
     825    } svg;
     826#endif
     827
     828    struct PaintCache
     829    {
     830        QwtSymbol::CachePolicy policy;
     831        QPixmap pixmap;
     832
     833    } cache;
    642834};
    643835
     
    652844{
    653845    d_data = new PrivateData( style, QBrush( Qt::gray ),
    654         QPen( Qt::black ), QSize( 0.0, 0.0 ) );
     846        QPen( Qt::black, 0 ), QSize() );
    655847}
    656848
     
    671863
    672864/*!
    673   \brief Copy constructor
    674 
    675   \param other Symbol
     865  \brief Constructor
     866
     867  The symbol gets initialized by a painter path. The style is
     868  set to QwtSymbol::Path, the size is set to empty ( the path
     869  is displayed unscaled ).
     870
     871  \param path painter path
     872  \param brush brush to fill the interior
     873  \param pen outline pen
     874
     875  \sa setPath(), setBrush(), setPen(), setSize()
    676876*/
    677 QwtSymbol::QwtSymbol( const QwtSymbol &other )
    678 {
    679     d_data = new PrivateData( other.style(), other.brush(),
    680         other.pen(), other.size() );
    681 };
     877
     878QwtSymbol::QwtSymbol( const QPainterPath &path,
     879    const QBrush &brush, const QPen &pen )
     880{
     881    d_data = new PrivateData( QwtSymbol::Path, brush, pen, QSize() );
     882    setPath( path );
     883}
    682884
    683885//! Destructor
     
    687889}
    688890
    689 //! \brief Assignment operator
    690 QwtSymbol &QwtSymbol::operator=( const QwtSymbol &other )
    691 {
    692     *d_data = *other.d_data;
    693     return *this;
    694 }
    695 
    696 //! \brief Compare two symbols
    697 bool QwtSymbol::operator==( const QwtSymbol &other ) const
    698 {
    699     return *d_data == *other.d_data;
    700 }
    701 
    702 //! \brief Compare two symbols
    703 bool QwtSymbol::operator!=( const QwtSymbol &other ) const
    704 {
    705     return !( *d_data == *other.d_data );
    706 }
     891/*!
     892  Change the cache policy
     893
     894  The default policy is AutoCache
     895
     896  \param policy Cache policy
     897  \sa CachePolicy, cachePolicy()
     898*/
     899void QwtSymbol::setCachePolicy(
     900    QwtSymbol::CachePolicy policy )
     901{
     902    if ( d_data->cache.policy != policy )
     903    {
     904        d_data->cache.policy = policy;
     905        invalidateCache();
     906    }
     907}
     908
     909/*!
     910  \return Cache policy
     911  \sa CachePolicy, setCachePolicy()
     912*/
     913QwtSymbol::CachePolicy QwtSymbol::cachePolicy() const
     914{
     915    return d_data->cache.policy;
     916}
     917
     918/*!
     919  \brief Set a painter path as symbol
     920
     921  The symbol is represented by a painter path, where the
     922  origin ( 0, 0 ) of the path coordinate system is mapped to
     923  the position of the symbol.
     924
     925  When the symbol has valid size the painter path gets scaled
     926  to fit into the size. Otherwise the symbol size depends on
     927  the bounding rectangle of the path.
     928
     929  The following code defines a symbol drawing an arrow:
     930
     931  \verbatim
     932#include <qwt_symbol.h>
     933
     934QwtSymbol *symbol = new QwtSymbol();
     935
     936QPen pen( Qt::black, 2 );
     937pen.setJoinStyle( Qt::MiterJoin );
     938
     939symbol->setPen( pen );
     940symbol->setBrush( Qt::red );
     941
     942QPainterPath path;
     943path.moveTo( 0, 8 );
     944path.lineTo( 0, 5 );
     945path.lineTo( -3, 5 );
     946path.lineTo( 0, 0 );
     947path.lineTo( 3, 5 );
     948path.lineTo( 0, 5 );
     949
     950QTransform transform;
     951transform.rotate( -30.0 );
     952path = transform.map( path );
     953
     954symbol->setPath( path );
     955symbol->setPinPoint( QPointF( 0.0, 0.0 ) );
     956
     957setSize( 10, 14 );
     958\endverbatim
     959
     960  \param path Painter path
     961
     962  \note The style is implicitely set to QwtSymbol::Path.
     963  \sa path(), setSize()
     964 */
     965void QwtSymbol::setPath( const QPainterPath &path )
     966{
     967    d_data->style = QwtSymbol::Path;
     968    d_data->path.path = path;
     969    d_data->path.graphic.reset();
     970}
     971
     972/*!
     973   \return Painter path for displaying the symbol
     974   \sa setPath()
     975*/
     976const QPainterPath &QwtSymbol::path() const
     977{
     978    return d_data->path.path;
     979}
     980
     981/*!
     982  Set a pixmap as symbol
     983
     984  \param pixmap Pixmap
     985
     986  \sa pixmap(), setGraphic()
     987
     988  \note the style() is set to QwtSymbol::Pixmap
     989  \note brush() and pen() have no effect
     990 */
     991void QwtSymbol::setPixmap( const QPixmap &pixmap )
     992{
     993    d_data->style = QwtSymbol::Pixmap;
     994    d_data->pixmap.pixmap = pixmap;
     995}
     996
     997/*!
     998  \return Assigned pixmap
     999  \sa setPixmap()
     1000 */
     1001const QPixmap &QwtSymbol::pixmap() const
     1002{
     1003    return d_data->pixmap.pixmap;
     1004}
     1005
     1006/*!
     1007  Set a graphic as symbol
     1008
     1009  \param graphic Graphic
     1010
     1011  \sa graphic(), setPixmap()
     1012
     1013  \note the style() is set to QwtSymbol::Graphic
     1014  \note brush() and pen() have no effect
     1015 */
     1016void QwtSymbol::setGraphic( const QwtGraphic &graphic )
     1017{
     1018    d_data->style = QwtSymbol::Graphic;
     1019    d_data->graphic.graphic = graphic;
     1020}
     1021
     1022/*!
     1023  \return Assigned graphic
     1024  \sa setGraphic()
     1025 */
     1026const QwtGraphic &QwtSymbol::graphic() const
     1027{
     1028    return d_data->graphic.graphic;
     1029}
     1030
     1031#ifndef QWT_NO_SVG
     1032
     1033/*!
     1034  Set a SVG icon as symbol
     1035
     1036  \param svgDocument SVG icon
     1037
     1038  \sa setGraphic(), setPixmap()
     1039
     1040  \note the style() is set to QwtSymbol::SvgDocument
     1041  \note brush() and pen() have no effect
     1042 */
     1043void QwtSymbol::setSvgDocument( const QByteArray &svgDocument )
     1044{
     1045    d_data->style = QwtSymbol::SvgDocument;
     1046    if ( d_data->svg.renderer == NULL )
     1047        d_data->svg.renderer = new QSvgRenderer();
     1048
     1049    d_data->svg.renderer->load( svgDocument );
     1050}
     1051
     1052#endif
    7071053
    7081054/*!
     
    7121058  and the 'w' parameter is greater than or equal to 0,
    7131059  the symbol size will be set to (w,w).
     1060
    7141061  \param width Width
    7151062  \param height Height (defaults to -1)
     
    7221069        height = width;
    7231070
    724     d_data->size = QSize( width, height );
     1071    setSize( QSize( width, height ) );
    7251072}
    7261073
     
    7331080void QwtSymbol::setSize( const QSize &size )
    7341081{
    735     if ( size.isValid() )
     1082    if ( size.isValid() && size != d_data->size )
     1083    {
    7361084        d_data->size = size;
     1085        invalidateCache();
     1086    }
    7371087}
    7381088
     
    7561106void QwtSymbol::setBrush( const QBrush &brush )
    7571107{
    758     d_data->brush = brush;
     1108    if ( brush != d_data->brush )
     1109    {
     1110        d_data->brush = brush;
     1111        invalidateCache();
     1112
     1113        if ( d_data->style == QwtSymbol::Path )
     1114            d_data->path.graphic.reset();
     1115    }
    7591116}
    7601117
     
    7691126
    7701127/*!
     1128  Build and assign a pen
     1129
     1130  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 )
     1131  what makes it non cosmetic ( see QPen::isCosmetic() ).
     1132  This method has been introduced to hide this incompatibility.
     1133
     1134  \param color Pen color
     1135  \param width Pen width
     1136  \param style Pen style
     1137
     1138  \sa pen(), brush()
     1139 */
     1140void QwtSymbol::setPen( const QColor &color,
     1141    qreal width, Qt::PenStyle style )
     1142{
     1143    setPen( QPen( color, width, style ) );
     1144}
     1145
     1146/*!
    7711147  Assign a pen
    7721148
     
    7781154void QwtSymbol::setPen( const QPen &pen )
    7791155{
    780     d_data->pen = pen;
     1156    if ( pen != d_data->pen )
     1157    {
     1158        d_data->pen = pen;
     1159        invalidateCache();
     1160
     1161        if ( d_data->style == QwtSymbol::Path )
     1162            d_data->path.graphic.reset();
     1163    }
    7811164}
    7821165
     
    8151198        case QwtSymbol::Hexagon:
    8161199        {
    817             d_data->brush.setColor( color );
     1200            if ( d_data->brush.color() != color )
     1201            {
     1202                d_data->brush.setColor( color );
     1203                invalidateCache();
     1204            }
    8181205            break;
    8191206        }
     
    8241211        case QwtSymbol::Star1:
    8251212        {
    826             d_data->pen.setColor( color );
     1213            if ( d_data->pen.color() != color )
     1214            {
     1215                d_data->pen.setColor( color );
     1216                invalidateCache();
     1217            }
    8271218            break;
    8281219        }
    8291220        default:
    8301221        {
     1222            if ( d_data->brush.color() != color ||
     1223                d_data->pen.color() != color )
     1224            {
     1225                invalidateCache();
     1226            }
     1227
    8311228            d_data->brush.setColor( color );
    8321229            d_data->pen.setColor( color );
     
    8361233
    8371234/*!
    838   Draw an array of symbols
     1235  \brief Set and enable a pin point
     1236
     1237  The position of a complex symbol is not always aligned to its center
     1238  ( f.e an arrow, where the peak points to a position ). The pin point
     1239  defines the position inside of a Pixmap, Graphic, SvgDocument
     1240  or PainterPath symbol where the represented point has to
     1241  be aligned to.
     1242 
     1243  \param pos Position
     1244  \param enable En/Disable the pin point alignment
     1245
     1246  \sa pinPoint(), setPinPointEnabled()
     1247 */
     1248void QwtSymbol::setPinPoint( const QPointF &pos, bool enable )
     1249{
     1250    if ( d_data->pinPoint != pos )
     1251    {
     1252        d_data->pinPoint = pos;
     1253        if ( d_data->isPinPointEnabled )
     1254        {
     1255            invalidateCache();
     1256        }
     1257    }
     1258
     1259    setPinPointEnabled( enable );
     1260}
     1261
     1262/*!
     1263  \return Pin point
     1264  \sa setPinPoint(), setPinPointEnabled()
     1265 */
     1266QPointF QwtSymbol::pinPoint() const
     1267{
     1268    return d_data->pinPoint;
     1269}
     1270
     1271/*!
     1272  En/Disable the pin point alignment
     1273
     1274  \param on Enabled, when on is true
     1275  \sa setPinPoint(), isPinPointEnabled()
     1276 */
     1277void QwtSymbol::setPinPointEnabled( bool on )
     1278{
     1279    if ( d_data->isPinPointEnabled != on )
     1280    {
     1281        d_data->isPinPointEnabled = on;
     1282        invalidateCache();
     1283    }
     1284}
     1285
     1286/*!
     1287  \return True, when the pin point translation is enabled
     1288  \sa setPinPoint(), setPinPointEnabled()
     1289 */
     1290bool QwtSymbol::isPinPointEnabled() const
     1291{
     1292    return d_data->isPinPointEnabled;
     1293}
     1294
     1295/*!
     1296  Render an array of symbols
    8391297
    8401298  Painting several symbols is more effective than drawing symbols
     
    8521310        return;
    8531311
    854     painter->save();
    855 
     1312    bool useCache = false;
     1313
     1314    // Don't use the pixmap, when the paint device
     1315    // could generate scalable vectors
     1316
     1317    if ( QwtPainter::roundingAlignment( painter ) &&
     1318        !painter->transform().isScaling() )
     1319    {
     1320        if ( d_data->cache.policy == QwtSymbol::Cache )
     1321        {
     1322            useCache = true;
     1323        }
     1324        else if ( d_data->cache.policy == QwtSymbol::AutoCache )
     1325        {
     1326            if ( painter->paintEngine()->type() == QPaintEngine::Raster )
     1327            {
     1328                useCache = true;
     1329            }
     1330            else
     1331            {
     1332                switch( d_data->style )
     1333                {
     1334                    case QwtSymbol::XCross:
     1335                    case QwtSymbol::HLine:
     1336                    case QwtSymbol::VLine:
     1337                    case QwtSymbol::Cross:
     1338                        break;
     1339
     1340                    case QwtSymbol::Pixmap:
     1341                    {
     1342                        if ( !d_data->size.isEmpty() &&
     1343                            d_data->size != d_data->pixmap.pixmap.size() )
     1344                        {
     1345                            useCache = true;
     1346                        }
     1347                        break;
     1348                    }                       
     1349                    default:
     1350                        useCache = true;
     1351                }
     1352            }
     1353        }
     1354    }
     1355
     1356    if ( useCache )
     1357    {
     1358        const QRect br = boundingRect();
     1359
     1360        const QRect rect( 0, 0, br.width(), br.height() );
     1361       
     1362        if ( d_data->cache.pixmap.isNull() )
     1363        {
     1364            d_data->cache.pixmap = QwtPainter::backingStore( NULL, br.size() );
     1365            d_data->cache.pixmap.fill( Qt::transparent );
     1366
     1367            QPainter p( &d_data->cache.pixmap );
     1368            p.setRenderHints( painter->renderHints() );
     1369            p.translate( -br.topLeft() );
     1370
     1371            const QPointF pos;
     1372            renderSymbols( &p, &pos, 1 );
     1373        }
     1374
     1375        const int dx = br.left();
     1376        const int dy = br.top();
     1377
     1378        for ( int i = 0; i < numPoints; i++ )
     1379        {
     1380            const int left = qRound( points[i].x() ) + dx;
     1381            const int top = qRound( points[i].y() ) + dy;
     1382
     1383            painter->drawPixmap( left, top, d_data->cache.pixmap );
     1384        }
     1385    }
     1386    else
     1387    {
     1388        painter->save();
     1389        renderSymbols( painter, points, numPoints );
     1390        painter->restore();
     1391    }
     1392}
     1393
     1394/*!
     1395  \brief Draw the symbol into a rectangle
     1396
     1397  The symbol is painted centered and scaled into the target rectangle.
     1398  It is always painted uncached and the pin point is ignored.
     1399
     1400  This method is primarily intended for drawing a symbol to
     1401  the legend.
     1402
     1403  \param painter Painter
     1404  \param rect Target rectangle for the symbol
     1405*/
     1406void QwtSymbol::drawSymbol( QPainter *painter, const QRectF &rect ) const
     1407{
     1408    if ( d_data->style == QwtSymbol::NoSymbol )
     1409        return;
     1410
     1411    if ( d_data->style == QwtSymbol::Graphic )
     1412    {
     1413        d_data->graphic.graphic.render(
     1414            painter, rect, Qt::KeepAspectRatio );
     1415    }
     1416    else if ( d_data->style == QwtSymbol::Path )
     1417    {
     1418        if ( d_data->path.graphic.isNull() )
     1419        {
     1420            d_data->path.graphic = qwtPathGraphic(
     1421                d_data->path.path, d_data->pen, d_data->brush );
     1422        }
     1423
     1424        d_data->path.graphic.render(
     1425            painter, rect, Qt::KeepAspectRatio );
     1426        return;
     1427    }
     1428    else if ( d_data->style == QwtSymbol::SvgDocument )
     1429    {
     1430#ifndef QWT_NO_SVG
     1431        if ( d_data->svg.renderer )
     1432        {
     1433            QRectF scaledRect;
     1434
     1435            QSizeF sz = d_data->svg.renderer->viewBoxF().size();
     1436            if ( !sz.isEmpty() )
     1437            {
     1438                sz.scale( rect.size(), Qt::KeepAspectRatio );
     1439                scaledRect.setSize( sz );
     1440                scaledRect.moveCenter( rect.center() );
     1441            }
     1442            else
     1443            {
     1444                scaledRect = rect;
     1445            }
     1446
     1447            d_data->svg.renderer->render(
     1448                painter, scaledRect );
     1449        }
     1450#endif
     1451    }
     1452    else
     1453    {
     1454        const QRect br = boundingRect();
     1455
     1456        // scale the symbol size to fit into rect.
     1457
     1458        const double ratio = qMin( rect.width() / br.width(),
     1459            rect.height() / br.height() );
     1460
     1461        painter->save();
     1462
     1463        painter->translate( rect.center() );
     1464        painter->scale( ratio, ratio );
     1465
     1466        const bool isPinPointEnabled = d_data->isPinPointEnabled;
     1467        d_data->isPinPointEnabled = false;
     1468
     1469        const QPointF pos;
     1470        renderSymbols( painter, &pos, 1 );
     1471   
     1472        d_data->isPinPointEnabled = isPinPointEnabled;
     1473
     1474        painter->restore();
     1475    }
     1476}
     1477
     1478/*!
     1479  Render the symbol to series of points
     1480
     1481  \param painter Qt painter
     1482  \param points Positions of the symbols
     1483  \param numPoints Number of points
     1484 */
     1485void QwtSymbol::renderSymbols( QPainter *painter,
     1486    const QPointF *points, int numPoints ) const
     1487{
    8561488    switch ( d_data->style )
    8571489    {
     
    9341566            break;
    9351567        }
     1568        case QwtSymbol::Path:
     1569        {
     1570            if ( d_data->path.graphic.isNull() )
     1571            {
     1572                d_data->path.graphic = qwtPathGraphic( d_data->path.path,
     1573                    d_data->pen, d_data->brush );
     1574            }
     1575
     1576            qwtDrawGraphicSymbols( painter, points, numPoints,
     1577                d_data->path.graphic, *this );
     1578            break;
     1579        }
     1580        case QwtSymbol::Pixmap:
     1581        {
     1582            qwtDrawPixmapSymbols( painter, points, numPoints, *this );
     1583            break;
     1584        }
     1585        case QwtSymbol::Graphic:
     1586        {
     1587            qwtDrawGraphicSymbols( painter, points, numPoints,
     1588                d_data->graphic.graphic, *this );
     1589            break;
     1590        }
     1591        case QwtSymbol::SvgDocument:
     1592        {
     1593#ifndef QWT_NO_SVG
     1594            qwtDrawSvgSymbols( painter, points, numPoints,
     1595                d_data->svg.renderer, *this );
     1596#endif
     1597            break;
     1598        }
    9361599        default:;
    9371600    }
    938     painter->restore();
    939 }
    940 
    941 //!  \return Size of the bounding rectangle of a symbol
    942 QSize QwtSymbol::boundingSize() const
    943 {
    944     QSize size;
     1601}
     1602
     1603/*!
     1604  Calculate the bounding rectangle for a symbol
     1605  at position (0,0).
     1606
     1607  \return Bounding rectangle
     1608 */
     1609QRect QwtSymbol::boundingRect() const
     1610{
     1611    QRectF rect;
     1612
     1613    bool pinPointTranslation = false;
    9451614
    9461615    switch ( d_data->style )
     
    9541623                pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) );
    9551624
    956             size = d_data->size + QSize( pw, pw );
     1625            rect.setSize( d_data->size + QSizeF( pw, pw ) );
     1626            rect.moveCenter( QPointF( 0.0, 0.0 ) );
    9571627
    9581628            break;
     
    9721642                pw = qMax( d_data->pen.widthF(), qreal( 1.0 ) );
    9731643
    974             size = d_data->size + QSize( 2 * pw, 2 * pw );
    975             break;
    976         }
     1644            rect.setSize( d_data->size + QSizeF( 2 * pw, 2 * pw ) );
     1645            rect.moveCenter( QPointF( 0.0, 0.0 ) );
     1646            break;
     1647        }
     1648        case QwtSymbol::Path:
     1649        {
     1650            if ( d_data->path.graphic.isNull() )
     1651            {
     1652                d_data->path.graphic = qwtPathGraphic(
     1653                    d_data->path.path, d_data->pen, d_data->brush );
     1654            }
     1655
     1656            rect = qwtScaledBoundingRect(
     1657                d_data->path.graphic, d_data->size );
     1658            pinPointTranslation = true;
     1659
     1660            break;
     1661        }
     1662        case QwtSymbol::Pixmap:
     1663        {
     1664            if ( d_data->size.isEmpty() )
     1665                rect.setSize( d_data->pixmap.pixmap.size() );
     1666            else
     1667                rect.setSize( d_data->size );
     1668           
     1669            pinPointTranslation = true;
     1670
     1671            break;
     1672        }
     1673        case QwtSymbol::Graphic:
     1674        {
     1675            rect = qwtScaledBoundingRect(
     1676                d_data->graphic.graphic, d_data->size );
     1677            pinPointTranslation = true;
     1678
     1679            break;
     1680        }
     1681#ifndef QWT_NO_SVG
     1682        case QwtSymbol::SvgDocument:
     1683        {
     1684            if ( d_data->svg.renderer )
     1685                rect = d_data->svg.renderer->viewBoxF();
     1686
     1687            if ( d_data->size.isValid() && !rect.isEmpty() )
     1688            {
     1689                QSizeF sz = rect.size();
     1690
     1691                const double sx = d_data->size.width() / sz.width();
     1692                const double sy = d_data->size.height() / sz.height();
     1693
     1694                QTransform transform;
     1695                transform.scale( sx, sy );
     1696
     1697                rect = transform.mapRect( rect );
     1698            }
     1699            pinPointTranslation = true;
     1700            break;
     1701        }
     1702#endif
    9771703        default:
    9781704        {
    979             size = d_data->size;
    980         }
    981     }
    982 
    983     return size + QSize( 1, 1 ); // for antialiasing
     1705            rect.setSize( d_data->size );
     1706            rect.moveCenter( QPointF( 0.0, 0.0 ) );
     1707        }
     1708    }
     1709
     1710    if ( pinPointTranslation )
     1711    {
     1712        QPointF pinPoint( 0.0, 0.0 );
     1713        if ( d_data->isPinPointEnabled )
     1714            pinPoint = rect.center() - d_data->pinPoint;
     1715
     1716        rect.moveCenter( pinPoint );
     1717    }
     1718
     1719    QRect r;
     1720    r.setLeft( qFloor( rect.left() ) );
     1721    r.setTop( qFloor( rect.top() ) );
     1722    r.setRight( qCeil( rect.right() ) );
     1723    r.setBottom( qCeil( rect.bottom() ) );
     1724
     1725    if ( d_data->style != QwtSymbol::Pixmap )
     1726        r.adjust( -1, -1, 1, 1 ); // for antialiasing
     1727
     1728    return r;
     1729}
     1730
     1731/*!
     1732  Invalidate the cached symbol pixmap
     1733
     1734  The symbol invalidates its cache, whenever an attribute is changed
     1735  that has an effect ob how to display a symbol. In case of derived
     1736  classes with individual styles ( >= QwtSymbol::UserStyle ) it
     1737  might be necessary to call invalidateCache() for attributes
     1738  that are relevant for this style.
     1739
     1740  \sa CachePolicy, setCachePolicy(), drawSymbols()
     1741 */
     1742void QwtSymbol::invalidateCache()
     1743{
     1744    if ( !d_data->cache.pixmap.isNull() )
     1745        d_data->cache.pixmap = QPixmap();
    9841746}
    9851747
     
    9921754void QwtSymbol::setStyle( QwtSymbol::Style style )
    9931755{
    994     d_data->style = style;
     1756    if ( d_data->style != style )
     1757    {
     1758        d_data->style = style;
     1759        invalidateCache();
     1760    }
    9951761}
    9961762
  • trunk/BNC/qwt/qwt_symbol.h

    r4271 r8127  
    1212
    1313#include "qwt_global.h"
    14 #include <QPolygonF>
     14#include <qpolygon.h>
    1515
    1616class QPainter;
     
    2121class QColor;
    2222class QPointF;
     23class QPolygonF;
     24class QPainterPath;
     25class QPixmap;
     26class QByteArray;
     27class QwtGraphic;
    2328
    2429//! A class for drawing symbols
     
    8186
    8287        /*!
     88          The symbol is represented by a painter path, where the
     89          origin ( 0, 0 ) of the path coordinate system is mapped to
     90          the position of the symbol.
     91
     92          \sa setPath(), path()
     93         */
     94        Path,
     95
     96        /*!
     97          The symbol is represented by a pixmap. The pixmap is centered
     98          or aligned to its pin point.
     99
     100          \sa setPinPoint()
     101         */
     102        Pixmap,
     103
     104        /*!
     105          The symbol is represented by a graphic. The graphic is centered
     106          or aligned to its pin point.
     107
     108          \sa setPinPoint()
     109         */
     110        Graphic,
     111
     112        /*!
     113          The symbol is represented by a SVG graphic. The graphic is centered
     114          or aligned to its pin point.
     115
     116          \sa setPinPoint()
     117         */
     118        SvgDocument,
     119
     120        /*!
    83121         Styles >= QwtSymbol::UserSymbol are reserved for derived
    84122         classes of QwtSymbol that overload drawSymbols() with
     
    88126    };
    89127
     128    /*!
     129      Depending on the render engine and the complexity of the
     130      symbol shape it might be faster to render the symbol
     131      to a pixmap and to paint this pixmap.
     132
     133      F.e. the raster paint engine is a pure software renderer
     134      where in cache mode a draw operation usually ends in
     135      raster operation with the the backing store, that are usually
     136      faster, than the algorithms for rendering polygons.
     137      But the opposite can be expected for graphic pipelines
     138      that can make use of hardware acceleration.
     139
     140      The default setting is AutoCache
     141
     142      \sa setCachePolicy(), cachePolicy()
     143
     144      \note The policy has no effect, when the symbol is painted
     145            to a vector graphics format ( PDF, SVG ).
     146      \warning Since Qt 4.8 raster is the default backend on X11
     147     */
     148
     149    enum CachePolicy
     150    {
     151        //! Don't use a pixmap cache
     152        NoCache,
     153
     154        //! Always use a pixmap cache
     155        Cache,
     156
     157        /*!
     158           Use a cache when one of the following conditions is true:
     159
     160           - The symbol is rendered with the software
     161             renderer ( QPaintEngine::Raster )
     162         */
     163        AutoCache
     164    };
     165
    90166public:
    91167    QwtSymbol( Style = NoSymbol );
    92168    QwtSymbol( Style, const QBrush &, const QPen &, const QSize & );
    93     QwtSymbol( const QwtSymbol & );
     169    QwtSymbol( const QPainterPath &, const QBrush &, const QPen & );
     170
    94171    virtual ~QwtSymbol();
    95172
    96     QwtSymbol &operator=( const QwtSymbol & );
    97     bool operator==( const QwtSymbol & ) const;
    98     bool operator!=( const QwtSymbol & ) const;
     173    void setCachePolicy( CachePolicy );
     174    CachePolicy cachePolicy() const;
    99175
    100176    void setSize( const QSize & );
     
    102178    const QSize& size() const;
    103179
     180    void setPinPoint( const QPointF &pos, bool enable = true );
     181    QPointF pinPoint() const;
     182
     183    void setPinPointEnabled( bool );
     184    bool isPinPointEnabled() const;
     185
    104186    virtual void setColor( const QColor & );
    105187
     
    107189    const QBrush& brush() const;
    108190
     191    void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
    109192    void setPen( const QPen & );
    110193    const QPen& pen() const;
     
    113196    Style style() const;
    114197
     198    void setPath( const QPainterPath & );
     199    const QPainterPath &path() const;
     200
     201    void setPixmap( const QPixmap & );
     202    const QPixmap &pixmap() const;
     203
     204    void setGraphic( const QwtGraphic & );
     205    const QwtGraphic &graphic() const;
     206
     207#ifndef QWT_NO_SVG
     208    void setSvgDocument( const QByteArray & );
     209#endif
     210
     211    void drawSymbol( QPainter *, const QRectF & ) const;
    115212    void drawSymbol( QPainter *, const QPointF & ) const;
    116213    void drawSymbols( QPainter *, const QPolygonF & ) const;
    117 
    118     virtual QSize boundingSize() const;
     214    void drawSymbols( QPainter *,
     215        const QPointF *, int numPoints ) const;
     216
     217    virtual QRect boundingRect() const;
     218    void invalidateCache();
    119219
    120220protected:
    121     virtual void drawSymbols( QPainter *,
     221    virtual void renderSymbols( QPainter *,
    122222        const QPointF *, int numPoints ) const;
    123223
    124224private:
     225    // Disabled copy constructor and operator=
     226    QwtSymbol( const QwtSymbol & );
     227    QwtSymbol &operator=( const QwtSymbol & );
     228
    125229    class PrivateData;
    126230    PrivateData *d_data;
  • trunk/BNC/qwt/qwt_system_clock.cpp

    r4271 r8127  
    99
    1010#include "qwt_system_clock.h"
     11
     12#if QT_VERSION >= 0x040800
     13#define USE_ELAPSED_TIMER 1
     14#endif
     15
     16#if USE_ELAPSED_TIMER
     17
     18#include <qelapsedtimer.h>
     19
     20class QwtSystemClock::PrivateData
     21{
     22public:
     23    QElapsedTimer timer;
     24};
     25
     26QwtSystemClock::QwtSystemClock()
     27{
     28    d_data = new PrivateData();
     29}
     30
     31QwtSystemClock::~QwtSystemClock()
     32{
     33    delete d_data;
     34}
     35   
     36bool QwtSystemClock::isNull() const
     37{
     38    return d_data->timer.isValid();
     39}
     40       
     41void QwtSystemClock::start()
     42{
     43    d_data->timer.start();
     44}
     45
     46double QwtSystemClock::restart()
     47{
     48    const qint64 nsecs = d_data->timer.restart();
     49    return nsecs / 1e6;
     50}
     51
     52double QwtSystemClock::elapsed() const
     53{
     54    const qint64 nsecs = d_data->timer.nsecsElapsed();
     55    return nsecs / 1e6;
     56}
     57   
     58#else // !USE_ELAPSED_TIMER
     59
    1160#include <qdatetime.h>
    1261
     
    111160        kern_return_t err = mach_timebase_info( &info );
    112161
    113         //Convert the timebase into ms
     162        // convert the timebase into ms
    114163        if ( err == 0  )
    115164            conversion = 1e-6 * ( double ) info.numer / ( double ) info.denom;
     
    308357
    309358/*!
    310   The start time to the current time and
    311   return the time, that is elapsed since the
    312   previous start time.
     359  Set the start time to the current time
     360  \return Time, that is elapsed since the previous start time.
    313361*/
    314362double QwtSystemClock::restart()
     
    346394}
    347395
    348 /*!
    349   \return Accuracy of the system clock in milliseconds.
    350 */
    351 double QwtSystemClock::precision()
    352 {
    353     static double prec = 0.0;
    354     if ( prec <= 0.0 )
    355     {
    356 #if defined(QWT_HIGH_RESOLUTION_CLOCK)
    357         prec = QwtHighResolutionClock::precision();
    358 #endif
    359         if ( prec <= 0.0 )
    360             prec = 1.0; // QTime offers 1 ms
    361     }
    362 
    363     return prec;
    364 }
     396#endif
  • trunk/BNC/qwt/qwt_system_clock.h

    r4271 r8127  
    4040    double elapsed() const;
    4141
    42     static double precision();
    43 
    4442private:
    4543    class PrivateData;
  • trunk/BNC/qwt/qwt_text.cpp

    r4271 r8127  
    22 * Qwt Widget Library
    33 * Copyright (C) 1997   Josef Wilgen
    4  * Copyright (C) 2003   Uwe Rathmann
     4 * Copyright (C) 2002   Uwe Rathmann
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    139139    PrivateData():
    140140        renderFlags( Qt::AlignCenter ),
    141         backgroundPen( Qt::NoPen ),
     141        borderRadius( 0 ),
     142        borderPen( Qt::NoPen ),
    142143        backgroundBrush( Qt::NoBrush ),
    143144        paintAttributes( 0 ),
     
    151152    QFont font;
    152153    QColor color;
    153     QPen backgroundPen;
     154    double borderRadius;
     155    QPen borderPen;
    154156    QBrush backgroundBrush;
    155157
     
    219221        d_data->font == other.d_data->font &&
    220222        d_data->color == other.d_data->color &&
    221         d_data->backgroundPen == other.d_data->backgroundPen &&
     223        d_data->borderRadius == other.d_data->borderRadius &&
     224        d_data->borderPen == other.d_data->borderPen &&
    222225        d_data->backgroundBrush == other.d_data->backgroundBrush &&
    223226        d_data->paintAttributes == other.d_data->paintAttributes &&
     
    248251
    249252/*!
    250    Return the text.
     253   \return Text as QString.
    251254   \sa setText()
    252255*/
     
    261264   The default setting is Qt::AlignCenter
    262265
    263    \param renderFlags Bitwise OR of the flags used like in QPainter::drawText
     266   \param renderFlags Bitwise OR of the flags used like in QPainter::drawText()
    264267
    265268   \sa renderFlags(), QwtTextEngine::draw()
     
    304307
    305308/*!
    306   Return the font of the text, if it has one.
    307   Otherwise return defaultFont.
    308 
    309   \param defaultFont Default font
    310   \sa setFont(), font(), PaintAttributes
     309   Return the font of the text, if it has one.
     310   Otherwise return defaultFont.
     311
     312   \param defaultFont Default font
     313   \return Font used for drawing the text
     314
     315   \sa setFont(), font(), PaintAttributes
    311316*/
    312317QFont QwtText::usedFont( const QFont &defaultFont ) const
     
    319324
    320325/*!
    321    Set the pen color used for painting the text.
     326   Set the pen color used for drawing the text.
    322327
    323328   \param color Color
     
    342347
    343348  \param defaultColor Default color
     349  \return Color used for drawing the text
     350
    344351  \sa setColor(), color(), PaintAttributes
    345352*/
     
    353360
    354361/*!
     362  Set the radius for the corners of the border frame
     363
     364  \param radius Radius of a rounded corner
     365  \sa borderRadius(), setBorderPen(), setBackgroundBrush()
     366*/
     367void QwtText::setBorderRadius( double radius )
     368{
     369    d_data->borderRadius = qMax( 0.0, radius );
     370}
     371
     372/*!
     373  \return Radius for the corners of the border frame
     374  \sa setBorderRadius(), borderPen(), backgroundBrush()
     375*/
     376double QwtText::borderRadius() const
     377{
     378    return d_data->borderRadius;
     379}
     380
     381/*!
    355382   Set the background pen
    356383
    357384   \param pen Background pen
    358    \sa backgroundPen(), setBackgroundBrush()
    359 */
    360 void QwtText::setBackgroundPen( const QPen &pen )
    361 {
    362     d_data->backgroundPen = pen;
     385   \sa borderPen(), setBackgroundBrush()
     386*/
     387void QwtText::setBorderPen( const QPen &pen )
     388{
     389    d_data->borderPen = pen;
    363390    setPaintAttribute( PaintBackground );
    364391}
     
    366393/*!
    367394   \return Background pen
    368    \sa setBackgroundPen(), backgroundBrush()
    369 */
    370 QPen QwtText::backgroundPen() const
    371 {
    372     return d_data->backgroundPen;
     395   \sa setBorderPen(), backgroundBrush()
     396*/
     397QPen QwtText::borderPen() const
     398{
     399    return d_data->borderPen;
    373400}
    374401
     
    377404
    378405   \param brush Background brush
    379    \sa backgroundBrush(), setBackgroundPen()
     406   \sa backgroundBrush(), setBorderPen()
    380407*/
    381408void QwtText::setBackgroundBrush( const QBrush &brush )
     
    387414/*!
    388415   \return Background brush
    389    \sa setBackgroundBrush(), backgroundPen()
     416   \sa setBackgroundBrush(), borderPen()
    390417*/
    391418QBrush QwtText::backgroundBrush() const
     
    401428
    402429   \note Used by setFont(), setColor(),
    403          setBackgroundPen() and setBackgroundBrush()
     430         setBorderPen() and setBackgroundBrush()
    404431   \sa testPaintAttribute()
    405432*/
     
    492519
    493520/*!
    494    Find the height for a given width
    495 
    496    \param defaultFont Font, used for the calculation if the text has no font
    497 
    498    \return Calculated height
    499 */
    500 
    501 /*!
    502521   Returns the size, that is needed to render text
    503522
    504523   \param defaultFont Font of the text
    505    \return Caluclated size
     524   \return Calculated size
    506525*/
    507526QSizeF QwtText::textSize( const QFont &defaultFont ) const
     
    543562    if ( d_data->paintAttributes & PaintBackground )
    544563    {
    545         if ( d_data->backgroundPen != Qt::NoPen ||
     564        if ( d_data->borderPen != Qt::NoPen ||
    546565            d_data->backgroundBrush != Qt::NoBrush )
    547566        {
    548567            painter->save();
    549             painter->setPen( d_data->backgroundPen );
     568
     569            painter->setPen( d_data->borderPen );
    550570            painter->setBrush( d_data->backgroundBrush );
    551             QwtPainter::drawRect( painter, rect );
     571
     572            if ( d_data->borderRadius == 0 )
     573            {
     574                QwtPainter::drawRect( painter, rect );
     575            }
     576            else
     577            {
     578                painter->setRenderHint( QPainter::Antialiasing, true );
     579                painter->drawRoundedRect( rect,
     580                    d_data->borderRadius, d_data->borderRadius );
     581            }
     582
    552583            painter->restore();
    553584        }
     
    596627   In case of QwtText::AutoText the first text engine
    597628   (beside QwtPlainTextEngine) is returned, where QwtTextEngine::mightRender
    598    returns true. If there is none QwtPlainTextEngine is returnd.
     629   returns true. If there is none QwtPlainTextEngine is returned.
    599630
    600631   If no text engine is registered for the format QwtPlainTextEngine
     
    603634   \param text Text, needed in case of AutoText
    604635   \param format Text format
     636
     637   \return Corresponding text engine
    605638*/
    606639const QwtTextEngine *QwtText::textEngine( const QString &text,
  • trunk/BNC/qwt/qwt_text.h

    r4271 r8127  
    22 * Qwt Widget Library
    33 * Copyright (C) 1997   Josef Wilgen
    4  * Copyright (C) 2003   Uwe Rathmann
     4 * Copyright (C) 2002   Uwe Rathmann
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    1515#include <qsize.h>
    1616#include <qfont.h>
     17#include <qmetatype.h>
    1718
    1819class QColor;
     
    3233    how to render it. Each format (f.e MathML, TeX, Qt Rich Text)
    3334    has its own set of control sequences, that can be handles by
    34     a QwtTextEngine for this format.
     35    a special QwtTextEngine for this format.
    3536  - Background\n
    3637    A text might have a background, defined by a QPen and QBrush
    37     to improve its visibility.
     38    to improve its visibility. The corners of the background might
     39    be rounded.
    3840  - Font\n
    3941    A text might have an individual font.
     
    4244  - Render Flags\n
    4345    Flags from Qt::AlignmentFlag and Qt::TextFlag used like in
    44     QPainter::drawText.
     46    QPainter::drawText().
    4547
    4648  \sa QwtTextEngine, QwtTextLabel
     
    6365    {
    6466        /*!
    65           The text format is determined using QwtTextEngine::mightRender for
     67          The text format is determined using QwtTextEngine::mightRender() for
    6668          all available text engines in increasing order > PlainText.
    6769          If none of the text engines can render the text is rendered
     
    168170    QColor usedColor( const QColor & ) const;
    169171
    170     void setBackgroundPen( const QPen & );
    171     QPen backgroundPen() const;
     172    void setBorderRadius( double );
     173    double borderRadius() const;
     174
     175    void setBorderPen( const QPen & );
     176    QPen borderPen() const;
    172177
    173178    void setBackgroundBrush( const QBrush & );
     
    214219Q_DECLARE_OPERATORS_FOR_FLAGS( QwtText::LayoutAttributes )
    215220
     221Q_DECLARE_METATYPE( QwtText )
     222
    216223#endif
  • trunk/BNC/qwt/qwt_text_engine.cpp

    r4271 r8127  
    22 * Qwt Widget Library
    33 * Copyright (C) 1997   Josef Wilgen
    4  * Copyright (C) 2003   Uwe Rathmann
     4 * Copyright (C) 2002   Uwe Rathmann
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    6262            option.setWrapMode( QTextOption::NoWrap );
    6363
    64         option.setAlignment( ( Qt::Alignment ) flags );
     64        option.setAlignment( static_cast<Qt::Alignment>( flags ) );
    6565        setDefaultTextOption( option );
    6666
     
    116116        for ( row = 0; row < img.height(); row++ )
    117117        {
    118             const QRgb *line = ( const QRgb * )img.scanLine( row );
     118            const QRgb *line = reinterpret_cast<const QRgb *>(
     119                img.scanLine( row ) );
    119120
    120121            const int w = pm.width();
     
    181182  \param text Text to be rendered
    182183
    183   \return Caluclated size
     184  \return Calculated size
    184185*/
    185186QSizeF QwtPlainTextEngine::textSize( const QFont &font,
     
    248249
    249250   \param font Font of the text
    250    \param flags Bitwise OR of the flags used like in QPainter::drawText
     251   \param flags Bitwise OR of the flags used like in QPainter::drawText()
    251252   \param text Text to be rendered
    252253   \param width Width
     
    267268
    268269  \param font Font of the text
    269   \param flags Bitwise OR of the flags used like in QPainter::drawText
     270  \param flags Bitwise OR of the flags used like in QPainter::drawText()
    270271  \param text Text to be rendered
    271272
    272   \return Caluclated size
     273  \return Calculated size
    273274*/
    274275
     
    294295  \param painter Painter
    295296  \param rect Clipping rectangle
    296   \param flags Bitwise OR of the flags like in for QPainter::drawText
     297  \param flags Bitwise OR of the flags like in for QPainter::drawText()
    297298  \param text Text to be rendered
    298299*/
     
    308309
    309310   \param text Text
    310    \param flags Bitwise OR of the flags like in for QPainter::drawText
     311   \param flags Bitwise OR of the flags like in for QPainter::drawText()
    311312
    312313   \return Tagged text
     
    321322
    322323  \param text Text to be tested
    323   \return QStyleSheet::mightBeRichText(text);
     324  \return Qt::mightBeRichText(text);
    324325*/
    325326bool QwtRichTextEngine::mightRender( const QString &text ) const
  • trunk/BNC/qwt/qwt_text_engine.h

    r4271 r8127  
    22 * Qwt Widget Library
    33 * Copyright (C) 1997   Josef Wilgen
    4  * Copyright (C) 2003   Uwe Rathmann
     4 * Copyright (C) 2002   Uwe Rathmann
    55 *
    66 * This library is free software; you can redistribute it and/or
     
    5858      \param text Text to be rendered
    5959
    60       \return Caluclated size
     60      \return Calculated size
    6161     */
    6262    virtual QSizeF textSize( const QFont &font, int flags,
     
    7575
    7676      The textSize might include margins around the
    77       text, like QFontMetrics::descent. In situations
    78       where texts need to be aligend in detail, knowing
     77      text, like QFontMetrics::descent(). In situations
     78      where texts need to be aligned in detail, knowing
    7979      these margins might improve the layout calculations.
    8080
     
    9494      \param painter Painter
    9595      \param rect Clipping rectangle
    96       \param flags Bitwise OR of the flags like in for QPainter::drawText
     96      \param flags Bitwise OR of the flags like in for QPainter::drawText()
    9797      \param text Text to be rendered
    9898     */
  • trunk/BNC/qwt/qwt_text_label.cpp

    r4271 r8127  
    6464
    6565/*!
     66   Interface for the designer plugin - does the same as setText()
     67   \sa plainText()
     68 */
     69void QwtTextLabel::setPlainText( const QString &text )
     70{
     71    setText( QwtText( text ) );
     72}
     73
     74/*!
     75   Interface for the designer plugin
     76
     77   \return Text as plain text
     78   \sa setPlainText(), text()
     79 */
     80QString QwtTextLabel::plainText() const
     81{
     82    return d_data->text.text();
     83}
     84
     85/*!
    6686   Change the label's text, keeping all other QwtText attributes
    6787   \param text New text
     
    7090  \sa QwtText
    7191*/
    72 void QwtTextLabel::setText( const QString &text, QwtText::TextFormat textFormat )
     92void QwtTextLabel::setText( const QString &text,
     93    QwtText::TextFormat textFormat )
    7394{
    7495    d_data->text.setText( text, textFormat );
     
    126147}
    127148
    128 //! Return label's text indent in pixels
     149//! Return label's text margin in pixels
    129150int QwtTextLabel::margin() const
    130151{
     
    144165}
    145166
    146 //! Return label's margin in pixels
     167//! Return a size hint
    147168QSize QwtTextLabel::sizeHint() const
    148169{
     
    177198
    178199/*!
    179    Returns the preferred height for this widget, given the width.
    180200   \param width Width
     201   \return Preferred height for this widget, given the width.
    181202*/
    182203int QwtTextLabel::heightForWidth( int width ) const
     
    192213        width -= indent;
    193214
    194     int height = d_data->text.heightForWidth( width, font() );
    195     if ( renderFlags & Qt::AlignTop || renderFlags & Qt::AlignBottom )
     215    int height = qCeil( d_data->text.heightForWidth( width, font() ) );
     216    if ( ( renderFlags & Qt::AlignTop ) || ( renderFlags & Qt::AlignBottom ) )
    196217        height += indent;
    197218
     
    232253    painter->setPen( palette().color( QPalette::Active, QPalette::Text ) );
    233254
    234     drawText( painter, r );
     255    drawText( painter, QRectF( r ) );
    235256
    236257    if ( hasFocus() )
    237258    {
    238         const int margin = 2;
    239 
    240         QRect focusRect = contentsRect();
    241         focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin,
    242             focusRect.width() - 2 * margin - 2,
    243             focusRect.height() - 2 * margin - 2 );
     259        const int m = 2;
     260
     261        QRect focusRect = contentsRect().adjusted( m, m, -m + 1, -m + 1);
    244262
    245263        QwtPainter::drawFocusRect( painter, this, focusRect );
     
    248266
    249267//! Redraw the text
    250 void QwtTextLabel::drawText( QPainter *painter, const QRect &textRect )
     268void QwtTextLabel::drawText( QPainter *painter, const QRectF &textRect )
    251269{
    252270    d_data->text.draw( painter, textRect );
     
    254272
    255273/*!
    256   Calculate the rect for the text in widget coordinates
    257   \return Text rect
     274  Calculate geometry for the text in widget coordinates
     275  \return Geometry for the text
    258276*/
    259277QRect QwtTextLabel::textRect() const
  • trunk/BNC/qwt/qwt_text_label.h

    r4271 r8127  
    2929    Q_PROPERTY( int indent READ indent WRITE setIndent )
    3030    Q_PROPERTY( int margin READ margin WRITE setMargin )
     31    Q_PROPERTY( QString plainText READ plainText WRITE setPlainText )
    3132
    3233public:
     
    3435    explicit QwtTextLabel( const QwtText &, QWidget *parent = NULL );
    3536    virtual ~QwtTextLabel();
     37
     38    void setPlainText( const QString & );
     39    QString plainText() const;
    3640
    3741public Q_SLOTS:
     
    5761    QRect textRect() const;
    5862
     63    virtual void drawText( QPainter *, const QRectF & );
     64
    5965protected:
    6066    virtual void paintEvent( QPaintEvent *e );
    6167    virtual void drawContents( QPainter * );
    62     virtual void drawText( QPainter *, const QRect & );
    6368
    6469private:
  • trunk/BNC/qwtpolar/qwt_polar_canvas.cpp

    r4272 r8127  
    99#include "qwt_polar_canvas.h"
    1010#include "qwt_polar_plot.h"
     11#include <qwt_painter.h>
    1112#include <qpainter.h>
    1213#include <qevent.h>
     
    213214                {
    214215                    QWidget *bgWidget = qwtBackgroundWidget( plot() );
    215                     bs.fill( bgWidget, mapTo( bgWidget, rect().topLeft() ) );
     216
     217                                        QwtPainter::fillPixmap( bgWidget, bs,
     218                                                mapTo( bgWidget, rect().topLeft() ) );
     219
    216220                    p.begin( &bs );
    217221                }
  • trunk/BNC/qwtpolar/qwt_polar_curve.cpp

    r7990 r8127  
    1414#include <qwt_symbol.h>
    1515#include <qwt_legend.h>
    16 #include <qwt_legend_item.h>
    1716#include <qwt_curve_fitter.h>
    1817#include <qwt_clipper.h>
     
    174173  \sa symbol()
    175174*/
    176 void QwtPolarCurve::setSymbol( const QwtSymbol *symbol )
     175void QwtPolarCurve::setSymbol( QwtSymbol *symbol )
    177176{
    178177    if ( symbol != d_data->symbol )
     
    434433    if ( !clipRect.isEmpty() )
    435434    {
    436         double off = qCeil( qMax(qreal(1.0), painter->pen().widthF() ) );
     435        double off = qCeil( qMax( qreal( 1.0 ), painter->pen().widthF() ) );
    437436        clipRect = clipRect.toRect().adjusted( -off, -off, off, off );
    438437        polyline = QwtClipper::clipPolygonF( clipRect, polyline );
     
    501500}
    502501
    503 //!  Update the widget that represents the curve on the legend
    504 void QwtPolarCurve::updateLegend( QwtLegend *legend ) const
    505 {
    506     if ( legend && testItemAttribute( QwtPolarCurve::Legend )
    507             && ( d_data->legendAttributes & QwtPolarCurve::LegendShowSymbol )
    508             && d_data->symbol
    509             && d_data->symbol->style() != QwtSymbol::NoSymbol )
    510     {
    511         QWidget *lgdItem = legend->find( this );
    512         if ( lgdItem == NULL )
    513         {
    514             lgdItem = legendItem();
    515             if ( lgdItem )
    516                 legend->insert( this, lgdItem );
    517         }
    518 
    519         QwtLegendItem *l = qobject_cast<QwtLegendItem *>( lgdItem );
    520         if ( l )
    521         {
    522             QSize sz = d_data->symbol->boundingSize();
    523             sz += QSize( 2, 2 ); // margin
    524 
    525             if ( d_data->legendAttributes & QwtPolarCurve::LegendShowLine )
    526             {
    527                 // Avoid, that the line is completely covered by the symbol
    528 
    529                 int w = qCeil( 1.5 * sz.width() );
    530                 if ( w % 2 )
    531                     w++;
    532 
    533                 sz.setWidth( qMax( 8, w ) );
    534             }
    535 
    536             l->setIdentifierSize( sz );
    537         }
    538     }
    539 
    540     QwtPolarItem::updateLegend( legend );
    541 }
    542 
    543 /*!
    544   \brief Draw the identifier representing the curve on the legend
    545 
    546   \param painter Qt Painter
    547   \param rect Bounding rectangle for the identifier
    548 
    549   \sa setLegendAttribute
    550 */
    551 void QwtPolarCurve::drawLegendIdentifier(
    552     QPainter *painter, const QRectF &rect ) const
    553 {
    554     if ( rect.isEmpty() )
    555         return;
    556 
    557     const double dim = qMin( rect.width(), rect.height() );
    558 
    559     QSizeF size( dim, dim );
    560 
    561     QRectF r( 0, 0, size.width(), size.height() );
    562     r.moveCenter( rect.center() );
     502/*!
     503   \return Icon representing the curve on the legend
     504
     505   \param index Index of the legend entry
     506                ( ignored as there is only one )
     507   \param size Icon size
     508
     509   \sa QwtPolarItem::setLegendIconSize(), QwtPolarItem::legendData()
     510 */
     511QwtGraphic QwtPolarCurve::legendIcon( int index,
     512    const QSizeF &size ) const
     513{
     514    Q_UNUSED( index );
     515
     516    if ( size.isEmpty() )
     517        return QwtGraphic();
     518
     519    QwtGraphic graphic;
     520    graphic.setDefaultSize( size );
     521    graphic.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
     522
     523    QPainter painter( &graphic );
     524    painter.setRenderHint( QPainter::Antialiasing,
     525        testRenderHint( QwtPolarItem::RenderAntialiased ) );
    563526
    564527    if ( d_data->legendAttributes == 0 )
    565528    {
    566529        QBrush brush;
     530
    567531        if ( style() != QwtPolarCurve::NoCurve )
     532        {
    568533            brush = QBrush( pen().color() );
     534        }
    569535        else if ( d_data->symbol &&
    570536            ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
     
    572538            brush = QBrush( d_data->symbol->pen().color() );
    573539        }
     540
    574541        if ( brush.style() != Qt::NoBrush )
    575             painter->fillRect( r, brush );
    576     }
     542        {
     543            QRectF r( 0, 0, size.width(), size.height() );
     544            painter.fillRect( r, brush );
     545        }
     546    }
     547
    577548    if ( d_data->legendAttributes & QwtPolarCurve::LegendShowLine )
    578549    {
    579550        if ( pen() != Qt::NoPen )
    580551        {
    581             painter->setPen( pen() );
    582             QwtPainter::drawLine( painter, rect.left(), rect.center().y(),
    583                 rect.right() - 1.0, rect.center().y() );
    584         }
    585     }
     552            QPen pn = pen();
     553            pn.setCapStyle( Qt::FlatCap );
     554
     555            painter.setPen( pn );
     556
     557            const double y = 0.5 * size.height();
     558            QwtPainter::drawLine( &painter, 0.0, y, size.width(), y );
     559        }
     560    }
     561
    586562    if ( d_data->legendAttributes & QwtPolarCurve::LegendShowSymbol )
    587563    {
    588         if ( d_data->symbol &&
    589             ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
    590         {
    591             QSize symbolSize = d_data->symbol->boundingSize();
    592             symbolSize -= QSize( 2, 2 );
    593 
    594             // scale the symbol size down if it doesn't fit into rect.
    595 
    596             double xRatio = 1.0;
    597             if ( rect.width() < symbolSize.width() )
    598                 xRatio = rect.width() / symbolSize.width();
    599             double yRatio = 1.0;
    600             if ( rect.height() < symbolSize.height() )
    601                 yRatio = rect.height() / symbolSize.height();
    602 
    603             const double ratio = qMin( xRatio, yRatio );
    604 
    605             painter->save();
    606             painter->scale( ratio, ratio );
    607 
    608             d_data->symbol->drawSymbol( painter, rect.center() / ratio );
    609 
    610             painter->restore();
    611         }
    612     }
     564        if ( d_data->symbol )
     565        {
     566            QRectF r( 0, 0, size.width(), size.height() );
     567            d_data->symbol->drawSymbol( &painter, r );
     568        }
     569    }
     570
     571    return graphic;
    613572}
    614573
     
    634593    return QwtInterval();
    635594}
     595
     596
  • trunk/BNC/qwtpolar/qwt_polar_curve.h

    r4272 r8127  
    5858        In the default setting all attributes are off.
    5959
    60         \sa setLegendAttribute(), testLegendAttribute(),
    61             drawLegendIdentifier()
     60        \sa setLegendAttribute(), testLegendAttribute()
    6261     */
    6362
     
    101100    CurveStyle style() const;
    102101
    103     void setSymbol( const QwtSymbol * );
     102    void setSymbol( QwtSymbol * );
    104103    const QwtSymbol *symbol() const;
    105104
     
    116115        const QPointF &pole, int from, int to ) const;
    117116
    118     virtual void updateLegend( QwtLegend * ) const;
    119117    virtual QwtInterval boundingInterval( int scaleId ) const;
    120118
    121     virtual void drawLegendIdentifier( QPainter *, const QRectF & ) const;
     119    virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
    122120
    123121protected:
  • trunk/BNC/qwtpolar/qwt_polar_global.h

    r4272 r8127  
    1414// QWT_POLAR_VERSION is (major << 16) + (minor << 8) + patch.
    1515
    16 #define QWT_POLAR_VERSION       0x010000
    17 #define QWT_POLAR_VERSION_STR   "1.0.0"
    18 
    19 #if defined(Q_WS_WIN) || defined(Q_WS_S60)
     16#define QWT_POLAR_VERSION       0x010101
     17#define QWT_POLAR_VERSION_STR   "1.1.1"
    2018
    2119#if defined(_MSC_VER) /* MSVC Compiler */
     
    2624#ifdef QWT_POLAR_DLL
    2725
    28 #if defined(QWT_POLAR_MAKEDLL)     // create a Qwt DLL library
    29 #define QWT_POLAR_EXPORT  __declspec(dllexport)
     26#if defined(QWT_POLAR_MAKEDLL)     // create DLL library
     27#define QWT_POLAR_EXPORT  Q_DECL_EXPORT
    3028#define QWT_POLAR_TEMPLATEDLL
    31 #else                        // use a Qwt DLL library
    32 #define QWT_POLAR_EXPORT  __declspec(dllimport)
     29#else                        // use DLL library
     30#define QWT_POLAR_EXPORT  Q_DECL_IMPORT
    3331#endif
    3432
    35 #endif // QWT_POLAR_MAKEDLL
    36 
    37 #endif // Q_WS_WIN
     33#endif // QWT_POLAR_DLL
    3834
    3935#ifndef QWT_POLAR_EXPORT
  • trunk/BNC/qwtpolar/qwt_polar_grid.cpp

    r4272 r8127  
    877877
    878878            scaleDraw->setAngleRange( from, from - 360.0 );
    879             scaleDraw->setTransformation( azimuthMap.transformation()->copy() );
     879
     880            const QwtTransform *transform = azimuthMap.transformation();
     881            if ( transform )
     882                scaleDraw->setTransformation( transform->copy() );
     883            else
     884                scaleDraw->setTransformation( NULL );
    880885        }
    881886        else
     
    911916                }
    912917            }
    913             scaleDraw->setTransformation( radialMap.transformation()->copy() );
     918            const QwtTransform *transform = radialMap.transformation();
     919            if ( transform )
     920                scaleDraw->setTransformation( transform->copy() );
     921            else
     922                scaleDraw->setTransformation( NULL );
    914923        }
    915924    }
     
    976985                QwtScaleDiv sd = radialGrid.scaleDiv;
    977986
    978                 QList<double> &ticks =
    979                     const_cast<QList<double> &>( sd.ticks( QwtScaleDiv::MajorTick ) );
     987                QList<double> ticks = sd.ticks( QwtScaleDiv::MajorTick );
    980988
    981989                if ( testDisplayFlag( SmartOriginLabel ) )
     
    10111019                }
    10121020
     1021                sd.setTicks( QwtScaleDiv::MajorTick, ticks );
    10131022                axis.scaleDraw->setScaleDiv( sd );
    10141023
     
    10491058const QwtScaleDraw *QwtPolarGrid::scaleDraw( int axisId ) const
    10501059{
    1051     if ( axisId >= QwtPolar::AxisLeft || axisId <= QwtPolar::AxisBottom )
     1060    if ( axisId >= QwtPolar::AxisLeft && axisId <= QwtPolar::AxisBottom )
    10521061        return static_cast<QwtScaleDraw *>( d_data->axisData[axisId].scaleDraw );
    10531062
     
    10641073QwtScaleDraw *QwtPolarGrid::scaleDraw( int axisId )
    10651074{
    1066     if ( axisId >= QwtPolar::AxisLeft || axisId <= QwtPolar::AxisBottom )
     1075    if ( axisId >= QwtPolar::AxisLeft && axisId <= QwtPolar::AxisBottom )
    10671076        return static_cast<QwtScaleDraw *>( d_data->axisData[axisId].scaleDraw );
    10681077
  • trunk/BNC/qwtpolar/qwt_polar_item.cpp

    r4272 r8127  
    1010#include "qwt_polar_item.h"
    1111#include <qwt_legend.h>
    12 #include <qwt_legend_item.h>
    1312#include <qwt_scale_div.h>
    1413#include <qpainter.h>
     
    2221        attributes( 0 ),
    2322        renderHints( 0 ),
    24         z( 0.0 )
     23        renderThreadCount( 1 ),
     24        z( 0.0 ),
     25        legendIconSize( 8, 8 )
    2526    {
    2627    }
     
    3132    QwtPolarItem::ItemAttributes attributes;
    3233    QwtPolarItem::RenderHints renderHints;
     34    uint renderThreadCount;
     35
    3336    double z;
    3437
    3538    QwtText title;
     39    QSize legendIconSize;
    3640};
    3741
     
    7478        return;
    7579
    76     // remove the item from the previous plot
    77 
    7880    if ( d_data->plot )
    79     {
    80         if ( d_data->plot->legend() )
    81             d_data->plot->legend()->remove( this );
    82 
    8381        d_data->plot->attachItem( this, false );
    8482
    85         if ( d_data->plot->autoReplot() )
    86             d_data->plot->update();
    87     }
    88 
    8983    d_data->plot = plot;
    9084
    9185    if ( d_data->plot )
    92     {
    93         // insert the item into the current plot
    94 
    9586        d_data->plot->attachItem( this, true );
    96         itemChanged();
    97     }
     87}
     88
     89/*!
     90   \brief This method detaches a QwtPolarItem from the QwtPolarPlot it
     91          has been associated with.
     92
     93   detach() is equivalent to calling attach( NULL )
     94   \sa attach()
     95*/
     96void QwtPolarItem::detach()
     97{
     98    attach( NULL );
    9899}
    99100
     
    257258}
    258259
     260/*!
     261   On multi core systems rendering of certain plot item
     262   ( f.e QwtPolarSpectrogram ) can be done in parallel in
     263   several threads.
     264
     265   The default setting is set to 1.
     266
     267   \param numThreads Number of threads to be used for rendering.
     268                     If numThreads is set to 0, the system specific
     269                     ideal thread count is used.
     270
     271   The default thread count is 1 ( = no additional threads )
     272*/
     273void QwtPolarItem::setRenderThreadCount( uint numThreads )
     274{
     275    d_data->renderThreadCount = numThreads;
     276}
     277
     278/*!
     279   \return Number of threads to be used for rendering.
     280           If numThreads() is set to 0, the system specific
     281           ideal thread count is used.
     282*/
     283uint QwtPolarItem::renderThreadCount() const
     284{
     285    return d_data->renderThreadCount;
     286}
     287
     288/*!
     289   Set the size of the legend icon
     290
     291   The default setting is 8x8 pixels
     292
     293   \param size Size
     294   \sa legendIconSize(), legendIcon()
     295*/
     296void QwtPolarItem::setLegendIconSize( const QSize &size )
     297{
     298    if ( d_data->legendIconSize != size )
     299    {
     300        d_data->legendIconSize = size;
     301        legendChanged();
     302    }
     303}
     304
     305/*!
     306   \return Legend icon size
     307   \sa setLegendIconSize(), legendIcon()
     308*/
     309QSize QwtPolarItem::legendIconSize() const
     310{
     311    return d_data->legendIconSize;
     312}
     313
    259314//! Show the item
    260315void QwtPolarItem::show()
     
    302357{
    303358    if ( d_data->plot )
    304     {
    305         if ( d_data->plot->legend() )
    306             updateLegend( d_data->plot->legend() );
    307 
    308359        d_data->plot->autoRefresh();
    309     }
     360}
     361
     362/*!
     363   Update the legend of the parent plot.
     364   \sa QwtPolarPlot::updateLegend(), itemChanged()
     365*/
     366void QwtPolarItem::legendChanged()
     367{
     368    if ( testItemAttribute( QwtPolarItem::Legend ) && d_data->plot )
     369        d_data->plot->updateLegend( this );
    310370}
    311371
     
    351411
    352412/*!
    353    \brief Update the widget that represents the item on the legend
    354 
    355    updateLegend() is called from itemChanged() to adopt the widget
    356    representing the item on the legend to its new configuration.
    357 
    358    The default implementation is made for QwtPolarCurve and updates a
    359    QwtLegendItem(), but an item could be represented by any type of widget,
    360    by overloading legendItem() and updateLegend().
    361 
    362    \sa legendItem(), itemChanged(), QwtLegend()
    363 */
    364 void QwtPolarItem::updateLegend( QwtLegend *legend ) const
    365 {
    366     if ( legend == NULL )
    367         return;
    368 
    369     QWidget *lgdItem = legend->find( this );
    370     if ( testItemAttribute( QwtPolarItem::Legend ) )
    371     {
    372         if ( lgdItem == NULL )
    373         {
    374             lgdItem = legendItem();
    375             if ( lgdItem )
    376                 legend->insert( this, lgdItem );
    377         }
    378 
    379         QwtLegendItem* label = qobject_cast<QwtLegendItem *>( lgdItem );
    380         if ( label )
    381         {
    382             // paint the identifier
    383             const QSize sz = label->identifierSize();
    384 
    385             QPixmap identifier( sz.width(), sz.height() );
    386             identifier.fill( Qt::transparent );
    387 
    388             QPainter painter( &identifier );
    389             painter.setRenderHint( QPainter::Antialiasing,
    390                 testRenderHint( QwtPolarItem::RenderAntialiased ) );
    391 
    392             drawLegendIdentifier( &painter,
    393                 QRect( 0, 0, sz.width(), sz.height() ) );
    394 
    395             painter.end();
    396 
    397             const bool doUpdate = label->updatesEnabled();
    398             if ( doUpdate )
    399                 label->setUpdatesEnabled( false );
    400 
    401             label->setText( title() );
    402             label->setIdentifier( identifier );
    403             label->setItemMode( legend->itemMode() );
    404 
    405             if ( doUpdate )
    406                 label->setUpdatesEnabled( true );
    407 
    408             label->update();
    409         }
    410     }
    411     else
    412     {
    413         if ( lgdItem )
    414         {
    415             lgdItem->hide();
    416             lgdItem->deleteLater();
    417         }
    418     }
    419 }
    420 /*!
    421    \brief Allocate the widget that represents the item on the legend
    422 
    423    The default implementation is made for QwtPolarCurve and returns a
    424    QwtLegendItem(), but an item could be represented by any type of widget,
    425    by overloading legendItem() and updateLegend().
    426 
    427    \return QwtLegendItem()
    428    \sa updateLegend() QwtLegend()
    429 */
    430 QWidget *QwtPolarItem::legendItem() const
    431 {
    432     QwtLegendItem *item = new QwtLegendItem;
    433     if ( d_data->plot )
    434     {
    435         QObject::connect( item, SIGNAL( clicked() ),
    436             d_data->plot, SLOT( legendItemClicked() ) );
    437         QObject::connect( item, SIGNAL( checked( bool ) ),
    438             d_data->plot, SLOT( legendItemChecked( bool ) ) );
    439     }
    440     return item;
     413   \brief Return all information, that is needed to represent
     414          the item on the legend
     415
     416   Most items are represented by one entry on the legend
     417   showing an icon and a text.
     418
     419   QwtLegendData is basically a list of QVariants that makes it
     420   possible to overload and reimplement legendData() to
     421   return almost any type of information, that is understood
     422   by the receiver that acts as the legend.
     423
     424   The default implementation returns one entry with
     425   the title() of the item and the legendIcon().
     426
     427   \sa title(), legendIcon(), QwtLegend
     428 */
     429QList<QwtLegendData> QwtPolarItem::legendData() const
     430{
     431    QwtLegendData data;
     432
     433    QwtText label = title();
     434    label.setRenderFlags( label.renderFlags() & Qt::AlignLeft );
     435
     436    QVariant titleValue;
     437    qVariantSetValue( titleValue, label );
     438    data.setValue( QwtLegendData::TitleRole, titleValue );
     439
     440    const QwtGraphic graphic = legendIcon( 0, legendIconSize() );
     441    if ( !graphic.isNull() )
     442    {
     443        QVariant iconValue;
     444        qVariantSetValue( iconValue, graphic );
     445        data.setValue( QwtLegendData::IconRole, iconValue );
     446    }
     447
     448    QList<QwtLegendData> list;
     449    list += data;
     450
     451    return list;
     452}
     453
     454/*!
     455   \return Icon representing the item on the legend
     456
     457   The default implementation returns an invalid icon
     458
     459   \param index Index of the legend entry
     460                ( usually there is only one )
     461   \param size Icon size
     462
     463   \sa setLegendIconSize(), legendData()
     464 */
     465QwtGraphic QwtPolarItem::legendIcon(
     466    int index, const QSizeF &size ) const
     467{
     468    Q_UNUSED( index )
     469    Q_UNUSED( size )
     470
     471    return QwtGraphic();
    441472}
    442473
  • trunk/BNC/qwtpolar/qwt_polar_item.h

    r4272 r8127  
    1212#include "qwt_polar_global.h"
    1313#include <qwt_text.h>
    14 #include <qwt_legend_itemmanager.h>
     14#include <qwt_legend_data.h>
     15#include <qwt_graphic.h>
    1516#include <qwt_interval.h>
    1617
     
    3435  types of items.
    3536*/
    36 class QWT_POLAR_EXPORT QwtPolarItem: public QwtLegendItemManager
     37class QWT_POLAR_EXPORT QwtPolarItem
    3738{
    3839public:
     
    103104
    104105    void attach( QwtPolarPlot *plot );
    105 
    106     /*!
    107        \brief This method detaches a QwtPolarItem from any QwtPolarPlot it
    108               has been associated with.
    109 
    110        detach() is equivalent to calling attach( NULL )
    111        \sa attach( QwtPolarPlot* plot )
    112     */
    113     void detach() { attach( NULL ); }
     106    void detach();
    114107
    115108    QwtPolarPlot *plot() const;
     
    127120    bool testRenderHint( RenderHint ) const;
    128121
     122    void setRenderThreadCount( uint numThreads );
     123    uint renderThreadCount() const;
     124
    129125    double z() const;
    130126    void setZ( double z );
     
    136132
    137133    virtual void itemChanged();
     134    virtual void legendChanged();
    138135
    139136    /*!
     
    154151    virtual QwtInterval boundingInterval( int scaleId ) const;
    155152
    156     virtual QWidget *legendItem() const;
    157 
    158     virtual void updateLegend( QwtLegend * ) const;
    159153    virtual void updateScaleDiv( const QwtScaleDiv &,
    160154        const QwtScaleDiv &, const QwtInterval & );
    161155
    162156    virtual int marginHint() const;
     157
     158    void setLegendIconSize( const QSize & );
     159    QSize legendIconSize() const;
     160
     161    virtual QList<QwtLegendData> legendData() const;
     162    virtual QwtGraphic legendIcon( int index, const QSizeF  & ) const;
    163163
    164164private:
     
    174174Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPolarItem::RenderHints )
    175175
     176Q_DECLARE_METATYPE( QwtPolarItem * )
     177
    176178#endif
  • trunk/BNC/qwtpolar/qwt_polar_itemdict.cpp

    r4272 r8127  
    110110
    111111/*!
    112    Attach/Detach a plot item
     112  Insert a plot item
    113113
    114    Attached items will be deleted in the destructor,
    115    if auto deletion is enabled (default). Manually detached
    116    items are not deleted.
     114  \param item PlotItem
     115  \sa removeItem()
     116 */
     117void QwtPolarItemDict::insertItem( QwtPolarItem *item )
     118{
     119    d_data->itemList.insertItem( item );
     120}
    117121
    118    \param item Plot item to attach/detach
    119    \ on If true attach, else detach the item
     122/*!
     123  Remove a plot item
    120124
    121    \sa setAutoDelete, ~QwtPolarItemDict
    122 */
    123 void QwtPolarItemDict::attachItem( QwtPolarItem *item, bool on )
     125  \param item PlotItem
     126  \sa insertItem()
     127 */
     128void QwtPolarItemDict::removeItem( QwtPolarItem *item )
    124129{
    125     if ( on )
    126         d_data->itemList.insertItem( item );
    127     else
    128         d_data->itemList.removeItem( item );
     130    d_data->itemList.removeItem( item );
    129131}
    130132
  • trunk/BNC/qwtpolar/qwt_polar_itemdict.h

    r4272 r8127  
    4444        bool autoDelete = true );
    4545
     46protected:
     47    void insertItem( QwtPolarItem * );
     48    void removeItem( QwtPolarItem * );
     49
    4650private:
    47     friend class QwtPolarItem;
    48 
    49     void attachItem( QwtPolarItem *, bool );
    50 
    5151    class PrivateData;
    5252    PrivateData *d_data;
  • trunk/BNC/qwtpolar/qwt_polar_layout.cpp

    r7990 r8127  
    2323    {
    2424        int frameWidth;
    25         int vScrollBarWidth;
    26         int hScrollBarHeight;
     25        int hScrollExtent;
     26        int vScrollExtent;
    2727        QSizeF hint;
    2828    } legend;
     
    4949    {
    5050        legend.frameWidth = plot->legend()->frameWidth();
    51         legend.vScrollBarWidth =
    52             plot->legend()->verticalScrollBar()->sizeHint().width();
    53         legend.hScrollBarHeight =
    54             plot->legend()->horizontalScrollBar()->sizeHint().height();
     51        legend.hScrollExtent =
     52            plot->legend()->scrollExtent( Qt::Horizontal );
     53        legend.vScrollExtent =
     54            plot->legend()->scrollExtent( Qt::Vertical );
    5555
    5656        const QSizeF hint = plot->legend()->sizeHint();
     
    6262
    6363        if ( h > rect.height() )
    64             w += legend.vScrollBarWidth;
     64            w += legend.hScrollExtent;
    6565
    6666        legend.hint = QSizeF( w, h );
     
    279279        // half of the available space.
    280280
    281         dim = qMin( hint.width(), qreal(rect.width() * d_data->legendRatio) );
     281        dim = qMin( double( hint.width() ), rect.width() * d_data->legendRatio );
    282282
    283283        if ( !( options & IgnoreScrollbars ) )
     
    288288                // space for the vertical scrollbar.
    289289
    290                 dim += d_data->layoutData.legend.vScrollBarWidth;
     290                dim += d_data->layoutData.legend.hScrollExtent;
    291291            }
    292292        }
     
    294294    else
    295295    {
    296         dim = qMin( hint.width(), qreal(rect.width() * d_data->legendRatio) );
    297         dim = qMax( dim, d_data->layoutData.legend.hScrollBarHeight );
     296        dim = qMin( double( hint.height() ), rect.height() * d_data->legendRatio );
     297        dim = qMax( dim, d_data->layoutData.legend.vScrollExtent );
    298298    }
    299299
  • trunk/BNC/qwtpolar/qwt_polar_plot.cpp

    r4272 r8127  
    1616#include <qwt_round_scale_draw.h>
    1717#include <qwt_legend.h>
    18 #include <qwt_legend_item.h>
    1918#include <qwt_dyngrid_layout.h>
    2019#include <qpointer.h>
     
    3534public:
    3635    ScaleData():
     36        isValid( false ),
    3737        scaleEngine( NULL )
    3838    {
     
    5353    int maxMinor;
    5454
     55    bool isValid;
     56
    5557    QwtScaleDiv scaleDiv;
    5658    QwtScaleEngine *scaleEngine;
     
    7072    QPointer<QwtTextLabel> titleLabel;
    7173    QPointer<QwtPolarCanvas> canvas;
    72     QPointer<QwtLegend> legend;
     74    QPointer<QwtAbstractLegend> legend;
    7375    double azimuthOrigin;
    7476
     
    183185      QwtPolarLayout::setLegendPosition()
    184186*/
    185 void QwtPolarPlot::insertLegend( QwtLegend *legend,
     187void QwtPolarPlot::insertLegend( QwtAbstractLegend *legend,
    186188    QwtPolarPlot::LegendPosition pos, double ratio )
    187189{
    188190    d_data->layout->setLegendPosition( pos, ratio );
     191
    189192    if ( legend != d_data->legend )
    190193    {
     
    196199        if ( d_data->legend )
    197200        {
    198             if ( pos != ExternalLegend )
     201            connect( this,
     202                SIGNAL( legendDataChanged(
     203                    const QVariant &, const QList<QwtLegendData> & ) ),
     204                d_data->legend,
     205                SLOT( updateLegend(
     206                    const QVariant &, const QList<QwtLegendData> & ) )
     207            );
     208
     209            if ( d_data->legend->parent() != this )
     210                d_data->legend->setParent( this );
     211
     212            updateLegend();
     213
     214            QwtLegend *lgd = qobject_cast<QwtLegend *>( legend );
     215            if ( lgd )
    199216            {
    200                 if ( d_data->legend->parent() != this )
    201                     d_data->legend->setParent( this );
    202             }
    203 
    204             const QwtPolarItemList& itmList = itemList();
    205             for ( QwtPolarItemIterator it = itmList.begin();
    206                     it != itmList.end(); ++it )
    207             {
    208                 ( *it )->updateLegend( d_data->legend );
    209             }
    210 
    211             QwtDynGridLayout *tl = qobject_cast<QwtDynGridLayout *>(
    212                 d_data->legend->contentsWidget()->layout() );
    213 
    214             if ( tl )
    215             {
    216                 switch( d_data->layout->legendPosition() )
     217                switch ( d_data->layout->legendPosition() )
    217218                {
    218219                    case LeftLegend:
    219220                    case RightLegend:
    220                         tl->setMaxCols( 1 ); // 1 column: align vertical
     221                    {
     222                        if ( lgd->maxColumns() == 0     )
     223                            lgd->setMaxColumns( 1 ); // 1 column: align vertical
    221224                        break;
    222 
     225                    }
    223226                    case TopLegend:
    224227                    case BottomLegend:
    225                         tl->setMaxCols( 0 ); // unlimited
     228                    {
     229                        lgd->setMaxColumns( 0 ); // unlimited
    226230                        break;
    227 
    228                     case ExternalLegend:
     231                    }
     232                    default:
    229233                        break;
    230234                }
    231235            }
    232         }
    233     }
     236
     237        }
     238    }
     239
    234240    updateLayout();
     241}
     242
     243/*!
     244  Emit legendDataChanged() for all plot item
     245
     246  \sa QwtPlotItem::legendData(), legendDataChanged()
     247 */
     248void QwtPolarPlot::updateLegend()
     249{
     250    const QwtPolarItemList& itmList = itemList();
     251    for ( QwtPolarItemIterator it = itmList.begin();
     252        it != itmList.end(); ++it )
     253    {
     254        updateLegend( *it );
     255    }
     256}
     257
     258/*!
     259  Emit legendDataChanged() for a plot item
     260
     261  \param plotItem Plot item
     262  \sa QwtPlotItem::legendData(), legendDataChanged()
     263 */
     264void QwtPolarPlot::updateLegend( const QwtPolarItem *plotItem )
     265{
     266    if ( plotItem == NULL )
     267        return;
     268
     269    QList<QwtLegendData> legendData;
     270
     271    if ( plotItem->testItemAttribute( QwtPolarItem::Legend ) )
     272        legendData = plotItem->legendData();
     273
     274    const QVariant itemInfo = itemToInfo( const_cast< QwtPolarItem *>( plotItem) );
     275    Q_EMIT legendDataChanged( itemInfo, legendData );
    235276}
    236277
     
    239280  \sa insertLegend()
    240281*/
    241 QwtLegend *QwtPolarPlot::legend()
     282QwtAbstractLegend *QwtPolarPlot::legend()
    242283{
    243284    return d_data->legend;
     
    248289  \sa insertLegend()
    249290*/
    250 const QwtLegend *QwtPolarPlot::legend() const
     291const QwtAbstractLegend *QwtPolarPlot::legend() const
    251292{
    252293    return d_data->legend;
    253 }
    254 
    255 /*!
    256   Called internally when the legend has been clicked on.
    257   Emits a legendClicked() signal.
    258 */
    259 void QwtPolarPlot::legendItemClicked()
    260 {
    261     if ( d_data->legend && sender()->isWidgetType() )
    262     {
    263         QwtPolarItem *plotItem = static_cast< QwtPolarItem* >(
    264             d_data->legend->find( qobject_cast<const QWidget *>( sender() ) ) );
    265         if ( plotItem )
    266             Q_EMIT legendClicked( plotItem );
    267     }
    268 }
    269 
    270 /*!
    271   Called internally when the legend has been checked
    272   Emits a legendClicked() signal.
    273 */
    274 void QwtPolarPlot::legendItemChecked( bool on )
    275 {
    276     if ( d_data->legend && sender()->isWidgetType() )
    277     {
    278         QwtPolarItem *plotItem = static_cast< QwtPolarItem* >(
    279             d_data->legend->find( qobject_cast<const QWidget *>( sender() ) ) );
    280         if ( plotItem )
    281             Q_EMIT legendChecked( plotItem, on );
    282     }
    283294}
    284295
     
    389400        return;
    390401
    391     if ( maxMinor < 0 )
    392         maxMinor = 0;
    393     if ( maxMinor > 100 )
    394         maxMinor = 100;
     402    maxMinor = qBound( 0, maxMinor, 100 );
    395403
    396404    ScaleData &scaleData = d_data->scaleData[scaleId];
     
    399407    {
    400408        scaleData.maxMinor = maxMinor;
    401         scaleData.scaleDiv.invalidate();
     409        scaleData.isValid = false;
    402410        autoRefresh();
    403411    }
     
    429437        return;
    430438
    431     if ( maxMajor < 1 )
    432         maxMajor = 1;
    433     if ( maxMajor > 1000 )
    434         maxMajor = 10000;
     439    maxMajor = qBound( 1, maxMajor, 10000 );
    435440
    436441    ScaleData &scaleData = d_data->scaleData[scaleId];
     
    438443    {
    439444        scaleData.maxMajor = maxMajor;
    440         scaleData.scaleDiv.invalidate();
     445        scaleData.isValid = false;
    441446        autoRefresh();
    442447    }
     
    477482    scaleData.scaleEngine = scaleEngine;
    478483
    479     scaleData.scaleDiv.invalidate();
     484    scaleData.isValid = false;
    480485
    481486    autoRefresh();
     
    527532    ScaleData &scaleData = d_data->scaleData[scaleId];
    528533
    529     scaleData.scaleDiv.invalidate();
     534    scaleData.isValid = false;
    530535
    531536    scaleData.minValue = min;
     
    551556
    552557    scaleData.scaleDiv = scaleDiv;
     558    scaleData.isValid = true;
    553559    scaleData.doAutoScale = false;
    554560
     
    732738    {
    733739        map.setPaintInterval( d_data->azimuthOrigin,
    734             d_data->azimuthOrigin + M_2PI );
     740            d_data->azimuthOrigin + 2 * M_PI );
    735741    }
    736742    else
     
    820826        scaleData.maxMajor = 8;
    821827
     828        scaleData.isValid = false;
     829
    822830        scaleData.scaleEngine = new QwtLinearScaleEngine;
    823         scaleData.scaleDiv.invalidate();
    824831    }
    825832    d_data->zoomFactor = 1.0;
     
    858865    }
    859866
    860     if ( d_data->legend &&
    861         d_data->layout->legendPosition() != ExternalLegend )
    862     {
    863         if ( d_data->legend->itemCount() > 0 )
    864         {
    865             d_data->legend->setGeometry( d_data->layout->legendRect().toRect() );
     867    if ( d_data->legend )
     868    {
     869        if ( d_data->legend->isEmpty() )
     870        {
     871            d_data->legend->hide();
     872        }
     873        else
     874        {
     875            const QRectF legendRect = d_data->layout->legendRect();
     876            d_data->legend->setGeometry( legendRect.toRect() );
    866877            d_data->legend->show();
    867878        }
    868         else
    869             d_data->legend->hide();
    870879    }
    871880
     
    10541063        d.scaleEngine->autoScale( d.maxMajor,
    10551064                                  minValue, maxValue, stepSize );
    1056         d.scaleDiv.invalidate();
    1057     }
    1058 
    1059     if ( !d.scaleDiv.isValid() )
     1065        d.isValid = false;
     1066    }
     1067
     1068    if ( !d.isValid )
    10601069    {
    10611070        d.scaleDiv = d.scaleEngine->divideScale(
    10621071            minValue, maxValue, d.maxMajor, d.maxMinor, stepSize );
     1072        d.isValid = true;
    10631073    }
    10641074
     
    12701280    return d_data->layout;
    12711281}
     1282
     1283/*!
     1284  \brief Attach/Detach a plot item
     1285
     1286  \param plotItem Plot item
     1287  \param on When true attach the item, otherwise detach it
     1288 */
     1289void QwtPolarPlot::attachItem( QwtPolarItem *plotItem, bool on )
     1290{
     1291    if ( on )
     1292        insertItem( plotItem );
     1293    else
     1294        removeItem( plotItem );
     1295
     1296    Q_EMIT itemAttached( plotItem, on );
     1297
     1298    if ( plotItem->testItemAttribute( QwtPolarItem::Legend ) )
     1299    {
     1300        // the item wants to be represented on the legend
     1301
     1302        if ( on )
     1303        {
     1304            updateLegend( plotItem );
     1305        }
     1306        else
     1307        {
     1308            const QVariant itemInfo = itemToInfo( plotItem );
     1309            Q_EMIT legendDataChanged( itemInfo, QList<QwtLegendData>() );
     1310        }
     1311    }
     1312
     1313    if ( autoReplot() )
     1314        update();
     1315}
     1316
     1317/*!
     1318  \brief Build an information, that can be used to identify
     1319         a plot item on the legend.
     1320
     1321  The default implementation simply wraps the plot item
     1322  into a QVariant object. When overloading itemToInfo()
     1323  usually infoToItem() needs to reimplemeted too.
     1324
     1325\code
     1326    QVariant itemInfo;
     1327    qVariantSetValue( itemInfo, plotItem );
     1328\endcode
     1329
     1330  \param plotItem Plot item
     1331  \sa infoToItem()
     1332 */
     1333QVariant QwtPolarPlot::itemToInfo( QwtPolarItem *plotItem ) const
     1334{
     1335    QVariant itemInfo;
     1336    qVariantSetValue( itemInfo, plotItem );
     1337
     1338    return itemInfo;
     1339}
     1340
     1341/*!
     1342  \brief Identify the plot item according to an item info object,
     1343         that has bee generated from itemToInfo().
     1344
     1345  The default implementation simply tries to unwrap a QwtPlotItem
     1346  pointer:
     1347
     1348\code
     1349    if ( itemInfo.canConvert<QwtPlotItem *>() )
     1350        return qvariant_cast<QwtPlotItem *>( itemInfo );
     1351\endcode
     1352  \param itemInfo Plot item
     1353  \return A plot item, when successful, otherwise a NULL pointer.
     1354  \sa itemToInfo()
     1355*/
     1356QwtPolarItem *QwtPolarPlot::infoToItem( const QVariant &itemInfo ) const
     1357{
     1358    if ( itemInfo.canConvert<QwtPolarItem *>() )
     1359        return qvariant_cast<QwtPolarItem *>( itemInfo );
     1360
     1361    return NULL;
     1362}
  • trunk/BNC/qwtpolar/qwt_polar_plot.h

    r4272 r8127  
    2424class QwtPolarCanvas;
    2525class QwtPolarLayout;
     26class QwtAbstractLegend;
    2627
    2728/*!
     
    141142    // Legend
    142143
    143     void insertLegend( QwtLegend *,
     144    void insertLegend( QwtAbstractLegend *,
    144145        LegendPosition = RightLegend, double ratio = -1.0 );
    145146
    146     QwtLegend *legend();
    147     const QwtLegend *legend() const;
     147    QwtAbstractLegend *legend();
     148    const QwtAbstractLegend *legend() const;
     149
     150    void updateLegend();
     151    void updateLegend( const QwtPolarItem * );
    148152
    149153    // Layout
     
    157161    int plotMarginHint() const;
    158162
     163    virtual QVariant itemToInfo( QwtPolarItem * ) const;
     164    virtual QwtPolarItem *infoToItem( const QVariant & ) const;
     165
    159166Q_SIGNALS:
    160167    /*!
    161       A signal which is emitted when the user has clicked on
    162       a legend item, which is in QwtLegend::ClickableItem mode.
    163 
    164       \param plotItem Corresponding plot item of the
    165                  selected legend item
    166 
    167       \note clicks are disabled as default
    168       \sa QwtLegend::setItemMode, QwtLegend::itemMode
    169      */
    170     void legendClicked( QwtPolarItem *plotItem );
    171 
    172     /*!
    173       A signal which is emitted when the user has clicked on
    174       a legend item, which is in QwtLegend::CheckableItem mode
    175 
    176       \param plotItem Corresponding plot item of the
    177                  selected legend item
    178       \param on True when the legen item is checked
    179 
    180       \note clicks are disabled as default
    181       \sa QwtLegend::setItemMode, QwtLegend::itemMode
    182      */
    183     void legendChecked( QwtPolarItem *plotItem, bool on );
     168      A signal indicating, that an item has been attached/detached
     169
     170      \param plotItem Plot item
     171      \param on Attached/Detached
     172     */
     173    void itemAttached( QwtPolarItem *plotItem, bool on );
     174
     175    /*!
     176      A signal with the attributes how to update
     177      the legend entries for a plot item.
     178               
     179      \param itemInfo Info about a plot, build from itemToInfo()
     180   
     181      \sa itemToInfo(), infoToItem(), QwtAbstractLegend::updateLegend()
     182     */
     183    void legendDataChanged( const QVariant &itemInfo,
     184        const QList<QwtLegendData> &data );
    184185
    185186    /*!
     
    194195    void setAzimuthOrigin( double );
    195196
    196 protected Q_SLOTS:
    197     virtual void legendItemClicked();
    198     virtual void legendItemChecked( bool );
    199 
    200197protected:
    201198    virtual bool event( QEvent * );
     
    210207
    211208private:
     209    friend class QwtPolarItem;
     210    void attachItem( QwtPolarItem *, bool );
     211
    212212    void initPlot( const QwtText & );
    213213
  • trunk/BNC/qwtpolar/qwt_polar_renderer.cpp

    r4272 r8127  
    1111#include "qwt_polar_layout.h"
    1212#include <qwt_legend.h>
    13 #include <qwt_legend_item.h>
    1413#include <qwt_dyngrid_layout.h>
    1514#include <qwt_text_label.h>
     
    1716#include <qpainter.h>
    1817#include <qprinter.h>
     18#include <qprintdialog.h>
     19#include <qfiledialog.h>
    1920#include <qimagewriter.h>
    2021#include <qfileinfo.h>
     
    115116
    116117    const QString fmt = format.toLower();
    117     if ( format == "pdf" || format == "ps" )
    118     {
     118    if ( format == "pdf" )
     119    {
     120#ifndef QT_NO_PRINTER
    119121        QPrinter printer;
     122        printer.setColorMode( QPrinter::Color );
    120123        printer.setFullPage( true );
    121124        printer.setPaperSize( sizeMM, QPrinter::Millimeter );
    122125        printer.setDocName( title );
    123126        printer.setOutputFileName( fileName );
    124         printer.setOutputFormat( ( format == "pdf" )
    125             ? QPrinter::PdfFormat : QPrinter::PostScriptFormat );
     127        printer.setOutputFormat( QPrinter::PdfFormat );
    126128        printer.setResolution( resolution );
    127129
    128130        QPainter painter( &printer );
    129131        render( plot, &painter, documentRect );
     132#endif
     133    }
     134    else if ( format == "ps" )
     135    {
     136#if QT_VERSION < 0x050000
     137#ifndef QT_NO_PRINTER
     138        QPrinter printer;
     139        printer.setColorMode( QPrinter::Color );
     140        printer.setFullPage( true );
     141        printer.setPaperSize( sizeMM, QPrinter::Millimeter );
     142        printer.setDocName( title );
     143        printer.setOutputFileName( fileName );
     144        printer.setOutputFormat( QPrinter::PostScriptFormat );
     145        printer.setResolution( resolution );
     146
     147        QPainter painter( &printer );
     148        render( plot, &painter, documentRect );
     149#endif
     150#endif
    130151    }
    131152#ifndef QWT_NO_POLAR_SVG
     
    300321
    301322    painter->save();
    302     renderLegend( painter, layout->legendRect() );
     323    renderLegend( plot, painter, layout->legendRect() );
    303324    painter->restore();
    304325
     
    340361  Render the legend into a given rectangle.
    341362
     363  \param plot Plot widget
    342364  \param painter Painter
    343365  \param rect Bounding rectangle
    344366*/
    345 
    346 void QwtPolarRenderer::renderLegend(
     367void QwtPolarRenderer::renderLegend( const QwtPolarPlot *plot,
    347368    QPainter *painter, const QRectF &rect ) const
    348369{
    349     QwtLegend *legend = d_data->plot->legend();
    350     if ( legend == NULL || legend->isEmpty() )
    351         return;
    352 
    353     const QwtDynGridLayout *legendLayout = qobject_cast<QwtDynGridLayout *>(
    354         legend->contentsWidget()->layout() );
    355     if ( legendLayout == NULL )
    356         return;
    357 
    358     uint numCols = legendLayout->columnsForWidth( rect.width() );
    359     const QList<QRect> itemRects =
    360         legendLayout->layoutItems( rect.toRect(), numCols );
    361 
    362     int index = 0;
    363 
    364     for ( int i = 0; i < legendLayout->count(); i++ )
    365     {
    366         QLayoutItem *item = legendLayout->itemAt( i );
    367         QWidget *w = item->widget();
    368         if ( w )
     370    if ( plot->legend() )
     371        plot->legend()->renderLegend( painter, rect, true );
     372}
     373
     374/*!
     375   \brief Execute a file dialog and render the plot to the selected file
     376
     377   The document will be rendered in 85 dpi for a size 30x30 cm
     378
     379   \param plot Plot widget
     380   \param documentName Default document name
     381   \param sizeMM Size for the document in millimeters.
     382   \param resolution Resolution in dots per Inch (dpi)
     383
     384   \sa renderDocument()
     385*/
     386bool QwtPolarRenderer::exportTo( QwtPolarPlot *plot,
     387    const QString &documentName, const QSizeF &sizeMM, int resolution )
     388{
     389    if ( plot == NULL )
     390        return false;
     391
     392    QString fileName = documentName;
     393
     394    // What about translation
     395
     396#ifndef QT_NO_FILEDIALOG
     397    const QList<QByteArray> imageFormats =
     398        QImageWriter::supportedImageFormats();
     399
     400    QStringList filter;
     401#ifndef QT_NO_PRINTER
     402    filter += QString( "PDF " ) + tr( "Documents" ) + " (*.pdf)";
     403#endif
     404#ifndef QWT_NO_SVG
     405    filter += QString( "SVG " ) + tr( "Documents" ) + " (*.svg)";
     406#endif
     407#ifndef QT_NO_PRINTER
     408    filter += QString( "Postscript " ) + tr( "Documents" ) + " (*.ps)";
     409#endif
     410
     411    if ( imageFormats.size() > 0 )
     412    {
     413        QString imageFilter( tr( "Images" ) );
     414        imageFilter += " (";
     415        for ( int i = 0; i < imageFormats.size(); i++ )
    369416        {
    370             painter->save();
    371 
    372             painter->setClipRect( itemRects[index] );
    373             renderLegendItem( painter, w, itemRects[index] );
    374 
    375             index++;
    376             painter->restore();
     417            if ( i > 0 )
     418                imageFilter += " ";
     419            imageFilter += "*.";
     420            imageFilter += imageFormats[i];
    377421        }
    378     }
    379 
    380 }
    381 
    382 /*!
    383   Print the legend item into a given rectangle.
    384 
    385   \param painter Painter
    386   \param widget Widget representing a legend item
    387   \param rect Bounding rectangle
    388 
    389   \note When widget is not derived from QwtLegendItem renderLegendItem
    390         does nothing and needs to be overloaded
    391 */
    392 void QwtPolarRenderer::renderLegendItem( QPainter *painter,
    393     const QWidget *widget, const QRectF &rect ) const
    394 {
    395     const QwtLegendItem *item = qobject_cast<const QwtLegendItem *>( widget );
    396     if ( item )
    397     {
    398         const QSize sz = item->identifierSize();
    399 
    400         const QRectF identifierRect( rect.x() + item->margin(),
    401             rect.center().y() - 0.5 * sz.height(), sz.width(), sz.height() );
    402 
    403         QwtLegendItemManager *itemManger = d_data->plot->legend()->find( item );
    404         if ( itemManger )
    405         {
    406             painter->save();
    407             painter->setClipRect( identifierRect, Qt::IntersectClip );
    408             itemManger->drawLegendIdentifier( painter, identifierRect );
    409             painter->restore();
    410         }
    411 
    412         // Label
    413 
    414         QRectF titleRect = rect;
    415         titleRect.setX( identifierRect.right() + 2 * item->spacing() );
    416 
    417         painter->setFont( item->font() );
    418         item->text().draw( painter, titleRect );
    419     }
    420 }
    421 
     422        imageFilter += ")";
     423
     424        filter += imageFilter;
     425    }
     426
     427    fileName = QFileDialog::getSaveFileName(
     428        NULL, tr( "Export File Name" ), fileName,
     429        filter.join( ";;" ), NULL, QFileDialog::DontConfirmOverwrite );
     430#endif
     431    if ( fileName.isEmpty() )
     432        return false;
     433
     434    renderDocument( plot, fileName, sizeMM, resolution );
     435
     436    return true;
     437}
  • trunk/BNC/qwtpolar/qwt_polar_renderer.h

    r4272 r8127  
    1212#include "qwt_polar_global.h"
    1313#include <qobject.h>
     14#include <qsize.h>
    1415
    1516class QwtPolarPlot;
    16 class QSizeF;
    1717class QRectF;
    1818class QPainter;
     
    5252#endif
    5353    void renderTo( QwtPolarPlot *, QPrinter & ) const;
    54     void renderTo( QwtPolarPlot *, QPaintDevice &p ) const;
     54    void renderTo( QwtPolarPlot *, QPaintDevice & ) const;
    5555
    5656    virtual void render( QwtPolarPlot *,
    5757        QPainter *, const QRectF &rect ) const;
    5858
    59 protected:
     59    bool exportTo( QwtPolarPlot *, const QString &documentName,
     60        const QSizeF &sizeMM = QSizeF( 200, 200 ), int resolution = 85 );
     61
    6062    virtual void renderTitle( QPainter *, const QRectF & ) const;
    61     virtual void renderLegend( QPainter *, const QRectF & ) const;
    6263
    63     virtual void renderLegendItem( QPainter *,
    64         const QWidget *, const QRectF & ) const;
     64    virtual void renderLegend(
     65        const QwtPolarPlot *, QPainter *, const QRectF & ) const;
    6566
    6667private:
  • trunk/BNC/qwtpolar/qwt_polar_spectrogram.cpp

    r4272 r8127  
    9595public:
    9696    PrivateData():
    97         data( NULL ),
    98         renderThreadCount( 1 )
     97        data( NULL )
    9998    {
    10099        colorMap = new QwtLinearColorMap();
     
    109108    QwtRasterData *data;
    110109    QwtColorMap *colorMap;
    111 
    112     uint renderThreadCount;
    113110
    114111    QwtPolarSpectrogram::PaintAttributes paintAttributes;
     
    223220{
    224221    return ( d_data->paintAttributes & attribute );
    225 }
    226 
    227 /*!
    228    Rendering an image from the raster data can often be done
    229    parallel on a multicore system.
    230 
    231    \param numThreads Number of threads to be used for rendering.
    232                      If numThreads is set to 0, the system specific
    233                      ideal thread count is used.
    234 
    235    The default thread count is 1 ( = no additional threads )
    236 
    237    \warning Rendering in multiple threads is only supported for Qt >= 4.4
    238    \sa renderThreadCount(), renderImage(), renderTile()
    239 */
    240 void QwtPolarSpectrogram::setRenderThreadCount( uint numThreads )
    241 {
    242     d_data->renderThreadCount = numThreads;
    243 }
    244 
    245 /*!
    246    \return Number of threads to be used for rendering.
    247            If numThreads is set to 0, the system specific
    248            ideal thread count is used.
    249 
    250    \warning Rendering in multiple threads is only supported for Qt >= 4.4
    251    \sa setRenderThreadCount(), renderImage(), renderTile()
    252 */
    253 uint QwtPolarSpectrogram::renderThreadCount() const
    254 {
    255     return d_data->renderThreadCount;
    256222}
    257223
     
    357323
    358324#if QT_VERSION >= 0x040400 && !defined(QT_NO_QFUTURE)
    359     uint numThreads = d_data->renderThreadCount;
     325    uint numThreads = renderThreadCount();
    360326
    361327    if ( numThreads <= 0 )
  • trunk/BNC/qwtpolar/qwt_polar_spectrogram.h

    r4272 r8127  
    6060    bool testPaintAttribute( PaintAttribute ) const;
    6161
    62     void setRenderThreadCount( uint numThreads );
    63     uint renderThreadCount() const;
    64 
    6562    virtual int rtti() const;
    6663
  • trunk/BNC/qwtpolar/qwtpolar.pro

    r5182 r8127  
    66CONFIG += release
    77DEFINES += QWT_POLAR_NO_SVG
     8greaterThan(QT_MAJOR_VERSION, 4) {
     9    QT += printsupport
     10    QT += concurrent
     11}
    812
    913INCLUDEPATH += ../qwt
     
    4549    qwt_polar_renderer.cpp \
    4650    qwt_polar_plot.cpp
    47 
  • trunk/BNC/src/PPP_SSR_I/pppFilter.h

    r7929 r8127  
    9090  double       lkB;
    9191  unsigned     obsIndex;
    92   char system() const {return prn.toAscii()[0];}
     92  char system() const {return prn.toLatin1()[0];}
    9393};
    9494
  • trunk/BNC/src/bnccaster.cpp

    r8119 r8127  
    208208          emit( newMessage(QString("%1: Old epoch %2 thrown away")
    209209                 .arg(staID.data()).arg(string(obs._time).c_str())
    210                .toAscii(), true) );
     210               .toLatin1(), true) );
    211211        }
    212212      }
     
    232232  _sockets->push_back( _server->nextPendingConnection() );
    233233  emit( newMessage(QString("New client connection on sync port: # %1")
    234                    .arg(_sockets->size()).toAscii(), true) );
     234                   .arg(_sockets->size()).toLatin1(), true) );
    235235}
    236236
     
    238238  _uSockets->push_back( _uServer->nextPendingConnection() );
    239239  emit( newMessage(QString("New client connection on usync port: # %1")
    240                    .arg(_uSockets->size()).toAscii(), true) );
     240                   .arg(_uSockets->size()).toLatin1(), true) );
    241241}
    242242
     
    286286  _staIDs.removeAll(staID);
    287287  emit( newMessage(
    288            QString("Decoding %1 stream(s)").arg(_staIDs.size()).toAscii(), true) );
     288           QString("Decoding %1 stream(s)").arg(_staIDs.size()).toLatin1(), true) );
    289289  if (_staIDs.size() == 0) {
    290290    emit(newMessage("bncCaster: Last get thread terminated", true));
     
    406406    // ----------------
    407407    if (!existFlg) {
    408       QByteArray format    = hlp[1].toAscii();
    409       QByteArray latitude  = hlp[3].toAscii();
    410       QByteArray longitude = hlp[4].toAscii();
    411       QByteArray nmea      = hlp[5].toAscii();
    412       QByteArray ntripVersion = hlp[6].toAscii();
     408      QByteArray format    = hlp[1].toLatin1();
     409      QByteArray latitude  = hlp[3].toLatin1();
     410      QByteArray longitude = hlp[4].toLatin1();
     411      QByteArray nmea      = hlp[5].toLatin1();
     412      QByteArray ntripVersion = hlp[6].toLatin1();
    413413
    414414      bncGetThread* getThread = new bncGetThread(url, format, latitude,
     
    450450                           + BNC_CORE->confFileName()
    451451                           + ", %1 stream(s)")
    452                             .arg(_threads.count()).toAscii(), true) );
     452                            .arg(_threads.count()).toLatin1(), true) );
    453453
    454454  // (Re-) Start the configuration timer
     
    555555  _miscSockets->push_back( _miscServer->nextPendingConnection() );
    556556  emit( newMessage(QString("New client connection on Miscellaneous Output Port: # %1")
    557                    .arg(_miscSockets->size()).toAscii(), true) );
    558 }
     557                   .arg(_miscSockets->size()).toLatin1(), true) );
     558}
  • trunk/BNC/src/bnccore.cpp

    r7999 r8127  
    170170      expandEnvVar(logFileName);
    171171      _logFile = new QFile(logFileName + "_" +
    172                           currDate.toString("yyMMdd").toAscii().data());
     172                          currDate.toString("yyMMdd").toLatin1().data());
    173173      _fileDate = currDate;
    174174      if ( Qt::CheckState(settings.value("rnxAppend").toInt()) == Qt::Checked) {
     
    189189      msgLocal = msg.mid(1);
    190190    }
    191     *_logStream << currentDateAndTimeGPS().toString("yy-MM-dd hh:mm:ss ").toAscii().data();
     191    *_logStream << currentDateAndTimeGPS().toString("yy-MM-dd hh:mm:ss ").toLatin1().data();
    192192    *_logStream << msgLocal.data() << endl;
    193193    _logStream->flush();
     
    202202  t_irc ircPut = _ephUser.putNewEph(eph, true);
    203203  if      (eph->checkState() == t_eph::bad) {
    204     messagePrivate("WRONG EPHEMERIS\n" + eph->toString(3.0).toAscii());
     204    messagePrivate("WRONG EPHEMERIS\n" + eph->toString(3.0).toLatin1());
    205205    return failure;
    206206  }
    207207  else if (eph->checkState() == t_eph::outdated) {
    208     messagePrivate("OUTDATED EPHEMERIS\n" + eph->toString(3.0).toAscii());
     208    messagePrivate("OUTDATED EPHEMERIS\n" + eph->toString(3.0).toLatin1());
    209209    return failure;
    210210  }
     
    270270    comments.append("Source: " + decoder +
    271271                    " " + url.encodedHost() +
    272                     "/" + url.path().mid(1).toAscii());
     272                    "/" + url.path().mid(1).toLatin1());
    273273  }
    274274
     
    388388        line.sprintf(
    389389          "%9.2f%11sN: GNSS NAV DATA    M: Mixed%12sRINEX VERSION / TYPE\n",
    390           t_rnxNavFile::defaultRnxNavVersion3, "", "");
     390          defaultRnxNavVersion3, "", "");
    391391        *_ephStreamGPS << line;
    392392
    393393        QString hlp = currentDateAndTimeGPS().toString("yyyyMMdd hhmmss UTC").leftJustified(20, ' ', true);
    394         *_ephStreamGPS << _pgmName.toAscii().data()
    395                        << _userName.toAscii().data()
    396                        << hlp.toAscii().data()
     394        *_ephStreamGPS << _pgmName.toLatin1().data()
     395                       << _userName.toLatin1().data()
     396                       << hlp.toLatin1().data()
    397397                       << "PGM / RUN BY / DATE" << endl;
    398398
     
    415415        QString line;
    416416        line.sprintf("%9.2f%11sN: GPS NAV DATA%25sRINEX VERSION / TYPE\n",
    417                      t_rnxNavFile::defaultRnxNavVersion2, "", "");
     417                     defaultRnxNavVersion2, "", "");
    418418        *_ephStreamGPS << line;
    419419
    420420        QString hlp = currentDateAndTimeGPS().date().toString("dd-MMM-yyyy").leftJustified(20, ' ', true);
    421         *_ephStreamGPS << _pgmName.toAscii().data()
    422                        << _userName.toAscii().data()
    423                        << hlp.toAscii().data()
     421        *_ephStreamGPS << _pgmName.toLatin1().data()
     422                       << _userName.toLatin1().data()
     423                       << hlp.toLatin1().data()
    424424                       << "PGM / RUN BY / DATE" << endl;
    425425
     
    437437        QString line;
    438438        line.sprintf("%9.2f%11sG: GLONASS NAV DATA%21sRINEX VERSION / TYPE\n",
    439                      t_rnxNavFile::defaultRnxNavVersion2, "", "");
     439                     defaultRnxNavVersion2, "", "");
    440440        *_ephStreamGlonass << line;
    441441
    442442        QString hlp = currentDateAndTimeGPS().date().toString("dd-MMM-yyyy").leftJustified(20, ' ', true);
    443         *_ephStreamGlonass << _pgmName.toAscii().data()
    444                            << _userName.toAscii().data()
    445                            << hlp.toAscii().data()
     443        *_ephStreamGlonass << _pgmName.toLatin1().data()
     444                           << _userName.toLatin1().data()
     445                           << hlp.toLatin1().data()
    446446                           << "PGM / RUN BY / DATE" << endl;
    447447
     
    464464void t_bncCore::printEph(const t_eph& eph, bool printFile) {
    465465
    466   QString strV2 = eph.toString(t_rnxNavFile::defaultRnxNavVersion2);
    467   QString strV3 = eph.toString(t_rnxObsHeader::defaultRnxObsVersion3);
     466  QString strV2 = eph.toString(defaultRnxNavVersion2);
     467  QString strV3 = eph.toString(defaultRnxObsVersion3);
    468468
    469469  if     (_rinexVers == 2 && eph.type() == t_eph::GLONASS) {
     
    487487  if (printFile && stream) {
    488488    if (_rinexVers == 2) {
    489       *stream << strV2.toAscii();
     489      *stream << strV2.toLatin1();
    490490    }
    491491    else {
    492       *stream << strV3.toAscii();
     492      *stream << strV3.toLatin1();
    493493    }
    494494    stream->flush();
     
    502502      QTcpSocket* sock = is.next();
    503503      if (sock->state() == QAbstractSocket::ConnectedState) {
    504         if (sock->write(strV3.toAscii()) == -1) {
     504        if (sock->write(strV3.toLatin1()) == -1) {
    505505          delete sock;
    506506          is.remove();
  • trunk/BNC/src/bncfigureppp.h

    r6730 r8127  
    4343
    4444 private:
    45   const static double _tRange = 300;
     45  enum {_tRange = 300};
    4646
    4747  class pppPos {
  • trunk/BNC/src/bncgetthread.cpp

    r8123 r8127  
    4343#include <sstream>
    4444
     45#include <QComboBox>
     46#include <QDialog>
    4547#include <QFile>
    4648#include <QTextStream>
    4749#include <QMutex>
    4850#include <QtNetwork>
     51#include <QPushButton>
     52#include <QTableWidget>
    4953#include <QTime>
    5054
     
    9094  _rawFile = 0;
    9195  _mountPoint = mountPoint;
    92   _staID = mountPoint.path().mid(1).toAscii();
     96  _staID = mountPoint.path().mid(1).toLatin1();
    9397  _format = format;
    9498  _latitude = latitude;
     
    134138      continue;
    135139    }
    136     QByteArray mp = hlp[0].toAscii();
     140    QByteArray mp = hlp[0].toLatin1();
    137141    if (_staID == mp) {
    138142      nmeaPort = hlp[9].toInt();
     
    275279        hlp = "0.0";
    276280      }
    277       QByteArray _serialHeightNMEA = hlp.toAscii();
     281      QByteArray _serialHeightNMEA = hlp.toLatin1();
    278282      _manualNMEAString = ggaString(_latitude, _longitude, _serialHeightNMEA,
    279283          nmeaMode);
     
    603607            QString prn(obs._prn.toString().c_str());
    604608            emit(newMessage(
    605                 _staID + " (" + prn.toAscii() + ")"
     609                _staID + " (" + prn.toLatin1() + ")"
    606610                    + ": Wrong observation epoch(s)", false));
    607611            continue;
     
    619623            long oldTime = it.value();
    620624            if (obsTime < oldTime) {
    621               emit(newMessage(_staID + ": old observation " + prn.toAscii(),
     625              emit(newMessage(_staID + ": old observation " + prn.toLatin1(),
    622626                  false));
    623627              continue;
     
    625629              emit(newMessage(
    626630                  _staID + ": observation coming more than once "
    627                       + prn.toAscii(), false));
     631                      + prn.toLatin1(), false));
    628632              continue;
    629633            }
     
    774778      for (int ii = 0; ii < decoder()->_typeList.size(); ii++) {
    775779        QString type = QString("%1 ").arg(decoder()->_typeList[ii]);
    776         emit(newMessage(_staID + ": Received message type " + type.toAscii(),
     780        emit(newMessage(_staID + ": Received message type " + type.toLatin1(),
    777781            true));
    778782      }
     
    847851            str << " " << rnxTypes[iType];
    848852          }
    849           emit(newMessage(_staID + ": Observation Types: " + msg.toAscii(),
     853          emit(newMessage(_staID + ": Observation Types: " + msg.toLatin1(),
    850854              true));
    851855        }
     
    856860      for (int ii = 0; ii < decoder()->_antType.size(); ii++) {
    857861        QString ant1 = QString("%1 ").arg(decoder()->_antType[ii]);
    858         emit(newMessage(_staID + ": Antenna descriptor " + ant1.toAscii(), true));
     862        emit(newMessage(_staID + ": Antenna descriptor " + ant1.toLatin1(), true));
    859863      }
    860864
     
    870874        QByteArray ant1, ant2, ant3;
    871875        ant1 =
    872             QString("%1 ").arg(decoder()->_antList[ii].xx, 0, 'f', 4).toAscii();
     876            QString("%1 ").arg(decoder()->_antList[ii].xx, 0, 'f', 4).toLatin1();
    873877        ant2 =
    874             QString("%1 ").arg(decoder()->_antList[ii].yy, 0, 'f', 4).toAscii();
     878            QString("%1 ").arg(decoder()->_antList[ii].yy, 0, 'f', 4).toLatin1();
    875879        ant3 =
    876             QString("%1 ").arg(decoder()->_antList[ii].zz, 0, 'f', 4).toAscii();
     880            QString("%1 ").arg(decoder()->_antList[ii].zz, 0, 'f', 4).toLatin1();
    877881        emit(newMessage(_staID + ": " + antT + " (ITRF) X " + ant1 + "m", true));
    878882        emit(newMessage(_staID + ": " + antT + " (ITRF) Y " + ant2 + "m", true));
     
    881885        if (decoder()->_antList[ii].height_f) {
    882886          hh = decoder()->_antList[ii].height;
    883           QByteArray ant4 = QString("%1 ").arg(hh, 0, 'f', 4).toAscii();
     887          QByteArray ant4 = QString("%1 ").arg(hh, 0, 'f', 4).toLatin1();
    884888          emit(newMessage(
    885889              _staID + ": Antenna height above marker " + ant4 + "m", true));
     
    902906          _gloSlots.sort();
    903907          emit(newMessage(
    904               _staID + ": GLONASS Slot:Freq " + _gloSlots.join(" ").toAscii(),
     908              _staID + ": GLONASS Slot:Freq " + _gloSlots.join(" ").toLatin1(),
    905909              true));
    906910        }
     
    983987  _nmeaSockets->push_back(_nmeaServer->nextPendingConnection());
    984988  emit(newMessage(
    985       QString("New PPP client on port: # %1").arg(_nmeaSockets->size()).toAscii(),
     989      QString("New PPP client on port: # %1").arg(_nmeaSockets->size()).toLatin1(),
    986990      true));
    987991}
  • trunk/BNC/src/bncmap_svg.cpp

    r7667 r8127  
    247247    QwtPlotRenderer renderer;
    248248    renderer.setDiscardFlag(QwtPlotRenderer::DiscardBackground, false);
    249     renderer.setLayoutFlag(QwtPlotRenderer::KeepFrames, true);
     249    //renderer.setLayoutFlag(QwtPlotRenderer::KeepFrames, true);
    250250    renderer.renderTo(_mapPlot, printer);
    251251  }
  • trunk/BNC/src/bncrinex.cpp

    r7878 r8127  
    124124      QStringList tags = line.split(";");
    125125      if (tags.size() > 7) {
    126         if (tags.at(1) == _mountPoint.path().mid(1).toAscii()) {
     126        if (tags.at(1) == _mountPoint.path().mid(1).toLatin1()) {
    127127          net = tags.at(7);
    128128          break;
     
    368368  }
    369369
    370   _fName = path.toAscii();
     370  _fName = path.toLatin1();
    371371}
    372372
  • trunk/BNC/src/bnctabledlg.cpp

    r7680 r8127  
    4040
    4141#include <iostream>
     42#include <QHeaderView>
     43#include <QLabel>
     44#include <QLineEdit>
     45#include <QMessageBox>
     46#include <QVBoxLayout>
    4247
    4348#include "bnctabledlg.h"
     
    492497    if (url.host() == newHost) {
    493498      _casterUserLineEdit->setText(
    494                 QUrl::fromPercentEncoding(url.userName().toAscii()));
     499                QUrl::fromPercentEncoding(url.userName().toLatin1()));
    495500      _casterPasswordLineEdit->setText(
    496                 QUrl::fromPercentEncoding(url.password().toAscii()));
     501                QUrl::fromPercentEncoding(url.password().toLatin1()));
    497502      if (url.port() > 0) {
    498503        _casterPortLineEdit->setText(QString("%1").arg(url.port()));
  • trunk/BNC/src/bnctabledlg.h

    r4658 r8127  
    2828#include <QtCore>
    2929#include <QtGui>
     30#include <QComboBox>
     31#include <QDialog>
     32#include <QPushButton>
     33#include <QTableWidget>
    3034#include <QWhatsThis>
    3135
  • trunk/BNC/src/bncwindow.cpp

    r8119 r8127  
    4040
    4141#include <iostream>
     42
     43#include <QAction>
     44#include <QApplication>
     45#include <QCheckBox>
     46#include <QComboBox>
     47#include <QDialog>
     48#include <QFontDialog>
     49#include <QGridLayout>
     50#include <QHeaderView>
     51#include <QLabel>
     52#include <QLineEdit>
     53#include <QMenu>
     54#include <QMenuBar>
     55#include <QMessageBox>
     56#include <QPushButton>
     57#include <QRadioButton>
     58#include <QSpinBox>
     59#include <QTableWidgetItem>
     60#include <QTextEdit>
     61#include <QToolBar>
    4262
    4363#include <unistd.h>
     
    409429  _mountPointsTable->horizontalHeader()->resizeSection(6,5*ww);
    410430  _mountPointsTable->horizontalHeader()->resizeSection(7,5*ww);
     431#if QT_VERSION < 0x050000
    411432  _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
     433#else
     434  _mountPointsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     435#endif
    412436  _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
    413437  _mountPointsTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
     
    439463  _cmbTable->horizontalHeader()->resizeSection(1,8*ww);
    440464  _cmbTable->horizontalHeader()->resizeSection(2,8*ww);
     465#if QT_VERSION < 0x050000
    441466  _cmbTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
     467#else
     468  _cmbTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     469#endif
    442470  _cmbTable->horizontalHeader()->setStretchLastSection(true);
    443471  _cmbTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
     
    501529  _uploadTable->horizontalHeader()->resizeSection(10, 4*ww);
    502530  _uploadTable->horizontalHeader()->resizeSection(11,12*ww);
     531#if QT_VERSION < 0x050000
    503532  _uploadTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
     533#else
     534  _uploadTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     535#endif
    504536  _uploadTable->horizontalHeader()->setStretchLastSection(true);
    505537  _uploadTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
     
    576608  _uploadEphTable->horizontalHeader()->resizeSection( 4,10*ww);
    577609  _uploadEphTable->horizontalHeader()->resizeSection( 5,12*ww);
     610#if QT_VERSION < 0x050000
    578611  _uploadEphTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
     612#else
     613  _uploadEphTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     614#endif
    579615  _uploadEphTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
    580616
     
    20772113           this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
    20782114
    2079   BNC_CORE->slotMessage("========== Start BNC v" BNCVERSION" ("BNC_OS") ==========", true);
     2115  BNC_CORE->slotMessage("========== Start BNC v" BNCVERSION " (" BNC_OS ") ==========", true);
    20802116
    20812117  bncSettings settings;
     
    23172353  img->setPixmap(QPixmap(":ntrip-logo.png"));
    23182354  dlgLayout->addWidget(img, 0,0);
    2319   dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version "BNCVERSION), 0,1);
     2355  dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version " BNCVERSION), 0,1);
    23202356  dlgLayout->addWidget(tb,1,0,1,2);
    23212357  dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
  • trunk/BNC/src/bncwindow.h

    r7889 r8127  
    2727
    2828#include <QtGui>
     29#include <QMainWindow>
    2930#include <QWhatsThis>
    3031
  • trunk/BNC/src/rinex/availplot.cpp

    r6542 r8127  
    7575
    7676  setCanvasBackground(QColor(Qt::white));
    77   canvas()->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
     77  ((QwtPlotCanvas *)canvas())->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
    7878
    7979  // Axes
     
    203203                                    const QVector<double>& yData) {
    204204  QwtPlotCurve* curve = new QwtPlotCurve(name);
    205   curve->setSymbol(new QwtSymbol(symbol));
     205  QwtSymbol *s = new QwtSymbol(symbol.style());
     206  s->setSize(symbol.size());
     207  s->setBrush(symbol.brush());
     208  s->setPen(symbol.pen());
     209  curve->setSymbol(s);
    206210  curve->setStyle(QwtPlotCurve::NoCurve);
    207211  curve->setXAxis(QwtPlot::xBottom);
  • trunk/BNC/src/rinex/dopplot.cpp

    r6537 r8127  
    6565
    6666  setCanvasBackground(QColor(Qt::white));
    67   canvas()->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
     67  ((QwtPlotCanvas *)canvas())->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
    6868
    6969  // Axes
  • trunk/BNC/src/rinex/eleplot.cpp

    r6537 r8127  
    6565
    6666  setCanvasBackground(QColor(Qt::white));
    67   canvas()->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
     67  ((QwtPlotCanvas *)canvas())->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
    6868
    6969  // Axes
     
    115115                                    const QVector<double>& yData) {
    116116  QwtPlotCurve* curve = new QwtPlotCurve(name);
    117   curve->setSymbol(new QwtSymbol(symbol));
     117  QwtSymbol *s = new QwtSymbol(symbol.style());
     118  s->setSize(symbol.size());
     119  s->setBrush(symbol.brush());
     120  s->setPen(symbol.pen());
     121  curve->setSymbol(s);
    118122  curve->setStyle(QwtPlotCurve::NoCurve);
    119123  curve->setXAxis(QwtPlot::xBottom);
  • trunk/BNC/src/rinex/graphwin.cpp

    r6262 r8127  
    8989   
    9090     QwtLinearScaleEngine scaleEngine;
    91      _colorScale->setScaleDiv(scaleEngine.transformation(),
    92                               scaleEngine.divideScale(scaleInterval->minValue(),
     91     _colorScale->setTransformation(scaleEngine.transformation());
     92     _colorScale->setScaleDiv(scaleEngine.divideScale(scaleInterval->minValue(),
    9393                                                      scaleInterval->maxValue(),
    9494                                                      8, 5));
  • trunk/BNC/src/rinex/polarplot.cpp

    r6262 r8127  
    3232  t_colorMap colorMap;
    3333  for (int ii = from; ii <= to; ii++) {
    34     QwtSymbol ss(symbol);
     34    QwtSymbol ss(symbol.style());
     35    ss.setSize(symbol.size());
    3536    const QwtPointPolar& point = sample(ii);
    3637    const QColor color = colorMap.color(_scaleInterval, point._value);
  • trunk/BNC/src/rinex/polarplot.h

    r4356 r8127  
    5151  virtual QwtPointPolar sample(size_t ii) const {
    5252    const t_polarPoint* point = _data->at(ii);
    53     QwtPointPolar qp(point->_az, point->_zen); qp._value = point->_value;
     53    QwtPointPolar qp(point->_az, point->_zen);  qp._value = point->_value;
    5454    return qp;
    5555  }
  • trunk/BNC/src/rinex/reqcedit.cpp

    r7999 r8127  
    6464  int version     = settings.value("reqcRnxVersion").toInt();
    6565  if (version < 3) {
    66     _rnxVersion = t_rnxObsHeader::defaultRnxObsVersion2;
     66    _rnxVersion = defaultRnxObsVersion2;
    6767  }
    6868  else {
    69     _rnxVersion = t_rnxObsHeader::defaultRnxObsVersion3;
     69    _rnxVersion = defaultRnxObsVersion3;
    7070  }
    7171  _samplingRate   = settings.value("reqcSampling").toInt();
     
    578578
    579579  if ( (haveGPS && haveGlonass) || _rnxVersion >= 3.0) {
    580     outNavFile.setVersion(t_rnxNavFile::defaultRnxNavVersion3);
     580    outNavFile.setVersion(defaultRnxNavVersion3);
    581581  }
    582582  else {
    583     outNavFile.setVersion(t_rnxNavFile::defaultRnxNavVersion2);
     583    outNavFile.setVersion(defaultRnxNavVersion2);
    584584  }
    585585
  • trunk/BNC/src/rinex/rnxnavfile.h

    r7999 r8127  
    3535class t_eph;
    3636
     37#define defaultRnxNavVersion2 2.11
     38#define defaultRnxNavVersion3 3.03
     39
    3740class t_rnxNavFile {
    3841
    3942 public:
    4043  enum e_inpOut {input, output};
    41   static const double defaultRnxNavVersion2 = 2.11;
    42   static const double defaultRnxNavVersion3 = 3.03;
    43 
    4444 private:
    4545  class t_rnxNavHeader {
  • trunk/BNC/src/rinex/rnxobsfile.cpp

    r8112 r8127  
    166166    else if (key == "# / TYPES OF OBSERV") {
    167167      if (_version == 0.0) {
    168         _version = t_rnxObsHeader::defaultRnxObsVersion2;
     168        _version = defaultRnxObsVersion2;
    169169      }
    170170      QTextStream* in = new QTextStream(value.toAscii(), QIODevice::ReadOnly);
     
    190190    else if (key == "SYS / # / OBS TYPES") {
    191191      if (_version == 0.0) {
    192         _version = t_rnxObsHeader::defaultRnxObsVersion3;
     192        _version = defaultRnxObsVersion3;
    193193      }
    194194      QTextStream* in = new QTextStream(value.toAscii(), QIODevice::ReadOnly);
     
    307307
    308308  if (version <= 2) {
    309     _version = t_rnxObsHeader::defaultRnxObsVersion2;
     309    _version = defaultRnxObsVersion2;
    310310  }
    311311  else {
    312     _version = t_rnxObsHeader::defaultRnxObsVersion3;
     312    _version = defaultRnxObsVersion3;
    313313  }
    314314
     
    371371
    372372  if (version <= 2) {
    373     _version = t_rnxObsHeader::defaultRnxObsVersion2;
     373    _version = defaultRnxObsVersion2;
    374374  }
    375375  else {
    376     _version = t_rnxObsHeader::defaultRnxObsVersion3;
     376    _version = defaultRnxObsVersion3;
    377377  }
    378378  _interval        = header._interval;
  • trunk/BNC/src/rinex/rnxobsfile.h

    r7980 r8127  
    3838#include "satObs.h"
    3939
     40#define defaultRnxObsVersion2 2.11
     41#define defaultRnxObsVersion3 3.03
     42
    4043class t_rnxObsHeader {
    4144
     
    4346
    4447 public:
    45   static const double  defaultRnxObsVersion2 = 2.11;
    46   static const double  defaultRnxObsVersion3 = 3.03;
    4748  static const QString defaultSystems;
    4849
Note: See TracChangeset for help on using the changeset viewer.