wait for core is on before displaying ui

Use directly accountProxy and react to signals.
This commit is contained in:
Gaelle Braud 2024-10-18 16:33:55 +02:00
parent 0afdc6d6d7
commit 075937aa00
9 changed files with 104 additions and 27 deletions

View file

@ -341,6 +341,13 @@ void App::setSelf(QSharedPointer<App>(me)) {
} }
}); });
}); });
mCoreModelConnection->makeConnectToModel(
&CoreModel::globalStateChanged,
[this](const std::shared_ptr<linphone::Core> &core, linphone::GlobalState gstate, const std::string &message) {
if (gstate == linphone::GlobalState::On) {
mCoreModelConnection->invokeToCore([this] { setCoreStarted(true); });
}
});
mCoreModelConnection->makeConnectToModel( mCoreModelConnection->makeConnectToModel(
&CoreModel::authenticationRequested, &CoreModel::authenticationRequested,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::AuthInfo> &authInfo, [this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::AuthInfo> &authInfo,
@ -424,9 +431,10 @@ void App::initCore() {
mLinphoneThread->getThreadId(), mLinphoneThread->getThreadId(),
[this]() mutable { [this]() mutable {
CoreModel::getInstance()->start(); CoreModel::getInstance()->start();
auto coreStarted = CoreModel::getInstance()->getCore()->getGlobalState() == linphone::GlobalState::On;
SettingsModel::create(); SettingsModel::create();
auto settings = SettingsCore::create(); auto settings = SettingsCore::create();
QMetaObject::invokeMethod(App::getInstance()->thread(), [this, settings] { QMetaObject::invokeMethod(App::getInstance()->thread(), [this, settings, coreStarted] {
// QML // QML
mEngine = new QQmlApplicationEngine(this); mEngine = new QQmlApplicationEngine(this);
assert(mEngine); assert(mEngine);
@ -473,6 +481,7 @@ void App::initCore() {
mNotifier = new Notifier(mEngine); mNotifier = new Notifier(mEngine);
mSettings = settings; mSettings = settings;
mEngine->setObjectOwnership(mSettings.get(), QQmlEngine::CppOwnership); mEngine->setObjectOwnership(mSettings.get(), QQmlEngine::CppOwnership);
mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
mAccountList = AccountList::create(); mAccountList = AccountList::create();
mCallList = CallList::create(); mCallList = CallList::create();
setAutoStart(mSettings->getAutoStart()); setAutoStart(mSettings->getAutoStart());
@ -484,7 +493,7 @@ void App::initCore() {
const QUrl url(u"qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml"_qs); const QUrl url(u"qrc:/qt/qml/Linphone/view/Page/Window/Main/MainWindow.qml"_qs);
QObject::connect( QObject::connect(
mEngine, &QQmlApplicationEngine::objectCreated, this, mEngine, &QQmlApplicationEngine::objectCreated, this,
[this, url](QObject *obj, const QUrl &objUrl) { [this, url, coreStarted](QObject *obj, const QUrl &objUrl) {
if (url == objUrl) { if (url == objUrl) {
if (!obj) { if (!obj) {
lCritical() << log().arg("MainWindow.qml couldn't be load. The app will exit"); lCritical() << log().arg("MainWindow.qml couldn't be load. The app will exit");
@ -492,7 +501,7 @@ void App::initCore() {
} }
auto window = qobject_cast<QQuickWindow *>(obj); auto window = qobject_cast<QQuickWindow *>(obj);
setMainWindow(window); setMainWindow(window);
QMetaObject::invokeMethod(obj, "initStackViewItem"); setCoreStarted(coreStarted);
#ifndef __APPLE__ #ifndef __APPLE__
// Enable TrayIconSystem. // Enable TrayIconSystem.
if (!QSystemTrayIcon::isSystemTrayAvailable()) if (!QSystemTrayIcon::isSystemTrayAvailable())
@ -523,6 +532,8 @@ void App::initCore() {
} }
void App::initCppInterfaces() { void App::initCppInterfaces() {
qmlRegisterSingletonType<App>(Constants::MainQmlUri, 1, 0, "AppCpp",
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return App::getInstance(); });
qmlRegisterSingletonType<LoginPage>( qmlRegisterSingletonType<LoginPage>(
Constants::MainQmlUri, 1, 0, "LoginPageCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * { Constants::MainQmlUri, 1, 0, "LoginPageCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * {
static auto loginPage = new LoginPage(); static auto loginPage = new LoginPage();
@ -698,6 +709,17 @@ void App::sendCommand() {
} }
} }
bool App::getCoreStarted() const {
return mCoreStarted;
}
void App::setCoreStarted(bool started) {
if (mCoreStarted != started) {
mCoreStarted = started;
emit coreStartedChanged(mCoreStarted);
}
}
bool App::notify(QObject *receiver, QEvent *event) { bool App::notify(QObject *receiver, QEvent *event) {
bool done = true; bool done = true;
try { try {

View file

@ -38,6 +38,7 @@ class QSystemTrayIcon;
class App : public SingleApplication, public AbstractObject { class App : public SingleApplication, public AbstractObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool coreStarted READ getCoreStarted WRITE setCoreStarted NOTIFY coreStartedChanged)
public: public:
App(int &argc, char *argv[]); App(int &argc, char *argv[]);
~App(); ~App();
@ -113,6 +114,9 @@ public:
void onLoggerInitialized(); void onLoggerInitialized();
void sendCommand(); void sendCommand();
bool getCoreStarted() const;
void setCoreStarted(bool started);
QQuickWindow *getCallsWindow(QVariant callGui = QVariant()); QQuickWindow *getCallsWindow(QVariant callGui = QVariant());
void setCallsWindowProperty(const char *id, QVariant property); void setCallsWindowProperty(const char *id, QVariant property);
void closeCallsWindow(); void closeCallsWindow();
@ -141,6 +145,7 @@ public:
signals: signals:
void mainWindowChanged(); void mainWindowChanged();
void coreStartedChanged(bool coreStarted);
// void executeCommand(QString command); // void executeCommand(QString command);
private: private:
@ -160,6 +165,7 @@ private:
QSharedPointer<SafeConnection<App, CoreModel>> mCoreModelConnection; QSharedPointer<SafeConnection<App, CoreModel>> mCoreModelConnection;
QSharedPointer<SafeConnection<App, CliModel>> mCliModelConnection; QSharedPointer<SafeConnection<App, CliModel>> mCliModelConnection;
bool mAutoStart = false; bool mAutoStart = false;
bool mCoreStarted = false;
QLocale mLocale = QLocale::system(); QLocale mLocale = QLocale::system();
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT

View file

@ -50,8 +50,8 @@ void AccountList::setSelf(QSharedPointer<AccountList> me) {
mModelConnection = QSharedPointer<SafeConnection<AccountList, CoreModel>>( mModelConnection = QSharedPointer<SafeConnection<AccountList, CoreModel>>(
new SafeConnection<AccountList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater); new SafeConnection<AccountList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
mModelConnection->makeConnectToCore(&AccountList::lUpdate, [this]() { mModelConnection->makeConnectToCore(&AccountList::lUpdate, [this](bool isInitialization) {
mModelConnection->invokeToModel([this]() { mModelConnection->invokeToModel([this, isInitialization]() {
// Avoid copy to lambdas // Avoid copy to lambdas
QList<QSharedPointer<AccountCore>> *accounts = new QList<QSharedPointer<AccountCore>>(); QList<QSharedPointer<AccountCore>> *accounts = new QList<QSharedPointer<AccountCore>>();
mustBeInLinphoneThread(getClassName()); mustBeInLinphoneThread(getClassName());
@ -63,11 +63,12 @@ void AccountList::setSelf(QSharedPointer<AccountList> me) {
if (it == defaultAccount) defaultAccountCore = AccountCore::create(defaultAccount); if (it == defaultAccount) defaultAccountCore = AccountCore::create(defaultAccount);
accounts->push_back(model); accounts->push_back(model);
} }
mModelConnection->invokeToCore([this, accounts, defaultAccountCore]() { mModelConnection->invokeToCore([this, accounts, defaultAccountCore, isInitialization]() {
mustBeInMainThread(getClassName()); mustBeInMainThread(getClassName());
resetData<AccountCore>(*accounts); resetData<AccountCore>(*accounts);
setHaveAccount(accounts->size() > 0); setHaveAccount(accounts->size() > 0);
setDefaultAccount(defaultAccountCore); setDefaultAccount(defaultAccountCore);
if (isInitialization) setInitialized(true);
delete accounts; delete accounts;
}); });
}); });
@ -80,11 +81,10 @@ void AccountList::setSelf(QSharedPointer<AccountList> me) {
mModelConnection->invokeToCore([this, model]() { setDefaultAccount(model); }); mModelConnection->invokeToCore([this, model]() { setDefaultAccount(model); });
} else mModelConnection->invokeToCore([this]() { setDefaultAccount(nullptr); }); } else mModelConnection->invokeToCore([this]() { setDefaultAccount(nullptr); });
}); });
mModelConnection->makeConnectToModel(&CoreModel::accountRemoved, &AccountList::lUpdate); mModelConnection->makeConnectToModel(&CoreModel::accountRemoved, [this] { emit lUpdate(); });
mModelConnection->makeConnectToModel(&CoreModel::accountAdded, &AccountList::lUpdate); mModelConnection->makeConnectToModel(&CoreModel::accountAdded, [this] { emit lUpdate(); });
lUpdate(); lUpdate(true);
emit initialized();
} }
QSharedPointer<AccountCore> AccountList::getDefaultAccountCore() const { QSharedPointer<AccountCore> AccountList::getDefaultAccountCore() const {
@ -135,6 +135,17 @@ void AccountList::setHaveAccount(bool haveAccount) {
} }
} }
bool AccountList::isInitialized() const {
return mIsInitialized;
}
void AccountList::setInitialized(bool init) {
if (mIsInitialized != init) {
mIsInitialized = init;
emit initializedChanged(mIsInitialized);
}
}
QVariant AccountList::data(const QModelIndex &index, int role) const { QVariant AccountList::data(const QModelIndex &index, int role) const {
int row = index.row(); int row = index.row();
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant(); if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();

View file

@ -49,15 +49,19 @@ public:
bool getHaveAccount() const; bool getHaveAccount() const;
void setHaveAccount(bool haveAccount); void setHaveAccount(bool haveAccount);
bool isInitialized() const;
void setInitialized(bool init);
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
signals: signals:
void lUpdate(); void lUpdate(bool isInitialization = false);
void haveAccountChanged(); void haveAccountChanged();
void defaultAccountChanged(); void defaultAccountChanged();
void initialized(); void initializedChanged(bool init);
private: private:
bool mHaveAccount = false; bool mHaveAccount = false;
bool mIsInitialized = false;
QSharedPointer<AccountCore> mDefaultAccount; QSharedPointer<AccountCore> mDefaultAccount;
QSharedPointer<SafeConnection<AccountList, CoreModel>> mModelConnection; QSharedPointer<SafeConnection<AccountList, CoreModel>> mModelConnection;
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT

View file

@ -24,7 +24,7 @@
#include "core/App.hpp" #include "core/App.hpp"
AccountProxy::AccountProxy(QObject *parent) : LimitProxy(parent) { AccountProxy::AccountProxy(QObject *parent) : LimitProxy(parent) {
setSourceModels(new SortFilterList(App::getInstance()->getAccountList().get(), Qt::AscendingOrder)); setSourceModel(App::getInstance()->getAccountList().get());
} }
AccountProxy::~AccountProxy() { AccountProxy::~AccountProxy() {
@ -59,6 +59,17 @@ bool AccountProxy::getHaveAccount() const {
return getListModel<AccountList>()->getHaveAccount(); return getListModel<AccountList>()->getHaveAccount();
} }
bool AccountProxy::isInitialized() const {
return mInitialized;
}
void AccountProxy::setInitialized(bool init) {
if (mInitialized != init) {
mInitialized = init;
emit initializedChanged();
}
}
void AccountProxy::setSourceModel(QAbstractItemModel *model) { void AccountProxy::setSourceModel(QAbstractItemModel *model) {
auto oldAccountList = getListModel<AccountList>(); auto oldAccountList = getListModel<AccountList>();
if (oldAccountList) { if (oldAccountList) {
@ -66,6 +77,11 @@ void AccountProxy::setSourceModel(QAbstractItemModel *model) {
} }
auto newAccountList = dynamic_cast<AccountList *>(model); auto newAccountList = dynamic_cast<AccountList *>(model);
if (newAccountList) { if (newAccountList) {
connect(newAccountList, &AccountList::initializedChanged, this, [this](bool init) {
qDebug() << "AccountProxy initialized";
setInitialized(init);
});
setInitialized(newAccountList->isInitialized());
connect(newAccountList, &AccountList::countChanged, this, &AccountProxy::resetDefaultAccount, connect(newAccountList, &AccountList::countChanged, this, &AccountProxy::resetDefaultAccount,
Qt::QueuedConnection); Qt::QueuedConnection);
connect(newAccountList, &AccountList::defaultAccountChanged, this, &AccountProxy::resetDefaultAccount, connect(newAccountList, &AccountList::defaultAccountChanged, this, &AccountProxy::resetDefaultAccount,
@ -73,7 +89,7 @@ void AccountProxy::setSourceModel(QAbstractItemModel *model) {
connect(newAccountList, &AccountList::haveAccountChanged, this, &AccountProxy::haveAccountChanged, connect(newAccountList, &AccountList::haveAccountChanged, this, &AccountProxy::haveAccountChanged,
Qt::QueuedConnection); Qt::QueuedConnection);
} }
QSortFilterProxyModel::setSourceModel(model); setSourceModels(new SortFilterList(model, Qt::AscendingOrder));
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------

View file

@ -33,6 +33,7 @@ class AccountProxy : public LimitProxy {
Q_PROPERTY(AccountGui *defaultAccount READ getDefaultAccount WRITE setDefaultAccount NOTIFY defaultAccountChanged) Q_PROPERTY(AccountGui *defaultAccount READ getDefaultAccount WRITE setDefaultAccount NOTIFY defaultAccountChanged)
Q_PROPERTY(bool haveAccount READ getHaveAccount NOTIFY haveAccountChanged) Q_PROPERTY(bool haveAccount READ getHaveAccount NOTIFY haveAccountChanged)
Q_PROPERTY(bool isInitialized READ isInitialized NOTIFY initializedChanged)
public: public:
DECLARE_SORTFILTER_CLASS() DECLARE_SORTFILTER_CLASS()
@ -48,14 +49,18 @@ public:
bool getHaveAccount() const; bool getHaveAccount() const;
bool isInitialized() const;
void setInitialized(bool init);
void setSourceModel(QAbstractItemModel *sourceModel) override; void setSourceModel(QAbstractItemModel *sourceModel) override;
signals: signals:
void defaultAccountChanged(); void defaultAccountChanged();
void haveAccountChanged(); void haveAccountChanged();
void initialized(); void initializedChanged();
protected: protected:
bool mInitialized = false;
QSharedPointer<AccountCore> mDefaultAccount; // When null, a new UI object is build from List QSharedPointer<AccountCore> mDefaultAccount; // When null, a new UI object is build from List
}; };

View file

@ -38,9 +38,11 @@ bool LimitProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent
void LimitProxy::setSourceModels(SortFilterProxy *firstList) { void LimitProxy::setSourceModels(SortFilterProxy *firstList) {
auto secondList = firstList->sourceModel(); auto secondList = firstList->sourceModel();
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::onAdded); if (secondList) {
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::onRemoved); connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::onAdded);
connect(secondList, &QAbstractItemModel::modelReset, this, &LimitProxy::invalidateRowsFilter); connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::onRemoved);
connect(secondList, &QAbstractItemModel::modelReset, this, &LimitProxy::invalidateRowsFilter);
}
connect(firstList, &SortFilterProxy::filterTextChanged, this, &LimitProxy::filterTextChanged); connect(firstList, &SortFilterProxy::filterTextChanged, this, &LimitProxy::filterTextChanged);
connect(firstList, &SortFilterProxy::filterTypeChanged, this, &LimitProxy::filterTypeChanged); connect(firstList, &SortFilterProxy::filterTypeChanged, this, &LimitProxy::filterTypeChanged);

View file

@ -201,7 +201,7 @@ AbstractMainPage {
spacing: 38 * DefaultStyle.dp spacing: 38 * DefaultStyle.dp
SearchBar { SearchBar {
id: searchBar id: searchBar
visible: contactList.model.sourceModel.count != 0 visible: contactList.count != 0
Layout.leftMargin: leftPanel.leftMargin Layout.leftMargin: leftPanel.leftMargin
Layout.rightMargin: leftPanel.rightMargin Layout.rightMargin: leftPanel.rightMargin
Layout.topMargin: 18 * DefaultStyle.dp Layout.topMargin: 18 * DefaultStyle.dp

View file

@ -17,7 +17,8 @@ AbstractWindow {
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
signal callCreated() signal callCreated()
property var accountProxy: accountProxyLoader.item
// TODO : use this to make the border transparent // TODO : use this to make the border transparent
// flags: Qt.Window | Qt.FramelessWindowHint | Qt.WindowTitleHint // flags: Qt.Window | Qt.FramelessWindowHint | Qt.WindowTitleHint
// menuBar: Rectangle { // menuBar: Rectangle {
@ -25,6 +26,7 @@ AbstractWindow {
// height: 40 * DefaultStyle.dp // height: 40 * DefaultStyle.dp
// color: DefaultStyle.grey_100 // color: DefaultStyle.grey_100
// } // }
function openMainPage(){ function openMainPage(){
if (mainWindowStackView.currentItem.objectName !== "mainPage") mainWindowStackView.replace(mainPage, StackView.Immediate) if (mainWindowStackView.currentItem.objectName !== "mainPage") mainWindowStackView.replace(mainPage, StackView.Immediate)
} }
@ -45,10 +47,12 @@ AbstractWindow {
UtilsCpp.showInformationPopup(qsTr("Appel transféré"), qsTr("Votre correspondant a été transféré au contact sélectionné")) UtilsCpp.showInformationPopup(qsTr("Appel transféré"), qsTr("Votre correspondant a été transféré au contact sélectionné"))
} }
function initStackViewItem() { function initStackViewItem() {
if (accountProxy.haveAccount) openMainPage() if(accountProxy && accountProxy.isInitialized) {
else if (SettingsCpp.getFirstLaunch()) mainWindowStackView.replace(welcomePage, StackView.Immediate) if (accountProxy.haveAccount) openMainPage()
else if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) mainWindowStackView.replace(sipLoginPage, StackView.Immediate) else if (SettingsCpp.getFirstLaunch()) mainWindowStackView.replace(welcomePage, StackView.Immediate)
else mainWindowStackView.replace(loginPage, StackView.Immediate) else if (SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin) mainWindowStackView.replace(sipLoginPage, StackView.Immediate)
else mainWindowStackView.replace(loginPage, StackView.Immediate)
}
} }
function goToLogin() { function goToLogin() {
@ -90,9 +94,16 @@ AbstractWindow {
} }
} }
AccountProxy { Loader {
id: accountProxy id: accountProxyLoader
onInitialized: initStackViewItem() active: AppCpp.coreStarted
sourceComponent: AccountProxy {
Component.onCompleted: {
mainWindow.accountProxy = this
mainWindow.initStackViewItem()
}
onInitializedChanged: mainWindow.initStackViewItem()
}
} }
StackView { StackView {