mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-05-07 14:44:01 +00:00
- Keyboard shortcuts:
* 'Ctrl+Shift+W' (or V): accept with video the last incoming call.
* 'Ctrl+Shift+A': accept without video the last incoming call.
* 'Ctrl+Shift+D': terminate the last call.
* 'Ctrl+Shift+E': Enable/disable echo cancellation.
* 'Ctrl+Shift+L': Unmute/Mute speaker.
* 'Ctrl+Shift+M': Unmute/Mute microphone.
- Request application focus when hovering a call notification.
- Forbid to calibrate echo cancellation while being in call because it is not supported.
# Conflicts:
# CHANGELOG.md
# linphone-app/src/components/settings/SettingsModel.hpp
# linphone-app/ui/modules/Common/Form/MouseArea.qml
This commit is contained in:
parent
56b35dfed1
commit
2338dae8e5
12 changed files with 135 additions and 15 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -22,6 +22,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Added
|
||||
- '[ui] logs_max_size' : option to set the max size of one log file.
|
||||
- '[ui] notification_origin' : option to specify where to display notifications (only supported: 0=bottom-right and 1=top-right).
|
||||
- '[ui] systray_notification_blink' : option to activate/deactivate the blinking systray on unread notifications.
|
||||
- '[ui] systray_notification_global' : option to display notification number from all accounts or only selected.
|
||||
- '[ui] systray_notification_filtered' : option to filter the notification number (not count if chat room is muted).
|
||||
- Keyboard shortcuts:
|
||||
* 'Ctrl+Shift+W' (or V): accept with video the last incoming call.
|
||||
* 'Ctrl+Shift+A': accept without video the last incoming call.
|
||||
* 'Ctrl+Shift+D': terminate the last call.
|
||||
* 'Ctrl+Shift+E': Enable/disable echo cancellation.
|
||||
* 'Ctrl+Shift+L': Unmute/Mute speaker.
|
||||
* 'Ctrl+Shift+M': Unmute/Mute microphone.
|
||||
- Request application focus when hovering a call notification.
|
||||
|
||||
## 5.2.1 - 2024-02-01
|
||||
|
||||
|
|
|
|||
|
|
@ -2076,7 +2076,7 @@
|
|||
<message>
|
||||
<source>checkForUpdates</source>
|
||||
<extracomment>'Check for updates' : Item menu for checking updates</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation type="unfinished">检测软件更新</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>recordings</source>
|
||||
|
|
@ -2106,7 +2106,7 @@
|
|||
<message>
|
||||
<source>checkForUpdates</source>
|
||||
<extracomment>'Check for updates' : Item menu for checking updates</extracomment>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation type="unfinished">检测软件更新</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>recordings</source>
|
||||
|
|
|
|||
|
|
@ -501,6 +501,55 @@ void CallsListModel::terminateCall (const QString& sipAddress) const{
|
|||
}
|
||||
}
|
||||
|
||||
QSharedPointer<CallModel> CallsListModel::getLastCall(bool incoming) const{
|
||||
QSharedPointer<CallModel> lastCall = nullptr;
|
||||
time_t lastTime = 0;
|
||||
auto item = mList.rbegin();
|
||||
while(item != mList.rend() && !lastCall) {
|
||||
auto call = item->objectCast<CallModel>();
|
||||
if(!incoming || call->getStatus() == CallModel::CallStatusIncoming) {
|
||||
lastCall = call;
|
||||
}
|
||||
}
|
||||
return lastCall;
|
||||
}
|
||||
|
||||
QSharedPointer<CallModel> CallsListModel::getCallModel(const std::shared_ptr<linphone::Call> &call) const{
|
||||
QSharedPointer<CallModel> callModel;
|
||||
if(call) {
|
||||
auto itCall = std::find_if(mList.begin(), mList.end(), [call](const QSharedPointer<QObject> &item){
|
||||
auto c = item.objectCast<CallModel>();
|
||||
return c && c->getCall() == call;
|
||||
});
|
||||
if( itCall != mList.end())
|
||||
callModel = itCall->objectCast<CallModel>();
|
||||
}
|
||||
return callModel;
|
||||
}
|
||||
|
||||
void CallsListModel::acceptLastIncomingCall(bool video) {
|
||||
auto call = getLastCall(true);
|
||||
if(call) {
|
||||
if(video) call->acceptWithVideo();
|
||||
else call->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void CallsListModel::terminateLastCall() {
|
||||
auto call = getLastCall(false); // Allow to terminate last outgoing call
|
||||
if(call) call->terminate();
|
||||
}
|
||||
|
||||
void CallsListModel::toggleMuteSpeaker() {
|
||||
auto currentCall = getCallModel(CoreManager::getInstance()->getCore()->getCurrentCall());
|
||||
if(currentCall) currentCall->setSpeakerMuted(!currentCall->getSpeakerMuted());
|
||||
}
|
||||
|
||||
void CallsListModel::toggleMuteMicrophone() {
|
||||
auto currentCall = getCallModel(CoreManager::getInstance()->getCore()->getCurrentCall());
|
||||
if(currentCall) currentCall->setMicroMuted(!currentCall->getMicroMuted());
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<linphone::CallLog>> CallsListModel::getCallHistory(const QString& peerAddress, const QString& localAddress){
|
||||
std::shared_ptr<linphone::Address> cleanedPeerAddress = Utils::interpretUrl(Utils::cleanSipAddress(peerAddress));
|
||||
std::shared_ptr<linphone::Address> cleanedLocalAddress = Utils::interpretUrl(Utils::cleanSipAddress(localAddress));
|
||||
|
|
|
|||
|
|
@ -68,6 +68,13 @@ public:
|
|||
|
||||
Q_INVOKABLE void terminateAllCalls () const;
|
||||
Q_INVOKABLE void terminateCall (const QString& sipAddress) const;
|
||||
// Call commands
|
||||
QSharedPointer<CallModel> getLastCall(bool incoming) const;
|
||||
QSharedPointer<CallModel> getCallModel(const std::shared_ptr<linphone::Call> &call) const;
|
||||
Q_INVOKABLE void acceptLastIncomingCall(bool video);
|
||||
Q_INVOKABLE void terminateLastCall();
|
||||
Q_INVOKABLE void toggleMuteSpeaker();
|
||||
Q_INVOKABLE void toggleMuteMicrophone();
|
||||
|
||||
static std::list<std::shared_ptr<linphone::CallLog>> getCallHistory(const QString& peerAddress, const QString& localAddress);
|
||||
|
||||
|
|
|
|||
|
|
@ -552,6 +552,10 @@ void SettingsModel::setEchoCancellationEnabled(bool status) {
|
|||
void SettingsModel::startEchoCancellerCalibration() {
|
||||
CoreManager::getInstance()->getCore()->startEchoCancellerCalibration();
|
||||
}
|
||||
|
||||
int SettingsModel::getEchoCancellationCalibration()const {
|
||||
return CoreManager::getInstance()->getCore()->getEchoCancellationCalibration();
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool SettingsModel::getShowAudioCodecs() const {
|
||||
|
|
@ -2051,6 +2055,7 @@ void SettingsModel::handleCallStateChanged(const shared_ptr<linphone::Call> &, l
|
|||
}
|
||||
void SettingsModel::handleEcCalibrationResult(linphone::EcCalibratorStatus status, int delayMs) {
|
||||
emit echoCancellationStatus((int)status, delayMs);
|
||||
emit echoCancellationCalibrationChanged();
|
||||
}
|
||||
bool SettingsModel::getIsInCall() const {
|
||||
return CoreManager::getInstance()->getCore()->getCallsNb() != 0;
|
||||
|
|
|
|||
|
|
@ -93,10 +93,10 @@ class SettingsModel : public QObject {
|
|||
Q_PROPERTY(QString ringerDevice READ getRingerDevice WRITE setRingerDevice NOTIFY ringerDeviceChanged)
|
||||
|
||||
Q_PROPERTY(QString ringPath READ getRingPath WRITE setRingPath NOTIFY ringPathChanged)
|
||||
|
||||
Q_PROPERTY(bool echoCancellationEnabled READ getEchoCancellationEnabled WRITE setEchoCancellationEnabled NOTIFY
|
||||
echoCancellationEnabledChanged)
|
||||
|
||||
Q_PROPERTY(
|
||||
int echoCancellationCalibration READ getEchoCancellationCalibration NOTIFY echoCancellationCalibrationChanged)
|
||||
Q_PROPERTY(bool showAudioCodecs READ getShowAudioCodecs WRITE setShowAudioCodecs NOTIFY showAudioCodecsChanged)
|
||||
|
||||
// Video. --------------------------------------------------------------------
|
||||
|
|
@ -372,7 +372,7 @@ public:
|
|||
|
||||
Q_INVOKABLE void startCaptureGraph();
|
||||
Q_INVOKABLE void stopCaptureGraph();
|
||||
;
|
||||
|
||||
Q_INVOKABLE void stopCaptureGraphs();
|
||||
Q_INVOKABLE void resetCaptureGraph();
|
||||
void createCaptureGraph();
|
||||
|
|
@ -406,6 +406,7 @@ public:
|
|||
|
||||
bool getEchoCancellationEnabled() const;
|
||||
void setEchoCancellationEnabled(bool status);
|
||||
int getEchoCancellationCalibration() const;
|
||||
|
||||
Q_INVOKABLE void startEchoCancellerCalibration();
|
||||
|
||||
|
|
@ -813,9 +814,9 @@ signals:
|
|||
|
||||
void echoCancellationEnabledChanged(bool status);
|
||||
void echoCancellationStatus(int status, int msDelay);
|
||||
void echoCancellationCalibrationChanged();
|
||||
|
||||
void showAudioCodecsChanged(bool status);
|
||||
|
||||
// Video. --------------------------------------------------------------------
|
||||
void videoEnabledChanged();
|
||||
void videoAvailableChanged();
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import Common 1.0
|
|||
import Common.Styles 1.0
|
||||
|
||||
Quick.MouseArea {
|
||||
property int hoveredCursor: Qt.PointingHandCursor
|
||||
property bool interactive: true
|
||||
cursorShape: containsMouse && interactive
|
||||
? Qt.PointingHandCursor
|
||||
cursorShape: containsMouse && interactive
|
||||
? hoveredCursor
|
||||
: Qt.ArrowCursor
|
||||
hoverEnabled: interactive
|
||||
hoverEnabled: interactive
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Linphone.Styles 1.0
|
|||
|
||||
DesktopPopup {
|
||||
id: notification
|
||||
|
||||
property bool selected: false
|
||||
property alias icon: iconSign.icon
|
||||
property var notificationData: ({
|
||||
timelineModel : null
|
||||
|
|
@ -35,8 +35,8 @@ DesktopPopup {
|
|||
width: NotificationStyle.width
|
||||
|
||||
border {
|
||||
color: NotificationStyle.border.colorModel.color
|
||||
width: NotificationStyle.border.width
|
||||
color: notification.selected ? NotificationStyle.selectedBorder.colorModel.color : NotificationStyle.border.colorModel.color
|
||||
width: notification.selected ? NotificationStyle.selectedBorder.width : NotificationStyle.border.width
|
||||
}
|
||||
|
||||
Item {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,15 @@ Notification {
|
|||
readonly property var call: notificationData && notificationData.call
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
selected: focusArea.containsMouse
|
||||
onSelectedChanged: { if(selected) Window.window.requestActivate()}
|
||||
MouseArea{
|
||||
id: focusArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
hoveredCursor: Qt.ArrowCursor
|
||||
}
|
||||
Loader {
|
||||
active: Boolean(notification.call)
|
||||
anchors {
|
||||
|
|
|
|||
|
|
@ -16,4 +16,8 @@ QtObject {
|
|||
property var colorModel: ColorsList.add(sectionName+'_border', 'n')
|
||||
property int width: 1
|
||||
}
|
||||
property QtObject selectedBorder: QtObject {
|
||||
property var colorModel: ColorsList.add(sectionName+'_selected_border', 'i')
|
||||
property int width: 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,9 +72,42 @@ ApplicationWindow {
|
|||
}
|
||||
|
||||
Shortcut {
|
||||
context: Qt.ApplicationShortcut
|
||||
sequence: StandardKey.Close
|
||||
onActivated: window.hide()
|
||||
}
|
||||
Shortcut {
|
||||
context: Qt.ApplicationShortcut
|
||||
sequence: ['Ctrl+Shift+W', 'Ctrl+Shift+V']
|
||||
onActivated: CallsListModel.acceptLastIncomingCall(true)
|
||||
}
|
||||
Shortcut {
|
||||
context: Qt.ApplicationShortcut
|
||||
sequence: 'Ctrl+Shift+A'
|
||||
onActivated: CallsListModel.acceptLastIncomingCall(false)
|
||||
}
|
||||
Shortcut {
|
||||
sequence: 'Ctrl+Shift+D'
|
||||
context: Qt.ApplicationShortcut
|
||||
onActivated: CallsListModel.terminateLastCall(true)
|
||||
}
|
||||
Shortcut {
|
||||
sequence: 'Ctrl+Shift+E'
|
||||
context: Qt.ApplicationShortcut
|
||||
onActivated: {// startEchoCancellerCalibration is unsupported while being in call.
|
||||
SettingsModel.echoCancellationEnabled = !SettingsModel.echoCancellationEnabled;
|
||||
}
|
||||
}
|
||||
Shortcut {
|
||||
sequence: 'Ctrl+Shift+L'
|
||||
context: Qt.ApplicationShortcut
|
||||
onActivated: CallsListModel.toggleMuteSpeaker()
|
||||
}
|
||||
Shortcut {
|
||||
sequence: 'Ctrl+Shift+M'
|
||||
context: Qt.ApplicationShortcut
|
||||
onActivated: CallsListModel.toggleMuteMicrophone()
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Loader {
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ TabContainer {
|
|||
}
|
||||
Text{
|
||||
id:echoCalibrationStatus
|
||||
text: ''
|
||||
text: SettingsModel.echoCancellationCalibration > 0 ? qsTr("calibratingEchoCancellationDone").replace('%1', SettingsModel.echoCancellationCalibration) : ''
|
||||
Layout.fillWidth:true
|
||||
height:parent.height
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
|
@ -262,7 +262,7 @@ TabContainer {
|
|||
}
|
||||
TextButtonB {
|
||||
id: echoCalibration
|
||||
enabled: SettingsModel.echoCancellationEnabled
|
||||
enabled: SettingsModel.echoCancellationEnabled && !SettingsModel.isInCall
|
||||
|
||||
text: qsTr('echoCancellationCalibrationLabel')
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue