20 #include <QFileSystemWatcher>
21 #include <QScopedPointer>
23 #include <QStringList>
25 #include <QStandardItemModel>
38 static const QString mapDirName =
"maps";
39 static const int columnRelativePath = 1;
51 void directoryChanged(
const QString& path );
52 void fileChanged(
const QString & path );
60 void updateMapThemeModel();
80 static GeoSceneDocument* loadMapThemeFile(
const QString& mapThemeId );
92 static bool deleteDirectory(
const QString &directory );
110 m_mapThemeModel( 0, 3 ),
112 m_fileSystemWatcher(),
113 m_isInitialized( false )
117 MapThemeManager::Private::~Private()
124 d( new Private( this ) )
127 connect( &d->m_fileSystemWatcher, SIGNAL(directoryChanged(
QString)),
128 this, SLOT(directoryChanged(
QString)));
130 this, SLOT(fileChanged(
QString)));
142 if ( !d->m_isInitialized ) {
143 d->updateMapThemeModel();
144 d->m_isInitialized =
true;
147 for(
int i = 0; i < d->m_mapThemeModel.rowCount(); ++i ) {
148 const QString id = d->m_mapThemeModel.data( d->m_mapThemeModel.index( i, 0 ), Qt::UserRole + 1 ).toString();
157 if ( mapThemeStringID.
isEmpty() )
160 return Private::loadMapThemeFile( mapThemeStringID );
169 Private::deleteDirectory( themeDir );
172 bool MapThemeManager::Private::deleteDirectory(
const QString& directory )
174 QDir dir( directory );
177 if ( dir.exists() ) {
178 Q_FOREACH(
const QFileInfo &info, dir.entryInfoList(
179 QDir::NoDotAndDotDot | QDir::System | QDir::Hidden |
180 QDir::AllDirs | QDir::Files,
181 QDir::DirsFirst ) ) {
183 if ( info.
isDir() ) {
194 result = dir.rmdir( directory );
204 GeoSceneDocument* MapThemeManager::Private::loadMapThemeFile(
const QString& mapThemeStringID )
206 const QString mapThemePath = mapDirName +
'/' + mapThemeStringID;
210 QFile file( dgmlPath );
211 if ( !file.exists() ) {
212 qWarning() <<
"Map theme file does not exist:" << dgmlPath;
217 const bool fileReadable = file.open( QIODevice::ReadOnly );
219 if ( !fileReadable ) {
220 qWarning() <<
"Map theme file not readable:" << dgmlPath;
226 if ( !parser.read( &file )) {
227 qWarning() <<
"Map theme file not well-formed:" << dgmlPath;
231 mDebug() <<
"Map theme file successfully loaded:" << dgmlPath;
234 GeoSceneDocument* document =
static_cast<GeoSceneDocument*
>( parser.releaseDocument() );
235 Q_ASSERT( document );
239 QStringList MapThemeManager::Private::pathsToWatch()
245 if( !
QDir().exists( localMapPathName ) ) {
249 result << localMapPathName;
250 result << systemMapPathName;
251 addMapThemePaths( localMapPathName, result );
252 addMapThemePaths( systemMapPathName, result );
258 const QString mapPathName = basePath +
'/' + mapDirName;
265 | QDir::NoDotAndDotDot );
268 for (
int planet = 0; planet < mapPaths.
size(); ++planet ) {
269 QDir themeDir =
QDir( mapPathName +
'/' + mapPaths.
at( planet ) );
274 QDir::NoDotAndDotDot );
275 for (
int theme = 0; theme < themeMapPaths.size(); ++theme ) {
276 mapDirs << mapPathName +
'/' + mapPaths.
at( planet ) +
'/'
277 + themeMapPaths.at( theme );
282 QStringListIterator it( mapDirs );
283 while ( it.hasNext() ) {
284 QString themeDir = it.next() +
'/';
287 QDir::Files | QDir::NoSymLinks );
289 QStringListIterator k( tmp );
290 while ( k.hasNext() ) {
292 mapFiles << themeDirName +
'/' + themeXml;
300 QStringList MapThemeManager::Private::findMapThemes()
305 allMapFiles << mapFilesSystem;
309 for (
int i = 1; i < allMapFiles.size(); ++i ) {
310 if ( allMapFiles.at(i) == allMapFiles.at( i-1 ) ) {
311 allMapFiles.removeAt( i );
321 if ( !d->m_isInitialized ) {
322 d->updateMapThemeModel();
323 d->m_isInitialized =
true;
325 return &d->m_mapThemeModel;
330 if ( !d->m_isInitialized ) {
331 d->updateMapThemeModel();
332 d->m_isInitialized =
true;
335 return &d->m_celestialList;
343 if ( !mapTheme || !mapTheme->head()->visible() ) {
350 relativePath = mapDirName +
'/'
351 + mapTheme->head()->target() +
'/' + mapTheme->head()->theme() +
'/'
352 + mapTheme->head()->icon()->pixmap();
355 if ( themeIconPixmap.
isNull() ) {
356 relativePath =
"svg/application-x-marble-gray.png";
363 QSize maxIconSize( 136, 136 );
364 if ( themeIconPixmap.
size() != maxIconSize ) {
365 mDebug() <<
"Smooth scaling theme icon";
366 themeIconPixmap = themeIconPixmap.
scaled( maxIconSize,
368 Qt::SmoothTransformation );
372 QIcon mapThemeIcon =
QIcon( themeIconPixmap );
374 QString name = mapTheme->head()->name();
375 QString description = mapTheme->head()->description();
379 item->
setData( mapThemeIcon, Qt::DecorationRole );
382 item->
setData( mapThemeID, Qt::UserRole + 1 );
390 void MapThemeManager::Private::updateMapThemeModel()
392 mDebug() <<
"updateMapThemeModel";
393 m_mapThemeModel.clear();
395 m_mapThemeModel.setHeaderData(0, Qt::Horizontal,
QObject::tr(
"Name"));
398 QStringListIterator it( stringlist );
400 while ( it.hasNext() ) {
401 QString mapThemeID = it.next();
404 if ( !itemList.
empty() ) {
405 m_mapThemeModel.appendRow( itemList );
409 foreach (
const QString &mapThemeId, stringlist ) {
413 QList<QStandardItem*> matchingItems = m_celestialList.findItems( celestialBodyId, Qt::MatchExactly, 1 );
414 if ( matchingItems.
isEmpty() ) {
422 void MapThemeManager::Private::watchPaths()
425 QStringList const files = m_fileSystemWatcher.files();
426 QStringList const directories = m_fileSystemWatcher.directories();
429 foreach(
const QString &resource, paths ) {
431 m_fileSystemWatcher.addPath( resource );
436 void MapThemeManager::Private::directoryChanged(
const QString& path )
438 mDebug() <<
"directoryChanged:" << path;
441 mDebug() <<
"Emitting themesChanged()";
442 updateMapThemeModel();
443 emit q->themesChanged();
446 void MapThemeManager::Private::fileChanged(
const QString& path )
448 mDebug() <<
"fileChanged:" << path;
456 mDebug() <<
"mapThemeId:" << mapThemeId;
459 | Qt::MatchCaseSensitive,
460 columnRelativePath );
461 mDebug() <<
"matchingItems:" << matchingItems.
size();
462 Q_ASSERT( matchingItems.
size() <= 1 );
465 if ( matchingItems.
size() == 1 ) {
466 const int row = matchingItems.
front()->row();
469 while ( !toBeDeleted.
isEmpty() ) {
475 if ( fileInfo.exists() ) {
477 if ( !newMapThemeRow.
empty() ) {
478 m_mapThemeModel.insertRow( insertAtRow, newMapThemeRow );
482 emit q->themesChanged();
488 void MapThemeManager::Private::addMapThemePaths(
const QString& mapPathName,
QStringList& result )
490 QDir mapPath( mapPathName );
494 | QDir::NoDotAndDotDot );
495 QStringListIterator itOrb( orbDirNames );
496 while ( itOrb.hasNext() ) {
497 QString orbPathName = mapPathName +
'/' + itOrb.next();
498 result << orbPathName;
500 QDir orbPath( orbPathName );
504 | QDir::NoDotAndDotDot );
505 QStringListIterator itThemeDir( themeDirNames );
506 while ( itThemeDir.hasNext() ) {
507 QString themePathName = orbPathName +
'/' + itThemeDir.next();
508 result << themePathName;
510 QDir themePath( themePathName );
513 | QDir::NoSymLinks );
514 QStringListIterator itThemeFile( themeFileNames );
515 while ( itThemeFile.hasNext() ) {
516 QString themeFilePathName = themePathName +
'/' + itThemeFile.next();
517 result << themeFilePathName;
525 #include "MapThemeManager.moc"
QStandardItemModel * mapThemeModel()
Provides a model of the locally existing themes.
static QString path(const QString &relativePath)
MapThemeManager(QObject *parent=0)
const T & at(int i) const
Provides access to all map themes installed locally.
bool contains(const QString &str, Qt::CaseSensitivity cs) const
static QString localPath()
QString tr(const char *sourceText, const char *disambiguation, int n)
virtual void setData(const QVariant &value, int role)
QString absoluteFilePath() const
static GeoSceneDocument * loadMapTheme(const QString &mapThemeStringID)
Returns the map theme as a GeoSceneDocument object.
static void deleteMapTheme(const QString &mapThemeId)
Deletes the map theme with the specified map theme ID.
QPixmap scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
bool load(const QString &fileName, const char *format, QFlags< Qt::ImageConversionFlag > flags)
A container for features parsed from the DGML file.
QString absolutePath() const
QStringList entryList(QFlags< QDir::Filter > filters, QFlags< QDir::SortFlag > sort) const
QString section(QChar sep, int start, int end, QFlags< QString::SectionFlag > flags) const
QString name() const
The user visible name of the planet.
static QString systemPath()
QStringList mapThemeIds() const
Returns a list of all locally available map theme IDs.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QDebug mDebug()
a function to replace qDebug() in Marble library code
QStandardItemModel * celestialBodiesModel()
Provides a model of all installed planets.
bool mkpath(const QString &dirPath) const
QByteArray toUtf8() const