diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ff9f283..3d7428a2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,345 +1,361 @@ 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( jamivideoview ) # Build the main desktop component ADD_SUBDIRECTORY( jamitroubleshooting ) # Build the main desktop component ADD_SUBDIRECTORY( desktopview ) +# Build the main desktop component +ADD_SUBDIRECTORY( jamihistoryview ) + +# Build the main desktop component +ADD_SUBDIRECTORY( jamichatview ) + +# Build the main desktop component +ADD_SUBDIRECTORY( jamitimelinebase ) + +# Build the main desktop component +ADD_SUBDIRECTORY( jamiaudioplayer ) + # 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 jamivideoview jamitroubleshooting + jamihistoryview + jamichatview + jamitimelinebase + jamiaudioplayer # 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/timeline/assets/welcome.html b/src/contactview/assets/welcome.html similarity index 100% rename from src/timeline/assets/welcome.html rename to src/contactview/assets/welcome.html diff --git a/src/contactview/contactview.qrc b/src/contactview/contactview.qrc index 28840227..6a889543 100644 --- a/src/contactview/contactview.qrc +++ b/src/contactview/contactview.qrc @@ -1,17 +1,22 @@ qml/pendingrequest.qml qml/contactlist.qml qml/bookmarklist.qml qml/contactcard.qml qml/bookmarkcard.qml qml/vcardform.qml qml/statistics.qml qml/newcontactdialog.qml qml/pendingrequests.qml qml/sendrequest.qml qml/viewcontactrequests.qml qml/contactinfo.qml qml/phonenumbers.qml + qml/contactdialog.qml + qml/addresses.qml + + + assets/welcome.html diff --git a/src/contactview/contactviewplugin.cpp b/src/contactview/contactviewplugin.cpp index de2d7bbc..6518a18f 100644 --- a/src/contactview/contactviewplugin.cpp +++ b/src/contactview/contactviewplugin.cpp @@ -1,59 +1,61 @@ /************************************************************************************ * 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 "contactviewplugin.h" // Qt #include #include #include // QRC #include // CallView #include "mainpage.h" #include "contactphoto.h" void JamiContactViewPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamicontactview")); qmlRegisterType(uri, 1, 0, "MainPage"); qmlRegisterType(uri, 1, 0, "ContactPhoto"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/pendingrequest.qml") , uri, 1, 0, "PendingRequest"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/contactlist.qml") , uri, 1, 0, "ContactList"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/bookmarklist.qml") , uri, 1, 0, "BookmarkList"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/contactcard.qml") , uri, 1, 0, "ContactCard"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/bookmarkcard.qml") , uri, 1, 0, "BookmarkCard"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/vcardform.qml") , uri, 1, 0, "VCardForm"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/statistics.qml") , uri, 1, 0, "Statistics"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/newcontactdialog.qml") , uri, 1, 0, "NewContactDialog"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/phonenumbers.qml") , uri, 1, 0, "PhoneNumbers"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/contactinfo.qml") , uri, 1, 0, "ContactInfo"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/pendingrequests.qml") , uri, 1, 0, "PendingRequests"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/sendrequest.qml") , uri, 1, 0, "SendRequest"); qmlRegisterType(QStringLiteral("qrc:/contactview/qml/viewcontactrequests.qml") , uri, 1, 0, "ViewContactRequests"); + qmlRegisterType(QStringLiteral("qrc:/contactview/qml/addresses.qml") , uri, 1, 0, "Addresses"); + qmlRegisterType(QStringLiteral("qrc:/contactview/qml/contactdialog.qml") , uri, 1, 0, "ContactDialog"); } void JamiContactViewPlugin::initializeEngine(QQmlEngine *engine, const char *uri) { Q_UNUSED(engine) Q_UNUSED(uri) } diff --git a/src/timeline/qml/addresses.qml b/src/contactview/qml/addresses.qml similarity index 100% rename from src/timeline/qml/addresses.qml rename to src/contactview/qml/addresses.qml diff --git a/src/timeline/qml/contactdialog.qml b/src/contactview/qml/contactdialog.qml similarity index 100% rename from src/timeline/qml/contactdialog.qml rename to src/contactview/qml/contactdialog.qml diff --git a/src/desktopview/qml/dockbar.qml b/src/desktopview/qml/dockbar.qml index 42239616..76e64ff7 100644 --- a/src/desktopview/qml/dockbar.qml +++ b/src/desktopview/qml/dockbar.qml @@ -1,293 +1,294 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Layouts 1.0 import QtQuick.Controls 2.0 as Controls import org.kde.kirigami 2.2 as Kirigami import QtQuick.Window 2.2 import net.lvindustries.ringqtquick 1.0 as RingQtQuick import org.kde.ringkde.jamicontactview 1.0 as JamiContactView import org.kde.ringkde.jamidialview 1.0 as JamiDialView import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline +import org.kde.ringkde.jamihistoryview 1.0 as JamiHistoryView import DesktopView 1.0 Item { id: topLevel width: Math.min(335, root.width-48) + dockBar.width property var newHolder: null function setCurrentIndex(index) { if (dockLoader.sourceComponent != timelineViewComponent) return dockLoader.item.setCurrentIndex(index) } signal timelineSelected() RowLayout { id: dockLayout spacing: 0 anchors.fill: parent Image { id: dockBar property string selectedItem: "timeline" source: "gui/icons/assets/toolbar_bg.png" fillMode: Image.Tile width: 48 height: parent.height Layout.fillHeight: true Layout.maximumWidth: width onSelectedItemChanged: { switch(selectedItem) { case "timeline": dockLoader.sourceComponent = timelineViewComponent break case "call" : dockLoader.sourceComponent = dialViewComponent break case "contact" : dockLoader.sourceComponent = contactViewComponent break case "bookmark": dockLoader.sourceComponent = bookmarkViewComponent break case "history" : dockLoader.sourceComponent = historyViewComponent break } } Behavior on width { NumberAnimation {duration: 200; easing.type: Easing.OutQuad } } DockModel { id: icons } FontMetrics { id: fontMetrics } Column { Item { width: dockBar.width height: Math.max( dockBar.width * 1.33, availableAccounts.count*(dockBar.width+5) + 6 ) ListView { y: 5 id: availableAccounts model: RingSession.profileModel.availableProfileModel height: 200 spacing: 5 interactive: false delegate: MouseArea { width: dockBar.width height: dockBar.width JamiContactView.ContactPhoto { anchors.centerIn: parent width: dockBar.width - 3 height: dockBar.width - 3 individual: object defaultColor: "#f2f2f2ff" //same as the SVG } onClicked: { var component = Qt.createComponent("PresenceSelector.qml") if (component.status == Component.Ready) { var window = component.createObject(applicationWindow().contentItem) window.individual = object window.open() } else console.log("ERROR", component.status, component.errorString()) } } } Loader { active: availableAccounts.count == 0 || !RingSession.profileModel.hasAvailableProfiles anchors.centerIn: parent sourceComponent: Rectangle { height: 48 width: 48 border.width: 2 border.color: Kirigami.Theme.negativeTextColor color: "transparent" radius: 99 Image { anchors.fill: parent sourceSize.width: 48 sourceSize.height: 48 anchors.verticalCenter: parent.verticalCenter source: "image://SymbolicColorizer/:/sharedassets/outline/warning.svg" } } } Rectangle { height: 1 width: parent.width color: "#939393" anchors.bottom: parent.bottom } } Repeater { model: icons Rectangle { id: actionIcon color: dockBar.selectedItem == identifier ? "#111111" : "transparent" height: dockBar.width + 10 width: dockBar.width Image { anchors.verticalCenter: parent.verticalCenter source: decoration width: 48 height: 48 sourceSize.width: 48 sourceSize.height: 48 fillMode: Image.PreserveAspectFit } MouseArea { anchors.fill: parent onClicked: { dockBar.selectedItem = identifier } } Rectangle { color: "red" radius: 99 x: 2 y: 2 width: fontMetrics.height + 4 height: fontMetrics.height + 4 visible: activeCount > 0 Text { color: "white" anchors.centerIn: parent font.bold: true text: activeCount } } } } } } Component { id: timelineViewComponent JamiTimeline.PeersTimeline { anchors.fill: parent state: "" onIndividualSelected: { mainPage.setIndividual(ind) } } } Component { id: dialViewComponent JamiDialView.DialView { anchors.fill: parent onSelectCall: { mainPage.showVideo(call) } } } Component { id: contactViewComponent JamiContactView.ContactList { anchors.fill: parent onIndividualSelected: { mainPage.setIndividual(ind) } } } Component { id: bookmarkViewComponent JamiContactView.BookmarkList { anchors.fill: parent onContactMethodSelected: { mainPage.setContactMethod(cm) } } } Component { id: historyViewComponent - JamiTimeline.HistoryTimeline { + JamiHistoryView.HistoryTimeline { anchors.fill: parent onContactMethodSelected: { mainPage.setContactMethod(cm) } } } ColumnLayout { id: dockHolder width: Math.min(335, root.width-48) Layout.fillHeight: true visible: true // This is a placeholder for the searchbox Item { Layout.fillWidth: true Layout.minimumHeight: 32 Layout.maximumHeight: 32 } Loader { id: dockLoader sourceComponent: timelineViewComponent Layout.fillWidth: true Layout.fillHeight: true onItemChanged: { if (item && sourceComponent == timelineViewComponent) timelineSelected() } } } } JamiTimeline.SearchOverlay { id: searchView source: parent anchors.fill: parent onContactMethodSelected: { mainPage.setContactMethod(cm) setCurrentIndex(RingSession.peersTimelineModel.individualIndex(cm.individual)) } } } diff --git a/src/desktopview/qml/viewcontact.qml b/src/desktopview/qml/viewcontact.qml index 01b16732..f5cf3a08 100644 --- a/src/desktopview/qml/viewcontact.qml +++ b/src/desktopview/qml/viewcontact.qml @@ -1,433 +1,435 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import org.kde.kirigami 2.2 as Kirigami import net.lvindustries.ringqtquick 1.0 as RingQtQuick import net.lvindustries.ringqtquick.media 1.0 as RingQtMedia import org.kde.ringkde.jamicallview 1.0 as JamiCallView import org.kde.ringkde.jamicontactview 1.0 as JamiContactView import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline +import org.kde.ringkde.jamihistoryview 1.0 as JamiHistoryView +import org.kde.ringkde.jamichatview 1.0 as JamiChatView Item { id: viewContact property var currentContactMethod: null property var timelineModel: null property string currentPage: "" property var contactHeader: null property bool mobile: false property var currentIndividual: null property var unsortedListView: null function getDefaultCm() { if (currentContactMethod) return currentContactMethod if (currentIndividual) return currentIndividual.mainContactMethod return null } function showVideo() { avView.active = true if (state == "mobile") stackView.push(avPage) else tabBar.currentIndex = 1 } function showNewContent() { if (timelinePage.item) timelinePage.item.showNewContent() } clip: true onCurrentContactMethodChanged: { if (contactHeader) contactHeader.currentContactMethod = currentContactMethod if (currentContactMethod && currentContactMethod.person) personConn.target = currentContactMethod.person if (currentContactMethod) avView.call = currentContactMethod.firstActiveCall else if (currentIndividual) avView.call = currentIndividual.firstActiveCall } onCurrentIndividualChanged: { if (contactHeader) contactHeader.currentIndividual = currentIndividual if (currentIndividual && currentIndividual.person) personConn.target = currentIndividual.person if (currentIndividual != null) avView.call = currentIndividual.firstActiveCall } onCurrentPageChanged: { if (currentPage == "") return switch(currentPage) { case "TIMELINE": tabBar.currentIndex = 0 break case "MEDIA": tabBar.currentIndex = 1 break case "CALL_HISTORY": tabBar.currentIndex = 2 break case "INFORMATION": tabBar.currentIndex = 3 break } currentPage = "" } RingQtMedia.AvailabilityTracker { id: availabilityTracker individual: currentIndividual } Connections { target: currentContactMethod onContactChanged: { if (currentContactMethod.person) personConn.target = currentContactMethod.person } } Connections { target: currentContactMethod onCallAdded: { if (currentContactMethod.person) return avView.call = call && call.lifeCycleState != RingQtQuick.Call.FINISHED ? call : null } } Connections { id: personConn target: currentContactMethod ? currentContactMethod.person : null onCallAdded: { avView.call = call } } ColumnLayout { id: columnLayout anchors.fill: parent TabBar { Layout.fillWidth: true id: tabBar currentIndex: swipeView.currentIndex TabButton { text: i18n("Chat/Timeline") } TabButton { text: i18n("Audio/Video") } TabButton { text: i18n("Calls/Recordings") } TabButton { text: i18n("Information") } onCurrentIndexChanged: { //TODO deactivate it after a minute in other tabs if (currentIndex == 0) { timelinePage.active = true } if (currentIndex == 2) { callHistory.active = true } } } SwipeView { id: swipeView Layout.fillHeight: true Layout.fillWidth: true background: Rectangle { color: activePalette.base } currentIndex: tabBar.currentIndex Page { id: chatPage background: Rectangle { color: activePalette.base } Loader { anchors.fill: parent asynchronous: true active: true id: timelinePage property bool showScrollbar: true - sourceComponent: JamiTimeline.TimelinePage { + sourceComponent: JamiChatView.ChatPage { showScrollbar: timelinePage.showScrollbar timelineModel: viewContact.timelineModel currentContactMethod: viewContact.currentContactMethod currentIndividual: viewContact.currentIndividual anchors.fill: parent } } } Page { id: avPage background: Rectangle { color: activePalette.base } Loader { id: avView asynchronous: true active: false anchors.fill: parent property QtObject call: null // QML bug? onCallChanged: { if (active) callViewWidget.call = call } JamiCallView.CallView { id: callViewWidget mode: "CONVERSATION" anchors.fill: parent call: avView.call onCallWithAudio: { var cm = viewContact.getDefaultCm() if (cm && cm.hasInitCall) { contactHeader.selectVideo() return } RingSession.callModel.dialingCall(cm) .performAction(RingQtQuick.Call.ACCEPT) } onCallWithVideo: { var cm = viewContact.getDefaultCm() if (cm && cm.hasInitCall) { contactHeader.selectVideo() return } RingSession.callModel.dialingCall(cm) .performAction(RingQtQuick.Call.ACCEPT) } onCallWithScreen: { var cm = viewContact.getDefaultCm() if (cm && cm.hasInitCall) { contactHeader.selectVideo() return } RingSession.callModel.dialingCall(cm) .performAction(RingQtQuick.Call.ACCEPT) } } } } Page { id: historyPage background: Rectangle { color: activePalette.base } Loader { anchors.fill: parent id: callHistory asynchronous: true active: false - sourceComponent: JamiTimeline.CallHistory { + sourceComponent: JamiHistoryView.CallHistory { showScrollbar: timelinePage.showScrollbar timelineModel: viewContact.timelineModel currentContactMethod: viewContact.currentContactMethod currentIndividual: viewContact.currentIndividual anchors.fill: parent } } } Page { id: contactInfoPage background: Rectangle { color: activePalette.base } JamiContactView.ContactInfo { id: contactInfo individual: viewContact.currentIndividual anchors.fill: parent onSelectChat: { stackView.push(page3) } onSelectHistory: { stackView.push(page2) } } } } } Kirigami.PageRow { id: stackView visible: false background: Rectangle { color: activePalette.base } anchors.fill: parent Page { id: page2 background: Rectangle { color: activePalette.base } } Page { id: page3 background: Rectangle { color: activePalette.base } } Page { id: page4 background: Rectangle { color: activePalette.base } } Page { id: page1 anchors.margins: 0 background: Rectangle { color: activePalette.base } } } onStateChanged: { stackView.clear() if (state == "mobile") stackView.push(page1) } states: [ State { name: "" when: !viewContact.mobile ParentChange { target: contactInfo parent: contactInfoPage } ParentChange { target: callHistory parent: historyPage } ParentChange { target: timelinePage parent: chatPage } PropertyChanges { target: columnLayout visible: true } PropertyChanges { target: stackView visible: false } PropertyChanges { target: contactInfo anchors.fill: contactInfoPage flickable.interactive: false } PropertyChanges { target: timelinePage showScrollbar: true } }, State { name: "mobile" when: viewContact.mobile ParentChange { target: contactInfo parent: page1 } ParentChange { target: callHistory parent: page2 } ParentChange { target: timelinePage parent: page3 } PropertyChanges { target: columnLayout visible: false } PropertyChanges { target: stackView visible: true } PropertyChanges { target: contactInfo anchors.fill: page1 flickable.interactive: true } PropertyChanges { target: callHistory active: true } PropertyChanges { target: timelinePage active: true } PropertyChanges { target: timelinePage showScrollbar: false } } ] } diff --git a/src/jamiaudioplayer/CMakeLists.txt b/src/jamiaudioplayer/CMakeLists.txt new file mode 100644 index 00000000..b30b258d --- /dev/null +++ b/src/jamiaudioplayer/CMakeLists.txt @@ -0,0 +1,119 @@ +cmake_minimum_required(VERSION 3.0) + +project(jamiaudioplayer) + +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(-DJAMIJAMIAUDIOPLAYER_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( jamiaudioplayer_LIB_SRCS + plugin.cpp +) + +qt5_add_resources(jamiaudioplayer_LIB_SRCS + jamiaudioplayer.qrc +) + +set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.ringkde.jamiaudioplayer) + +add_library(jamiaudioplayer ${jamiaudioplayer_LIB_SRCS} ) + +target_link_libraries( jamiaudioplayer + # Project + ringqt + ringqtquick + + # Qt + Qt5::Core + Qt5::Gui + Qt5::Quick + Qt5::QuickControls2 +) + +# Configure the target config +set(jamiaudioplayer_CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/JamiAudioPlayerConfig.cmake") + +if(USES_ADD_SUBDIRECTORY) + set(JamiAudioPlayer_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) +endif() + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/JamiAudioPlayerConfig.cmake.in" ${jamiaudioplayer_CONFIG_PATH} + INSTALL_DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiAudioPlayer/ + PATH_VARS INCLUDE_INSTALL_DIR +) + +install( FILES ${jamiaudioplayer_CONFIG_PATH} + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiAudioPlayer/ + COMPONENT Devel +) + +# Create the target +target_include_directories(jamiaudioplayer + PUBLIC + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/ +) + +set_target_properties(jamiaudioplayer PROPERTIES + PUBLIC_HEADER + "${jamiaudioplayer_EXPORT_HDRS}" +) + +export(TARGETS jamiaudioplayer + FILE "${PROJECT_BINARY_DIR}/cmake/JamiAudioPlayerTargets.cmake" +) + +install(TARGETS jamiaudioplayer + EXPORT JamiAudioPlayerTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" COMPONENT jamiaudioplayer + ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + COMPONENT Devel +) + +install(EXPORT JamiAudioPlayerTargets + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiAudioPlayer + COMPONENT Devel +) diff --git a/src/jamiaudioplayer/cmake/JamiAudioPlayerConfig.cmake.in b/src/jamiaudioplayer/cmake/JamiAudioPlayerConfig.cmake.in new file mode 100644 index 00000000..31bf2933 --- /dev/null +++ b/src/jamiaudioplayer/cmake/JamiAudioPlayerConfig.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(-DJAMIJAMIAUDIOPLAYER_USE_STATIC_PLUGIN=1) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/JamiAudioPlayerTargets.cmake") diff --git a/src/jamiaudioplayer/jamiaudioplayer.json b/src/jamiaudioplayer/jamiaudioplayer.json new file mode 100644 index 00000000..00fad9f2 --- /dev/null +++ b/src/jamiaudioplayer/jamiaudioplayer.json @@ -0,0 +1,4 @@ +{ + "Keys": [ "org.kde.ringkde.jamiaudioplayer" ], + "uri": ["org.kde.ringkde.jamiaudioplayer"] +} diff --git a/src/jamiaudioplayer/jamiaudioplayer.qrc b/src/jamiaudioplayer/jamiaudioplayer.qrc new file mode 100644 index 00000000..71316d8c --- /dev/null +++ b/src/jamiaudioplayer/jamiaudioplayer.qrc @@ -0,0 +1,5 @@ + + + qml/audioplayer.qml + + diff --git a/src/jamiaudioplayer/plugin.cpp b/src/jamiaudioplayer/plugin.cpp new file mode 100644 index 00000000..ae801990 --- /dev/null +++ b/src/jamiaudioplayer/plugin.cpp @@ -0,0 +1,39 @@ +/************************************************************************************ + * 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 + +// QRC +#include + +void JamiAudioPlayer::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamiaudioplayer")); + qmlRegisterType(QStringLiteral("qrc:/jamiaudioplayer/qml/audioplayer.qml"), uri, 1, 0, "AudioPlayer"); + +} + +void JamiAudioPlayer::initializeEngine(QQmlEngine *engine, const char *uri) +{ + Q_UNUSED(engine) + Q_UNUSED(uri) +} diff --git a/src/jamiaudioplayer/plugin.h b/src/jamiaudioplayer/plugin.h new file mode 100644 index 00000000..9d01cffc --- /dev/null +++ b/src/jamiaudioplayer/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 JamiAudioPlayer final : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kde.ringkde.jamiaudioplayer" FILE "jamiaudioplayer.json") + +public: + void registerTypes(const char* uri) override; + virtual void initializeEngine(QQmlEngine* engine, const char* uri) override; +}; diff --git a/src/timeline/qml/audioplayer.qml b/src/jamiaudioplayer/qml/audioplayer.qml similarity index 100% rename from src/timeline/qml/audioplayer.qml rename to src/jamiaudioplayer/qml/audioplayer.qml diff --git a/src/jamichatview/CMakeLists.txt b/src/jamichatview/CMakeLists.txt new file mode 100644 index 00000000..bf431543 --- /dev/null +++ b/src/jamichatview/CMakeLists.txt @@ -0,0 +1,120 @@ +cmake_minimum_required(VERSION 3.0) + +project(jamichatview) + +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(-DJAMIJAMICHATVIEW_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( jamichatview_LIB_SRCS + plugin.cpp + bubble.cpp +) + +qt5_add_resources(jamichatview_LIB_SRCS + jamichatview.qrc +) + +set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.ringkde.jamichatview) + +add_library(jamichatview ${jamichatview_LIB_SRCS} ) + +target_link_libraries( jamichatview + # Project + ringqt + ringqtquick + + # Qt + Qt5::Core + Qt5::Gui + Qt5::Quick + Qt5::QuickControls2 +) + +# Configure the target config +set(jamichatview_CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/JamiChatViewConfig.cmake") + +if(USES_ADD_SUBDIRECTORY) + set(JamiChatView_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) +endif() + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/JamiChatViewConfig.cmake.in" ${jamichatview_CONFIG_PATH} + INSTALL_DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiChatView/ + PATH_VARS INCLUDE_INSTALL_DIR +) + +install( FILES ${jamichatview_CONFIG_PATH} + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiChatView/ + COMPONENT Devel +) + +# Create the target +target_include_directories(jamichatview + PUBLIC + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/ +) + +set_target_properties(jamichatview PROPERTIES + PUBLIC_HEADER + "${jamichatview_EXPORT_HDRS}" +) + +export(TARGETS jamichatview + FILE "${PROJECT_BINARY_DIR}/cmake/JamiChatViewTargets.cmake" +) + +install(TARGETS jamichatview + EXPORT JamiChatViewTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" COMPONENT jamichatview + ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + COMPONENT Devel +) + +install(EXPORT JamiChatViewTargets + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiChatView + COMPONENT Devel +) diff --git a/src/qmlwidgets/bubble.cpp b/src/jamichatview/bubble.cpp similarity index 100% rename from src/qmlwidgets/bubble.cpp rename to src/jamichatview/bubble.cpp diff --git a/src/qmlwidgets/bubble.h b/src/jamichatview/bubble.h similarity index 100% rename from src/qmlwidgets/bubble.h rename to src/jamichatview/bubble.h diff --git a/src/jamichatview/cmake/JamiChatViewConfig.cmake.in b/src/jamichatview/cmake/JamiChatViewConfig.cmake.in new file mode 100644 index 00000000..aa870f32 --- /dev/null +++ b/src/jamichatview/cmake/JamiChatViewConfig.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(-DJAMIJAMICHATVIEW_USE_STATIC_PLUGIN=1) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/JamiChatViewTargets.cmake") diff --git a/src/jamichatview/jamichatview.json b/src/jamichatview/jamichatview.json new file mode 100644 index 00000000..d326c6c0 --- /dev/null +++ b/src/jamichatview/jamichatview.json @@ -0,0 +1,4 @@ +{ + "Keys": [ "org.kde.ringkde.jamichatview" ], + "uri": ["org.kde.ringkde.jamichatview"] +} diff --git a/src/jamichatview/jamichatview.qrc b/src/jamichatview/jamichatview.qrc new file mode 100644 index 00000000..f2262078 --- /dev/null +++ b/src/jamichatview/jamichatview.qrc @@ -0,0 +1,16 @@ + + + qml/chatbox.qml + qml/chatview.qml + qml/textbubble.qml + qml/categoryheader.qml + qml/textmessagegroup.qml + qml/callgroup.qml + qml/groupheader.qml + qml/groupfooter.qml + qml/chatpage.qml + qml/snapshots.qml + qml/slideshow.qml + qml/thumbnail.qml + + diff --git a/src/jamichatview/plugin.cpp b/src/jamichatview/plugin.cpp new file mode 100644 index 00000000..58419306 --- /dev/null +++ b/src/jamichatview/plugin.cpp @@ -0,0 +1,54 @@ +/************************************************************************************ + * 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 + +// QRC +#include + +// ChatView +#include "bubble.h" + +void JamiChatView::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamichatview")); + + qmlRegisterType(uri, 1, 0, "Bubble"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/chatbox.qml") , uri, 1, 0, "ChatBox"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/chatview.qml") , uri, 1, 0, "ChatView"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/textbubble.qml") , uri, 1, 0, "TextBubble"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/categoryheader.qml") , uri, 1, 0, "CategoryHeader"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/textmessagegroup.qml"), uri, 1, 0, "TextMessageGroup"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/callgroup.qml") , uri, 1, 0, "CallGroup"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/groupheader.qml") , uri, 1, 0, "GroupHeader"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/groupfooter.qml") , uri, 1, 0, "GroupFooter"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/snapshots.qml") , uri, 1, 0, "Snapshots"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/slideshow.qml") , uri, 1, 0, "Slideshow"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/thumbnail.qml") , uri, 1, 0, "Thumbnail"); + qmlRegisterType(QStringLiteral("qrc:/jamichatview/qml/chatpage.qml") , uri, 1, 0, "ChatPage"); +} + +void JamiChatView::initializeEngine(QQmlEngine *engine, const char *uri) +{ + Q_UNUSED(engine) + Q_UNUSED(uri) +} diff --git a/src/jamichatview/plugin.h b/src/jamichatview/plugin.h new file mode 100644 index 00000000..2e5dbb46 --- /dev/null +++ b/src/jamichatview/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 JamiChatView final : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kde.ringkde.jamichatview" FILE "jamichatview.json") + +public: + void registerTypes(const char* uri) override; + virtual void initializeEngine(QQmlEngine* engine, const char* uri) override; +}; diff --git a/src/timeline/qml/callgroup.qml b/src/jamichatview/qml/callgroup.qml similarity index 89% rename from src/timeline/qml/callgroup.qml rename to src/jamichatview/qml/callgroup.qml index 545181d5..1673fc37 100644 --- a/src/timeline/qml/callgroup.qml +++ b/src/jamichatview/qml/callgroup.qml @@ -1,49 +1,50 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Layouts 1.0 import RingQmlWidgets 1.0 -import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline +import org.kde.ringkde.jamichatview 1.0 as JamiChatView +import org.kde.ringkde.jamitimelinebase 1.0 as JamiTimelineBase ColumnLayout { id: textGroupDelegate - JamiTimeline.GroupHeader { + JamiChatView.GroupHeader { type: "call" anchors.margins: 4 Layout.fillWidth: true Layout.preferredHeight: 38 } - MultiCall { + JamiTimelineBase.MultiCall { Layout.fillWidth: true width: textGroupDelegate.width modelIndex: rootIndex count: callCount } Item { height: 3 } - JamiTimeline.GroupFooter { + JamiChatView.GroupFooter { Layout.fillWidth: true } } diff --git a/src/timeline/qml/categoryheader.qml b/src/jamichatview/qml/categoryheader.qml similarity index 100% rename from src/timeline/qml/categoryheader.qml rename to src/jamichatview/qml/categoryheader.qml diff --git a/src/timeline/qml/chatbox.qml b/src/jamichatview/qml/chatbox.qml similarity index 100% rename from src/timeline/qml/chatbox.qml rename to src/jamichatview/qml/chatbox.qml diff --git a/src/timeline/qml/timelinepage.qml b/src/jamichatview/qml/chatpage.qml similarity index 96% rename from src/timeline/qml/timelinepage.qml rename to src/jamichatview/qml/chatpage.qml index 57c9eb55..1814d04c 100644 --- a/src/timeline/qml/timelinepage.qml +++ b/src/jamichatview/qml/chatpage.qml @@ -1,219 +1,221 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import QtGraphicalEffects 1.0 import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline +import org.kde.ringkde.jamitimelinebase 1.0 as JamiTimelineBase +import org.kde.ringkde.jamichatview 1.0 as JamiChatView import net.lvindustries.ringqtquick 1.0 as RingQtQuick import RingQmlWidgets 1.0 Rectangle { id: timelinePage property bool showScrollbar: true function focusEdit() { chatBox.focusEdit() } function showNewContent() { chatView.moveTo(Qt.BottomEdge) } function setContactMethod() { if (currentIndividual && !currentContactMethod) { currentContactMethod = currentIndividual.preferredContactMethod(Media.TEXT) if (!currentContactMethod) console.log("Cannot find a valid ContactMethod for", currentIndividual) } return currentContactMethod } onCurrentIndividualChanged: { currentContactMethod = null setContactMethod() } SystemPalette { id: activePalette colorGroup: SystemPalette.Active } color: activePalette.base property var currentContactMethod: null property var currentIndividual: null property var timelineModel: null property bool canSendTexts: currentIndividual ? currentIndividual.canSendTexts : false onTimelineModelChanged: { if (!fixmeTimer.running) chatView.model = timelineModel } // Add a blurry background ShaderEffectSource { id: effectSource visible: false sourceItem: chatView anchors.right: timelinePage.right anchors.top: timelinePage.top width: scrollbar.fullWidth + 15 height: chatView.height sourceRect: Qt.rect( burryOverlay.x, burryOverlay.y, burryOverlay.width, burryOverlay.height ) } ColumnLayout { anchors.fill: parent clip: true RowLayout { id: chatScrollView Layout.fillHeight: true Layout.fillWidth: true property bool lock: false Item { Layout.fillHeight: true Layout.fillWidth: true - JamiTimeline.ChatView { + JamiChatView.ChatView { id: chatView anchors.fill: parent model: null//FIXME timelinePage.timelineModel // Due to a race condition, wait a bit, it should be fixed elsewhere, //FIXME but it would take much longer. Timer { id: fixmeTimer repeat: false running: true interval: 33 onTriggered: { chatView.model = timelinePage.timelineModel } } } // It needs to be here due to z-index conflicts between // chatScrollView and timelinePage Item { id: burryOverlay z: 2 visible: false opacity: 0 anchors.right: parent.right anchors.top: parent.top anchors.rightMargin: - 15 width: scrollbar.fullWidth + 15 height: chatView.height clip: true Behavior on opacity { NumberAnimation {duration: 300; easing.type: Easing.InQuad} } Repeater { anchors.fill: parent model: 5 FastBlur { anchors.fill: parent source: effectSource radius: 30 } } Rectangle { anchors.fill: parent color: activePalette.base opacity: 0.75 } } } - JamiTimeline.TimelineScrollbar { + JamiTimelineBase.Scrollbar { id: scrollbar z: 1000 bottomUp: true Layout.fillHeight: true Layout.preferredWidth: 10 display: chatView.moving || timelinePage.showScrollbar model: timelinePage.timelineModel view: chatView onWidthChanged: { burryOverlay.width = scrollbar.fullWidth + 15 } onOverlayVisibleChanged: { burryOverlay.visible = overlayVisible burryOverlay.opacity = overlayVisible ? 1 : 0 effectSource.visible = overlayVisible } } } - JamiTimeline.ChatBox { + JamiChatView.ChatBox { id: chatBox Layout.fillWidth: true height: 90 visible: canSendTexts RingQtQuick.MessageBuilder {id: builder} requireContactRequest: currentContactMethod && currentContactMethod.confirmationStatus == RingQtQuick.ContactMethod.UNCONFIRMED && currentContactMethod.confirmationStatus != RingQtQuick.ContactMethod.DISABLED textColor: activePalette.text backgroundColor: activePalette.window emojiColor: activePalette.highlight onDisableContactRequests: { if (timelinePage.setContactMethod()) { currentContactMethod.confirmationEnabled = false } } } } Connections { target: chatBox onSendMessage: { timelinePage.setContactMethod() if (currentContactMethod) { if (currentContactMethod.account && currentContactMethod.confirmationStatus == ContactMethod.UNCONFIRMED) currentContactMethod.sendContactRequest() builder.addPayload("text/plain", message) builder.sendWidth(currentContactMethod) } } } } diff --git a/src/timeline/qml/chatview.qml b/src/jamichatview/qml/chatview.qml similarity index 94% rename from src/timeline/qml/chatview.qml rename to src/jamichatview/qml/chatview.qml index 9c58541f..5154654c 100644 --- a/src/timeline/qml/chatview.qml +++ b/src/jamichatview/qml/chatview.qml @@ -1,157 +1,157 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import org.kde.playground.kquickitemviews 1.0 as KQuickItemViews import net.lvindustries.ringqtquick 1.0 as RingQtQuick -import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline import net.lvindustries.ringqtquick.models 1.0 as RingQtModels +import org.kde.ringkde.jamichatview 1.0 as JamiChatView import RingQmlWidgets 1.0 KQuickItemViews.HierarchyView { id: chatView clip: true property var treeHelper: _treeHelper SystemPalette { id: activePalette colorGroup: SystemPalette.Active } TreeHelper { id: _treeHelper } property var bubbleBackground: blendColor() property var bubbleForeground: "" property var unreadBackground: "" property var unreadForeground: "" property alias slideshow: slideshow function blendColor() { var base2 = activePalette.highlight base2 = Qt.rgba(base2.r, base2.g, base2.b, 0.3) var base1 = Qt.tint(activePalette.base, base2) chatView.bubbleBackground = base1 chatView.unreadBackground = Qt.tint(activePalette.base, "#33BB0000") chatView.bubbleForeground = activePalette.text chatView.unreadForeground = activePalette.text return base1 } - JamiTimeline.Slideshow { + JamiChatView.Slideshow { id: slideshow } // Display something when the chat is empty Text { color: activePalette.text text: i18n("There is nothing yet, enter a message below or place a call using the buttons\nfound in the header") anchors.centerIn: parent visible: chatView.empty horizontalAlignment: Text.AlignHCenter } Component { id: messageDelegate Loader { id: chatLoader // Create a delegate for each type Component { id: sectionDelegate - JamiTimeline.TextMessageGroup { + JamiChatView.TextMessageGroup { width: chatView.width } } Component { id: snapshotGroupDelegate - JamiTimeline.Snapshots { + JamiChatView.Snapshots { width: chatView.width onViewImage: { chatView.slideshow.active = true chatView.slideshow.model = model chatView.slideshow.source = path } } } Component { id: callDelegate - JamiTimeline.CallGroup { + JamiChatView.CallGroup { width: chatView.width } } Component { id: categoryDelegate - JamiTimeline.CategoryHeader { + JamiChatView.CategoryHeader { width: chatView.width } } Component { id: textDelegate - JamiTimeline.TextBubble { + JamiChatView.TextBubble { background: isRead ? chatView.bubbleBackground : chatView.unreadBackground foreground: isRead ? chatView.bubbleForeground : chatView.unreadForeground width: chatView.width onClicked: { chatView.treeHelper.setData(rootIndex, true, "isRead") } } } // Some elements don't have delegates because they are handled // by their parent delegates function selectDelegate() { if (nodeType == RingQtModels.IndividualTimelineModel.TIME_CATEGORY) return categoryDelegate if (nodeType == RingQtModels.IndividualTimelineModel.TEXT_MESSAGE) return textDelegate if (nodeType == RingQtModels.IndividualTimelineModel.SNAPSHOT_GROUP) return snapshotGroupDelegate if (nodeType == RingQtModels.IndividualTimelineModel.SECTION_DELIMITER) return sectionDelegate if ( nodeType == RingQtModels.IndividualTimelineModel.CALL_GROUP || nodeType == RingQtModels.IndividualTimelineModel.RECORDINGS ) return callDelegate } sourceComponent: selectDelegate() } } delegate: messageDelegate } diff --git a/src/timeline/qml/groupfooter.qml b/src/jamichatview/qml/groupfooter.qml similarity index 100% rename from src/timeline/qml/groupfooter.qml rename to src/jamichatview/qml/groupfooter.qml diff --git a/src/timeline/qml/groupheader.qml b/src/jamichatview/qml/groupheader.qml similarity index 100% rename from src/timeline/qml/groupheader.qml rename to src/jamichatview/qml/groupheader.qml diff --git a/src/timeline/qml/slideshow.qml b/src/jamichatview/qml/slideshow.qml similarity index 100% rename from src/timeline/qml/slideshow.qml rename to src/jamichatview/qml/slideshow.qml diff --git a/src/timeline/qml/snapshots.qml b/src/jamichatview/qml/snapshots.qml similarity index 96% rename from src/timeline/qml/snapshots.qml rename to src/jamichatview/qml/snapshots.qml index 4018d35f..73ac54e8 100644 --- a/src/timeline/qml/snapshots.qml +++ b/src/jamichatview/qml/snapshots.qml @@ -1,55 +1,55 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQml.Models 2.2 -import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline +import org.kde.ringkde.jamichatview 1.0 as JamiChatView Item { id: snapshots property QtObject model_: rootIndex.model property var rootIndex_: rootIndex signal viewImage(QtObject model, int index) height: Math.ceil(rowCount/4)*96 + 40 // 1 inch + margins - JamiTimeline.Thumbnail { + JamiChatView.Thumbnail { id: delegateModel rootIndex_: snapshots.rootIndex_ model_: snapshots.model_ onViewImage: { snapshots.viewImage(model, index, path) } } Rectangle { height: parent.height - 20 width: Math.min(4, rowCount)*96 + 40 anchors.centerIn: parent color: "transparent" radius: 10 border.color: activePalette.text border.width: 1 GridView { anchors.fill: parent anchors.margins: 10 model: delegateModel } } } diff --git a/src/timeline/qml/textbubble.qml b/src/jamichatview/qml/textbubble.qml similarity index 98% rename from src/timeline/qml/textbubble.qml rename to src/jamichatview/qml/textbubble.qml index 96bfe6b3..79ea895c 100644 --- a/src/timeline/qml/textbubble.qml +++ b/src/jamichatview/qml/textbubble.qml @@ -1,125 +1,126 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Layouts 1.2 import RingQmlWidgets 1.0 import QtGraphicalEffects 1.0 import org.kde.kirigami 2.2 as Kirigami import org.kde.ringkde.jamicontactview 1.0 as JamiContactView +import org.kde.ringkde.jamichatview 1.0 as JamiChatView Item { id: chatMessage width: parent.width property color background property color foreground property var cm: contactMethod signal clicked() height: bubble.height + 10 function getFactor() { return (height > (chatMessage.width*0.5)) ? 0.9 : 0.7 } // Prevent a binding loop. the "current" height isn't required anyway onWidthChanged: { bubble.maximumWidth = chatMessage.width*getFactor() } RowLayout { anchors.fill: parent JamiContactView.ContactPhoto { width: 50 height: 50 visible: direction == 0 drawEmptyOutline: false tracked: false contactMethod: chatMessage.cm Layout.alignment: Qt.AlignBottom Layout.bottomMargin: 20 } Item { Layout.fillWidth: true Layout.fillHeight: true - Bubble { + JamiChatView.Bubble { id: bubble anchors.margins: 5 anchors.right: direction == 1 ? parent.right : undefined anchors.left : direction == 1 ? undefined : parent.left font.pointSize: Kirigami.Theme.defaultFont.pointSize*1.2 font.family: "Noto Color Emoji" z: 1 alignment: direction == 1 ? Text.AlignRight : Text.AlignLeft color: background text: display != undefined ? display : "N/A" height: Math.max(50, label.implicitHeight + dateLabel.implicitHeight + 5) Text { id: label anchors.fill: parent anchors.leftMargin: 30 anchors.rightMargin: 30 anchors.topMargin: 5 anchors.bottomMargin: 5 horizontalAlignment: direction == 1 ? Text.AlignRight : Text.AlignLeft font: bubble.font text: display != undefined ? display : "N/A" color: foreground wrapMode: Text.WordWrap } Text { id: dateLabel anchors.bottom: parent.bottom anchors.left: direction == 1 ? parent.left : undefined anchors.right: direction == 0 ? parent.right : undefined anchors.bottomMargin: 4 anchors.leftMargin: direction == 1 ? 4 : undefined anchors.rightMargin: direction == 0 ? 4 : undefined text: formattedDate != undefined ? formattedDate : "N/A" color: "gray" } MouseArea { anchors.fill: parent onClicked: { chatMessage.clicked() } } } } JamiContactView.ContactPhoto { width: 50 height: 50 visible: direction == 1 drawEmptyOutline: false tracked: false contactMethod: chatMessage.cm Layout.alignment: Qt.AlignBottom Layout.bottomMargin: 20 } } } diff --git a/src/timeline/qml/textmessagegroup.qml b/src/jamichatview/qml/textmessagegroup.qml similarity index 93% rename from src/timeline/qml/textmessagegroup.qml rename to src/jamichatview/qml/textmessagegroup.qml index da08e118..740cfdf7 100644 --- a/src/timeline/qml/textmessagegroup.qml +++ b/src/jamichatview/qml/textmessagegroup.qml @@ -1,41 +1,41 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Layouts 1.0 -import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline +import org.kde.ringkde.jamichatview 1.0 as JamiChatView import RingQmlWidgets 1.0 Item { id: textGroupDelegate width: parent.width height: 50 - JamiTimeline.GroupHeader { + JamiChatView.GroupHeader { type: "text" anchors.margins: 4 height: 38 } - JamiTimeline.GroupFooter { + JamiChatView.GroupFooter { anchors.horizontalCenter: parent.horizontalCenter y: (parent.parent && parent.parent.parent && parent.parent.parent.height) ? parent.parent.parent.height - height : 0 } } diff --git a/src/timeline/qml/thumbnail.qml b/src/jamichatview/qml/thumbnail.qml similarity index 100% rename from src/timeline/qml/thumbnail.qml rename to src/jamichatview/qml/thumbnail.qml diff --git a/src/jamihistoryview/CMakeLists.txt b/src/jamihistoryview/CMakeLists.txt new file mode 100644 index 00000000..1c472278 --- /dev/null +++ b/src/jamihistoryview/CMakeLists.txt @@ -0,0 +1,119 @@ +cmake_minimum_required(VERSION 3.0) + +project(jamihistoryview) + +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(-DJAMIJAMIHISTORYVIEW_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( jamihistoryview_LIB_SRCS + plugin.cpp +) + +qt5_add_resources(jamihistoryview_LIB_SRCS + jamihistoryview.qrc +) + +set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.ringkde.jamihistoryview) + +add_library(jamihistoryview ${jamihistoryview_LIB_SRCS} ) + +target_link_libraries( jamihistoryview + # Project + ringqt + ringqtquick + + # Qt + Qt5::Core + Qt5::Gui + Qt5::Quick + Qt5::QuickControls2 +) + +# Configure the target config +set(jamihistoryview_CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/JamiHistoryViewConfig.cmake") + +if(USES_ADD_SUBDIRECTORY) + set(JamiHistoryView_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) +endif() + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/JamiHistoryViewConfig.cmake.in" ${jamihistoryview_CONFIG_PATH} + INSTALL_DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiHistoryView/ + PATH_VARS INCLUDE_INSTALL_DIR +) + +install( FILES ${jamihistoryview_CONFIG_PATH} + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiHistoryView/ + COMPONENT Devel +) + +# Create the target +target_include_directories(jamihistoryview + PUBLIC + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/ +) + +set_target_properties(jamihistoryview PROPERTIES + PUBLIC_HEADER + "${jamihistoryview_EXPORT_HDRS}" +) + +export(TARGETS jamihistoryview + FILE "${PROJECT_BINARY_DIR}/cmake/JamiHistoryViewTargets.cmake" +) + +install(TARGETS jamihistoryview + EXPORT JamiHistoryViewTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" COMPONENT jamihistoryview + ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + COMPONENT Devel +) + +install(EXPORT JamiHistoryViewTargets + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiHistoryView + COMPONENT Devel +) diff --git a/src/jamihistoryview/cmake/JamiHistoryViewConfig.cmake.in b/src/jamihistoryview/cmake/JamiHistoryViewConfig.cmake.in new file mode 100644 index 00000000..b2104222 --- /dev/null +++ b/src/jamihistoryview/cmake/JamiHistoryViewConfig.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(-DJAMIJAMIHISTORYVIEW_USE_STATIC_PLUGIN=1) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/JamiHistoryViewTargets.cmake") diff --git a/src/jamihistoryview/jamihistoryview.json b/src/jamihistoryview/jamihistoryview.json new file mode 100644 index 00000000..64660542 --- /dev/null +++ b/src/jamihistoryview/jamihistoryview.json @@ -0,0 +1,4 @@ +{ + "Keys": [ "org.kde.ringkde.jamihistoryview" ], + "uri": ["org.kde.ringkde.jamihistoryview"] +} diff --git a/src/jamihistoryview/jamihistoryview.qrc b/src/jamihistoryview/jamihistoryview.qrc new file mode 100644 index 00000000..14a77b9b --- /dev/null +++ b/src/jamihistoryview/jamihistoryview.qrc @@ -0,0 +1,7 @@ + + + qml/recordinghistory.qml + qml/callhistory.qml + qml/historytimeline.qml + + diff --git a/src/jamihistoryview/plugin.cpp b/src/jamihistoryview/plugin.cpp new file mode 100644 index 00000000..e3e09523 --- /dev/null +++ b/src/jamihistoryview/plugin.cpp @@ -0,0 +1,41 @@ +/************************************************************************************ + * 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 + +// QRC +#include + +void JamiHistoryView::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamihistoryview")); + + qmlRegisterType(QStringLiteral("qrc:/jamihistoryview/qml/callhistory.qml") , uri, 1, 0, "CallHistory"); + qmlRegisterType(QStringLiteral("qrc:/jamihistoryview/qml/historytimeline.qml") , uri, 1, 0, "HistoryTimeline"); + qmlRegisterType(QStringLiteral("qrc:/jamihistoryview/qml/recordinghistory.qml") , uri, 1, 0, "RecordingHistory"); +} + +void JamiHistoryView::initializeEngine(QQmlEngine *engine, const char *uri) +{ + Q_UNUSED(engine) + Q_UNUSED(uri) +} diff --git a/src/jamihistoryview/plugin.h b/src/jamihistoryview/plugin.h new file mode 100644 index 00000000..4a0edaaa --- /dev/null +++ b/src/jamihistoryview/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 JamiHistoryView final : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kde.ringkde.jamihistoryview" FILE "jamihistoryview.json") + +public: + void registerTypes(const char* uri) override; + virtual void initializeEngine(QQmlEngine* engine, const char* uri) override; +}; diff --git a/src/timeline/qml/callhistory.qml b/src/jamihistoryview/qml/callhistory.qml similarity index 96% rename from src/timeline/qml/callhistory.qml rename to src/jamihistoryview/qml/callhistory.qml index 4ebb6e67..bf8a175c 100644 --- a/src/timeline/qml/callhistory.qml +++ b/src/jamihistoryview/qml/callhistory.qml @@ -1,181 +1,182 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import QtGraphicalEffects 1.0 -import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline +import org.kde.ringkde.jamitimelinebase 1.0 as JamiTimelineBase +import org.kde.ringkde.jamihistoryview 1.0 as JamiHistoryView import RingQmlWidgets 1.0 Rectangle { id: timelinePage property bool showScrollbar: true function focusEdit() { chatBox.focusEdit() } function setContactMethod() { if (currentIndividual && !currentContactMethod) { currentContactMethod = currentIndividual.preferredContactMethod(Media.TEXT) if (!currentContactMethod) console.log("Cannot find a valid ContactMethod for", currentIndividual) } return currentContactMethod } onCurrentIndividualChanged: { currentContactMethod = null setContactMethod() } SystemPalette { id: activePalette colorGroup: SystemPalette.Active } color: activePalette.base property var currentContactMethod: null property var currentIndividual: null property var timelineModel: null property bool canSendTexts: currentIndividual ? currentIndividual.canSendTexts : false onTimelineModelChanged: { if (!fixmeTimer.running) chatView.model = timelineModel } // Add a blurry background ShaderEffectSource { id: effectSource visible: false sourceItem: chatView anchors.right: timelinePage.right anchors.top: timelinePage.top width: scrollbar.fullWidth + 15 height: chatView.height sourceRect: Qt.rect( burryOverlay.x, burryOverlay.y, burryOverlay.width, burryOverlay.height ) } ColumnLayout { anchors.fill: parent clip: true RowLayout { id: chatScrollView Layout.fillHeight: true Layout.fillWidth: true property bool lock: false Item { Layout.fillHeight: true Layout.fillWidth: true - JamiTimeline.RecordingHistory { + JamiHistoryView.RecordingHistory { id: chatView anchors.horizontalCenter: parent.horizontalCenter width: parent.width*0.66 height: parent.height model: null//FIXME timelinePage.timelineModel // Due to a race condition, wait a bit, it should be fixed elsewhere, //FIXME but it would take much longer. Timer { id: fixmeTimer repeat: false running: true interval: 33 onTriggered: { chatView.model = timelinePage.timelineModel } } } // It needs to be here due to z-index conflicts between // chatScrollView and timelinePage Item { id: burryOverlay z: 2 visible: false opacity: 0 anchors.right: parent.right anchors.top: parent.top anchors.rightMargin: - 15 width: scrollbar.fullWidth + 15 height: chatView.height clip: true Behavior on opacity { NumberAnimation {duration: 300; easing.type: Easing.InQuad} } Repeater { anchors.fill: parent model: 5 FastBlur { anchors.fill: parent source: effectSource radius: 30 } } Rectangle { anchors.fill: parent color: activePalette.base opacity: 0.75 } } } - JamiTimeline.TimelineScrollbar { + JamiTimelineBase.Scrollbar { id: scrollbar z: 1000 bottomUp: true Layout.fillHeight: true Layout.preferredWidth: 10 display: chatView.moving || timelinePage.showScrollbar model: timelinePage.timelineModel view: chatView onWidthChanged: { burryOverlay.width = scrollbar.fullWidth + 15 } onOverlayVisibleChanged: { burryOverlay.visible = overlayVisible burryOverlay.opacity = overlayVisible ? 1 : 0 effectSource.visible = overlayVisible } } } } } diff --git a/src/timeline/qml/historytimeline.qml b/src/jamihistoryview/qml/historytimeline.qml similarity index 100% rename from src/timeline/qml/historytimeline.qml rename to src/jamihistoryview/qml/historytimeline.qml diff --git a/src/timeline/qml/recordinghistory.qml b/src/jamihistoryview/qml/recordinghistory.qml similarity index 98% rename from src/timeline/qml/recordinghistory.qml rename to src/jamihistoryview/qml/recordinghistory.qml index 0d57996d..69bcca77 100644 --- a/src/timeline/qml/recordinghistory.qml +++ b/src/jamihistoryview/qml/recordinghistory.qml @@ -1,434 +1,436 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import org.kde.playground.kquickitemviews 1.0 as KQuickItemViews import net.lvindustries.ringqtquick 1.0 as RingQtQuick import net.lvindustries.ringqtquick.models 1.0 as RingQtModels import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline +import org.kde.ringkde.jamitimelinebase 1.0 as JamiTimelineBase +import org.kde.ringkde.jamiaudioplayer 1.0 as JamiAudioPlayer import RingQmlWidgets 1.0 KQuickItemViews.TreeView { id: chatView clip: true property var treeHelper: _treeHelper SystemPalette { id: activePalette colorGroup: SystemPalette.Active } TreeHelper { id: _treeHelper } // Display something when the chat is empty Text { color: activePalette.text text: i18n("There is nothing yet, enter a message below or place a call using the buttons\nfound in the header") anchors.centerIn: parent visible: chatView.empty horizontalAlignment: Text.AlignHCenter } Component { id: messageDelegate Loader { id: chatLoader property bool showDetailed: false // Create a delegate for each type Component { id: sectionDelegate Item { height: content.implicitHeight + 10 width: parent.width Rectangle { width: 1 color: inactivePalette.text height: parent.height x: 10 } Rectangle { radius: 99 color: activePalette.base border.width: 1 border.color: inactivePalette.text width: 16 height: 16 y: 10 x: 3 // (16 - 10) / 2 Rectangle { id: demandsAttention radius: 99 color: inactivePalette.text anchors.centerIn: parent height: 8 width: 8 } } Rectangle { border.color: inactivePalette.text border.width: 1 anchors.fill: parent anchors.topMargin: 5 anchors.bottomMargin: 5 anchors.leftMargin: 30 anchors.rightMargin: 40 color: "transparent" radius: 10 ColumnLayout { id: content anchors.fill: parent Row { Layout.preferredHeight: 2*fontMetrics.height Image { height: parent.height width: parent.height asynchronous: true anchors.margins: 6 source: "image://icon/dialog-messages" } Text { height: parent.height text: formattedDate leftPadding: 10 verticalAlignment: Text.AlignVCenter color: ListView.isCurrentItem ? activePalette.highlightedText : activePalette.text } } Rectangle { color: inactivePalette.text height:1 Layout.preferredHeight: 1 Layout.fillWidth: true } Text { Layout.fillWidth: true text: incomingEntryCount + i18n(" incoming messages") Layout.preferredHeight: 2*fontMetrics.height leftPadding: 10 verticalAlignment: Text.AlignVCenter color: ListView.isCurrentItem ? activePalette.highlightedText : activePalette.text } Text { Layout.fillWidth: true text: outgoingEntryCount + i18n(" outgoing messages") Layout.preferredHeight: 2*fontMetrics.height leftPadding: 10 verticalAlignment: Text.AlignVCenter color: ListView.isCurrentItem ? activePalette.highlightedText : activePalette.text } Item { Layout.fillHeight: true } } } MouseArea { anchors.fill: parent onClicked: { treeView.currentIndex = index } } } } Component { id: callDelegate Item { height: content.implicitHeight + 10 width: parent.width Behavior on height { NumberAnimation {duration: 200; easing.type: Easing.OutQuad} } Rectangle { width: 1 color: inactivePalette.text height: parent.height x: 10 } Rectangle { radius: 99 color: activePalette.base border.width: 1 border.color: inactivePalette.text width: 16 height: 16 y: 10 x: 3 // (16 - 10) / 2 Rectangle { id: demandsAttention radius: 99 color: inactivePalette.text anchors.centerIn: parent height: 8 width: 8 } } Rectangle { border.color: inactivePalette.text border.width: 1 anchors.fill: parent anchors.topMargin: 5 anchors.bottomMargin: 5 anchors.leftMargin: 30 anchors.rightMargin: 40 color: "transparent" radius: 10 ColumnLayout { id: content anchors.fill: parent Row { Layout.preferredHeight: 2*fontMetrics.height Image { height: parent.height width: parent.height asynchronous: true anchors.margins: 6 source: "image://icon/call-start" } Text { height: parent.height text: formattedDate leftPadding: 10 verticalAlignment: Text.AlignVCenter color: ListView.isCurrentItem ? activePalette.highlightedText : activePalette.text } } Rectangle { color: inactivePalette.text height:1 Layout.preferredHeight: 1 Layout.fillWidth: true } - MultiCall { + JamiTimelineBase.MultiCall { width: chatView.width - 90 modelIndex: rootIndex count: callCount MouseArea { anchors.fill: parent onClicked: { chatLoader.showDetailed = true chatView.reloadChildren(rootIndex) } } } } } } } Component { id: categoryDelegate Item { height: rect.height JamiTimeline.PeersTimelineCategories { id: rect property var section: display property var recentDate: formattedDate } } } Component { id: singleCallDelegate RowLayout { width: parent.width Text { text: formattedDate color: activePalette.text Layout.fillWidth: true } Item { height: 1 Layout.fillWidth: true } Text { text: length color: inactivePalette.text } } } Component { id: recordingDelegate Item { height: content.implicitHeight + 10 width: parent.width Rectangle { width: 1 color: inactivePalette.text height: parent.height x: 10 } Rectangle { radius: 99 color: activePalette.base border.width: 1 border.color: inactivePalette.text width: 16 height: 16 y: 10 x: 3 // (16 - 10) / 2 Rectangle { id: demandsAttention radius: 99 color: inactivePalette.text anchors.centerIn: parent height: 8 width: 8 } } Rectangle { id: box border.color: inactivePalette.text border.width: 1 anchors.fill: parent anchors.topMargin: 5 anchors.bottomMargin: 5 anchors.leftMargin: 30 anchors.rightMargin: 40 color: "transparent" radius: 10 ColumnLayout { id: content anchors.fill: parent Row { Layout.preferredHeight: 2*fontMetrics.height Image { height: parent.height width: parent.height asynchronous: true anchors.margins: 6 source: "image://icon/media-record" } Text { height: parent.height text: formattedDate leftPadding: 10 verticalAlignment: Text.AlignVCenter color: ListView.isCurrentItem ? activePalette.highlightedText : activePalette.text } } Rectangle { color: inactivePalette.text height:1 Layout.preferredHeight: 1 Layout.fillWidth: true } - JamiTimeline.AudioPlayer { + JamiAudioPlayer.AudioPlayer { id: rect Layout.minimumWidth: box.width - 10 } Item { Layout.fillHeight: true } } } } } // Some elements don't have delegates because they are handled // by their parent delegates function selectDelegate() { if (nodeType == RingQtModels.IndividualTimelineModel.TIME_CATEGORY) return categoryDelegate if (nodeType == RingQtModels.IndividualTimelineModel.SECTION_DELIMITER) return sectionDelegate if (nodeType == RingQtModels.IndividualTimelineModel.CALL_GROUP) return callDelegate if (nodeType == RingQtModels.IndividualTimelineModel.RECORDINGS) return recordingDelegate if (nodeType == RingQtModels.IndividualTimelineModel.CALL_GROUP) return callDelegate if (nodeType == RingQtModels.IndividualTimelineModel.CALL && chatView.parentTreeItem(rootIndex).showDetailed) return singleCallDelegate } sourceComponent: selectDelegate() } } delegate: messageDelegate } diff --git a/src/jamitimelinebase/CMakeLists.txt b/src/jamitimelinebase/CMakeLists.txt new file mode 100644 index 00000000..ce16a706 --- /dev/null +++ b/src/jamitimelinebase/CMakeLists.txt @@ -0,0 +1,121 @@ +cmake_minimum_required(VERSION 3.0) + +project(jamitimelinebase) + +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(-DJAMIJAMITIMELINEBASE_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( jamitimelinebase_LIB_SRCS + plugin.cpp + multicall.cpp + timelinedots.cpp +) + +qt5_add_resources(jamitimelinebase_LIB_SRCS + jamitimelinebase.qrc +) + +set(AUTOMOC_MOC_OPTIONS -Muri=org.kde.ringkde.jamitimelinebase) + +add_library(jamitimelinebase ${jamitimelinebase_LIB_SRCS} ) + +target_link_libraries( jamitimelinebase + # Project + ringqt + ringqtquick + + # Qt + Qt5::Core + Qt5::Gui + Qt5::Quick + Qt5::QuickControls2 +) + +# Configure the target config +set(jamitimelinebase_CONFIG_PATH "${CMAKE_CURRENT_BINARY_DIR}/JamiTimelineBaseConfig.cmake") + +if(USES_ADD_SUBDIRECTORY) + set(JamiTimelineBase_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) +endif() + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/JamiTimelineBaseConfig.cmake.in" ${jamitimelinebase_CONFIG_PATH} + INSTALL_DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiTimelineBase/ + PATH_VARS INCLUDE_INSTALL_DIR +) + +install( FILES ${jamitimelinebase_CONFIG_PATH} + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiTimelineBase/ + COMPONENT Devel +) + +# Create the target +target_include_directories(jamitimelinebase + PUBLIC + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/ +) + +set_target_properties(jamitimelinebase PROPERTIES + PUBLIC_HEADER + "${jamitimelinebase_EXPORT_HDRS}" +) + +export(TARGETS jamitimelinebase + FILE "${PROJECT_BINARY_DIR}/cmake/JamiTimelineBaseTargets.cmake" +) + +install(TARGETS jamitimelinebase + EXPORT JamiTimelineBaseTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" COMPONENT jamitimelinebase + ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + COMPONENT Devel +) + +install(EXPORT JamiTimelineBaseTargets + DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/JamiTimelineBase + COMPONENT Devel +) diff --git a/src/jamitimelinebase/cmake/JamiTimelineBaseConfig.cmake.in b/src/jamitimelinebase/cmake/JamiTimelineBaseConfig.cmake.in new file mode 100644 index 00000000..cb311e3d --- /dev/null +++ b/src/jamitimelinebase/cmake/JamiTimelineBaseConfig.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(-DJAMIJAMITIMELINEBASE_USE_STATIC_PLUGIN=1) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/JamiTimelineBaseTargets.cmake") diff --git a/src/jamitimelinebase/jamitimelinebase.json b/src/jamitimelinebase/jamitimelinebase.json new file mode 100644 index 00000000..0b475027 --- /dev/null +++ b/src/jamitimelinebase/jamitimelinebase.json @@ -0,0 +1,4 @@ +{ + "Keys": [ "org.kde.ringkde.jamitimelinebase" ], + "uri": ["org.kde.ringkde.jamitimelinebase"] +} diff --git a/src/jamitimelinebase/jamitimelinebase.qrc b/src/jamitimelinebase/jamitimelinebase.qrc new file mode 100644 index 00000000..f2fb1587 --- /dev/null +++ b/src/jamitimelinebase/jamitimelinebase.qrc @@ -0,0 +1,5 @@ + + + qml/scrollbar.qml + + diff --git a/src/qmlwidgets/multicall.cpp b/src/jamitimelinebase/multicall.cpp similarity index 100% rename from src/qmlwidgets/multicall.cpp rename to src/jamitimelinebase/multicall.cpp diff --git a/src/qmlwidgets/multicall.h b/src/jamitimelinebase/multicall.h similarity index 100% rename from src/qmlwidgets/multicall.h rename to src/jamitimelinebase/multicall.h diff --git a/src/jamitimelinebase/plugin.cpp b/src/jamitimelinebase/plugin.cpp new file mode 100644 index 00000000..aca6dbfa --- /dev/null +++ b/src/jamitimelinebase/plugin.cpp @@ -0,0 +1,45 @@ +/************************************************************************************ + * 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 + +// QRC +#include + +// TimelineBase +#include "multicall.h" +#include "timelinedots.h" + +void JamiTimelineBase::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamitimelinebase")); + + qmlRegisterType(uri, 1, 0, "MultiCall"); + qmlRegisterType(uri, 1, 0, "TimelineDots"); + qmlRegisterType(QStringLiteral("qrc:/jamitimelinebase/qml/scrollbar.qml"), uri, 1, 0, "Scrollbar"); +} + +void JamiTimelineBase::initializeEngine(QQmlEngine *engine, const char *uri) +{ + Q_UNUSED(engine) + Q_UNUSED(uri) +} diff --git a/src/jamitimelinebase/plugin.h b/src/jamitimelinebase/plugin.h new file mode 100644 index 00000000..198e2426 --- /dev/null +++ b/src/jamitimelinebase/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 JamiTimelineBase final : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kde.ringkde.jamitimelinebase" FILE "jamitimelinebase.json") + +public: + void registerTypes(const char* uri) override; + virtual void initializeEngine(QQmlEngine* engine, const char* uri) override; +}; diff --git a/src/timeline/qml/timelinescrollbar.qml b/src/jamitimelinebase/qml/scrollbar.qml similarity index 98% rename from src/timeline/qml/timelinescrollbar.qml rename to src/jamitimelinebase/qml/scrollbar.qml index 452d8e61..4235a7f8 100644 --- a/src/timeline/qml/timelinescrollbar.qml +++ b/src/jamitimelinebase/qml/scrollbar.qml @@ -1,297 +1,298 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import RingQmlWidgets 1.0 import org.kde.kirigami 2.2 as Kirigami import org.kde.playground.kquickitemviews 1.0 as KQuickItemViews +import org.kde.ringkde.jamitimelinebase 1.0 as JamiTimelineBase KQuickItemViews.FlickableScrollBar { id: scrollbar property var tmlList: null property alias fullWidth: timelineOverlay.width property alias model: timelineOverlay.tlModel property bool bottomUp: false property bool display: true property alias hideTimeout: hideTimer.interval property bool overlayVisible: false visible: handleVisible // This isn't correct at all, but close enough for now function getSectionHeight(height, total, section, index, activeCategoryCount) { var h = (height-(activeCategoryCount*22)) * (section/total) // Align to the closest "hole" in the dotted bar var align = h%22 h += align > 22/2 ? (22 - align) : -align // The minimum height (22points) prevents the text from overlapping and // allow the list to look unified. return 22 + h } onPositionChanged: { if (!mouseArea.drag.active) { handle.y = position } } SystemPalette { id: inactivePalette colorGroup: SystemPalette.Disabled } SystemPalette { id: activePalette colorGroup: SystemPalette.Active } Timer { id: hideTimer running: false interval: 5000 repeat: false } onDisplayChanged: { if (!display) hideTimer.running = true } Rectangle { id: handle radius: 99 color: inactivePalette.text width: parent.width height: scrollbar.handleHeight visible: scrollbar.display || hideTimer.running || stateGroup.state == "overlay" onYChanged: { if (!tmlList) return if (mouseArea.drag.active) scrollbar.position = y // Keep a reference as this function is racy var oldItem = tmlList.currentItem var relH = scrollbar.height - height // Highlight the current index var point = bottomUp ? y + height : y var item = tmlList.itemAt(10, point) if ((!item) || item == oldItem) return tmlList.currentIndex = tmlList.indexAt(10, point) item.selected = true if (oldItem != undefined) oldItem.selected = false } } Component { id: category Item { width: parent.width property bool selected: false height: getSectionHeight(scrollbar.height, totalEntries, categoryEntries, index, activeCategories) RowLayout { width: parent.width anchors.top : bottomUp ? undefined : parent.top anchors.bottom: bottomUp ? parent.bottom : undefined height: 22 Rectangle { id: mainCircle y: 0 width: 16 height: 16 radius: 999 color: inactivePalette.highlight border.width: 1 border.color: activePalette.text Rectangle { id: smallCircle height: 8 width: 8 radius: 99 anchors.centerIn: parent color: activePalette.text Behavior on color { ColorAnimation {duration: 300} } } Behavior on border.color { ColorAnimation {duration: 300} } } Text { id: label Layout.fillWidth: true text: display color: activePalette.text font.pointSize: Kirigami.Theme.defaultFont.pointSize*1.2 Behavior on font.pointSize { NumberAnimation {duration: 150} } } } states: [ State { name: "" when: !selected PropertyChanges { target: label font.pointSize: Kirigami.Theme.defaultFont.pointSize*1.2 } }, State { name: "selected" when: selected PropertyChanges { target: mainCircle border.color: "#298223" } PropertyChanges { target: smallCircle color: "#298223" } PropertyChanges { target: label font.pointSize: Kirigami.Theme.defaultFont.pointSize*1.6 } } ] } } Component { id: panelComponent ListView { id: tmlList anchors.fill: parent delegate: category model: tlModel interactive: false Component.onCompleted: { scrollbar.tmlList = tmlList currentIndex = bottomUp ? count - 1 : 0 if (currentItem) currentItem.selected = true } - TimelineDots { + JamiTimelineBase.TimelineDots { height: parent.height width: 16 z: -1 } } } MouseArea { id: mouseArea anchors.fill: parent hoverEnabled: true onEntered: overlayVisible = true onExited: overlayVisible = drag.active drag.target: handle drag.axis: Drag.YAxis drag.minimumY: 0 drag.maximumY: scrollbar.height - handleHeight drag.onActiveChanged: { overlayVisible = drag.active } Loader { id: timelineOverlay property var tlModel: null active: false sourceComponent: panelComponent width: 150 x: -130 visible: false opacity: 0 } } StateGroup { id: stateGroup states: [ State { name: "overlay" when: scrollbar.overlayVisible PropertyChanges { target: timelineOverlay height: scrollbar.height visible: true opacity: 1 x: -150 } PropertyChanges { target: handle color: activePalette.highlight } } ] transitions: [ Transition { to: "overlay" NumberAnimation { properties: "opacity" target: timelineOverlay duration: 200 } NumberAnimation { properties: "x" target: timelineOverlay easing.type: Easing.InQuad duration: 200 } ColorAnimation { target: handle duration: 100 } } ] // Load the timeline only once onStateChanged: { if (state == "overlay") timelineOverlay.active = true } } } diff --git a/src/qmlwidgets/timelinedots.cpp b/src/jamitimelinebase/timelinedots.cpp similarity index 100% rename from src/qmlwidgets/timelinedots.cpp rename to src/jamitimelinebase/timelinedots.cpp diff --git a/src/qmlwidgets/timelinedots.h b/src/jamitimelinebase/timelinedots.h similarity index 100% rename from src/qmlwidgets/timelinedots.h rename to src/jamitimelinebase/timelinedots.h diff --git a/src/main.cpp b/src/main.cpp index 36ee2504..c7fed1ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,306 +1,366 @@ /*************************************************************************** * 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 #ifdef JAMIVIDEOVIEW_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiVideoView) #else #include #endif #ifdef JAMITROUBLESHOOTING_USE_STATIC_PLUGIN Q_IMPORT_PLUGIN(JamiTroubleshooting) #else #include #endif +#ifdef JAMICHATVIEW_USE_STATIC_PLUGIN +Q_IMPORT_PLUGIN(JamiChatView) +#else +#include +#endif + +#ifdef JAMIHISTORYVIEW_USE_STATIC_PLUGIN +Q_IMPORT_PLUGIN(JamiHistoryView) +#else +#include +#endif + +#ifdef JAMITIMELINEBASE_USE_STATIC_PLUGIN +Q_IMPORT_PLUGIN(JamiTimelineBase) +#else +#include +#endif + +#ifdef JAMIAUDIOPLAYER_USE_STATIC_PLUGIN +Q_IMPORT_PLUGIN(JamiAudioPlayer) +#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.jamitimeline"); qobject_cast(qt_static_plugin_JamiTimelineView().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamitimeline"); #else JamiTimelineView v8; v8.registerTypes("org.kde.ringkde.jamitimeline"); v8.initializeEngine(app.engine(), "org.kde.ringkde.jamitimeline"); #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 #ifdef JAMIVIDEOVIEW_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiNotification().instance())->registerTypes("org.kde.ringkde.jamivideoview"); qobject_cast(qt_static_plugin_JamiNotification().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamivideoview"); #else JamiVideoView v12; v12.registerTypes("org.kde.ringkde.jamivideoview"); v12.initializeEngine(app.engine(), "org.kde.ringkde.jamivideoview"); #endif #ifdef JAMITROUBLESHOOTING_USE_STATIC_PLUGIN qobject_cast(qt_static_plugin_JamiTroubleshooting().instance())->registerTypes("org.kde.ringkde.jamitroubleshooting"); qobject_cast(qt_static_plugin_JamiTroubleshooting().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamitroubleshooting"); #else JamiTroubleshooting v13; v13.registerTypes("org.kde.ringkde.jamitroubleshooting"); v13.initializeEngine(app.engine(), "org.kde.ringkde.jamitroubleshooting"); #endif +#ifdef JAMITIMELINEBASE_USE_STATIC_PLUGIN + qobject_cast(qt_static_plugin_JamiTimelineBase().instance())->registerTypes("org.kde.ringkde.jamitimelinebase"); + qobject_cast(qt_static_plugin_JamiTimelineBase().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamitimelinebase"); +#else + JamiTimelineBase v14; + v14.registerTypes("org.kde.ringkde.jamitimelinebase"); + v14.initializeEngine(app.engine(), "org.kde.ringkde.jamitimelinebase"); +#endif + +#ifdef JAMIHISTORYVIEW_USE_STATIC_PLUGIN + qobject_cast(qt_static_plugin_JamiHistoryView().instance())->registerTypes("org.kde.ringkde.jamihistoryview"); + qobject_cast(qt_static_plugin_JamiHistoryView().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamihistoryview"); +#else + JamiHistoryView v15; + v15.registerTypes("org.kde.ringkde.jamihistoryview"); + v15.initializeEngine(app.engine(), "org.kde.ringkde.jamihistoryview"); +#endif + +#ifdef JAMICHATVIEW_USE_STATIC_PLUGIN + qobject_cast(qt_static_plugin_JamiChatView().instance())->registerTypes("org.kde.ringkde.jamichatview"); + qobject_cast(qt_static_plugin_JamiChatView().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamichatview"); +#else + JamiChatView v16; + v16.registerTypes("org.kde.ringkde.jamichatview"); + v16.initializeEngine(app.engine(), "org.kde.ringkde.jamichatview"); +#endif + +#ifdef JAMIAUDIOPLAYER_USE_STATIC_PLUGIN + qobject_cast(qt_static_plugin_JamiAudioPlayer().instance())->registerTypes("org.kde.ringkde.jamiaudioplayer"); + qobject_cast(qt_static_plugin_JamiAudioPlayer().instance())->initializeEngine(app.engine(), "org.kde.ringkde.jamiaudioplayer"); +#else + JamiAudioPlayer v17; + v17.registerTypes("org.kde.ringkde.jamiaudioplayer"); + v17.initializeEngine(app.engine(), "org.kde.ringkde.jamiaudioplayer"); +#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/qmlwidgets/CMakeLists.txt b/src/qmlwidgets/CMakeLists.txt index 6cc7506e..09439e70 100644 --- a/src/qmlwidgets/CMakeLists.txt +++ b/src/qmlwidgets/CMakeLists.txt @@ -1,80 +1,76 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.0) ADD_DEFINITIONS("-std=c++11") PROJECT(libqmlwidgets) IF(POLICY CMP0063) CMAKE_POLICY(SET CMP0063 NEW) ENDIF(POLICY CMP0063) FIND_PACKAGE(ECM 1.1.0 REQUIRED NO_MODULE) INCLUDE(ECMInstallIcons) INCLUDE(ECMOptionalAddSubdirectory) INCLUDE(KDEInstallDirs) INCLUDE(KDECMakeSettings) INCLUDE(KDECompilerSettings) SET(CMAKE_AUTOMOC ON) SET(CMAKE_AUTORCC ON) SET(CMAKE_AUTOUIC ON) FIND_PACKAGE ( LibRingQt QUIET ) FIND_PACKAGE(Qt5 CONFIG REQUIRED Core Gui Quick QuickWidgets QuickControls2 ) FIND_PACKAGE(KF5 REQUIRED COMPONENTS I18n Config ConfigWidgets ) INCLUDE_DIRECTORIES(SYSTEM ${Qt5Widgets_INCLUDES} ${Qt5Core_INCLUDES} ${ringqt_INCLUDE_DIR}) ADD_DEFINITIONS(${Qt5Core_DEFINITIONS}) SET(GENERIC_LIB_VERSION "1.0.0") #File to compile SET( libqmlwidgets_LIB_SRCS - bubble.cpp plugin.cpp treehelper.cpp - multicall.cpp - timelinedots.cpp symboliccolorizer.cpp ) QT5_ADD_RESOURCES(libqmlwidgets_LIB_SRCS qmlwidgets.qrc ) ADD_LIBRARY( libqmlwidgets STATIC ${libqmlwidgets_LIB_SRCS} ) target_link_libraries( libqmlwidgets ringqt Qt5::Core Qt5::Gui Qt5::Quick Qt5::QuickControls2 KF5::ConfigCore KF5::ConfigGui KF5::ConfigWidgets KF5::XmlGui ) SET( libqmlwidgets_LIB_HDRS - bubble.h plugin.h ) diff --git a/src/qmlwidgets/plugin.cpp b/src/qmlwidgets/plugin.cpp index bdaa1ac6..2a0b9709 100644 --- a/src/qmlwidgets/plugin.cpp +++ b/src/qmlwidgets/plugin.cpp @@ -1,42 +1,37 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ #include "plugin.h" #include #include +#include -#include "bubble.h" #include "treehelper.h" -#include "multicall.h" -#include "timelinedots.h" #include "qrc_qmlwidgets.cpp" void RingQmlWidgets::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("RingQmlWidgets")); qmlRegisterType(uri, 1, 0, "QAction"); - qmlRegisterType(uri, 1, 0, "Bubble"); - qmlRegisterType(uri, 1, 0, "MultiCall"); qmlRegisterType(uri, 1, 0, "TreeHelper"); - qmlRegisterType(uri, 1, 0, "TimelineDots"); qmlRegisterType(QStringLiteral("qrc:/OutlineButton.qml"), uri, 1, 0, "OutlineButton"); qmlRegisterType(QStringLiteral("qrc:/OutlineButtons.qml"), uri, 1, 0, "OutlineButtons"); } diff --git a/src/timeline/qml/historycallicon.qml b/src/timeline/qml/historycallicon.qml deleted file mode 100644 index 9f54cc80..00000000 --- a/src/timeline/qml/historycallicon.qml +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2017 by Bluesystems * - * Author : 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 . * - **************************************************************************/ -import QtQuick 2.7 -import QtQuick.Controls 2.0 -import QtQuick.Layouts 1.0 - -import net.lvindustries.ringqtquick 1.0 as RingQtQuick - -Item { - width: 30 - height: 30 - Image { - function selectIcon(isMissed, direction) { - if (isMissed && direction == RingQtQuick.Call.INCOMING) - return "sharedassets/phone_dark/missed_incoming.svg" - else if (isMissed && direction == RingQtQuick.Call.OUTGOING) - return "sharedassets/phone_dark/missed_outgoing.svg" - else if (direction == RingQtQuick.Call.INCOMING) - return "sharedassets/phone_dark/incoming.svg" - else - return "sharedassets/phone_dark/outgoing.svg" - } - - source: selectIcon(object.missed, object.direction) - asynchronous: true - Layout.fillHeight: true - width: 30 - height: 30 - } -} diff --git a/src/timeline/qml/peerstimeline.qml b/src/timeline/qml/peerstimeline.qml index 9aed09dd..66b6101f 100644 --- a/src/timeline/qml/peerstimeline.qml +++ b/src/timeline/qml/peerstimeline.qml @@ -1,312 +1,313 @@ /*************************************************************************** * Copyright (C) 2017 by Bluesystems * * Author : 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 . * **************************************************************************/ import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.0 import QtGraphicalEffects 1.0 import org.kde.kirigami 2.2 as Kirigami import org.kde.playground.kquickitemviews 1.0 as KQuickItemViews import net.lvindustries.ringqtquick 1.0 as RingQtQuick import org.kde.ringkde.jamitimeline 1.0 as JamiTimeline import org.kde.ringkde.jamicontactview 1.0 as JamiContactView import org.kde.ringkde.jamitroubleshooting 1.0 as JamiTroubleShooting +import org.kde.ringkde.jamitimelinebase 1.0 as JamiTimelineBase import RingQmlWidgets 1.0 Rectangle { SystemPalette { id: activePalette colorGroup: SystemPalette.Active } SystemPalette { id: inactivePalette colorGroup: SystemPalette.Disabled } color: activePalette.base id: recentDock visible: true property alias overlayVisible: scrollBar.overlayVisible signal contactMethodSelected(var cm) signal individualSelected(var ind) signal contextMenuRequested(var cm, int index) function setCurrentIndex(index) { recentView.setCurrentIndex(index) } FontMetrics { id: fontMetrics } Component { id: contactDelegate JamiTimeline.ContactMethodDelegate {} } Component { id: sectionDelegate JamiTimeline.PeersTimelineCategories {} } Component { id: noRegisteredAccounts JamiTroubleShooting.AccountError { Component.onCompleted: { implicitHeight = height + 20 accountError.height = height + 20 } } } Component { id: noEnabledAccounts JamiTroubleShooting.AccountDisabled { Component.onCompleted: { implicitHeight = height accountError.height = height } } } Component { id: noAccounts JamiTroubleShooting.NoAccount { Component.onCompleted: { implicitHeight = height accountError.height = height } } } Component { id: pendingContactRequests JamiContactView.ViewContactRequests { Component.onCompleted: { implicitHeight = height accountError.height = height } } } property bool displayNoAccount: RingSession.accountModel.size == 0 property bool displayDisabled: !RingSession.accountModel.hasEnabledAccounts property bool displayNoRegAccounts: !RingSession.accountModel.hasAvailableAccounts property bool displayContactRequests: RingSession.accountModel.incomingContactRequestModel.size > 0 property bool displayActionHeader: displayNoAccount || displayNoRegAccounts || displayDisabled || displayContactRequests Item { anchors.fill: parent Text { visible: recentView.empty anchors.centerIn: parent width: parent.width anchors.margins: 10 wrapMode: Text.WordWrap color: activePalette.text text: i18n("To begin using Ring-KDE, enter an username in the box above and press enter") } Loader { id: accountError active: displayActionHeader width: parent.width -20 - scrollBar.width x: 10 y: 10 height: item ? item.implicitHeight : 0 sourceComponent: displayNoAccount ? noAccounts : ( displayDisabled ? noEnabledAccounts : ( displayNoRegAccounts ? noRegisteredAccounts : pendingContactRequests )) } KQuickItemViews.ListView { id: recentView clip: true anchors.fill: parent anchors.topMargin: (!accountError.active) ? 0 : accountError.height + 20 delegate: contactDelegate section.delegate: sectionDelegate section.property: "formattedLastUsed" // indexedLastUsed section.model: RingSession.peersTimelineModel.timelineSummaryModel highlight: Item { anchors.topMargin: 5 anchors.bottomMargin: 5 anchors.leftMargin: 30 anchors.rightMargin: 40 Rectangle { anchors.fill: parent anchors.topMargin: 5 anchors.bottomMargin: 5 anchors.leftMargin: 30 anchors.rightMargin: 40 radius: 10 color: activePalette.highlight } } model: KQuickItemViews.SizeHintProxyModel { id: proxyModel /*invalidationRoles: [ "object", "unreadTextMessageCount", "isRecording", "hasActiveVideo", ]*/ constants: ({ fmh: fontMetrics.height, fmh2: fontMetrics.height, }) function getRowCount(obj) { var activeCM = obj ? obj.activeContactMethod : null return 2 + ((obj != null) && (obj.hasActiveCall || obj.unreadTextMessageCount > 0 || (activeCM && activeCM.isRecording) || (activeCM && activeCM.hasActiveVideo) ) ? 1 : 0) } widthHint: recentView.width heightHint: (proxyModel.getRowCount(object)*2+1)*fmh + 13 sourceModel: RingSession.peersTimelineModel } } - JamiTimeline.TimelineScrollbar { + JamiTimelineBase.Scrollbar { id: scrollBar height: parent.height anchors.top: parent.top anchors.right: parent.right width: 10 model: RingSession.peersTimelineModel.timelineSummaryModel z: 100 display: recentView.moving || recentDock.state == "" view: recentView onWidthChanged: { burryOverlay.width = scrollBar.fullWidth + 15 } } // Add a blurry background ShaderEffectSource { id: effectSource visible: false sourceItem: recentView anchors.right: recentView.right anchors.top: recentView.top width: scrollBar.fullWidth + 15 height: recentView.height sourceRect: Qt.rect( parent.width - scrollBar.fullWidth - 15, 0, scrollBar.fullWidth + 15, recentView.height ) } Item { id: burryOverlay visible: false opacity: 0 anchors.right: recentView.right anchors.top: recentView.top width: scrollBar.fullWidth + 15 height: recentView.height clip: true Repeater { anchors.fill: parent model: 5 FastBlur { anchors.fill: parent source: effectSource radius: 30 } } Rectangle { anchors.fill: parent color: inactivePalette.highlight opacity: 0.75 } } } // Timeline scrollbar StateGroup { states: [ State { name: "overlay" when: scrollBar.overlayVisible PropertyChanges { target: burryOverlay visible: true } PropertyChanges { target: burryOverlay opacity: 1 } PropertyChanges { target: effectSource visible: true } } ] transitions: [ Transition { to: "overlay" NumberAnimation { properties: "opacity" easing.type: Easing.InQuad duration: 400 loops: 1 } } ] } states: [ State { name: "" }, State { name: "mobile" } ] } diff --git a/src/timeline/recentdock.qrc b/src/timeline/recentdock.qrc index 5610deee..15975b2e 100644 --- a/src/timeline/recentdock.qrc +++ b/src/timeline/recentdock.qrc @@ -1,36 +1,16 @@ qml/peerstimeline.qml - qml/historytimeline.qml - qml/contactdialog.qml - qml/callhistory.qml - qml/recordinghistory.qml - qml/audioplayer.qml - qml/chatbox.qml - qml/chatview.qml - qml/timelinepage.qml - qml/timelinescrollbar.qml - qml/textbubble.qml - qml/categoryheader.qml - qml/textmessagegroup.qml - qml/callgroup.qml - qml/groupheader.qml - qml/groupfooter.qml qml/contactmethoddelegate.qml qml/peerstimelinecategories.qml - qml/addresses.qml qml/searchdelegate.qml qml/findpeers.qml - qml/snapshots.qml - qml/slideshow.qml - qml/thumbnail.qml - qml/historycallicon.qml qml/firstrun.qml qml/searchtip.qml qml/searchbox.qml qml/searchoverlay.qml icons/bookmarked.svg icons/not_bookmarked.svg - assets/welcome.html + diff --git a/src/timeline/timelineplugin.cpp b/src/timeline/timelineplugin.cpp index eecb0755..61c5ad48 100644 --- a/src/timeline/timelineplugin.cpp +++ b/src/timeline/timelineplugin.cpp @@ -1,66 +1,47 @@ /************************************************************************************ * 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 "timelineplugin.h" // Qt #include // QRC #include void JamiTimelineView::registerTypes(const char *uri) { Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamitimeline")); + qmlRegisterType(QStringLiteral("qrc:/qml/firstrun.qml") , uri, 1, 0, "FirstRun"); + qmlRegisterType(QStringLiteral("qrc:/qml/searchtip.qml") , uri, 1, 0, "SearchTip"); + qmlRegisterType(QStringLiteral("qrc:/qml/searchbox.qml") , uri, 1, 0, "SearchBox"); + qmlRegisterType(QStringLiteral("qrc:/qml/searchoverlay.qml") , uri, 1, 0, "SearchOverlay"); qmlRegisterType(QStringLiteral("qrc:/qml/peerstimeline.qml") , uri, 1, 0, "PeersTimeline"); - qmlRegisterType(QStringLiteral("qrc:/qml/historytimeline.qml") , uri, 1, 0, "HistoryTimeline"); - qmlRegisterType(QStringLiteral("qrc:/qml/contactdialog.qml") , uri, 1, 0, "ContactDialog"); - qmlRegisterType(QStringLiteral("qrc:/qml/callhistory.qml") , uri, 1, 0, "CallHistory"); - qmlRegisterType(QStringLiteral("qrc:/qml/recordinghistory.qml") , uri, 1, 0, "RecordingHistory"); - qmlRegisterType(QStringLiteral("qrc:/qml/audioplayer.qml") , uri, 1, 0, "AudioPlayer"); - qmlRegisterType(QStringLiteral("qrc:/qml/chatbox.qml") , uri, 1, 0, "ChatBox"); - qmlRegisterType(QStringLiteral("qrc:/qml/chatview.qml") , uri, 1, 0, "ChatView"); + qmlRegisterType(QStringLiteral("qrc:/qml/findpeers.qml") , uri, 1, 0, "FindPeers"); qmlRegisterType(QStringLiteral("qrc:/qml/timelinepage.qml") , uri, 1, 0, "TimelinePage"); - qmlRegisterType(QStringLiteral("qrc:/qml/timelinescrollbar.qml") , uri, 1, 0, "TimelineScrollbar"); - qmlRegisterType(QStringLiteral("qrc:/qml/textbubble.qml") , uri, 1, 0, "TextBubble"); - qmlRegisterType(QStringLiteral("qrc:/qml/categoryheader.qml") , uri, 1, 0, "CategoryHeader"); - qmlRegisterType(QStringLiteral("qrc:/qml/textmessagegroup.qml") , uri, 1, 0, "TextMessageGroup"); - qmlRegisterType(QStringLiteral("qrc:/qml/callgroup.qml") , uri, 1, 0, "CallGroup"); - qmlRegisterType(QStringLiteral("qrc:/qml/groupheader.qml") , uri, 1, 0, "GroupHeader"); - qmlRegisterType(QStringLiteral("qrc:/qml/groupfooter.qml") , uri, 1, 0, "GroupFooter"); qmlRegisterType(QStringLiteral("qrc:/qml/contactmethoddelegate.qml") , uri, 1, 0, "ContactMethodDelegate"); qmlRegisterType(QStringLiteral("qrc:/qml/peerstimelinecategories.qml") , uri, 1, 0, "PeersTimelineCategories"); - qmlRegisterType(QStringLiteral("qrc:/qml/addresses.qml") , uri, 1, 0, "Addresses"); qmlRegisterType(QStringLiteral("qrc:/qml/searchdelegate.qml") , uri, 1, 0, "SearchDelegate"); - qmlRegisterType(QStringLiteral("qrc:/qml/findpeers.qml") , uri, 1, 0, "FindPeers"); - qmlRegisterType(QStringLiteral("qrc:/qml/snapshots.qml") , uri, 1, 0, "Snapshots"); - qmlRegisterType(QStringLiteral("qrc:/qml/slideshow.qml") , uri, 1, 0, "Slideshow"); - qmlRegisterType(QStringLiteral("qrc:/qml/thumbnail.qml") , uri, 1, 0, "Thumbnail"); - qmlRegisterType(QStringLiteral("qrc:/qml/historycallicon.qml") , uri, 1, 0, "HistoryCallIcon"); - qmlRegisterType(QStringLiteral("qrc:/qml/firstrun.qml") , uri, 1, 0, "FirstRun"); - qmlRegisterType(QStringLiteral("qrc:/qml/searchtip.qml") , uri, 1, 0, "SearchTip"); - qmlRegisterType(QStringLiteral("qrc:/qml/searchbox.qml") , uri, 1, 0, "SearchBox"); - qmlRegisterType(QStringLiteral("qrc:/qml/searchoverlay.qml") , uri, 1, 0, "SearchOverlay"); } void JamiTimelineView::initializeEngine(QQmlEngine *engine, const char *uri) { Q_UNUSED(engine) Q_UNUSED(uri) }