File indexing completed on 2024-04-21 03:48:35

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
0004 // SPDX-FileCopyrightText: 2008 Inge Wallin <inge@lysator.liu.se>
0005 // SPDX-FileCopyrightText: 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
0006 // SPDX-FileCopyrightText: 2010 Harshit Jain <hjain.itbhu@gmail.com>
0007 //
0008 
0009 // Own
0010 #include "marble_part.h"
0011 
0012 // Qt
0013 #include <QDir>
0014 #include <QPointer>
0015 #include <QStringList>
0016 #include <QClipboard>
0017 #include <QLabel>
0018 #include <QFontMetrics>
0019 #include <QPrinter>
0020 #include <QPrintDialog>
0021 #include <QProgressBar>
0022 #include <QStandardItemModel>
0023 #include <QNetworkProxy>
0024 #include <QDomDocument>
0025 #include <QDomNodeList>
0026 #include <QFileDialog>
0027 #include <QMenu>
0028 #include <QStatusBar>
0029 
0030 // KF
0031 #include <KAboutData>
0032 #include <KActionCollection>
0033 #include <KConfigDialog>
0034 #include <KLocalizedString>
0035 #include <KMessageBox>
0036 #include <KPluginFactory>
0037 #include <kparts/statusbarextension.h>
0038 #include <KStandardAction>
0039 #include <KToggleAction>
0040 #include <KToggleFullScreenAction>
0041 
0042 // Marble library classes
0043 #include "AbstractFloatItem.h"
0044 #include "EditBookmarkDialog.h"
0045 #include "BookmarkManager.h"
0046 #include "BookmarkManagerDialog.h"
0047 #include "CurrentLocationWidget.h"
0048 #include "DownloadRegionDialog.h"
0049 #include "FileManager.h"
0050 #include "GeoDataCoordinates.h"
0051 #include "GeoDataFolder.h"
0052 #include "GeoDataLatLonAltBox.h"
0053 #include "GeoDataLookAt.h"
0054 #include "GeoDataPlacemark.h"
0055 #include "HttpDownloadManager.h"
0056 #include "MarbleDirs.h"
0057 #include "MarbleDebug.h"
0058 #include "MarbleLocale.h"
0059 #include "MarbleModel.h"
0060 #include "MarblePluginSettingsWidget.h"
0061 #include "MapWizard.h"
0062 #include "NewBookmarkFolderDialog.h"
0063 #include "RenderPluginModel.h"
0064 #include "routing/RoutingManager.h"
0065 #include "routing/RoutingProfilesModel.h"
0066 #include "routing/RoutingProfilesWidget.h"
0067 #include "routing/RouteRequest.h"
0068 #include "SunControlWidget.h"
0069 #include "TimeControlWidget.h"
0070 #include "TileCoordsPyramid.h"
0071 #include "ViewportParams.h"
0072 #include "MarbleClock.h"
0073 #include "ParseRunnerPlugin.h"
0074 #include "PositionTracking.h"
0075 #include "PositionProviderPlugin.h"
0076 #include "PluginManager.h"
0077 #include "SearchInputWidget.h"
0078 #include "MarbleWidgetInputHandler.h"
0079 #include "Planet.h"
0080 #include "MapThemeDownloadDialog.h"
0081 #include "cloudsync/BookmarkSyncManager.h"
0082 #include "MovieCaptureDialog.h"
0083 #include "cloudsync/RouteSyncManager.h"
0084 #include "cloudsync/CloudSyncManager.h"
0085 
0086 // Marble non-library classes
0087 #include "ControlView.h"
0088 #include "settings.h"
0089 
0090 using namespace Marble;
0091 
0092 #include "ui_MarbleCacheSettingsWidget.h"
0093 #include "ui_MarbleViewSettingsWidget.h"
0094 #include "ui_MarbleNavigationSettingsWidget.h"
0095 #include "ui_MarbleTimeSettingsWidget.h"
0096 
0097 namespace Marble
0098 {
0099 
0100 namespace
0101 {
0102     const char POSITION_STRING[] = I18N_NOOP( "Position: %1" );
0103     const char DISTANCE_STRING[] = I18N_NOOP( "Altitude: %1" );
0104     const char TILEZOOMLEVEL_STRING[] = I18N_NOOP( "Tile Zoom Level: %1" );
0105     const char DATETIME_STRING[] = I18N_NOOP( "Time: %1" );
0106 }
0107 
0108 K_PLUGIN_FACTORY(MarblePartFactory, registerPlugin<MarblePart>();)
0109 K_EXPORT_PLUGIN(MarblePartFactory("marble"))
0110 
0111 MarblePart::MarblePart( QWidget *parentWidget, QObject *parent, const QVariantList &arguments )
0112   : KParts::ReadOnlyPart( parent ),
0113     m_sunControlDialog( nullptr ),
0114     m_timeControlDialog( nullptr ),
0115     m_downloadRegionDialog( nullptr ),
0116     m_movieCaptureDialog( nullptr ),
0117     m_externalMapEditorAction( nullptr ),
0118     m_recordMovieAction( nullptr ),
0119     m_stopRecordingAction( nullptr ),
0120     m_recentFilesAction( nullptr ),
0121     m_configDialog( nullptr ),
0122     m_position( QCoreApplication::translate( "Marble", NOT_AVAILABLE ) ),
0123     m_tileZoomLevel( QCoreApplication::translate( "Marble", NOT_AVAILABLE ) ),
0124     m_positionLabel( nullptr ),
0125     m_distanceLabel( nullptr )
0126 {
0127     // only set marble data path when a path was given
0128     if ( arguments.count() != 0 && !arguments.first().toString().isEmpty() )
0129         MarbleDirs::setMarbleDataPath( arguments.first().toString() );
0130 
0131     // Setting measure system to provide nice standards for all unit questions.
0132     // This has to happen before any initialization so plugins (for example) can
0133     // use it during initialization.
0134     MarbleLocale *marbleLocale = MarbleGlobal::getInstance()->locale();
0135     // KF5 TODO: Read Connecting Calls to Catalogs" in ki18n programmer's guide
0136     //           and enable translations
0137     //     KLocale *kLocale = KGlobal::locale();
0138 //     if ( kLocale->measureSystem() == KLocale::Metric ) {
0139 //         marbleLocale->setMeasurementSystem( QLocale::MetricSystem );
0140 //     }
0141 //     else {
0142 //         marbleLocale->setMeasurementSystem( QLocale::ImperialSystem );
0143 //     }
0144 
0145     marbleLocale->setMeasurementSystem( MarbleLocale::ImperialSystem );
0146     migrateNewstuffConfigFiles();
0147 
0148     m_externalEditorMapping[0] = "";
0149     m_externalEditorMapping[1] = "potlatch";
0150     m_externalEditorMapping[2] = "josm";
0151     m_externalEditorMapping[3] = "merkaartor";
0152 
0153     m_controlView = new ControlView( parentWidget );
0154 
0155     setWidget( m_controlView );
0156 
0157     setupActions();
0158 
0159     setXMLFile( "marble_part.rc" );
0160 
0161     m_statusBarExtension = new KParts::StatusBarExtension( this );
0162     m_statusBarExtension->statusBar()->setUpdatesEnabled( false );
0163 
0164     connect(m_controlView->marbleModel()->fileManager(), &FileManager::fileError, this,
0165         [this](const QString& path, const QString& error) {
0166         KMessageBox::error( widget(),
0167         i18n( "Sorry, unable to open '%1':\n'%2'", path, error),
0168         i18n( "File not readable" ) );
0169         });
0170 
0171     // Load bookmark file. If it does not exist, a default one will be used.
0172     m_controlView->marbleModel()->bookmarkManager()->loadFile( "bookmarks/bookmarks.kml" );
0173 
0174     initializeCustomTimezone();
0175 
0176     setupStatusBar();
0177     readSettings();
0178     m_statusBarExtension->statusBar()->setUpdatesEnabled( true );
0179 
0180     // Show startup location
0181     switch ( MarbleSettings::onStartup() ) {
0182     case LastLocationVisited: {
0183             GeoDataLookAt target;
0184             target.setLongitude( MarbleSettings::quitLongitude() );
0185             target.setLatitude( MarbleSettings::quitLatitude() );
0186             target.setRange( MarbleSettings::quitRange() );
0187             m_controlView->marbleWidget()->flyTo( target, Instant );
0188         }
0189         break;
0190     case ShowHomeLocation:
0191         m_controlView->marbleWidget()->goHome( Instant );
0192         break;
0193     }
0194 
0195     connect( m_controlView, SIGNAL(showMapWizard()), this, SLOT(showMapWizard()) );
0196     connect( m_controlView, SIGNAL(mapThemeDeleted()), this, SLOT(fallBackToDefaultTheme()) );
0197 }
0198 
0199 MarblePart::~MarblePart()
0200 {
0201     writeSettings();
0202 
0203     // Check whether this delete is really needed.
0204     delete m_configDialog;
0205 }
0206 
0207 ControlView* MarblePart::controlView() const
0208 {
0209     return m_controlView;
0210 }
0211 
0212 KAboutData *MarblePart::createAboutData()
0213 {
0214     return new KAboutData( QString( I18N_NOOP( "marble_part" ) ),
0215                            QString( "Marble" ),
0216                            ControlView::applicationVersion(),
0217                            i18n( "A Virtual Globe" ),
0218                            KAboutLicense::LGPL_V2 );
0219 }
0220 
0221 bool MarblePart::openUrl( const QUrl &url )
0222 {
0223     QFileInfo fileInfo( url.toLocalFile() );
0224     if ( fileInfo.isReadable() ) {
0225         m_controlView->marbleModel()->addGeoDataFile( url.toLocalFile() );
0226         m_recentFilesAction->addUrl( url );
0227         return true;
0228     }
0229 
0230     KMessageBox::error( widget(),
0231         i18n( "Sorry, unable to open '%1'. The file is not accessible.", fileInfo.fileName() ),
0232         i18n( "File not accessible" ) );
0233     return false;
0234 }
0235 
0236 bool MarblePart::openFile()
0237 {
0238     const PluginManager *const pluginManager = m_controlView->marbleModel()->pluginManager();
0239 
0240     QStringList allFileExtensions;
0241     QStringList filters;
0242     for ( const ParseRunnerPlugin *plugin: pluginManager->parsingRunnerPlugins() ) {
0243         if (plugin->nameId() == QLatin1String("Cache"))
0244             continue;
0245 
0246         const QStringList fileExtensions = plugin->fileExtensions().replaceInStrings( QRegExp( "^" ), "*." );
0247         const QString filter = plugin->fileFormatDescription() + QLatin1String(" (") + fileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')');
0248         filters << filter;
0249         allFileExtensions << fileExtensions;
0250     }
0251 
0252     allFileExtensions.sort();  // sort since file extensions are visible under Windows
0253     const QString allFileTypes = i18n("All Supported Files") + QLatin1String(" (") + allFileExtensions.join(QLatin1Char(' ')) + QLatin1Char(')');
0254 
0255     filters.sort();
0256     filters.prepend( allFileTypes );
0257     const QString filter = filters.join( ";;" );
0258 
0259     QStringList fileNames = QFileDialog::getOpenFileNames( widget(), i18nc("@title:window", "Open File"),
0260                                                            m_lastFileOpenPath, filter );
0261 
0262     if ( !fileNames.isEmpty() ) {
0263         const QString firstFile = fileNames.first();
0264         m_lastFileOpenPath = QFileInfo( firstFile ).absolutePath();
0265     }
0266 
0267     for( const QString &fileName: fileNames ) {
0268         openUrl( QUrl::fromLocalFile(fileName) );
0269     }
0270 
0271     return true;
0272 }
0273 
0274 void MarblePart::exportMapScreenShot()
0275 {
0276     QString  fileName = QFileDialog::getSaveFileName( widget(), i18nc("@title:window", "Export Map"), QDir::homePath(),
0277                                                       i18n( "Images *.jpg *.png" ) );
0278 
0279     if ( !fileName.isEmpty() ) {
0280         // Take the case into account where no file format is indicated
0281         const char * format = nullptr;
0282         if ( !fileName.endsWith(QLatin1String( "png" ), Qt::CaseInsensitive)
0283            && !fileName.endsWith(QLatin1String( "jpg" ), Qt::CaseInsensitive) )
0284         {
0285             format = "JPG";
0286         }
0287 
0288         QPixmap mapPixmap = m_controlView->mapScreenShot();
0289         bool  success = mapPixmap.save( fileName, format );
0290         if ( !success ) {
0291             KMessageBox::error( widget(), i18nc( "Application name", "Marble" ),
0292                                 i18n( "An error occurred while trying to save the file.\n" ),
0293                                 KMessageBox::Notify );
0294         }
0295     }
0296 }
0297 
0298 void MarblePart::setShowBookmarks( bool show )
0299 {
0300     m_controlView->marbleModel()->bookmarkManager()->setShowBookmarks( show );
0301 
0302     m_toggleBookmarkDisplayAction->setChecked( show ); // Sync state with the GUI
0303 }
0304 
0305 void MarblePart::setShowClouds( bool isChecked )
0306 {
0307     m_controlView->marbleWidget()->setShowClouds( isChecked );
0308 
0309     m_showCloudsAction->setChecked( isChecked ); // Sync state with the GUI
0310 }
0311 
0312 void MarblePart::showPositionLabel( bool isChecked )
0313 {
0314     m_positionLabel->setVisible( isChecked );
0315 }
0316 
0317 void MarblePart::showAltitudeLabel( bool isChecked )
0318 {
0319     m_distanceLabel->setVisible( isChecked );
0320 }
0321 
0322 void MarblePart::showTileZoomLevelLabel( bool isChecked )
0323 {
0324     m_tileZoomLevelLabel->setVisible( isChecked );
0325 }
0326 
0327 void MarblePart::showDateTimeLabel( bool isChecked )
0328 {
0329     m_clockLabel->setVisible( isChecked );
0330 }
0331 
0332 void MarblePart::showDownloadProgressBar( bool isChecked )
0333 {
0334     MarbleSettings::setShowDownloadProgressBar( isChecked );
0335     // Change visibility only if there is a download happening
0336     m_downloadProgressBar->setVisible( isChecked && m_downloadProgressBar->value() >= 0 );
0337 }
0338 
0339 void MarblePart::showFullScreen( bool isChecked )
0340 {
0341     if ( QApplication::activeWindow() )
0342         KToggleFullScreenAction::setFullScreen( QApplication::activeWindow(), isChecked );
0343 
0344     m_fullScreenAct->setChecked( isChecked ); // Sync state with the GUI
0345 }
0346 
0347 void MarblePart::showStatusBar( bool isChecked )
0348 {
0349     if ( !m_statusBarExtension->statusBar() )
0350         return;
0351 
0352     m_statusBarExtension->statusBar()->setVisible( isChecked );
0353 }
0354 
0355 void MarblePart::controlSun()
0356 {
0357     if ( !m_sunControlDialog ) {
0358         m_sunControlDialog = new SunControlWidget( m_controlView->marbleWidget(), m_controlView );
0359         connect( m_sunControlDialog, SIGNAL(showSun(bool)),
0360                  this,               SLOT (showSun(bool)) );
0361         connect( m_sunControlDialog, SIGNAL(showSun(bool)),
0362                  m_showShadow,               SLOT (setChecked(bool)) );
0363         connect( m_sunControlDialog,    SIGNAL(isLockedToSubSolarPoint(bool)),
0364                  m_lockToSubSolarPoint, SLOT (setChecked(bool)) );
0365         connect( m_sunControlDialog,         SIGNAL(isSubSolarPointIconVisible(bool)),
0366                  m_setSubSolarPointIconVisible, SLOT (setChecked(bool)) );
0367     }
0368 
0369     m_sunControlDialog->show();
0370     m_sunControlDialog->raise();
0371     m_sunControlDialog->activateWindow();
0372 }
0373 
0374 void MarblePart::controlTime()
0375 {
0376     if ( !m_timeControlDialog )
0377     {
0378         m_timeControlDialog = new TimeControlWidget( m_controlView->marbleModel()->clock() );
0379     }
0380     m_timeControlDialog->show();
0381     m_timeControlDialog->raise();
0382     m_timeControlDialog->activateWindow();
0383 }
0384 
0385 
0386 void MarblePart::showSun( bool active )
0387 {
0388     m_controlView->marbleWidget()->setShowSunShading( active );
0389     m_sunControlDialog->setSunShading( active );
0390 }
0391 
0392 void MarblePart::lockToSubSolarPoint( bool lock )
0393 {
0394     m_controlView->marbleWidget()->setLockToSubSolarPoint( lock );
0395 }
0396 
0397 void MarblePart::setSubSolarPointIconVisible( bool show )
0398 {
0399     m_controlView->marbleWidget()->setSubSolarPointIconVisible( show );
0400 }
0401 
0402 void MarblePart::workOffline( bool offline )
0403 {
0404     m_controlView->setWorkOffline( offline );
0405     m_newStuffAction->setEnabled( !offline );
0406     m_downloadRegionAction->setEnabled( !offline );
0407 }
0408 
0409 void MarblePart::copyMap()
0410 {
0411     QPixmap      mapPixmap = m_controlView->mapScreenShot();
0412     QClipboard  *clipboard = QApplication::clipboard();
0413 
0414     clipboard->setPixmap( mapPixmap );
0415 }
0416 
0417 void MarblePart::copyCoordinates()
0418 {
0419     qreal lon = m_controlView->marbleWidget()->centerLongitude();
0420     qreal lat = m_controlView->marbleWidget()->centerLatitude();
0421 
0422     QString  positionString = GeoDataCoordinates( lon, lat, 0.0, GeoDataCoordinates::Degree ).toString();
0423     QClipboard  *clipboard = QApplication::clipboard();
0424 
0425     clipboard->setText( positionString );
0426 }
0427 
0428 void MarblePart::readSettings()
0429 {
0430     qDebug() << "start";
0431 
0432     // Set home position
0433     m_controlView->marbleModel()->setHome( MarbleSettings::homeLongitude(),
0434                                            MarbleSettings::homeLatitude(),
0435                                            MarbleSettings::homeZoom() );
0436 
0437     // Map theme and projection
0438     QString mapTheme = MarbleSettings::mapTheme();
0439     if ( mapTheme.isEmpty() ) {
0440         mapTheme = m_controlView->defaultMapThemeId();
0441     }
0442     m_controlView->marbleWidget()->setMapThemeId( mapTheme );
0443     m_controlView->marbleWidget()->setProjection( (Projection) MarbleSettings::projection() );
0444 
0445     m_controlView->marbleWidget()->setShowClouds( MarbleSettings::showClouds() );
0446     m_showCloudsAction->setChecked( MarbleSettings::showClouds() );
0447 
0448     workOffline( MarbleSettings::workOffline() );
0449     m_workOfflineAction->setChecked( MarbleSettings::workOffline() );
0450 
0451     m_lockFloatItemsAct->setChecked(MarbleSettings::lockFloatItemPositions());
0452     lockFloatItemPosition(MarbleSettings::lockFloatItemPositions());
0453 
0454     setShowBookmarks( MarbleSettings::showBookmarks() );
0455 
0456     // Sun
0457     m_controlView->marbleWidget()->setShowSunShading( MarbleSettings::showSun() );
0458     m_showShadow->setChecked( MarbleSettings::showSun() );
0459     m_controlView->marbleWidget()->setShowCityLights( MarbleSettings::showCitylights() );
0460     m_controlView->marbleWidget()->setSubSolarPointIconVisible( MarbleSettings::subSolarPointIconVisible() );
0461     m_controlView->marbleWidget()->setLockToSubSolarPoint( MarbleSettings::lockToSubSolarPoint() );
0462     m_setSubSolarPointIconVisible->setChecked( MarbleSettings::subSolarPointIconVisible() );
0463     m_lockToSubSolarPoint->setChecked( MarbleSettings::lockToSubSolarPoint() );
0464 
0465     // View
0466     m_lastFileOpenPath = MarbleSettings::lastFileOpenDir();
0467 
0468     // Tracking settings
0469     readTrackingSettings();
0470 
0471     // Load previous route settings
0472     m_controlView->marbleModel()->routingManager()->readSettings();
0473     bool const startupWarning = MarbleSettings::showGuidanceModeStartupWarning();
0474     m_controlView->marbleModel()->routingManager()->setShowGuidanceModeStartupWarning( startupWarning );
0475 
0476     KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
0477     if ( sharedConfig->hasGroup( "Routing Profiles" ) ) {
0478         QList<RoutingProfile> profiles;
0479         KConfigGroup profilesGroup = sharedConfig->group( "Routing Profiles" );
0480         int numProfiles = profilesGroup.readEntry( "Num", 0 );
0481         for ( int i = 0; i < numProfiles; ++i ) {
0482             KConfigGroup profileGroup = profilesGroup.group( QString( "Profile %0" ).arg(i) );
0483             QString name = profileGroup.readEntry( "Name", i18n( "Unnamed" ) );
0484             RoutingProfile profile( name );
0485             for ( const QString& pluginName: profileGroup.groupList() ) {
0486                 KConfigGroup pluginGroup = profileGroup.group( pluginName );
0487                 profile.pluginSettings().insert( pluginName, QHash<QString, QVariant>() );
0488                 for ( const QString& key: pluginGroup.keyList() ) {
0489                     if (key != QLatin1String("Enabled")) {
0490                         profile.pluginSettings()[ pluginName ].insert( key, pluginGroup.readEntry( key ) );
0491                     }
0492                 }
0493             }
0494             profiles << profile;
0495         }
0496         m_controlView->marbleModel()->routingManager()->profilesModel()->setProfiles( profiles );
0497     } else {
0498         m_controlView->marbleModel()->routingManager()->profilesModel()->loadDefaultProfiles();
0499     }
0500     int const profileIndex = MarbleSettings::currentRoutingProfile();
0501     if ( profileIndex >= 0 && profileIndex < m_controlView->marbleModel()->routingManager()->profilesModel()->rowCount() ) {
0502         RoutingProfile profile = m_controlView->marbleModel()->routingManager()->profilesModel()->profiles().at( profileIndex );
0503         m_controlView->marbleModel()->routingManager()->routeRequest()->setRoutingProfile( profile );
0504     }
0505 
0506     PositionTracking *const tracking = m_controlView->marbleModel()->positionTracking();
0507     tracking->readSettings();
0508     QString positionProvider = MarbleSettings::activePositionTrackingPlugin();
0509     if ( !positionProvider.isEmpty() ) {
0510         const PluginManager* pluginManager = m_controlView->marbleModel()->pluginManager();
0511         for( const PositionProviderPlugin* plugin: pluginManager->positionProviderPlugins() ) {
0512             if ( plugin->nameId() == positionProvider ) {
0513                 PositionProviderPlugin* instance = plugin->newInstance();
0514                 tracking->setPositionProviderPlugin( instance );
0515                 break;
0516             }
0517         }
0518     }
0519 
0520     readStatusBarSettings();
0521 
0522     updateSettings();
0523 
0524     // Time
0525     if( MarbleSettings::systemTime() == true  )
0526     {
0527         /* nothing to do */
0528     }
0529     else if( MarbleSettings::lastSessionTime() == true )
0530     {
0531         m_controlView->marbleModel()->setClockDateTime( MarbleSettings::dateTime() );
0532         m_controlView->marbleModel()->setClockSpeed( MarbleSettings::speedSlider() );
0533     }
0534 
0535     readPluginSettings();
0536 
0537     m_controlView->setExternalMapEditor( m_externalEditorMapping[MarbleSettings::externalMapEditor()] );
0538 
0539     CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager();
0540     cloudSyncManager->setOwncloudCredentials( MarbleSettings::owncloudServer(),
0541                                               MarbleSettings::owncloudUsername(),
0542                                               MarbleSettings::owncloudPassword());
0543     cloudSyncManager->setSyncEnabled( MarbleSettings::enableSync() );
0544     cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( MarbleSettings::syncRoutes() );
0545     cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( MarbleSettings::syncBookmarks() );
0546 }
0547 
0548 void MarblePart::readTrackingSettings()
0549 {
0550     if( MarbleSettings::autoCenter() || MarbleSettings::recenterMode() ) {
0551         CurrentLocationWidget *trackingWidget = m_controlView->currentLocationWidget();
0552         if( trackingWidget ) {
0553             trackingWidget->setRecenterMode( MarbleSettings::recenterMode() );
0554             trackingWidget->setAutoZoom( MarbleSettings::autoZoom() );
0555             trackingWidget->setTrackVisible( MarbleSettings::trackVisible() );
0556             trackingWidget->setLastOpenPath( MarbleSettings::lastTrackOpenPath() );
0557             trackingWidget->setLastSavePath( MarbleSettings::lastTrackSavePath() );
0558         }
0559     }
0560 }
0561 
0562 void MarblePart::readStatusBarSettings()
0563 {
0564     const bool showPos = MarbleSettings::showPositionLabel();
0565     m_showPositionAction->setChecked( showPos );
0566     showPositionLabel( showPos );
0567 
0568     const bool showAlt = MarbleSettings::showAltitudeLabel();
0569     m_showAltitudeAction->setChecked( showAlt );
0570     showAltitudeLabel( showAlt );
0571 
0572     const bool showTileZoom = MarbleSettings::showTileZoomLevelLabel();
0573     m_showTileZoomLevelAction->setChecked( showTileZoom );
0574     showTileZoomLevelLabel( showTileZoom );
0575 
0576     const bool showDateTime = MarbleSettings::showDateTimeLabel();
0577     m_showDateTimeAction->setChecked( showDateTime );
0578     showDateTimeLabel( showDateTime );
0579 
0580     const bool showProgress = MarbleSettings::showDownloadProgressBar();
0581     m_showDownloadProgressAction->setChecked( showProgress );
0582     showDownloadProgressBar( showProgress );
0583 }
0584 
0585 void MarblePart::writeSettings()
0586 {
0587     // Get the 'quit' values from the widget and store them in the settings.
0588     qreal  quitLon = m_controlView->marbleWidget()->lookAt().longitude();
0589     qreal  quitLat = m_controlView->marbleWidget()->lookAt().latitude();
0590     qreal  quitRange = m_controlView->marbleWidget()->lookAt().range();
0591 
0592     MarbleSettings::setQuitLongitude( quitLon );
0593     MarbleSettings::setQuitLatitude( quitLat );
0594     MarbleSettings::setQuitRange( quitRange );
0595 
0596     // Get the 'home' values from the widget and store them in the settings.
0597     qreal  homeLon = 0;
0598     qreal  homeLat = 0;
0599     int     homeZoom = 0;
0600 
0601     m_controlView->marbleModel()->home( homeLon, homeLat, homeZoom );
0602     MarbleSettings::setHomeLongitude( homeLon );
0603     MarbleSettings::setHomeLatitude( homeLat );
0604     MarbleSettings::setHomeZoom( homeZoom );
0605 
0606     // Set default font
0607     MarbleSettings::setMapFont( m_controlView->marbleWidget()->defaultFont() );
0608 
0609     // Get whether animations to the target are enabled
0610     MarbleSettings::setAnimateTargetVoyage( m_controlView->marbleWidget()->animationsEnabled() );
0611 
0612     // Map theme and projection
0613     MarbleSettings::setMapTheme( m_controlView->marbleWidget()->mapThemeId() );
0614     MarbleSettings::setProjection( m_controlView->marbleWidget()->projection() );
0615 
0616     MarbleSettings::setShowClouds( m_controlView->marbleWidget()->showClouds() );
0617 
0618     MarbleSettings::setWorkOffline( m_workOfflineAction->isChecked() );
0619 
0620     MarbleSettings::setStillQuality( m_controlView->marbleWidget()->mapQuality( Still ) );
0621     MarbleSettings::setAnimationQuality( m_controlView->marbleWidget()->
0622                                          mapQuality( Animation ) );
0623 
0624     MarbleSettings::setShowBookmarks( m_controlView->marbleModel()->bookmarkManager()->showBookmarks() );
0625 
0626     MarbleSettings::setLastFileOpenDir( m_lastFileOpenPath );
0627 
0628     MarbleSettings::setDistanceUnit( MarbleGlobal::getInstance()->locale()->measurementSystem() );
0629     MarbleSettings::setAngleUnit( m_controlView->marbleWidget()->defaultAngleUnit() );
0630 
0631     // Sun
0632     MarbleSettings::setShowSun( m_controlView->marbleWidget()->showSunShading() );
0633     MarbleSettings::setShowCitylights( m_controlView->marbleWidget()->showCityLights() );
0634     MarbleSettings::setLockToSubSolarPoint( m_controlView->marbleWidget()->isLockedToSubSolarPoint() );
0635     MarbleSettings::setSubSolarPointIconVisible( m_controlView->marbleWidget()->isSubSolarPointIconVisible() );
0636 
0637     // Tracking
0638     CurrentLocationWidget *trackingWidget = m_controlView->currentLocationWidget();
0639     if( trackingWidget )
0640     {
0641         MarbleSettings::setRecenterMode( trackingWidget->recenterMode() );
0642         MarbleSettings::setAutoZoom( trackingWidget->autoZoom() );
0643         MarbleSettings::setTrackVisible( trackingWidget->trackVisible() );
0644         MarbleSettings::setLastTrackOpenPath( trackingWidget->lastOpenPath() );
0645         MarbleSettings::setLastTrackSavePath( trackingWidget->lastSavePath() );
0646     }
0647 
0648     // Caches
0649     MarbleSettings::setVolatileTileCacheLimit( m_controlView->marbleWidget()->
0650                                                volatileTileCacheLimit() / 1024 );
0651     MarbleSettings::setPersistentTileCacheLimit( m_controlView->marbleModel()->
0652                                                  persistentTileCacheLimit() / 1024 );
0653 
0654     // Time
0655     MarbleSettings::setDateTime( m_controlView->marbleModel()->clockDateTime() );
0656     MarbleSettings::setSpeedSlider( m_controlView->marbleModel()->clockSpeed() );
0657 
0658     // Plugins
0659     writePluginSettings();
0660 
0661     QString positionProvider;
0662     PositionTracking* tracking = m_controlView->marbleModel()->positionTracking();
0663     tracking->writeSettings();
0664     if ( tracking->positionProviderPlugin() ) {
0665         positionProvider = tracking->positionProviderPlugin()->nameId();
0666     }
0667     MarbleSettings::setActivePositionTrackingPlugin( positionProvider );
0668 
0669     MarbleSettings::setLockFloatItemPositions( m_lockFloatItemsAct->isChecked() );
0670 
0671     writeStatusBarSettings();
0672 
0673     // Store recent files
0674     KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
0675     m_recentFilesAction->saveEntries( sharedConfig->group( "RecentFiles" ) );
0676 
0677     // Store current route settings
0678     RoutingManager *routingManager = m_controlView->marbleWidget()->model()->routingManager();
0679     routingManager->writeSettings();
0680     bool const startupWarning = routingManager->showGuidanceModeStartupWarning();
0681     MarbleSettings::setShowGuidanceModeStartupWarning( startupWarning );
0682     QList<RoutingProfile>  profiles = routingManager->profilesModel()->profiles();
0683     RoutingProfile const profile = routingManager->routeRequest()->routingProfile();
0684     MarbleSettings::setCurrentRoutingProfile( profiles.indexOf( profile ) );
0685 
0686     QList<QString> const editors = m_externalEditorMapping.values();
0687     MarbleSettings::setExternalMapEditor( editors.indexOf( m_controlView->externalMapEditor() ) );
0688 
0689     applyPluginState();
0690 
0691     MarbleSettings::self()->save();
0692 }
0693 
0694 void MarblePart::writeStatusBarSettings()
0695 {
0696     MarbleSettings::setShowPositionLabel( m_showPositionAction->isChecked() );
0697     MarbleSettings::setShowAltitudeLabel( m_showAltitudeAction->isChecked() );
0698     MarbleSettings::setShowTileZoomLevelLabel( m_showTileZoomLevelAction->isChecked() );
0699     MarbleSettings::setShowDateTimeLabel( m_showDateTimeAction->isChecked() );
0700     MarbleSettings::setShowDownloadProgressBar( m_showDownloadProgressAction->isChecked() );
0701 }
0702 
0703 void MarblePart::setupActions()
0704 {
0705     // Action: Recent Files
0706     m_recentFilesAction = KStandardAction::openRecent( this, SLOT(openUrl(QUrl)),
0707                                                        actionCollection() );
0708     KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
0709     m_recentFilesAction->loadEntries( sharedConfig->group( "RecentFiles" ) );
0710 
0711     // Action: Download Region
0712     m_downloadRegionAction = new QAction( this );
0713     m_downloadRegionAction->setText( i18nc( "Action for downloading an entire region of a map",
0714                                             "Download Region..." ));
0715     actionCollection()->addAction( "file_download_region", m_downloadRegionAction );
0716     connect( m_downloadRegionAction, SIGNAL(triggered()), SLOT(showDownloadRegionDialog()));
0717 
0718     // Action: Print Map
0719     m_printMapAction = KStandardAction::print( this, SLOT(printMapScreenShot()),
0720                                                actionCollection() );
0721 
0722     m_printPreviewAction = KStandardAction::printPreview( m_controlView, SLOT(printPreview()),
0723                                                actionCollection() );
0724 
0725     // Action: Export Map
0726     m_exportMapAction = new QAction( this );
0727     actionCollection()->addAction( "exportMap", m_exportMapAction );
0728     m_exportMapAction->setText( i18nc( "Action for saving the map to a file", "&Export Map..." ) );
0729     m_exportMapAction->setIcon( QIcon::fromTheme( "document-save-as" ) );
0730     actionCollection()->setDefaultShortcut( m_exportMapAction, Qt::CTRL | Qt::Key_S );
0731     connect( m_exportMapAction, SIGNAL(triggered(bool)),
0732              this,              SLOT(exportMapScreenShot()) );
0733 
0734     // Action: Work Offline
0735     m_workOfflineAction = new QAction( this );
0736     actionCollection()->addAction( "workOffline", m_workOfflineAction );
0737     m_workOfflineAction->setText( i18nc( "Action for toggling offline mode", "&Work Offline" ) );
0738     m_workOfflineAction->setIcon( QIcon::fromTheme( "user-offline" ) );
0739     m_workOfflineAction->setCheckable( true );
0740     m_workOfflineAction->setChecked( false );
0741     connect( m_workOfflineAction, SIGNAL(triggered(bool)),
0742              this,                SLOT(workOffline(bool)) );
0743 
0744     // Action: Copy Map to the Clipboard
0745     m_copyMapAction = KStandardAction::copy( this, SLOT(copyMap()),
0746                                              actionCollection() );
0747     m_copyMapAction->setText( i18nc( "Action for copying the map to the clipboard", "&Copy Map" ) );
0748 
0749     // Action: Copy Coordinates string
0750     m_copyCoordinatesAction = new QAction( this );
0751     actionCollection()->addAction( "edit_copy_coordinates",
0752                                    m_copyCoordinatesAction );
0753     m_copyCoordinatesAction->setText( i18nc( "Action for copying the coordinates to the clipboard",
0754                                              "C&opy Coordinates" ) );
0755     m_copyCoordinatesAction->setIcon(QIcon(QStringLiteral(":/icons/copy-coordinates.png")));
0756     connect( m_copyCoordinatesAction, SIGNAL(triggered(bool)),
0757              this,                    SLOT(copyCoordinates()) );
0758 
0759     // Action: Open a Gpx or a Kml File
0760     m_openAct = KStandardAction::open( this, SLOT(openFile()),
0761                                        actionCollection() );
0762     m_openAct->setText( i18nc( "Action for opening a file", "&Open..." ) );
0763 
0764     // Standard actions.  So far only Quit.
0765     KStandardAction::quit( qApp, SLOT(closeAllWindows()),
0766                            actionCollection() );
0767 
0768     // Action: Get hot new stuff
0769     const QString knsText = i18nc("Action for downloading maps (GHNS)", "Download Maps...");
0770     m_newStuffAction = new QAction(QIcon::fromTheme(QStringLiteral("get-hot-new-stuff")), knsText, this);
0771     connect(m_newStuffAction, &QAction::triggered, this, &MarblePart::showNewStuffDialog);
0772     m_newStuffAction->setStatusTip( i18nc( "Status tip", "Download new maps"));
0773     actionCollection()->addAction(QStringLiteral("new_stuff"), m_newStuffAction);
0774     actionCollection()->setDefaultShortcut( m_newStuffAction, Qt::CTRL | Qt::Key_N );
0775 
0776     // Action: Create a New Map
0777     m_mapWizardAct = new QAction( i18nc( "Action for creating new maps",
0778                                          "&Create a New Map..." ),
0779                                   this );
0780     m_mapWizardAct->setIcon(QIcon(QStringLiteral(":/icons/create-new-map.png")));
0781     actionCollection()->addAction( "createMap", m_mapWizardAct );
0782     m_mapWizardAct->setStatusTip( i18nc( "Status tip",
0783                                          "A wizard guides you through the creation of your own map theme." ) );
0784     connect( m_mapWizardAct, SIGNAL(triggered()), SLOT(showMapWizard()) );
0785 
0786     KStandardAction::showStatusbar( this, SLOT(showStatusBar(bool)),
0787                                     actionCollection() );
0788 
0789     m_fullScreenAct = KStandardAction::fullScreen( nullptr, nullptr, widget(),
0790                                                    actionCollection() );
0791     connect( m_fullScreenAct, SIGNAL(triggered(bool)),
0792              this,            SLOT(showFullScreen(bool)) );
0793 
0794     // Action: Show Crosshairs option
0795     QList<RenderPlugin *> pluginList = m_controlView->marbleWidget()->renderPlugins();
0796     QList<RenderPlugin *>::const_iterator i = pluginList.constBegin();
0797     QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd();
0798     for (; i != end; ++i ) {
0799         if ((*i)->nameId() == QLatin1String("crosshairs")) {
0800             actionCollection()->addAction( "show_crosshairs", (*i)->action() );
0801         }
0802     }
0803 
0804     // Action: Show Clouds option
0805     m_showCloudsAction = new QAction( this );
0806     actionCollection()->addAction( "show_clouds", m_showCloudsAction );
0807     m_showCloudsAction->setCheckable( true );
0808     m_showCloudsAction->setChecked( true );
0809     m_showCloudsAction->setIcon(QIcon(QStringLiteral(":/icons/clouds.png")));
0810     m_showCloudsAction->setText( i18nc( "Action for toggling clouds", "&Clouds" ) );
0811     connect( m_showCloudsAction, SIGNAL(triggered(bool)),
0812              this,               SLOT(setShowClouds(bool)) );
0813 
0814     // Action: Show Sunshade options
0815     m_controlSunAction = new QAction( this );
0816     actionCollection()->addAction( "control_sun", m_controlSunAction );
0817     m_controlSunAction->setText( i18nc( "Action for sun control dialog", "S&un Control..." ) );
0818     connect( m_controlSunAction, SIGNAL(triggered(bool)),
0819              this,               SLOT(controlSun()) );
0820 
0821     KStandardAction::redisplay( m_controlView->marbleWidget(), SLOT(reloadMap()), actionCollection() );
0822 
0823     // Action: Show Time options
0824     m_controlTimeAction = new QAction( this );
0825     actionCollection()->addAction( "control_time", m_controlTimeAction );
0826     m_controlTimeAction->setIcon(QIcon(QStringLiteral(":/icons/clock.png")));
0827     m_controlTimeAction->setText( i18nc( "Action for time control dialog", "&Time Control..." ) );
0828     connect( m_controlTimeAction, SIGNAL(triggered(bool)),
0829          this,               SLOT(controlTime()) );
0830 
0831     // Action: Lock float items
0832     m_lockFloatItemsAct = new QAction ( this );
0833     actionCollection()->addAction( "options_lock_floatitems",
0834                                    m_lockFloatItemsAct );
0835     m_lockFloatItemsAct->setText( i18nc( "Action for locking float items on the map",
0836                                          "Lock Position" ) );
0837     m_lockFloatItemsAct->setIcon(QIcon(QStringLiteral(":/icons/unlock.png")));
0838     m_lockFloatItemsAct->setCheckable( true );
0839     m_lockFloatItemsAct->setChecked( false );
0840     connect( m_lockFloatItemsAct, SIGNAL(triggered(bool)),
0841              this,                SLOT(lockFloatItemPosition(bool)) );
0842 
0843     KStandardAction::preferences( this, SLOT(editSettings()),
0844                                   actionCollection() );
0845 
0846     //Toggle Action: Show sun shadow
0847     m_showShadow = new KToggleAction( i18n( "Show Shadow" ), this );
0848 //     m_showShadow->setIcon(QIcon(QStringLiteral("")));        // Fixme: Add Icon
0849     actionCollection()->addAction( "sun_shadow", m_showShadow );
0850     m_showShadow->setCheckedState( KGuiItem( i18n( "Hide Shadow" ) ) );
0851     m_showShadow->setToolTip(i18n("Shows and hides the shadow of the sun"));
0852     connect( m_showShadow, SIGNAL(triggered(bool)), this, SLOT(showSun(bool)));
0853 
0854     //Toggle Action: Show Sun icon on the Sub-Solar Point
0855     m_setSubSolarPointIconVisible = new KToggleAction( i18n( "Show sun icon on the Sub-Solar Point" ), this );
0856     actionCollection()->addAction( "show_icon_on_subsolarpoint", m_setSubSolarPointIconVisible );
0857     m_setSubSolarPointIconVisible->setCheckedState( KGuiItem( i18n( "Hide sun icon on the Sub-Solar Point" ) ) );
0858     m_setSubSolarPointIconVisible->setToolTip( i18n( "Show sun icon on the sub-solar point" ) );
0859     connect( m_setSubSolarPointIconVisible, SIGNAL(triggered(bool)), this, SLOT(setSubSolarPointIconVisible(bool)));
0860 
0861 
0862     //Toggle Action: Lock globe to the Sub-Solar Point
0863     m_lockToSubSolarPoint = new KToggleAction( i18n( "Lock Globe to the Sub-Solar Point" ), this );
0864     actionCollection()->addAction( "lock_to_subsolarpoint", m_lockToSubSolarPoint );
0865     m_lockToSubSolarPoint->setCheckedState( KGuiItem( i18n( "Unlock Globe to the Sub-Solar Point" ) ) );
0866     m_lockToSubSolarPoint->setToolTip( i18n( "Lock globe to the sub-solar point" ) );
0867     connect( m_lockToSubSolarPoint, SIGNAL(triggered(bool)), this, SLOT(lockToSubSolarPoint(bool)));
0868 
0869     //    FIXME: Discuss if this is the best place to put this
0870     QList<RenderPlugin *>::const_iterator it = pluginList.constBegin();
0871     QList<RenderPlugin *>::const_iterator const itEnd = pluginList.constEnd();
0872     for (; it != itEnd; ++it ) {
0873         if ((*it)->nameId() != QLatin1String("annotation")) {
0874             connect( (*it), SIGNAL(actionGroupsChanged()),
0875                      this, SLOT(createPluginMenus()) );
0876         }
0877     }
0878 
0879     m_addBookmarkAction = new QAction( this );
0880     actionCollection()->addAction( "add_bookmark", m_addBookmarkAction );
0881     m_addBookmarkAction->setText( i18nc( "Add Bookmark", "Add &Bookmark..." ) );
0882     m_addBookmarkAction->setIcon(QIcon(QStringLiteral(":/icons/bookmark-new.png")));
0883     actionCollection()->setDefaultShortcut( m_addBookmarkAction, Qt::CTRL | Qt::Key_B );
0884     connect( m_addBookmarkAction, SIGNAL(triggered()),
0885              this,                SLOT(openEditBookmarkDialog()) );
0886 
0887     m_toggleBookmarkDisplayAction = new QAction( this );
0888     actionCollection()->addAction( "show_bookmarks", m_toggleBookmarkDisplayAction );
0889     m_toggleBookmarkDisplayAction->setText( i18nc( "Show Bookmarks", "Show &Bookmarks" ) );
0890     m_toggleBookmarkDisplayAction->setStatusTip( i18n( "Show or hide bookmarks in the map" ) );
0891     m_toggleBookmarkDisplayAction->setCheckable( true );
0892     m_toggleBookmarkDisplayAction->setChecked( m_controlView->marbleModel()->bookmarkManager()->showBookmarks() );
0893     connect( m_toggleBookmarkDisplayAction, SIGNAL(toggled(bool)),
0894                   m_controlView->marbleModel()->bookmarkManager(), SLOT(setShowBookmarks(bool)) );
0895 
0896     m_setHomeAction = new QAction( this );
0897     actionCollection()->addAction( "set_home", m_setHomeAction );
0898     m_setHomeAction->setText( i18n( "&Set Home Location" ) );
0899     m_setHomeAction->setIcon( QIcon::fromTheme( "go-home" ) );
0900     connect( m_setHomeAction, SIGNAL(triggered()),
0901              this,                SLOT(setHome()) );
0902 
0903     m_manageBookmarksAction = new QAction( this );
0904     actionCollection()->addAction( "manage_bookmarks", m_manageBookmarksAction );
0905     m_manageBookmarksAction->setText( i18nc( "Manage Bookmarks", "&Manage Bookmarks..." ) );
0906     m_manageBookmarksAction->setIcon(QIcon(QStringLiteral(":/icons/bookmarks-organize.png")));
0907     connect( m_manageBookmarksAction, SIGNAL(triggered()),
0908              this,                SLOT(openManageBookmarksDialog()) );
0909 
0910 
0911     createFolderList();
0912     connect( m_controlView->marbleModel()->bookmarkManager(),
0913              SIGNAL(bookmarksChanged()), this, SLOT(createFolderList()) );
0914 
0915     m_externalMapEditorAction = new QAction( this );
0916     actionCollection()->addAction( "external_editor", m_externalMapEditorAction );
0917     m_externalMapEditorAction->setText( i18nc( "Edit the map in an external application", "&Edit Map..." ) );
0918     m_externalMapEditorAction->setIcon(QIcon(QStringLiteral(":/icons/edit-map.png")));
0919     actionCollection()->setDefaultShortcut( m_externalMapEditorAction, Qt::CTRL | Qt::Key_E );
0920     connect( m_externalMapEditorAction, SIGNAL(triggered()),
0921              m_controlView, SLOT(launchExternalMapEditor()) );
0922     connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)),
0923              this, SLOT(updateMapEditButtonVisibility(QString)) );
0924 
0925      m_recordMovieAction = new QAction( i18n( "&Record Movie" ), this );
0926      actionCollection()->addAction( "record_movie" , m_recordMovieAction );
0927      m_recordMovieAction->setStatusTip( i18n( "Records a movie of the globe" ) );
0928      actionCollection()->setDefaultShortcut( m_recordMovieAction, Qt::CTRL | Qt::SHIFT | Qt::Key_R );
0929      m_recordMovieAction->setIcon(QIcon(QStringLiteral(":/icons/animator.png")));
0930      connect( m_recordMovieAction, SIGNAL(triggered()),
0931              this, SLOT(showMovieCaptureDialog()) );
0932 
0933      m_stopRecordingAction = new QAction( i18n( "&Stop Recording" ), this );
0934      actionCollection()->addAction( "stop_recording" , m_stopRecordingAction );
0935      m_stopRecordingAction->setStatusTip( i18n( "Stop recording a movie of the globe" ) );
0936      actionCollection()->setDefaultShortcut( m_recordMovieAction, Qt::CTRL | Qt::SHIFT | Qt::Key_S );
0937      m_stopRecordingAction->setEnabled( false );
0938      connect( m_stopRecordingAction, SIGNAL(triggered()),
0939              this, SLOT(stopRecording()) );
0940 }
0941 
0942 void MarblePart::createFolderList()
0943 {
0944 
0945     QList<QAction*> actionList;
0946 
0947    QVector<GeoDataFolder*> folders = m_controlView->marbleModel()->bookmarkManager()->folders();
0948    QVector<GeoDataFolder*>::const_iterator i = folders.constBegin();
0949    QVector<GeoDataFolder*>::const_iterator end = folders.constEnd();
0950 
0951    for (; i != end; ++i ) {
0952        QMenu *m_bookmarksListMenu = new QMenu( (*i)->name() );
0953 
0954        createBookmarksListMenu( m_bookmarksListMenu, *(*i) );
0955        connect( m_bookmarksListMenu, SIGNAL(triggered(QAction*)),
0956             this, SLOT(lookAtBookmark(QAction*)) );
0957 
0958        actionList.append( m_bookmarksListMenu->menuAction() );
0959    }
0960    unplugActionList("folders");
0961    plugActionList( "folders", actionList );
0962 }
0963 
0964 void MarblePart::createBookmarksListMenu( QMenu *m_bookmarksListMenu, const GeoDataFolder &folder )
0965 {
0966     m_bookmarksListMenu->clear();
0967     QVector<GeoDataPlacemark*> bookmarks = folder.placemarkList();
0968 
0969     QVector<GeoDataPlacemark*>::const_iterator i = bookmarks.constBegin();
0970     QVector<GeoDataPlacemark*>::const_iterator end = bookmarks.constEnd();
0971 
0972     for (; i != end; ++i ) {
0973         QAction *bookmarkAct = new QAction( (*i)->name(), this );
0974         QVariant var;
0975         GeoDataLookAt* lookAt = (*i)->lookAt();
0976         if ( !lookAt ) {
0977             GeoDataLookAt coordinateToLookAt;
0978             coordinateToLookAt.setCoordinates( (*i)->coordinate() );
0979             coordinateToLookAt.setRange( (*i)->coordinate().altitude() );
0980         } else {
0981             var.setValue( *lookAt );
0982         }
0983         bookmarkAct->setData( var );
0984         m_bookmarksListMenu->addAction( bookmarkAct );
0985     }
0986 
0987 }
0988 
0989 void MarblePart::createInfoBoxesMenu()
0990 {
0991     QList<AbstractFloatItem *> floatItemList = m_controlView->marbleWidget()->floatItems();
0992 
0993     QList<QAction*> actionList;
0994 
0995     QList<AbstractFloatItem *>::const_iterator i = floatItemList.constBegin();
0996     QList<AbstractFloatItem *>::const_iterator const end = floatItemList.constEnd();
0997     for (; i != end; ++i ) {
0998         actionList.append( (*i)->action() );
0999     }
1000 
1001     unplugActionList( "infobox_actionlist" );
1002     plugActionList( "infobox_actionlist", actionList );
1003 }
1004 
1005 void MarblePart::createOnlineServicesMenu()
1006 {
1007     QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
1008 
1009     QList<QAction*> actionList;
1010 
1011     QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
1012     QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
1013     for (; i != end; ++i ) {
1014         // FIXME: This will go into the layer manager when AbstractDataPlugin is an interface
1015 
1016         if( (*i)->renderType() == RenderPlugin::OnlineRenderType ) {
1017             actionList.append( (*i)->action() );
1018         }
1019     }
1020 
1021     unplugActionList( "onlineservices_actionlist" );
1022     plugActionList( "onlineservices_actionlist", actionList );
1023 }
1024 
1025 void MarblePart::createRenderPluginActions()
1026 {
1027     QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
1028 
1029     QList<QAction*> actionList;
1030 
1031     QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
1032     QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
1033     for (; i != end; ++i ) {
1034         if( (*i)->renderType() == RenderPlugin::ThemeRenderType ) {
1035             actionList.append( (*i)->action() );
1036         }
1037     }
1038 
1039     unplugActionList( "themerender_actionlist" );
1040     plugActionList( "themerender_actionlist", actionList );
1041 }
1042 
1043 void MarblePart::showDateTime()
1044 {
1045     m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat );
1046     updateStatusBar();
1047 }
1048 
1049 void MarblePart::showPosition( const QString& position )
1050 {
1051     m_position = position;
1052     updateStatusBar();
1053 }
1054 
1055 void MarblePart::showZoomLevel( const int tileLevel )
1056 {
1057     if ( tileLevel == -1 )
1058         m_tileZoomLevel = QCoreApplication::translate( "Marble", NOT_AVAILABLE );
1059     else {
1060         m_tileZoomLevel.setNum( tileLevel );
1061     }
1062     updateStatusBar();
1063 }
1064 
1065 void MarblePart::mapThemeChanged( const QString& newMapTheme )
1066 {
1067     Q_UNUSED( newMapTheme );
1068     updateTileZoomLevel();
1069     updateStatusBar();
1070 }
1071 
1072 void MarblePart::createPluginMenus()
1073 {
1074     unplugActionList("plugins_actionlist");
1075     unplugActionList("plugins_menuactionlist");
1076 
1077     QList<RenderPlugin *> renderPluginList = m_controlView->marbleWidget()->renderPlugins();
1078     QList<RenderPlugin *>::const_iterator i = renderPluginList.constBegin();
1079     QList<RenderPlugin *>::const_iterator const end = renderPluginList.constEnd();
1080 
1081     for (; i != end; ++i ) {
1082         // menus
1083         const QList<QActionGroup*> *tmp_actionGroups = (*i)->actionGroups();
1084         if( (*i)->enabled() && tmp_actionGroups ) {
1085             for( QActionGroup *ag: *tmp_actionGroups ) {
1086                 plugActionList( "plugins_menuactionlist", ag->actions() );
1087             }
1088         }
1089 
1090         // toolbars
1091         const QList<QActionGroup*> *tmp_toolbarActionGroups = (*i)->toolbarActionGroups();
1092         if ( (*i)->enabled() && tmp_toolbarActionGroups ) {
1093 
1094             for( QActionGroup* ag: *tmp_toolbarActionGroups ) {
1095                 plugActionList( "plugins_actionlist", ag->actions() );
1096             }
1097         }
1098     }
1099 
1100 }
1101 
1102 void MarblePart::updateTileZoomLevel()
1103 {
1104     const int tileZoomLevel =
1105         m_controlView->marbleWidget()->tileZoomLevel();
1106     if ( tileZoomLevel == -1 )
1107         m_tileZoomLevel = QCoreApplication::translate( "Marble", NOT_AVAILABLE );
1108     else {
1109         m_tileZoomLevel.setNum( tileZoomLevel );
1110     }
1111 }
1112 
1113 void MarblePart::migrateNewstuffConfigFiles()
1114 {
1115     // Newstuff config files used to be in the KDE data directory of the user, but are now
1116     // shared between Marble KDE and Marble Qt in Marble's data path of the user.
1117     // This method moves an old KDE newstuff config file to the new location if the former
1118     // exists and the latter not.
1119     QFileInfo const target(MarbleDirs::localPath() + QLatin1String("/newstuff/marble-map-themes.knsregistry"));
1120     if ( !target.exists() ) {
1121         QString const source = QStandardPaths::locate( QStandardPaths::GenericDataLocation, "knewstuff3/marble.knsregistry" );
1122         if ( !source.isEmpty() ) {
1123             if ( !target.absoluteDir().exists() ) {
1124                 if ( !QDir::root().mkpath( target.absolutePath() ) ) {
1125                     mDebug() << "Failed to create target directory " << target.absolutePath() << " needed for newstuff migration";
1126                     return;
1127                 }
1128             }
1129 
1130             QFile registryFile( source );
1131             if ( !registryFile.open( QFile::ReadOnly ) ) {
1132                 mDebug() << "Cannot parse newstuff xml file";
1133                 return;
1134             }
1135             QDomDocument xml;
1136             if ( !xml.setContent( registryFile.readAll() ) ) {
1137                 mDebug() << "Cannot parse newstuff xml data";
1138                 return;
1139             }
1140 
1141             QDomNodeList items = xml.elementsByTagName( "stuff" );
1142             for ( int i = 0; i < items.length(); ++i ) {
1143                 repairNode( items.item(i), QString("summary") );
1144                 repairNode( items.item(i), QString("author") );
1145             }
1146 
1147             QFile output( target.absoluteFilePath() );
1148             if ( !output.open( QFile::WriteOnly ) ) {
1149                 mDebug() << "Cannot open " << target.absoluteFilePath() << " for writing";
1150             } else {
1151                 QTextStream outStream( &output );
1152                 outStream << xml.toString( 2 );
1153                 outStream.flush();
1154                 output.close();
1155             }
1156         }
1157     }
1158 }
1159 
1160 void MarblePart::repairNode( QDomNode node, const QString &child )
1161 {
1162     int const size = node.namedItem( child ).toElement().text().size();
1163     if ( size > 1024 ) {
1164         QString const theme = node.namedItem(QStringLiteral("name")).toElement().text();
1165         mDebug() << "Removing GHNS field " << child << " of map theme " << theme << ": Size " << size << " exceeds maximum size (see bug 319542).";
1166         node.removeChild( node.namedItem( child ) );
1167     }
1168 }
1169 
1170 void MarblePart::updateCloudSyncStatus(const QString& status )
1171 {
1172     m_ui_cloudSyncSettings.cloudSyncStatus->setText(status);
1173     switch (m_controlView->cloudSyncManager()->status()){
1174         case CloudSyncManager::Success:
1175             m_ui_cloudSyncSettings.cloudSyncStatus->setStyleSheet("QLabel { color : green; }");
1176             break;
1177         case CloudSyncManager::Error:
1178             m_ui_cloudSyncSettings.cloudSyncStatus->setStyleSheet("QLabel { color : red; }");
1179             break;
1180         case CloudSyncManager::Unknown:
1181             m_ui_cloudSyncSettings.cloudSyncStatus->setStyleSheet("QLabel { color : grey; }");
1182             break;
1183     }
1184 }
1185 
1186 void MarblePart::updateCloudSyncCredentials()
1187 {
1188     m_controlView->cloudSyncManager()->setOwncloudCredentials( m_ui_cloudSyncSettings.kcfg_owncloudServer->text(),
1189                                                                m_ui_cloudSyncSettings.kcfg_owncloudUsername->text(),
1190                                                                m_ui_cloudSyncSettings.kcfg_owncloudPassword->text() );
1191 }
1192 
1193 void MarblePart::updateStatusBar()
1194 {
1195     if ( m_positionLabel )
1196         m_positionLabel->setText( i18n( POSITION_STRING, m_position ) );
1197 
1198     if ( m_distanceLabel )
1199         m_distanceLabel->setText( i18n( DISTANCE_STRING, m_controlView->marbleWidget()->distanceString() ) );
1200 
1201     if ( m_tileZoomLevelLabel )
1202         m_tileZoomLevelLabel->setText( i18n( TILEZOOMLEVEL_STRING,
1203                                              m_tileZoomLevel ) );
1204 
1205     if ( m_clockLabel )
1206         m_clockLabel->setText( i18n( DATETIME_STRING, m_clock ) );
1207 }
1208 
1209 void MarblePart::setupStatusBar()
1210 {
1211     QFontMetrics statusBarFontMetrics( m_statusBarExtension->statusBar()->fontMetrics() );
1212 
1213     // UTM syntax is used in the template string, as it is longer than the lon/lat one
1214     QString templatePositionString =
1215         QString( "%1 00Z 000000.00 m E, 00000000.00 m N_" ).arg(POSITION_STRING);
1216     m_positionLabel = setupStatusBarLabel( templatePositionString );
1217 
1218     QString templateDistanceString =
1219         QString( "%1 00.000,0 mu" ).arg(DISTANCE_STRING);
1220     m_distanceLabel = setupStatusBarLabel( templateDistanceString );
1221 
1222     QString templateDateTimeString = QString( "%1 %2" ).arg( DATETIME_STRING , QLocale().toString( QDateTime::fromString ( "01:01:1000", "dd:mm:yyyy"), QLocale::ShortFormat ) );
1223 
1224     m_clockLabel = setupStatusBarLabel( templateDateTimeString );
1225 
1226     const QString templateTileZoomLevelString = i18n( TILEZOOMLEVEL_STRING, m_tileZoomLevel );
1227     m_tileZoomLevelLabel = setupStatusBarLabel( templateTileZoomLevelString );
1228 
1229     connect( m_controlView->marbleWidget(), SIGNAL(mouseMoveGeoPosition(QString)),
1230              this,                          SLOT(showPosition(QString)) );
1231     connect( m_controlView->marbleWidget(), SIGNAL(distanceChanged(QString)),
1232              this,                          SLOT(updateStatusBar()) );
1233     connect( m_controlView->marbleWidget(), SIGNAL(tileLevelChanged(int)),
1234              SLOT(showZoomLevel(int)));
1235     connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)),
1236              this, SLOT(mapThemeChanged(QString)), Qt::QueuedConnection );
1237     connect( m_controlView->marbleModel()->clock(), SIGNAL(timeChanged()),
1238              this,                          SLOT(showDateTime()) );
1239 
1240 
1241     setupDownloadProgressBar();
1242 
1243     setupStatusBarActions();
1244     updateStatusBar();
1245 }
1246 
1247 QLabel * MarblePart::setupStatusBarLabel( const QString& templateString )
1248 {
1249     QFontMetrics statusBarFontMetrics( m_statusBarExtension->statusBar()->fontMetrics() );
1250 
1251     QLabel * const label = new QLabel( m_statusBarExtension->statusBar() );
1252     label->setIndent( 5 );
1253     int maxWidth = statusBarFontMetrics.boundingRect( templateString ).width()
1254         + 2 * label->margin() + 2 * label->indent();
1255     label->setFixedWidth( maxWidth );
1256     m_statusBarExtension->addStatusBarItem( label, -1, false );
1257     return label;
1258 }
1259 
1260 void MarblePart::setupDownloadProgressBar()
1261 {
1262     // get status bar and add progress widget
1263     QStatusBar * const statusBar = m_statusBarExtension->statusBar();
1264     Q_ASSERT( statusBar );
1265 
1266     m_downloadProgressBar = new QProgressBar;
1267     m_downloadProgressBar->setVisible( MarbleSettings::showDownloadProgressBar() );
1268     statusBar->addPermanentWidget( m_downloadProgressBar );
1269 
1270     HttpDownloadManager * const downloadManager =
1271         m_controlView->marbleModel()->downloadManager();
1272     Q_ASSERT( downloadManager );
1273     connect( downloadManager, SIGNAL(progressChanged(int,int)), SLOT(handleProgress(int,int)) );
1274     connect( downloadManager, SIGNAL(jobRemoved()), SLOT(removeProgressItem()) );
1275 }
1276 
1277 void MarblePart::setupStatusBarActions()
1278 {
1279     QStatusBar * const statusBar = m_statusBarExtension->statusBar();
1280     Q_ASSERT( statusBar );
1281 
1282     statusBar->setContextMenuPolicy( Qt::CustomContextMenu );
1283 
1284     connect( statusBar, SIGNAL(customContextMenuRequested(QPoint)),
1285              this, SLOT(showStatusBarContextMenu(QPoint)));
1286 
1287     m_showPositionAction = new KToggleAction( i18nc( "Action for toggling", "Show Position" ),
1288                                               this );
1289     m_showDateTimeAction = new KToggleAction( i18nc( "Action for toggling", "Show Date and Time" ),
1290                                               this );
1291     m_showAltitudeAction = new KToggleAction( i18nc( "Action for toggling", "Show Altitude" ),
1292                                               this );
1293     m_showTileZoomLevelAction = new KToggleAction( i18nc( "Action for toggling",
1294                                                           "Show Tile Zoom Level" ), this );
1295     m_showDownloadProgressAction = new KToggleAction( i18nc( "Action for toggling",
1296                                                              "Show Download Progress Bar" ), this );
1297 
1298     connect( m_showPositionAction, SIGNAL(triggered(bool)),
1299              this, SLOT(showPositionLabel(bool)) );
1300     connect( m_showAltitudeAction, SIGNAL(triggered(bool)),
1301              this, SLOT(showAltitudeLabel(bool)) );
1302     connect( m_showTileZoomLevelAction, SIGNAL(triggered(bool)),
1303              this, SLOT(showTileZoomLevelLabel(bool)) );
1304     connect( m_showDateTimeAction, SIGNAL(triggered(bool)),
1305              this, SLOT(showDateTimeLabel(bool)) );
1306     connect( m_showDownloadProgressAction, SIGNAL(triggered(bool)),
1307              this, SLOT(showDownloadProgressBar(bool)) );
1308 }
1309 
1310 void MarblePart::showNewStuffDialog()
1311 {
1312     QPointer<MapThemeDownloadDialog> dialog( new MapThemeDownloadDialog( m_controlView->marbleWidget() ) );
1313     dialog->exec();
1314     delete dialog;
1315 }
1316 
1317 void MarblePart::showDownloadRegionDialog()
1318 {
1319     MarbleWidget * const marbleWidget = m_controlView->marbleWidget();
1320     if ( !m_downloadRegionDialog ) {
1321         m_downloadRegionDialog = new DownloadRegionDialog( marbleWidget, widget() );
1322         // it might be tempting to move the connects to DownloadRegionDialog's "accepted" and
1323         // "applied" signals, be aware that the "hidden" signal might be come before the "accepted"
1324         // signal, leading to a too early disconnect.
1325         connect( m_downloadRegionDialog, SIGNAL(accepted()), SLOT(downloadRegion()));
1326         connect( m_downloadRegionDialog, SIGNAL(applied()), SLOT(downloadRegion()));
1327     }
1328     // FIXME: get allowed range from current map theme
1329     m_downloadRegionDialog->setAllowedTileLevelRange( 0, 16 );
1330     m_downloadRegionDialog->setSelectionMethod( DownloadRegionDialog::VisibleRegionMethod );
1331     ViewportParams const * const viewport = marbleWidget->viewport();
1332     m_downloadRegionDialog->setSpecifiedLatLonAltBox( viewport->viewLatLonAltBox() );
1333     m_downloadRegionDialog->setVisibleLatLonAltBox( viewport->viewLatLonAltBox() );
1334     m_downloadRegionDialog->setVisibleTileLevel( marbleWidget->tileZoomLevel() );
1335 
1336     m_downloadRegionDialog->show();
1337     m_downloadRegionDialog->raise();
1338     m_downloadRegionDialog->activateWindow();
1339 }
1340 
1341 void MarblePart::downloadRegion()
1342 {
1343     Q_ASSERT( m_downloadRegionDialog );
1344     QVector<TileCoordsPyramid> const pyramid = m_downloadRegionDialog->region();
1345     if ( !pyramid.isEmpty() ) {
1346         m_controlView->marbleWidget()->downloadRegion( pyramid );
1347     }
1348 }
1349 
1350 void MarblePart::showStatusBarContextMenu( const QPoint& pos )
1351 {
1352     QStatusBar * const statusBar = m_statusBarExtension->statusBar();
1353     Q_ASSERT( statusBar );
1354 
1355     QMenu statusBarContextMenu( m_controlView->marbleWidget() );
1356     statusBarContextMenu.addAction( m_showPositionAction );
1357     statusBarContextMenu.addAction( m_showDateTimeAction );
1358     statusBarContextMenu.addAction( m_showAltitudeAction );
1359     statusBarContextMenu.addAction( m_showTileZoomLevelAction );
1360     statusBarContextMenu.addAction( m_showDownloadProgressAction );
1361 
1362     statusBarContextMenu.exec( statusBar->mapToGlobal( pos ));
1363 }
1364 
1365 void MarblePart::showMapWizard()
1366 {
1367     // Map Wizard
1368     QPointer<MapWizard> mapWizard = new MapWizard( m_controlView );
1369     mapWizard->setWmsServers( MarbleSettings::wmsServers() );
1370     mapWizard->setWmtsServers( MarbleSettings::wmtsServers() );
1371     mapWizard->setStaticUrlServers( MarbleSettings::staticUrlServers() );
1372     mapWizard->exec();
1373     MarbleSettings::setWmsServers( mapWizard->wmsServers() );
1374     MarbleSettings::setWmtsServers( mapWizard->wmtsServers() );
1375     MarbleSettings::setStaticUrlServers( mapWizard->staticUrlServers() );
1376     mapWizard->deleteLater();
1377 }
1378 
1379 void MarblePart::editSettings()
1380 {
1381     if ( KConfigDialog::showDialog( "settings" ) )
1382         return;
1383 
1384     m_configDialog = new KConfigDialog( m_controlView, "settings",
1385                                         MarbleSettings::self() );
1386 
1387     // view page
1388     Ui_MarbleViewSettingsWidget  ui_viewSettings;
1389     QWidget                     *w_viewSettings = new QWidget( nullptr );
1390 
1391     w_viewSettings->setObjectName( "view_page" );
1392     ui_viewSettings.setupUi( w_viewSettings );
1393     m_configDialog->addPage( w_viewSettings, i18n( "View" ), "configure" );
1394 
1395     ui_viewSettings.label_labelLocalization->hide();
1396     ui_viewSettings.kcfg_labelLocalization->hide();
1397 
1398     // navigation page
1399     Ui_MarbleNavigationSettingsWidget  ui_navigationSettings;
1400     QWidget                           *w_navigationSettings = new QWidget( nullptr );
1401 
1402     w_navigationSettings->setObjectName( "navigation_page" );
1403     ui_navigationSettings.setupUi( w_navigationSettings );
1404     m_configDialog->addPage( w_navigationSettings, i18n( "Navigation" ),
1405                              "transform-move" );
1406     ui_navigationSettings.kcfg_dragLocation->hide();
1407     ui_navigationSettings.label_dragLocation->hide();
1408 
1409     // cache page
1410     Ui_MarbleCacheSettingsWidget  ui_cacheSettings;
1411     QWidget                      *w_cacheSettings = new QWidget( nullptr );
1412 
1413     w_cacheSettings->setObjectName( "cache_page" );
1414     ui_cacheSettings.setupUi( w_cacheSettings );
1415     m_configDialog->addPage( w_cacheSettings, i18n( "Cache & Proxy" ),
1416                              "preferences-web-browser-cache" );
1417     connect( ui_cacheSettings.button_clearVolatileCache, SIGNAL(clicked()),
1418              m_controlView->marbleWidget(), SLOT(clearVolatileTileCache()) );
1419     connect( ui_cacheSettings.button_clearPersistentCache, SIGNAL(clicked()),
1420              m_controlView->marbleModel(), SLOT(clearPersistentTileCache()) );
1421 
1422     // time page
1423     Ui_MarbleTimeSettingsWidget ui_timeSettings;
1424     QWidget *w_timeSettings = new QWidget( nullptr );
1425 
1426     w_timeSettings->setObjectName( "time_page" );
1427     ui_timeSettings.setupUi( w_timeSettings );
1428     m_configDialog->addPage( w_timeSettings, i18n( "Date & Time" ), "clock" );
1429     
1430     // Sync page
1431     QWidget *w_cloudSyncSettings = new QWidget( nullptr );
1432 
1433     w_cloudSyncSettings->setObjectName( "sync_page" );
1434     m_ui_cloudSyncSettings.setupUi( w_cloudSyncSettings );
1435     m_ui_cloudSyncSettings.button_syncNow->setEnabled( MarbleSettings::syncBookmarks() );
1436     m_configDialog->addPage( w_cloudSyncSettings, i18n( "Synchronization" ), "folder-sync" );
1437 
1438     connect( m_ui_cloudSyncSettings.button_syncNow, SIGNAL(clicked()),
1439              m_controlView->cloudSyncManager()->bookmarkSyncManager(), SLOT(startBookmarkSync()) );
1440     connect( m_ui_cloudSyncSettings.testLoginButton, SIGNAL(clicked()),
1441              this, SLOT(updateCloudSyncCredentials()) );
1442 
1443     connect( m_controlView->cloudSyncManager(), SIGNAL(statusChanged(QString)),
1444              this, SLOT(updateCloudSyncStatus(QString)));
1445 
1446     // routing page
1447     RoutingProfilesWidget *w_routingSettings = new RoutingProfilesWidget( m_controlView->marbleModel() );
1448     w_routingSettings->setObjectName( "routing_page" );
1449     m_configDialog->addPage( w_routingSettings, i18n( "Routing" ), "flag");
1450 
1451     // plugin page
1452     MarblePluginSettingsWidget *w_pluginSettings = new MarblePluginSettingsWidget();
1453     RenderPluginModel *const pluginModel = new RenderPluginModel( w_pluginSettings );
1454     pluginModel->setRenderPlugins( m_controlView->marbleWidget()->renderPlugins() );
1455     w_pluginSettings->setModel( pluginModel );
1456     w_pluginSettings->setObjectName( "plugin_page" );
1457     m_configDialog->addPage( w_pluginSettings, i18n( "Plugins" ),
1458                              "preferences-plugin" );
1459     // Setting the icons of the pluginSettings page.
1460     w_pluginSettings->setConfigIcon( QIcon::fromTheme( "configure" ) );
1461     w_pluginSettings->setAboutIcon( QIcon::fromTheme( "help-about" ) );
1462 
1463     connect( w_pluginSettings, SIGNAL(pluginListViewClicked()),
1464                                SLOT(enableApplyButton()) );
1465     connect( m_configDialog,   SIGNAL(settingsChanged(QString)),
1466                                SLOT(updateSettings()) );
1467     connect( m_configDialog,   SIGNAL(accepted()),
1468                                SLOT(applyPluginState()) );
1469     connect( m_configDialog,   SIGNAL(accepted()),
1470              pluginModel,      SLOT(applyPluginState()) );
1471     connect( m_configDialog,   SIGNAL(rejected()),
1472              pluginModel,      SLOT(retrievePluginState()) );
1473 
1474     m_configDialog->show();
1475 }
1476 
1477 void MarblePart::enableApplyButton()
1478 {
1479     //m_configDialog->enableButtonApply( true );
1480 }
1481 
1482 void MarblePart::applyPluginState()
1483 {
1484     QList<RoutingProfile>  profiles = m_controlView->marbleWidget()
1485                         ->model()->routingManager()->profilesModel()->profiles();
1486     KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
1487     KConfigGroup profilesGroup = sharedConfig->group( "Routing Profiles" );
1488     profilesGroup.writeEntry( "Num", profiles.count() );
1489     for ( int i = 0; i < profiles.count(); ++i ) {
1490         KConfigGroup profileGroup = profilesGroup.group( QString( "Profile %0" ).arg(i) );
1491         RoutingProfile profile = profiles.at( i );
1492         profileGroup.writeEntry( "Name", profile.name() );
1493         for ( const QString &pluginName: profileGroup.groupList() ) {
1494             profileGroup.group( pluginName ).deleteGroup();
1495         }
1496         for ( const QString &key: profile.pluginSettings().keys() ) {
1497             KConfigGroup pluginGroup = profileGroup.group( key );
1498             pluginGroup.writeEntry( "Enabled", true );
1499             for ( const QString& settingKey: profile.pluginSettings()[ key ].keys() ) {
1500                 Q_ASSERT(settingKey != QLatin1String("Enabled"));
1501                 pluginGroup.writeEntry( settingKey, profile.pluginSettings()[ key ][ settingKey ] );
1502             }
1503         }
1504     }
1505 }
1506 
1507 void MarblePart::updateSettings()
1508 {
1509     qDebug() << "Updating Settings ...";
1510 
1511     // FIXME: Font doesn't get updated instantly.
1512     m_controlView->marbleWidget()->setDefaultFont( MarbleSettings::mapFont() );
1513 
1514     m_controlView->marbleWidget()->
1515         setMapQualityForViewContext( (MapQuality) MarbleSettings::stillQuality(),
1516                                      Still );
1517     m_controlView->marbleWidget()->
1518         setMapQualityForViewContext( (MapQuality) MarbleSettings::animationQuality(),
1519                                      Animation );
1520 
1521     m_controlView->marbleWidget()->
1522         setDefaultAngleUnit( (AngleUnit) MarbleSettings::angleUnit() );
1523     MarbleGlobal::getInstance()->locale()->
1524         setMeasurementSystem( (MarbleLocale::MeasurementSystem) MarbleSettings::distanceUnit() );
1525 
1526     updateStatusBar();
1527 
1528     m_controlView->marbleWidget()->setAnimationsEnabled( MarbleSettings::animateTargetVoyage() );
1529 
1530     // Cache
1531     m_controlView->marbleModel()->
1532         setPersistentTileCacheLimit( MarbleSettings::persistentTileCacheLimit() * 1024 );
1533     m_controlView->marbleWidget()->
1534         setVolatileTileCacheLimit( MarbleSettings::volatileTileCacheLimit() * 1024 );
1535 
1536     //Create and export the proxy
1537     QNetworkProxy proxy;
1538 
1539     // Make sure that no proxy is used for an empty string or the default value:
1540     if (MarbleSettings::proxyUrl().isEmpty() || MarbleSettings::proxyUrl() == QLatin1String("http://")) {
1541         proxy.setType( QNetworkProxy::NoProxy );
1542     } else {
1543         if ( MarbleSettings::proxyType() == Marble::Socks5Proxy ) {
1544             proxy.setType( QNetworkProxy::Socks5Proxy );
1545         }
1546         else if ( MarbleSettings::proxyType() == Marble::HttpProxy ) {
1547             proxy.setType( QNetworkProxy::HttpProxy );
1548         }
1549         else {
1550             qDebug() << "Unknown proxy type! Using Http Proxy instead.";
1551             proxy.setType( QNetworkProxy::HttpProxy );
1552         }
1553     }
1554 
1555     proxy.setHostName( MarbleSettings::proxyUrl() );
1556     proxy.setPort( MarbleSettings::proxyPort() );
1557 
1558     if ( MarbleSettings::proxyAuth() ) {
1559         proxy.setUser( MarbleSettings::proxyUser() );
1560         proxy.setPassword( MarbleSettings::proxyPass() );
1561     }
1562 
1563     QNetworkProxy::setApplicationProxy(proxy);
1564 
1565     m_controlView->marbleWidget()->update();
1566 
1567     // Time
1568     if( MarbleSettings::systemTimezone() == true  )
1569     {
1570         QDateTime localTime = QDateTime::currentDateTime().toLocalTime();
1571         localTime.setTimeSpec( Qt::UTC );
1572         m_controlView->marbleModel()->setClockTimezone( QDateTime::currentDateTime().toUTC().secsTo( localTime ) );
1573     }
1574     else if( MarbleSettings::utc() == true )
1575     {
1576         m_controlView->marbleModel()->setClockTimezone( 0 );
1577     }
1578     else if( MarbleSettings::customTimezone() == true )
1579     {
1580         m_controlView->marbleModel()->setClockTimezone( m_timezone.value( MarbleSettings::chosenTimezone() ) );
1581     }
1582 
1583     // Route rendering colors and alpha values
1584     QColor tempColor;
1585     tempColor = MarbleSettings::routeColorStandard();
1586     tempColor.setAlpha( MarbleSettings::routeAlphaStandard() );
1587     m_controlView->marbleModel()->routingManager()->setRouteColorStandard( tempColor );
1588 
1589     tempColor = MarbleSettings::routeColorHighlighted();
1590     tempColor.setAlpha( MarbleSettings::routeAlphaHighlighted() );
1591     m_controlView->marbleModel()->routingManager()->setRouteColorHighlighted( tempColor );
1592 
1593     tempColor = MarbleSettings::routeColorAlternative();
1594     tempColor.setAlpha( MarbleSettings::routeAlphaAlternative() );
1595     m_controlView->marbleModel()->routingManager()->setRouteColorAlternative( tempColor );
1596 
1597     // External map editor
1598     m_controlView->setExternalMapEditor( m_externalEditorMapping[MarbleSettings::externalMapEditor()] );
1599     m_controlView->marbleWidget()->inputHandler()->setInertialEarthRotationEnabled( MarbleSettings::inertialEarthRotation() );
1600     m_controlView->marbleWidget()->inputHandler()->setMouseViewRotationEnabled( MarbleSettings::mouseViewRotation() );
1601 
1602     CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager();
1603     cloudSyncManager->setOwncloudCredentials( MarbleSettings::owncloudServer(),
1604                                               MarbleSettings::owncloudUsername(),
1605                                               MarbleSettings::owncloudPassword());
1606     cloudSyncManager->setSyncEnabled( MarbleSettings::enableSync() );
1607     cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( MarbleSettings::syncRoutes() );
1608     cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( MarbleSettings::syncBookmarks() );
1609 }
1610 
1611 void MarblePart::writePluginSettings()
1612 {
1613     KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
1614 
1615     for( RenderPlugin *plugin: m_controlView->marbleWidget()->renderPlugins() ) {
1616         KConfigGroup group = sharedConfig->group( QString( "plugin_" ) + plugin->nameId() );
1617 
1618         const QHash<QString,QVariant> hash = plugin->settings();
1619 
1620         QHash<QString,QVariant>::const_iterator it = hash.begin();
1621         while( it != hash.end() ) {
1622             group.writeEntry( it.key(), it.value() );
1623             ++it;
1624         }
1625         group.sync();
1626     }
1627 }
1628 
1629 void MarblePart::readPluginSettings()
1630 {
1631     disconnect( m_controlView->marbleWidget(), SIGNAL(pluginSettingsChanged()),
1632                 this,                          SLOT(writePluginSettings()) );
1633 
1634     KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig();
1635 
1636     for( RenderPlugin *plugin: m_controlView->marbleWidget()->renderPlugins() ) {
1637         KConfigGroup group = sharedConfig->group( QString( "plugin_" ) + plugin->nameId() );
1638 
1639         QHash<QString,QVariant> hash;
1640 
1641         for ( const QString& key: group.keyList() ) {
1642             hash.insert( key, group.readEntry( key ) );
1643         }
1644 
1645         plugin->setSettings( hash );
1646     }
1647 
1648     connect( m_controlView->marbleWidget(), SIGNAL(pluginSettingsChanged()),
1649              this,                          SLOT(writePluginSettings()) );
1650 }
1651 
1652 void MarblePart::lockFloatItemPosition( bool enabled )
1653 {
1654     QList<AbstractFloatItem *> floatItemList = m_controlView->marbleWidget()->floatItems();
1655 
1656     QList<AbstractFloatItem *>::const_iterator i = floatItemList.constBegin();
1657     QList<AbstractFloatItem *>::const_iterator const end = floatItemList.constEnd();
1658     for (; i != end; ++i ) {
1659         // Locking one would suffice as it affects all.
1660         // Nevertheless go through all.
1661         (*i)->setPositionLocked(enabled);
1662     }
1663 }
1664 
1665 void MarblePart::handleProgress( int active, int queued )
1666 {
1667     m_downloadProgressBar->setUpdatesEnabled( false );
1668     if ( m_downloadProgressBar->value() < 0 ) {
1669         m_downloadProgressBar->setMaximum( 1 );
1670         m_downloadProgressBar->setValue( 0 );
1671         m_downloadProgressBar->setVisible( MarbleSettings::showDownloadProgressBar() );
1672     } else {
1673         m_downloadProgressBar->setMaximum( qMax<int>( m_downloadProgressBar->maximum(), active + queued ) );
1674     }
1675 
1676 //     qDebug() << "downloadProgressJobAdded: value/maximum: "
1677 //              << m_downloadProgressBar->value() << '/' << m_downloadProgressBar->maximum();
1678 
1679     m_downloadProgressBar->setUpdatesEnabled( true );
1680 }
1681 
1682 void MarblePart::removeProgressItem()
1683 {
1684     m_downloadProgressBar->setUpdatesEnabled( false );
1685     m_downloadProgressBar->setValue( m_downloadProgressBar->value() + 1 );
1686     if ( m_downloadProgressBar->value() == m_downloadProgressBar->maximum() ) {
1687         m_downloadProgressBar->reset();
1688         m_downloadProgressBar->setVisible( false );
1689     }
1690 
1691 //     qDebug() << "downloadProgressJobCompleted: value/maximum: "
1692 //              << m_downloadProgressBar->value() << '/' << m_downloadProgressBar->maximum();
1693 
1694     m_downloadProgressBar->setUpdatesEnabled( true );
1695 }
1696 
1697 void MarblePart::openEditBookmarkDialog()
1698 {
1699     MarbleWidget *widget = m_controlView->marbleWidget();
1700     QPointer<EditBookmarkDialog> dialog = new EditBookmarkDialog( widget->model()->bookmarkManager(), widget );
1701     dialog->setCoordinates( widget->lookAt().coordinates() );
1702     dialog->setRange( widget->lookAt().range() );
1703     dialog->setMarbleWidget( widget );
1704     dialog->setReverseGeocodeName();
1705     if ( dialog->exec() == QDialog::Accepted ) {
1706         widget->model()->bookmarkManager()->addBookmark( dialog->folder(), dialog->bookmark() );
1707     }
1708     delete dialog;
1709 }
1710 
1711 void MarblePart::setHome()
1712 {
1713     MarbleWidget *widget = m_controlView->marbleWidget();
1714     widget->model()->setHome( widget->centerLongitude(), widget->centerLatitude(), widget->zoom() );
1715 }
1716 
1717 void MarblePart::openManageBookmarksDialog()
1718 {
1719     MarbleModel * const model = m_controlView->marbleModel();
1720     QPointer<BookmarkManagerDialog> dialog = new BookmarkManagerDialog( model, m_controlView->marbleWidget() );
1721     dialog->exec();
1722     delete dialog;
1723 }
1724 
1725 void MarblePart::lookAtBookmark( QAction *action)
1726 {
1727         GeoDataLookAt temp = qvariant_cast<GeoDataLookAt>( action->data() ) ;
1728         m_controlView->marbleWidget()->flyTo( temp ) ;
1729                 mDebug() << " looking at bookmark having longitude : "<< temp.longitude(GeoDataCoordinates::Degree)
1730                          << " latitude :  "<< temp.latitude(GeoDataCoordinates::Degree)
1731                          << " distance : " << temp.range();
1732 }
1733 
1734 
1735 void MarblePart::initializeCustomTimezone()
1736 {
1737     if( m_timezone.count() == 0)
1738     {
1739         m_timezone.insert( 0, 0 );
1740         m_timezone.insert( 1, 3600 );
1741         m_timezone.insert( 2, 7200 );
1742         m_timezone.insert( 3, 7200 );
1743         m_timezone.insert( 4, 10800 );
1744         m_timezone.insert( 5, 12600 );
1745         m_timezone.insert( 6, 14400 );
1746         m_timezone.insert( 7, 18000 );
1747         m_timezone.insert( 8, 19800 );
1748         m_timezone.insert( 9, 21600 );
1749         m_timezone.insert( 10, 25200 );
1750         m_timezone.insert( 11, 28800 );
1751         m_timezone.insert( 12, 32400 );
1752         m_timezone.insert( 13, 34200 );
1753         m_timezone.insert( 14, 36000 );
1754         m_timezone.insert( 15, 39600 );
1755         m_timezone.insert( 16, 43200 );
1756         m_timezone.insert( 17, -39600 );
1757         m_timezone.insert( 18, -36000 );
1758         m_timezone.insert( 19, -32400 );
1759         m_timezone.insert( 20, -28800 );
1760         m_timezone.insert( 21, -25200 );
1761         m_timezone.insert( 22, -25200 );
1762         m_timezone.insert( 23, -21600 );
1763         m_timezone.insert( 24, -18000 );
1764         m_timezone.insert( 25, -18000 );
1765         m_timezone.insert( 26, -14400 );
1766         m_timezone.insert( 27, -12600 );
1767         m_timezone.insert( 28, -10800 );
1768         m_timezone.insert( 29, -10800 );
1769         m_timezone.insert( 30, -3600 );
1770     }
1771 }
1772 
1773 void MarblePart::printMapScreenShot()
1774 {
1775 #ifndef QT_NO_PRINTER
1776     QPrinter printer( QPrinter::HighResolution );
1777     QPointer<QPrintDialog> printDialog = new QPrintDialog( &printer, widget() );
1778     m_controlView->printMapScreenShot( printDialog );
1779     delete printDialog;
1780 #endif
1781 }
1782 
1783 void MarblePart::updateMapEditButtonVisibility( const QString &mapTheme )
1784 {
1785     Q_ASSERT( m_externalMapEditorAction );
1786     m_externalMapEditorAction->setVisible(mapTheme == QLatin1String("earth/openstreetmap/openstreetmap.dgml"));
1787 }
1788 
1789 void MarblePart::fallBackToDefaultTheme()
1790 {
1791     m_controlView->marbleWidget()->setMapThemeId( m_controlView->defaultMapThemeId() );
1792 }
1793 
1794 void MarblePart::showMovieCaptureDialog()
1795 {
1796     if (m_movieCaptureDialog == nullptr) {
1797         m_movieCaptureDialog = new MovieCaptureDialog(m_controlView->marbleWidget(),
1798                                                       m_controlView->marbleWidget());
1799         connect( m_movieCaptureDialog, SIGNAL(started()), this, SLOT(changeRecordingState()));
1800     }
1801     m_movieCaptureDialog->show();
1802 }
1803 
1804 void MarblePart::stopRecording()
1805 {
1806     if ( m_movieCaptureDialog ) {
1807         m_movieCaptureDialog->stopRecording();
1808         changeRecordingState();
1809     }
1810 }
1811 
1812 void MarblePart::changeRecordingState()
1813 {
1814     m_recordMovieAction->setEnabled( !m_recordMovieAction->isEnabled() );
1815     m_stopRecordingAction->setEnabled( !m_stopRecordingAction->isEnabled() );
1816 }
1817 
1818 }
1819 
1820 #include "moc_marble_part.cpp"
1821 #include "marble_part.moc"