#include <QDesktopWidget> #include <QMenu> #include <QQmlComponent> #include <QQmlContext> #include <QQuickView> #include <QtDebug> #include "../components/contacts/ContactsListProxyModel.hpp" #include "../components/linphone/LinphoneCore.hpp" #include "../components/settings/AccountSettingsModel.hpp" #include "../components/timeline/TimelineModel.hpp" #include "App.hpp" #define LANGUAGES_PATH ":/languages/" #define WINDOW_ICON_PATH ":/assets/images/linphone.png" // =================================================================== App *App::m_instance = nullptr; App::App (int &argc, char **argv) : QApplication(argc, argv) { // Try to use default locale. Otherwise use english. if (m_translator.load(QString(LANGUAGES_PATH) + QLocale::system().name()) || m_translator.load(LANGUAGES_PATH "en")) { installTranslator(&m_translator); } else { qWarning("No translation found."); } setWindowIcon(QIcon(WINDOW_ICON_PATH)); // Provide `+custom` folders for custom components. m_file_selector = new QQmlFileSelector(&m_engine); m_file_selector->setExtraSelectors(QStringList("custom")); // Set modules paths. m_engine.addImportPath(":/ui/modules"); m_engine.addImportPath(":/ui/scripts"); m_engine.addImportPath(":/ui/views"); } // ------------------------------------------------------------------- void App::initContentApp () { // Register types and load context properties. registerTypes(); addContextProperties(); // Load main view. m_engine.load(QUrl("qrc:/ui/views/App/MainWindow/MainWindow.qml")); if (m_engine.rootObjects().isEmpty()) qFatal("Unable to open main window."); // Enable TrayIconSystem. if (!QSystemTrayIcon::isSystemTrayAvailable()) qWarning("System tray not found on this system."); else setTrayIcon(); // Set notification attr. setNotificationAttributes(); } void App::registerTypes () { qmlRegisterUncreatableType<Presence>( "Linphone", 1, 0, "Presence", "Presence is uncreatable" ); ContactsListProxyModel::initContactsListModel(new ContactsListModel()); qmlRegisterType<ContactsListProxyModel>("Linphone", 1, 0, "ContactsListProxyModel"); // Expose the static functions of ContactsListModel. qmlRegisterSingletonType<ContactsListModel>( "Linphone", 1, 0, "ContactsListModel", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject *{ Q_UNUSED(engine); Q_UNUSED(scriptEngine); return ContactsListProxyModel::getContactsListModel(); } ); } void App::addContextProperties () { QQmlContext *context = m_engine.rootContext(); QQmlComponent component(&m_engine, QUrl("qrc:/ui/views/App/Calls/Calls.qml")); // Windows. if (component.isError()) { qWarning() << component.errors(); } else { context->setContextProperty("CallsWindow", component.create()); } // Models. context->setContextProperty("AccountSettingsModel", new AccountSettingsModel()); context->setContextProperty("TimelineModel", new TimelineModel()); // Other. context->setContextProperty("LinphoneCore", LinphoneCore::getInstance()); m_notification = new Notification(); context->setContextProperty("Notification", m_notification); } void App::setTrayIcon () { QQuickWindow *root = qobject_cast<QQuickWindow *>(m_engine.rootObjects().at(0)); QMenu *menu = new QMenu(); m_system_tray_icon = new QSystemTrayIcon(root); // trayIcon: Right click actions. QAction *quit_action = new QAction("Quit", root); root->connect(quit_action, &QAction::triggered, qApp, &QCoreApplication::quit); QAction *restore_action = new QAction("Restore", root); root->connect(restore_action, &QAction::triggered, root, &QQuickWindow::showNormal); // trayIcon: Left click actions. root->connect(m_system_tray_icon, &QSystemTrayIcon::activated, [root](QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::Trigger) { if (root->visibility() == QWindow::Hidden) root->showNormal(); else root->hide(); } }); // Build trayIcon menu. menu->addAction(restore_action); menu->addSeparator(); menu->addAction(quit_action); m_system_tray_icon->setContextMenu(menu); m_system_tray_icon->setIcon(QIcon(WINDOW_ICON_PATH)); m_system_tray_icon->setToolTip("Linphone"); m_system_tray_icon->show(); } void App::setNotificationAttributes () { if (!m_system_tray_icon) { return; } QDesktopWidget *desktop = QApplication::desktop(); QRect icon_rect = m_system_tray_icon->geometry(); QRect screen_rect = desktop->screenGeometry(); int x = icon_rect.x() + icon_rect.width() / 2; int y = icon_rect.y() + icon_rect.height() / 2; Qt::Edges edge = (x < screen_rect.width() / 2) ? Qt::LeftEdge : Qt::RightEdge; edge |= (y < screen_rect.height() / 2) ? Qt::TopEdge : Qt::BottomEdge; m_notification->setEdge(edge); }