diff --git a/Map/GeoCoordinates.cpp b/Map/GeoCoordinates.cpp index 03b72cd2..03c4c784 100644 --- a/Map/GeoCoordinates.cpp +++ b/Map/GeoCoordinates.cpp @@ -1,75 +1,75 @@ -/* Copyright (C) 2018 Tobias Leupold +/* Copyright (C) 2018 The KPhotoAlbum Development Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "GeoCoordinates.h" bool Map::GeoCoordinates::hasCoordinates() const { return m_hasCoordinates; } double Map::GeoCoordinates::lon() const { return m_lon; } double Map::GeoCoordinates::lat() const { return m_lat; } double Map::GeoCoordinates::alt() const { return m_alt; } bool Map::GeoCoordinates::hasAltitude() const { return m_hasAlt; } void Map::GeoCoordinates::setLatLon(const double lat, const double lon) { m_lat = lat; m_lon = lon; m_hasCoordinates = true; } void Map::GeoCoordinates::setAlt(const double alt) { m_alt = alt; m_hasAlt = true; } Map::GeoCoordinates::Pair Map::GeoCoordinates::makePair(const double lat1, const double lon1, const double lat2, const double lon2) { Map::GeoCoordinates coordinates1; coordinates1.setLatLon(lat1, lon1); Map::GeoCoordinates coordinates2; coordinates2.setLatLon(lat2, lon2); return Pair(coordinates1, coordinates2); } Map::GeoCoordinates::operator QString() const { - return QString::fromLatin1("(%1, %2)").arg(m_lon).arg(m_lat); + return QStringLiteral("(%1, %2)").arg(m_lon).arg(m_lat); } // vi:expandtab:tabstop=4 shiftwidth=4: diff --git a/Map/GeoCoordinates.h b/Map/GeoCoordinates.h index cb1c3906..ce5f88c7 100644 --- a/Map/GeoCoordinates.h +++ b/Map/GeoCoordinates.h @@ -1,62 +1,63 @@ -/* Copyright (C) 2018 Tobias Leupold +/* Copyright (C) 2018 The KPhotoAlbum Development Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef GEOCOORDINATES_H #define GEOCOORDINATES_H #include #include #include namespace Map { class GeoCoordinates { public: bool hasCoordinates() const; double lon() const; double lat() const; double alt() const; bool hasAltitude() const; void setLatLon(const double lat, const double lon); void setAlt(const double alt); typedef QPair Pair; static Pair makePair(const double lat1, const double lon1, const double lat2, const double lon2); operator QString() const; + private: // Variables double m_lat; double m_lon; double m_alt; bool m_hasCoordinates; bool m_hasAlt; }; } Q_DECLARE_METATYPE(Map::GeoCoordinates::Pair) #endif // GEOCOORDINATES_H // vi:expandtab:tabstop=4 shiftwidth=4: diff --git a/Map/MapView.cpp b/Map/MapView.cpp index 62e48908..9a54b238 100644 --- a/Map/MapView.cpp +++ b/Map/MapView.cpp @@ -1,290 +1,289 @@ -/* Copyright (C) 2014-2018 Tobias Leupold +/* Copyright (C) 2014-2018 The KPhotoAlbum Development Team This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + along with this program. If not, see . */ // Local includes #include "MapView.h" #include "Logging.h" // Marble includes #include #include #include // Qt includes #include #include #include #include #include #include #include // KDE includes #include #include #include #include #include namespace { -const QString FLOATER_VISIBLE_CONFIG_PREFIX = QStringLiteral("MarbleFloaterVisible "); +const QString MAPVIEW_FLOATER_VISIBLE_CONFIG_PREFIX = QStringLiteral("MarbleFloaterVisible "); +const QStringList MAPVIEW_RENDER_POSITION({QStringLiteral("HOVERS_ABOVE_SURFACE")}); } Map::MapView::MapView(QWidget *parent, UsageType type) : QWidget(parent) { if (type == MapViewWindow) { setWindowFlags(Qt::Window); setAttribute(Qt::WA_DeleteOnClose); } QVBoxLayout *layout = new QVBoxLayout(this); m_statusLabel = new QLabel; m_statusLabel->setAlignment(Qt::AlignCenter); m_statusLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); m_statusLabel->hide(); layout->addWidget(m_statusLabel); m_mapWidget = new Marble::MarbleWidget; m_mapWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_mapWidget->setProjection(Marble::Mercator); - m_mapWidget->setMapThemeId(QString::fromUtf8("earth/openstreetmap/openstreetmap.dgml")); + m_mapWidget->setMapThemeId(QStringLiteral("earth/openstreetmap/openstreetmap.dgml")); m_mapWidget->addLayer(this); layout->addWidget(m_mapWidget); m_mapWidget->show(); QHBoxLayout *controlLayout = new QHBoxLayout; layout->addLayout(controlLayout); // KPA's control buttons QWidget *kpaButtons = new QWidget; QHBoxLayout *kpaButtonsLayout = new QHBoxLayout(kpaButtons); controlLayout->addWidget(kpaButtons); QPushButton *saveButton = new QPushButton; saveButton->setFlat(true); - saveButton->setIcon(QPixmap(SmallIcon(QString::fromUtf8("media-floppy")))); + saveButton->setIcon(QPixmap(SmallIcon(QStringLiteral("media-floppy")))); saveButton->setToolTip(i18n("Save the current map settings")); kpaButtonsLayout->addWidget(saveButton); connect(saveButton, &QPushButton::clicked, this, &MapView::saveSettings); m_setLastCenterButton = new QPushButton; m_setLastCenterButton->setFlat(true); - m_setLastCenterButton->setIcon(QPixmap(SmallIcon(QString::fromUtf8("go-first")))); + m_setLastCenterButton->setIcon(QPixmap(SmallIcon(QStringLiteral("go-first")))); m_setLastCenterButton->setToolTip(i18n("Go to last map position")); kpaButtonsLayout->addWidget(m_setLastCenterButton); connect(m_setLastCenterButton, &QPushButton::clicked, this, &MapView::setLastCenter); // Marble floater control buttons m_floaters = new QWidget; QHBoxLayout *floatersLayout = new QHBoxLayout(m_floaters); controlLayout->addStretch(); controlLayout->addWidget(m_floaters); KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(QStringLiteral("MapView")); for (const Marble::RenderPlugin *plugin : m_mapWidget->renderPlugins()) { if (plugin->renderType() != Marble::RenderPlugin::PanelRenderType) { continue; } QPushButton *button = new QPushButton; button->setCheckable(true); button->setFlat(true); button->setChecked(plugin->action()->isChecked()); button->setToolTip(plugin->description()); const QString name = plugin->name(); button->setProperty("floater", name); QPixmap icon = plugin->action()->icon().pixmap(QSize(20, 20)); if (icon.isNull()) { icon = QPixmap(20, 20); icon.fill(Qt::white); } button->setIcon(icon); connect(plugin->action(), &QAction::toggled, button, &QPushButton::setChecked); connect(button, &QPushButton::toggled, plugin->action(), &QAction::setChecked); floatersLayout->addWidget(button); - const QString value = group.readEntry(FLOATER_VISIBLE_CONFIG_PREFIX + name); + const QString value = group.readEntry(MAPVIEW_FLOATER_VISIBLE_CONFIG_PREFIX + name); if (! value.isEmpty()) { button->setChecked(value == QStringLiteral("true") ? true : false); } } } void Map::MapView::clear() { m_images.clear(); } void Map::MapView::addImage(DB::ImageInfoPtr image) { - if (image->coordinates().hasCoordinates()) - { + if (image->coordinates().hasCoordinates()) { qCDebug(MapLog) << "Adding image" << image->label(); m_images.append(image); - } - else + } else { qCDebug(MapLog) << "Image" << image->label() << "has no geo coordinates"; + } } void Map::MapView::zoomToMarkers() { qDebug() << ">>> Implement me! Map::MapView::zoomToMarkers()"; } void Map::MapView::setCenter(const DB::ImageInfoPtr image) { m_lastCenter = image->coordinates(); setLastCenter(); } void Map::MapView::saveSettings() { KSharedConfigPtr config = KSharedConfig::openConfig(); KConfigGroup group = config->group(QStringLiteral("MapView")); for (const QPushButton *button : m_floaters->findChildren()) { - group.writeEntry(FLOATER_VISIBLE_CONFIG_PREFIX + button->property("floater").toString(), - button->isChecked()); + group.writeEntry(MAPVIEW_FLOATER_VISIBLE_CONFIG_PREFIX + + button->property("floater").toString(), button->isChecked()); } config->sync(); QMessageBox::information(this, i18n("Map view"), i18n("Settings saved!")); } void Map::MapView::setShowThumbnails(bool state) { Q_UNUSED(state); qDebug() << ">>> Implement me! Map::MapView::setShowThumbnails(bool state)"; } void Map::MapView::displayStatus(MapStatus status) { switch (status) { case MapStatus::Loading: m_statusLabel->setText(i18n("Loading coordinates from the images ...")); m_statusLabel->show(); m_mapWidget->hide(); //m_mapWidget->clearRegionSelection(); m_setLastCenterButton->setEnabled(false); break; case MapStatus::ImageHasCoordinates: m_statusLabel->hide(); //m_mapWidget->setAvailableMouseModes(KGeoMap::MouseModePan); //m_mapWidget->setVisibleMouseModes(0); //m_mapWidget->setMouseMode(KGeoMap::MouseModePan); //m_mapWidget->clearRegionSelection(); m_mapWidget->show(); m_setLastCenterButton->show(); m_setLastCenterButton->setEnabled(true); break; case MapStatus::ImageHasNoCoordinates: m_statusLabel->setText(i18n("This image does not contain geographic coordinates.")); m_statusLabel->show(); m_mapWidget->hide(); m_setLastCenterButton->show(); m_setLastCenterButton->setEnabled(false); break; case MapStatus::SomeImagesHaveNoCoordinates: m_statusLabel->setText(i18n("Some of the selected images do not contain geographic " "coordinates.")); m_statusLabel->show(); //m_mapWidget->setAvailableMouseModes(KGeoMap::MouseModePan); //m_mapWidget->setVisibleMouseModes(0); //m_mapWidget->setMouseMode(KGeoMap::MouseModePan); //m_mapWidget->clearRegionSelection(); m_mapWidget->show(); m_setLastCenterButton->show(); m_setLastCenterButton->setEnabled(true); break; case MapStatus::SearchCoordinates: m_statusLabel->setText(i18n("Search for geographic coordinates.")); m_statusLabel->show(); //m_mapWidget->setAvailableMouseModes(KGeoMap::MouseModePan // | KGeoMap::MouseModeRegionSelectionFromIcon // | KGeoMap::MouseModeRegionSelection); //m_mapWidget->setVisibleMouseModes(KGeoMap::MouseModePan // | KGeoMap::MouseModeRegionSelectionFromIcon // | KGeoMap::MouseModeRegionSelection); //m_mapWidget->setMouseMode(KGeoMap::MouseModeRegionSelectionFromIcon); m_mapWidget->show(); //m_mapWidget->setCenter(KGeoMap::GeoCoordinates()); m_setLastCenterButton->hide(); break; case MapStatus::NoImagesHaveNoCoordinates: m_statusLabel->setText(i18n("None of the selected images contain geographic " "coordinates.")); m_statusLabel->show(); m_mapWidget->hide(); m_setLastCenterButton->show(); m_setLastCenterButton->setEnabled(false); break; } emit displayStatusChanged(status); } void Map::MapView::setLastCenter() { m_mapWidget->centerOn(m_lastCenter.lon(), m_lastCenter.lat()); } Map::GeoCoordinates::Pair Map::MapView::getRegionSelection() const { qDebug() << ">>> Implement me! Map::MapView::getRegionSelection()"; return GeoCoordinates::makePair(0, 0, 0, 0); } bool Map::MapView::regionSelected() const { qDebug() << ">>> Implement me! Map::MapView::regionSelected()"; return false; } QStringList Map::MapView::renderPosition() const { // we only ever paint on the same layer: - return QStringList({QStringLiteral("HOVERS_ABOVE_SURFACE")}); + return MAPVIEW_RENDER_POSITION; } -bool Map::MapView::render(Marble::GeoPainter *painter, Marble::ViewportParams *viewport, const QString &renderPos, Marble::GeoSceneLayer *layer) +bool Map::MapView::render(Marble::GeoPainter *painter, Marble::ViewportParams *, + const QString &renderPos, Marble::GeoSceneLayer *) { - Q_UNUSED(viewport); - Q_UNUSED(renderPos); - Q_UNUSED(layer); Q_ASSERT(renderPos == renderPosition().first()); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(QPen(QBrush(QColor::fromRgb(255, 0, 0)), 3.0, Qt::SolidLine, Qt::RoundCap)); - for (const auto &image: m_images) - { - auto pos = Marble::GeoDataCoordinates(image->coordinates().lon(), image->coordinates().lat() - , image->coordinates().alt(), Marble::GeoDataCoordinates::Degree); + for (const DB::ImageInfoPtr &image: m_images) { + const Marble::GeoDataCoordinates pos(image->coordinates().lon(), image->coordinates().lat(), + image->coordinates().alt(), + Marble::GeoDataCoordinates::Degree); painter->drawAnnotation(pos, image->label()); } return true; } // vi:expandtab:tabstop=4 shiftwidth=4: diff --git a/Map/MapView.h b/Map/MapView.h index 3df973cf..9730053e 100644 --- a/Map/MapView.h +++ b/Map/MapView.h @@ -1,161 +1,163 @@ -/* Copyright (C) 2014-2018 Tobias Leupold +/* Copyright (C) 2014-2018 The KPhotoAlbum Development Team This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License or (at your option) version 3 or any later version + accepted by the membership of KDE e.V. (or its successor approved + by the membership of KDE e.V.), which shall act as a proxy + defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + along with this program. If not, see . */ #ifndef MAPVIEW_H #define MAPVIEW_H // Local includes #include "GeoCoordinates.h" #include "DB/ImageInfo.h" #include "DB/ImageInfoPtr.h" // Qt includes #include #include // Marble includes #include #include // Marble classes namespace Marble { class MarbleWidget; } // Qt classes class QLabel; class QPushButton; namespace Map { class MapView : public QWidget , public Marble::LayerInterface { Q_OBJECT public: /** * UsageType: determines whether the widget is used as a standalone widget * or within another widget (e.g. the AnnotationDialog). * @see Viewer::ViewerWidget::UsageType */ enum UsageType { InlineMapView, MapViewWindow }; /** * MapStatus: determines the visibility and text of the status label and the visibility of the * map, depending on the availability of coordinates of the image(s) that are displayed. */ enum MapStatus { Loading, ImageHasCoordinates, ImageHasNoCoordinates, NoImagesHaveNoCoordinates, SomeImagesHaveNoCoordinates, SearchCoordinates }; explicit MapView(QWidget *parent = nullptr, UsageType type = InlineMapView); ~MapView() = default; /** * Removes all images from the map. */ void clear(); /** * Add an image to the map. */ void addImage(DB::ImageInfoPtr image); /** * Sets the map's zoom so that all images on the map are visible. * If no images have been added, the zoom is not altered. */ void zoomToMarkers(); /** * Sets the state of the "Show Thumbnails" button on the map's control widget. */ void setShowThumbnails(bool state); /** * This sets the status label text and it's visibility, as well as the visibilty of the map * itself to the state indicated by the given MapStatus. */ void displayStatus(MapStatus status); GeoCoordinates::Pair getRegionSelection() const; bool regionSelected() const; // LayerInterface: /** * @brief renderPosition tells the LayerManager what layers we (currently) want to paint on. * Part of the LayerInterface; called by the LayerManager. * @return */ QStringList renderPosition() const override; /** * @brief Render all markers onto the marbleWidget. * Part of the LayerInterface; called by the LayerManager. * @param painter the painter used by the LayerManager * @param viewport * @param renderPos the layer name * @param layer always \c nullptr * @return \c true (return value is discarded by LayerManager::renderLayers()) */ - bool render(Marble::GeoPainter *painter, Marble::ViewportParams *viewport, - const QString &renderPos, Marble::GeoSceneLayer *layer) override; + bool render(Marble::GeoPainter *painter, Marble::ViewportParams *, + const QString &renderPos, Marble::GeoSceneLayer *) override; Q_SIGNALS: void signalRegionSelectionChanged(); void displayStatusChanged(MapStatus); public slots: /** * Centers the map on the coordinates of the given image. */ void setCenter(const DB::ImageInfoPtr image); private slots: void saveSettings(); void setLastCenter(); private: // Variables Marble::MarbleWidget *m_mapWidget; QLabel *m_statusLabel; QPushButton *m_setLastCenterButton; GeoCoordinates m_lastCenter; QWidget *m_floaters; // FIXME(jzarl): dirty hack to get it working // if this should work efficiently with a large number of images, - // some spatially aware data structure probably needs to be used (e.g. binning images by location) + // some spatially aware data structure probably needs to be used + // (e.g. binning images by location) QList m_images; }; } #endif // MAPVIEW_H // vi:expandtab:tabstop=4 shiftwidth=4: