1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2013 Mihail Ivchenko <ematirov@gmail.com>
4 // SPDX-FileCopyrightText: 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
5 // SPDX-FileCopyrightText: 2014 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
6 //
7 
8 #include "FlyToEditWidget.h"
9 
10 #include <QDoubleSpinBox>
11 #include <QToolButton>
12 #include <QLabel>
13 #include <QHBoxLayout>
14 #include <QComboBox>
15 
16 #include "MarbleWidget.h"
17 #include "geodata/data/GeoDataFlyTo.h"
18 #include "GeoDataLookAt.h"
19 #include "GeoDataCamera.h"
20 #include "MarblePlacemarkModel.h"
21 
22 namespace Marble
23 {
24 
FlyToEditWidget(const QModelIndex & index,MarbleWidget * widget,QWidget * parent)25 FlyToEditWidget::FlyToEditWidget( const QModelIndex &index, MarbleWidget* widget, QWidget *parent ) :
26     QWidget( parent ),
27     m_widget( widget ),
28     m_index( index ),
29     m_button( new QToolButton )
30 {
31     QHBoxLayout *layout = new QHBoxLayout;
32     layout->setSpacing( 5 );
33 
34     QLabel* iconLabel = new QLabel;
35     iconLabel->setPixmap(QPixmap(QStringLiteral(":/marble/flag.png")));
36     layout->addWidget( iconLabel );
37 
38     QHBoxLayout *pairLayout = new QHBoxLayout;
39     pairLayout->setSpacing( 10 );
40 
41     QHBoxLayout *durationLayout = new QHBoxLayout;
42     durationLayout->setSpacing( 5 );
43 
44     QLabel *durationLabel = new QLabel;
45     durationLabel->setText( tr("Duration:") );
46     durationLayout->addWidget( durationLabel );
47 
48     m_durationSpin = new QDoubleSpinBox;
49     durationLayout->addWidget( m_durationSpin );
50     m_durationSpin->setValue( flyToElement()->duration() );
51     m_durationSpin->setSuffix( tr(" s", "seconds") );
52 
53     QHBoxLayout *modeLayout = new QHBoxLayout;
54     modeLayout->addSpacing( 5 );
55 
56     QLabel *modeLabel = new QLabel;
57     modeLabel->setText( tr("Mode:") );
58     modeLayout->addWidget( modeLabel );
59 
60     m_modeCombo = new QComboBox;
61     modeLayout->addWidget( m_modeCombo );
62     m_modeCombo->addItem( tr("Smooth") );
63     m_modeCombo->addItem( tr("Bounce") );
64 
65     if( flyToElement()->flyToMode() == GeoDataFlyTo::Smooth ){
66         m_modeCombo->setCurrentIndex( 0 );
67     } else if( flyToElement()->flyToMode() == GeoDataFlyTo::Bounce ){
68         m_modeCombo->setCurrentIndex( 1 );
69     } else {
70         m_modeCombo->setCurrentIndex( -1 );
71     }
72 
73     pairLayout->addLayout( durationLayout );
74     pairLayout->addLayout( modeLayout );
75 
76     layout->addLayout( pairLayout );
77 
78     QToolButton* flyToPinCenter = new QToolButton;
79     flyToPinCenter->setIcon(QIcon(QStringLiteral(":/marble/places.png")));
80     flyToPinCenter->setToolTip(tr("Current map center"));
81     connect(flyToPinCenter, SIGNAL(clicked()), this, SLOT(updateCoordinates()));
82     layout->addWidget(flyToPinCenter);
83 
84     m_button->setIcon(QIcon(QStringLiteral(":/marble/document-save.png")));
85     connect(m_button, SIGNAL(clicked()), this, SLOT(save()));
86     layout->addWidget( m_button );
87 
88     setLayout( layout );
89 }
90 
editable() const91 bool FlyToEditWidget::editable() const
92 {
93     return m_button->isEnabled();
94 }
95 
setEditable(bool editable)96 void FlyToEditWidget::setEditable( bool editable )
97 {
98     m_button->setEnabled( editable );
99 }
100 
setFirstFlyTo(const QPersistentModelIndex & index)101 void FlyToEditWidget::setFirstFlyTo(const QPersistentModelIndex &index)
102 {
103     if( m_index.internalPointer() == index.internalPointer() ) {
104         m_durationSpin->setValue(0);
105     }
106 }
107 
updateCoordinates()108 void FlyToEditWidget::updateCoordinates()
109 {
110     m_coord = m_widget->focusPoint();
111     m_coord.setAltitude( m_widget->lookAt().range() );
112 }
113 
save()114 void FlyToEditWidget::save()
115 {
116     if (flyToElement()->view() != nullptr && m_coord != GeoDataCoordinates()) {
117         GeoDataCoordinates coords = m_coord;
118         if (auto camera = geodata_cast<GeoDataCamera>(flyToElement()->view())) {
119             camera->setCoordinates( coords );
120         } else if (auto lookAt = geodata_cast<GeoDataLookAt>(flyToElement()->view())) {
121             lookAt->setCoordinates( coords );
122         } else{
123             lookAt = new GeoDataLookAt;
124             lookAt->setCoordinates( coords );
125             flyToElement()->setView( lookAt );
126         }
127     }
128 
129     flyToElement()->setDuration(m_durationSpin->value());
130 
131     if (m_modeCombo->currentIndex() == 0) {
132         flyToElement()->setFlyToMode( GeoDataFlyTo::Smooth );
133     } else if (m_modeCombo->currentIndex() == 1) {
134         flyToElement()->setFlyToMode( GeoDataFlyTo::Bounce );
135     }
136 
137     emit editingDone(m_index);
138 }
139 
flyToElement()140 GeoDataFlyTo* FlyToEditWidget::flyToElement()
141 {
142     GeoDataObject *object = qvariant_cast<GeoDataObject*>(m_index.data( MarblePlacemarkModel::ObjectPointerRole ) );
143     Q_ASSERT( object );
144     auto flyTo = geodata_cast<GeoDataFlyTo>(object);
145     Q_ASSERT(flyTo);
146     return flyTo;
147 }
148 
149 } // namespace Marble
150 
151 #include "moc_FlyToEditWidget.cpp"
152