diff --git a/linphone-desktop/src/app/App.cpp b/linphone-desktop/src/app/App.cpp index 2eeb5a9ef..1e1ae3cea 100644 --- a/linphone-desktop/src/app/App.cpp +++ b/linphone-desktop/src/app/App.cpp @@ -89,6 +89,7 @@ App::App (int &argc, char *argv[]) : SingleApplication(argc, argv, true) { App::~App () { qInfo() << QStringLiteral("Destroying app..."); + delete mEngine; } // ----------------------------------------------------------------------------- @@ -120,35 +121,56 @@ inline void activeSplashScreen (App *app) { } void App::initContentApp () { + // Destroy qml components and linphone core if necessary. + if (mEngine) { + qInfo() << QStringLiteral("Restarting app..."); + delete mEngine; + + mCallsWindow = nullptr; + mSettingsWindow = nullptr; + + CoreManager::uninit(); + } else { + // Don't quit if last window is closed!!! + setQuitOnLastWindowClosed(false); + + QObject::connect( + this, &App::receivedMessage, this, [this](int, QByteArray message) { + if (message == "show") + App::smartShowWindow(getMainWindow()); + } + ); + } + // Init core. CoreManager::init(this, mParser.value("config")); - qInfo() << "Activated selectors:" << QQmlFileSelector::get(&mEngine)->selector()->allSelectors(); + + // Init engine content. + mEngine = new QQmlApplicationEngine(); + qInfo() << QStringLiteral("Activated selectors:") << QQmlFileSelector::get(mEngine)->selector()->allSelectors(); // Provide `+custom` folders for custom components. - (new QQmlFileSelector(&mEngine, this))->setExtraSelectors(QStringList("custom")); + (new QQmlFileSelector(mEngine, mEngine))->setExtraSelectors(QStringList("custom")); // Set modules paths. - mEngine.addImportPath(":/ui/modules"); - mEngine.addImportPath(":/ui/scripts"); - mEngine.addImportPath(":/ui/views"); + mEngine->addImportPath(":/ui/modules"); + mEngine->addImportPath(":/ui/scripts"); + mEngine->addImportPath(":/ui/views"); // Provide avatars/thumbnails providers. - mEngine.addImageProvider(AvatarProvider::PROVIDER_ID, new AvatarProvider()); - mEngine.addImageProvider(ThumbnailProvider::PROVIDER_ID, new ThumbnailProvider()); + mEngine->addImageProvider(AvatarProvider::PROVIDER_ID, new AvatarProvider()); + mEngine->addImageProvider(ThumbnailProvider::PROVIDER_ID, new ThumbnailProvider()); - // Don't quit if last window is closed!!! - setQuitOnLastWindowClosed(false); - - // Register types. registerTypes(); + registerSharedTypes(); // Enable notifications. - mNotifier = new Notifier(this); + createNotifier(); // Load main view. - qInfo() << "Loading main view..."; - mEngine.load(QUrl(QML_VIEW_MAIN_WINDOW)); - if (mEngine.rootObjects().isEmpty()) + qInfo() << QStringLiteral("Loading main view..."); + mEngine->load(QUrl(QML_VIEW_MAIN_WINDOW)); + if (mEngine->rootObjects().isEmpty()) qFatal("Unable to open main window."); // Load splashscreen. @@ -159,13 +181,6 @@ void App::initContentApp () { &CoreManager::linphoneCoreCreated, this, mParser.isSet("selftest") ? &App::quit : &App::openAppAfterInit ); - - QObject::connect( - this, &App::receivedMessage, this, [this](int, QByteArray message) { - if (message == "show") - App::smartShowWindow(getMainWindow()); - } - ); } // ----------------------------------------------------------------------------- @@ -228,7 +243,7 @@ QQuickWindow *App::getCallsWindow () { QQuickWindow *App::getMainWindow () const { return qobject_cast( - const_cast(&mEngine)->rootObjects().at(0) + const_cast(mEngine)->rootObjects().at(0) ); } @@ -238,7 +253,7 @@ QQuickWindow *App::getSettingsWindow () { QObject::connect( mSettingsWindow, &QWindow::visibilityChanged, this, [](QWindow::Visibility visibility) { if (visibility == QWindow::Hidden) { - qInfo() << "Update nat policy."; + qInfo() << QStringLiteral("Update nat policy."); shared_ptr core = CoreManager::getInstance()->getCore(); core->setNatPolicy(core->getNatPolicy()); } @@ -331,6 +346,10 @@ void App::registerTypes () { registerUncreatableType(ContactModel, "ContactModel"); registerUncreatableType(SipAddressObserver, "SipAddressObserver"); registerUncreatableType(VcardModel, "VcardModel"); +} + +void App::registerSharedTypes () { + qInfo() << QStringLiteral("Registering shared types..."); registerSharedSingletonType(App, "App", App::getInstance); registerSharedSingletonType(CoreManager, "CoreManager", CoreManager::getInstance); @@ -348,7 +367,7 @@ void App::registerTypes () { void App::setTrayIcon () { QQuickWindow *root = getMainWindow(); - QSystemTrayIcon *systemTrayIcon = new QSystemTrayIcon(root); + QSystemTrayIcon *systemTrayIcon = new QSystemTrayIcon(mEngine); // trayIcon: Right click actions. QAction *quitAction = new QAction("Quit", root); @@ -387,6 +406,13 @@ void App::setTrayIcon () { // ----------------------------------------------------------------------------- +void App::createNotifier () { + if (!mNotifier) + mNotifier = new Notifier(this); +} + +// ----------------------------------------------------------------------------- + QString App::getConfigLocale () const { return ::Utils::linphoneStringToQString( CoreManager::getInstance()->getCore()->getConfig()->getString( diff --git a/linphone-desktop/src/app/App.hpp b/linphone-desktop/src/app/App.hpp index e995933f7..9e26f2a8f 100644 --- a/linphone-desktop/src/app/App.hpp +++ b/linphone-desktop/src/app/App.hpp @@ -30,6 +30,8 @@ #include "../components/notifier/Notifier.hpp" #include "../externals/single-application/SingleApplication.hpp" +#define APP_CODE_RESTART 1000 + // ============================================================================= class DefaultTranslator; @@ -52,7 +54,7 @@ public: void tryToUsePreferredLocale (); QQmlEngine *getEngine () { - return &mEngine; + return mEngine; } Notifier *getNotifier () const { @@ -64,12 +66,16 @@ public: bool hasFocus () const; - Q_INVOKABLE QQuickWindow *getSettingsWindow (); - static App *getInstance () { return static_cast(QApplication::instance()); } + Q_INVOKABLE void restart () { + exit(APP_CODE_RESTART); + } + + Q_INVOKABLE QQuickWindow *getSettingsWindow (); + Q_INVOKABLE static void smartShowWindow (QQuickWindow *window); Q_INVOKABLE static QString convertUrlToLocalPath (const QUrl &url); @@ -81,7 +87,9 @@ signals: private: void registerTypes (); + void registerSharedTypes (); void setTrayIcon (); + void createNotifier (); QString getConfigLocale () const; void setConfigLocale (const QString &locale); @@ -103,7 +111,7 @@ private: QVariantList mAvailableLocales; QString mLocale; - QQmlApplicationEngine mEngine; + QQmlApplicationEngine *mEngine = nullptr; DefaultTranslator *mTranslator = nullptr; Notifier *mNotifier = nullptr; diff --git a/linphone-desktop/src/components/core/CoreManager.cpp b/linphone-desktop/src/components/core/CoreManager.cpp index 1a884d701..546f28c47 100644 --- a/linphone-desktop/src/components/core/CoreManager.cpp +++ b/linphone-desktop/src/components/core/CoreManager.cpp @@ -73,6 +73,13 @@ void CoreManager::init (QObject *parent, const QString &configPath) { QObject::connect(timer, &QTimer::timeout, mInstance, &CoreManager::iterate); } +void CoreManager::uninit () { + if (mInstance) { + delete mInstance; + mInstance = nullptr; + } +} + // ----------------------------------------------------------------------------- VcardModel *CoreManager::createDetachedVcardModel () { diff --git a/linphone-desktop/src/components/core/CoreManager.hpp b/linphone-desktop/src/components/core/CoreManager.hpp index bfeaf3fc6..eaf9e564b 100644 --- a/linphone-desktop/src/components/core/CoreManager.hpp +++ b/linphone-desktop/src/components/core/CoreManager.hpp @@ -98,6 +98,7 @@ public: // --------------------------------------------------------------------------- static void init (QObject *parent, const QString &configPath); + static void uninit (); static CoreManager *getInstance () { return mInstance; diff --git a/linphone-desktop/src/main.cpp b/linphone-desktop/src/main.cpp index 3faeb435c..343bbc2c7 100644 --- a/linphone-desktop/src/main.cpp +++ b/linphone-desktop/src/main.cpp @@ -97,7 +97,12 @@ int main (int argc, char *argv[]) { // Init and run! // --------------------------------------------------------------------------- - app.initContentApp(); qInfo() << QStringLiteral("Running app..."); - return app.exec(); + + int ret; + do { + app.initContentApp(); + ret = app.exec(); + } while (ret == APP_CODE_RESTART); + return ret; } diff --git a/linphone-desktop/ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml b/linphone-desktop/ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml index be5e64610..e00c4d657 100644 --- a/linphone-desktop/ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml +++ b/linphone-desktop/ui/views/App/Main/Assistant/FetchRemoteConfiguration.qml @@ -1,10 +1,11 @@ import Common 1.0 +import Linphone 1.0 // ============================================================================= AssistantAbstractView { mainAction: (function () { - console.log('TODO') + App.restart() }) mainActionEnabled: url.text.length > 0