Marble

PlaybackAnimatedUpdateItem.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2014 Sanjiban Bairagya <[email protected]>
4 //
5 
6 #include "PlaybackAnimatedUpdateItem.h"
7 
8 #include "GeoDataAnimatedUpdate.h"
9 #include "GeoDataDocument.h"
10 #include "GeoDataPlacemark.h"
11 #include "GeoDataCreate.h"
12 #include "GeoDataUpdate.h"
13 #include "GeoDataDelete.h"
14 #include "GeoDataChange.h"
15 #include "GeoDataFolder.h"
16 #include "GeoDataGroundOverlay.h"
17 #include "GeoDataPhotoOverlay.h"
18 #include "GeoDataScreenOverlay.h"
19 
20 #include <QString>
21 
22 namespace Marble
23 {
24 PlaybackAnimatedUpdateItem::PlaybackAnimatedUpdateItem( GeoDataAnimatedUpdate* animatedUpdate )
25 {
26  m_animatedUpdate = animatedUpdate;
27  m_rootDocument = rootDocument( m_animatedUpdate );
28  m_playing = false;
29 }
30 
31 const GeoDataAnimatedUpdate* PlaybackAnimatedUpdateItem::animatedUpdate() const
32 {
33  return m_animatedUpdate;
34 }
35 
36 double PlaybackAnimatedUpdateItem::duration() const
37 {
38  return m_animatedUpdate->duration();
39 }
40 
41 void PlaybackAnimatedUpdateItem::play()
42 {
43  if( m_playing ){
44  return;
45  }
46  m_playing = true;
47 
48  if ( !m_rootDocument || !m_animatedUpdate->update() ) {
49  return;
50  }
51 
52  // Apply updates of elements
53  if ( m_animatedUpdate->update()->change() ) {
54  QVector<GeoDataPlacemark*> placemarkList = m_animatedUpdate->update()->change()->placemarkList();
55  for( int i = 0; i < placemarkList.size(); i++ ){
56  GeoDataPlacemark* placemark = placemarkList.at( i );
57  QString targetId = placemark->targetId();
58  if( targetId.isEmpty() ) {
59  continue;
60  }
61  if( placemark->isBalloonVisible() ){
62  GeoDataFeature* feature = findFeature( m_rootDocument, targetId );
63  if (auto placemark = geodata_cast<GeoDataPlacemark>(feature)) {
64  emit balloonShown(placemark);
65  }
66  } else {
67  emit balloonHidden();
68  }
69  }
70  }
71 
72  // Create new elements
73  if( m_animatedUpdate->update()->create() ){
74  for( int index = 0; index < m_animatedUpdate->update()->create()->size(); ++index ) {
75  GeoDataFeature* child = m_animatedUpdate->update()->create()->child( index );
76  if( child &&
77  (geodata_cast<GeoDataDocument>(child)||
78  geodata_cast<GeoDataFolder>(child))) {
79  GeoDataContainer *addContainer = static_cast<GeoDataContainer*>( child );
80  QString targetId = addContainer->targetId();
81  GeoDataFeature* feature = findFeature( m_rootDocument, targetId );
82  if( feature &&
83  (geodata_cast<GeoDataDocument>(feature) ||
84  geodata_cast<GeoDataFolder>(feature))) {
85  GeoDataContainer* container = static_cast<GeoDataContainer*>( feature );
86  for( int i = 0; i < addContainer->size(); ++i ) {
87  emit added( container, addContainer->child( i ), -1 );
88  if (auto placemark = geodata_cast<GeoDataPlacemark>(addContainer->child(i)))
89  {
90  if( placemark->isBalloonVisible() ) {
91  emit balloonShown( placemark );
92  }
93  }
94  }
95  }
96 
97  }
98  }
99  }
100 
101  // Delete elements
102  if( m_animatedUpdate->update()->getDelete() ){
103  for( int index = 0; index < m_animatedUpdate->update()->getDelete()->size(); ++index ) {
104  GeoDataFeature* child = m_animatedUpdate->update()->getDelete()->child( index );
105  QString targetId = child->targetId();
106  if( targetId.isEmpty() ) {
107  continue;
108  }
109  GeoDataFeature* feature = findFeature( m_rootDocument, targetId );
110  if (feature && canDelete(*feature)) {
111  m_deletedObjects.append( feature );
112  emit removed( feature );
113  if (auto placemark = geodata_cast<GeoDataPlacemark>(feature))
114  {
115  if( placemark->isBalloonVisible() ) {
116  emit balloonHidden();
117  }
118  }
119  }
120  }
121  }
122 }
123 
124 GeoDataFeature* PlaybackAnimatedUpdateItem::findFeature(GeoDataFeature* feature, const QString& id ) const
125 {
126  if ( feature && feature->id() == id ){
127  return feature;
128  }
129 
130  GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( feature );
131  if ( container ){
132  QVector<GeoDataFeature*>::Iterator end = container->end();
133  QVector<GeoDataFeature*>::Iterator iter = container->begin();
134  for( ; iter != end; ++iter ){
135  GeoDataFeature *foundFeature = findFeature( *iter, id );
136  if ( foundFeature ){
137  return foundFeature;
138  }
139  }
140  }
141  return nullptr;
142 }
143 
144 GeoDataDocument *PlaybackAnimatedUpdateItem::rootDocument( GeoDataObject* object ) const
145 {
146  if( !object || !object->parent() ){
147  GeoDataDocument* document = dynamic_cast<GeoDataDocument*>( object );
148  return document;
149  } else {
150  return rootDocument( object->parent() );
151  }
152  return nullptr;
153 }
154 
156 {
157  //do nothing
158 }
159 
160 void PlaybackAnimatedUpdateItem::seek( double position )
161 {
162  Q_UNUSED( position );
163  play();
164 }
165 
167 {
168  if( !m_playing ){
169  return;
170  }
171  m_playing = false;
172 
173  if ( m_animatedUpdate->update()->change() ) {
174  QVector<GeoDataPlacemark*> placemarkList = m_animatedUpdate->update()->change()->placemarkList();
175  for( int i = 0; i < placemarkList.size(); i++ ){
176  GeoDataPlacemark* placemark = placemarkList.at( i );
177  QString targetId = placemark->targetId();
178  if( targetId.isEmpty() ) {
179  continue;
180  }
181  GeoDataFeature* feature = findFeature( m_rootDocument, targetId );
182  if( placemark->isBalloonVisible() ){
183  if (geodata_cast<GeoDataPlacemark>(feature)) {
184  emit balloonHidden();
185  }
186  } else {
187  emit balloonShown( static_cast<GeoDataPlacemark*>( feature ) );
188  }
189  }
190  }
191 
192  if( m_animatedUpdate->update()->create() ){
193  for( int index = 0; index < m_animatedUpdate->update()->create()->size(); ++index ) {
194  GeoDataFeature* feature = m_animatedUpdate->update()->create()->child( index );
195  if( feature &&
196  (geodata_cast<GeoDataDocument>(feature) ||
197  geodata_cast<GeoDataFolder>(feature))) {
198  GeoDataContainer* container = static_cast<GeoDataContainer*>( feature );
199  for( int i = 0; i < container->size(); ++i ) {
200 
201  emit removed( container->child( i ) );
202  if (auto placemark = geodata_cast<GeoDataPlacemark>(container->child(i)))
203  {
204  if( placemark->isBalloonVisible() ) {
205  emit balloonHidden();
206  }
207  }
208  }
209  }
210  }
211  }
212 
213  for( GeoDataFeature* feature: m_deletedObjects ) {
214  if( feature->targetId().isEmpty() ) {
215  continue;
216  }
217  GeoDataFeature* target = findFeature( m_rootDocument, feature->targetId() );
218  if ( target ) {
219  /** @todo Do we have to note the original row position and restore it? */
220  Q_ASSERT( dynamic_cast<GeoDataContainer*>( target ) );
221  emit added( static_cast<GeoDataContainer*>( target ), feature, -1 );
222  if (auto placemark = geodata_cast<GeoDataPlacemark>(feature))
223  {
224  if( placemark->isBalloonVisible() ) {
225  emit balloonShown( placemark );
226  }
227  }
228  } // else the root document was modified in an unfortunate way and we cannot restore it at this point
229  }
230  m_deletedObjects.clear();
231 }
232 
233 bool PlaybackAnimatedUpdateItem::isApplied() const
234 {
235  return m_playing;
236 }
237 
238 bool PlaybackAnimatedUpdateItem::canDelete(const GeoDataFeature &feature)
239 {
240  return geodata_cast<GeoDataDocument>(&feature) ||
241  geodata_cast<GeoDataFolder>(&feature) ||
242  geodata_cast<GeoDataGroundOverlay>(&feature) ||
243  geodata_cast<GeoDataPlacemark>(&feature) ||
244  geodata_cast<GeoDataScreenOverlay>(&feature) ||
245  geodata_cast<GeoDataPhotoOverlay>(&feature);
246 }
247 
248 }
249 
250 #include "moc_PlaybackAnimatedUpdateItem.cpp"
void stop(Ekos::AlignState mode)
QVector::iterator begin()
const T & at(int i) const const
bool isEmpty() const const
Q_SCRIPTABLE Q_NOREPLY void pause()
Binds a QML item to a specific geodetic location in screen coordinates.
QAction * create(StandardGameAction id, const QObject *recvr, const char *slot, QObject *parent)
int size() const const
const QList< QKeySequence > & end()
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Sep 25 2023 03:50:20 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.