Qt Virtual Chart Table (QVCT)
CTrackSubContainer.cpp
Go to the documentation of this file.
1 // INDENTING (emacs/vi): -*- mode:c++; tab-width:2; c-basic-offset:2; intent-tabs-mode:nil; -*- ex: set tabstop=2 expandtab:
2 
3 /*
4  * Qt Virtual Chart Table (QVCT)
5  * Copyright (C) 2012 Cedric Dufour <http://cedric.dufour.name>
6  * Author: Cedric Dufour <http://cedric.dufour.name>
7  *
8  * The Qt Virtual Chart Table (QVCT) is free software:
9  * you can redistribute it and/or modify it under the terms of the GNU General
10  * Public License as published by the Free Software Foundation, Version 3.
11  *
12  * The Qt Virtual Chart Table (QVCT) is distributed in the hope
13  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
14  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  * See the GNU General Public License for more details.
17  */
18 
19 // QT
20 #include <QDateTime>
21 #include <QDomElement> // QtXml module
22 #include <QPainter>
23 #include <QPen>
24 #include <QPointF>
25 #include <QTreeWidgetItem>
26 #include <QXmlStreamWriter>
27 
28 // QVCT
29 #include "QVCTRuntime.hpp"
30 #include "charts/CChart.hpp"
33 
34 
35 //------------------------------------------------------------------------------
36 // CONSTRUCTORS / DESTRUCTOR
37 //------------------------------------------------------------------------------
38 
39 CTrackSubContainer::CTrackSubContainer( const QString& _rqsName )
40  : COverlayContainer( COverlayObject::SUBCONTAINER, _rqsName )
41 {
42  QTreeWidgetItem::setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled );
43  QTreeWidgetItem::setText( CTrackOverlay::NAME, qsName );
44  QTreeWidgetItem::setCheckState( CTrackOverlay::VISIBLE, Qt::Checked );
45 }
46 
48 {
49  QTreeWidgetItem* __pqTreeWidgetItem = QTreeWidgetItem::takeChild( 0 );
50  while( __pqTreeWidgetItem )
51  {
52  delete (CTrackPoint*)__pqTreeWidgetItem;
53  __pqTreeWidgetItem = QTreeWidgetItem::takeChild( 0 );
54  }
55 }
56 
57 
58 //------------------------------------------------------------------------------
59 // METHODS: COverlayObject (implement/override)
60 //------------------------------------------------------------------------------
61 
62 void CTrackSubContainer::unserialize( QDataStream& _rqDataStream )
63 {
64  COverlayObject::unserialize( _rqDataStream );
65  QTreeWidgetItem::setText( CTrackOverlay::NAME, qsName );
66 }
67 
68 
69 //------------------------------------------------------------------------------
70 // METHODS: COverlayObject (implement/override)
71 //------------------------------------------------------------------------------
72 
73 void CTrackSubContainer::draw( const CChart* _poChart, QPainter* _pqPainter )
74 {
75  // Exit if we're not visible
76  if( !bVisible ) return;
77 
78  // Retrieve and adjust drawing parameters
79  double __fdZoom = _poChart->getZoom();
80  if( __fdZoom < 0.5 ) __fdZoom = 0.5;
81  else if( __fdZoom > 2.0 ) __fdZoom = 2.0;
82  __fdZoom *= QVCTRuntime::useSettings()->getScreenDpi() / 96.0 ;
83  QPen __qPenMultiSelected = QVCTRuntime::useTrackOverlay()->getPenMarkerSelected();
84  QPen __qPenLine = QVCTRuntime::useTrackOverlay()->getPenLine();
85  __qPenMultiSelected.setWidth( __qPenLine.width() * __fdZoom );
86 
87  // Draw
88  int __iCount = QTreeWidgetItem::childCount();
89  if( !__iCount ) return;
90  CTrackPoint* __poTrackPointFrom = (CTrackPoint*)QTreeWidgetItem::child( 0 );
91  CTrackPoint* __poTrackPointTo = 0;
92  COverlayObject* __poOverlayObjectSelected = QVCTRuntime::useChartTable()->getOverlayObjectSelected();
93  // ... start
94  if( !__poTrackPointFrom->CDataPosition::operator==( CDataPosition::UNDEFINED ) &&
95  __poTrackPointFrom->isVisible() &&
96  _poChart->getDrawArea().contains( _poChart->toDrawPosition( *__poTrackPointFrom ).toPoint() ) )
97  {
98  if( __poOverlayObjectSelected == __poTrackPointFrom ||
99  __poOverlayObjectSelected == this ||
100  __poOverlayObjectSelected == QTreeWidgetItem::parent() )
101  __poTrackPointFrom->COverlayPoint::drawMarker( _poChart, _pqPainter, 0, true );
102  __poTrackPointFrom->COverlayPoint::drawTag( _poChart, _pqPainter );
103  }
104  // ... track
105  for( int __i = 1; __i < __iCount; __i++ )
106  {
107  __poTrackPointTo = (CTrackPoint*)QTreeWidgetItem::child( __i );
108  __poTrackPointFrom->drawLine( _poChart, _pqPainter, __poTrackPointTo );
109  if( __poTrackPointFrom->isMultiSelected() )
110  {
111  _pqPainter->setPen( __qPenMultiSelected );
112  _pqPainter->drawPoint( _poChart->toDrawPosition( *__poTrackPointFrom ) );
113  }
114  __poTrackPointFrom = __poTrackPointTo;
115  }
116  // ... end
117  if( __poTrackPointTo &&
118  !__poTrackPointTo->CDataPosition::operator==( CDataPosition::UNDEFINED ) &&
119  __poTrackPointTo->isVisible() &&
120  _poChart->getDrawArea().contains( _poChart->toDrawPosition( *__poTrackPointTo ).toPoint() ) )
121  {
122  if( __poTrackPointTo->isMultiSelected() )
123  {
124  _pqPainter->setPen( __qPenMultiSelected );
125  _pqPainter->drawPoint( _poChart->toDrawPosition( *__poTrackPointTo ) );
126  }
127  if( __poOverlayObjectSelected == __poTrackPointTo ||
128  __poOverlayObjectSelected == this ||
129  __poOverlayObjectSelected == QTreeWidgetItem::parent() )
130  __poTrackPointTo->COverlayPoint::drawMarker( _poChart, _pqPainter, 0, true );
131  __poTrackPointTo->COverlayPoint::drawTag( _poChart, _pqPainter );
132  }
133 }
134 
136 {
142 }
143 
144 
145 //------------------------------------------------------------------------------
146 // METHODS: COverlayContainer (implement/override)
147 //------------------------------------------------------------------------------
148 
149 COverlayPoint* CTrackSubContainer::matchScrPosition( const CChart* _poChart, const QPointF& _rqPointFScrPosition ) const
150 {
151  if( !bVisible ) return 0;
152  int __iCount = QTreeWidgetItem::childCount();
153  for( int __i = __iCount-1 ; __i >= 0; __i-- ) // we must go in the reverse order of CTrackSubContainer::draw() to pick the correct (overlapping) item
154  {
155  COverlayPoint* __poOverlayPoint = (COverlayPoint*)QTreeWidgetItem::child( __i );
156  if( __poOverlayPoint->matchScrPosition( _poChart, _rqPointFScrPosition ) )
157  return __poOverlayPoint;
158  }
159  return 0;
160 }
161 
162 
163 //------------------------------------------------------------------------------
164 // METHODS: COverlayVisibility (override)
165 //------------------------------------------------------------------------------
166 
167 void CTrackSubContainer::setVisibleName( bool _bVisibleName )
168 {
169  bVisibleName = _bVisibleName;
170  int __iCount = QTreeWidgetItem::childCount();
171  for( int __i = 0; __i < __iCount; __i++ )
172  ((CTrackPoint*)QTreeWidgetItem::child( __i ))->setVisibleName( bVisibleName );
173 }
174 
175 void CTrackSubContainer::setVisiblePosition( bool _bVisiblePosition )
176 {
177  bVisiblePosition = _bVisiblePosition;
178  int __iCount = QTreeWidgetItem::childCount();
179  for( int __i = 0; __i < __iCount; __i++ )
180  ((CTrackPoint*)QTreeWidgetItem::child( __i ))->setVisiblePosition( bVisiblePosition );
181 }
182 
183 void CTrackSubContainer::setVisibleRouting( bool _bVisibleRouting )
184 {
185  bVisibleRouting = _bVisibleRouting;
186  int __iCount = QTreeWidgetItem::childCount();
187  for( int __i = 0; __i < __iCount; __i++ )
188  ((CTrackPoint*)QTreeWidgetItem::child( __i ))->setVisibleRouting( bVisibleRouting );
189 }
190 
192 {
193  // Toggle global visibility
195  // Set points visibility
196  int __iCount = QTreeWidgetItem::childCount();
197  for( int __i = 0; __i < __iCount; __i++ )
198  {
199  CTrackPoint* __poTrackPoint = (CTrackPoint*)QTreeWidgetItem::child( __i );
200  __poTrackPoint->setVisibleName( bVisibleName );
201  __poTrackPoint->setVisiblePosition( bVisiblePosition );
202  __poTrackPoint->setVisibleRouting( bVisibleRouting );
203  }
204 }
205 
206 
207 //------------------------------------------------------------------------------
208 // METHODS
209 //------------------------------------------------------------------------------
210 
211 //
212 // OTHER
213 //
214 
216 {
217  int __iCount = QTreeWidgetItem::childCount();
218  if( !__iCount ) return 0;
219  return (CTrackPoint*)QTreeWidgetItem::child( __iCount-1 );
220 }
221 
222 CTrackPoint* CTrackSubContainer::addPoint( const QString& _rqsName, const CDataPosition& _roDataPosition )
223 {
224  CTrackPoint* __poTrackPoint = new CTrackPoint( _rqsName, _roDataPosition );
225  __poTrackPoint->setVisibility( this->getVisibility() | 1 );
226  QTreeWidgetItem::addChild( __poTrackPoint );
227  return __poTrackPoint;
228 }
229 
231 {
232  int __iCount = QTreeWidgetItem::childCount();
233  if( __iCount < 2 ) return 0.0;
234  CTrackPoint* __poTrackPointFrom = (CTrackPoint*)QTreeWidgetItem::child( 0 );
235  CTrackPoint* __poTrackPointTo = 0;
236  double __fdLength = 0;
237  for( int __i = 1; __i < __iCount; __i++ )
238  {
239  __poTrackPointTo = (CTrackPoint*)QTreeWidgetItem::child( __i );
240  __fdLength += CDataPosition::distanceRL( *__poTrackPointFrom, *__poTrackPointTo );
241  __poTrackPointFrom = __poTrackPointTo;
242  }
243  return __fdLength;
244 }
245 
247 {
248  int __iCount = QTreeWidgetItem::childCount();
249  if( __iCount < 2 ) return 0.0;
250  CTrackPoint* __poTrackPointFirst = (CTrackPoint*)QTreeWidgetItem::child( 0 );
251  CTrackPoint* __poTrackPointLast = (CTrackPoint*)QTreeWidgetItem::child( __iCount-1 );
252  if( __poTrackPointFirst->getTime() < 0 || __poTrackPointLast->getTime() < 0 ) return 0.0;
253  return( __poTrackPointLast->getTime() - __poTrackPointFirst->getTime() );
254 }
255 
256 int CTrackSubContainer::parseQVCT( const QDomElement& _rqDomElement )
257 {
258  COverlayVisibility::setVisibility( _rqDomElement.attribute( "visibility", "3" ).toInt() );
259  QTreeWidgetItem::setCheckState( CTrackOverlay::VISIBLE, bVisible ? Qt::Checked : Qt::Unchecked );
260  int __iCount = 0;
261  for( QDomElement __qDomElement = _rqDomElement.firstChildElement( "Point" );
262  !__qDomElement.isNull();
263  __qDomElement = __qDomElement.nextSiblingElement( "Point" ) )
264  {
265  __iCount++;
266  QString __qsName;
267  QString __qsName_aux = __qDomElement.attribute( "time" );
268  if( !__qsName_aux.isEmpty() ) __qsName = CUnitTime::toString( QDateTime::fromString( __qsName_aux, Qt::ISODate ).toTime_t() );
269  if( __qsName.isEmpty() ) __qsName = __qDomElement.firstChildElement( "name" ).text();
270  if( __qsName.isEmpty() ) __qsName = COverlayObject::newChildName( tr("Point"), 3, __iCount );
271  CTrackPoint* __poTrackPoint = new CTrackPoint( __qsName );
272  __poTrackPoint->parseQVCT( __qDomElement );
273  addChild( __poTrackPoint );
274  }
275  return __iCount;
276 }
277 
278 int CTrackSubContainer::parseGPX( const QDomElement& _rqDomElement )
279 {
280  // GPX format reference: see http://www.topografix.com/GPX/1/1/
281  int __iCount = 0;
282  for( QDomElement __qDomElement = _rqDomElement.firstChildElement( "trkpt" );
283  !__qDomElement.isNull();
284  __qDomElement = __qDomElement.nextSiblingElement( "trkpt" ) )
285  {
286  __iCount++;
287  QString __qsName;
288  QString __qsName_aux = __qDomElement.firstChildElement( "time" ).text();
289  if( !__qsName_aux.isEmpty() ) __qsName = CUnitTime::toString( QDateTime::fromString( __qsName_aux, Qt::ISODate ).toTime_t() );
290  if( __qsName.isEmpty() ) __qsName = __qDomElement.firstChildElement( "name" ).text();
291  if( __qsName.isEmpty() ) __qsName = COverlayObject::newChildName( tr("Point"), 3, __iCount );
292  CTrackPoint* __poTrackPoint = new CTrackPoint( __qsName );
293  __poTrackPoint->parseGPX( __qDomElement );
294  addChild( __poTrackPoint );
295  }
296  return __iCount;
297 }
298 
299 void CTrackSubContainer::dumpQVCT( QXmlStreamWriter & _rqXmlStreamWriter, bool bOnlySelected ) const
300 {
301  int __iCount = QTreeWidgetItem::childCount();
302  if( !__iCount ) return;
303 
304  // Data
305  _rqXmlStreamWriter.writeStartElement( "Segment" );
306  // ... visibility
307  _rqXmlStreamWriter.writeAttribute( "visibility", QString::number( COverlayVisibility::getVisibility() ) );
308  // ... points
309  for( int __i = 0; __i < __iCount; __i++ )
310  {
311  CTrackPoint* __poTrackPoint = (CTrackPoint*)QTreeWidgetItem::child( __i );
312  if( bOnlySelected && !__poTrackPoint->isMultiSelected() ) continue;
313  __poTrackPoint->dumpQVCT( _rqXmlStreamWriter );
314  }
315  // ... [end]
316  _rqXmlStreamWriter.writeEndElement(); // Segment
317 }
318 
319 void CTrackSubContainer::dumpGPX( QXmlStreamWriter & _rqXmlStreamWriter, bool bOnlySelected ) const
320 {
321  // GPX format reference: see http://www.topografix.com/GPX/1/1/
322  int __iCount = QTreeWidgetItem::childCount();
323  if( !__iCount ) return;
324 
325  // Data
326  _rqXmlStreamWriter.writeStartElement( "trkseg" );
327  // ... points
328  for( int __i = 0; __i < __iCount; __i++ )
329  {
330  CTrackPoint* __poTrackPoint = (CTrackPoint*)QTreeWidgetItem::child( __i );
331  if( bOnlySelected && !__poTrackPoint->isMultiSelected() ) continue;
332  __poTrackPoint->dumpGPX( _rqXmlStreamWriter );
333  }
334  // ... [end]
335  _rqXmlStreamWriter.writeEndElement(); // trkseg
336 }
337 
339 {
340  int __iCount = 0;
341  for( int __i = QTreeWidgetItem::childCount()-1; __i >= 0; __i-- )
342  {
343  CTrackPoint* __poTrackPoint = (CTrackPoint*)QTreeWidgetItem::child( __i );
344  if( __poTrackPoint->isMultiSelected() )
345  {
346  __iCount++;
347  QTreeWidgetItem::removeChild( __poTrackPoint );
348  delete __poTrackPoint;
349  }
350  }
351  return __iCount;
352 }
COverlayObject * getOverlayObjectSelected() const
Returns the currently selected overlay object.
void setOverlayObjectSelected(COverlayObject *_poOverlayObject)
Sets the currently selected overlay object.
[UI] Chart (view)
Definition: CChart.hpp:44
double getZoom() const
Returns the current zoom factor.
Definition: CChart.hpp:139
QRectF getDrawArea() const
Returns the viewport draw area.
Definition: CChart.hpp:127
QPointF toDrawPosition(const CDataPosition &_roGeoPosition) const
Converts the given (geographical) position [long,lat,elev] to chart draw point [px].
Definition: CChart.cpp:192
(Geographical) Position data [long,lat,elev]
static double distanceRL(const CDataPosition &_roPosition1, const CDataPosition &_roPosition2)
Returns the rhumb-line distance between two points, in meters.
static const CDataPosition UNDEFINED
Specific value for an undefined position.
double getTime() const
Returns this time's time, in seconds from Unix epoch.
Definition: CDataTime.hpp:89
Generic overlay container.
void switchView(EView eView)
Displays the requested container/item details (switching to the appropriate widget)
@ TRACK_SUBCONTAINER
Track sub-container (segment)
bool isMultiSelected() const
Returns this item's selection status.
@ TRACK
Track overlay.
void switchView(EView eView)
Displays the requested overlay (switching to the appropriate tab)
void setOverlayObject(COverlayObject *_poOverlayObject)
Sets the overlay object to be displayed (and refreshes the underlying widget)
Generic overlay object.
virtual void unserialize(QDataStream &_rqDataStream)
Unserializes (restore) this object's data from binary format.
QString newChildName(const QString &_rqsName, int _iZeroPrefix=0, bool _bForceSuffix=false) const
Returns a valid (non-duplicate) name for a new sibling of this object.
QString qsName
Object name.
Generic overlay point.
virtual bool matchScrPosition(const CChart *_poChart, const QPointF &_rqPointFScrPosition) const
Returns whether this point matches the given screen position.
virtual void drawLine(const CChart *_poChart, QPainter *_pqPainter, const COverlayPoint *_poOverlayPoint)
Draws a line (between this and the other specified point), including distance/bearing data.
bool bVisibleRouting
Routing's (data) visibility status.
virtual void setVisiblePosition(bool _bVisiblePosition)
Sets the position's visibility status.
void setVisibility(int _iVisibilityCode)
Sets the global (coded) visibility status.
virtual void setVisibleRouting(bool _bVisibleRouting)
Sets the routing's (data) visibility status.
virtual void toggleVisibility(bool _bIncludeCourse, bool _bIncludeRouting)
Toggle the visibility status.
bool bVisible
Global (marker) visibility status.
bool bVisiblePosition
Position's visibility status.
bool bVisibleName
Name's (tag) visibility status.
bool isVisible() const
Returns the point's (marker) visibility status.
int getVisibility() const
Returns the global (coded) visibility status.
virtual void setVisibleName(bool _bVisibleName)
Sets the name's (tag) visibility status.
const QPen & getPenMarkerSelected() const
Definition: COverlay.hpp:128
const QPen & getPenLine() const
Definition: COverlay.hpp:129
int getScreenDpi()
[Misc] Returns the screen Dots-per-Inch (DPI)
Definition: CSettings.hpp:429
@ VISIBLE
Track visibility status.
@ NAME
Track name.
[UI] Track overlay point (item)
Definition: CTrackPoint.hpp:40
void parseQVCT(const QDomElement &_rqDomElement)
Retrieves this object's content from the given QVCT source (file)
void parseGPX(const QDomElement &_rqDomElement)
Retrieves this object's content from the given GPX source (file)
void dumpQVCT(QXmlStreamWriter &_rqXmlStreamWriter) const
Stores this object's content to the given QVCT destination (file)
void dumpGPX(QXmlStreamWriter &_rqXmlStreamWriter) const
Stores this object's content to the given GPX destination (file)
virtual void refreshContent()
Refreshes the content of the underlying widget.
int parseGPX(const QDomElement &_rqDomElement)
Retrieves this object's content from the given GPX source (file)
virtual void showDetail()
Displays this object's details (in the appropriate widget/view)
virtual void setVisibleRouting(bool _bVisibleRouting)
Sets the routing's (data) visibility status.
CTrackSubContainer(const QString &_rqsName)
int deleteSelection()
Deletes selected items within this sub-container.
virtual void setVisibleName(bool _bVisibleName)
Sets the name's (tag) visibility status.
double getLengthRL()
Returns the track's (rhumb-line) length.
virtual void draw(const CChart *_poChart, QPainter *_pqPainter)
Draws this object (itself or its content)
void dumpQVCT(QXmlStreamWriter &_rqXmlStreamWriter, bool bOnlySelected=false) const
Stores this object's content to the given QVCT destination (file)
virtual void unserialize(QDataStream &_rqDataStream)
Unserializes (restore) this object's data from binary format.
CTrackPoint * getLastPoint()
Returns the last track (item/point) from this sub-container (0 if none is found)
CTrackPoint * addPoint(const QString &_rqsName, const CDataPosition &_roDataPosition=CDataPosition::UNDEFINED)
Add a new track (item/point) to this sub-container.
double getTimeElapsed()
Returns the track's elapsed time.
virtual void setVisiblePosition(bool _bVisiblePosition)
Sets the position's visibility status.
int parseQVCT(const QDomElement &_rqDomElement)
Retrieves this object's content from the given QVCT source (file)
virtual void toggleVisibility()
virtual COverlayPoint * matchScrPosition(const CChart *_poChart, const QPointF &_rqPointFScrPosition) const
Returns the overlay container's point that (first) matches the given screen position (0 if none is fo...
void dumpGPX(QXmlStreamWriter &_rqXmlStreamWriter, bool bOnlySelected=false) const
Stores this object's content to the given GPX destination (file)
static QString toString(double _fdValue, CUnitTimeZone::EUnit _eUnitTimeZone, EUnit _eUnit, int _iPrecision=0)
Returns the formatted represention of the given value, using the specified format/unit and decimal pr...
Definition: CUnitTime.cpp:79
static COverlayDetailView * useOverlayDetailView()
static COverlayListView * useOverlayListView()
static CChartTable * useChartTable()
static CTrackSubContainerDetailView * useTrackSubContainerDetailView()
static CSettings * useSettings()
static CTrackOverlay * useTrackOverlay()