mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-20 21:28:07 +00:00
feat(app): many changes
- refactoring - supports own transient window system - update languages - ...
This commit is contained in:
parent
2db66e1f98
commit
dd1bd7124c
26 changed files with 436 additions and 340 deletions
|
|
@ -249,10 +249,6 @@ Server url not configured.</translation>
|
|||
<source>removeContactDescription</source>
|
||||
<translation>Do you really want remove this contact from your book?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>removeContactTitle</source>
|
||||
<translation>Delete confirmation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>sipAccounts</source>
|
||||
<translation>SIP ACCOUNT(S)</translation>
|
||||
|
|
@ -317,10 +313,6 @@ Server url not configured.</translation>
|
|||
<source>locality</source>
|
||||
<translation>Locality</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>abortEditionTitle</source>
|
||||
<translation>Cancel contact edition</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>abortEditionDescriptionText</source>
|
||||
<translation>Are you sure you want to cancel the contact edition?</translation>
|
||||
|
|
@ -348,10 +340,6 @@ Server url not configured.</translation>
|
|||
<source>removeContactDescription</source>
|
||||
<translation>Do you really want remove this contact from your book?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>removeContactTitle</source>
|
||||
<translation>Delete confirmation</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Conversation</name>
|
||||
|
|
@ -371,10 +359,6 @@ Server url not configured.</translation>
|
|||
<source>removeAllEntriesDescription</source>
|
||||
<translation>Are you sure you want to clean history?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>removeAllEntriesTitle</source>
|
||||
<translation>Clean history</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DroppableTextArea</name>
|
||||
|
|
@ -573,23 +557,19 @@ Server url not configured.</translation>
|
|||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ManageAccountsWindow</name>
|
||||
<name>ManageAccounts</name>
|
||||
<message>
|
||||
<source>ok</source>
|
||||
<translation>OK</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>manageAccountsTitle</source>
|
||||
<translation>Presence and accounts</translation>
|
||||
<source>selectPresenceLabel</source>
|
||||
<translation>Select a presence status</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>selectAccountLabel</source>
|
||||
<translation>Select you active account</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>selectPresenceLabel</source>
|
||||
<translation>Select a presence status</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Presence</name>
|
||||
|
|
|
|||
|
|
@ -249,10 +249,6 @@ Url du serveur non configurée.</translation>
|
|||
<source>removeContactDescription</source>
|
||||
<translation>Voulez-vous vraiment supprimer ce contact de votre carnet ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>removeContactTitle</source>
|
||||
<translation>Confirmation de la suppression</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>sipAccounts</source>
|
||||
<translation>COMPTE(S) SIP</translation>
|
||||
|
|
@ -317,10 +313,6 @@ Url du serveur non configurée.</translation>
|
|||
<source>locality</source>
|
||||
<translation>Localité</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>abortEditionTitle</source>
|
||||
<translation>Annuler l'édition du contact</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>abortEditionDescriptionText</source>
|
||||
<translation>Êtes-vous sûr de vouloir annuler l'édition du contact ?</translation>
|
||||
|
|
@ -348,10 +340,6 @@ Url du serveur non configurée.</translation>
|
|||
<source>removeContactDescription</source>
|
||||
<translation>Voulez-vous vraiment supprimer ce contact de votre carnet ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>removeContactTitle</source>
|
||||
<translation>Confirmation de la suppression</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Conversation</name>
|
||||
|
|
@ -371,10 +359,6 @@ Url du serveur non configurée.</translation>
|
|||
<source>removeAllEntriesDescription</source>
|
||||
<translation>Êtes-vous sûr de vouloir supprimer cet historique ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>removeAllEntriesTitle</source>
|
||||
<translation>Suppression de l'historique</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DroppableTextArea</name>
|
||||
|
|
@ -573,23 +557,19 @@ Url du serveur non configurée.</translation>
|
|||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ManageAccountsWindow</name>
|
||||
<name>ManageAccounts</name>
|
||||
<message>
|
||||
<source>ok</source>
|
||||
<translation>OK</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>manageAccountsTitle</source>
|
||||
<translation>Présence et comptes</translation>
|
||||
<source>selectPresenceLabel</source>
|
||||
<translation>Sélectionner votre présence</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>selectAccountLabel</source>
|
||||
<translation>Sélectionner votre compte principal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>selectPresenceLabel</source>
|
||||
<translation>Sélectionner votre présence</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Presence</name>
|
||||
|
|
|
|||
|
|
@ -253,10 +253,14 @@
|
|||
<file>ui/modules/Common/Styles/Popup/PopupStyle.qml</file>
|
||||
<file>ui/modules/Common/Styles/qmldir</file>
|
||||
<file>ui/modules/Common/Styles/Tooltip/TooltipStyle.qml</file>
|
||||
<file>ui/modules/Common/Styles/Window/WindowStyle.qml</file>
|
||||
<file>ui/modules/Common/Tooltip/TooltipArea.qml</file>
|
||||
<file>ui/modules/Common/Tooltip/Tooltip.qml</file>
|
||||
<file>ui/modules/Common/View/ScrollableListView.js</file>
|
||||
<file>ui/modules/Common/View/ScrollableListView.qml</file>
|
||||
<file>ui/modules/Common/Window/ApplicationWindow.qml</file>
|
||||
<file>ui/modules/Common/Window/VirtualWindow.qml</file>
|
||||
<file>ui/modules/Common/Window/Window.js</file>
|
||||
<file>ui/modules/Linphone/Account/AccountStatus.qml</file>
|
||||
<file>ui/modules/Linphone/Calls/CallControls.qml</file>
|
||||
<file>ui/modules/Linphone/Calls/Calls.qml</file>
|
||||
|
|
@ -319,15 +323,17 @@
|
|||
<file>ui/views/App/Main/Assistant/AssistantUseLinphoneSipAccount.qml</file>
|
||||
<file>ui/views/App/Main/Assistant/AssistantUseOtherSipAccount.qml</file>
|
||||
<file>ui/views/App/Main/Assistant.qml</file>
|
||||
<file>ui/views/App/Main/ContactEdit.js</file>
|
||||
<file>ui/views/App/Main/ContactEdit.qml</file>
|
||||
<file>ui/views/App/Main/Contacts.qml</file>
|
||||
<file>ui/views/App/Main/Conversation.js</file>
|
||||
<file>ui/views/App/Main/Conversation.qml</file>
|
||||
<file>ui/views/App/Main/Home.qml</file>
|
||||
<file>ui/views/App/Main/InviteFriends.qml</file>
|
||||
<file>ui/views/App/Main/MainWindow.js</file>
|
||||
<file>ui/views/App/Main/MainWindowMenuBar.qml</file>
|
||||
<file>ui/views/App/Main/MainWindow.qml</file>
|
||||
<file>ui/views/App/ManageAccountsWindow.qml</file>
|
||||
<file>ui/views/App/Main/ManageAccounts.qml</file>
|
||||
<file>ui/views/App/qmldir</file>
|
||||
<file>ui/views/App/Settings/SettingsAudio.qml</file>
|
||||
<file>ui/views/App/Settings/SettingsCallsChat.qml</file>
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ private:
|
|||
) override;
|
||||
|
||||
void onNotifyPresenceReceivedForUriOrTel (
|
||||
const std::shared_ptr<linphone::Core> &lc,
|
||||
const std::shared_ptr<linphone::Friend> &lf,
|
||||
const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Friend> &linphone_friend,
|
||||
const std::string &uri_or_tel,
|
||||
const std::shared_ptr<linphone::PresenceModel> &presence_model
|
||||
) override;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ using namespace std;
|
|||
// =============================================================================
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
qputenv("QML_DISABLE_DISK_CACHE", "true");
|
||||
|
||||
QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true);
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ QtObject {
|
|||
property color k50: '#32FFFFFF'
|
||||
property color l: '#000000'
|
||||
property color l50: '#32000000'
|
||||
property color l80: '#80000000'
|
||||
property color m: '#D1D1D1'
|
||||
property color n: '#C0C0C0'
|
||||
property color o: '#232323'
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ DialogPlus {
|
|||
onClicked: exit(1)
|
||||
}
|
||||
]
|
||||
|
||||
centeredButtons: true
|
||||
maximumHeight: DialogStyle.confirmDialog.height
|
||||
maximumWidth: DialogStyle.confirmDialog.width
|
||||
minimumHeight: DialogStyle.confirmDialog.height
|
||||
minimumWidth: DialogStyle.confirmDialog.width
|
||||
|
||||
height: DialogStyle.confirmDialog.height
|
||||
width: DialogStyle.confirmDialog.width
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import Common 1.0
|
||||
import Common.Styles 1.0
|
||||
|
||||
// =============================================================================
|
||||
// Helper to build quickly dialogs.
|
||||
// =============================================================================
|
||||
|
||||
Window {
|
||||
Rectangle {
|
||||
property alias buttons: buttons.data // Optionnal.
|
||||
property alias descriptionText: description.text // Optionnal.
|
||||
property bool centeredButtons: false
|
||||
|
|
@ -22,21 +22,21 @@ Window {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Derived class must use this function instead of close.
|
||||
// Destroy the component and send signal to caller.
|
||||
function exit (status) {
|
||||
if (!_disableExitStatus) {
|
||||
_disableExitStatus = true
|
||||
exitStatus(status)
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
flags: Qt.Tool | Qt.FramelessWindowHint
|
||||
modality: Qt.WindowModal
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Handle normal windows close.
|
||||
onClosing: !_disableExitStatus && exitStatus(0)
|
||||
color: DialogStyle.color
|
||||
|
||||
layer {
|
||||
enabled: true
|
||||
effect: PopupShadow {}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import Common 1.0
|
|||
// =============================================================================
|
||||
|
||||
QtObject {
|
||||
property color color: Colors.k
|
||||
|
||||
property int leftMargin: 50
|
||||
property int rightMargin: 50
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
pragma Singleton
|
||||
import QtQuick 2.7
|
||||
|
||||
import Common 1.0
|
||||
|
||||
// =============================================================================
|
||||
|
||||
QtObject {
|
||||
property QtObject transientWindow: QtObject {
|
||||
property color color: Colors.l80
|
||||
}
|
||||
}
|
||||
|
|
@ -50,3 +50,5 @@ singleton PanedStyle 1.0 Misc/PanedStyle.qml
|
|||
singleton PopupStyle 1.0 Popup/PopupStyle.qml
|
||||
|
||||
singleton TooltipStyle 1.0 Tooltip/TooltipStyle.qml
|
||||
|
||||
singleton WindowStyle 1.0 Window/WindowStyle.qml
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
import QtQuick 2.7
|
||||
|
||||
// Explicit import to support Toolbar.
|
||||
import QtQuick.Controls 1.4 as Controls1
|
||||
|
||||
import 'Window.js' as Logic
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Controls1.ApplicationWindow {
|
||||
default property alias _content: content.data
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function attachVirtualWindow () {
|
||||
Logic.attachVirtualWindow.apply(this, arguments)
|
||||
}
|
||||
|
||||
function detachVirtualWindow () {
|
||||
Logic.detachVirtualWindow()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
id: content
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
VirtualWindow {
|
||||
id: virtualWindow
|
||||
}
|
||||
}
|
||||
}
|
||||
40
linphone-desktop/ui/modules/Common/Window/VirtualWindow.qml
Normal file
40
linphone-desktop/ui/modules/Common/Window/VirtualWindow.qml
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import QtQuick 2.7
|
||||
|
||||
import Common.Styles 1.0
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Item {
|
||||
function setContent (object) {
|
||||
object.parent = content
|
||||
object.anchors.centerIn = content
|
||||
|
||||
visible = true
|
||||
}
|
||||
|
||||
function unsetContent () {
|
||||
visible = false
|
||||
|
||||
var object = content.data[0]
|
||||
content.data = []
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: content
|
||||
|
||||
anchors.fill: parent
|
||||
color: WindowStyle.transientWindow.color
|
||||
}
|
||||
}
|
||||
31
linphone-desktop/ui/modules/Common/Window/Window.js
Normal file
31
linphone-desktop/ui/modules/Common/Window/Window.js
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// =============================================================================
|
||||
// Windows (qml) Logic.
|
||||
// =============================================================================
|
||||
|
||||
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
|
||||
|
||||
// =============================================================================
|
||||
|
||||
// Create a dynamic component hover the main content of one window.
|
||||
// The object parameter must have a `exitStatus` signal which is used
|
||||
// at item destruction.
|
||||
//
|
||||
// The exit status handler is optional.
|
||||
function attachVirtualWindow (object, properties, exitStatusHandler) {
|
||||
if (virtualWindow.visible) {
|
||||
return
|
||||
}
|
||||
|
||||
var object = Utils.createObject(object, null, {
|
||||
properties: properties
|
||||
})
|
||||
|
||||
if (exitStatusHandler) {
|
||||
object.exitStatus.connect(exitStatusHandler)
|
||||
}
|
||||
object.exitStatus.connect(function () {
|
||||
virtualWindow.unsetContent().destroy()
|
||||
})
|
||||
|
||||
virtualWindow.setContent(object)
|
||||
}
|
||||
|
|
@ -75,3 +75,5 @@ PopupShadow 1.0 Popup/PopupShadow.qml
|
|||
TooltipArea 1.0 Tooltip/TooltipArea.qml
|
||||
|
||||
ScrollableListView 1.0 View/ScrollableListView.qml
|
||||
|
||||
ApplicationWindow 1.0 Window/ApplicationWindow.qml
|
||||
|
|
|
|||
|
|
@ -20,6 +20,12 @@ var PORT_RANGE_REGEX = PortTools.PORT_RANGE_REGEX
|
|||
// QML helpers.
|
||||
// =============================================================================
|
||||
|
||||
function buildDialogUri (component) {
|
||||
return 'qrc:/ui/modules/Common/Dialog/' + component + '.qml'
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Destroy timeout.
|
||||
function clearTimeout (timer) {
|
||||
timer.stop() // NECESSARY.
|
||||
|
|
@ -90,25 +96,35 @@ function getTopParent (object, useFakeParent) {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Display a simple ConfirmDialog component.
|
||||
// Wrap the openWindow function.
|
||||
function openConfirmDialog (parent, options) {
|
||||
return openWindow(
|
||||
'import QtQuick 2.7;' +
|
||||
'import Common 1.0;' +
|
||||
'ConfirmDialog {' +
|
||||
'descriptionText: \'' + escapeQuotes(options.descriptionText) + '\';' +
|
||||
'title: \'' + escapeQuotes(options.title) + '\'' +
|
||||
'}',
|
||||
parent, {
|
||||
isString: true,
|
||||
exitHandler: (options && options.exitHandler) ||
|
||||
function () {
|
||||
return 0
|
||||
},
|
||||
properties: options && options.properties
|
||||
function createObject (source, parent, options) {
|
||||
if (options && options.isString) {
|
||||
var object = Qt.createQmlObject(source, parent)
|
||||
|
||||
var properties = options && options.properties
|
||||
if (properties) {
|
||||
for (var key in properties) {
|
||||
object[key] = properties[key]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
var component = Qt.createComponent(source)
|
||||
if (component.status !== QtQuick.Component.Ready) {
|
||||
console.debug('Component not ready.')
|
||||
if (component.status === QtQuick.Component.Error) {
|
||||
console.debug('Error: ' + component.errorString())
|
||||
}
|
||||
return // Error.
|
||||
}
|
||||
|
||||
var object = component.createObject(parent, (options && options.properties) || {})
|
||||
if (!object) {
|
||||
console.debug('Error: unable to create dynamic object.')
|
||||
}
|
||||
|
||||
return object
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -121,32 +137,7 @@ function openConfirmDialog (parent, options) {
|
|||
//
|
||||
// If exitHandler is used, window must implement exitStatus signal.
|
||||
function openWindow (window, parent, options) {
|
||||
var object
|
||||
|
||||
if (options && options.isString) {
|
||||
object = Qt.createQmlObject(window, parent)
|
||||
|
||||
var properties = options && options.properties
|
||||
if (properties) {
|
||||
for (var key in properties) {
|
||||
object[key] = properties[key]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var component = Qt.createComponent(
|
||||
'qrc:/ui/views/App/' + window + '.qml'
|
||||
)
|
||||
|
||||
if (component.status !== QtQuick.Component.Ready) {
|
||||
console.debug('Window not ready.')
|
||||
if (component.status === QtQuick.Component.Error) {
|
||||
console.debug('Error:' + component.errorString())
|
||||
}
|
||||
return // Error.
|
||||
}
|
||||
|
||||
object = component.createObject(parent, options ? options.properties : {})
|
||||
}
|
||||
var object = createObject(window, parent, options)
|
||||
|
||||
object.closing.connect(object.destroy.bind(object))
|
||||
|
||||
|
|
|
|||
|
|
@ -41,29 +41,6 @@ TestCase {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Test only if a confirm dialog can be opened.
|
||||
// The other tests are launched by `ConfirmDialog.spec.qml`.
|
||||
function test_openConfirmDialog () {
|
||||
var dialog
|
||||
|
||||
try {
|
||||
dialog = Utils.openConfirmDialog(testCase, {
|
||||
descriptionText: '',
|
||||
title: ''
|
||||
})
|
||||
} catch (e) {
|
||||
fail(e)
|
||||
}
|
||||
|
||||
if (dialog == null) {
|
||||
fail('`dialog` is not returned')
|
||||
}
|
||||
|
||||
dialog.close()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function test_qmlTypeof_data () {
|
||||
return [
|
||||
{
|
||||
|
|
|
|||
185
linphone-desktop/ui/views/App/Main/ContactEdit.js
Normal file
185
linphone-desktop/ui/views/App/Main/ContactEdit.js
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
// =============================================================================
|
||||
// `Conversation.qml` Logic.
|
||||
// =============================================================================
|
||||
|
||||
.import Linphone 1.0 as Linphone
|
||||
|
||||
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
|
||||
|
||||
// =============================================================================
|
||||
|
||||
function handleCreation () {
|
||||
var sipAddress = contactEdit.sipAddress
|
||||
var contact = contactEdit._contact = Linphone.SipAddressesModel.mapSipAddressToContact(
|
||||
sipAddress
|
||||
)
|
||||
|
||||
if (!contact) {
|
||||
var vcard = Linphone.CoreManager.createDetachedVcardModel()
|
||||
contactEdit._vcard = vcard
|
||||
|
||||
if (sipAddress && sipAddress.length > 0) {
|
||||
vcard.addSipAddress(sipAddress)
|
||||
}
|
||||
|
||||
contactEdit._edition = true
|
||||
} else {
|
||||
contactEdit._vcard = contact.vcard
|
||||
}
|
||||
}
|
||||
|
||||
function handleDestruction () {
|
||||
var contact = contactEdit._contact
|
||||
|
||||
if (contactEdit._edition && contact) {
|
||||
contact.abortEdit()
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function editContact () {
|
||||
contactEdit._contact.startEdit()
|
||||
contactEdit._edition = true
|
||||
|
||||
window.lockView({
|
||||
descriptionText: qsTr('abortEditionDescriptionText')
|
||||
})
|
||||
}
|
||||
|
||||
function removeContact () {
|
||||
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
|
||||
descriptionText: qsTr('removeContactDescription'),
|
||||
}, function (status) {
|
||||
if (status) {
|
||||
window.unlockView()
|
||||
window.setView('Contacts')
|
||||
ContactsListModel.removeContact(_contact)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function save () {
|
||||
var contact = contactEdit._contact
|
||||
|
||||
if (contact) {
|
||||
contact.endEdit()
|
||||
window.unlockView()
|
||||
} else {
|
||||
contactEdit._contact = Linphone.ContactsListModel.addContact(contactEdit._vcard)
|
||||
}
|
||||
|
||||
contactEdit._edition = false
|
||||
}
|
||||
|
||||
function cancel () {
|
||||
var contact = contactEdit._contact
|
||||
|
||||
if (contact) {
|
||||
contact.abortEdit()
|
||||
contactEdit._edition = false
|
||||
window.unlockView()
|
||||
} else {
|
||||
window.setView('Contacts')
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function setAvatar (path) {
|
||||
contactEdit._vcard.avatar = path.match(/^(?:file:\/\/)?(.*)$/)[1]
|
||||
}
|
||||
|
||||
function setUsername (username) {
|
||||
var vcard = contactEdit._vcard
|
||||
|
||||
vcard.username = username
|
||||
|
||||
// Update current text with new/old username.
|
||||
usernameInput.text = _vcard.username
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function handleSipAddressChanged (sipAddresses, index, defaultValue, newValue) {
|
||||
if (newValue === defaultValue) {
|
||||
return
|
||||
}
|
||||
|
||||
var vcard = contactEdit._vcard
|
||||
var soFarSoGood = (defaultValue.length === 0)
|
||||
? vcard.addSipAddress(newValue)
|
||||
: vcard.updateSipAddress(defaultValue, newValue)
|
||||
|
||||
sipAddresses.setInvalid(index, !soFarSoGood)
|
||||
}
|
||||
|
||||
function handleCompanyChanged (companies, index, defaultValue, newValue) {
|
||||
var vcard = contactEdit._vcard
|
||||
var soFarSoGood = (defaultValue.length === 0)
|
||||
? vcard.addCompany(newValue)
|
||||
: vcard.updateCompany(defaultValue, newValue)
|
||||
|
||||
companies.setInvalid(index, !soFarSoGood)
|
||||
}
|
||||
|
||||
function handleEmailChanged (emails, index, defaultValue, newValue) {
|
||||
var vcard = contactEdit._vcard
|
||||
var soFarSoGood = (defaultValue.length === 0)
|
||||
? vcard.addEmail(newValue)
|
||||
: vcard.updateEmail(defaultValue, newValue)
|
||||
|
||||
emails.setInvalid(index, !soFarSoGood)
|
||||
}
|
||||
|
||||
function handleUrlChanged (urls, index, defaultValue, newValue) {
|
||||
var url = Utils.extractFirstUri(newValue)
|
||||
if (url === defaultValue) {
|
||||
return
|
||||
}
|
||||
|
||||
var vcard = contactEdit._vcard
|
||||
var soFarSoGood = url && (
|
||||
defaultValue.length === 0
|
||||
? vcard.addUrl(newValue)
|
||||
: vcard.updateUrl(defaultValue, newValue)
|
||||
)
|
||||
|
||||
urls.setInvalid(index, !soFarSoGood)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function buildAddressFields () {
|
||||
var address = contactEdit._vcard.address
|
||||
|
||||
return [{
|
||||
placeholder: qsTr('street'),
|
||||
text: address.street
|
||||
}, {
|
||||
placeholder: qsTr('locality'),
|
||||
text: address.locality
|
||||
}, {
|
||||
placeholder: qsTr('postalCode'),
|
||||
text: address.postalCode
|
||||
}, {
|
||||
placeholder: qsTr('country'),
|
||||
text: address.country
|
||||
}]
|
||||
}
|
||||
|
||||
function handleAddressChanged (index, value) {
|
||||
var vcard = contactEdit._vcard
|
||||
|
||||
if (index === 0) { // Street.
|
||||
vcard.setStreet(value)
|
||||
} else if (index === 1) { // Locality.
|
||||
vcard.setLocality(value)
|
||||
} else if (index === 2) { // Postal code.
|
||||
vcard.setPostalCode(value)
|
||||
} else if (index === 3) { // Country.
|
||||
vcard.setCountry(value)
|
||||
}
|
||||
}
|
||||
|
|
@ -6,10 +6,11 @@ import QtQuick.Layouts 1.3
|
|||
import Common 1.0
|
||||
import Linphone 1.0
|
||||
import Linphone.Styles 1.0
|
||||
import Utils 1.0
|
||||
|
||||
import App.Styles 1.0
|
||||
|
||||
import 'ContactEdit.js' as Logic
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ColumnLayout {
|
||||
|
|
@ -23,87 +24,10 @@ ColumnLayout {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function _editContact () {
|
||||
_contact.startEdit()
|
||||
_edition = true
|
||||
|
||||
window.lockView({
|
||||
title: qsTr('abortEditionTitle'),
|
||||
descriptionText: qsTr('abortEditionDescriptionText')
|
||||
})
|
||||
}
|
||||
|
||||
function _save () {
|
||||
if (_contact) {
|
||||
_contact.endEdit()
|
||||
window.unlockView()
|
||||
} else {
|
||||
_contact = ContactsListModel.addContact(_vcard)
|
||||
}
|
||||
|
||||
_edition = false
|
||||
}
|
||||
|
||||
function _cancel () {
|
||||
if (_contact) {
|
||||
_contact.abortEdit()
|
||||
_edition = false
|
||||
window.unlockView()
|
||||
} else {
|
||||
window.setView('Contacts')
|
||||
}
|
||||
}
|
||||
|
||||
function _removeContact () {
|
||||
Utils.openConfirmDialog(window, {
|
||||
descriptionText: qsTr('removeContactDescription'),
|
||||
exitHandler: function (status) {
|
||||
if (status) {
|
||||
window.unlockView()
|
||||
window.setView('Contacts')
|
||||
ContactsListModel.removeContact(_contact)
|
||||
}
|
||||
},
|
||||
title: qsTr('removeContactTitle')
|
||||
})
|
||||
}
|
||||
|
||||
function _setAvatar (path) {
|
||||
_vcard.avatar = path.match(/^(?:file:\/\/)?(.*)$/)[1]
|
||||
}
|
||||
|
||||
function _setUsername (username) {
|
||||
_vcard.username = username
|
||||
|
||||
// Update current text with new/old username.
|
||||
usernameInput.text = _vcard.username
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
spacing: 0
|
||||
|
||||
Component.onCompleted: {
|
||||
_contact = SipAddressesModel.mapSipAddressToContact(sipAddress)
|
||||
|
||||
if (!_contact) {
|
||||
_vcard = CoreManager.createDetachedVcardModel()
|
||||
|
||||
if (sipAddress && sipAddress.length > 0) {
|
||||
_vcard.addSipAddress(sipAddress)
|
||||
}
|
||||
|
||||
_edition = true
|
||||
} else {
|
||||
_vcard = _contact.vcard
|
||||
}
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (_edition && _contact) {
|
||||
_contact.abortEdit()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: Logic.handleCreation()
|
||||
Component.onDestruction: Logic.handleDestruction()
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -113,7 +37,7 @@ ColumnLayout {
|
|||
folder: shortcuts.home
|
||||
title: qsTr('avatarChooserTitle')
|
||||
|
||||
onAccepted: _setAvatar(fileUrls[0])
|
||||
onAccepted: Logic.setAvatar(fileUrls[0])
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -169,7 +93,7 @@ ColumnLayout {
|
|||
readOnly: !_edition
|
||||
text: avatar.username
|
||||
|
||||
onEditingFinished: _setUsername(text)
|
||||
onEditingFinished: Logic.setUsername(text)
|
||||
}
|
||||
|
||||
Row {
|
||||
|
|
@ -198,14 +122,14 @@ ColumnLayout {
|
|||
iconSize: ContactEditStyle.bar.actions.edit.iconSize
|
||||
|
||||
visible: !_edition
|
||||
onClicked: _editContact()
|
||||
onClicked: Logic.editContact()
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
icon: 'delete'
|
||||
iconSize: ContactEditStyle.bar.actions.del.iconSize
|
||||
|
||||
onClicked: _removeContact()
|
||||
onClicked: Logic.removeContact()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -245,65 +169,6 @@ ColumnLayout {
|
|||
sourceComponent: Flickable {
|
||||
id: flick
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
function _handleSipAddressChanged (index, defaultValue, newValue) {
|
||||
if (newValue === defaultValue) {
|
||||
return
|
||||
}
|
||||
|
||||
var so_far_so_good = (defaultValue.length === 0)
|
||||
? _vcard.addSipAddress(newValue)
|
||||
: _vcard.updateSipAddress(defaultValue, newValue)
|
||||
|
||||
addresses.setInvalid(index, !so_far_so_good)
|
||||
}
|
||||
|
||||
function _handleCompanyChanged (index, defaultValue, newValue) {
|
||||
var so_far_so_good = (defaultValue.length === 0)
|
||||
? _vcard.addCompany(newValue)
|
||||
: _vcard.updateCompany(defaultValue, newValue)
|
||||
|
||||
companies.setInvalid(index, !so_far_so_good)
|
||||
}
|
||||
|
||||
function _handleEmailChanged (index, defaultValue, newValue) {
|
||||
var so_far_so_good = (defaultValue.length === 0)
|
||||
? _vcard.addEmail(newValue)
|
||||
: _vcard.updateEmail(defaultValue, newValue)
|
||||
|
||||
emails.setInvalid(index, !so_far_so_good)
|
||||
}
|
||||
|
||||
function _handleUrlChanged (index, defaultValue, newValue) {
|
||||
var url = Utils.extractFirstUri(newValue)
|
||||
if (url === defaultValue) {
|
||||
return
|
||||
}
|
||||
|
||||
var so_far_so_good = url && (
|
||||
defaultValue.length === 0
|
||||
? _vcard.addUrl(newValue)
|
||||
: _vcard.updateUrl(defaultValue, newValue)
|
||||
)
|
||||
|
||||
urls.setInvalid(index, !so_far_so_good)
|
||||
}
|
||||
|
||||
function _handleAddressChanged (index, value) {
|
||||
if (index === 0) { // Street.
|
||||
_vcard.setStreet(value)
|
||||
} else if (index === 1) { // Locality.
|
||||
_vcard.setLocality(value)
|
||||
} else if (index === 2) { // Postal code.
|
||||
_vcard.setPostalCode(value)
|
||||
} else if (index === 3) { // Country.
|
||||
_vcard.setCountry(value)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
ScrollBar.vertical: ForceScrollBar {}
|
||||
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
|
|
@ -345,7 +210,7 @@ ColumnLayout {
|
|||
readOnly: !_edition
|
||||
title: qsTr('sipAccounts')
|
||||
|
||||
onChanged: _handleSipAddressChanged(index, defaultValue, newValue)
|
||||
onChanged: Logic.handleSipAddressChanged(addresses, index, defaultValue, newValue)
|
||||
onRemoved: _vcard.removeSipAddress(value)
|
||||
}
|
||||
|
||||
|
|
@ -366,7 +231,7 @@ ColumnLayout {
|
|||
readOnly: !_edition
|
||||
title: qsTr('companies')
|
||||
|
||||
onChanged: _handleCompanyChanged(index, defaultValue, newValue)
|
||||
onChanged: Logic.handleCompanyChanged(companies, index, defaultValue, newValue)
|
||||
onRemoved: _vcard.removeCompany(value)
|
||||
}
|
||||
|
||||
|
|
@ -388,7 +253,7 @@ ColumnLayout {
|
|||
readOnly: !_edition
|
||||
title: qsTr('emails')
|
||||
|
||||
onChanged: _handleEmailChanged(index, defaultValue, newValue)
|
||||
onChanged: Logic.handleEmailChanged(emails, index, defaultValue, newValue)
|
||||
onRemoved: _vcard.removeEmail(value)
|
||||
}
|
||||
|
||||
|
|
@ -410,7 +275,7 @@ ColumnLayout {
|
|||
readOnly: !_edition
|
||||
title: qsTr('webSites')
|
||||
|
||||
onChanged: _handleUrlChanged(index, defaultValue, newValue)
|
||||
onChanged: Logic.handleUrlChanged(urls, index, defaultValue, newValue)
|
||||
onRemoved: _vcard.removeUrl(value)
|
||||
}
|
||||
|
||||
|
|
@ -424,28 +289,12 @@ ColumnLayout {
|
|||
Layout.leftMargin: ContactEditStyle.values.leftMargin
|
||||
Layout.rightMargin: ContactEditStyle.values.rightMargin
|
||||
|
||||
fields: {
|
||||
var address = _vcard.address
|
||||
|
||||
return [{
|
||||
placeholder: qsTr('street'),
|
||||
text: address.street
|
||||
}, {
|
||||
placeholder: qsTr('locality'),
|
||||
text: address.locality
|
||||
}, {
|
||||
placeholder: qsTr('postalCode'),
|
||||
text: address.postalCode
|
||||
}, {
|
||||
placeholder: qsTr('country'),
|
||||
text: address.country
|
||||
}]
|
||||
}
|
||||
fields: Logic.buildAddressFields()
|
||||
|
||||
readOnly: !_edition
|
||||
title: qsTr('address')
|
||||
|
||||
onChanged: _handleAddressChanged(index, value)
|
||||
onChanged: Logic.handleAddressChanged(index, value)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
|
@ -462,13 +311,13 @@ ColumnLayout {
|
|||
|
||||
TextButtonA {
|
||||
text: qsTr('cancel')
|
||||
onClicked: _cancel()
|
||||
onClicked: Logic.cancel()
|
||||
}
|
||||
|
||||
TextButtonB {
|
||||
enabled: usernameInput.text.length > 0 && _vcard.sipAddresses.length > 0
|
||||
text: qsTr('save')
|
||||
onClicked: _save()
|
||||
onClicked: Logic.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,12 @@ import App.Styles 1.0
|
|||
|
||||
ColumnLayout {
|
||||
function _removeContact (contact) {
|
||||
Utils.openConfirmDialog(window, {
|
||||
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
|
||||
descriptionText: qsTr('removeContactDescription'),
|
||||
exitHandler: function (status) {
|
||||
if (status) {
|
||||
ContactsListModel.removeContact(contact)
|
||||
}
|
||||
},
|
||||
title: qsTr('removeContactTitle')
|
||||
}, function (status) {
|
||||
if (status) {
|
||||
ContactsListModel.removeContact(contact)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
17
linphone-desktop/ui/views/App/Main/Conversation.js
Normal file
17
linphone-desktop/ui/views/App/Main/Conversation.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// =============================================================================
|
||||
// `Conversation.qml` Logic.
|
||||
// =============================================================================
|
||||
|
||||
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
|
||||
|
||||
// =============================================================================
|
||||
|
||||
function removeAllEntries () {
|
||||
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
|
||||
descriptionText: qsTr('removeAllEntriesDescription'),
|
||||
}, function (status) {
|
||||
if (status) {
|
||||
chatProxyModel.removeAllEntries()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -4,10 +4,11 @@ import QtQuick.Layouts 1.3
|
|||
import Common 1.0
|
||||
import Linphone 1.0
|
||||
import LinphoneUtils 1.0
|
||||
import Utils 1.0
|
||||
|
||||
import App.Styles 1.0
|
||||
|
||||
import 'Conversation.js' as Logic
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ColumnLayout {
|
||||
|
|
@ -17,18 +18,6 @@ ColumnLayout {
|
|||
|
||||
property var _contact: SipAddressesModel.mapSipAddressToContact(sipAddress)
|
||||
|
||||
function _removeAllEntries () {
|
||||
Utils.openConfirmDialog(window, {
|
||||
descriptionText: qsTr('removeAllEntriesDescription'),
|
||||
exitHandler: function (status) {
|
||||
if (status) {
|
||||
chatProxyModel.removeAllEntries()
|
||||
}
|
||||
},
|
||||
title: qsTr('removeAllEntriesTitle')
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
spacing: 0
|
||||
|
|
@ -104,7 +93,7 @@ ColumnLayout {
|
|||
icon: 'delete'
|
||||
iconSize: ConversationStyle.bar.actions.edit.iconSize
|
||||
|
||||
onClicked: _removeAllEntries()
|
||||
onClicked: Logic.removeAllEntries()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,22 +36,26 @@ function setView (view, props) {
|
|||
return
|
||||
}
|
||||
|
||||
Utils.openConfirmDialog(window, {
|
||||
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
|
||||
descriptionText: lockedInfo.descriptionText,
|
||||
exitHandler: function (status) {
|
||||
if (status) {
|
||||
unlockView()
|
||||
apply(view, props)
|
||||
} else {
|
||||
updateSelectedEntry(window._currentView, props)
|
||||
}
|
||||
},
|
||||
title: lockedInfo.title
|
||||
}, function (status) {
|
||||
if (status) {
|
||||
unlockView()
|
||||
apply(view, props)
|
||||
} else {
|
||||
updateSelectedEntry(window._currentView, props)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function manageAccounts () {
|
||||
window.attachVirtualWindow(Qt.resolvedUrl('ManageAccounts.qml'))
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function updateSelectedEntry (view, props) {
|
||||
if (view === 'Home' || view === 'Contacts') {
|
||||
menu.setSelectedEntry(view === 'Home' ? 0 : 1)
|
||||
|
|
|
|||
|
|
@ -2,9 +2,6 @@ import QtQuick 2.7
|
|||
import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
// Explicit import to support Toolbar.
|
||||
import QtQuick.Controls 1.4 as Controls1
|
||||
|
||||
import Common 1.0
|
||||
import Linphone 1.0
|
||||
import Utils 1.0
|
||||
|
|
@ -15,7 +12,7 @@ import 'MainWindow.js' as Logic
|
|||
|
||||
// =============================================================================
|
||||
|
||||
Controls1.ApplicationWindow {
|
||||
ApplicationWindow {
|
||||
id: window
|
||||
|
||||
property string _currentView
|
||||
|
|
@ -28,7 +25,7 @@ Controls1.ApplicationWindow {
|
|||
}
|
||||
|
||||
function unlockView () {
|
||||
Logic.unlockView(info)
|
||||
Logic.unlockView()
|
||||
}
|
||||
|
||||
function setView (view, props) {
|
||||
|
|
@ -116,7 +113,7 @@ Controls1.ApplicationWindow {
|
|||
text: AccountSettingsModel.sipAddress
|
||||
}
|
||||
|
||||
onClicked: Utils.openWindow('ManageAccountsWindow', window)
|
||||
onClicked: Logic.manageAccounts()
|
||||
}
|
||||
|
||||
Column {
|
||||
|
|
|
|||
|
|
@ -18,16 +18,10 @@ DialogPlus {
|
|||
]
|
||||
|
||||
centeredButtons: true
|
||||
title: qsTr('manageAccountsTitle')
|
||||
|
||||
height: ManageAccountsWindowStyle.height
|
||||
width: ManageAccountsWindowStyle.width
|
||||
|
||||
minimumHeight: ManageAccountsWindowStyle.height
|
||||
minimumWidth: ManageAccountsWindowStyle.width
|
||||
maximumHeight: ManageAccountsWindowStyle.height
|
||||
maximumWidth: ManageAccountsWindowStyle.width
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Form {
|
||||
|
|
@ -7,4 +7,3 @@ module App
|
|||
# Views ------------------------------------------------------------------------
|
||||
|
||||
IncallFullscreenWindow 1.0 IncallFullscreenWindow.qml
|
||||
ManageAccountsWindow 1.0 ManageAccountsWindow.qml
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue