diff --git a/src/lib/marble/geodata/data/GeoDataContainer.cpp b/src/lib/marble/geodata/data/GeoDataContainer.cpp index 6a6032c8c..ea3d83afe 100644 --- a/src/lib/marble/geodata/data/GeoDataContainer.cpp +++ b/src/lib/marble/geodata/data/GeoDataContainer.cpp @@ -1,414 +1,450 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2007 Murad Tagirov // Copyright 2009 Patrick Spendrin // // Own #include "GeoDataContainer.h" #include "GeoDataContainer_p.h" // Qt #include // Marble #include "MarbleDebug.h" #include "GeoDataFeature.h" #include "GeoDataFolder.h" #include "GeoDataPlacemark.h" #include "GeoDataDocument.h" #include "GeoDataNetworkLinkControl.h" #include "GeoDataNetworkLink.h" #include "GeoDataGroundOverlay.h" #include "GeoDataPhotoOverlay.h" #include "GeoDataScreenOverlay.h" #include "GeoDataTour.h" namespace Marble { GeoDataContainer::GeoDataContainer() : GeoDataFeature( new GeoDataContainerPrivate ) { } GeoDataContainer::GeoDataContainer( GeoDataContainerPrivate *priv ) : GeoDataFeature( priv ) { } GeoDataContainer::GeoDataContainer( const GeoDataContainer& other ) : GeoDataFeature( other ) { } GeoDataContainer::~GeoDataContainer() { } GeoDataContainerPrivate* GeoDataContainer::p() { return static_cast(d); } const GeoDataContainerPrivate* GeoDataContainer::p() const { return static_cast(d); } bool GeoDataContainer::equals( const GeoDataContainer &other ) const { if ( !GeoDataFeature::equals(other) ) { return false; } QVector::const_iterator thisBegin = p()->m_vector.constBegin(); QVector::const_iterator thisEnd = p()->m_vector.constEnd(); QVector::const_iterator otherBegin = other.p()->m_vector.constBegin(); QVector::const_iterator otherEnd = other.p()->m_vector.constEnd(); for (; thisBegin != thisEnd && otherBegin != otherEnd; ++thisBegin, ++otherBegin) { if ( (*thisBegin)->nodeType() != (*otherBegin)->nodeType() ) { return false; } if ( (*thisBegin)->nodeType() == GeoDataTypes::GeoDataDocumentType ) { GeoDataDocument *thisDoc = static_cast( *thisBegin ); GeoDataDocument *otherDoc = static_cast( *otherBegin ); Q_ASSERT( thisDoc && otherDoc ); if ( *thisDoc != *otherDoc ) { return false; } } else if ( (*thisBegin)->nodeType() == GeoDataTypes::GeoDataFolderType ) { GeoDataFolder *thisFolder = static_cast( *thisBegin ); GeoDataFolder *otherFolder = static_cast( *otherBegin ); Q_ASSERT( thisFolder && otherFolder ); if ( *thisFolder != *otherFolder ) { return false; } } else if ( (*thisBegin)->nodeType() == GeoDataTypes::GeoDataNetworkLinkControlType ) { GeoDataNetworkLinkControl *thisNLC = static_cast( *thisBegin ); GeoDataNetworkLinkControl *otherNLC = static_cast( *otherBegin ); Q_ASSERT( thisNLC && otherNLC ); if ( *thisNLC != *otherNLC ) { return false; } } else if ( (*thisBegin)->nodeType() == GeoDataTypes::GeoDataNetworkLinkType ) { GeoDataNetworkLink *thisNetLink = static_cast( *thisBegin ); GeoDataNetworkLink *otherNetLink = static_cast( *otherBegin ); Q_ASSERT( thisNetLink && otherNetLink ); if ( *thisNetLink != *otherNetLink ) { return false; } } else if ( (*thisBegin)->nodeType() == GeoDataTypes::GeoDataGroundOverlayType ) { GeoDataGroundOverlay *thisGO = static_cast( *thisBegin ); GeoDataGroundOverlay *otherGO = static_cast( *otherBegin ); Q_ASSERT( thisGO && otherGO ); if ( *thisGO != *otherGO ) { return false; } } else if ( (*thisBegin)->nodeType() == GeoDataTypes::GeoDataPhotoOverlayType ) { GeoDataPhotoOverlay *thisPO = static_cast( *thisBegin ); GeoDataPhotoOverlay *otherPO = static_cast( *otherBegin ); Q_ASSERT( thisPO && otherPO ); if ( *thisPO != *otherPO ) { return false; } } else if ( (*thisBegin)->nodeType() == GeoDataTypes::GeoDataScreenOverlayType ) { GeoDataScreenOverlay *thisSO = static_cast( *thisBegin ); GeoDataScreenOverlay *otherSO = static_cast( *otherBegin ); Q_ASSERT( thisSO && otherSO ); if ( *thisSO != *otherSO ) { return false; } } else if ( (*thisBegin)->nodeType() == GeoDataTypes::GeoDataTourType ) { GeoDataTour *thisTour = static_cast( *thisBegin ); GeoDataTour *otherTour = static_cast( *otherBegin ); Q_ASSERT( thisTour && otherTour ); if ( *thisTour != *otherTour ) { return false; } } else if ( (*thisBegin)->nodeType() == GeoDataTypes::GeoDataPlacemarkType ) { GeoDataPlacemark *thisPM = static_cast( *thisBegin ); GeoDataPlacemark *otherPM = static_cast( *otherBegin ); Q_ASSERT( thisPM && otherPM ); if ( *thisPM != *otherPM ) { return false; } } } return thisBegin == thisEnd && otherBegin == otherEnd; } GeoDataLatLonAltBox GeoDataContainer::latLonAltBox() const { GeoDataLatLonAltBox result; QVector::const_iterator it = p()->m_vector.constBegin(); QVector::const_iterator end = p()->m_vector.constEnd(); for (; it != end; ++it) { // Get all the placemarks from GeoDataContainer if ( (*it)->nodeType() == GeoDataTypes::GeoDataPlacemarkType ) { GeoDataPlacemark *placemark = static_cast(*it); // Only use visible placemarks for extracting their latLonAltBox and // making an union with the global latLonAltBox Marble will fit its // zoom to if (placemark->isVisible()) { if (result.isEmpty()) { result = placemark->geometry()->latLonAltBox(); } else { result |= placemark->geometry()->latLonAltBox(); } } } else if ( (*it)->nodeType() == GeoDataTypes::GeoDataFolderType || (*it)->nodeType() == GeoDataTypes::GeoDataDocumentType ) { GeoDataContainer *container = static_cast(*it); if (result.isEmpty()) { result = container->latLonAltBox(); } else { result |= container->latLonAltBox(); } } } return result; } QVector GeoDataContainer::folderList() const { QVector results; QVector::const_iterator it = p()->m_vector.constBegin(); QVector::const_iterator end = p()->m_vector.constEnd(); for (; it != end; ++it) { GeoDataFolder *folder = dynamic_cast(*it); if ( folder ) { results.append( folder ); } } return results; } QVector GeoDataContainer::placemarkList() const { QVector results; QVector::const_iterator it = p()->m_vector.constBegin(); QVector::const_iterator end = p()->m_vector.constEnd(); for (; it != end; ++it) { GeoDataPlacemark *placemark = dynamic_cast( *it ); if ( placemark ) { results.append( placemark ); } } return results; } QVector GeoDataContainer::featureList() const { return p()->m_vector; } /** * @brief returns the requested child item */ GeoDataFeature* GeoDataContainer::child( int i ) { detach(); return p()->m_vector.at(i); } const GeoDataFeature* GeoDataContainer::child( int i ) const { return p()->m_vector.at(i); } /** * @brief returns the position of an item in the list */ int GeoDataContainer::childPosition( const GeoDataFeature* object ) const { for ( int i=0; i< p()->m_vector.size(); i++ ) { if ( p()->m_vector.at( i ) == object ) { return i; } } return -1; } void GeoDataContainer::insert( GeoDataFeature *other, int index ) { insert( index, other ); } void GeoDataContainer::insert( int index, GeoDataFeature *feature ) { detach(); feature->setParent(this); p()->m_vector.insert( index, feature ); } void GeoDataContainer::append( GeoDataFeature *other ) { detach(); other->setParent(this); p()->m_vector.append( other ); } void GeoDataContainer::remove( int index ) { detach(); p()->m_vector.remove( index ); } +void GeoDataContainer::remove(int index, int count) +{ + detach(); + p()->m_vector.remove( index, count ); +} + +int GeoDataContainer::removeAll(GeoDataFeature* const &feature) +{ + detach(); + return p()->m_vector.removeAll(feature); +} + +void GeoDataContainer::removeAt(int index) +{ + detach(); + p()->m_vector.removeAt( index ); +} + +void GeoDataContainer::removeFirst() +{ + detach(); + p()->m_vector.removeFirst(); +} + +void GeoDataContainer::removeLast() +{ + detach(); + p()->m_vector.removeLast(); +} + +bool GeoDataContainer::removeOne( GeoDataFeature *feature ) +{ + detach(); + return p()->m_vector.removeOne( feature ); +} + int GeoDataContainer::size() const { return p()->m_vector.size(); } GeoDataFeature& GeoDataContainer::at( int pos ) { detach(); return *(p()->m_vector[ pos ]); } const GeoDataFeature& GeoDataContainer::at( int pos ) const { return *(p()->m_vector.at( pos )); } GeoDataFeature& GeoDataContainer::last() { detach(); return *(p()->m_vector.last()); } const GeoDataFeature& GeoDataContainer::last() const { return *(p()->m_vector.last()); } GeoDataFeature& GeoDataContainer::first() { detach(); return *(p()->m_vector.first()); } const GeoDataFeature& GeoDataContainer::first() const { return *(p()->m_vector.first()); } void GeoDataContainer::clear() { GeoDataContainer::detach(); qDeleteAll(p()->m_vector); p()->m_vector.clear(); } QVector::Iterator GeoDataContainer::begin() { detach(); return p()->m_vector.begin(); } QVector::Iterator GeoDataContainer::end() { detach(); return p()->m_vector.end(); } QVector::ConstIterator GeoDataContainer::constBegin() const { return p()->m_vector.constBegin(); } QVector::ConstIterator GeoDataContainer::constEnd() const { return p()->m_vector.constEnd(); } void GeoDataContainer::pack( QDataStream& stream ) const { GeoDataFeature::pack( stream ); stream << p()->m_vector.count(); for ( QVector ::const_iterator iterator = p()->m_vector.constBegin(); iterator != p()->m_vector.constEnd(); ++iterator ) { const GeoDataFeature *feature = *iterator; stream << feature->featureId(); feature->pack( stream ); } } void GeoDataContainer::unpack( QDataStream& stream ) { detach(); GeoDataFeature::unpack( stream ); int count; stream >> count; for ( int i = 0; i < count; ++i ) { int featureId; stream >> featureId; switch( featureId ) { case GeoDataDocumentId: /* not usable!!!! */ break; case GeoDataFolderId: { GeoDataFolder *folder = new GeoDataFolder; folder->unpack( stream ); p()->m_vector.append( folder ); } break; case GeoDataPlacemarkId: { GeoDataPlacemark *placemark = new GeoDataPlacemark; placemark->unpack( stream ); p()->m_vector.append( placemark ); } break; case GeoDataNetworkLinkId: break; case GeoDataScreenOverlayId: break; case GeoDataGroundOverlayId: break; default: break; }; } } } diff --git a/src/lib/marble/geodata/data/GeoDataContainer.h b/src/lib/marble/geodata/data/GeoDataContainer.h index 76189672d..4df8d603e 100644 --- a/src/lib/marble/geodata/data/GeoDataContainer.h +++ b/src/lib/marble/geodata/data/GeoDataContainer.h @@ -1,171 +1,183 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2007 Murad Tagirov // Copyright 2007 Inge Wallin // Copyright 2009 Patrick Spendrin // #ifndef MARBLE_GEODATACONTAINER_H #define MARBLE_GEODATACONTAINER_H #include #include "geodata_export.h" #include "GeoDataFeature.h" namespace Marble { class GeoDataContainerPrivate; class GeoDataFolder; class GeoDataPlacemark; class GeoDataLatLonAltBox; /** * @short A base class that can hold GeoDataFeatures * * GeoDataContainer is the base class for the GeoData container * classes GeoDataFolder and GeoDataDocument. It is never * instantiated by itself, but is always used as part of a derived * class. * * It is based on GeoDataFeature, and it only adds a * QVector to it, making it a Feature that can hold * other Features. * * @see GeoDataFolder * @see GeoDataDocument */ class GEODATA_EXPORT GeoDataContainer : public GeoDataFeature { public: /// Default constructor GeoDataContainer(); GeoDataContainer( const GeoDataContainer& other ); /// Destruct the GeoDataContainer virtual ~GeoDataContainer(); /** * @brief A convenience function that returns the LatLonAltBox of all * placemarks in this container. * @return The GeoDataLatLonAltBox * * @see GeoDataLatLonAltBox */ GeoDataLatLonAltBox latLonAltBox() const; /** * @brief A convenience function that returns all folders in this container. * @return A QVector of GeoDataFolder * * @see GeoDataFolder */ QVector folderList() const; /** * @brief A convenience function that returns all features in this container. * @return A QVector of GeoDataFeature * * @see GeoDataFeature */ QVector featureList() const; /** * @brief A convenience function that returns all placemarks in this container. * @return A QVector of GeoDataPlacemark * * @see GeoDataPlacemark */ QVector placemarkList() const; /** * @brief returns the requested child item */ GeoDataFeature* child( int ); /** * @brief returns the requested child item */ const GeoDataFeature* child( int ) const; /** * @brief returns the position of an item in the list */ int childPosition( const GeoDataFeature *child) const; /** * @brief inserts @p feature at position @p index in the container */ void insert( int index, GeoDataFeature *feature ); GEODATA_DEPRECATED( void insert( GeoDataFeature *other, int index ) ); /** * @brief add an element */ void append( GeoDataFeature *other ); void remove( int index ); + void remove(int index, int count); + + int removeAll(GeoDataFeature* const &feature); + + void removeAt(int index); + + void removeFirst(); + + void removeLast(); + + bool removeOne( GeoDataFeature *feature ); + /** * @brief size of the container */ int size() const; /** * @brief return the reference of the element at a specific position */ GeoDataFeature& at( int pos ); const GeoDataFeature& at( int pos ) const; /** * @brief return the reference of the last element for convenience */ GeoDataFeature& last(); const GeoDataFeature& last() const; /** * @brief return the reference of the last element for convenience */ GeoDataFeature& first(); const GeoDataFeature& first() const; QVector::Iterator begin(); QVector::Iterator end(); QVector::ConstIterator constBegin() const; QVector::ConstIterator constEnd() const; void clear(); /** * @brief Serialize the container to a stream. * @param stream the stream */ virtual void pack( QDataStream& stream ) const; /** * @brief Unserialize the container from a stream * @param stream the stream */ virtual void unpack( QDataStream& stream ); protected: explicit GeoDataContainer( GeoDataContainerPrivate *priv ); bool equals( const GeoDataContainer &other ) const; using GeoDataFeature::equals; private: GeoDataContainerPrivate* p(); const GeoDataContainerPrivate* p() const; }; } #endif