diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e89a23b9..6257c7e3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,333 +1,337 @@ IF(POLICY CMP0017) CMAKE_POLICY(SET CMP0017 NEW) ENDIF(POLICY CMP0017) IF(POLICY CMP0022) CMAKE_POLICY(SET CMP0022 NEW) ENDIF(POLICY CMP0022) IF(POLICY CMP0063) CMAKE_POLICY(SET CMP0063 NEW) ENDIF(POLICY CMP0063) SET(QT_MIN_VERSION "5.2.0") ADD_DEFINITIONS( ${KF5_DEFINITIONS} ${QT_DEFINITIONS} -fexceptions -Wno-error -Wno-reorder -Wno-error=deprecated-declarations ) # It doesn't work in sandboxes IF (NOT ENABLE_SINGLE_INSTANCE) ADD_DEFINITIONS(-DDISABLE_KDBUS_SERVICE=1) ENDIF() # Enable some useful warnings ADD_DEFINITIONS( -Wall -Wextra -Wmissing-declarations -Wmissing-noreturn -Wpointer-arith -Wcast-align -Wwrite-strings -Wformat-nonliteral -Wformat-security -Wswitch-enum -Winit-self -Wmissing-include-dirs -Wundef -Wmissing-format-attribute -Wno-reorder -Wunused -Wuninitialized -Woverloaded-virtual -Wunused-value -pedantic -Wnonnull -Wsequence-point #-Wsystem-headers -Wsizeof-pointer-memaccess #-Wuseless-cast -Wvarargs ) #Add more warnings for compilers that support it. I used this command: #curl https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Warning-Options.html | \ #grep -E "^[\t ]+
-W[a-zA-Z=-]*" -o | grep -E "\-W[a-zA-Z=-]*" -o > #cat /tmp/48 /tmp/49 | sort | uniq -u # IF (CMAKE_COMPILER_IS_GNUCC) IF (CMAKE_COMPILER_IS_GNUCC) IF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.9) ADD_DEFINITIONS( -Wunused-but-set-parameter -Wconditionally-supported -Wno-cpp # -Wdouble-promotion -Wdate-time -Wdelete-incomplete # -Wfloat-conversion ) ENDIF() IF (CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.9) ADD_DEFINITIONS( -Wno-pragmas ) ENDIF() IF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 5.0) ADD_DEFINITIONS( -Wsuggest-override -Wsuggest-final-types -Wsuggest-final-methods -Wbool-compare -Wformat-signedness -Wlogical-not-parentheses -Wnormalized -Wshift-count-negative -Wshift-count-overflow -Wsized-deallocation -Wsizeof-array-argument ) ENDIF() IF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 6.0) ADD_DEFINITIONS( -Wnull-dereference -Wtautological-compare -Wduplicated-cond -Wmisleading-indentation ) ENDIF() IF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 7.0) ADD_DEFINITIONS( -Wimplicit-fallthrough -Wduplicated-branches -Wswitch-unreachable -Wformat-overflow -Wformat-truncation -Wnonnull ) ENDIF() IF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 8.0) ADD_DEFINITIONS( -Wmultistatement-macros -Wstringop-truncation -Wif-not-aligned -Wmissing-attributes ) ENDIF() ENDIF() IF (CMAKE_COMPILER_IS_GNUCC) EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE CMAKE_CXX_COMPILER_VERSION) IF (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6.9 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.6) #GCC 4.6 version of those warnings does detect valid C++0x/C++11 as invalid. ADD_DEFINITIONS( -Wno-error=pragmas -Wno-pragmas -Wno-error ) ENDIF() IF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.7 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.7) ADD_DEFINITIONS( -Wmaybe-uninitialized -Wunused-local-typedefs -pedantic ) ENDIF() IF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.8 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.8) # ADD_DEFINITIONS("-Wzero-as-null-pointer-constant") # ADD_DEFINITIONS( -DENABLE_IGNORE_NULL=true ) ENDIF() ELSE() ADD_DEFINITIONS(-Wno-unknown-pragmas -Wno-unknown-warning-option) ENDIF() ADD_DEFINITIONS("-std=c++0x") #Make sure it can access DBUS autogenerated files INCLUDE_DIRECTORIES(SYSTEM ${KF5_INCLUDES} ${Qt5Widgets_INCLUDES} ${Qt5PrintSupport_INCLUDES} ${Qt5Core_INCLUDES} ${CMAKE_BINARY_DIR} ${ringqt_INCLUDE_DIR} ${LIB_TIP_INCLUDE} ${LIB_CONFIG_INCLUDE} ${LIB_CONFIG_WIDGETS} ) # Shared C++ QML components ADD_SUBDIRECTORY( qmlwidgets ) #Build KDE specific files ADD_SUBDIRECTORY( jamikdeintegration ) # Build the QML based first run Wizard ADD_SUBDIRECTORY( wizard ) # Build the QML based interactive video canvas ADD_SUBDIRECTORY( callview ) # Build the advanced phone dialer ADD_SUBDIRECTORY( dialview ) # Build the views and widgets related to the social timeline feature ADD_SUBDIRECTORY( timeline ) # Build the contact and profile photo editor dialog ADD_SUBDIRECTORY( photoselector ) # Build the elements used to notify the users of events ADD_SUBDIRECTORY( canvasindicators ) # Build the contact manager subsystem ADD_SUBDIRECTORY( contactview ) # Build the account manager subsystem ADD_SUBDIRECTORY( accountview ) +# Build the account manager subsystem +ADD_SUBDIRECTORY( jaminotification ) + # Build the main desktop component ADD_SUBDIRECTORY( desktopview ) # ADD_DEPENDENCIES(desktopview DEPENDS jamikdeintegration) IF(${CMAKE_BUILD_TYPE} MATCHES Release) MESSAGE("NO DEBUG OUTPUT") ADD_DEFINITIONS( -DQT_NO_DEBUG_OUTPUT) ELSE() ENDIF(${CMAKE_BUILD_TYPE} MATCHES Release) SET( ring_kde_SRCS main.cpp cmd.cpp ringapplication.cpp ) # generate rules for building source files from the resources SET(QtApp_RCCS qrc/resources.qrc # conf/confresources.qrc ../data/appicon.qrc ) QT5_ADD_RESOURCES(QtApp_RCC_SRCS ${QtApp_RCCS}) # add_subdirectory( test ) #Enable again some day, it cause compile problems for some users IF(NOT (${ENABLE_VIDEO} MATCHES false)) SET(ENABLE_VIDEO 1 CACHE BOOLEAN "Enable video") ADD_DEFINITIONS( -DENABLE_VIDEO=true ) SET ( config_ui_files ${config_ui_files} conf/dlgvideobase.ui ) ENDIF(NOT (${ENABLE_VIDEO} MATCHES false)) IF(${DISABLE_UNIQUE_APPLICATION} MATCHES true) MESSAGE("KUniqueApplication disabled") SET(DISABLE_UNIQUE_APPLICATION 1 CACHE BOOLEAN "Disable KUniqueApplication") ADD_DEFINITIONS( -DDISABLE_UNIQUE_APPLICATION=true ) ENDIF(${DISABLE_UNIQUE_APPLICATION} MATCHES true) ki18n_wrap_ui(ring_kde_SRCS ${config_ui_files} ) IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") ADD_EXECUTABLE(ring-kde MACOSX_BUNDLE ${ring_kde_SRCS} ${QtApp_RCC_SRCS}) set_source_files_properties( ../data/ring-kdeui.rc PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) file( COPY ../data/ring-kdeui.rc DESTINATION "ring-kde.app/Contents/Resources/" ) ELSE() ADD_EXECUTABLE(ring-kde ${ring_kde_SRCS} ${QtApp_RCC_SRCS}) ENDIF() IF(NOT ${ENABLE_STATIC} MATCHES false) FIND_PACKAGE(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED DBus) INCLUDE_DIRECTORIES(SYSTEM ${Qt5DBus_INCLUDE_DIRS} ) LINK_DIRECTORIES(${Qt5DBus_LIBRARY_DIRS} ) ADD_DEFINITIONS(${Qt5DBus_CFLAGS}) IF(NOT DEFINED OS_ANDROID) TARGET_LINK_LIBRARIES(ring-kde -lpthread ) ENDIF() TARGET_LINK_LIBRARIES(ring-kde ${ringqt_LIBRARY_STATIC} ) IF(NOT ${ENABLE_LIBWRAP}) TARGET_LINK_LIBRARIES(ring-kde ${Qt5DBus_LIBRARIES} ) ENDIF() ELSE() TARGET_LINK_LIBRARIES(ring-kde ${ringqt_LIBRARY_DYNAMIC}) ENDIF() QT5_ADD_DBUS_ADAPTOR(ring_kde_SRCS ../data/org.kde.kuiserver.xml cmd.h Cmd ) TARGET_LINK_LIBRARIES(ring-kde jamiwizard jamicallview jamidialview jamitimelineview jamiphotoselector jamicanvasindicator desktopview jamicontactview jamiaccountview + jaminotification libqmlwidgets kquickitemviews jamikdeintegration # RingQt ringqtquick # Qt5 Qt5::Widgets Qt5::Core Qt5::Gui Qt5::Svg Qt5::PrintSupport # KF5 KF5::I18n KF5::WidgetsAddons KF5::ConfigCore KF5::ConfigGui KF5::DBusAddons KF5::XmlGui KF5::Notifications KF5::IconThemes KF5::Crash KF5::NotifyConfig KF5::GlobalAccel KF5::Declarative KF5::Kirigami2 ) IF (Qt5TextToSpeech_FOUND) TARGET_LINK_LIBRARIES(ring-kde Qt5::TextToSpeech ) ENDIF() ########### install files ############### INSTALL( TARGETS ring-kde DESTINATION ${BIN_INSTALL_DIR} ) INSTALL( FILES wizard/assets/beta_logo.svg DESTINATION ${DATA_INSTALL_DIR}/ring-kde ) diff --git a/src/jamikdeintegration/CMakeLists.txt b/src/jamikdeintegration/CMakeLists.txt index 72150141..753dd44a 100644 --- a/src/jamikdeintegration/CMakeLists.txt +++ b/src/jamikdeintegration/CMakeLists.txt @@ -1,189 +1,188 @@ cmake_minimum_required(VERSION 3.0) project(jamikdeintegration) if(POLICY CMP0063) CMAKE_POLICY(SET CMP0063 NEW) endif(POLICY CMP0063) find_package(ECM 1.1.0 REQUIRED NO_MODULE) list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}") find_package(KF5 QUIET COMPONENTS Akonadi AkonadiContact Contacts ) include(ECMInstallIcons) include(ECMOptionalAddSubdirectory) include(CMakePackageConfigHelpers) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings) SET(CMAKE_C_VISIBILITY_PRESET hidden) SET(CMAKE_CXX_VISIBILITY_PRESET hidden) SET(CMAKE_VISIBILITY_INLINES_HIDDEN 1) # When used with `add_subdirectory`, assume it is a static Qt plugin get_directory_property(USES_ADD_SUBDIRECTORY PARENT_DIRECTORY) if(USES_ADD_SUBDIRECTORY) set(BUILD_SHARED_LIBS OFF) endif() if(NOT BUILD_SHARED_LIBS) set(ENABLE__STATIC_PLUGIN 1) else() set(ENABLE__STATIC_PLUGIN 0) endif() set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 14) if(ENABLE__STATIC_PLUGIN) add_definitions(-DQT_PLUGIN) add_definitions(-DQT_STATICPLUGIN=1) add_definitions(-DJAMIKDEINTEGRATION_USE_STATIC_PLUGIN=1) endif(ENABLE__STATIC_PLUGIN) find_package(Qt5 CONFIG REQUIRED Core Gui Quick Widgets QuickControls2 ) set(GENERIC_LIB_VERSION "1.0.0") # Pack the icons shared by various components ADD_SUBDIRECTORY( sharedassets ) #File to compile set( jamikdeintegration_LIB_SRCS src/colorinterface.cpp src/shortcutinterface.cpp src/actioninterface.cpp src/fileproverderinterface.cpp src/pixmapinterface.cpp src/serializationinterface.cpp src/actioncollection.cpp - src/notification.cpp src/systray.cpp src/windowevent.cpp src/cmiconengine.cpp src/personiconengine.cpp src/plugin.cpp ) if(Qt5TextToSpeech_FOUND) set( jamikdeintegration_LIB_SRCS ${jamikdeintegration_LIB_SRCS} accessibility.cpp ) endif() if(KF5_AKONADI_FOUND AND KF5_AKONADICONTACT_FOUND AND KF5_CONTACTS_FOUND) set(AKONADI_FOUND 1) endif() if( ${AKONADI_FOUND} ) set(jamikdeintegration_LIB_SRCS ${jamikdeintegration_LIB_SRCS} akonadibackend.cpp ) endif() kconfig_add_kcfg_files (jamikdeintegration_LIB_SRCS kcfg_settings.kcfgc) set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.ringkde.jamikdeintegration) add_library(jamikdeintegration ${jamikdeintegration_LIB_SRCS} ) target_link_libraries( jamikdeintegration # Project ringqt ringqtquick # Qt Qt5::Core Qt5::Gui Qt5::Quick Qt5::Widgets Qt5::QuickControls2 # KF5 - KF5::Notifications + KF5::Notifications # the Systray KF5::I18n KF5::ConfigCore KF5::ConfigGui KF5::ConfigWidgets # KColorScheme KF5::XmlGui # KSortcutdialog # (DESKTOP) KF5::NotifyConfig # the notification dialog # (DESKTOP) KF5::GlobalAccel # (DESKTOP) ) if ( ${AKONADI_FOUND} ) target_link_libraries( jamikdeintegration KF5::AkonadiCore KF5::AkonadiContact KF5::Contacts ) endif() set(jamikdeintegration_EXPORT_HDRS src/actioncollection.h src/windowevent.h ) # Configure the target config set(jamikdeintegration_CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/JamiKDEIntegrationConfig.cmake") if(USES_ADD_SUBDIRECTORY) set(JamiKDEIntegration_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) endif() configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/JamiKDEIntegrationConfig.cmake.in" ${jamikdeintegration_CONFIG_PATH} INSTALL_DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiKDEIntegration/ PATH_VARS INCLUDE_INSTALL_DIR ) install( FILES ${jamikdeintegration_CONFIG_PATH} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiKDEIntegration/ COMPONENT Devel ) # Create the target target_include_directories(jamikdeintegration PUBLIC # $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ ) set_target_properties(jamikdeintegration PROPERTIES PUBLIC_HEADER "${jamikdeintegration_EXPORT_HDRS}" ) export(TARGETS jamikdeintegration FILE "${PROJECT_BINARY_DIR}/cmake/JamiKDEIntegrationTargets.cmake" ) install(TARGETS jamikdeintegration EXPORT JamiKDEIntegrationTargets LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" COMPONENT jamikdeintegration ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin COMPONENT Devel ) install(EXPORT JamiKDEIntegrationTargets DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiKDEIntegration COMPONENT Devel ) install(FILES ring-kde.kcfg DESTINATION ${KCFG_INSTALL_DIR}) diff --git a/src/jamikdeintegration/src/plugin.cpp b/src/jamikdeintegration/src/plugin.cpp index 6359d0c3..8d4a7a09 100644 --- a/src/jamikdeintegration/src/plugin.cpp +++ b/src/jamikdeintegration/src/plugin.cpp @@ -1,177 +1,175 @@ /************************************************************************************ * Copyright (C) 2018 by BlueSystems GmbH * * Author : Emmanuel Lepage Vallee * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***********************************************************************************/ #include "plugin.h" // Qt #include #include #include #include #include // KDE #include // LinRingQt #include #include #include #include #include #include #include #include #include #include #include // Collections #include #include #include #include #include #include #include #include // Ring-KDE -#include "notification.h" #include "actioncollection.h" #include "actioninterface.h" #include "colorinterface.h" #include "pixmapinterface.h" #include "serializationinterface.h" #include "windowevent.h" #include "systray.h" #include "kcfg_settings.h" #include "sharedassets/qrc_assets.cpp" static QQmlEngine* e = nullptr; static void loadNumberCategories() { auto model = Session::instance()->numberCategoryModel(); static const QString pathTemplate = QStringLiteral(":/mini/icons/miniicons/%1.png"); #define ICN(name) QPixmap(QString(pathTemplate).arg(QStringLiteral(name))) model->addCategory(i18n("Home") ,ICN("home") , 1 /*KABC::PhoneNumber::Home */); model->addCategory(i18n("Work") ,ICN("work") , 2 /*KABC::PhoneNumber::Work */); model->addCategory(i18n("Msg") ,ICN("mail") , 3 /*KABC::PhoneNumber::Msg */); model->addCategory(i18n("Pref") ,ICN("call") , 4 /*KABC::PhoneNumber::Pref */); model->addCategory(i18n("Voice") ,ICN("video") , 5 /*KABC::PhoneNumber::Voice*/); model->addCategory(i18n("Fax") ,ICN("call") , 6 /*KABC::PhoneNumber::Fax */); model->addCategory(i18n("Cell") ,ICN("mobile") , 7 /*KABC::PhoneNumber::Cell */); model->addCategory(i18n("Video") ,ICN("call") , 8 /*KABC::PhoneNumber::Video*/); model->addCategory(i18n("Bbs") ,ICN("call") , 9 /*KABC::PhoneNumber::Bbs */); model->addCategory(i18n("Modem") ,ICN("call") , 10/*KABC::PhoneNumber::Modem*/); model->addCategory(i18n("Car") ,ICN("car") , 11/*KABC::PhoneNumber::Car */); model->addCategory(i18n("Isdn") ,ICN("call") , 12/*KABC::PhoneNumber::Isdn */); model->addCategory(i18n("Pcs") ,ICN("call") , 13/*KABC::PhoneNumber::Pcs */); model->addCategory(i18n("Pager") ,ICN("pager") , 14/*KABC::PhoneNumber::Pager*/); model->addCategory(i18n("Preferred"),ICN("preferred"), 10000 ); #undef ICN #undef IS_ENABLED } static void initCollections() { loadNumberCategories(); Session::instance()->callModel()->setAudoCleanDelay(5000); // Load the old phone call history and port it to the newer calendar events format. if (QFile::exists(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1Char('/') +"history.ini")) { auto histo = Session::instance()->historyModel()->addCollection(LoadOptions::FORCE_ENABLED); HistoryImporter::importHistory(histo); histo->clear(); } //HACK load the Calendar now to speedup everything else const int accountCount = Session::instance()->accountModel()->size(); for (int i=0; i < accountCount; i++) (*Session::instance()->accountModel())[i]->calendar(); Session::instance()->profileModel()->addCollection(LoadOptions::FORCE_ENABLED); #ifdef Q_OS_LINUX CertificateModel::instance().addCollection,QString>( QStringLiteral("/usr/share/ca-certificates/"), FolderCertificateCollection::Options::ROOT | FolderCertificateCollection::Options::RECURSIVE | FolderCertificateCollection::Options::READ_ONLY, i18n("System root certificates"), LoadOptions::FORCE_ENABLED ); #endif Session::instance()->bookmarkModel()->addCollection(); Session::instance()->bookmarkModel()->setDisplayPopular( ConfigurationSkeleton::displayPopularAsBookmark() ); Session::instance()->personDirectory()->addCollection(LoadOptions::FORCE_ENABLED); auto ppc = Session::instance()->personDirectory()->addCollection(LoadOptions::FORCE_ENABLED); const auto m = static_cast(ConfigurationSkeleton::defaultPeerProfileMode()); ppc->setDefaultMode(m); #ifdef ENABLE_AKONADI AkonadiBackend::initCollections(); #endif Session::instance()->profileModel(); } void JamiKDEIntegration::registerTypes(const char *uri) { Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamikdeintegration")); GlobalInstances::setInterface(); GlobalInstances::setInterface(); GlobalInstances::setInterface(); GlobalInstances::setInterface(); GlobalInstances::itemModelStateSerializer().load(); qmlRegisterType(uri, 1, 0, "WindowEvent"); } void JamiKDEIntegration::initializeEngine(QQmlEngine *engine, const char *uri) { e = engine; - Notification::instance(); ActionCollection::instance()->setupAction(); initCollections(); engine->rootContext()->setContextProperty( QStringLiteral("ActionCollection"), ActionCollection::instance() ); new SysTray(QIcon(QStringLiteral(":appicon/icons/64-apps-ring-kde.png"))); } QQmlEngine* JamiKDEIntegration::engine() { return e; } diff --git a/src/jaminotification/CMakeLists.txt b/src/jaminotification/CMakeLists.txt new file mode 100644 index 00000000..481fcebb --- /dev/null +++ b/src/jaminotification/CMakeLists.txt @@ -0,0 +1,121 @@ +cmake_minimum_required(VERSION 3.0) + +project(jaminotification) + +if(POLICY CMP0063) + CMAKE_POLICY(SET CMP0063 NEW) +endif(POLICY CMP0063) + +find_package(ECM 1.1.0 REQUIRED NO_MODULE) +list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}") + +include(ECMInstallIcons) +include(ECMOptionalAddSubdirectory) +include(CMakePackageConfigHelpers) + +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDECompilerSettings) + +SET(CMAKE_C_VISIBILITY_PRESET hidden) +SET(CMAKE_CXX_VISIBILITY_PRESET hidden) +SET(CMAKE_VISIBILITY_INLINES_HIDDEN 1) + +# When used with `add_subdirectory`, assume it is a static Qt plugin +get_directory_property(USES_ADD_SUBDIRECTORY PARENT_DIRECTORY) +if(USES_ADD_SUBDIRECTORY) + set(BUILD_SHARED_LIBS OFF) +endif() + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_CXX_STANDARD 14) + +if(NOT BUILD_SHARED_LIBS) + set(ENABLE_STATIC_PLUGIN 1) # Used in Config.cmake.in + add_definitions(-DQT_PLUGIN) + add_definitions(-DQT_STATICPLUGIN=1) + add_definitions(-DJAMINOTIFICATION_USE_STATIC_PLUGIN=1) +endif() + +find_package(Qt5 CONFIG REQUIRED + Core Gui Quick QuickControls2 +) + +set(GENERIC_LIB_VERSION "1.0.0") + +#File to compile +set( jaminotification_LIB_SRCS + plugin.cpp + notification.cpp + focuslistener.cpp +) + +set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.ringkde.jaminotification) + +add_library(jaminotification ${jaminotification_LIB_SRCS} ) + +target_link_libraries( jaminotification + # Project + ringqt + ringqtquick + + # Qt + Qt5::Core + Qt5::Gui + Qt5::Quick + Qt5::QuickControls2 + + # KF5 + KF5::Notifications + KF5::I18n +) + +# Configure the target config +set(jaminotification_CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/JamiNotificationConfig.cmake") + +if(USES_ADD_SUBDIRECTORY) + set(JamiNotification_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) +endif() + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/JamiNotificationConfig.cmake.in" ${jaminotification_CONFIG_PATH} + INSTALL_DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiNotification/ + PATH_VARS INCLUDE_INSTALL_DIR +) + +install( FILES ${jaminotification_CONFIG_PATH} + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiNotification/ + COMPONENT Devel +) + +# Create the target +target_include_directories(jaminotification + PUBLIC + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/ +) + +set_target_properties(jaminotification PROPERTIES + PUBLIC_HEADER + "${jaminotification_EXPORT_HDRS}" +) + +export(TARGETS jaminotification + FILE "${PROJECT_BINARY_DIR}/cmake/JamiNotificationTargets.cmake" +) + +install(TARGETS jaminotification + EXPORT JamiNotificationTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" COMPONENT jaminotification + ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + COMPONENT Devel +) + +install(EXPORT JamiNotificationTargets + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiNotification + COMPONENT Devel +) diff --git a/src/jaminotification/cmake/JamiNotificationConfig.cmake.in b/src/jaminotification/cmake/JamiNotificationConfig.cmake.in new file mode 100644 index 00000000..760ca873 --- /dev/null +++ b/src/jaminotification/cmake/JamiNotificationConfig.cmake.in @@ -0,0 +1,8 @@ +@PACKAGE_INIT@ + +#Allow users to when to use Q_IMPORT_PLUGIN in main.cpp +if(@ENABLE_STATIC_PLUGIN@ MATCHES 1) + add_definitions(-DJAMINOTIFICATION_USE_STATIC_PLUGIN=1) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/JamiNotificationTargets.cmake") diff --git a/src/jaminotification/focuslistener.cpp b/src/jaminotification/focuslistener.cpp new file mode 100644 index 00000000..89afaf9e --- /dev/null +++ b/src/jaminotification/focuslistener.cpp @@ -0,0 +1,89 @@ +/************************************************************************************ + * Copyright (C) 2019 by BlueSystems GmbH * + * Author : Emmanuel Lepage Vallee * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***********************************************************************************/ +#include "focuslistener.h" + +// Qt +#include +#include + +//This code detect if the window is active, innactive or minimzed +class FocusListenerPrivate final : public QObject +{ + Q_OBJECT +public: + explicit FocusListenerPrivate(QObject* ev) : QObject(ev) {} + + bool m_MayHaveFocus {false}; + QObject* m_pWindow {nullptr}; + static QList m_slInstances; + +protected: + virtual bool eventFilter(QObject *, QEvent *event) override { + if (event->type() != QEvent::WindowActivate && event->type() != QEvent::WindowDeactivate) + return false; + + m_MayHaveFocus = event->type() == QEvent::WindowActivate; + + for (auto o : qAsConst(m_slInstances)) + emit o->changed(); + + return false; + } +}; + +QList FocusListenerPrivate::m_slInstances; + +FocusListener::FocusListener(QObject* parent) : QObject(parent), + d_ptr(new FocusListenerPrivate(this)) +{ + FocusListenerPrivate::m_slInstances << this; +} + +FocusListener::~FocusListener() +{ + FocusListenerPrivate::m_slInstances.removeAll(this); +} + +QObject* FocusListener::window() const +{ + return d_ptr->m_pWindow; +} + +void FocusListener::setWindow(QObject* w) +{ + if (w && w->metaObject()->inherits(&QWindow::staticMetaObject)) + w->installEventFilter(d_ptr); + + d_ptr->m_pWindow = w; + + for (auto o : qAsConst(FocusListenerPrivate::m_slInstances)) + emit o->changed(); +} + +bool FocusListener::mayHaveFocus() const +{ + bool ret = false; + + for (auto o : qAsConst(FocusListenerPrivate::m_slInstances)) + ret |= o->d_ptr->m_MayHaveFocus; + + return ret; +} + +#include diff --git a/src/jaminotification/focuslistener.h b/src/jaminotification/focuslistener.h new file mode 100644 index 00000000..4aa9a7f9 --- /dev/null +++ b/src/jaminotification/focuslistener.h @@ -0,0 +1,60 @@ +/************************************************************************************ + * Copyright (C) 2019 by BlueSystems GmbH * + * Author : Emmanuel Lepage Vallee * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***********************************************************************************/ +#pragma once + +#include + +class FocusListenerPrivate; + +/** + * Get the focus information anywhere in the code without pulling dependencies + * on the window system. + * + * This solution is superior to lets say, KF5::KWindowSystem because it doesn't + * have platform specific code. + */ +class Q_DECL_EXPORT FocusListener : public QObject +{ + Q_OBJECT +public: + /** + * An optional QWindow derived objects. + * + * As long as *one* of the FocusListener instance has a valid window it + * will still work. + */ + Q_PROPERTY(QObject* window READ window WRITE setWindow NOTIFY changed) + + Q_PROPERTY(bool mayHaveFocus READ mayHaveFocus NOTIFY changed) + + Q_INVOKABLE explicit FocusListener(QObject* parent = nullptr); + virtual ~FocusListener(); + + QObject* window() const; + void setWindow(QObject* w); + + bool mayHaveFocus() const; + +Q_SIGNALS: + void changed(); + +private: + FocusListenerPrivate* d_ptr; + Q_DECLARE_PRIVATE(FocusListener) +}; diff --git a/src/jamikdeintegration/src/notification.cpp b/src/jaminotification/notification.cpp similarity index 100% rename from src/jamikdeintegration/src/notification.cpp rename to src/jaminotification/notification.cpp diff --git a/src/jamikdeintegration/src/notification.h b/src/jaminotification/notification.h similarity index 100% rename from src/jamikdeintegration/src/notification.h rename to src/jaminotification/notification.h diff --git a/src/jaminotification/notification.json b/src/jaminotification/notification.json new file mode 100644 index 00000000..b352f7a2 --- /dev/null +++ b/src/jaminotification/notification.json @@ -0,0 +1,4 @@ +{ + "Keys": [ "org.kde.ringkde.jaminotification" ], + "uri": ["org.kde.ringkde.jaminotification"] +} diff --git a/src/jaminotification/plugin.cpp b/src/jaminotification/plugin.cpp new file mode 100644 index 00000000..886508c9 --- /dev/null +++ b/src/jaminotification/plugin.cpp @@ -0,0 +1,43 @@ +/************************************************************************************ + * Copyright (C) 2018 by BlueSystems GmbH * + * Author : Emmanuel Lepage Vallee * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***********************************************************************************/ +#include "plugin.h" + +// Qt +#include +#include +#include + +// Ring-KDE +#include "focuslistener.h" +#include "notification.h" + +void JamiNotification::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QByteArray("org.kde.ringkde.jaminotification")); + + qmlRegisterType(uri, 1, 0, "FocusListener"); +} + +void JamiNotification::initializeEngine(QQmlEngine *engine, const char *uri) +{ + Q_ASSERT(uri == QByteArray("org.kde.ringkde.jaminotification")); + Q_UNUSED(engine) + + Notification::instance(); +} diff --git a/src/jaminotification/plugin.h b/src/jaminotification/plugin.h new file mode 100644 index 00000000..3e74cf52 --- /dev/null +++ b/src/jaminotification/plugin.h @@ -0,0 +1,31 @@ +/************************************************************************************ + * Copyright (C) 2019 by BlueSystems GmbH * + * Author : Emmanuel Lepage Vallee * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***********************************************************************************/ +#pragma once + +#include + +class Q_DECL_EXPORT JamiNotification final : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kde.ringkde.jaminotification" FILE "notification.json") + +public: + void registerTypes(const char* uri) override; + virtual void initializeEngine(QQmlEngine* engine, const char* uri) override; +}; diff --git a/src/main.cpp b/src/main.cpp index 942f3781..92975d23 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,261 +1,276 @@ /*************************************************************************** * Copyright (C) 2009-2015 by Savoir-Faire Linux * * Author : Jérémy Quentin * * Emmanuel Lepage Vallee * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * **************************************************************************/ //Qt #include #include #include #include //KDE #include #include #include //Ring #include "ringapplication.h" #include "kcfg_settings.h" #include "cmd.h" #include #include #ifdef KQUICKITEMVIEWS_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(KQuickItemViews) #else #include #endif #ifdef JAMIKDEINTEGRATION_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiKDEIntegration) #else #include #endif #ifdef JAMIWIZARD_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiWizard) #else #include #endif #ifdef JAMIACCOUNTVIEW_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiAccountView) #else #include #endif #ifdef JAMIACCOUNTVIEW_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiCallView) #else #include #endif #ifdef JAMIACCOUNTVIEW_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiContactView) #else #include #endif #ifdef JAMIACCOUNTVIEW_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiDialView) #else #include #endif #ifdef JAMIACCOUNTVIEW_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiTimelineView) #else #include #endif #ifdef JAMICANVASINDICATOR_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiCanvasIndicator) #else #include #endif #ifdef JAMIPHOTOSELECTOR_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiPhotoSelector) #else #include #endif +#ifdef JAMINOTIFICATION_USE_STATIC_PLUGIN +Q_IMPORT_PLUGIN(JamiNotification) +#else +#include +#endif + Q_IMPORT_PLUGIN(RingQtQuick) constexpr static const char version[] = "3.1.0"; int main(int argc, char **argv) { try { //QQmlDebuggingEnabler enabler; QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); RingApplication app( argc, argv ); KLocalizedString::setApplicationDomain("ring-kde"); //FIXME remove #ifdef KQUICKITEMVIEWS_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_KQuickItemViews().instance())->registerTypes("org.kde.playground.kquickitemviews"); #else KQuickItemViews v; v.registerTypes("org.kde.playground.kquickitemviews"); #endif qobject_cast(qt_static_plugin_RingQtQuick().instance())->registerTypes("net.lvindustries.ringqtquick"); qobject_cast(qt_static_plugin_RingQtQuick().instance())->initializeEngine(app.engine(), "net.lvindustries.ringqtquick"); #ifdef JAMIKDEINTEGRATION_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiKDEIntegration().instance())->registerTypes("org.kde.ringkde.jamikdeintegration"); qobject_cast(qt_static_plugin_JamiKDEIntegration().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamikdeintegration"); #else JamiKDEIntegration v2; v2.registerTypes("org.kde.ringkde.jamikdeintegration"); v2.initializeEngine(app.engine(), "org.kde.ringkde.jamikdeintegration"); #endif #ifdef JAMIWIZARD_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiWizard().instance())->registerTypes("org.kde.ringkde.jamiwizard"); qobject_cast(qt_static_plugin_JamiWizard().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamiwizard"); #else JamiWizard v3; v3.registerTypes("org.kde.ringkde.jamiwizard"); v3.initializeEngine(app.engine(), "org.kde.ringkde.jamiwizard"); #endif #ifdef JAMIACCOUNTVIEW_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiAccountView().instance())->registerTypes("org.kde.ringkde.jamiaccountview"); qobject_cast(qt_static_plugin_JamiAccountView().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamiaccountview"); #else JamiAccountView v4; v4.registerTypes("org.kde.ringkde.jamiaccountview"); v4.initializeEngine(app.engine(), "org.kde.ringkde.jamiaccountview"); #endif #ifdef JAMIACCOUNTVIEW_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiCallView().instance())->registerTypes("org.kde.ringkde.jamicallview"); qobject_cast(qt_static_plugin_JamiCallView().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamicallview"); #else JamiCallViewPlugin v5; v5.registerTypes("org.kde.ringkde.jamicallview"); v5.initializeEngine(app.engine(), "org.kde.ringkde.jamicallview"); #endif #ifdef JAMICONTACTVIEW_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiContactView().instance())->registerTypes("org.kde.ringkde.jamicontactview"); qobject_cast(qt_static_plugin_JamiContactView().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamicontactview"); #else JamiContactViewPlugin v6; v6.registerTypes("org.kde.ringkde.jamicontactview"); v6.initializeEngine(app.engine(), "org.kde.ringkde.jamicontactview"); #endif #ifdef JAMIDIALVIEW_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiDialView().instance())->registerTypes("org.kde.ringkde.jamidialview"); qobject_cast(qt_static_plugin_JamiDialView().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamidialview"); #else JamiDialView v7; v7.registerTypes("org.kde.ringkde.jamidialview"); v7.initializeEngine(app.engine(), "org.kde.ringkde.jamidialview"); #endif #ifdef JAMITIMELINEVIEW_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiTimelineView().instance())->registerTypes("org.kde.ringkde.jamitimelineview"); qobject_cast(qt_static_plugin_JamiTimelineView().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamitimelineview"); #else JamiTimelineView v8; v8.registerTypes("org.kde.ringkde.jamitimelineview"); v8.initializeEngine(app.engine(), "org.kde.ringkde.jamitimelineview"); #endif #ifdef JAMICANVASINDICATOR_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiCanvasIndicator().instance())->registerTypes("org.kde.ringkde.jamicanvasindicator"); qobject_cast(qt_static_plugin_JamiCanvasIndicator().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamicanvasindicator"); #else JamiCanvasIndicator v9; v9.registerTypes("org.kde.ringkde.jamicanvasindicator"); v9.initializeEngine(app.engine(), "org.kde.ringkde.jamicanvasindicator"); #endif #ifdef JAMIPHOTOSELECTOR_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiPhotoSelector().instance())->registerTypes("org.kde.ringkde.jamiphotoselector"); qobject_cast(qt_static_plugin_JamiPhotoSelector().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamiphotoselector"); #else JamiPhotoSelector v10; v10.registerTypes("org.kde.ringkde.jamiphotoselector"); v10.initializeEngine(app.engine(), "org.kde.ringkde.jamiphotoselector"); #endif +#ifdef JAMINOTIFICATION_USE_STATIC_PLUGIN + qobject_cast(qt_static_plugin_JamiNotification().instance())->registerTypes("org.kde.ringkde.jaminotification"); + qobject_cast(qt_static_plugin_JamiNotification().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jaminotification"); +#else + JamiNotification v11; + v11.registerTypes("org.kde.ringkde.jaminotification"); + v11.initializeEngine(app.engine(), "org.kde.ringkde.jaminotification"); +#endif + KAboutData about(QStringLiteral("ring-kde"), i18n("ring-kde"), /*QStringLiteral(*/version/*)*/, i18n("RING, a secured and distributed communication software"), KAboutLicense::GPL_V3, i18n("(C) 2004-2015 Savoir-faire Linux\n2016-2017 Emmanuel Lepage Vallee"), QString(), QStringLiteral("http://www.ring.cx"), QStringLiteral("ring@gnu.org") ); about.setOrganizationDomain(QByteArray("kde.org")); about.setProgramLogo(QImage(QStringLiteral(":appicon/icons/64-apps-ring-kde.png"))); about.addAuthor( i18n( "Emmanuel Lepage-Vallée" ), QString(), QStringLiteral("elv1313@gmail.com" )); about.addAuthor( i18n( "Alexandre Lision" ), QString(), QStringLiteral("alexandre.lision@savoirfairelinux.com")); about.addCredit( i18n( "Based on the SFLphone teamworks" ), QString(), QString() ); if (!Cmd::parseCmd(argc, argv, about)) return 0; KAboutData::setApplicationData(about); app.setOrganizationDomain(QStringLiteral("ring.cx")); //Only start the application once #ifdef Q_OS_LINUX #ifndef DISABLE_KDBUS_SERVICE KDBusService service(KDBusService::Unique); QObject::connect(&service, &KDBusService::activateActionRequested, Cmd::instance(), &Cmd::slotActivateActionRequested); QObject::connect(&service, &KDBusService::activateRequested , Cmd::instance(), &Cmd::slotActivateRequested ); QObject::connect(&service, &KDBusService::openRequested , Cmd::instance(), &Cmd::slotOpenRequested ); #endif #endif //The app will have quitted by now if an instance already exist app.newInstance(); const int retVal = app.exec(); ConfigurationSkeleton::self()->save(); return retVal; } catch(const char * msg) { qDebug() << msg; } catch(QString& msg) { qDebug() << msg; } } // kate: space-indent on; indent-width 3; replace-tabs on; diff --git a/src/ringapplication.cpp b/src/ringapplication.cpp index 2c01ed59..a43e93d0 100644 --- a/src/ringapplication.cpp +++ b/src/ringapplication.cpp @@ -1,241 +1,213 @@ /*************************************************************************** * Copyright (C) 2009-2015 by Savoir-Faire Linux * * Author : Emmanuel Lepage Valle * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * **************************************************************************/ //Parent #include "ringapplication.h" //Qt #include #include #include #include #include #include #include //KDE #include #include #include #include //LRC #include #include #include //Ring #include "kcfg_settings.h" #include "cmd.h" #include "jamikdeintegration/src/windowevent.h" //QML #include "qmlwidgets/plugin.h" #include "qmlwidgets/symboliccolorizer.h" #include "desktopview/desktopviewplugin.h" ///Error to display when there is nothing else to say static const QString GENERIC_ERROR = i18n("An unknown error occurred. Ring KDE will now exit. If the problem persist, please report a bug.\n\n" "It is known that this message can be caused by trying to open Ring KDE while the Ring daemon is exiting. If so, waiting 15 seconds and " "trying again will solve the issue."); KDeclarative::KDeclarative* RingApplication::m_pDeclarative {nullptr}; RingQmlWidgets* RingApplication::m_pQmlWidget {nullptr}; DesktopView* RingApplication::m_pDesktopView {nullptr}; RingApplication* RingApplication::m_spInstance {nullptr}; -//This code detect if the window is active, innactive or minimzed -class PhoneWindowEvent final : public QObject { - Q_OBJECT -public: - PhoneWindowEvent(RingApplication* ev) : QObject(ev),m_pParent(ev) { - QTimer::singleShot(0, [this]() { - m_pParent->desktopWindow()->installEventFilter(this); - }); - } -protected: - virtual bool eventFilter(QObject *obj, QEvent *event) override { - Q_UNUSED(obj) - if (event->type() == QEvent::WindowDeactivate) { - m_pParent->m_HasFocus = false; - } - else if (event->type() == QEvent::WindowActivate) { - m_pParent->m_HasFocus = true; - } - return false; - } - -private: - RingApplication* m_pParent; -Q_SIGNALS: - void minimized(bool); -}; /** * The application constructor */ RingApplication::RingApplication(int & argc, char ** argv) : QApplication(argc,argv),m_StartIconified(false) { Q_ASSERT(argc != -1); setAttribute(Qt::AA_EnableHighDpiScaling); - m_pEventFilter = new PhoneWindowEvent(this); - m_spInstance = this; } /** * Destructor */ RingApplication::~RingApplication() { delete m_pDeclarative; delete engine(); delete m_pQmlWidget; m_spInstance = nullptr; } RingApplication* RingApplication::instance() { Q_ASSERT(m_spInstance); return m_spInstance; } ///Parse command line arguments int RingApplication::newInstance() { static bool displayWizard = ConfigurationSkeleton::enableWizard() || ConfigurationSkeleton::showSplash(); const bool displayOnStart = ConfigurationSkeleton::displayOnStart() && !startIconified(); static bool init = true; //Only call on the first instance if (init) { init = false; desktopWindow(); } // The first run wizard if (displayOnStart && displayWizard) { // Also add this object engine()->rootContext()->setContextProperty( QStringLiteral("RingApplication"), this ); if (ConfigurationSkeleton::enableWizard()) WindowEvent::instance()->showWizard(); if (!Session::instance()->accountModel()->size()) WindowEvent::instance()->showWizard(); ConfigurationSkeleton::setEnableWizard(false); displayWizard = false; return 0; } return 0; } bool RingApplication::startIconified() const { return m_StartIconified; } void RingApplication::setIconify(bool iconify) { m_StartIconified = iconify; } /// Create a QML engine for various canvas widgets QQmlApplicationEngine* RingApplication::engine() { static QQmlApplicationEngine* e = nullptr; static std::atomic_flag engineInit = ATOMIC_FLAG_INIT; if (!engineInit.test_and_set()) { m_pQmlWidget = new RingQmlWidgets; m_pQmlWidget->registerTypes("RingQmlWidgets"); m_pDesktopView = new DesktopView; m_pDesktopView->registerTypes("DesktopView"); e = new QQmlApplicationEngine(QGuiApplication::instance()); // Setup the icon theme provider and ki18n m_pDeclarative = new KDeclarative::KDeclarative; m_pDeclarative->setDeclarativeEngine(e); auto im2 = new SymbolicColorizer(); e->addImageProvider( QStringLiteral("SymbolicColorizer"), im2 ); } return e; } QQuickWindow* RingApplication::desktopWindow() const { static QQuickWindow* dw = nullptr; if (!dw) { QQmlComponent component(engine()); component.loadUrl(QUrl(QStringLiteral("qrc:/DesktopWindow.qml"))); if ( component.isReady() ) { qDebug() << "Previous error" << component.errorString(); auto obj2 = component.create(); // I have *no* clue why this is needed... A race somewhere while (component.errorString().isEmpty() && !obj2) obj2 = component.create(); if (!(dw = qobject_cast(obj2))) qWarning() << "Failed to load:" << component.errorString(); } else qWarning() << component.errorString(); } Q_ASSERT(dw); return dw; } ///Exit gracefully bool RingApplication::notify (QObject* receiver, QEvent* e) { try { return QApplication::notify(receiver,e); } catch (...) { Q_ASSERT(false); qDebug() << GENERIC_ERROR; KMessageBox::error(nullptr, GENERIC_ERROR); } return false; } bool RingApplication::mayHaveFocus() { return m_HasFocus; } #include // kate: space-indent on; indent-width 3; replace-tabs on; diff --git a/src/ringapplication.h b/src/ringapplication.h index 46b76edc..ab8d1001 100644 --- a/src/ringapplication.h +++ b/src/ringapplication.h @@ -1,92 +1,90 @@ /*************************************************************************** * Copyright (C) 2009-2015 by Savoir-Faire Linux * * Author : Jérémy Quentin * * Emmanuel Lepage Vallee * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * **************************************************************************/ #ifndef RINGAPPLICATION_H #define RINGAPPLICATION_H #include //Qt class QEvent; class QQmlApplicationEngine; class QQuickWindow; //KF5 namespace KDeclarative { class KDeclarative; } //Ring class RingQmlWidgets; class DesktopView; class DialView; -class PhoneWindowEvent; ///RingApplication: Main application class RingApplication final : public QApplication { Q_OBJECT public: // Constructor RingApplication(int & argc, char ** argv); // Destructor virtual ~RingApplication(); // Manage new instances Q_INVOKABLE virtual int newInstance(); // Exit gracefully virtual bool notify (QObject* receiver, QEvent* e) override; //Getter bool startIconified() const; QQuickWindow* desktopWindow() const; static QQmlApplicationEngine* engine(); static RingApplication* instance(); /** * An unreliable way to track the application focus * * It is better than nothing */ bool mayHaveFocus(); //Setter void setIconify(bool iconify); bool m_HasFocus {false}; private: //Attributes bool m_StartIconified {false}; static KDeclarative::KDeclarative* m_pDeclarative; static RingQmlWidgets* m_pQmlWidget; static RingApplication* m_spInstance; static DesktopView* m_pDesktopView; - PhoneWindowEvent* m_pEventFilter {nullptr}; }; #endif // RINGAPPLICATION_H // kate: space-indent on; indent-width 3; replace-tabs on;