Options : 'auto_start' + 'exit_on_close'

This commit is contained in:
Julien Wadel 2024-10-02 12:40:45 +02:00
parent ca09b82047
commit d8f75c3994
10 changed files with 161 additions and 60 deletions

View file

@ -22,17 +22,20 @@
#include "App.hpp"
#include <QAction>
#include <QCoreApplication>
#include <QDirIterator>
#include <QFileSelector>
#include <QFontDatabase>
#include <QGuiApplication>
#include <QLibraryInfo>
#include <QMenu>
#include <QProcessEnvironment>
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlFileSelector>
#include <QQuickWindow>
#include <QSystemTrayIcon>
#include <QTimer>
#include "core/account/AccountCore.hpp"
@ -122,7 +125,7 @@ bool App::autoStartEnabled() {
// check if the Exec part of the autostart ini file not corresponding to our executable (old desktop entry with
// wrong version in filename)
if (autoStartConf.indexOf(QString("Exec=" + exec + " ")) <
0) { // On autostart, there is the option --iconified so there is one space.
0) { // On autostart, there is the option --minimized so there is one space.
// replace file
setAutoStart(true);
}
@ -231,10 +234,10 @@ void App::setAutoStart(bool enabled) {
#else
void App::setAutoStart(bool enabled) {
if (enabled == mAutoStart) return;
QSettings settings(AutoStartSettingsFilePath, QSettings::NativeFormat);
if (enabled) settings.setValue(EXECUTABLE_NAME, QDir::toNativeSeparators(applicationFilePath()));
QString parameters;
if (!mSettings->getExitOnClose()) parameters = " --minimized";
if (enabled) settings.setValue(EXECUTABLE_NAME, QDir::toNativeSeparators(applicationFilePath()) + parameters);
else settings.remove(EXECUTABLE_NAME);
mAutoStart = enabled;
@ -402,7 +405,6 @@ void App::init() {
lDebug() << log().arg("Starting Thread");
mLinphoneThread->start();
}
setQuitOnLastWindowClosed(true); // TODO: use settings to set it
lInfo() << log().arg("Display server : %1").arg(platformName());
}
@ -468,6 +470,9 @@ void App::initCore() {
mAccountList = AccountList::create();
mCallList = CallList::create();
setAutoStart(mSettings->getAutoStart());
setQuitOnLastWindowClosed(mSettings->getExitOnClose());
connect(mSettings.get(), &SettingsCore::exitOnCloseChanged, this, &App::onExitOnCloseChanged,
Qt::UniqueConnection);
const QUrl url(u"qrc:/Linphone/view/Page/Window/Main/MainWindow.qml"_qs);
QObject::connect(
@ -478,9 +483,20 @@ void App::initCore() {
lCritical() << log().arg("MainWindow.qml couldn't be load. The app will exit");
exit(-1);
}
setMainWindow(qobject_cast<QQuickWindow *>(obj));
auto window = qobject_cast<QQuickWindow *>(obj);
setMainWindow(window);
QMetaObject::invokeMethod(obj, "initStackViewItem");
Q_ASSERT(mMainWindow);
#ifndef __APPLE__
// Enable TrayIconSystem.
if (!QSystemTrayIcon::isSystemTrayAvailable())
qWarning("System tray not found on this system.");
else setSysTrayIcon();
#endif // ifndef __APPLE__
static bool firstOpen = true;
if (!firstOpen || !mParser->isSet("minimized")) {
window->show();
}
firstOpen = false;
}
},
Qt::QueuedConnection);
@ -634,7 +650,7 @@ void App::createCommandParser() {
tr("commandLineOptionFetchConfigArg")},
{{"c", "call"}, tr("commandLineOptionCall").replace("%1", EXECUTABLE_NAME), tr("commandLineOptionCallArg")},
#ifndef Q_OS_MACOS
{"iconified", tr("commandLineOptionIconified")},
{"minimized", tr("commandLineOptionMinimized")},
#endif // ifndef Q_OS_MACOS
{{"V", "verbose"}, tr("commandLineOptionVerbose")},
{"qt-logs-only", tr("commandLineOptionQtLogsOnly")},
@ -750,6 +766,12 @@ QSharedPointer<SettingsCore> App::getSettings() const {
return mSettings;
}
void App::onExitOnCloseChanged() {
setSysTrayIcon(); // Restore button depends from this option
setQuitOnLastWindowClosed(mSettings->getExitOnClose());
setAutoStart(mSettings->getAutoStart());
}
#ifdef Q_OS_LINUX
QString App::getApplicationPath() const {
const QString binPath(QCoreApplication::applicationFilePath());
@ -827,7 +849,7 @@ bool App::generateDesktopFile(const QString &confPath, bool remove, bool openInB
"GenericName=SIP Phone\n"
"Comment=" APPLICATION_DESCRIPTION "\n"
"Type=Application\n")
<< (openInBackground ? "Exec=" + exec + " --iconified %u\n" : "Exec=" + exec + " %u\n")
<< (openInBackground ? "Exec=" + exec + " --minimized %u\n" : "Exec=" + exec + " %u\n")
<< (haveIcon ? "Icon=" + iconPath + "\n" : "Icon=" EXECUTABLE_NAME "\n")
<< "Terminal=false\n"
"Categories=Network;Telephony;\n"
@ -860,5 +882,56 @@ bool App::event(QEvent *event) {
#endif
//-----------------------------------------------------------
// AutoStart
// System tray
//-----------------------------------------------------------
void App::setSysTrayIcon() {
QQuickWindow *root = getMainWindow();
QSystemTrayIcon *systemTrayIcon =
(mSystemTrayIcon
? mSystemTrayIcon
: new QSystemTrayIcon(
nullptr)); // Workaround : QSystemTrayIcon cannot be deleted because of setContextMenu (indirectly)
// trayIcon: Right click actions.
QAction *restoreAction = nullptr;
if (!mSettings->getExitOnClose()) {
restoreAction = new QAction(root);
auto setRestoreActionText = [restoreAction](bool visible) {
restoreAction->setText(visible ? tr("Cacher") : tr("Afficher"));
};
setRestoreActionText(root->isVisible());
connect(root, &QWindow::visibleChanged, restoreAction, setRestoreActionText);
root->connect(restoreAction, &QAction::triggered, this, [this, restoreAction](bool checked) {
auto mainWindow = getMainWindow();
if (mainWindow->isVisible()) {
mainWindow->close();
} else {
mainWindow->show();
}
});
}
QAction *quitAction = new QAction(tr("Quit"), root);
root->connect(quitAction, &QAction::triggered, this, &App::quit);
// trayIcon: Left click actions.
QMenu *menu = mSystemTrayIcon ? mSystemTrayIcon->contextMenu() : new QMenu();
menu->clear();
menu->setTitle(APPLICATION_NAME);
// Build trayIcon menu.
if (restoreAction) {
menu->addAction(restoreAction);
menu->addSeparator();
}
menu->addAction(quitAction);
if (!mSystemTrayIcon)
systemTrayIcon->setContextMenu(menu); // This is a Qt bug. We cannot call setContextMenu more than once. So we
// have to keep an instance of the menu.
systemTrayIcon->setIcon(QIcon(Constants::WindowIconPath));
systemTrayIcon->setToolTip(APPLICATION_NAME);
systemTrayIcon->show();
if (!mSystemTrayIcon) mSystemTrayIcon = systemTrayIcon;
if (!QSystemTrayIcon::isSystemTrayAvailable()) qInfo() << "System tray is not available";
}

View file

@ -34,6 +34,7 @@ class CallGui;
class Thread;
class Notifier;
class QQuickWindow;
class QSystemTrayIcon;
class App : public SingleApplication, public AbstractObject {
Q_OBJECT
@ -106,6 +107,7 @@ public:
void initCppInterfaces();
void restart();
bool autoStartEnabled();
void setSysTrayIcon();
void onLoggerInitialized();
void sendCommand();
@ -120,6 +122,8 @@ public:
QSharedPointer<CallList> getCallList() const;
QSharedPointer<SettingsCore> getSettings() const;
void onExitOnCloseChanged(); // Can be used for UniqueConnection
#ifdef Q_OS_LINUX
Q_INVOKABLE void exportDesktopFile();
@ -145,6 +149,7 @@ private:
QCommandLineParser *mParser = nullptr;
Thread *mLinphoneThread = nullptr;
Notifier *mNotifier = nullptr;
QSystemTrayIcon *mSystemTrayIcon = nullptr;
QQuickWindow *mMainWindow = nullptr;
QQuickWindow *mCallsWindow = nullptr;
QSharedPointer<SettingsCore> mSettings;

View file

@ -42,25 +42,25 @@ public:
Q_INVOKABLE void save();
Q_INVOKABLE bool isValid();
DECLARE_CORE_GETSET(bool, enabled, Enabled)
DECLARE_CORE_GETSET(QString, server, Server)
DECLARE_CORE_GETSET(QString, bindDn, BindDn)
DECLARE_CORE_GETSET(QString, password, Password)
DECLARE_CORE_GETSET(linphone::Ldap::AuthMethod, authMethod, AuthMethod)
DECLARE_CORE_GETSET(bool, tls, Tls)
DECLARE_CORE_GETSET(linphone::Ldap::CertVerificationMode,
serverCertificatesVerificationMode,
ServerCertificatesVerificationMode)
DECLARE_CORE_GETSET(QString, baseObject, BaseObject)
DECLARE_CORE_GETSET(QString, filter, Filter)
DECLARE_CORE_GETSET(int, maxResults, MaxResults)
DECLARE_CORE_GETSET(int, timeout, Timeout)
DECLARE_CORE_GETSET(int, delay, Delay)
DECLARE_CORE_GETSET(int, minChars, MinChars)
DECLARE_CORE_GETSET(QString, nameAttribute, NameAttribute)
DECLARE_CORE_GETSET(QString, sipAttribute, SipAttribute)
DECLARE_CORE_GETSET(QString, sipDomain, SipDomain)
DECLARE_CORE_GETSET(linphone::Ldap::DebugLevel, debugLevel, DebugLevel)
DECLARE_CORE_GETSET_MEMBER(bool, enabled, Enabled)
DECLARE_CORE_GETSET_MEMBER(QString, server, Server)
DECLARE_CORE_GETSET_MEMBER(QString, bindDn, BindDn)
DECLARE_CORE_GETSET_MEMBER(QString, password, Password)
DECLARE_CORE_GETSET_MEMBER(linphone::Ldap::AuthMethod, authMethod, AuthMethod)
DECLARE_CORE_GETSET_MEMBER(bool, tls, Tls)
DECLARE_CORE_GETSET_MEMBER(linphone::Ldap::CertVerificationMode,
serverCertificatesVerificationMode,
ServerCertificatesVerificationMode)
DECLARE_CORE_GETSET_MEMBER(QString, baseObject, BaseObject)
DECLARE_CORE_GETSET_MEMBER(QString, filter, Filter)
DECLARE_CORE_GETSET_MEMBER(int, maxResults, MaxResults)
DECLARE_CORE_GETSET_MEMBER(int, timeout, Timeout)
DECLARE_CORE_GETSET_MEMBER(int, delay, Delay)
DECLARE_CORE_GETSET_MEMBER(int, minChars, MinChars)
DECLARE_CORE_GETSET_MEMBER(QString, nameAttribute, NameAttribute)
DECLARE_CORE_GETSET_MEMBER(QString, sipAttribute, SipAttribute)
DECLARE_CORE_GETSET_MEMBER(QString, sipDomain, SipDomain)
DECLARE_CORE_GETSET_MEMBER(linphone::Ldap::DebugLevel, debugLevel, DebugLevel)
private:
std::shared_ptr<LdapModel> mLdapModel;

View file

@ -92,6 +92,7 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
INIT_CORE_MEMBER(AssistantThirdPartySipAccountDomain, mSettingsModel)
INIT_CORE_MEMBER(AssistantThirdPartySipAccountTransport, mSettingsModel)
INIT_CORE_MEMBER(AutoStart, mSettingsModel)
INIT_CORE_MEMBER(ExitOnClose, mSettingsModel)
INIT_CORE_MEMBER(SyncLdapContacts, mSettingsModel)
}
@ -326,6 +327,8 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, autoStart,
AutoStart)
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, exitOnClose,
ExitOnClose)
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool,
syncLdapContacts, SyncLdapContacts)
@ -486,3 +489,15 @@ QString SettingsCore::getLogsFolder() const {
bool SettingsCore::dndEnabled() const {
return mDndEnabled;
}
bool SettingsCore::getAutoStart() const {
return mAutoStart;
}
bool SettingsCore::getExitOnClose() const {
return mExitOnClose;
}
bool SettingsCore::getSyncLdapContacts() const {
return mSyncLdapContacts;
}

View file

@ -143,31 +143,26 @@ public:
bool dndEnabled() const;
DECLARE_CORE_GETSET(bool, disableChatFeature, DisableChatFeature)
DECLARE_CORE_GETSET(bool, disableMeetingsFeature, DisableMeetingsFeature)
DECLARE_CORE_GETSET(bool, disableBroadcastFeature, DisableBroadcastFeature)
DECLARE_CORE_GETSET(bool, hideSettings, HideSettings)
DECLARE_CORE_GETSET(bool, hideAccountSettings, HideAccountSettings)
DECLARE_CORE_GETSET(bool, disableCallRecordings, DisableCallRecordings)
DECLARE_CORE_GETSET(bool, assistantHideCreateAccount, AssistantHideCreateAccount)
DECLARE_CORE_GETSET(bool, assistantDisableQrCode, AssistantDisableQrCode)
DECLARE_CORE_GETSET(bool, assistantHideThirdPartyAccount, AssistantHideThirdPartyAccount)
DECLARE_CORE_GETSET(bool, onlyDisplaySipUriUsername, OnlyDisplaySipUriUsername)
DECLARE_CORE_GETSET(bool, darkModeAllowed, DarkModeAllowed)
DECLARE_CORE_GETSET(int, maxAccount, MaxAccount)
DECLARE_CORE_GETSET(bool,
assistantGoDirectlyToThirdPartySipAccountLogin,
AssistantGoDirectlyToThirdPartySipAccountLogin)
DECLARE_CORE_GETSET(QString, assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain)
DECLARE_CORE_GETSET(QString, assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
DECLARE_CORE_GETSET_MEMBER(bool, disableChatFeature, DisableChatFeature)
DECLARE_CORE_GETSET_MEMBER(bool, disableMeetingsFeature, DisableMeetingsFeature)
DECLARE_CORE_GETSET_MEMBER(bool, disableBroadcastFeature, DisableBroadcastFeature)
DECLARE_CORE_GETSET_MEMBER(bool, hideSettings, HideSettings)
DECLARE_CORE_GETSET_MEMBER(bool, hideAccountSettings, HideAccountSettings)
DECLARE_CORE_GETSET_MEMBER(bool, disableCallRecordings, DisableCallRecordings)
DECLARE_CORE_GETSET_MEMBER(bool, assistantHideCreateAccount, AssistantHideCreateAccount)
DECLARE_CORE_GETSET_MEMBER(bool, assistantDisableQrCode, AssistantDisableQrCode)
DECLARE_CORE_GETSET_MEMBER(bool, assistantHideThirdPartyAccount, AssistantHideThirdPartyAccount)
DECLARE_CORE_GETSET_MEMBER(bool, onlyDisplaySipUriUsername, OnlyDisplaySipUriUsername)
DECLARE_CORE_GETSET_MEMBER(bool, darkModeAllowed, DarkModeAllowed)
DECLARE_CORE_GETSET_MEMBER(int, maxAccount, MaxAccount)
DECLARE_CORE_GETSET_MEMBER(bool,
assistantGoDirectlyToThirdPartySipAccountLogin,
AssistantGoDirectlyToThirdPartySipAccountLogin)
DECLARE_CORE_GETSET_MEMBER(QString, assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain)
DECLARE_CORE_GETSET_MEMBER(QString, assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
DECLARE_CORE_GETSET(bool, autoStart, AutoStart)
bool getAutoStart() {
return mAutoStart;
};
DECLARE_CORE_GETSET(bool, exitOnClose, ExitOnClose)
DECLARE_CORE_GETSET(bool, syncLdapContacts, SyncLdapContacts)
bool getSyncLdapContacts() {
return mSyncLdapContacts;
};
signals:

View file

@ -527,6 +527,7 @@ void SettingsModel::notifyConfigReady(){
DEFINE_NOTIFY_CONFIG_READY(assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain)
DEFINE_NOTIFY_CONFIG_READY(assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
DEFINE_NOTIFY_CONFIG_READY(autoStart, AutoStart)
DEFINE_NOTIFY_CONFIG_READY(exitOnClose, ExitOnClose)
DEFINE_NOTIFY_CONFIG_READY(syncLdapContacts, SyncLdapContacts)
}
@ -610,6 +611,13 @@ DEFINE_GETSET_CONFIG(SettingsModel,
AutoStart,
"auto_start",
false)
DEFINE_GETSET_CONFIG(SettingsModel,
bool,
Bool,
exitOnClose,
ExitOnClose,
"exit_on_close",
false)
DEFINE_GETSET_CONFIG(SettingsModel,
bool,
Bool,

View file

@ -144,6 +144,7 @@ public:
DECLARE_GETSET(QString, assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain)
DECLARE_GETSET(QString, assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
DECLARE_GETSET(bool, autoStart, AutoStart)
DECLARE_GETSET(bool, exitOnClose, ExitOnClose)
DECLARE_GETSET(bool, syncLdapContacts, SyncLdapContacts)
signals:

View file

@ -61,12 +61,19 @@ public:
} \
}
#define DECLARE_CORE_GETSET(type, x, X) \
#define DECLARE_CORE_GETSET_MEMBER(type, x, X) \
Q_PROPERTY(type x MEMBER m##X WRITE set##X NOTIFY x##Changed) \
Q_SIGNAL void set##X(type data); \
Q_SIGNAL void x##Changed(); \
type m##X;
#define DECLARE_CORE_GETSET(type, x, X) \
Q_PROPERTY(type x READ get##X WRITE set##X NOTIFY x##Changed) \
Q_SIGNAL void set##X(type data); \
type get##X() const; \
Q_SIGNAL void x##Changed(); \
type m##X;
#define DECLARE_CORE_GET(type, x, X) \
Q_PROPERTY(type x MEMBER m##X NOTIFY x##Changed) \
Q_SIGNAL void x##Changed(); \
@ -123,8 +130,7 @@ public:
} \
}
#define DEFINE_NOTIFY_CONFIG_READY(x, X) \
emit x##Changed(get##X());
#define DEFINE_NOTIFY_CONFIG_READY(x, X) emit x##Changed(get##X());
#define DECLARE_GETSET_API(type, x, X) \
type get##X() const; \
@ -145,7 +151,7 @@ public:
}
#define DEFINE_GETSET_MODEL_STRING(Class, x, X, ownerNotNull) \
QString Class::get##X() const { \
QString Class::get##X() const { \
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); \
return Utils::coreStringToAppString(ownerNotNull->get##X()); \
} \
@ -158,7 +164,7 @@ QString Class::get##X() const {
}
#define DEFINE_GETSET_ENABLED(Class, x, X, ownerNotNull) \
bool Class::get##X() const { \
bool Class::get##X() const { \
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); \
return ownerNotNull->x##Enabled(); \
} \

View file

@ -159,7 +159,6 @@ void Utils::closeCallsWindow() {
QQuickWindow *Utils::getMainWindow() {
auto win = App::getInstance()->getMainWindow();
smartShowWindow(win);
return win;
}
@ -1378,4 +1377,4 @@ QString Utils::boldTextPart(const QString &text, const QString &regex) {
}
if (splittedText.size() > 0) result.append(splittedText[splittedText.size() - 1]);
return result;
}
}

View file

@ -10,7 +10,6 @@ import LinphoneAccountsCpp
AbstractWindow {
id: mainWindow
// height: 982 * DefaultStyle.dp
visible: true
title: qsTr("Linphone")
// TODO : handle this bool when security mode is implemented
property bool firstConnection: true