File indexing completed on 2024-03-24 03:52:37
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2014 Sanjiban Bairagya <sanjiban22393@gmail.com> 0004 // 0005 0006 #include "PlaybackAnimatedUpdateItem.h" 0007 0008 #include "GeoDataAnimatedUpdate.h" 0009 #include "GeoDataDocument.h" 0010 #include "GeoDataPlacemark.h" 0011 #include "GeoDataCreate.h" 0012 #include "GeoDataUpdate.h" 0013 #include "GeoDataDelete.h" 0014 #include "GeoDataChange.h" 0015 #include "GeoDataFolder.h" 0016 #include "GeoDataGroundOverlay.h" 0017 #include "GeoDataPhotoOverlay.h" 0018 #include "GeoDataScreenOverlay.h" 0019 0020 #include <QString> 0021 0022 namespace Marble 0023 { 0024 PlaybackAnimatedUpdateItem::PlaybackAnimatedUpdateItem( GeoDataAnimatedUpdate* animatedUpdate ) 0025 { 0026 m_animatedUpdate = animatedUpdate; 0027 m_rootDocument = rootDocument( m_animatedUpdate ); 0028 m_playing = false; 0029 } 0030 0031 const GeoDataAnimatedUpdate* PlaybackAnimatedUpdateItem::animatedUpdate() const 0032 { 0033 return m_animatedUpdate; 0034 } 0035 0036 double PlaybackAnimatedUpdateItem::duration() const 0037 { 0038 return m_animatedUpdate->duration(); 0039 } 0040 0041 void PlaybackAnimatedUpdateItem::play() 0042 { 0043 if( m_playing ){ 0044 return; 0045 } 0046 m_playing = true; 0047 0048 if ( !m_rootDocument || !m_animatedUpdate->update() ) { 0049 return; 0050 } 0051 0052 // Apply updates of elements 0053 if ( m_animatedUpdate->update()->change() ) { 0054 QVector<GeoDataPlacemark*> placemarkList = m_animatedUpdate->update()->change()->placemarkList(); 0055 for( int i = 0; i < placemarkList.size(); i++ ){ 0056 GeoDataPlacemark* placemark = placemarkList.at( i ); 0057 QString targetId = placemark->targetId(); 0058 if( targetId.isEmpty() ) { 0059 continue; 0060 } 0061 if( placemark->isBalloonVisible() ){ 0062 GeoDataFeature* feature = findFeature( m_rootDocument, targetId ); 0063 if (auto placemark = geodata_cast<GeoDataPlacemark>(feature)) { 0064 emit balloonShown(placemark); 0065 } 0066 } else { 0067 emit balloonHidden(); 0068 } 0069 } 0070 } 0071 0072 // Create new elements 0073 if( m_animatedUpdate->update()->create() ){ 0074 for( int index = 0; index < m_animatedUpdate->update()->create()->size(); ++index ) { 0075 GeoDataFeature* child = m_animatedUpdate->update()->create()->child( index ); 0076 if( child && 0077 (geodata_cast<GeoDataDocument>(child)|| 0078 geodata_cast<GeoDataFolder>(child))) { 0079 GeoDataContainer *addContainer = static_cast<GeoDataContainer*>( child ); 0080 QString targetId = addContainer->targetId(); 0081 GeoDataFeature* feature = findFeature( m_rootDocument, targetId ); 0082 if( feature && 0083 (geodata_cast<GeoDataDocument>(feature) || 0084 geodata_cast<GeoDataFolder>(feature))) { 0085 GeoDataContainer* container = static_cast<GeoDataContainer*>( feature ); 0086 for( int i = 0; i < addContainer->size(); ++i ) { 0087 emit added( container, addContainer->child( i ), -1 ); 0088 if (auto placemark = geodata_cast<GeoDataPlacemark>(addContainer->child(i))) 0089 { 0090 if( placemark->isBalloonVisible() ) { 0091 emit balloonShown( placemark ); 0092 } 0093 } 0094 } 0095 } 0096 0097 } 0098 } 0099 } 0100 0101 // Delete elements 0102 if( m_animatedUpdate->update()->getDelete() ){ 0103 for( int index = 0; index < m_animatedUpdate->update()->getDelete()->size(); ++index ) { 0104 GeoDataFeature* child = m_animatedUpdate->update()->getDelete()->child( index ); 0105 QString targetId = child->targetId(); 0106 if( targetId.isEmpty() ) { 0107 continue; 0108 } 0109 GeoDataFeature* feature = findFeature( m_rootDocument, targetId ); 0110 if (feature && canDelete(*feature)) { 0111 m_deletedObjects.append( feature ); 0112 emit removed( feature ); 0113 if (auto placemark = geodata_cast<GeoDataPlacemark>(feature)) 0114 { 0115 if( placemark->isBalloonVisible() ) { 0116 emit balloonHidden(); 0117 } 0118 } 0119 } 0120 } 0121 } 0122 } 0123 0124 GeoDataFeature* PlaybackAnimatedUpdateItem::findFeature(GeoDataFeature* feature, const QString& id ) const 0125 { 0126 if ( feature && feature->id() == id ){ 0127 return feature; 0128 } 0129 0130 GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( feature ); 0131 if ( container ){ 0132 QVector<GeoDataFeature*>::Iterator end = container->end(); 0133 QVector<GeoDataFeature*>::Iterator iter = container->begin(); 0134 for( ; iter != end; ++iter ){ 0135 GeoDataFeature *foundFeature = findFeature( *iter, id ); 0136 if ( foundFeature ){ 0137 return foundFeature; 0138 } 0139 } 0140 } 0141 return nullptr; 0142 } 0143 0144 GeoDataDocument *PlaybackAnimatedUpdateItem::rootDocument( GeoDataObject* object ) const 0145 { 0146 if( !object || !object->parent() ){ 0147 GeoDataDocument* document = dynamic_cast<GeoDataDocument*>( object ); 0148 return document; 0149 } else { 0150 return rootDocument( object->parent() ); 0151 } 0152 return nullptr; 0153 } 0154 0155 void PlaybackAnimatedUpdateItem::pause() 0156 { 0157 //do nothing 0158 } 0159 0160 void PlaybackAnimatedUpdateItem::seek( double position ) 0161 { 0162 Q_UNUSED( position ); 0163 play(); 0164 } 0165 0166 void PlaybackAnimatedUpdateItem::stop() 0167 { 0168 if( !m_playing ){ 0169 return; 0170 } 0171 m_playing = false; 0172 0173 if ( m_animatedUpdate->update()->change() ) { 0174 QVector<GeoDataPlacemark*> placemarkList = m_animatedUpdate->update()->change()->placemarkList(); 0175 for( int i = 0; i < placemarkList.size(); i++ ){ 0176 GeoDataPlacemark* placemark = placemarkList.at( i ); 0177 QString targetId = placemark->targetId(); 0178 if( targetId.isEmpty() ) { 0179 continue; 0180 } 0181 GeoDataFeature* feature = findFeature( m_rootDocument, targetId ); 0182 if( placemark->isBalloonVisible() ){ 0183 if (geodata_cast<GeoDataPlacemark>(feature)) { 0184 emit balloonHidden(); 0185 } 0186 } else { 0187 emit balloonShown( static_cast<GeoDataPlacemark*>( feature ) ); 0188 } 0189 } 0190 } 0191 0192 if( m_animatedUpdate->update()->create() ){ 0193 for( int index = 0; index < m_animatedUpdate->update()->create()->size(); ++index ) { 0194 GeoDataFeature* feature = m_animatedUpdate->update()->create()->child( index ); 0195 if( feature && 0196 (geodata_cast<GeoDataDocument>(feature) || 0197 geodata_cast<GeoDataFolder>(feature))) { 0198 GeoDataContainer* container = static_cast<GeoDataContainer*>( feature ); 0199 for( int i = 0; i < container->size(); ++i ) { 0200 0201 emit removed( container->child( i ) ); 0202 if (auto placemark = geodata_cast<GeoDataPlacemark>(container->child(i))) 0203 { 0204 if( placemark->isBalloonVisible() ) { 0205 emit balloonHidden(); 0206 } 0207 } 0208 } 0209 } 0210 } 0211 } 0212 0213 for( GeoDataFeature* feature: m_deletedObjects ) { 0214 if( feature->targetId().isEmpty() ) { 0215 continue; 0216 } 0217 GeoDataFeature* target = findFeature( m_rootDocument, feature->targetId() ); 0218 if ( target ) { 0219 /** @todo Do we have to note the original row position and restore it? */ 0220 Q_ASSERT( dynamic_cast<GeoDataContainer*>( target ) ); 0221 emit added( static_cast<GeoDataContainer*>( target ), feature, -1 ); 0222 if (auto placemark = geodata_cast<GeoDataPlacemark>(feature)) 0223 { 0224 if( placemark->isBalloonVisible() ) { 0225 emit balloonShown( placemark ); 0226 } 0227 } 0228 } // else the root document was modified in an unfortunate way and we cannot restore it at this point 0229 } 0230 m_deletedObjects.clear(); 0231 } 0232 0233 bool PlaybackAnimatedUpdateItem::isApplied() const 0234 { 0235 return m_playing; 0236 } 0237 0238 bool PlaybackAnimatedUpdateItem::canDelete(const GeoDataFeature &feature) 0239 { 0240 return geodata_cast<GeoDataDocument>(&feature) || 0241 geodata_cast<GeoDataFolder>(&feature) || 0242 geodata_cast<GeoDataGroundOverlay>(&feature) || 0243 geodata_cast<GeoDataPlacemark>(&feature) || 0244 geodata_cast<GeoDataScreenOverlay>(&feature) || 0245 geodata_cast<GeoDataPhotoOverlay>(&feature); 0246 } 0247 0248 } 0249 0250 #include "moc_PlaybackAnimatedUpdateItem.cpp"