Qt Virtual Chart Table (QVCT)
CTrackContainer.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 <QDomElement> // QtXml module
21 #include <QPainter>
22 #include <QPointF>
23 #include <QTreeWidgetItem>
24 #include <QXmlStreamWriter>
25 
26 // QVCT
27 #include "QVCTRuntime.hpp"
32 
33 
34 //------------------------------------------------------------------------------
35 // CONSTRUCTORS / DESTRUCTOR
36 //------------------------------------------------------------------------------
37 
38 CTrackContainer::CTrackContainer( const QString& _rqsName )
39  : COverlayContainer( COverlayObject::CONTAINER, _rqsName )
40  , qsType()
41  , qsDescription()
42  , qsComment()
43  , qsUrl()
44 {
45  QTreeWidgetItem::setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable );
46  QTreeWidgetItem::setText( CTrackOverlay::NAME, qsName );
47  QTreeWidgetItem::setCheckState( CTrackOverlay::VISIBLE, Qt::Checked );
48 }
49 
51 {
52  QTreeWidgetItem* __pqTreeWidgetItem = QTreeWidgetItem::takeChild( 0 );
53  while( __pqTreeWidgetItem )
54  {
55  delete (CTrackSubContainer*)__pqTreeWidgetItem;
56  __pqTreeWidgetItem = QTreeWidgetItem::takeChild( 0 );
57  }
58 }
59 
60 
61 //------------------------------------------------------------------------------
62 // METHODS: COverlayObject (implement/override)
63 //------------------------------------------------------------------------------
64 
65 void CTrackContainer::serialize( QDataStream& _rqDataStream ) const
66 {
67  COverlayObject::serialize( _rqDataStream );
68  _rqDataStream << qsType << qsDescription << qsComment << qsUrl;
69 }
70 
71 void CTrackContainer::unserialize( QDataStream& _rqDataStream )
72 {
73  COverlayObject::unserialize( _rqDataStream );
74  _rqDataStream >> qsType >> qsDescription >> qsComment >> qsUrl;
75  QTreeWidgetItem::setText( CTrackOverlay::NAME, qsName );
76 }
77 
78 void CTrackContainer::draw( const CChart* _poChart, QPainter* _pqPainter )
79 {
80  if( !bVisible ) return;
81  int __iCount = QTreeWidgetItem::childCount();
82  for( int __i = 0; __i < __iCount; __i++ )
83  ((CTrackSubContainer*)QTreeWidgetItem::child( __i ))->draw( _poChart, _pqPainter );
84 }
85 
87 {
93 }
94 
96 {
97  CTrackContainerEditView* __poTrackContainerEditView = new CTrackContainerEditView( this );
98  if( __poTrackContainerEditView->exec() == QDialog::Accepted ) showDetail();
99  delete __poTrackContainerEditView;
100 }
101 
102 
103 //------------------------------------------------------------------------------
104 // METHODS: COverlayContainer (implement/override)
105 //------------------------------------------------------------------------------
106 
107 COverlayPoint* CTrackContainer::matchScrPosition( const CChart* _poChart, const QPointF& _rqPointFScrPosition ) const
108 {
109  if( !bVisible ) return 0;
110  int __iCount = QTreeWidgetItem::childCount();
111  for( int __i = __iCount-1 ; __i >= 0; __i-- ) // we must go in the reverse order of CTrackOverlay::draw() to pick the correct (overlapping) item
112  {
113  CTrackSubContainer* __poTrackSubContainer = (CTrackSubContainer*)QTreeWidgetItem::child( __i );
114  COverlayPoint* __poOverlayPoint = __poTrackSubContainer->matchScrPosition( _poChart, _rqPointFScrPosition );
115  if( __poOverlayPoint ) return __poOverlayPoint;
116  }
117  return 0;
118 }
119 
120 
121 //------------------------------------------------------------------------------
122 // METHODS: COverlayVisibility (override)
123 //------------------------------------------------------------------------------
124 
125 void CTrackContainer::setVisibleName( bool _bVisibleName )
126 {
127  bVisibleName = _bVisibleName;
128  int __iCount = QTreeWidgetItem::childCount();
129  for( int __i = 0; __i < __iCount; __i++ )
130  ((CTrackSubContainer*)QTreeWidgetItem::child( __i ))->setVisibleName( bVisibleName );
131 }
132 
133 void CTrackContainer::setVisiblePosition( bool _bVisiblePosition )
134 {
135  bVisiblePosition = _bVisiblePosition;
136  int __iCount = QTreeWidgetItem::childCount();
137  for( int __i = 0; __i < __iCount; __i++ )
138  ((CTrackSubContainer*)QTreeWidgetItem::child( __i ))->setVisiblePosition( bVisiblePosition );
139 }
140 
141 void CTrackContainer::setVisibleRouting( bool _bVisibleRouting )
142 {
143  bVisibleRouting = _bVisibleRouting;
144  int __iCount = QTreeWidgetItem::childCount();
145  for( int __i = 0; __i < __iCount; __i++ )
146  ((CTrackSubContainer*)QTreeWidgetItem::child( __i ))->setVisibleRouting( bVisibleRouting );
147 }
148 
150 {
151  // Toggle global visibility
153  // Set points visibility
154  int __iCount = QTreeWidgetItem::childCount();
155  for( int __i = 0; __i < __iCount; __i++ )
156  {
157  CTrackSubContainer* __poTrackSubContainer = (CTrackSubContainer*)QTreeWidgetItem::child( __i );
158  __poTrackSubContainer->setVisibleName( bVisibleName );
159  __poTrackSubContainer->setVisiblePosition( bVisiblePosition );
160  __poTrackSubContainer->setVisibleRouting( bVisibleRouting );
161  }
162 }
163 
164 
165 //------------------------------------------------------------------------------
166 // METHODS
167 //------------------------------------------------------------------------------
168 
169 //
170 // OTHER
171 //
172 
174 {
175  int __iCount = QTreeWidgetItem::childCount();
176  if( __iCount ) return (CTrackSubContainer*)QTreeWidgetItem::child( __iCount-1 );
177  return addSubContainer();
178 }
179 
181 {
182  CTrackSubContainer* __poTrackSubContainer = 0;
183  int __iCount = QTreeWidgetItem::childCount();
184  if( !__iCount || QTreeWidgetItem::child( __iCount-1 )->childCount() )
185  {
186  __poTrackSubContainer = new CTrackSubContainer( COverlayObject::newChildName( tr("Segment"), 1, true ) );
187  __poTrackSubContainer->setVisibility( this->getVisibility() | 1 );
188  QTreeWidgetItem::addChild( __poTrackSubContainer );
189  }
190  else __poTrackSubContainer = (CTrackSubContainer*)QTreeWidgetItem::child( __iCount-1 );
191  return __poTrackSubContainer;
192 }
193 
195 {
196  double __fdLength = 0;
197  int __iCount = QTreeWidgetItem::childCount();
198  for( int __i = 0; __i < __iCount; __i++ )
199  __fdLength += ((CTrackSubContainer*)QTreeWidgetItem::child( __i ))->getLengthRL();
200  return __fdLength;
201 }
202 
204 {
205  double __fdTimeElapsed = 0;
206  int __iCount = QTreeWidgetItem::childCount();
207  for( int __i = 0; __i < __iCount; __i++ )
208  __fdTimeElapsed += ((CTrackSubContainer*)QTreeWidgetItem::child( __i ))->getTimeElapsed();
209  return __fdTimeElapsed;
210 }
211 
212 int CTrackContainer::parseQVCT( const QDomElement& _rqDomElement )
213 {
214  COverlayVisibility::setVisibility( _rqDomElement.attribute( "visibility", "3" ).toInt() );
215  QTreeWidgetItem::setCheckState( CTrackOverlay::VISIBLE, bVisible ? Qt::Checked : Qt::Unchecked );
216  qsType = _rqDomElement.attribute( "type" );
217  qsUrl = _rqDomElement.attribute( "url" );
218  qsDescription = _rqDomElement.firstChildElement( "Description" ).text();
219  qsComment = _rqDomElement.firstChildElement( "Comment" ).text();
220  int __iCount = 0, __iCountSegment = 0;
221  for( QDomElement __qDomElement = _rqDomElement.firstChildElement( "Segment" );
222  !__qDomElement.isNull();
223  __qDomElement = __qDomElement.nextSiblingElement( "Segment" ) )
224  {
225  __iCountSegment++;
226  CTrackSubContainer* __poTrackSubContainer = new CTrackSubContainer( COverlayObject::newChildName( tr("Segment"), 1, __iCountSegment ) );
227  __iCount += __poTrackSubContainer->parseQVCT( __qDomElement );
228  addChild( __poTrackSubContainer );
229  }
230  return __iCount;
231 }
232 
233 int CTrackContainer::parseGPX( const QDomElement& _rqDomElement )
234 {
235  // GPX format reference: see http://www.topografix.com/GPX/1/1/
236  qsType = _rqDomElement.firstChildElement( "type" ).text();
237  qsDescription = _rqDomElement.firstChildElement( "desc" ).text();
238  qsComment = _rqDomElement.firstChildElement( "cmt" ).text();
239  qsUrl = _rqDomElement.firstChildElement( "link" ).attribute( "href" );
240  int __iCount = 0, __iCountSegment = 0;
241  for( QDomElement __qDomElement = _rqDomElement.firstChildElement( "trkseg" );
242  !__qDomElement.isNull();
243  __qDomElement = __qDomElement.nextSiblingElement( "trkseg" ) )
244  {
245  __iCountSegment++;
246  CTrackSubContainer* __poTrackSubContainer = new CTrackSubContainer( COverlayObject::newChildName( tr("Segment"), 1, __iCountSegment ) );
247  __iCount += __poTrackSubContainer->parseGPX( __qDomElement );
248  addChild( __poTrackSubContainer );
249  }
250  return __iCount;
251 }
252 
253 void CTrackContainer::dumpQVCT( QXmlStreamWriter & _rqXmlStreamWriter, bool bOnlySelected ) const
254 {
255  // Data
256  _rqXmlStreamWriter.writeStartElement( "Track" );
257  // ... name
258  if( !qsName.isEmpty() ) _rqXmlStreamWriter.writeAttribute( "name", qsName );
259  // ... visibility
260  _rqXmlStreamWriter.writeAttribute( "visibility", QString::number( COverlayVisibility::getVisibility() ) );
261  // ... type
262  if( !qsType.isEmpty() ) _rqXmlStreamWriter.writeAttribute( "type", qsType );
263  // ... url
264  if( !qsUrl.isEmpty() ) _rqXmlStreamWriter.writeAttribute( "url", qsUrl );
265  // ... description
266  if( !qsDescription.isEmpty() )
267  {
268  _rqXmlStreamWriter.writeStartElement( "Description" );
269  _rqXmlStreamWriter.writeCDATA( qsDescription );
270  _rqXmlStreamWriter.writeEndElement(); // Description
271  }
272  // ... comment
273  if( !qsComment.isEmpty() )
274  {
275  _rqXmlStreamWriter.writeStartElement( "Comment" );
276  _rqXmlStreamWriter.writeCDATA( qsComment );
277  _rqXmlStreamWriter.writeEndElement(); // Comment
278  }
279  // ... segments
280  int __iCount = QTreeWidgetItem::childCount();
281  for( int __i = 0; __i < __iCount; __i++ )
282  ((CTrackSubContainer*)QTreeWidgetItem::child( __i ))->dumpQVCT( _rqXmlStreamWriter, bOnlySelected );
283  // ... [end]
284  _rqXmlStreamWriter.writeEndElement(); // Track
285 }
286 
287 void CTrackContainer::dumpGPX( QXmlStreamWriter & _rqXmlStreamWriter, bool bOnlySelected ) const
288 {
289  // GPX format reference: see http://www.topografix.com/GPX/1/1/
290 
291  // Data
292  _rqXmlStreamWriter.writeStartElement( "trk" );
293  // ... name
294  if( !qsName.isEmpty() )
295  {
296  _rqXmlStreamWriter.writeStartElement( "name" );
297  _rqXmlStreamWriter.writeCharacters( qsName );
298  _rqXmlStreamWriter.writeEndElement(); // name
299  }
300  // ... type
301  if( !qsType.isEmpty() )
302  {
303  _rqXmlStreamWriter.writeStartElement( "type" );
304  _rqXmlStreamWriter.writeCharacters( qsType );
305  _rqXmlStreamWriter.writeEndElement(); // type
306  }
307  // ... description
308  if( !qsDescription.isEmpty() )
309  {
310  _rqXmlStreamWriter.writeStartElement( "desc" );
311  _rqXmlStreamWriter.writeCDATA( qsDescription );
312  _rqXmlStreamWriter.writeEndElement(); // desc
313  }
314  // ... comment
315  if( !qsComment.isEmpty() )
316  {
317  _rqXmlStreamWriter.writeStartElement( "cmt" );
318  _rqXmlStreamWriter.writeCDATA( qsComment );
319  _rqXmlStreamWriter.writeEndElement(); // cmt
320  }
321  // ... url
322  if( !qsUrl.isEmpty() )
323  {
324  _rqXmlStreamWriter.writeStartElement( "link" );
325  _rqXmlStreamWriter.writeAttribute( "href", qsUrl );
326  _rqXmlStreamWriter.writeEndElement(); // link
327  }
328  // ... segments
329  int __iCount = QTreeWidgetItem::childCount();
330  for( int __i = 0; __i < __iCount; __i++ )
331  ((CTrackSubContainer*)QTreeWidgetItem::child( __i ))->dumpGPX( _rqXmlStreamWriter, bOnlySelected );
332  _rqXmlStreamWriter.writeEndElement(); // trk
333 }
334 
336 {
337  int __iCount = 0;
338  for( int __i = QTreeWidgetItem::childCount()-1; __i >= 0; __i-- )
339  __iCount += ((CTrackSubContainer*)QTreeWidgetItem::child( __i ))->deleteSelection();
340  return __iCount;
341 }
void setOverlayObjectSelected(COverlayObject *_poOverlayObject)
Sets the currently selected overlay object.
[UI] Chart (view)
Definition: CChart.hpp:44
Generic overlay container.
void switchView(EView eView)
Displays the requested container/item details (switching to the appropriate widget)
@ TRACK_CONTAINER
Track container.
@ 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 serialize(QDataStream &_rqDataStream) const
Serializes (store) this object's data to binary format.
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.
bool bVisibleRouting
Routing's (data) visibility status.
void setVisibility(int _iVisibilityCode)
Sets the global (coded) 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.
int getVisibility() const
Returns the global (coded) visibility status.
virtual void refreshContent()
Refreshes the content of the underlying widget.
[UI] Track container's edit view
int parseGPX(const QDomElement &_rqDomElement)
Retrieves this object's content from the given GPX source (file)
CTrackSubContainer * pickSubContainer()
Returns the last/current sub-container of this container.
QString qsUrl
Track's URL.
CTrackContainer(const QString &_rqsName)
QString qsComment
Track's comment.
QString qsDescription
Track's description.
virtual void draw(const CChart *_poChart, QPainter *_pqPainter)
Draws this object (itself or its content)
virtual void setVisibleName(bool _bVisibleName)
Sets the name's (tag) visibility status.
virtual void setVisibleRouting(bool _bVisibleRouting)
Sets the routing's (data) visibility status.
int deleteSelection()
Deletes selected items within this container.
virtual void setVisiblePosition(bool _bVisiblePosition)
Sets the position's visibility status.
QString qsType
Track's type.
void dumpQVCT(QXmlStreamWriter &_rqXmlStreamWriter, bool bOnlySelected=false) const
Stores this object's content to the given QVCT destination (file)
virtual void serialize(QDataStream &_rqDataStream) const
Serializes (store) this object's data to binary format.
virtual void showDetail()
Displays this object's details (in the appropriate widget/view)
int parseQVCT(const QDomElement &_rqDomElement)
Retrieves this object's content from the given QVCT source (file)
virtual void toggleVisibility()
double getLengthRL()
Returns the track's (rhumb-line) length.
virtual void showEdit()
Displays this object's edit widget/view.
void dumpGPX(QXmlStreamWriter &_rqXmlStreamWriter, bool bOnlySelected=false) const
Stores this object's content to the given GPX destination (file)
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...
virtual ~CTrackContainer()
double getTimeElapsed()
Returns the track's elapsed time.
virtual void unserialize(QDataStream &_rqDataStream)
Unserializes (restore) this object's data from binary format.
CTrackSubContainer * addSubContainer()
Add a new sub-container to this container.
@ VISIBLE
Track visibility status.
@ NAME
Track name.
[UI] Track overlay sub-container
int parseGPX(const QDomElement &_rqDomElement)
Retrieves this object's content from the given GPX source (file)
virtual void setVisibleRouting(bool _bVisibleRouting)
Sets the routing's (data) visibility status.
virtual void setVisibleName(bool _bVisibleName)
Sets the name's (tag) visibility status.
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 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...
static COverlayDetailView * useOverlayDetailView()
static CTrackContainerDetailView * useTrackContainerDetailView()
static COverlayListView * useOverlayListView()
static CChartTable * useChartTable()