import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import Qt.labs.platform 1.0 import Common 1.0 import Linphone 1.0 import Utils 1.0 import App.Styles 1.0 import ColorsList 1.0 import 'MainWindow.js' as Logic import 'qrc:/ui/scripts/Utils/utils.js' as Utils // ============================================================================= ApplicationWindow { id: window property string _currentView property var _lockedInfo property SmartSearchBar mainSearchBar : (mainLoader.item ? mainLoader.item.mainSearchBar : null) // --------------------------------------------------------------------------- function lockView (info) { Logic.lockView(info) } function unlockView () { Logic.unlockView() } function setView (view, props, callback) { Logic.setView(view, props, callback) } // --------------------------------------------------------------------------- // Window properties. // --------------------------------------------------------------------------- minimumHeight: MainWindowStyle.minimumHeight minimumWidth: MainWindowStyle.minimumWidth title: Utils.capitalizeFirstLetter(applicationName) // --------------------------------------------------------------------------- onActiveFocusItemChanged: Logic.handleActiveFocusItemChanged(activeFocusItem) onClosing: Logic.handleClosing(close) // --------------------------------------------------------------------------- Connections { target: CoreManager onCoreManagerInitialized: mainLoader.active = true } Shortcut { sequence: StandardKey.Close onActivated: window.hide() } // --------------------------------------------------------------------------- Loader { id: mainLoader active: false anchors.fill: parent sourceComponent: ColumnLayout { // Workaround to get these properties in `MainWindow.js`. readonly property alias contactsEntry: contactsEntry readonly property alias conferencesEntry: conferencesEntry readonly property alias contentLoader: contentLoader readonly property alias menu: menu readonly property alias timeline: timeline readonly property alias mainSearchBar: toolBar.mainSearchBar spacing: 0 // ----------------------------------------------------------------------- AuthenticationNotifier { onAuthenticationRequested: Logic.handleAuthenticationRequested(authInfo, realm, sipAddress, userId) } // ----------------------------------------------------------------------- // Toolbar properties. // ----------------------------------------------------------------------- ToolBar { id: toolBar property alias mainSearchBar : smartSearchBar Layout.fillWidth: true Layout.preferredHeight: MainWindowStyle.toolBar.height hoverEnabled : true background: MainWindowStyle.toolBar.background RowLayout { anchors { fill: parent leftMargin: MainWindowStyle.toolBar.leftMargin rightMargin: MainWindowStyle.toolBar.rightMargin } spacing: MainWindowStyle.toolBar.spacing ActionButton { icon: (leftPanel.visible?'panel_shown':'panel_hidden') //: 'Hide Timeline' : Tooltip for a button that hide the timeline tooltipText : (leftPanel.visible?qsTr('hideTimeline') //: 'Open Timeline' : Tooltip for a button that open the timeline :qsTr('openTimeline')) iconSize: MainWindowStyle.panelButtonSize //autoIcon: true onClicked: leftPanel.visible = !leftPanel.visible } ActionButton { id: home isCustom: true backgroundRadius: 4 colorSet: MainWindowStyle.buttons.home //: 'Open Home' : Tooltip for a button that open the home view tooltipText : qsTr('openHome') //autoIcon: true onClicked: setView('Home') } AccountStatus { id: accountStatus betterIcon:true Layout.preferredHeight: parent.height Layout.preferredWidth: MainWindowStyle.accountStatus.width Layout.fillWidth: false TooltipArea { text: AccountSettingsModel.sipAddress hoveringCursor: Qt.PointingHandCursor } onClicked: { CoreManager.forceRefreshRegisters() Logic.manageAccounts() } } ColumnLayout { Layout.preferredWidth: MainWindowStyle.autoAnswerStatus.width visible: SettingsModel.autoAnswerStatus Icon { icon: SettingsModel.autoAnswerStatus ? 'auto_answer_custom' : '' iconSize: MainWindowStyle.autoAnswerStatus.iconSize overwriteColor: MainWindowStyle.autoAnswerStatus.text.colorModel.color } Text { clip: true color: MainWindowStyle.autoAnswerStatus.text.colorModel.color font { bold: true pointSize: MainWindowStyle.autoAnswerStatus.text.pointSize } text: qsTr('autoAnswerStatus') visible: SettingsModel.autoAnswerStatus width: parent.width } } SmartSearchBar { id: smartSearchBar Layout.fillWidth: true maxMenuHeight: MainWindowStyle.searchBox.maxHeight placeholderText: qsTr('mainSearchBarPlaceholder') tooltipText: qsTr('smartSearchBarTooltip') onAddContact: window.setView('ContactEdit', { sipAddress: sipAddress }) onEntryClicked: { if (SettingsModel.contactsEnabled) { window.setView('ContactEdit', { sipAddress: entry.sipAddress }) } else { CallsListModel.createChatRoom( '', false, [entry.sipAddress], true ) } } onLaunchCall: CallsListModel.launchAudioCall(sipAddress, '') onLaunchChat: CallsListModel.launchChat( sipAddress,0 ) onLaunchSecureChat: CallsListModel.launchChat( sipAddress,1 ) onLaunchVideoCall: CallsListModel.launchVideoCall(sipAddress, '') } ActionButton { isCustom: true backgroundRadius: 90 colorSet: MainWindowStyle.buttons.telKeyad onClicked: telKeypad.visible = !telKeypad.visible toggled: telKeypad.visible } ActionButton { Layout.leftMargin: 30 isCustom: true backgroundRadius: 4 colorSet: MainWindowStyle.buttons.newChatGroup //: 'Start a chat room' : Tooltip to illustrate a button tooltipText : qsTr('newChatRoom') visible: (SettingsModel.standardChatEnabled || SettingsModel.secureChatEnabled) enabled: SettingsModel.groupChatEnabled onClicked: { window.detachVirtualWindow() window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/NewChatRoom.qml') ,{}) } TooltipArea{ visible: !SettingsModel.groupChatEnabled maxWidth: smartSearchBar.width delay:0 //: 'Conference URI is not set. You have to change it in your account settings in order to create new group chats.' : Tooltip to warn the user to change a setting to activate an action. text: qsTr('newChatRoomUriMissing') } } ActionButton { isCustom: true backgroundRadius: 4 colorSet: MainWindowStyle.buttons.newConference visible: SettingsModel.conferenceEnabled enabled: SettingsModel.videoConferenceEnabled tooltipText:qsTr('newConferenceButton') onClicked: { window.detachVirtualWindow() window.attachVirtualWindow(Utils.buildAppDialogUri('NewConference') ,{}, function (status) { if( status){ setView('Conferences') } }) } TooltipArea{ visible: !SettingsModel.videoConferenceEnabled maxWidth: smartSearchBar.width delay:0 //: 'Video conference URI is not set. You have to change it in your account settings in order to create new meetings.' : Tooltip to warn the user to change a setting to activate an action. text: qsTr('newConferenceUriMissing') } } ActionButton { isCustom: true backgroundRadius: 4 colorSet: MainWindowStyle.buttons.burgerMenu visible: Qt.platform.os !== 'osx' toggled: menuBar.isOpenned onClicked: toggled ? menuBar.close() : menuBar.open()// a bit useless as Menu will depopup on losing focus but this code is kept for giving idea MainWindowMenuBar { id: menuBar onDisplayRecordings: { timeline.model.unselectAll() setView('Recordings') } } } } } // ----------------------------------------------------------------------- // Content. // ----------------------------------------------------------------------- RowLayout { Layout.fillHeight: true Layout.fillWidth: true spacing: 0 // Main menu. ColumnLayout { id:leftPanel Layout.maximumWidth: MainWindowStyle.menu.width Layout.preferredWidth: MainWindowStyle.menu.width spacing: 0 ApplicationMenu { id: menu defaultSelectedEntry: null entryHeight: MainWindowStyle.menu.height+10 entryWidth: MainWindowStyle.menu.width ApplicationMenuEntry { id: contactsEntry icon: MainWindowStyle.menu.contacts.icon iconSize: MainWindowStyle.menu.contacts.iconSize overwriteColor: isSelected ? MainWindowStyle.menu.contacts.selectedColor.color : MainWindowStyle.menu.contacts.colorModel.color name: qsTr('contactsEntry') visible: SettingsModel.contactsEnabled onSelected: { ContactsListModel.update() timeline.model.unselectAll() setView('Contacts') } onClicked:{ ContactsListModel.update() setView('Contacts') } Icon{ anchors.right:parent.right anchors.verticalCenter: parent.verticalCenter anchors.rightMargin: 10 icon: MainWindowStyle.menu.direction.icon overwriteColor: contactsEntry.overwriteColor iconSize: MainWindowStyle.menu.direction.iconSize } } ApplicationMenuEntry { id: conferencesEntry icon: MainWindowStyle.menu.conferences.icon iconSize: MainWindowStyle.menu.conferences.iconSize overwriteColor: isSelected ? MainWindowStyle.menu.conferences.selectedColor.color : MainWindowStyle.menu.conferences.colorModel.color //: 'Meetings' : Meeting title for main window. name: qsTr('mainWindowConferencesTitle').toUpperCase() visible: SettingsModel.videoConferenceEnabled && SettingsModel.conferenceEnabled onSelected: { timeline.model.unselectAll() setView('Conferences') } onClicked:{ setView('Conferences') } Icon{ anchors.right:parent.right anchors.verticalCenter: parent.verticalCenter anchors.rightMargin: 10 icon: MainWindowStyle.menu.direction.icon overwriteColor: conferencesEntry.overwriteColor iconSize: MainWindowStyle.menu.direction.iconSize } } } // History. Timeline { id: timeline Layout.fillHeight: true Layout.fillWidth: true model: TimelineProxyModel{ listSource: TimelineProxyModel.Main } onEntrySelected:{ if( entry ) { if( entry.selected){ console.debug("Load conversation from entry selected on timeline") window.setView('Conversation', { chatRoomModel:entry.chatRoomModel }) } }else{ window.setView('Home', {}) } menu.resetSelectedEntry() } onShowHistoryRequest: { timeline.model.unselectAll() window.setView('HistoryView') } } } // Main content. Item{ Layout.fillHeight: true Layout.fillWidth: true Loader { id: contentLoader objectName: '__contentLoader' anchors.fill: parent source: 'Home.qml' Component.onCompleted: if (AccountSettingsModel.accounts.length < 2) source= 'Assistant.qml' // default proxy = 1. Do not use this set diretly in source because of bindings that will override next setSource } TelKeypad { anchors.right: parent.right anchors.top: parent.top id: telKeypad onSendDtmf: smartSearchBar.text = smartSearchBar.previousText+dtmf onVisibleChanged: if(!visible) smartSearchBar.previousText = '' // this is a way to reset search text visible: SettingsModel.showTelKeypadAutomatically } } } } } Loader{ id: customMenuBar active:Qt.platform.os === 'osx' sourceComponent:MainWindowTopMenuBar{ onDisplayRecordings: { if(mainLoader.item) mainLoader.item.timeline.model.unselectAll() setView('Recordings') } } } Component.onCompleted: if(Qt.platform.os === 'osx') menuBar = customMenuBar // --------------------------------------------------------------------------- // Url handlers. // --------------------------------------------------------------------------- Connections { target: UrlHandlers onSip: { mainSearchBar.text = sipAddress } } Connections{ target: App onRequestFetchConfig: { window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), { flat: true, //: 'Do you want to download and apply configuration from this URL?' : text to confirm to fetch a specified URL descriptionText: ''+qsTr('confirmFetchUri') +'

'+filePath, }, function (status) { if (status) { App.setFetchConfig(filePath) } }) } } }