Qt Virtual Chart Table (QVCT)
CTrackContainerDetailView.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 // C/C++
20 #include <algorithm>
21 
22 // QT
23 #include <QFileInfo>
24 #include <QHBoxLayout>
25 #include <QLabel>
26 #include <QPushButton>
27 #include <QScrollArea>
28 #include <QStackedWidget>
29 #include <QVBoxLayout>
30 #include <QWidget>
31 
32 // QVCT
33 #include "QVCTRuntime.hpp"
34 #include "data/CDataPosition.hpp"
36 #include "overlays/COverlayUrl.hpp"
40 
41 
42 //------------------------------------------------------------------------------
43 // CONSTRUCTORS / DESTRUCTOR
44 //------------------------------------------------------------------------------
45 
47  : COverlayObjectDetailView( _pqParent )
48 {
50 }
51 
53 {
54  // Create the buttons
55  // ... visible
56  pqPushButtonVisible = new QPushButton( QIcon( ":icons/32x32/visible.png" ), "" );
57  pqPushButtonVisible->setMaximumSize( 36, 34 );
58  pqPushButtonVisible->setToolTip( tr("Toggle this track's visibility") );
59  pqPushButtonVisible->setEnabled( false );
60  QWidget::connect( pqPushButtonVisible, SIGNAL( clicked() ), this, SLOT( slotToggleVisible() ) );
61  // ... center
62  pqPushButtonCenter = new QPushButton( QIcon( ":icons/32x32/center.png" ), "" );
63  pqPushButtonCenter->setMaximumSize( 36, 34 );
64  pqPushButtonCenter->setToolTip( tr("Center chart on this track's mean position") );
65  pqPushButtonCenter->setEnabled( false );
66  QWidget::connect( pqPushButtonCenter, SIGNAL( clicked() ), this, SLOT( slotPositionCenter() ) );
67  // ... edit
68  pqPushButtonEdit = new QPushButton( QIcon( ":icons/32x32/edit.png" ), "" );
69  pqPushButtonEdit->setMaximumSize( 36, 34 );
70  pqPushButtonEdit->setToolTip( tr("Edit this track") );
71  pqPushButtonEdit->setEnabled( false );
72  QWidget::connect( pqPushButtonEdit, SIGNAL( clicked() ), this, SLOT( slotEdit() ) );
73  // ... save
74  pqPushButtonSave = new QPushButton( QIcon( ":icons/32x32/save.png" ), "" );
75  pqPushButtonSave->setMaximumSize( 36, 34 );
76  pqPushButtonSave->setToolTip( tr("Save this track to disk") );
77  pqPushButtonSave->setEnabled( false );
78  QWidget::connect( pqPushButtonSave, SIGNAL( clicked() ), this, SLOT( slotSave() ) );
79  // ... delete
80  pqPushButtonDelete = new QPushButton( QIcon( ":icons/32x32/delete.png" ), "" );
81  pqPushButtonDelete->setMaximumSize( 36, 34 );
82  pqPushButtonDelete->setToolTip( tr("Delete this track") );
83  pqPushButtonDelete->setEnabled( false );
84  QWidget::connect( pqPushButtonDelete, SIGNAL( clicked() ), this, SLOT( slotDelete() ) );
85 
86  // Create layout
87  QVBoxLayout* __pqVBoxLayout = new QVBoxLayout();
88 
89  // Add header
90  QFont __qFontHeader;
91  __qFontHeader.setPixelSize( 16 );
92  __qFontHeader.setBold( true );
93  QHBoxLayout* __pqHBoxLayoutHeader = new QHBoxLayout();
94  QLabel* __pqLabelIcon = new QLabel();
95  __pqLabelIcon->setPixmap( QPixmap( ":icons/32x32/track.png" ) );
96  __pqLabelIcon->setToolTip( tr("Track") );
97  __pqHBoxLayoutHeader->addWidget( __pqLabelIcon, 0, Qt::AlignTop );
98  poTextName = new COverlayText();
99  poTextName->setToolTip( tr("Name") );
100  poTextName->setFont( __qFontHeader );
101  poTextName->setWordWrap( true );
102  __pqHBoxLayoutHeader->addWidget( poTextName, 1 );
103  __pqVBoxLayout->addLayout( __pqHBoxLayoutHeader );
104 
105  // Add data
106  QFont __qFontData;
107  QTabWidget* __poTabWidget = new QTabWidget();
108  __poTabWidget->setTabPosition( QTabWidget::South );
109  __poTabWidget->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
110 
111  // ... summary
112  QWidget* __poWidgetSummary = new QWidget();
113  QVBoxLayout* __pqVBoxLayoutSummary = new QVBoxLayout();
114  __qFontData.setPixelSize( 20 );
115  poTextContent = new COverlayText();
116  poTextContent->setToolTip( tr("Points count") );
117  poTextContent->setFont( __qFontData );
118  poTextContent->setIndent( 10 );
119  poTextContent->setAlignment( Qt::AlignHCenter );
121  __pqVBoxLayoutSummary->addWidget( poTextContent, 0 );
123  poTextLengthRL->setToolTip( tr("Length (rhumb-lines along track)") );
124  poTextLengthRL->setFont( __qFontData );
125  poTextLengthRL->setIndent( 10 );
126  poTextLengthRL->setAlignment( Qt::AlignHCenter );
128  __pqVBoxLayoutSummary->addWidget( poTextLengthRL, 0 );
130  poTextTimeElapsed->setToolTip( tr("Elapsed time") );
131  poTextTimeElapsed->setFont( __qFontData );
132  poTextTimeElapsed->setIndent( 10 );
133  poTextTimeElapsed->setAlignment( Qt::AlignHCenter );
135  __pqVBoxLayoutSummary->addWidget( poTextTimeElapsed, 1 );
136  __poWidgetSummary->setLayout( __pqVBoxLayoutSummary );
137  __poTabWidget->addTab( __poWidgetSummary, tr("Summary") );
138 
139  // ... info
140  QScrollArea* __poScrollAreaInfo = new QScrollArea();
141  __poScrollAreaInfo->setStyleSheet( ".QScrollArea, .QWidget { BACKGROUND-COLOR: rgba(0, 0, 0, 0); BORDER: none; }" );
142  __poScrollAreaInfo->setWidgetResizable( true );
143  QWidget* __poWidgetInfo = new QWidget();
144  QVBoxLayout* __pqVBoxLayoutInfo = new QVBoxLayout();
145  __qFontData.setPixelSize( 12 );
146  __qFontData.setBold( true );
147  poTextType = new COverlayText();
148  poTextType->setToolTip( tr("Type") );
149  poTextType->setFont( __qFontData );
150  poTextType->setIndent( 10 );
152  __pqVBoxLayoutInfo->addWidget( poTextType );
153  __qFontData.setBold( false );
155  poTextDescription->setToolTip( tr("Description") );
156  poTextDescription->setFont( __qFontData );
157  poTextDescription->setIndent( 10 );
159  __pqVBoxLayoutInfo->addWidget( poTextDescription );
160  __qFontData.setPixelSize( 10 );
161  poTextComment = new COverlayText();
162  poTextComment->setToolTip( tr("Comment") );
163  poTextComment->setFont( __qFontData );
164  poTextComment->setIndent( 10 );
166  __pqVBoxLayoutInfo->addWidget( poTextComment );
167  poUrl = new COverlayUrl();
168  poUrl->setToolTip( tr("URL") );
169  poUrl->setFont( __qFontData );
170  poUrl->setIndent( 10 );
171  poUrl->resetText();
172  __pqVBoxLayoutInfo->addWidget( poUrl, 1 );
173  __poWidgetInfo->setLayout( __pqVBoxLayoutInfo );
174  __poScrollAreaInfo->setWidget( __poWidgetInfo );
175  __poTabWidget->addTab( __poScrollAreaInfo, tr("Info") );
176 
177  // ... [end]
178  __pqVBoxLayout->addWidget( __poTabWidget, 1 );
179 
180  // Add separator
181  QFrame* __pqFrameSeparator = new QFrame();
182  __pqFrameSeparator->setFrameStyle( QFrame::HLine | QFrame::Sunken );
183  __pqVBoxLayout->addWidget( __pqFrameSeparator );
184 
185  // Add buttons
186  QHBoxLayout* __pqHBoxLayoutButtons = new QHBoxLayout();
187  __pqHBoxLayoutButtons->addWidget( pqPushButtonVisible, 0, Qt::AlignLeft );
188  __pqHBoxLayoutButtons->addWidget( pqPushButtonCenter, 1, Qt::AlignLeft );
189  __pqHBoxLayoutButtons->addWidget( pqPushButtonEdit, 0, Qt::AlignHCenter );
190  __pqHBoxLayoutButtons->addWidget( pqPushButtonSave, 0, Qt::AlignHCenter );
191  __pqHBoxLayoutButtons->addWidget( pqPushButtonDelete, 0, Qt::AlignHCenter );
192  __pqHBoxLayoutButtons->addWidget( new QLabel(), 1, Qt::AlignRight );
193  __pqVBoxLayout->addLayout( __pqHBoxLayoutButtons );
194 
195  // Set the layout
196  COverlayObjectDetailView::setLayout( __pqVBoxLayout );
197 
198 }
199 
200 
201 //------------------------------------------------------------------------------
202 // METHODS: COverlayObjectDetailView (implement/override)
203 //------------------------------------------------------------------------------
204 
206 {
207  if( !poOverlayObject ) return;
208  CTrackContainer* __poTrackContainer = (CTrackContainer*)poOverlayObject;
209  int __iCountPoints = 0;
210  int __iCount = __poTrackContainer->childCount();
211  for( int __i = 0; __i < __iCount; __i++ )
212  __iCountPoints += __poTrackContainer->child( __i )->childCount();
213  poTextName->setText( __poTrackContainer->getName() );
214  poTextContent->setText( QString::number( __iCountPoints )+" "+tr("Point(s)") );
215  poTextLengthRL->setText( CUnitDistance::toString( __poTrackContainer->getLengthRL() ) );
217  poTextType->setText( __poTrackContainer->getType() );
218  poTextDescription->setText( __poTrackContainer->getDescription() );
219  poTextComment->setText( __poTrackContainer->getComment() );
220  poUrl->setText( __poTrackContainer->getUrl() );
221 }
222 
224 {
232  poUrl->resetText();
233 }
234 
236 {
237  if( poOverlayObject )
238  {
239  pqPushButtonVisible->setEnabled( true );
240  pqPushButtonCenter->setEnabled( true );
241  pqPushButtonEdit->setEnabled( true );
242  pqPushButtonSave->setEnabled( true );
243  pqPushButtonDelete->setEnabled( true );
244  }
245 }
246 
248 {
249  pqPushButtonVisible->setEnabled( false );
250  pqPushButtonCenter->setEnabled( false );
251  pqPushButtonEdit->setEnabled( false );
252  pqPushButtonSave->setEnabled( false );
253  pqPushButtonDelete->setEnabled( false );
254 }
255 
256 
257 //------------------------------------------------------------------------------
258 // METHODS
259 //------------------------------------------------------------------------------
260 
261 //
262 // SLOTS
263 //
264 
266 {
267  if( !poOverlayObject ) return;
268  CTrackContainer* __poTrackContainer = (CTrackContainer*)poOverlayObject;
269  bool __bVisible = __poTrackContainer->isVisible();
270  __poTrackContainer->toggleVisibility();
271  if( __bVisible != __poTrackContainer->isVisible() )
272  {
273  __poTrackContainer->setCheckState( CTrackOverlay::VISIBLE, __bVisible ? Qt::Unchecked : Qt::Checked );
274  }
275  __poTrackContainer->useOverlay()->forceRedraw();
277 }
278 
280 {
281  if( !poOverlayObject ) return;
282  CDataPosition __oDataPositionLower( 180, 90, 999999 ), __oDataPositionUpper( -180, -90, -999999 );
283  int __iCountBox = 0;
284  int __iCount = poOverlayObject->childCount();
285  for( int __i = 0; __i < __iCount; __i++ )
286  {
287  CDataPosition __oDataPositionLower_aux, __oDataPositionUpper_aux;
288  int __iCountBox_aux = COverlayPoint::getPositionBox( (COverlayObject*)poOverlayObject->child( __i ), &__oDataPositionLower_aux, &__oDataPositionUpper_aux );
289  if( __iCountBox_aux )
290  {
291  __iCountBox += __iCountBox_aux;
292  __oDataPositionLower.setPosition( std::min( __oDataPositionLower.getLongitude(), __oDataPositionLower_aux.getLongitude() ),
293  std::min( __oDataPositionLower.getLatitude(), __oDataPositionLower_aux.getLatitude() ),
294  std::min( __oDataPositionLower.getElevation(), __oDataPositionLower_aux.getElevation() ) );
295  __oDataPositionUpper.setPosition( std::max( __oDataPositionUpper.getLongitude(), __oDataPositionUpper_aux.getLongitude() ),
296  std::max( __oDataPositionUpper.getLatitude(), __oDataPositionUpper_aux.getLatitude() ),
297  std::max( __oDataPositionUpper.getElevation(), __oDataPositionUpper_aux.getElevation() ) );
298  }
299  }
300  if( __iCountBox > 1 ) QVCTRuntime::useChartTable()->setScaleArea( __oDataPositionLower, __oDataPositionUpper, 0.9 );
301  else if( __iCountBox == 1 ) QVCTRuntime::useChartTable()->setGeoPosition( __oDataPositionLower );
303 }
304 
306 {
307  if( !poOverlayObject ) return;
308  ((CTrackContainer*)poOverlayObject)->showEdit();
310 }
311 
313 {
314  if( !poOverlayObject ) return;
315  QString __qsFilename = QVCTRuntime::useMainWindow()->fileDialog( QVCT::SAVE, tr("Save Track"), tr("GPX Files")+" (*.gpx);;"+tr("QVCT Files")+" (*.qvct)" );
316  if( __qsFilename.isEmpty() ) return;
317  QFileInfo __qFileInfo( __qsFilename );
318  if( __qFileInfo.suffix().isEmpty() ) __qsFilename += ".qvct";
319  QStringList __qsListExtensions; __qsListExtensions << "qvct" << "gpx";
320  if( !QVCTRuntime::useMainWindow()->fileCheck( QVCT::SAVE, __qsFilename, &__qsListExtensions ) ) return;
322 }
323 
325 {
326  if( !poOverlayObject ) return;
327  if( !QVCTRuntime::useMainWindow()->deleteConfirm( poOverlayObject->getName() ) ) return;
328  QMutex* __pqMutexDataChange = QVCTRuntime::useMutexDataChange();
329  CTrackOverlay* __poTrackOverlay = (CTrackOverlay*)poOverlayObject->useOverlay();
330  CTrackContainer* __poTrackContainer = (CTrackContainer*)poOverlayObject;
331  __pqMutexDataChange->lock();
332  __poTrackOverlay->removeChild( __poTrackContainer );
333  __pqMutexDataChange->unlock();
334  delete __poTrackContainer;
335  QTreeWidgetItem* __pqTreeWidgetItem = __poTrackOverlay->currentItem();
336  if( __pqTreeWidgetItem ) __poTrackOverlay->showDetail( __pqTreeWidgetItem );
337  __poTrackOverlay->forceRedraw();
340 }
void setProjectModified()
Sets the status of the project to modified (data have changed and need saving)
void setScaleArea(const CDataPosition &_roGeoPosition1, const CDataPosition &_roGeoPosition2, double _fdScaleCorrection=1.0)
Sets the reference scale factor to display the given (geographical) area (defined by its opposite cor...
void updateChart()
Update the (current) chart content (on screen)
void setGeoPosition(const CDataPosition &_roGeoPosition, bool _bSkipCurrent=false)
Sets the reference chart (geographical) position.
(Geographical) Position data [long,lat,elev]
double getLongitude() const
Returns this position's longitude, in degrees.
double getElevation() const
Returns this position's elevation, in meters.
double getLatitude() const
Returns this position's latitude, in degrees.
void setPosition(double _fdLongitude, double _fdLatitude, double _fdElevation=UNDEFINED_ELEVATION)
Sets new coordinates.
QString fileDialog(QVCT::EFileOperation _eFileOperation, const QString &_rqsTitle, const QString &_rqsFilter)
Displays a generic dialog to pick a file for the given operation (open/save)
[UI] Generic overlay object's detail view
COverlayObject * poOverlayObject
Overlay object being displayed.
Generic overlay object.
virtual COverlay * useOverlay()=0
Returns this object's (base) overlay.
QString getName() const
Returns this object's name.
static int getPositionBox(const QTreeWidgetItem *_pqTreeWidgetItem, CDataPosition *_poDataPositionLower, CDataPosition *_poDataPositionUpper, int _iIndexMin=0, int _iIndexMax=-1)
Returns the minimal geographical positions box containing the points in the given overlay/container.
[UI] Overlay-specific text label
void setText(const QString &_rqsText)
[override] QLabel::setText( const QString& )
void resetText()
Resets (clears) the underlying QLabel's text.
[UI] Overlay-specific URL label
Definition: COverlayUrl.hpp:36
void setText(const QString &_rqsText)
Definition: COverlayUrl.cpp:51
bool isVisible() const
Returns the point's (marker) visibility status.
void forceRedraw()
Forces this overlay's rendering (not matter its cache content)
Definition: COverlay.hpp:115
virtual void disableContent()
Disables the content (controls) of the underlying widget.
COverlayText * poTextDescription
[UI:Label] Description
virtual void refreshContent()
Refreshes the content of the underlying widget.
COverlayText * poTextType
[UI:Label] Type
virtual void enableContent()
Enables the content (controls) of the underlying widget.
COverlayText * poTextContent
[UI:Label] Content (items summary)
void slotSave()
[UI:Slot] Slot to save this container to file
COverlayUrl * poUrl
[UI:Label] URL
void slotEdit()
[UI:Slot] Slot to display edit view
QPushButton * pqPushButtonVisible
[UI:Button] Visibility status
void constructLayout()
Constructs the layout of the user-interface.
COverlayText * poTextName
[UI:Label] Name
COverlayText * poTextLengthRL
[UI:Label] Length (rhumb-line)
QPushButton * pqPushButtonCenter
[UI:Button] Center (on chart)
virtual void resetContent()
Resets (clears) the content of the underlying widget.
void slotDelete()
[UI:Slot] Slot to delete (this container)
COverlayText * poTextComment
[UI:Label] Comment
QPushButton * pqPushButtonSave
[UI:Button] Save
COverlayText * poTextTimeElapsed
[UI:Label] Elapsed time
QPushButton * pqPushButtonEdit
[UI:Button] Edit
void slotToggleVisible()
[UI:Slot] Slot to modify the visibility status
QPushButton * pqPushButtonDelete
[UI:Button] Delete
void slotPositionCenter()
[UI:Slot] Slot to center chart (on container's items position)
CTrackContainerDetailView(QWidget *_pqParent=0)
[UI] Track overlay container
QString getUrl() const
Returns this track's URL.
QString getType() const
Returns this track's type.
QString getDescription() const
Returns this track's description.
virtual void toggleVisibility()
double getLengthRL()
Returns the track's (rhumb-line) length.
virtual COverlay * useOverlay()
Returns this object's (base) overlay.
double getTimeElapsed()
Returns the track's elapsed time.
QString getComment() const
Returns this track's comment.
[UI] Track overlay container
@ VISIBLE
Track visibility status.
virtual void showDetail(const QTreeWidgetItem *_pqTreeWidgetItem) const
Displays the given overlay object's details (in the appropriate widget/view)
void save(const QString &_rqsFilename, CTrackContainer *_poTrackContainer=0) const
Save this object's content (container) to the given file (all selected items if no container is given...
static QString toString(double _fdValue, EUnit _eUnit, int _iPrecision=0)
Returns the formatted represention of the given value, using the specified format/unit and decimal pr...
static QString toString(double _fdValue, EUnit _eUnit, int _iPrecision=0)
Returns the formatted represention of the given value, using the specified format/unit and decimal pr...
static QMutex * useMutexDataChange()
static CMainWindow * useMainWindow()
static CChartTable * useChartTable()
static CTrackOverlay * useTrackOverlay()
@ SAVE
Definition: QVCT.hpp:42