mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-10-30 07:53:33 +08:00
Cf. https://review.jami.net/c/jami-daemon/+/29901 Change-Id: I46a0d1297c2e60ca43dc5524fd6e8a192bc45139
218 lines
8.8 KiB
QML
218 lines
8.8 KiB
QML
/*
|
|
* Copyright (C) 2024-2025 Savoir-faire Linux Inc.
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import Qt.labs.qmlmodels
|
|
|
|
import net.jami.Models 1.1
|
|
import net.jami.Adapters 1.1
|
|
import net.jami.Enums 1.1
|
|
import net.jami.Helpers 1.1
|
|
import net.jami.Constants 1.1
|
|
|
|
import "mainview"
|
|
import "mainview/components"
|
|
import "wizardview"
|
|
import "commoncomponents"
|
|
|
|
// A window into which we can load a QML file for testing.
|
|
ApplicationWindow {
|
|
id: appWindow
|
|
visible: true
|
|
width: testWidth || loader.implicitWidth || 800
|
|
height: testHeight || loader.implicitHeight || 600
|
|
title: testComponentURI
|
|
|
|
// WARNING: The following currently must be maintained in tandem with MainApplicationWindow.qml
|
|
// Used to manage full screen mode and save/restore window geometry.
|
|
readonly property bool useFrameless: false
|
|
property bool isRTL: UtilsAdapter.isRTL
|
|
LayoutMirroring.enabled: isRTL
|
|
LayoutMirroring.childrenInherit: isRTL
|
|
property LayoutManager layoutManager: LayoutManager {
|
|
appContainer: null
|
|
}
|
|
// Used to manage dynamic view loading and unloading.
|
|
property ViewManager viewManager: ViewManager {}
|
|
// Used to manage the view stack and the current view.
|
|
property ViewCoordinator viewCoordinator: ViewCoordinator {}
|
|
|
|
Loader {
|
|
id: loader
|
|
|
|
source: Qt.resolvedUrl(testComponentURI)
|
|
onStatusChanged: {
|
|
console.log("Status changed to:", loader.status)
|
|
if (loader.status == Loader.Error || loader.status == Loader.Null) {
|
|
console.error("Couldn't load component:", source)
|
|
Qt.exit(1);
|
|
} else if (loader.status == Loader.Ready) {
|
|
console.info("Loaded component:", source);
|
|
// If any of the dimensions are not set, set them to the appWindow's dimensions
|
|
item.width = item.width || Qt.binding(() => appWindow.width);
|
|
item.height = item.height || Qt.binding(() => appWindow.height);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Closing this window should always exit the application.
|
|
onClosing: Qt.quit()
|
|
|
|
// A window to modify properties for Jamified components.
|
|
// Sometimes we need to modify properties including current conversation ID, account ID, etc.
|
|
// This window should have a simple layout: a list of editable parameters within a scroll view.
|
|
Window {
|
|
id: configTool
|
|
width: 400
|
|
height: 400
|
|
title: "Config tool"
|
|
|
|
visible: true
|
|
// Cannot be closed.
|
|
flags: Qt.SplashScreen
|
|
|
|
// Anchor the window to the right of the parent window.
|
|
x: appWindow.x + appWindow.width
|
|
y: appWindow.y
|
|
|
|
color: "lightgray"
|
|
|
|
Page {
|
|
anchors.fill: parent
|
|
header: Control {
|
|
contentItem: Text {
|
|
horizontalAlignment: Text.AlignHCenter
|
|
text: "Config tool"
|
|
}
|
|
background: Rectangle { color: configTool.color }
|
|
}
|
|
contentItem: Control {
|
|
background: Rectangle { color: Qt.lighter(configTool.color, 1.1) }
|
|
padding: 10
|
|
contentItem: ListView {
|
|
// Declare types of controls. TODO: add as needed.
|
|
Component {
|
|
id: checkComponent
|
|
CheckBox {
|
|
text: label
|
|
onCheckedChanged: checkChangedCb(checked)
|
|
}
|
|
}
|
|
Component {
|
|
id: comboComponent
|
|
Control {
|
|
contentItem: RowLayout {
|
|
Text { text: label }
|
|
ComboBox {
|
|
id: comboBox
|
|
displayText: CurrentConversation.title || "undefined"
|
|
model: getDataModel()
|
|
delegate: ItemDelegate {
|
|
highlighted: comboBox.highlightedIndex === index
|
|
width: parent.width
|
|
text: JamiQmlUtils.getModelData(comboBox.model, index, displayRole)
|
|
}
|
|
onCurrentIndexChanged: onIndexChanged(model, currentIndex)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
spacing: 5
|
|
model: ListModel {
|
|
ListElement {
|
|
label: "Conversation ID"
|
|
type: "combobox"
|
|
getDataModel: () => ConversationsAdapter.convListProxyModel
|
|
displayRole: ConversationList.Title
|
|
onIndexChanged: function(model, index) {
|
|
const convUid = JamiQmlUtils.getModelData(model, index, ConversationList.UID);
|
|
LRCInstance.selectConversation(convUid);
|
|
}
|
|
}
|
|
ListElement {
|
|
label: "Account ID"
|
|
type: "combobox"
|
|
getDataModel: () => AccountListModel
|
|
displayRole: AccountList.Username
|
|
onIndexChanged: function(model, index) {
|
|
const accountId = JamiQmlUtils.getModelData(model, index, AccountList.ID);
|
|
LRCInstance.currentAccountId = accountId;
|
|
}
|
|
}
|
|
ListElement {
|
|
label: "Force local preview"
|
|
type: "checkbox"
|
|
value: false
|
|
checkChangedCb: function(checked) {
|
|
// Find any child component of type `LocalVideo` and start it.
|
|
const localVideo = findChild(loader.item, LocalVideo, "type");
|
|
if (localVideo) {
|
|
if (checked) {
|
|
localVideo.startWithId(VideoDevices.getDefaultDevice());
|
|
} else {
|
|
localVideo.startWithId("");
|
|
}
|
|
} else {
|
|
console.error("LocalVideo not found");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
delegate: DelegateChooser {
|
|
role: "type"
|
|
DelegateChoice {
|
|
roleValue: "checkbox"
|
|
delegate: checkComponent
|
|
}
|
|
DelegateChoice {
|
|
roleValue: "combobox"
|
|
delegate: comboComponent
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// From TestCase.qml, refactored to find a child by type or name.
|
|
function findChild(parent, searchValue, searchBy = "name") {
|
|
if (!parent || parent.children === undefined) {
|
|
console.error("No children found");
|
|
return null;
|
|
}
|
|
// Search directly under the given parent
|
|
for (var i = 0; i < parent.children.length; ++i) {
|
|
var child = parent.children[i];
|
|
var match = false;
|
|
if (searchBy === "name" && child.objectName === searchValue) {
|
|
match = true;
|
|
} else if (searchBy === "type" && child instanceof searchValue) {
|
|
match = true;
|
|
}
|
|
if (match) return child;
|
|
}
|
|
// Recursively search in child objects
|
|
for (i = 0; i < parent.children.length; ++i) {
|
|
var found = findChild(parent.children[i], searchValue, searchBy);
|
|
if (found) return found;
|
|
}
|
|
return null;
|
|
}
|
|
}
|