1
/****************************************************************************
2
** Copyright (C) 2001-2010 Klaralvdalens Datakonsult AB. All rights reserved.
4
** This file is part of the KD Chart library.
6
** Licensees holding valid commercial KD Chart licenses may use this file in
7
** accordance with the KD Chart Commercial License Agreement provided with
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 and version 3 as published by the
13
** Free Software Foundation and appearing in the file LICENSE.GPL included.
15
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18
** Contact info@kdab.com if any conditions of this licensing are not
21
**********************************************************************/
23
#include "ReverseMapper.h"
30
#include <QPainterPath>
31
#include <QGraphicsScene>
33
#include "../KDChartAbstractDiagram.h"
34
#include "ChartGraphicsItem.h"
36
using namespace KDChart;
38
ReverseMapper::ReverseMapper()
44
ReverseMapper::ReverseMapper( AbstractDiagram* diagram )
46
, m_diagram( diagram )
50
ReverseMapper::~ReverseMapper()
52
delete m_scene; m_scene = 0;
55
void ReverseMapper::setDiagram( AbstractDiagram* diagram )
61
void ReverseMapper::clear()
64
m_scene = new QGraphicsScene();
67
QModelIndexList ReverseMapper::indexesIn( const QRect& rect ) const
69
Q_ASSERT( m_diagram );
70
if ( m_scene && m_scene->sceneRect().intersects( rect ) ) {
71
QList<QGraphicsItem *> items = m_scene->items( rect );
72
QModelIndexList indexes;
73
Q_FOREACH( QGraphicsItem* item, items ) {
74
ChartGraphicsItem* i = qgraphicsitem_cast<ChartGraphicsItem*>( item );
76
QModelIndex index ( m_diagram->model()->index( i->row(), i->column(), m_diagram->rootIndex() ) );
82
return QModelIndexList();
86
QModelIndexList ReverseMapper::indexesAt( const QPointF& point ) const
88
Q_ASSERT( m_diagram );
89
if ( m_scene && m_scene->sceneRect().contains( point ) ) {
90
QList<QGraphicsItem *> items = m_scene->items( point );
91
QModelIndexList indexes;
92
Q_FOREACH( QGraphicsItem* item, items ) {
93
ChartGraphicsItem* i = qgraphicsitem_cast<ChartGraphicsItem*>( item );
95
QModelIndex index ( m_diagram->model()->index( i->row(), i->column(), m_diagram->rootIndex() ) );
96
if( !indexes.contains(index) )
102
return QModelIndexList();
106
QPolygonF ReverseMapper::polygon( int row, int column ) const
108
const QModelIndex index = m_diagram->model()->index( row, column, m_diagram->rootIndex() );
109
return m_itemMap.contains( index ) ? m_itemMap[ index ]->polygon() : QPolygon();
112
QRectF ReverseMapper::boundingRect( int row, int column ) const
114
const QModelIndex index = m_diagram->model()->index( row, column, m_diagram->rootIndex() );
115
return m_itemMap.contains( index ) ? m_itemMap[ index ]->polygon().boundingRect() : QRectF();
118
void ReverseMapper::addItem( ChartGraphicsItem* item )
121
m_scene->addItem( item );
122
m_itemMap.insert( m_diagram->model()->index( item->row(), item->column(), m_diagram->rootIndex() ), item );
125
void ReverseMapper::addRect( int row, int column, const QRectF& rect )
127
addPolygon( row, column, QPolygonF( rect ) );
130
void ReverseMapper::addPolygon( int row, int column, const QPolygonF& polygon )
132
ChartGraphicsItem* item = new ChartGraphicsItem( row, column );
133
item->setPolygon( polygon );
137
void ReverseMapper::addCircle( int row, int column, const QPointF& location, const QSizeF& diameter )
140
QPointF ossfet( -0.5*diameter.width(), -0.5*diameter.height() );
141
path.addEllipse( QRectF( location + ossfet, diameter ) );
142
addPolygon( row, column, QPolygonF( path.toFillPolygon() ) );
145
void ReverseMapper::addLine( int row, int column, const QPointF& from, const QPointF& to )
147
// that's no line, dude... make a small circle around that point, instead
150
addCircle( row, column, from, QSizeF( 1.5, 1.5 ) );
153
// lines do not make good polygons to click on. we calculate a 2
154
// pixel wide rectangle, where the original line is excatly
156
// make a 3 pixel wide polygon from the line:
157
static const QPointF pixel( 1.0, 1.0 );
159
if ( from.x() < to.x() ) {
166
const QPointF lineVector( right - left );
167
const qreal lineVectorLength = sqrt( lineVector.x() * lineVector.x() + lineVector.y() * lineVector.y() );
168
const QPointF lineVectorUnit( lineVector / lineVectorLength );
169
const QPointF normOfLineVectorUnit( -lineVectorUnit.y(), lineVectorUnit.x() );
170
// now the four polygon end points:
171
const QPointF one( left - lineVectorUnit + normOfLineVectorUnit );
172
const QPointF two( left - lineVectorUnit - normOfLineVectorUnit );
173
const QPointF three( right + lineVectorUnit - normOfLineVectorUnit );
174
const QPointF four( right + lineVectorUnit + normOfLineVectorUnit );
175
addPolygon( row, column, QPolygonF() << one << two << three << four );