diff --git a/src/callview/callview.qrc b/src/callview/callview.qrc index 1ebc799e..c05822b8 100644 --- a/src/callview/callview.qrc +++ b/src/callview/callview.qrc @@ -1,17 +1,16 @@ - - qml/callview.qml - qml/videowidget.qml - qml/actiontoolbar.qml - qml/videocontroltoolbar.qml - qml/callbackground.qml - qml/devicesetting.qml - qml/videosource.qml - qml/canvaspopup.qml - qml/screensharing.qml - qml/streaming.qml - qml/cmselector.qml - qml/troubleshoot.qml - qml/recordingicon.qml + + qml/callview.qml + qml/videowidget.qml + qml/videocontroltoolbar.qml + qml/callbackground.qml + qml/devicesetting.qml + qml/videosource.qml + qml/canvaspopup.qml + qml/screensharing.qml + qml/streaming.qml + qml/cmselector.qml + qml/troubleshoot.qml + qml/recordingicon.qml diff --git a/src/callview/callviewplugin.cpp b/src/callview/callviewplugin.cpp index a16cbe78..ecebee34 100644 --- a/src/callview/callviewplugin.cpp +++ b/src/callview/callviewplugin.cpp @@ -1,49 +1,62 @@ /************************************************************************************ * 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 "callviewplugin.h" // Qt #include #include #include // QRC #include // CallView #include "snapshotadapter.h" #include "imageprovider.h" void JamiCallViewPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamicallview")); qmlRegisterType(uri, 1, 0, "SnapshotAdapter"); -// qmlRegisterType(QStringLiteral("qrc:/ButtonBar.qml"), uri, 1, 0, "ButtonBar"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/callview.qml"), uri, 1, 0, "CallView"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/videowidget.qml"), uri, 1, 0, "VideoWidget"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/videocontroltoolbar.qml"), uri, 1, 0, "VideoControlToolbar"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/callbackground.qml"), uri, 1, 0, "CallBackground"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/devicesetting.qml"), uri, 1, 0, "DeviceSetting"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/videosource.qml"), uri, 1, 0, "VideoSource"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/canvaspopup.qml"), uri, 1, 0, "CanvasPopup"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/screensharing.qml"), uri, 1, 0, "ScreenSharing"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/streaming.qml"), uri, 1, 0, "Streaming"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/cmselector.qml"), uri, 1, 0, "CMSelector"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/troubleshoot.qml"), uri, 1, 0, "Troubleshoot"); + qmlRegisterType(QStringLiteral("qrc:/callview/qml/recordingicon.qml"), uri, 1, 0, "RecordingIcon"); + + } void JamiCallViewPlugin::initializeEngine(QQmlEngine *engine, const char *uri) { Q_UNUSED(engine) Q_UNUSED(uri) static ImageProvider p; engine->addImageProvider( QStringLiteral("VideoFrame"), &p ); } diff --git a/src/callview/qml/callbackground.qml b/src/callview/qml/callbackground.qml index 2d591689..2f07ac74 100644 --- a/src/callview/qml/callbackground.qml +++ b/src/callview/qml/callbackground.qml @@ -1,198 +1,200 @@ /*************************************************************************** * 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 RingQmlWidgets 1.0 import net.lvindustries.ringqtquick 1.0 as RingQtQuick +import org.kde.ringkde.jamicanvasindicator 1.0 as JamiCanvasIndicator +import org.kde.ringkde.jamicallview 1.0 as JamiCallView Rectangle { property QtObject call: null; property string mode: "PREVIEW" property alias toubleshooting: troubleshootDispatcher property real bottomMargin: 0 id: placeholderMessage color: "black" Text { id: defaultText color: "white" text: i18n("[No video]") anchors.centerIn: parent visible: false } - Troubleshoot { + JamiCallView.Troubleshoot { id: troubleshootDispatcher call: placeholderMessage.call anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top anchors.topMargin: 5 z: 100000 } - NewCall { + JamiCanvasIndicator.NewCall { id: newCall visible: false anchors.centerIn: parent } - Ringing { + JamiCanvasIndicator.Ringing { id: ringingIndicator anchors.centerIn: parent running: false visible: false } - Searching { + JamiCanvasIndicator.Searching { id: searchingIndicator anchors.centerIn: parent visible: false running: false } - Progress { + JamiCanvasIndicator.Progress { id: progresIndicator anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom anchors.margins: 5 visible: false anchors.bottomMargin: bottomMargin > 0 ? bottomMargin : undefined transitions: Transition { AnchorAnimation { duration: 300 } } } Rectangle { id: callEnded radius: 5 color: "white" width: 100 height: 30 visible: false anchors.centerIn: parent Text { color: "black" text: i18n("Call Ended") anchors.centerIn: parent } } onCallChanged: { if (call && (call.state == RingQtQuick.Call.RINGING || call.state == 1 /*Call.INCOMING*/)) callStateGroup.state = "RINGING" else if (call && (call.state == RingQtQuick.Call.CONNECTED || call.state == 14 /*Call.INITIALIZATION*/)) callStateGroup.state = "CONNECTED" else callStateGroup.state = "DEFAULT" lifecycleStateGroup.state = "INITIALIZATION" progresIndicator.call = call } Timer { id: clearNotifications interval: 3000 running: false repeat: false onTriggered: { if (call.lifeCycleState == RingQtQuick.Call.FINISHED) call = null } } StateGroup { id: callStateGroup states: [ State { name: "DEFAULT" when: !call PropertyChanges { target: defaultText visible: mode == "PREVIEW" } PropertyChanges { target: newCall visible: mode != "PREVIEW" && !troubleshootDispatcher.isActive } }, State { name: "RINGING" when: call && (call.state == RingQtQuick.Call.RINGING || call.state == 1 /*Call.INCOMING*/) PropertyChanges { target: ringingIndicator visible: true running: true } }, State { name: "CONNECTED" when: call && (call.state == RingQtQuick.Call.CONNECTED || call.state == 14 /*Call.INITIALIZATION*/) PropertyChanges { target: searchingIndicator visible: true running: true } }, State { name: "ENDED" when: call.lifeCycleState == RingQtQuick.Call.FINISHED PropertyChanges { target: callEnded visible: true } PropertyChanges { target: clearNotifications running: true } } ] } StateGroup { id: lifecycleStateGroup states: [ State { name: "CREATION" when: call.lifeCycleState == RingQtQuick.Call.CREATION PropertyChanges { target: progresIndicator visible: true } }, State { name: "INITIALIZATION" when: call.lifeCycleState == RingQtQuick.Call.INITIALIZATION PropertyChanges { target: progresIndicator visible: true } }, State { name: "PROGRESS" when: call.lifeCycleState == RingQtQuick.Call.PROGRESS }, State { name: "FINISHED" when: (!call) || call.lifeCycleState == RingQtQuick.Call.FINISHED } ] } } diff --git a/src/callview/qml/callview.qml b/src/callview/qml/callview.qml index 0f067d06..5e03ddd8 100644 --- a/src/callview/qml/callview.qml +++ b/src/callview/qml/callview.qml @@ -1,281 +1,283 @@ /*************************************************************************** * 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 net.lvindustries.ringqtquick 1.0 as RingQtQuick +import org.kde.ringkde.jamicallview 1.0 as JamiCallView +import org.kde.ringkde.jamidialview 1.0 as JamiDialView Item { id: videoDock signal callWithVideo () signal callWithAudio () signal callWithScreen() height: 480 width: 640 // C++ bindings property alias rendererName : videoWidget.rendererName property bool displayPreview : false property string mode : "PREVIEW" property bool previewRunning : false property alias peerRunning : videoWidget.started property QtObject call : null property QtObject renderer : call ? call.renderer : null property bool previewVisible: mode != "PREVIEW" && call && RingSession.previewManager.previewing Connections { target: renderer onDestroyed: { videoWidget.started = false } } // Let the animations finish before Timer { id: toolbarTimer running: false interval: 150 repeat: false onTriggered: { actionToolbar.visible = false videoSource.visible = false controlToolbar.visible = false } } function showToolbars() { actionToolbar.visible = true videoSource.visible = true // This toolbar is only useful when there is video if (videoWidget.started) controlToolbar.visible = true actionToolbar.opacity = 1 videoSource.opacity = 1 controlToolbar.opacity = 1 videoPreview.opacity = 0.8 actionToolbar.anchors.bottomMargin = 0 videoSource.anchors.rightMargin = 0 controlToolbar.anchors.topMargin = 0 } function hideToolbars() { actionToolbar.opacity = 0 videoSource.opacity = 0 controlToolbar.opacity = 0 videoPreview.opacity = 1 videoSource.anchors.rightMargin = -20 actionToolbar.anchors.bottomMargin = -20 controlToolbar.anchors.topMargin = -20 toolbarTimer.running = true } - VideoWidget { + JamiCallView.VideoWidget { id: videoWidget anchors.fill: parent z: -100 started: false visible: started && !hasFailed call: videoDock.call } - VideoWidget { + JamiCallView.VideoWidget { id: videoPreview z: -95 started: false visible: previewVisible anchors.right: parent.right anchors.bottom: parent.bottom width: 192 height: 108 } - VideoControlToolbar { + JamiCallView.VideoControlToolbar { id: controlToolbar anchors.top: parent.top visible: false Behavior on opacity { NumberAnimation {duration: 100} } Behavior on anchors.topMargin { NumberAnimation {duration: 150} } } - ActionToolbar { + JamiDialView.ActionToolbar { id: actionToolbar anchors.bottom: parent.bottom visible: false Behavior on opacity { NumberAnimation {duration: 100} } Behavior on anchors.bottomMargin { NumberAnimation {duration: 150} } } - RecordingIcon { + JamiCallView.RecordingIcon { anchors.right: videoDock.right anchors.top: controlToolbar.bottom } - DeviceSetting { + JamiCallView.DeviceSetting { id: deviceSettings visible: mode == "PREVIEW" width: parent.width z: 100 Rectangle { anchors.fill: parent color: "black" opacity: 0.5 z: -1 } } - VideoSource { + JamiCallView.VideoSource { id: videoSource z: 101 visible: false anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter Behavior on opacity { NumberAnimation {duration: 100} } Behavior on anchors.rightMargin { NumberAnimation {duration: 150} } } // The background - CallBackground { + JamiCallView.CallBackground { id: placeholderMessage z: -99 anchors.fill: parent bottomMargin: actionToolbar.visible ? actionToolbar.height : 0 } // Hide both toolbars when the mouse isn't moving //TODO keep visible if the mouse if over the toolbars MouseArea { id: mainMouseArea Timer { id: activityTimer interval: 3000 running: true repeat: false onTriggered: { hideToolbars() } } function trackActivity() { if (mode == "PREVIEW") { deviceSettings.visible = true } else if (call) { showToolbars() } activityTimer.restart() } anchors.fill: parent hoverEnabled: true propagateComposedEvents: true onMouseXChanged: trackActivity() onMouseYChanged: trackActivity() } onModeChanged: { if (mode == "PREVIEW") { hideToolbars() videoWidget.rendererName = "preview" } else if (mode == "CONVERSATION") { videoPreview.started = RingSession.previewManager.previewing videoWidget.rendererName = "peer" } placeholderMessage.mode = mode } onCallChanged: { if (call) { actionToolbar.userActionModel = call.userActionModel placeholderMessage.call = call videoSource.call = call controlToolbar.call = call } videoWidget.hasFailed = false mainMouseArea.visible = call != null || mode == "PREVIEW" } Connections { target: RingSession.previewManager onPreviewingChanged: { if (mode == "PREVIEW") videoWidget.started = RingSession.previewManager.previewing videoPreview.started = RingSession.previewManager.previewing } } Connections { target: call } Connections { target: call onVideoStarted: { videoWidget.started = true } onVideoStopped: { videoWidget.started = false } onLiveMediaIssuesChanaged: { // This isn't using properties because the renderer live in their // own thread and QML doesn't support this yet videoWidget.hasFailed = call.hasIssue(RingQtQuick.Call.VIDEO_ACQUISITION_FAILED) } } Connections { target: videoWidget onStartedChanged: { placeholderMessage.visible = (!videoWidget.started) || (videoWidget.hasFailed) } onHasFailedChanged: { placeholderMessage.visible = (!videoWidget.started) || (videoWidget.hasFailed) } } Connections { target: call onStateChanged: { if (call == null || call.lifeCycleState == RingQtQuick.Call.FINISHED) { call = null hideToolbars() } } } } diff --git a/src/callview/qml/videosource.qml b/src/callview/qml/videosource.qml index 240c1c52..6e5d5345 100644 --- a/src/callview/qml/videosource.qml +++ b/src/callview/qml/videosource.qml @@ -1,224 +1,225 @@ /*************************************************************************** * 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.0 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.0 import org.kde.playground.kquickitemviews 1.0 as KQuickItemViews import net.lvindustries.ringqtquick.video.models 1.0 as RingQtVideoModel +import org.kde.ringkde.jamicallview 1.0 as JamiCallView Item { property QtObject call: null property int current: -1 id: videoSource width: 50 height: elements.implicitHeight // Camera popup - CanvasPopup { + JamiCallView.CanvasPopup { id: sourcePopup parent: videoSource.parent width: 400 height: 400 x: videoSource.parent.width - width - 50 y: 50 title: "Camera settings" contentItem: Component { ColumnLayout { anchors.fill: parent - DeviceSetting { + JamiCallView.DeviceSetting { id: deviceSettings Layout.fillHeight: true Layout.fillWidth: true } Item { Layout.fillWidth: true height: applyButton.height Button { id: applyButton text: i18n("Apply") anchors.right: parent.right onClicked: { if (!videoSource.call) return videoSource.call.sourceModel.switchTo( videoSource.current ) } } } } } } // Screen sharing popup - CanvasPopup { + JamiCallView.CanvasPopup { id: screenPopup parent: videoSource.parent width: 400 height: 400 x: videoSource.parent.width - width - 50 y: 50 title: "Screen sharing" contentItem: Component { - ScreenSharing { + JamiCallView.ScreenSharing { id: deviceSettings call: videoSource.call anchors.fill: parent } } } // Streaming popup - CanvasPopup { + JamiCallView.CanvasPopup { id: filePopup parent: videoSource.parent width: 400 height: 400 x: videoSource.parent.width - width - 50 y: 50 title: "Camera settings" contentItem: Component { - Streaming { + JamiCallView.Streaming { id: deviceSettings call: videoSource.call anchors.fill: parent } } } // Use a separate label. This allows to use only icons in the buttons, // this reducing the footprint and avoiding a second row. Rectangle { id: currentText clip: true color: "#333333" height: 20 width: 200 radius: 99 // circle visible: false anchors.verticalCenter: parent.verticalCenter anchors.right: parent.left anchors.margins: 5 Text { id: currentTextText anchors.fill: parent color: "white" font.bold : true horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter onContentWidthChanged: parent.width = contentWidth + 20 onContentHeightChanged: parent.height = contentHeight + 10 } Behavior on width { NumberAnimation {duration: 50} } } onCallChanged: { devices.model = call ? call.sourceModel : null } Connections { target: call onMediaAdded: { devices.model = call.sourceModel } } MouseArea { anchors.fill: parent hoverEnabled: true ColumnLayout { id: elements anchors.fill: parent Component { id: deviceDelegate Rectangle { id: backgroundRect width: 50 height: 50 radius: 99 color: "#CC222222" border.width: mouseArea.containsMouse ? 3 : 0 border.color: "#dd5555" KQuickItemViews.DecorationAdapter { anchors.fill: parent anchors.margins: 10 pixmap: decoration } MouseArea { id: mouseArea anchors.fill: parent hoverEnabled: true onContainsMouseChanged: { if (containsMouse) { currentTextText.text = display } backgroundRect.color = containsMouse ? "#CC333333" : "#CC222222" } onClicked: { videoSource.current = index switch(index) { case RingQtVideoModel.SourceModel.NONE: videoSource.call.sourceModel.switchTo(0) return case RingQtVideoModel.SourceModel.SCREEN: screenPopup.show() return case RingQtVideoModel.SourceModel.FILE: filePopup.show() return } sourcePopup.show() } } Behavior on color { ColorAnimation {duration: 300} } Behavior on border.width { NumberAnimation {duration: 200} } } } Repeater { id: devices delegate: deviceDelegate model: videoSource.call ? videoSource.call.sourceModel : null } } onContainsMouseChanged: { currentText.visible = containsMouse } } } diff --git a/src/canvasindicators/canvasindicator.cpp b/src/canvasindicators/canvasindicator.cpp index 86cc9198..1a12dcfe 100644 --- a/src/canvasindicators/canvasindicator.cpp +++ b/src/canvasindicators/canvasindicator.cpp @@ -1,42 +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 "canvasindicator.h" // Qt #include #include #include // QRC #include #include "ringingimageprovider.h" void JamiCanvasIndicator::registerTypes(const char *uri) { Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamicanvasindicator")); + + qmlRegisterType(QStringLiteral("qrc:/canvasassets/qml/ringing.qml"), uri, 1, 0, "Ringing" ); + qmlRegisterType(QStringLiteral("qrc:/canvasassets/qml/searching.qml"), uri, 1, 0, "Searching"); + qmlRegisterType(QStringLiteral("qrc:/canvasassets/qml/progress.qml"), uri, 1, 0, "Progress" ); + qmlRegisterType(QStringLiteral("qrc:/canvasassets/qml/newcall.qml"), uri, 1, 0, "NewCall" ); } void JamiCanvasIndicator::initializeEngine(QQmlEngine *engine, const char *uri) { Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamicanvasindicator")); static RingingImageProvider im; engine->addImageProvider( QStringLiteral("RingingImageProvider"), &im ); } diff --git a/src/canvasindicators/canvasindicator.qrc b/src/canvasindicators/canvasindicator.qrc index 1f5dcf49..f691ccee 100644 --- a/src/canvasindicators/canvasindicator.qrc +++ b/src/canvasindicators/canvasindicator.qrc @@ -1,14 +1,14 @@ - - qml/ringing.qml - qml/searching.qml - qml/progress.qml - qml/newcall.qml + + qml/ringing.qml + qml/searching.qml + qml/progress.qml + qml/newcall.qml - icons/phoneDown.svg - icons/ring3.svg - icons/ring2.svg - icons/ring1.svg - icons/searching.svg + icons/phoneDown.svg + icons/ring3.svg + icons/ring2.svg + icons/ring1.svg + icons/searching.svg diff --git a/src/desktopview/qml/dockbar.qml b/src/desktopview/qml/dockbar.qml index 4cda23ec..a4d3a20f 100644 --- a/src/desktopview/qml/dockbar.qml +++ b/src/desktopview/qml/dockbar.qml @@ -1,292 +1,292 @@ /*************************************************************************** * 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.jamicontactview 1.0 as JamiContactView +import org.kde.ringkde.jamidialview 1.0 as JamiDialView 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 PeersTimeline { anchors.fill: parent state: "" onIndividualSelected: { mainPage.setIndividual(ind) } } } Component { id: dialViewComponent - DialView { + JamiDialView.DialView { anchors.fill: parent onSelectCall: { mainPage.showVideo(call) } } } Component { id: contactViewComponent ContactList { anchors.fill: parent onIndividualSelected: { mainPage.setIndividual(ind) } } } Component { id: bookmarkViewComponent BookmarkList { anchors.fill: parent onContactMethodSelected: { mainPage.setContactMethod(cm) } } } Component { id: historyViewComponent 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() } } } } SearchOverlay { id: searchView source: parent anchors.fill: parent onContactMethodSelected: { mainPage.setContactMethod(cm) setCurrentIndex(RingSession.peersTimelineModel.individualIndex(cm.individual)) } } } diff --git a/src/dialview/dialview.qrc b/src/dialview/dialview.qrc index 3d5c0d10..7fddd6a9 100644 --- a/src/dialview/dialview.qrc +++ b/src/dialview/dialview.qrc @@ -1,17 +1,19 @@ - - qml/dialview.qml - qml/dialpad.qml - qml/calllist.qml - qml/calldelegate.qml - qml/calldelegateitem.qml - qml/addcall.qml - qml/mergecall.qml - qml/callerror.qml - qml/missedcall.qml - qml/outgoingcall.qml - qml/incomingcall.qml - qml/finishedcall.qml - qml/currentcall.qml + + qml/dialview.qml + qml/dialpad.qml + qml/calllist.qml + qml/calldelegate.qml + qml/calldelegateitem.qml + qml/addcall.qml + qml/mergecall.qml + qml/callerror.qml + qml/missedcall.qml + qml/outgoingcall.qml + qml/incomingcall.qml + qml/finishedcall.qml + qml/currentcall.qml + qml/completiondelegate.qml + qml/actiontoolbar.qml diff --git a/src/dialview/dialviewplugin.cpp b/src/dialview/dialviewplugin.cpp index 8ec7ec46..a3bb95ff 100644 --- a/src/dialview/dialviewplugin.cpp +++ b/src/dialview/dialviewplugin.cpp @@ -1,37 +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 "dialviewplugin.h" // Qt #include #include // QRC #include void JamiDialView::registerTypes(const char *uri) { Q_ASSERT(uri == QByteArray("org.kde.ringkde.jamidialview")); + + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/dialview.qml"), uri, 1, 0, "DialView" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/dialpad.qml"), uri, 1, 0, "DialPad" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/calllist.qml"), uri, 1, 0, "CallList" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/calldelegate.qml"), uri, 1, 0, "CallDelegate" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/calldelegateitem.qml"), uri, 1, 0, "CallDelegateItem"); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/addcall.qml"), uri, 1, 0, "AddCall" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/mergecall.qml"), uri, 1, 0, "MergeCall" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/callerror.qml"), uri, 1, 0, "CallError" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/missedcall.qml"), uri, 1, 0, "MissedCall" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/outgoingcall.qml"), uri, 1, 0, "OutgoingCall" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/incomingcall.qml"), uri, 1, 0, "IncomingCall" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/finishedcall.qml"), uri, 1, 0, "FinishedCall" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/currentcall.qml"), uri, 1, 0, "CurrentCall" ); + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/completiondelegate.qml"), uri, 1, 0, "CompletionDelegate"); + + qmlRegisterType(QStringLiteral("qrc:/dialview/qml/actiontoolbar.qml"), uri, 1, 0, "ActionToolbar"); } void JamiDialView::initializeEngine(QQmlEngine *engine, const char *uri) { Q_UNUSED(engine) Q_UNUSED(uri) } diff --git a/src/callview/qml/actiontoolbar.qml b/src/dialview/qml/actiontoolbar.qml similarity index 100% rename from src/callview/qml/actiontoolbar.qml rename to src/dialview/qml/actiontoolbar.qml diff --git a/src/dialview/qml/calldelegate.qml b/src/dialview/qml/calldelegate.qml index 9fd1a4f4..aebc84a9 100644 --- a/src/dialview/qml/calldelegate.qml +++ b/src/dialview/qml/calldelegate.qml @@ -1,118 +1,119 @@ /****************************************************************************** * Copyright (C) 2012 by Savoir-Faire Linux * * 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 Lesser GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ import QtQuick 2.0 import org.kde.playground.kquickitemviews 1.0 as KQuickItemViews import net.lvindustries.ringqtquick 1.0 as RingQtQuick +import org.kde.ringkde.jamidialview 1.0 as JamiDialView Item { id: item height: callDelegateItem.visible ? callDelegateItem.height : confDelegateLayout.height + 40 + 12 width: parent.width - 10 x: 5 property bool selected: object == RingSession.callModel.selectedCall //If it is not a conference, use this delegate - CallDelegateItem { + JamiDialView.CallDelegateItem { id: callDelegateItem //Geometry width: parent.width anchors.margins: 2 } Rectangle { id: confDelegateItem //Geometry anchors.topMargin: 10 anchors.margins: 2 anchors.fill: parent visible: false y: 10 //Display color: item.selected ? activePalette.highlight: "transparent" radius: 5 border.color: inactivePalette.text border.width: 2 Component { id:confItemDelegate - CallDelegateItem { + JamiDialView.CallDelegateItem { width: isConference ? item.width - 40 : item.width - 20 } } Row { y:parent.y x:parent.x spacing: 4 height: 20 width: parent.width KQuickItemViews.DecorationAdapter { pixmap: decoration height: 20 width: 20 } Text { text: i18n("Conference") font.bold: true font.underline: true color: activePalette.text } MouseArea { anchors.fill: parent propagateComposedEvents: true onClicked: { RingSession.callModel.selectedCall = object } } } Column { id: confDelegateLayout y:30 width: parent.width - 20 x: 10 //anchors.fill: parent anchors.margins: 2 spacing: 4 Repeater { id:confDelegateRepeater model:VisualDataModel { id:confDelegateVisualDataModel } } } } //Conference delegate Component.onCompleted: { if (isConference == true) { callDelegateItem.visible = false confDelegateItem.visible = true confDelegateVisualDataModel.model = RingSession.callModel confDelegateVisualDataModel.delegate = confItemDelegate confDelegateRepeater.model.rootIndex = confDelegateRepeater.model.modelIndex(index) } } } diff --git a/src/dialview/qml/calldelegateitem.qml b/src/dialview/qml/calldelegateitem.qml index c473d281..51f6f661 100644 --- a/src/dialview/qml/calldelegateitem.qml +++ b/src/dialview/qml/calldelegateitem.qml @@ -1,453 +1,453 @@ /****************************************************************************** * Copyright (C) 2012 by Savoir-Faire Linux * * 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 Lesser GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ import QtQuick 2.0 import QtQuick.Layouts 1.0 import RingQmlWidgets 1.0 import org.kde.kirigami 2.2 as Kirigami import net.lvindustries.ringqtquick 1.0 as RingQtQuick import org.kde.ringkde.jamicontactview 1.0 as JamiContactView -import org.kde.ringkde.jamicontactview 1.0 as JamiContactView +import org.kde.ringkde.jamidialview 1.0 as JamiDialView Rectangle { id: callDelegateItem anchors.margins: 2 radius: 5 border.width: 0 color: selected ? activePalette.highlight: "transparent" height: content.implicitHeight + 20 + errorMessage.height property bool selected: object == RingSession.callModel.selectedCall property bool skipSelect: errorMessage.active || missedMessage.active property var labelColor: callDelegateItem.selected && !skipSelect ? activePalette.highlightedText : activePalette.text Drag.active: mouseArea.drag.active Drag.dragType: Drag.Automatic Drag.onDragStarted: { var ret = treeHelper.mimeData(model.rootIndex, index) Drag.mimeData = ret } Behavior on height { NumberAnimation {duration: 200; easing.type: Easing.OutQuad } } TreeHelper { id: treeHelper model: RingSession.callModel } Drag.onDragFinished: { if (dropAction == Qt.MoveAction) { item.display = "hello" } } OutlineButton { id: closeButton label: " "+i18n("Close") anchors.right: parent.right anchors.top: parent.top anchors.margins: 3 height: 24 visible: false z: 100 alignment: Qt.AlignRight property string colString: selected && !skipSelect ? activePalette.highlightedText.toString(16) : activePalette.text.toString(16) color: colString icon: "image://SymbolicColorizer/?color="+colString+";:/sharedassets/outline/close.svg" onClicked: { object.performAction(RingQtQuick.Call.REFUSE) } } RowLayout { id: content spacing: 10 width: parent.width - 4 JamiContactView.ContactPhoto { contactMethod: object.peerContactMethod height:40 width:40 drawEmptyOutline: false defaultColor: labelColor anchors.verticalCenter: parent.verticalCenter } Column { Layout.fillWidth: true Text { text: display width: parent.width wrapMode: Text.WrapAnywhere color: labelColor font.bold: true } Text { text: model.number width: parent.width wrapMode: Text.WrapAnywhere color: labelColor } } } DropArea { anchors.fill: parent keys: ["text/ring.call.id", "text/plain"] onEntered: { callDelegateItem.color = "red" } onExited: { callDelegateItem.color = "blue" } onDropped: { var formats = drop.formats var ret = {} ret["x-ring/dropaction"] = "join" // stupid lack of official APIs... for(var i=0; i< formats.length; i++) { ret[formats[i]] = drop.getDataAsArrayBuffer(formats[i]) } treeHelper.dropMimeData2(ret, model.rootIndex, index) } } MouseArea { id: mouseArea anchors.fill: parent propagateComposedEvents: true onClicked: { mouse.accepted = true RingSession.callModel.selectedCall = object dialView.selectCall(object) } drag.target: callDelegateItem } Loader { id: completionLoader active: false opacity: 0 anchors.bottom: parent.bottom anchors.bottomMargin: 10 width: callDelegateItem.width height: 0 Behavior on height { NumberAnimation {duration: 200; easing.type: Easing.OutQuad } } Behavior on opacity { NumberAnimation {duration: 200; easing.type: Easing.OutQuad } } sourceComponent: Component { ListView { clip: true anchors.fill: parent anchors.margins: 10 spacing: 10 model: RingSession.numberCompletionModel currentIndex: completionSelection.currentIndex delegate: Rectangle { property bool selected: ListView.isCurrentItem height: searchDelegate.height width: callDelegateItem.width - 20 color: selected ? activePalette.highlightedText : "transparent" border.width: 1 border.color: activePalette.highlightedText radius: 5 clip: true - CompletionDelegate { + JamiDialView.CompletionDelegate { id: searchDelegate showPhoto: false showControls: false showSeparator: false labelHeight: fontMetrics.height } } onCountChanged: { completionLoader.height = Math.min(4, count)*(3*fontMetrics.height+12) callDelegateItem.height = content.implicitHeight + Math.min(4, count)*(3*fontMetrics.height+10) + 10 } } } } Loader { id: errorMessage anchors.top: content.bottom active: false width: parent.width height: active ? item.implicitHeight : 0 sourceComponent: Component { - CallError { + JamiDialView.CallError { call: object width: errorMessage.width } } } Loader { id: outgoingMessage anchors.top: content.bottom active: false width: parent.width height: active ? item.implicitHeight : 0 sourceComponent: Component { - OutgoingCall { + JamiDialView.OutgoingCall { call: object width: outgoingMessage.width } } } Loader { id: finishedMessage anchors.top: content.bottom active: false width: parent.width height: active ? item.implicitHeight : 0 sourceComponent: Component { - FinishedCall { + JamiDialView.FinishedCall { call: object width: finishedMessage.width } } } Loader { id: currentMessage anchors.top: content.bottom active: false width: parent.width height: active ? item.implicitHeight : 0 sourceComponent: Component { - CurrentCall { + JamiDialView.CurrentCall { call: object width: currentMessage.width } } } Loader { id: missedMessage active: false width: parent.width height: active ? item.implicitHeight : 0 sourceComponent: Component { - MissedCall { + JamiDialView.MissedCall { call: object width: missedMessage.width } } } Loader { id: rigningAnimation active: false width: parent.width height: active ? 32 : 0 anchors.top: content.bottom anchors.horizontalCenter: parent.horizontalCenter sourceComponent: Component { - IncomingCall { + JamiDialView.IncomingCall { //call: object width: rigningAnimation.width } } } StateGroup { id: stateGroup states: [ State { name: "" PropertyChanges { target: callDelegateItem border.width: 0 } }, State { name: "dialing" when: selected && object.state == RingQtQuick.Call.DIALING PropertyChanges { target: callDelegateItem border.width: 0 height: content.implicitHeight + Math.min(4, count)*(3*fontMetrics.height+10) + 10 } PropertyChanges { target: completionLoader active: true opacity: 1 height: Math.min(4, count)*(3*fontMetrics.height+10) + 10 } PropertyChanges { target: closeButton visible: false } }, State { name: "error" when: lifeCycleState == RingQtQuick.Call.FINISHED && object.state != RingQtQuick.Call.OVER && object.state != RingQtQuick.Call.ABORTED PropertyChanges { target: errorMessage active: true } PropertyChanges { target: callDelegateItem color: "#33ff0000" border.width: 1 border.color: "#55ff0000" } PropertyChanges { target: closeButton visible: true } }, State { name: "missed" when: object.state == RingQtQuick.Call.OVER && object.missed PropertyChanges { target: missedMessage active: true } PropertyChanges { target: content visible: false } PropertyChanges { target: callDelegateItem height: missedMessage.height color: "#33ff0000" border.width: 1 border.color: "#55ff0000" } PropertyChanges { target: closeButton visible: true } }, State { name: "incoming" when: object.state == 1/*iNCOMING*/ PropertyChanges { target: callDelegateItem border.width: 0 height: rigningAnimation.height + content.implicitHeight + 3 } PropertyChanges { target: rigningAnimation active: true } PropertyChanges { target: closeButton visible: false } }, State { name: "outgoing" when: object.lifeCycleState == RingQtQuick.Call.INITIALIZATION && object.direction == 1/*OUTGOING*/ PropertyChanges { target: callDelegateItem border.width: 0 height: outgoingMessage.height + content.implicitHeight } PropertyChanges { target: outgoingMessage active: true } PropertyChanges { target: closeButton visible: false } }, State { name: "finished" when: object.state == RingQtQuick.Call.OVER PropertyChanges { target: callDelegateItem border.width: 0 height: finishedMessage.height + content.implicitHeight } PropertyChanges { target: finishedMessage active: true } PropertyChanges { target: closeButton visible: true } }, State { name: "current" when: object.lifeCycleState == RingQtQuick.Call.PROGRESS PropertyChanges { target: callDelegateItem border.width: 0 height: currentMessage.height + content.implicitHeight } PropertyChanges { target: currentMessage active: true } PropertyChanges { target: closeButton visible: false } } ] } } //Call delegate diff --git a/src/dialview/qml/calllist.qml b/src/dialview/qml/calllist.qml index 6c4c7bd7..feaccecf 100644 --- a/src/dialview/qml/calllist.qml +++ b/src/dialview/qml/calllist.qml @@ -1,36 +1,37 @@ /****************************************************************************** * Copyright (C) 2012 by Savoir-Faire Linux * * 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 Lesser GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ import QtQuick 2.0 import net.lvindustries.ringqtquick 1.0 as RingQtQuick +import org.kde.ringkde.jamidialview 1.0 as JamiDialView ListView { Component { id: callDelegate - CallDelegate {} + JamiDialView.CallDelegate {} } - header: MergeCall {} - footer: AddCall {} + header: JamiDialView.MergeCall {} + footer: JamiDialView.AddCall {} id: callList spacing: 10 delegate: callDelegate model: RingSession.callModel } //CallList diff --git a/src/timeline/qml/completiondelegate.qml b/src/dialview/qml/completiondelegate.qml similarity index 100% rename from src/timeline/qml/completiondelegate.qml rename to src/dialview/qml/completiondelegate.qml diff --git a/src/dialview/qml/dialview.qml b/src/dialview/qml/dialview.qml index 624c91e9..62cfb41f 100644 --- a/src/dialview/qml/dialview.qml +++ b/src/dialview/qml/dialview.qml @@ -1,196 +1,197 @@ /*************************************************************************** * 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.kirigami 2.2 as Kirigami import RingQmlWidgets 1.0 import net.lvindustries.ringqtquick 1.0 as RingQtQuick +import org.kde.ringkde.jamidialview 1.0 as JamiDialView FocusScope { id: dialView focus: true anchors.fill: parent signal selectCall(RingQtQuick.Call call) SystemPalette { id: inactivePalette colorGroup: SystemPalette.Disabled } SystemPalette { id: activePalette colorGroup: SystemPalette.Active } FontMetrics { id: fontMetrics } TreeHelper { id: completionSelection selectionModel: RingSession.numberCompletionModel.selectionModel } - CallList { + JamiDialView.CallList { anchors.fill: parent } - DialPad { + JamiDialView.DialPad { width: parent.width visible: RingSession.callModel.supportsDTMF height: 200 anchors.horizontalCenter: dialView.horizontalCenter anchors.bottom: actionToolbar.top anchors.bottomMargin: 50 } - ActionToolbar { + JamiDialView.ActionToolbar { id: actionToolbar width: parent.width anchors.bottom: parent.bottom } function selectPrevious(call) { if (call.state == RingQtQuick.Call.DIALING && completionSelection.selectPrevious()) return completionSelection.clearSelection() var idx = RingSession.callModel.getIndex(call) if (!idx.valid) return var directPrev = RingSession.callModel.index(idx.row-1, 0, idx.parent) var nextCall = RingSession.callModel.getCall(directPrev) if (!nextCall) return RingSession.callModel.selectedCall = nextCall dialView.selectCall(nextCall) } function selectNext(call) { if (call.state == RingQtQuick.Call.DIALING && completionSelection.selectNext()) return completionSelection.clearSelection() var idx = RingSession.callModel.getIndex(call) if (!idx.valid) return var directPrev = RingSession.callModel.index(idx.row+1, 0, idx.parent) var nextCall = RingSession.callModel.getCall(directPrev) if (!nextCall) return RingSession.callModel.selectedCall = nextCall dialView.selectCall(nextCall) } function performCall() { var call = RingSession.callModel.selectedCall if (!call) { call = RingSession.callModel.dialingCall() RingSession.callModel.selectedCall = call } // Apply the auto completion if (call.state == RingQtQuick.Call.DIALING && RingSession.numberCompletionModell.selectedContactMethod) call.peerContactMethod = RingSession.ompletionModel.selectedContactMethod call.performAction(RingQtQuick.Call.ACCEPT) } function getCall() { var call = RingSession.callModel.selectedCall if (!call) { call = RingSession.callModel.dialingCall() RingSession.callModel.selectedCall = call } return call } Keys.onPressed: { switch (event.key) { case Qt.Key_Up: selectPrevious(getCall()) break case Qt.Key_Down: selectNext(getCall()) break case Qt.Key_Escape: getCall().performAction(RingQtQuick.Call.REFUSE) break case Qt.Key_Backspace: getCall().backspaceItemText() break; case Qt.Key_Return: case Qt.Key_Enter: performCall() break default: // Prevent "control" from creating a dialing call if (event.text == "") return var call = getCall() call.appendText(event.text) call.playDTMF(event.text) } } Connections { target: RingSession.callModel onCallAttentionRequest: { RingSession.callModel.selectedCall = call } } Component.onCompleted: { dialView.forceActiveFocus() } MouseArea { z: 9999 anchors.fill: parent propagateComposedEvents: true onClicked: { mouse.accepted = false mouse.refused = true dialView.focus = true dialView.forceActiveFocus() } } } diff --git a/src/dialview/qml/incomingcall.qml b/src/dialview/qml/incomingcall.qml index 3563cf87..303afb13 100644 --- a/src/dialview/qml/incomingcall.qml +++ b/src/dialview/qml/incomingcall.qml @@ -1,39 +1,40 @@ /****************************************************************************** * Copyright (C) 2018 by Bluesystems * * 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 Lesser GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ import QtQuick 2.0 +import org.kde.ringkde.jamicanvasindicator 1.0 as JamiCanvasIndicator Column { id: outgoingCall property QtObject call: null spacing: 6 - Ringing { + JamiCanvasIndicator.Ringing { height: 32 width: 32 anchors.horizontalCenter: parent.horizontalCenter running: true visible: true } Item { height: 4 width: parent.width } } diff --git a/src/dialview/qml/outgoingcall.qml b/src/dialview/qml/outgoingcall.qml index d2a08824..bb42d6f6 100644 --- a/src/dialview/qml/outgoingcall.qml +++ b/src/dialview/qml/outgoingcall.qml @@ -1,48 +1,48 @@ /****************************************************************************** * Copyright (C) 2018 by Bluesystems * * 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 Lesser GNU General Public License * * along with this program. If not, see . * *****************************************************************************/ import QtQuick 2.0 - +import org.kde.ringkde.jamicanvasindicator 1.0 as JamiCanvasIndicator Column { id: outgoingCall property QtObject call: null spacing: 6 Text { text: call.toHumanStateName color: selected ? activePalette.highlightedText : activePalette.text wrapMode: Text.WordWrap font.bold: true anchors.horizontalCenter: parent.horizontalCenter } - Progress { + JamiCanvasIndicator.Progress { call: outgoingCall.call displayLabels: false width: parent.width*0.66 outlineColor: selected ? activePalette.highlightedText : activePalette.text anchors.horizontalCenter: parent.horizontalCenter backgroundColor: selected ? activePalette.highlight : activePalette.base } Item { height: 1 width: parent.width } } diff --git a/src/timeline/qml/viewcontact.qml b/src/timeline/qml/viewcontact.qml index 4dbf31ae..295630bd 100644 --- a/src/timeline/qml/viewcontact.qml +++ b/src/timeline/qml/viewcontact.qml @@ -1,430 +1,431 @@ /*************************************************************************** * 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 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: TimelinePage { 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 } - CallView { + 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: CallHistory { showScrollbar: timelinePage.showScrollbar timelineModel: viewContact.timelineModel currentContactMethod: viewContact.currentContactMethod currentIndividual: viewContact.currentIndividual anchors.fill: parent } } } Page { id: contactInfoPage background: Rectangle { color: activePalette.base } 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/timeline/recentdock.qrc b/src/timeline/recentdock.qrc index 61c93a23..196e3609 100644 --- a/src/timeline/recentdock.qrc +++ b/src/timeline/recentdock.qrc @@ -1,48 +1,47 @@ qml/peerstimeline.qml qml/historytimeline.qml qml/mediabuttons.qml qml/contactheader.qml qml/contactinfo.qml qml/contactdialog.qml qml/callhistory.qml qml/recordinghistory.qml qml/audioplayer.qml qml/viewcontact.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/phonenumbers.qml qml/searchdelegate.qml - qml/completiondelegate.qml qml/findpeers.qml qml/snapshots.qml qml/slideshow.qml qml/thumbnail.qml qml/historycallicon.qml qml/accounterror.qml qml/accountdisabled.qml qml/pendingrequests.qml qml/sendrequest.qml qml/viewcontactrequests.qml qml/noaccount.qml qml/firstrun.qml qml/searchtip.qml qml/searchbox.qml qml/searchoverlay.qml icons/bookmarked.svg icons/not_bookmarked.svg assets/welcome.html