9#include "MapThemeManager.h"
15#include <QFileSystemWatcher>
16#include <QScopedPointer>
19#include <QStandardItemModel>
22#include "GeoDataPhotoOverlay.h"
23#include "GeoSceneDocument.h"
24#include "GeoSceneMap.h"
25#include "GeoSceneHead.h"
26#include "GeoSceneIcon.h"
27#include "GeoSceneParser.h"
28#include "GeoSceneLayer.h"
29#include "GeoSceneTileDataset.h"
30#include "GeoSceneTextureTileDataset.h"
31#include "GeoSceneProperty.h"
32#include "GeoSceneZoom.h"
33#include "GeoSceneSettings.h"
34#include "MarbleDebug.h"
35#include "MarbleDirs.h"
37#include "PlanetFactory.h"
44 static const QString mapDirName =
"maps";
45 static const int columnRelativePath = 1;
57 void directoryChanged(
const QString& path );
58 void fileChanged(
const QString & path );
66 void updateMapThemeModel();
86 static GeoSceneDocument* loadMapThemeFile(
const QString& mapThemeId );
98 static bool deleteDirectory(
const QString &directory );
104 bool m_isInitialized;
116 m_mapThemeModel( 0, 3 ),
118 m_fileSystemWatcher(),
119 m_isInitialized( false )
123MapThemeManager::Private::~Private()
130 d( new Private( this ) )
133 connect( &d->m_fileSystemWatcher, SIGNAL(directoryChanged(
QString)),
134 this, SLOT(directoryChanged(
QString)));
136 this, SLOT(fileChanged(
QString)));
139MapThemeManager::~MapThemeManager()
148 if ( !d->m_isInitialized ) {
149 d->updateMapThemeModel();
150 d->m_isInitialized =
true;
171void MapThemeManager::deleteMapTheme(
const QString &mapThemeId )
177 Private::deleteDirectory(
themeDir );
180bool MapThemeManager::Private::deleteDirectory(
const QString& directory )
182 QDir dir( directory );
185 if ( dir.exists() ) {
186 for(
const QFileInfo &info: dir.entryInfoList(
189 QDir::DirsFirst ) ) {
191 if ( info.isDir() ) {
192 result = deleteDirectory( info.absoluteFilePath() );
202 result =
dir.rmdir( directory );
212GeoSceneDocument* MapThemeManager::Private::loadMapThemeFile(
const QString& mapThemeStringID )
215 const QString dgmlPath = MarbleDirs::path( mapThemePath );
218 QFile file( dgmlPath );
219 if ( !file.exists() ) {
220 qWarning() <<
"Map theme file does not exist:" << dgmlPath;
227 if ( !fileReadable ) {
228 qWarning() <<
"Map theme file not readable:" << dgmlPath;
232 GeoSceneParser parser( GeoScene_DGML );
234 if ( !parser.read( &file )) {
235 qWarning() <<
"Map theme file not well-formed:" << dgmlPath;
239 mDebug() <<
"Map theme file successfully loaded:" << dgmlPath;
242 GeoSceneDocument* document =
static_cast<GeoSceneDocument*
>( parser.releaseDocument() );
243 Q_ASSERT( document );
247QStringList MapThemeManager::Private::pathsToWatch()
250 const QString localMapPathName = MarbleDirs::localPath() +
QLatin1Char(
'/') + mapDirName;
251 const QString systemMapPathName = MarbleDirs::systemPath() +
QLatin1Char(
'/') + mapDirName;
253 if( !
QDir().exists( localMapPathName ) ) {
257 result << localMapPathName;
258 result << systemMapPathName;
259 addMapThemePaths( localMapPathName, result );
260 addMapThemePaths( systemMapPathName, result );
276 for (
int planet = 0; planet < mapPaths.
size(); ++planet ) {
283 for (
int theme = 0; theme < themeMapPaths.
size(); ++theme ) {
285 + themeMapPaths.
at( theme );
290 QStringListIterator it( mapDirs );
291 while ( it.hasNext() ) {
297 QStringListIterator k( tmp );
298 while ( k.hasNext() ) {
300 mapFiles << themeDirName +
QLatin1Char(
'/') + themeXml;
308QStringList MapThemeManager::Private::findMapThemes()
310 QStringList mapFilesLocal = findMapThemes( MarbleDirs::localPath() );
311 QStringList mapFilesSystem = findMapThemes( MarbleDirs::systemPath() );
313 allMapFiles << mapFilesSystem;
317 for (
int i = 1; i < allMapFiles.size(); ++i ) {
318 if ( allMapFiles.at(i) == allMapFiles.at( i-1 ) ) {
319 allMapFiles.removeAt( i );
329 if ( !d->m_isInitialized ) {
330 d->updateMapThemeModel();
331 d->m_isInitialized =
true;
333 return &d->m_mapThemeModel;
338 if ( !d->m_isInitialized ) {
339 d->updateMapThemeModel();
340 d->m_isInitialized =
true;
343 return &d->m_celestialList;
351 if ( !mapTheme || !mapTheme->head()->visible() ) {
359 + mapTheme->head()->icon()->pixmap();
360 themeIconPixmap.
load( MarbleDirs::path( relativePath ) );
362 if ( themeIconPixmap.
isNull() ) {
363 relativePath =
"svg/application-x-marble-gray.png";
364 themeIconPixmap.
load( MarbleDirs::path( relativePath ) );
370 QSize maxIconSize( 136, 136 );
371 if ( themeIconPixmap.
size() != maxIconSize ) {
372 mDebug() <<
"Smooth scaling theme icon";
373 themeIconPixmap = themeIconPixmap.
scaled( maxIconSize,
379 QIcon mapThemeIcon =
QIcon( themeIconPixmap );
397void MapThemeManager::Private::updateMapThemeModel()
400 m_mapThemeModel.clear();
405 QStringListIterator it( stringlist );
407 while ( it.hasNext() ) {
408 QString mapThemeID = it.next();
411 if ( !itemList.
empty() ) {
412 m_mapThemeModel.appendRow( itemList );
416 for (
const QString &mapThemeId: stringlist ) {
418 QString celestialBodyName = PlanetFactory::localizedName( celestialBodyId );
421 if ( matchingItems.
isEmpty() ) {
429void MapThemeManager::Private::watchPaths()
432 QStringList const files = m_fileSystemWatcher.files();
433 QStringList const directories = m_fileSystemWatcher.directories();
436 for(
const QString &resource: paths ) {
438 m_fileSystemWatcher.addPath( resource );
443void MapThemeManager::Private::directoryChanged(
const QString& path )
445 mDebug() <<
"directoryChanged:" <<
path;
448 mDebug() <<
"Emitting themesChanged()";
449 updateMapThemeModel();
450 emit q->themesChanged();
453void MapThemeManager::Private::fileChanged(
const QString& path )
455 mDebug() <<
"fileChanged:" <<
path;
463 mDebug() <<
"mapThemeId:" << mapThemeId;
467 columnRelativePath );
468 mDebug() <<
"matchingItems:" << matchingItems.
size();
469 Q_ASSERT( matchingItems.
size() <= 1 );
472 if ( matchingItems.
size() == 1 ) {
473 const int row = matchingItems.
front()->row();
476 while ( !toBeDeleted.
isEmpty() ) {
482 if ( fileInfo.exists() ) {
484 if ( !newMapThemeRow.
empty() ) {
485 m_mapThemeModel.insertRow( insertAtRow, newMapThemeRow );
489 emit q->themesChanged();
495void MapThemeManager::Private::addMapThemePaths(
const QString& mapPathName,
QStringList& result )
497 QDir mapPath( mapPathName );
502 QStringListIterator itOrb( orbDirNames );
503 while ( itOrb.hasNext() ) {
505 result << orbPathName;
507 QDir orbPath( orbPathName );
512 QStringListIterator itThemeDir( themeDirNames );
513 while ( itThemeDir.hasNext() ) {
515 result << themePathName;
517 QDir themePath( themePathName );
521 QStringListIterator itThemeFile( themeFileNames );
522 while ( itThemeFile.hasNext() ) {
523 const QString themeFilePathName = themePathName +
QLatin1Char(
'/') + itThemeFile.next();
524 result << themeFilePathName;
530GeoSceneDocument *MapThemeManager::createMapThemeFromOverlay(
const GeoDataPhotoOverlay *overlayData )
533 document->head()->setDescription(
overlayData->description() );
535 document->head()->setTheme(
"photo" );
536 document->head()->setTarget(
"panorama" );
537 document->head()->setRadius(36000);
538 document->head()->setVisible(
true);
540 document->head()->zoom()->setMaximum(3500);
541 document->head()->zoom()->setMinimum(900);
542 document->head()->zoom()->setDiscrete(
false);
545 layer->setBackend(
"texture");
547 GeoSceneTextureTileDataset * texture =
new GeoSceneTextureTileDataset(
"map" );
548 texture->setExpire(std::numeric_limits<int>::max());
558 texture->setSourceDir( sourceDir );
559 texture->setFileFormat( extension );
560 texture->setInstallMap( fileName );
561 texture->setTileProjection(GeoSceneAbstractTileProjection::Equirectangular);
581 compass->setAvailable(
false );
594#include "moc_MapThemeManager.cpp"
Provides access to all map themes installed locally.
QStringList mapThemeIds() const
A list of all installed map theme ids, each entry has the form "planet/themeid/themeid....
MapThemeManager(QObject *parent=nullptr)
Constructor.
A container for features parsed from the DGML file.
Layer of a GeoScene document.
void addDataset(GeoSceneAbstractDataset *)
Add a data set to the legend.
void addLayer(GeoSceneLayer *)
Add a new layer to the map.
Settings property within a GeoScene document.
Settings of a GeoScene document.
void addProperty(GeoSceneProperty *property)
Add a property to the settings.
QString path(const QString &relativePath)
KIOCORE_EXPORT QString dir(const QString &fileClass)
QString name(StandardShortcut id)
Binds a QML item to a specific geodetic location in screen coordinates.
const char * constData() const const
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
QStringList entryList(Filters filters, SortFlags sort) const const
bool mkpath(const QString &dirPath) const const
QString path() const const
QDir absoluteDir() const const
QString fileName() const const
QString suffix() const const
const_reference at(qsizetype i) const const
bool isEmpty() const const
void reserve(qsizetype size)
qsizetype size() const const
T qobject_cast(QObject *object)
QString tr(const char *sourceText, const char *disambiguation, int n)
bool isNull() const const
bool load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
QPixmap scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
virtual void setData(const QVariant &value, int role)
QString section(QChar sep, qsizetype start, qsizetype end, SectionFlags flags) const const
QByteArray toUtf8() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
void sort(Qt::CaseSensitivity cs)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)