00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "ReverseMapper.h"
00031
00032 #include <math.h>
00033
00034 #include <QRect>
00035 #include <QtDebug>
00036 #include <QPolygonF>
00037 #include <QPainterPath>
00038 #include <QGraphicsScene>
00039
00040 #include "../KDChartAbstractDiagram.h"
00041 #include "ChartGraphicsItem.h"
00042
00043 using namespace KDChart;
00044
00045 ReverseMapper::ReverseMapper()
00046 : m_scene( 0 )
00047 , m_diagram( 0 )
00048 {
00049 }
00050
00051 ReverseMapper::ReverseMapper( AbstractDiagram* diagram )
00052 : m_scene( 0 )
00053 , m_diagram( diagram )
00054 {
00055 }
00056
00057 ReverseMapper::~ReverseMapper()
00058 {
00059 delete m_scene; m_scene = 0;
00060 }
00061
00062 void ReverseMapper::setDiagram( AbstractDiagram* diagram )
00063 {
00064
00065 m_diagram = diagram;
00066 }
00067
00068 void ReverseMapper::clear()
00069 {
00070 delete m_scene;
00071 m_scene = new QGraphicsScene();
00072 }
00073
00074 QModelIndexList ReverseMapper::indexesIn( const QRect& rect ) const
00075 {
00076 Q_ASSERT( m_diagram );
00077 if ( m_scene && m_scene->sceneRect().intersects( rect ) ) {
00078 QList<QGraphicsItem *> items = m_scene->items( rect );
00079 QModelIndexList indexes;
00080 Q_FOREACH( QGraphicsItem* item, items ) {
00081 ChartGraphicsItem* i = qgraphicsitem_cast<ChartGraphicsItem*>( item );
00082 if ( i ) {
00083 QModelIndex index ( m_diagram->model()->index( i->row(), i->column(), m_diagram->rootIndex() ) );
00084 indexes << index;
00085 }
00086 }
00087 return indexes;
00088 } else {
00089 return QModelIndexList();
00090 }
00091 }
00092
00093 QModelIndexList ReverseMapper::indexesAt( const QPointF& point ) const
00094 {
00095 Q_ASSERT( m_diagram );
00096 if ( m_scene && m_scene->sceneRect().contains( point ) ) {
00097 QList<QGraphicsItem *> items = m_scene->items( point );
00098 QModelIndexList indexes;
00099 Q_FOREACH( QGraphicsItem* item, items ) {
00100 ChartGraphicsItem* i = qgraphicsitem_cast<ChartGraphicsItem*>( item );
00101 if ( i ) {
00102 QModelIndex index ( m_diagram->model()->index( i->row(), i->column(), m_diagram->rootIndex() ) );
00103 if( !indexes.contains(index) )
00104 indexes << index;
00105 }
00106 }
00107 return indexes;
00108 } else {
00109 return QModelIndexList();
00110 }
00111 }
00112
00113 QPolygonF ReverseMapper::polygon( int row, int column ) const
00114 {
00115 const QModelIndex index = m_diagram->model()->index( row, column, m_diagram->rootIndex() );
00116 return m_itemMap.contains( index ) ? m_itemMap[ index ]->polygon() : QPolygon();
00117 }
00118
00119 QRectF ReverseMapper::boundingRect( int row, int column ) const
00120 {
00121 const QModelIndex index = m_diagram->model()->index( row, column, m_diagram->rootIndex() );
00122 return m_itemMap.contains( index ) ? m_itemMap[ index ]->polygon().boundingRect() : QRectF();
00123 }
00124
00125 void ReverseMapper::addItem( ChartGraphicsItem* item )
00126 {
00127 Q_ASSERT( m_scene );
00128 m_scene->addItem( item );
00129 m_itemMap.insert( m_diagram->model()->index( item->row(), item->column(), m_diagram->rootIndex() ), item );
00130 }
00131
00132 void ReverseMapper::addRect( int row, int column, const QRectF& rect )
00133 {
00134 addPolygon( row, column, QPolygonF( rect ) );
00135 }
00136
00137 void ReverseMapper::addPolygon( int row, int column, const QPolygonF& polygon )
00138 {
00139 ChartGraphicsItem* item = new ChartGraphicsItem( row, column );
00140 item->setPolygon( polygon );
00141 addItem( item );
00142 }
00143
00144 void ReverseMapper::addCircle( int row, int column, const QPointF& location, const QSizeF& diameter )
00145 {
00146 QPainterPath path;
00147 QPointF ossfet( -0.5*diameter.width(), -0.5*diameter.height() );
00148 path.addEllipse( QRectF( location + ossfet, diameter ) );
00149 addPolygon( row, column, QPolygonF( path.toFillPolygon() ) );
00150 }
00151
00152 void ReverseMapper::addLine( int row, int column, const QPointF& from, const QPointF& to )
00153 {
00154
00155 if( from == to )
00156 {
00157 addCircle( row, column, from, QSizeF( 1.5, 1.5 ) );
00158 return;
00159 }
00160
00161
00162
00163
00164 static const QPointF pixel( 1.0, 1.0 );
00165 QPointF left, right;
00166 if ( from.x() < to.x() ) {
00167 left = from;
00168 right = to;
00169 } else {
00170 right = from;
00171 left = to;
00172 }
00173 const QPointF lineVector( right - left );
00174 const qreal lineVectorLength = sqrt( lineVector.x() * lineVector.x() + lineVector.y() * lineVector.y() );
00175 const QPointF lineVectorUnit( lineVector / lineVectorLength );
00176 const QPointF normOfLineVectorUnit( -lineVectorUnit.y(), lineVectorUnit.x() );
00177
00178 const QPointF one( left - lineVectorUnit + normOfLineVectorUnit );
00179 const QPointF two( left - lineVectorUnit - normOfLineVectorUnit );
00180 const QPointF three( right + lineVectorUnit - normOfLineVectorUnit );
00181 const QPointF four( right + lineVectorUnit + normOfLineVectorUnit );
00182 addPolygon( row, column, QPolygonF() << one << two << three << four );
00183 }