Marble

PlaybackAnimatedUpdateItem.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2014 Sanjiban Bairagya <sanjiban22393@gmail.com>
4//
5
6#include "PlaybackAnimatedUpdateItem.h"
7
8#include "GeoDataAnimatedUpdate.h"
9#include "GeoDataChange.h"
10#include "GeoDataCreate.h"
11#include "GeoDataDelete.h"
12#include "GeoDataDocument.h"
13#include "GeoDataFolder.h"
14#include "GeoDataGroundOverlay.h"
15#include "GeoDataPhotoOverlay.h"
16#include "GeoDataPlacemark.h"
17#include "GeoDataScreenOverlay.h"
18#include "GeoDataUpdate.h"
19
20#include <QString>
21
22namespace Marble
23{
24PlaybackAnimatedUpdateItem::PlaybackAnimatedUpdateItem(GeoDataAnimatedUpdate *animatedUpdate)
25{
26 m_animatedUpdate = animatedUpdate;
27 m_rootDocument = rootDocument(m_animatedUpdate);
28 m_playing = false;
29}
30
31const GeoDataAnimatedUpdate *PlaybackAnimatedUpdateItem::animatedUpdate() const
32{
33 return m_animatedUpdate;
34}
35
36double PlaybackAnimatedUpdateItem::duration() const
37{
38 return m_animatedUpdate->duration();
39}
40
41void 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 QList<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 Q_EMIT balloonShown(placemark);
65 }
66 } else {
67 Q_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 && (geodata_cast<GeoDataDocument>(child) || geodata_cast<GeoDataFolder>(child))) {
77 auto addContainer = static_cast<GeoDataContainer *>(child);
78 QString targetId = addContainer->targetId();
79 GeoDataFeature *feature = findFeature(m_rootDocument, targetId);
80 if (feature && (geodata_cast<GeoDataDocument>(feature) || geodata_cast<GeoDataFolder>(feature))) {
81 auto container = static_cast<GeoDataContainer *>(feature);
82 for (int i = 0; i < addContainer->size(); ++i) {
83 Q_EMIT added(container, addContainer->child(i), -1);
84 if (auto placemark = geodata_cast<GeoDataPlacemark>(addContainer->child(i))) {
85 if (placemark->isBalloonVisible()) {
86 Q_EMIT balloonShown(placemark);
87 }
88 }
89 }
90 }
91 }
92 }
93 }
94
95 // Delete elements
96 if (m_animatedUpdate->update()->getDelete()) {
97 for (int index = 0; index < m_animatedUpdate->update()->getDelete()->size(); ++index) {
98 GeoDataFeature *child = m_animatedUpdate->update()->getDelete()->child(index);
99 QString targetId = child->targetId();
100 if (targetId.isEmpty()) {
101 continue;
102 }
103 GeoDataFeature *feature = findFeature(m_rootDocument, targetId);
104 if (feature && canDelete(*feature)) {
105 m_deletedObjects.append(feature);
106 Q_EMIT removed(feature);
107 if (auto placemark = geodata_cast<GeoDataPlacemark>(feature)) {
108 if (placemark->isBalloonVisible()) {
109 Q_EMIT balloonHidden();
110 }
111 }
112 }
113 }
114 }
115}
116
117GeoDataFeature *PlaybackAnimatedUpdateItem::findFeature(GeoDataFeature *feature, const QString &id) const
118{
119 if (feature && feature->id() == id) {
120 return feature;
121 }
122
123 auto container = dynamic_cast<GeoDataContainer *>(feature);
124 if (container) {
125 QList<GeoDataFeature *>::Iterator end = container->end();
126 QList<GeoDataFeature *>::Iterator iter = container->begin();
127 for (; iter != end; ++iter) {
128 GeoDataFeature *foundFeature = findFeature(*iter, id);
129 if (foundFeature) {
130 return foundFeature;
131 }
132 }
133 }
134 return nullptr;
135}
136
137GeoDataDocument *PlaybackAnimatedUpdateItem::rootDocument(GeoDataObject *object) const
138{
139 if (!object || !object->parent()) {
140 auto document = dynamic_cast<GeoDataDocument *>(object);
141 return document;
142 } else {
143 return rootDocument(object->parent());
144 }
145 return nullptr;
146}
147
148void PlaybackAnimatedUpdateItem::pause()
149{
150 // do nothing
151}
152
153void PlaybackAnimatedUpdateItem::seek(double position)
154{
155 Q_UNUSED(position);
156 play();
157}
158
159void PlaybackAnimatedUpdateItem::stop()
160{
161 if (!m_playing) {
162 return;
163 }
164 m_playing = false;
165
166 if (m_animatedUpdate->update()->change()) {
167 QList<GeoDataPlacemark *> placemarkList = m_animatedUpdate->update()->change()->placemarkList();
168 for (int i = 0; i < placemarkList.size(); i++) {
169 GeoDataPlacemark *placemark = placemarkList.at(i);
170 QString targetId = placemark->targetId();
171 if (targetId.isEmpty()) {
172 continue;
173 }
174 GeoDataFeature *feature = findFeature(m_rootDocument, targetId);
175 if (placemark->isBalloonVisible()) {
176 if (geodata_cast<GeoDataPlacemark>(feature)) {
177 Q_EMIT balloonHidden();
178 }
179 } else {
180 Q_EMIT balloonShown(static_cast<GeoDataPlacemark *>(feature));
181 }
182 }
183 }
184
185 if (m_animatedUpdate->update()->create()) {
186 for (int index = 0; index < m_animatedUpdate->update()->create()->size(); ++index) {
187 GeoDataFeature *feature = m_animatedUpdate->update()->create()->child(index);
188 if (feature && (geodata_cast<GeoDataDocument>(feature) || geodata_cast<GeoDataFolder>(feature))) {
189 auto container = static_cast<GeoDataContainer *>(feature);
190 for (int i = 0; i < container->size(); ++i) {
191 Q_EMIT removed(container->child(i));
192 if (auto placemark = geodata_cast<GeoDataPlacemark>(container->child(i))) {
193 if (placemark->isBalloonVisible()) {
194 Q_EMIT balloonHidden();
195 }
196 }
197 }
198 }
199 }
200 }
201
202 for (GeoDataFeature *feature : std::as_const(m_deletedObjects)) {
203 if (feature->targetId().isEmpty()) {
204 continue;
205 }
206 GeoDataFeature *target = findFeature(m_rootDocument, feature->targetId());
207 if (target) {
208 /** @todo Do we have to note the original row position and restore it? */
209 Q_ASSERT(dynamic_cast<GeoDataContainer *>(target));
210 Q_EMIT added(static_cast<GeoDataContainer *>(target), feature, -1);
211 if (auto placemark = geodata_cast<GeoDataPlacemark>(feature)) {
212 if (placemark->isBalloonVisible()) {
213 Q_EMIT balloonShown(placemark);
214 }
215 }
216 } // else the root document was modified in an unfortunate way and we cannot restore it at this point
217 }
218 m_deletedObjects.clear();
219}
220
221bool PlaybackAnimatedUpdateItem::isApplied() const
222{
223 return m_playing;
224}
225
226bool PlaybackAnimatedUpdateItem::canDelete(const GeoDataFeature &feature)
227{
230}
231
232}
233
234#include "moc_PlaybackAnimatedUpdateItem.cpp"
GeoDataFeature * child(int)
returns the requested child item
QList< GeoDataPlacemark * > placemarkList() const
A convenience function that returns all placemarks in this container.
QAction * create(StandardAction id, const QObject *recvr, const char *slot, QObject *parent)
const QList< QKeySequence > & end()
Binds a QML item to a specific geodetic location in screen coordinates.
T * geodata_cast(GeoDataObject *node)
Returns the given node cast to type T if the node was instantiated as type T; otherwise returns 0.
const_reference at(qsizetype i) const const
qsizetype size() const const
Q_EMITQ_EMIT
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Dec 20 2024 11:52:13 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.