diff --git a/linphone-app/assets/languages/en.ts b/linphone-app/assets/languages/en.ts
index 9cb9f4301..50aaa4eb6 100644
--- a/linphone-app/assets/languages/en.ts
+++ b/linphone-app/assets/languages/en.ts
@@ -423,6 +423,16 @@
callPause
HOLD CALL
+
+ attendedTransferComplete
+ 'COMPLETE ATTENDED TRANSFER' : Title button, design is in uppercase.
+ COMPLETE ATTENDED TRANSFER
+
+
+ attendedTransferCall
+ 'ATTENDED TRANSFER CALL' : Title button, design is in uppercase.
+ ATTENDED TRANSFER CALL
+
CallsWindow
diff --git a/linphone-app/src/app/cli/Cli.cpp b/linphone-app/src/app/cli/Cli.cpp
index 66fe7cff8..f21e5f0b0 100644
--- a/linphone-app/src/app/cli/Cli.cpp
+++ b/linphone-app/src/app/cli/Cli.cpp
@@ -58,7 +58,7 @@ static void cliCall (QHash &args) {
app->processArguments(args);
app->initContentApp();
}else
- CoreManager::getInstance()->getCallsListModel()->launchAudioCall(args["sip-address"]);
+ CoreManager::getInstance()->getCallsListModel()->launchAudioCall(args["sip-address"], "");
}
static void cliBye (QHash &args) {
@@ -89,7 +89,7 @@ static void cliJoinConference (QHash &args) {
}
args["method"] = QStringLiteral("join-conference");
- coreManager->getCallsListModel()->launchAudioCall(sipAddress, args);
+ coreManager->getCallsListModel()->launchAudioCall(sipAddress, "", args);
}
static void cliJoinConferenceAs (QHash &args) {
@@ -121,7 +121,7 @@ static void cliJoinConferenceAs (QHash &args) {
}
args["method"] = QStringLiteral("join-conference");
- coreManager->getCallsListModel()->launchAudioCall(toSipAddress, args);
+ coreManager->getCallsListModel()->launchAudioCall(toSipAddress, "", args);
}
static void cliInitiateConference (QHash &args) {
diff --git a/linphone-app/src/components/call/CallModel.cpp b/linphone-app/src/components/call/CallModel.cpp
index 06d309b35..ccbb54c45 100644
--- a/linphone-app/src/components/call/CallModel.cpp
+++ b/linphone-app/src/components/call/CallModel.cpp
@@ -45,45 +45,45 @@
using namespace std;
namespace {
- constexpr char AutoAnswerObjectName[] = "auto-answer-timer";
+constexpr char AutoAnswerObjectName[] = "auto-answer-timer";
}
CallModel::CallModel (shared_ptr call){
- Q_CHECK_PTR(call);
- mCall = call;
- mCall->setData("call-model", *this);
-
- updateIsInConference();
-
- CoreManager *coreManager = CoreManager::getInstance();
-
- // Deal with auto-answer.
- if (!isOutgoing()) {
- SettingsModel *settings = coreManager->getSettingsModel();
-
- if (settings->getAutoAnswerStatus()) {
- QTimer *timer = new QTimer(this);
- timer->setInterval(settings->getAutoAnswerDelay());
- timer->setSingleShot(true);
- timer->setObjectName(AutoAnswerObjectName);
-
- QObject::connect(timer, &QTimer::timeout, this, &CallModel::acceptWithAutoAnswerDelay);
- timer->start();
- }
- }
-
- CoreHandlers *coreHandlers = coreManager->getHandlers().get();
- QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &CallModel::handleCallStateChanged );
- QObject::connect(coreHandlers, &CoreHandlers::callEncryptionChanged, this, &CallModel::handleCallEncryptionChanged );
-
-// Update fields and make a search to know to who the call belong
- mMagicSearch = CoreManager::getInstance()->getCore()->createMagicSearch();
- mSearch = std::make_shared(this);
- QObject::connect(mSearch.get(), SIGNAL(searchReceived(std::list> )), this, SLOT(searchReceived(std::list>)));
- mMagicSearch->addListener(mSearch);
-
- mRemoteAddress = mCall->getRemoteAddress()->clone();
- mMagicSearch->getContactListFromFilterAsync(mRemoteAddress->getUsername(),mRemoteAddress->getDomain());
+ Q_CHECK_PTR(call);
+ mCall = call;
+ mCall->setData("call-model", *this);
+
+ updateIsInConference();
+
+ CoreManager *coreManager = CoreManager::getInstance();
+
+ // Deal with auto-answer.
+ if (!isOutgoing()) {
+ SettingsModel *settings = coreManager->getSettingsModel();
+
+ if (settings->getAutoAnswerStatus()) {
+ QTimer *timer = new QTimer(this);
+ timer->setInterval(settings->getAutoAnswerDelay());
+ timer->setSingleShot(true);
+ timer->setObjectName(AutoAnswerObjectName);
+
+ QObject::connect(timer, &QTimer::timeout, this, &CallModel::acceptWithAutoAnswerDelay);
+ timer->start();
+ }
+ }
+
+ CoreHandlers *coreHandlers = coreManager->getHandlers().get();
+ QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &CallModel::handleCallStateChanged );
+ QObject::connect(coreHandlers, &CoreHandlers::callEncryptionChanged, this, &CallModel::handleCallEncryptionChanged );
+
+ // Update fields and make a search to know to who the call belong
+ mMagicSearch = CoreManager::getInstance()->getCore()->createMagicSearch();
+ mSearch = std::make_shared(this);
+ QObject::connect(mSearch.get(), SIGNAL(searchReceived(std::list> )), this, SLOT(searchReceived(std::list>)));
+ mMagicSearch->addListener(mSearch);
+
+ mRemoteAddress = mCall->getRemoteAddress()->clone();
+ mMagicSearch->getContactListFromFilterAsync(mRemoteAddress->getUsername(),mRemoteAddress->getDomain());
}
CallModel::~CallModel () {
@@ -94,18 +94,18 @@ CallModel::~CallModel () {
// -----------------------------------------------------------------------------
QString CallModel::getPeerAddress () const {
- return Utils::coreStringToAppString(mRemoteAddress->asStringUriOnly());
+ return Utils::coreStringToAppString(mRemoteAddress->asStringUriOnly());
}
QString CallModel::getLocalAddress () const {
- return Utils::coreStringToAppString(mCall->getCallLog()->getLocalAddress()->asStringUriOnly());
+ return Utils::coreStringToAppString(mCall->getCallLog()->getLocalAddress()->asStringUriOnly());
}
QString CallModel::getFullPeerAddress () const {
- return Utils::coreStringToAppString(mRemoteAddress->asString());
+ return Utils::coreStringToAppString(mRemoteAddress->asString());
}
QString CallModel::getFullLocalAddress () const {
- return Utils::coreStringToAppString(mCall->getCallLog()->getLocalAddress()->asString());
+ return Utils::coreStringToAppString(mCall->getCallLog()->getLocalAddress()->asString());
}
// -----------------------------------------------------------------------------
@@ -123,520 +123,536 @@ ChatRoomModel * CallModel::getChatRoomModel() const{
// -----------------------------------------------------------------------------
void CallModel::setRecordFile (const shared_ptr &callParams) {
- callParams->setRecordFile(Utils::appStringToCoreString(
- CoreManager::getInstance()->getSettingsModel()->getSavedCallsFolder()
- .append(generateSavedFilename())
- .append(".mkv")
- ));
+ callParams->setRecordFile(Utils::appStringToCoreString(
+ CoreManager::getInstance()->getSettingsModel()->getSavedCallsFolder()
+ .append(generateSavedFilename())
+ .append(".mkv")
+ ));
}
void CallModel::setRecordFile (const shared_ptr &callParams, const QString &to) {
- const QString from(
- Utils::coreStringToAppString(
- CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->getUsername()
- )
- );
-
- callParams->setRecordFile(Utils::appStringToCoreString(
- CoreManager::getInstance()->getSettingsModel()->getSavedCallsFolder()
- .append(generateSavedFilename(from, to))
- .append(".mkv")
- ));
+ const QString from(
+ Utils::coreStringToAppString(
+ CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->getUsername()
+ )
+ );
+
+ callParams->setRecordFile(Utils::appStringToCoreString(
+ CoreManager::getInstance()->getSettingsModel()->getSavedCallsFolder()
+ .append(generateSavedFilename(from, to))
+ .append(".mkv")
+ ));
}
// -----------------------------------------------------------------------------
void CallModel::updateStats (const shared_ptr &callStats) {
- switch (callStats->getType()) {
- case linphone::StreamType::Text:
- case linphone::StreamType::Unknown:
- break;
-
- case linphone::StreamType::Audio:
- updateStats(callStats, mAudioStats);
- break;
- case linphone::StreamType::Video:
- updateStats(callStats, mVideoStats);
- break;
- }
-
- emit statsUpdated();
+ switch (callStats->getType()) {
+ case linphone::StreamType::Text:
+ case linphone::StreamType::Unknown:
+ break;
+
+ case linphone::StreamType::Audio:
+ updateStats(callStats, mAudioStats);
+ break;
+ case linphone::StreamType::Video:
+ updateStats(callStats, mVideoStats);
+ break;
+ }
+
+ emit statsUpdated();
}
// -----------------------------------------------------------------------------
float CallModel::getSpeakerVolumeGain () const {
- return mCall->getSpeakerVolumeGain();
+ return mCall->getSpeakerVolumeGain();
}
void CallModel::setSpeakerVolumeGain (float volume) {
- Q_ASSERT(volume >= 0.0f && volume <= 1.0f);
- mCall->setSpeakerVolumeGain(volume);
- emit speakerVolumeGainChanged(getSpeakerVolumeGain());
+ Q_ASSERT(volume >= 0.0f && volume <= 1.0f);
+ mCall->setSpeakerVolumeGain(volume);
+ emit speakerVolumeGainChanged(getSpeakerVolumeGain());
}
float CallModel::getMicroVolumeGain () const {
- return mCall->getMicrophoneVolumeGain();
+ return mCall->getMicrophoneVolumeGain();
}
void CallModel::setMicroVolumeGain (float volume) {
- Q_ASSERT(volume >= 0.0f && volume <= 1.0f);
- mCall->setMicrophoneVolumeGain(volume);
- emit microVolumeGainChanged(getMicroVolumeGain());
+ Q_ASSERT(volume >= 0.0f && volume <= 1.0f);
+ mCall->setMicrophoneVolumeGain(volume);
+ emit microVolumeGainChanged(getMicroVolumeGain());
}
// -----------------------------------------------------------------------------
void CallModel::notifyCameraFirstFrameReceived (unsigned int width, unsigned int height) {
- if (mNotifyCameraFirstFrameReceived) {
- mNotifyCameraFirstFrameReceived = false;
- emit cameraFirstFrameReceived(width, height);
- }
+ if (mNotifyCameraFirstFrameReceived) {
+ mNotifyCameraFirstFrameReceived = false;
+ emit cameraFirstFrameReceived(width, height);
+ }
}
// -----------------------------------------------------------------------------
void CallModel::accept () {
- accept(false);
+ accept(false);
}
void CallModel::acceptWithVideo () {
- accept(true);
+ accept(true);
}
void CallModel::terminate () {
- CoreManager *core = CoreManager::getInstance();
- core->lockVideoRender();
- mCall->terminate();
- core->unlockVideoRender();
+ CoreManager *core = CoreManager::getInstance();
+ core->lockVideoRender();
+ mCall->terminate();
+ core->unlockVideoRender();
}
// -----------------------------------------------------------------------------
void CallModel::askForTransfer () {
- CoreManager::getInstance()->getCallsListModel()->askForTransfer(this);
+ CoreManager::getInstance()->getCallsListModel()->askForTransfer(this);
+}
+
+void CallModel::askForAttendedTransfer () {
+ CoreManager::getInstance()->getCallsListModel()->askForAttendedTransfer(this);
}
bool CallModel::transferTo (const QString &sipAddress) {
- bool status = !!mCall->transfer(Utils::appStringToCoreString(sipAddress));
- if (status)
- qWarning() << QStringLiteral("Unable to transfer: `%1`.").arg(sipAddress);
- return status;
+ bool failure = !!mCall->transferTo(Utils::interpretUrl(sipAddress));
+ if (failure)
+ qWarning() << QStringLiteral("Unable to transfer: `%1`.").arg(sipAddress);
+ return !failure;
}
+bool CallModel::transferToAnother (const QString &peerAddress) {
+ qInfo() << QStringLiteral("Transferring to another: `%1`.").arg(peerAddress);
+ CallModel *transferCallModel = CoreManager::getInstance()->getCallsListModel()->findCallModelFromPeerAddress(peerAddress);
+ if (transferCallModel == nullptr) {
+ qWarning() << QStringLiteral("Unable to transfer to another: `%1` (peer not found)").arg(peerAddress);
+ return false;
+ }
+ bool failure = !!transferCallModel->mCall->transferToAnother(mCall);
+ if (failure)
+ qWarning() << QStringLiteral("Unable to transfer to another: `%1` (transfer failed)").arg(peerAddress);
+ return !failure;
+}
// -----------------------------------------------------------------------------
void CallModel::acceptVideoRequest () {
- shared_ptr params = CoreManager::getInstance()->getCore()->createCallParams(mCall);
- params->enableVideo(true);
-
- mCall->acceptUpdate(params);
+ shared_ptr params = CoreManager::getInstance()->getCore()->createCallParams(mCall);
+ params->enableVideo(true);
+
+ mCall->acceptUpdate(params);
}
void CallModel::rejectVideoRequest () {
- shared_ptr params = CoreManager::getInstance()->getCore()->createCallParams(mCall);
- params->enableVideo(false);
-
- mCall->acceptUpdate(params);
+ shared_ptr params = CoreManager::getInstance()->getCore()->createCallParams(mCall);
+ params->enableVideo(false);
+
+ mCall->acceptUpdate(params);
}
void CallModel::takeSnapshot () {
- static QString oldName;
- QString newName(generateSavedFilename().append(".jpg"));
-
- if (newName == oldName) {
- qWarning() << QStringLiteral("Unable to take snapshot. Wait one second.");
- return;
- }
- oldName = newName;
-
- qInfo() << QStringLiteral("Take snapshot of call:") << this;
-
- const QString filePath(CoreManager::getInstance()->getSettingsModel()->getSavedScreenshotsFolder().append(newName));
- mCall->takeVideoSnapshot(Utils::appStringToCoreString(filePath));
- App::getInstance()->getNotifier()->notifySnapshotWasTaken(filePath);
+ static QString oldName;
+ QString newName(generateSavedFilename().append(".jpg"));
+
+ if (newName == oldName) {
+ qWarning() << QStringLiteral("Unable to take snapshot. Wait one second.");
+ return;
+ }
+ oldName = newName;
+
+ qInfo() << QStringLiteral("Take snapshot of call:") << this;
+
+ const QString filePath(CoreManager::getInstance()->getSettingsModel()->getSavedScreenshotsFolder().append(newName));
+ mCall->takeVideoSnapshot(Utils::appStringToCoreString(filePath));
+ App::getInstance()->getNotifier()->notifySnapshotWasTaken(filePath);
}
void CallModel::startRecording () {
- if (mRecording)
- return;
-
- qInfo() << QStringLiteral("Start recording call:") << this;
-
- mCall->startRecording();
- mRecording = true;
-
- emit recordingChanged(true);
+ if (mRecording)
+ return;
+
+ qInfo() << QStringLiteral("Start recording call:") << this;
+
+ mCall->startRecording();
+ mRecording = true;
+
+ emit recordingChanged(true);
}
void CallModel::stopRecording () {
- if (!mRecording)
- return;
-
- qInfo() << QStringLiteral("Stop recording call:") << this;
-
- mRecording = false;
- mCall->stopRecording();
-
- App::getInstance()->getNotifier()->notifyRecordingCompleted(
- Utils::coreStringToAppString(mCall->getParams()->getRecordFile())
- );
-
- emit recordingChanged(false);
+ if (!mRecording)
+ return;
+
+ qInfo() << QStringLiteral("Stop recording call:") << this;
+
+ mRecording = false;
+ mCall->stopRecording();
+
+ App::getInstance()->getNotifier()->notifyRecordingCompleted(
+ Utils::coreStringToAppString(mCall->getParams()->getRecordFile())
+ );
+
+ emit recordingChanged(false);
}
// -----------------------------------------------------------------------------
void CallModel::handleCallEncryptionChanged (const shared_ptr &call) {
- if (call == mCall)
- emit securityUpdated();
+ if (call == mCall)
+ emit securityUpdated();
}
void CallModel::handleCallStateChanged (const shared_ptr &call, linphone::Call::State state) {
- if (call != mCall)
- return;
-
- updateIsInConference();
-
- switch (state) {
- case linphone::Call::State::Error:
- case linphone::Call::State::End:
- setCallErrorFromReason(call->getReason());
- stopAutoAnswerTimer();
- stopRecording();
- mPausedByRemote = false;
- break;
-
- case linphone::Call::State::StreamsRunning: {
- if (!mWasConnected && CoreManager::getInstance()->getSettingsModel()->getAutomaticallyRecordCalls()) {
- startRecording();
- mWasConnected = true;
- }
- mPausedByRemote = false;
- break;
- }
- case linphone::Call::State::Connected:
- case linphone::Call::State::Referred:
- case linphone::Call::State::Released:
- mPausedByRemote = false;
- break;
-
- case linphone::Call::State::PausedByRemote:
- mNotifyCameraFirstFrameReceived = true;
- mPausedByRemote = true;
- break;
-
- case linphone::Call::State::Pausing:
- mNotifyCameraFirstFrameReceived = true;
- mPausedByUser = true;
- break;
-
- case linphone::Call::State::Resuming:
- mPausedByUser = false;
- break;
-
- case linphone::Call::State::UpdatedByRemote:
- if (!mCall->getCurrentParams()->videoEnabled() && mCall->getRemoteParams()->videoEnabled()) {
- mCall->deferUpdate();
- emit videoRequested();
- }
- break;
-
- case linphone::Call::State::Idle:
- case linphone::Call::State::IncomingReceived:
- case linphone::Call::State::OutgoingInit:
- case linphone::Call::State::OutgoingProgress:
- case linphone::Call::State::OutgoingRinging:
- case linphone::Call::State::OutgoingEarlyMedia:
- case linphone::Call::State::Paused:
- case linphone::Call::State::IncomingEarlyMedia:
- case linphone::Call::State::Updating:
- case linphone::Call::State::EarlyUpdatedByRemote:
- case linphone::Call::State::EarlyUpdating:
- break;
- }
-
- emit statusChanged(getStatus());
+ if (call != mCall)
+ return;
+
+ updateIsInConference();
+
+ switch (state) {
+ case linphone::Call::State::Error:
+ case linphone::Call::State::End:
+ setCallErrorFromReason(call->getReason());
+ stopAutoAnswerTimer();
+ stopRecording();
+ mPausedByRemote = false;
+ break;
+
+ case linphone::Call::State::StreamsRunning: {
+ if (!mWasConnected && CoreManager::getInstance()->getSettingsModel()->getAutomaticallyRecordCalls()) {
+ startRecording();
+ mWasConnected = true;
+ }
+ mPausedByRemote = false;
+ break;
+ }
+ case linphone::Call::State::Connected:
+ case linphone::Call::State::Referred:
+ case linphone::Call::State::Released:
+ mPausedByRemote = false;
+ break;
+
+ case linphone::Call::State::PausedByRemote:
+ mNotifyCameraFirstFrameReceived = true;
+ mPausedByRemote = true;
+ break;
+
+ case linphone::Call::State::Pausing:
+ mNotifyCameraFirstFrameReceived = true;
+ mPausedByUser = true;
+ break;
+
+ case linphone::Call::State::Resuming:
+ mPausedByUser = false;
+ break;
+
+ case linphone::Call::State::UpdatedByRemote:
+ if (!mCall->getCurrentParams()->videoEnabled() && mCall->getRemoteParams()->videoEnabled()) {
+ mCall->deferUpdate();
+ emit videoRequested();
+ }
+ break;
+
+ case linphone::Call::State::Idle:
+ case linphone::Call::State::IncomingReceived:
+ case linphone::Call::State::OutgoingInit:
+ case linphone::Call::State::OutgoingProgress:
+ case linphone::Call::State::OutgoingRinging:
+ case linphone::Call::State::OutgoingEarlyMedia:
+ case linphone::Call::State::Paused:
+ case linphone::Call::State::IncomingEarlyMedia:
+ case linphone::Call::State::Updating:
+ case linphone::Call::State::EarlyUpdatedByRemote:
+ case linphone::Call::State::EarlyUpdating:
+ break;
+ }
+
+ emit statusChanged(getStatus());
}
// -----------------------------------------------------------------------------
void CallModel::accept (bool withVideo) {
- stopAutoAnswerTimer();
- CoreManager *coreManager = CoreManager::getInstance();
-
- QQuickWindow *callsWindow = App::getInstance()->getCallsWindow();
- if (callsWindow) {
- if (coreManager->getSettingsModel()->getKeepCallsWindowInBackground()) {
- if (!callsWindow->isVisible())
- callsWindow->showMinimized();
- } else
- App::smartShowWindow(callsWindow);
- }
- qApp->processEvents(); // Process GUI events before accepting in order to be synchronized with Call objects and be ready to get SDK events
- shared_ptr core = coreManager->getCore();
- shared_ptr params = core->createCallParams(mCall);
- params->enableVideo(withVideo);
- setRecordFile(params);
-
- mCall->acceptWithParams(params);
+ stopAutoAnswerTimer();
+ CoreManager *coreManager = CoreManager::getInstance();
+
+ QQuickWindow *callsWindow = App::getInstance()->getCallsWindow();
+ if (callsWindow) {
+ if (coreManager->getSettingsModel()->getKeepCallsWindowInBackground()) {
+ if (!callsWindow->isVisible())
+ callsWindow->showMinimized();
+ } else
+ App::smartShowWindow(callsWindow);
+ }
+ qApp->processEvents(); // Process GUI events before accepting in order to be synchronized with Call objects and be ready to get SDK events
+ shared_ptr core = coreManager->getCore();
+ shared_ptr params = core->createCallParams(mCall);
+ params->enableVideo(withVideo);
+ setRecordFile(params);
+
+ mCall->acceptWithParams(params);
}
// -----------------------------------------------------------------------------
void CallModel::updateIsInConference () {
- if (mIsInConference != mCall->getCurrentParams()->getLocalConferenceMode()) {
- mIsInConference = !mIsInConference;
- }
- emit isInConferenceChanged(mIsInConference);
+ if (mIsInConference != mCall->getCurrentParams()->getLocalConferenceMode()) {
+ mIsInConference = !mIsInConference;
+ }
+ emit isInConferenceChanged(mIsInConference);
}
// -----------------------------------------------------------------------------
void CallModel::stopAutoAnswerTimer () const {
- QTimer *timer = findChild(AutoAnswerObjectName, Qt::FindDirectChildrenOnly);
- if (timer) {
- timer->stop();
- timer->deleteLater();
- }
+ QTimer *timer = findChild(AutoAnswerObjectName, Qt::FindDirectChildrenOnly);
+ if (timer) {
+ timer->stop();
+ timer->deleteLater();
+ }
}
// -----------------------------------------------------------------------------
CallModel::CallStatus CallModel::getStatus () const {
- switch (mCall->getState()) {
- case linphone::Call::State::Connected:
- case linphone::Call::State::StreamsRunning:
- return CallStatusConnected;
-
- case linphone::Call::State::End:
- case linphone::Call::State::Error:
- case linphone::Call::State::Referred:
- case linphone::Call::State::Released:
- return CallStatusEnded;
-
- case linphone::Call::State::Paused:
- case linphone::Call::State::PausedByRemote:
- case linphone::Call::State::Pausing:
- case linphone::Call::State::Resuming:
- return CallStatusPaused;
-
- case linphone::Call::State::Updating:
- case linphone::Call::State::UpdatedByRemote:
- return mPausedByRemote ? CallStatusPaused : CallStatusConnected;
-
- case linphone::Call::State::EarlyUpdatedByRemote:
- case linphone::Call::State::EarlyUpdating:
- case linphone::Call::State::Idle:
- case linphone::Call::State::IncomingEarlyMedia:
- case linphone::Call::State::IncomingReceived:
- case linphone::Call::State::OutgoingEarlyMedia:
- case linphone::Call::State::OutgoingInit:
- case linphone::Call::State::OutgoingProgress:
- case linphone::Call::State::OutgoingRinging:
- break;
- }
-
- return mCall->getDir() == linphone::Call::Dir::Incoming ? CallStatusIncoming : CallStatusOutgoing;
+ switch (mCall->getState()) {
+ case linphone::Call::State::Connected:
+ case linphone::Call::State::StreamsRunning:
+ return CallStatusConnected;
+
+ case linphone::Call::State::End:
+ case linphone::Call::State::Error:
+ case linphone::Call::State::Referred:
+ case linphone::Call::State::Released:
+ return CallStatusEnded;
+
+ case linphone::Call::State::Paused:
+ case linphone::Call::State::PausedByRemote:
+ case linphone::Call::State::Pausing:
+ case linphone::Call::State::Resuming:
+ return CallStatusPaused;
+
+ case linphone::Call::State::Updating:
+ case linphone::Call::State::UpdatedByRemote:
+ return mPausedByRemote ? CallStatusPaused : CallStatusConnected;
+
+ case linphone::Call::State::EarlyUpdatedByRemote:
+ case linphone::Call::State::EarlyUpdating:
+ case linphone::Call::State::Idle:
+ case linphone::Call::State::IncomingEarlyMedia:
+ case linphone::Call::State::IncomingReceived:
+ case linphone::Call::State::OutgoingEarlyMedia:
+ case linphone::Call::State::OutgoingInit:
+ case linphone::Call::State::OutgoingProgress:
+ case linphone::Call::State::OutgoingRinging:
+ break;
+ }
+
+ return mCall->getDir() == linphone::Call::Dir::Incoming ? CallStatusIncoming : CallStatusOutgoing;
}
// -----------------------------------------------------------------------------
void CallModel::acceptWithAutoAnswerDelay () {
- CoreManager *coreManager = CoreManager::getInstance();
- SettingsModel *settingsModel = coreManager->getSettingsModel();
-
- // Use auto-answer if activated and it's the only call.
- if (settingsModel->getAutoAnswerStatus() && coreManager->getCore()->getCallsNb() == 1) {
- if (mCall->getRemoteParams()->videoEnabled() && settingsModel->getAutoAnswerVideoStatus() && settingsModel->getVideoSupported())
- acceptWithVideo();
- else
- accept();
- }
+ CoreManager *coreManager = CoreManager::getInstance();
+ SettingsModel *settingsModel = coreManager->getSettingsModel();
+
+ // Use auto-answer if activated and it's the only call.
+ if (settingsModel->getAutoAnswerStatus() && coreManager->getCore()->getCallsNb() == 1) {
+ if (mCall->getRemoteParams()->videoEnabled() && settingsModel->getAutoAnswerVideoStatus() && settingsModel->getVideoSupported())
+ acceptWithVideo();
+ else
+ accept();
+ }
}
// -----------------------------------------------------------------------------
QString CallModel::getCallError () const {
- return mCallError;
+ return mCallError;
}
void CallModel::setCallErrorFromReason (linphone::Reason reason) {
- switch (reason) {
- case linphone::Reason::Declined:
- mCallError = tr("callErrorDeclined");
- break;
- case linphone::Reason::NotFound:
- mCallError = tr("callErrorNotFound");
- break;
- case linphone::Reason::Busy:
- mCallError = tr("callErrorBusy");
- break;
- case linphone::Reason::NotAcceptable:
- mCallError = tr("callErrorNotAcceptable");
- break;
- default:
- break;
- }
-
- if (!mCallError.isEmpty())
- qInfo() << QStringLiteral("Call terminated with error (%1):").arg(mCallError) << this;
-
- emit callErrorChanged(mCallError);
+ switch (reason) {
+ case linphone::Reason::Declined:
+ mCallError = tr("callErrorDeclined");
+ break;
+ case linphone::Reason::NotFound:
+ mCallError = tr("callErrorNotFound");
+ break;
+ case linphone::Reason::Busy:
+ mCallError = tr("callErrorBusy");
+ break;
+ case linphone::Reason::NotAcceptable:
+ mCallError = tr("callErrorNotAcceptable");
+ break;
+ default:
+ break;
+ }
+
+ if (!mCallError.isEmpty())
+ qInfo() << QStringLiteral("Call terminated with error (%1):").arg(mCallError) << this;
+
+ emit callErrorChanged(mCallError);
}
// -----------------------------------------------------------------------------
int CallModel::getDuration () const {
- return mCall->getDuration();
+ return mCall->getDuration();
}
float CallModel::getQuality () const {
- return mCall->getCurrentQuality();
+ return mCall->getCurrentQuality();
}
// -----------------------------------------------------------------------------
float CallModel::getSpeakerVu () const {
- if (mCall->getState() == linphone::Call::State::StreamsRunning)
- return MediastreamerUtils::computeVu(mCall->getPlayVolume());
- return 0.0;
+ if (mCall->getState() == linphone::Call::State::StreamsRunning)
+ return MediastreamerUtils::computeVu(mCall->getPlayVolume());
+ return 0.0;
}
float CallModel::getMicroVu () const {
- if (mCall->getState() == linphone::Call::State::StreamsRunning)
- return MediastreamerUtils::computeVu(mCall->getRecordVolume());
- return 0.0;
+ if (mCall->getState() == linphone::Call::State::StreamsRunning)
+ return MediastreamerUtils::computeVu(mCall->getRecordVolume());
+ return 0.0;
}
// -----------------------------------------------------------------------------
bool CallModel::getSpeakerMuted () const {
- return mCall->getSpeakerMuted();
+ return mCall->getSpeakerMuted();
}
void CallModel::setSpeakerMuted (bool status) {
- if (status == getSpeakerMuted())
- return;
-
- mCall->setSpeakerMuted(status);
- emit speakerMutedChanged(getSpeakerMuted());
+ if (status == getSpeakerMuted())
+ return;
+
+ mCall->setSpeakerMuted(status);
+ emit speakerMutedChanged(getSpeakerMuted());
}
// -----------------------------------------------------------------------------
bool CallModel::getMicroMuted () const {
- return mCall->getMicrophoneMuted();
+ return mCall->getMicrophoneMuted();
}
void CallModel::setMicroMuted (bool status) {
- if (status == getMicroMuted())
- return;
-
- mCall->setMicrophoneMuted(status);
- emit microMutedChanged(getMicroMuted());
+ if (status == getMicroMuted())
+ return;
+
+ mCall->setMicrophoneMuted(status);
+ emit microMutedChanged(getMicroMuted());
}
// -----------------------------------------------------------------------------
bool CallModel::getPausedByUser () const {
- return mPausedByUser;
+ return mPausedByUser;
}
void CallModel::setPausedByUser (bool status) {
- switch (mCall->getState()) {
- case linphone::Call::State::Connected:
- case linphone::Call::State::StreamsRunning:
- case linphone::Call::State::Paused:
- case linphone::Call::State::PausedByRemote:
- break;
- default: return;
- }
-
- if (status) {
- if (!mPausedByUser)
- mCall->pause();
- return;
- }
-
- if (mPausedByUser)
- mCall->resume();
+ switch (mCall->getState()) {
+ case linphone::Call::State::Connected:
+ case linphone::Call::State::StreamsRunning:
+ case linphone::Call::State::Paused:
+ case linphone::Call::State::PausedByRemote:
+ break;
+ default: return;
+ }
+
+ if (status) {
+ if (!mPausedByUser)
+ mCall->pause();
+ return;
+ }
+
+ if (mPausedByUser)
+ mCall->resume();
}
// -----------------------------------------------------------------------------
bool CallModel::getVideoEnabled () const {
- shared_ptr params = mCall->getCurrentParams();
- return params && params->videoEnabled() && getStatus() == CallStatusConnected;
+ shared_ptr params = mCall->getCurrentParams();
+ return params && params->videoEnabled() && getStatus() == CallStatusConnected;
}
void CallModel::setVideoEnabled (bool status) {
- shared_ptr core = CoreManager::getInstance()->getCore();
- if (!core->videoSupported()) {
- qWarning() << QStringLiteral("Unable to update video call property. (Video not supported.)");
- return;
- }
-
- switch (mCall->getState()) {
- case linphone::Call::State::Connected:
- case linphone::Call::State::StreamsRunning:
- break;
- default: return;
- }
-
- if (status == getVideoEnabled())
- return;
-
- shared_ptr params = core->createCallParams(mCall);
- params->enableVideo(status);
-
- mCall->update(params);
+ shared_ptr core = CoreManager::getInstance()->getCore();
+ if (!core->videoSupported()) {
+ qWarning() << QStringLiteral("Unable to update video call property. (Video not supported.)");
+ return;
+ }
+
+ switch (mCall->getState()) {
+ case linphone::Call::State::Connected:
+ case linphone::Call::State::StreamsRunning:
+ break;
+ default: return;
+ }
+
+ if (status == getVideoEnabled())
+ return;
+
+ shared_ptr params = core->createCallParams(mCall);
+ params->enableVideo(status);
+
+ mCall->update(params);
}
// -----------------------------------------------------------------------------
bool CallModel::getUpdating () const {
- switch (mCall->getState()) {
- case linphone::Call::State::Connected:
- case linphone::Call::State::StreamsRunning:
- case linphone::Call::State::Paused:
- case linphone::Call::State::PausedByRemote:
- return false;
-
- default:
- break;
- }
-
- return true;
+ switch (mCall->getState()) {
+ case linphone::Call::State::Connected:
+ case linphone::Call::State::StreamsRunning:
+ case linphone::Call::State::Paused:
+ case linphone::Call::State::PausedByRemote:
+ return false;
+
+ default:
+ break;
+ }
+
+ return true;
}
bool CallModel::getRecording () const {
- return mRecording;
+ return mRecording;
}
// -----------------------------------------------------------------------------
void CallModel::sendDtmf (const QString &dtmf) {
- const char key = dtmf.constData()[0].toLatin1();
- qInfo() << QStringLiteral("Send dtmf: `%1`.").arg(key);
- mCall->sendDtmf(key);
- CoreManager::getInstance()->getCore()->playDtmf(key, DtmfSoundDelay);
+ const char key = dtmf.constData()[0].toLatin1();
+ qInfo() << QStringLiteral("Send dtmf: `%1`.").arg(key);
+ mCall->sendDtmf(key);
+ CoreManager::getInstance()->getCore()->playDtmf(key, DtmfSoundDelay);
}
// -----------------------------------------------------------------------------
void CallModel::verifyAuthenticationToken (bool verify) {
- mCall->setAuthenticationTokenVerified(verify);
- emit securityUpdated();
+ mCall->setAuthenticationTokenVerified(verify);
+ emit securityUpdated();
}
// -----------------------------------------------------------------------------
void CallModel::updateStreams () {
- mCall->update(nullptr);
+ mCall->update(nullptr);
}
void CallModel::toggleSpeakerMute(){
- setSpeakerMuted(!getSpeakerMuted());
+ setSpeakerMuted(!getSpeakerMuted());
}
// -----------------------------------------------------------------------------
@@ -687,181 +703,201 @@ void CallModel::setRemoteDisplayName(const std::string& name){
}
emit fullPeerAddressChanged();
}
+
+QString CallModel::getTransferAddress () const {
+ return mTransferAddress;
+}
+
+void CallModel::setTransferAddress (const QString &transferAddress) {
+ mTransferAddress = transferAddress;
+ emit transferAddressChanged(mTransferAddress);
+}
+
+void CallModel::prepareTransfert(shared_ptr call, const QString& transfertAddress){
+ if( call && transfertAddress != ""){
+ CallModel * model = &call->getData("call-model");
+ model->setTransferAddress(transfertAddress);
+ }
+}
+
+std::shared_ptr CallModel::getRemoteAddress()const{
+ return mRemoteAddress;
+}
// -----------------------------------------------------------------------------
CallModel::CallEncryption CallModel::getEncryption () const {
- return static_cast(mCall->getCurrentParams()->getMediaEncryption());
+ return static_cast(mCall->getCurrentParams()->getMediaEncryption());
}
bool CallModel::isSecured () const {
- shared_ptr params = mCall->getCurrentParams();
- linphone::MediaEncryption encryption = params->getMediaEncryption();
- return (
- encryption == linphone::MediaEncryption::ZRTP && mCall->getAuthenticationTokenVerified()
- ) || encryption == linphone::MediaEncryption::SRTP || encryption == linphone::MediaEncryption::DTLS;
+ shared_ptr params = mCall->getCurrentParams();
+ linphone::MediaEncryption encryption = params->getMediaEncryption();
+ return (
+ encryption == linphone::MediaEncryption::ZRTP && mCall->getAuthenticationTokenVerified()
+ ) || encryption == linphone::MediaEncryption::SRTP || encryption == linphone::MediaEncryption::DTLS;
}
// -----------------------------------------------------------------------------
QString CallModel::getLocalSas () const {
- QString token = Utils::coreStringToAppString(mCall->getAuthenticationToken());
- return mCall->getDir() == linphone::Call::Dir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper();
+ QString token = Utils::coreStringToAppString(mCall->getAuthenticationToken());
+ return mCall->getDir() == linphone::Call::Dir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper();
}
QString CallModel::getRemoteSas () const {
- QString token = Utils::coreStringToAppString(mCall->getAuthenticationToken());
- return mCall->getDir() != linphone::Call::Dir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper();
+ QString token = Utils::coreStringToAppString(mCall->getAuthenticationToken());
+ return mCall->getDir() != linphone::Call::Dir::Incoming ? token.left(2).toUpper() : token.right(2).toUpper();
}
// -----------------------------------------------------------------------------
QString CallModel::getSecuredString () const {
- switch (mCall->getCurrentParams()->getMediaEncryption()) {
- case linphone::MediaEncryption::SRTP:
- return QStringLiteral("SRTP");
- case linphone::MediaEncryption::ZRTP:
- return QStringLiteral("ZRTP");
- case linphone::MediaEncryption::DTLS:
- return QStringLiteral("DTLS");
- case linphone::MediaEncryption::None:
- break;
- }
-
- return QString("");
+ switch (mCall->getCurrentParams()->getMediaEncryption()) {
+ case linphone::MediaEncryption::SRTP:
+ return QStringLiteral("SRTP");
+ case linphone::MediaEncryption::ZRTP:
+ return QStringLiteral("ZRTP");
+ case linphone::MediaEncryption::DTLS:
+ return QStringLiteral("DTLS");
+ case linphone::MediaEncryption::None:
+ break;
+ }
+
+ return QString("");
}
// -----------------------------------------------------------------------------
QVariantList CallModel::getAudioStats () const {
- return mAudioStats;
+ return mAudioStats;
}
QVariantList CallModel::getVideoStats () const {
- return mVideoStats;
+ return mVideoStats;
}
// -----------------------------------------------------------------------------
static inline QVariantMap createStat (const QString &key, const QString &value) {
- QVariantMap m;
- m["key"] = key;
- m["value"] = value;
- return m;
+ QVariantMap m;
+ m["key"] = key;
+ m["value"] = value;
+ return m;
}
void CallModel::updateStats (const shared_ptr &callStats, QVariantList &statsList) {
- shared_ptr params = mCall->getCurrentParams();
- shared_ptr payloadType;
-
- switch (callStats->getType()) {
- case linphone::StreamType::Audio:
- payloadType = params->getUsedAudioPayloadType();
- break;
- case linphone::StreamType::Video:
- payloadType = params->getUsedVideoPayloadType();
- break;
- default:
- return;
- }
-
- QString family;
- switch (callStats->getIpFamilyOfRemote()) {
- case linphone::AddressFamily::Inet:
- family = QStringLiteral("IPv4");
- break;
- case linphone::AddressFamily::Inet6:
- family = QStringLiteral("IPv6");
- break;
- default:
- family = QStringLiteral("Unknown");
- break;
- }
-
- statsList.clear();
-
- statsList << createStat(tr("callStatsCodec"), payloadType
- ? QStringLiteral("%1 / %2kHz").arg(Utils::coreStringToAppString(payloadType->getMimeType())).arg(payloadType->getClockRate() / 1000)
- : QString(""));
- statsList << createStat(tr("callStatsUploadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getUploadBandwidth())));
- statsList << createStat(tr("callStatsDownloadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getDownloadBandwidth())));
- statsList << createStat(tr("callStatsIceState"), iceStateToString(callStats->getIceState()));
- statsList << createStat(tr("callStatsIpFamily"), family);
- statsList << createStat(tr("callStatsSenderLossRate"), QStringLiteral("%1 %").arg(static_cast(callStats->getSenderLossRate())));
- statsList << createStat(tr("callStatsReceiverLossRate"), QStringLiteral("%1 %").arg(static_cast(callStats->getReceiverLossRate())));
-
- switch (callStats->getType()) {
- case linphone::StreamType::Audio:
- statsList << createStat(tr("callStatsJitterBuffer"), QStringLiteral("%1 ms").arg(callStats->getJitterBufferSizeMs()));
- break;
- case linphone::StreamType::Video: {
- statsList << createStat(tr("callStatsEstimatedDownloadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getEstimatedDownloadBandwidth())));
- const QString sentVideoDefinitionName = Utils::coreStringToAppString(params->getSentVideoDefinition()->getName());
- const QString sentVideoDefinition = QStringLiteral("%1x%2")
- .arg(params->getSentVideoDefinition()->getWidth())
- .arg(params->getSentVideoDefinition()->getHeight());
-
- statsList << createStat(tr("callStatsSentVideoDefinition"), sentVideoDefinition == sentVideoDefinitionName
- ? sentVideoDefinition
- : QStringLiteral("%1 (%2)").arg(sentVideoDefinition).arg(sentVideoDefinitionName));
-
- const QString receivedVideoDefinitionName = Utils::coreStringToAppString(params->getReceivedVideoDefinition()->getName());
- const QString receivedVideoDefinition = QString("%1x%2")
- .arg(params->getReceivedVideoDefinition()->getWidth())
- .arg(params->getReceivedVideoDefinition()->getHeight());
-
- statsList << createStat(tr("callStatsReceivedVideoDefinition"), receivedVideoDefinition == receivedVideoDefinitionName
- ? receivedVideoDefinition
- : QString("%1 (%2)").arg(receivedVideoDefinition).arg(receivedVideoDefinitionName));
-
- statsList << createStat(tr("callStatsReceivedFramerate"), QStringLiteral("%1 FPS").arg(static_cast(params->getReceivedFramerate())));
- statsList << createStat(tr("callStatsSentFramerate"), QStringLiteral("%1 FPS").arg(static_cast(params->getSentFramerate())));
- } break;
-
- default:
- break;
- }
+ shared_ptr params = mCall->getCurrentParams();
+ shared_ptr payloadType;
+
+ switch (callStats->getType()) {
+ case linphone::StreamType::Audio:
+ payloadType = params->getUsedAudioPayloadType();
+ break;
+ case linphone::StreamType::Video:
+ payloadType = params->getUsedVideoPayloadType();
+ break;
+ default:
+ return;
+ }
+
+ QString family;
+ switch (callStats->getIpFamilyOfRemote()) {
+ case linphone::AddressFamily::Inet:
+ family = QStringLiteral("IPv4");
+ break;
+ case linphone::AddressFamily::Inet6:
+ family = QStringLiteral("IPv6");
+ break;
+ default:
+ family = QStringLiteral("Unknown");
+ break;
+ }
+
+ statsList.clear();
+
+ statsList << createStat(tr("callStatsCodec"), payloadType
+ ? QStringLiteral("%1 / %2kHz").arg(Utils::coreStringToAppString(payloadType->getMimeType())).arg(payloadType->getClockRate() / 1000)
+ : QString(""));
+ statsList << createStat(tr("callStatsUploadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getUploadBandwidth())));
+ statsList << createStat(tr("callStatsDownloadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getDownloadBandwidth())));
+ statsList << createStat(tr("callStatsIceState"), iceStateToString(callStats->getIceState()));
+ statsList << createStat(tr("callStatsIpFamily"), family);
+ statsList << createStat(tr("callStatsSenderLossRate"), QStringLiteral("%1 %").arg(static_cast(callStats->getSenderLossRate())));
+ statsList << createStat(tr("callStatsReceiverLossRate"), QStringLiteral("%1 %").arg(static_cast(callStats->getReceiverLossRate())));
+
+ switch (callStats->getType()) {
+ case linphone::StreamType::Audio:
+ statsList << createStat(tr("callStatsJitterBuffer"), QStringLiteral("%1 ms").arg(callStats->getJitterBufferSizeMs()));
+ break;
+ case linphone::StreamType::Video: {
+ statsList << createStat(tr("callStatsEstimatedDownloadBandwidth"), QStringLiteral("%1 kbits/s").arg(int(callStats->getEstimatedDownloadBandwidth())));
+ const QString sentVideoDefinitionName = Utils::coreStringToAppString(params->getSentVideoDefinition()->getName());
+ const QString sentVideoDefinition = QStringLiteral("%1x%2")
+ .arg(params->getSentVideoDefinition()->getWidth())
+ .arg(params->getSentVideoDefinition()->getHeight());
+
+ statsList << createStat(tr("callStatsSentVideoDefinition"), sentVideoDefinition == sentVideoDefinitionName
+ ? sentVideoDefinition
+ : QStringLiteral("%1 (%2)").arg(sentVideoDefinition).arg(sentVideoDefinitionName));
+
+ const QString receivedVideoDefinitionName = Utils::coreStringToAppString(params->getReceivedVideoDefinition()->getName());
+ const QString receivedVideoDefinition = QString("%1x%2")
+ .arg(params->getReceivedVideoDefinition()->getWidth())
+ .arg(params->getReceivedVideoDefinition()->getHeight());
+
+ statsList << createStat(tr("callStatsReceivedVideoDefinition"), receivedVideoDefinition == receivedVideoDefinitionName
+ ? receivedVideoDefinition
+ : QString("%1 (%2)").arg(receivedVideoDefinition).arg(receivedVideoDefinitionName));
+
+ statsList << createStat(tr("callStatsReceivedFramerate"), QStringLiteral("%1 FPS").arg(static_cast(params->getReceivedFramerate())));
+ statsList << createStat(tr("callStatsSentFramerate"), QStringLiteral("%1 FPS").arg(static_cast(params->getSentFramerate())));
+ } break;
+
+ default:
+ break;
+ }
}
// -----------------------------------------------------------------------------
QString CallModel::iceStateToString (linphone::IceState state) const {
- switch (state) {
- case linphone::IceState::NotActivated:
- return tr("iceStateNotActivated");
- case linphone::IceState::Failed:
- return tr("iceStateFailed");
- case linphone::IceState::InProgress:
- return tr("iceStateInProgress");
- case linphone::IceState::ReflexiveConnection:
- return tr("iceStateReflexiveConnection");
- case linphone::IceState::HostConnection:
- return tr("iceStateHostConnection");
- case linphone::IceState::RelayConnection:
- return tr("iceStateRelayConnection");
- }
-
- return tr("iceStateInvalid");
+ switch (state) {
+ case linphone::IceState::NotActivated:
+ return tr("iceStateNotActivated");
+ case linphone::IceState::Failed:
+ return tr("iceStateFailed");
+ case linphone::IceState::InProgress:
+ return tr("iceStateInProgress");
+ case linphone::IceState::ReflexiveConnection:
+ return tr("iceStateReflexiveConnection");
+ case linphone::IceState::HostConnection:
+ return tr("iceStateHostConnection");
+ case linphone::IceState::RelayConnection:
+ return tr("iceStateRelayConnection");
+ }
+
+ return tr("iceStateInvalid");
}
// -----------------------------------------------------------------------------
QString CallModel::generateSavedFilename () const {
- const shared_ptr callLog(mCall->getCallLog());
- return generateSavedFilename(
- Utils::coreStringToAppString(callLog->getFromAddress()->getUsername()),
- Utils::coreStringToAppString(callLog->getToAddress()->getUsername())
- );
+ const shared_ptr callLog(mCall->getCallLog());
+ return generateSavedFilename(
+ Utils::coreStringToAppString(callLog->getFromAddress()->getUsername()),
+ Utils::coreStringToAppString(callLog->getToAddress()->getUsername())
+ );
}
QString CallModel::generateSavedFilename (const QString &from, const QString &to) {
- auto escape = [](const QString &str) {
- constexpr char ReservedCharacters[] = "<>:\"/\\|\\?\\*";
- static QRegularExpression regexp(ReservedCharacters);
- return QString(str).replace(regexp, "");
- };
-
- return QStringLiteral("%1_%2_%3")
- .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss"))
- .arg(escape(from))
- .arg(escape(to));
+ auto escape = [](const QString &str) {
+ constexpr char ReservedCharacters[] = "<>:\"/\\|\\?\\*";
+ static QRegularExpression regexp(ReservedCharacters);
+ return QString(str).replace(regexp, "");
+ };
+
+ return QStringLiteral("%1_%2_%3")
+ .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss"))
+ .arg(escape(from))
+ .arg(escape(to));
}
diff --git a/linphone-app/src/components/call/CallModel.hpp b/linphone-app/src/components/call/CallModel.hpp
index 064bd9521..7ee9de087 100644
--- a/linphone-app/src/components/call/CallModel.hpp
+++ b/linphone-app/src/components/call/CallModel.hpp
@@ -30,237 +30,243 @@ class ContactModel;
class ChatRoomModel;
class CallModel : public QObject {
- Q_OBJECT;
-
- Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT);
- Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT);
- Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged);
- Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress CONSTANT);
+ Q_OBJECT;
+
+ Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT);
+ Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT);
+ Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged);
+ Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress CONSTANT);
Q_PROPERTY(ContactModel *contactModel READ getContactModel CONSTANT )
Q_PROPERTY(ChatRoomModel * chatRoomModel READ getChatRoomModel CONSTANT)
- /*
- Q_PROPERTY(QString sipAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged)
- Q_PROPERTY(QString username READ getUsername NOTIFY usernameChanged)
- Q_PROPERTY(QString avatar READ getAvatar NOTIFY avatarChanged)
- Q_PROPERTY(int presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged)*/
-
- Q_PROPERTY(CallStatus status READ getStatus NOTIFY statusChanged);
- Q_PROPERTY(QString callError READ getCallError NOTIFY callErrorChanged);
-
- Q_PROPERTY(bool isOutgoing READ isOutgoing CONSTANT);
-
- Q_PROPERTY(bool isInConference READ isInConference NOTIFY isInConferenceChanged);
-
- Q_PROPERTY(int duration READ getDuration CONSTANT); // Constants but called with a timer in qml.
- Q_PROPERTY(float quality READ getQuality CONSTANT);
- Q_PROPERTY(float speakerVu READ getSpeakerVu CONSTANT);
- Q_PROPERTY(float microVu READ getMicroVu CONSTANT);
-
- Q_PROPERTY(bool speakerMuted READ getSpeakerMuted WRITE setSpeakerMuted NOTIFY speakerMutedChanged);
- Q_PROPERTY(bool microMuted READ getMicroMuted WRITE setMicroMuted NOTIFY microMutedChanged);
-
- Q_PROPERTY(bool pausedByUser READ getPausedByUser WRITE setPausedByUser NOTIFY statusChanged);
- Q_PROPERTY(bool videoEnabled READ getVideoEnabled WRITE setVideoEnabled NOTIFY statusChanged);
- Q_PROPERTY(bool updating READ getUpdating NOTIFY statusChanged)
-
- Q_PROPERTY(bool recording READ getRecording NOTIFY recordingChanged);
-
- Q_PROPERTY(QVariantList audioStats READ getAudioStats NOTIFY statsUpdated);
- Q_PROPERTY(QVariantList videoStats READ getVideoStats NOTIFY statsUpdated);
-
- Q_PROPERTY(CallEncryption encryption READ getEncryption NOTIFY securityUpdated);
- Q_PROPERTY(bool isSecured READ isSecured NOTIFY securityUpdated);
- Q_PROPERTY(QString localSas READ getLocalSas NOTIFY securityUpdated);
- Q_PROPERTY(QString remoteSas READ getRemoteSas NOTIFY securityUpdated);
- Q_PROPERTY(QString securedString READ getSecuredString NOTIFY securityUpdated);
-
- Q_PROPERTY(float speakerVolumeGain READ getSpeakerVolumeGain WRITE setSpeakerVolumeGain NOTIFY speakerVolumeGainChanged);
- Q_PROPERTY(float microVolumeGain READ getMicroVolumeGain WRITE setMicroVolumeGain NOTIFY microVolumeGainChanged);
-
-
-
+ Q_PROPERTY(CallStatus status READ getStatus NOTIFY statusChanged);
+ Q_PROPERTY(QString callError READ getCallError NOTIFY callErrorChanged);
+
+ Q_PROPERTY(bool isOutgoing READ isOutgoing CONSTANT);
+
+ Q_PROPERTY(bool isInConference READ isInConference NOTIFY isInConferenceChanged);
+
+ Q_PROPERTY(int duration READ getDuration CONSTANT); // Constants but called with a timer in qml.
+ Q_PROPERTY(float quality READ getQuality CONSTANT);
+ Q_PROPERTY(float speakerVu READ getSpeakerVu CONSTANT);
+ Q_PROPERTY(float microVu READ getMicroVu CONSTANT);
+
+ Q_PROPERTY(bool speakerMuted READ getSpeakerMuted WRITE setSpeakerMuted NOTIFY speakerMutedChanged);
+ Q_PROPERTY(bool microMuted READ getMicroMuted WRITE setMicroMuted NOTIFY microMutedChanged);
+
+ Q_PROPERTY(float speakerVolumeGain READ getSpeakerVolumeGain WRITE setSpeakerVolumeGain NOTIFY speakerVolumeGainChanged);
+ Q_PROPERTY(float microVolumeGain READ getMicroVolumeGain WRITE setMicroVolumeGain NOTIFY microVolumeGainChanged);
+
+ Q_PROPERTY(bool pausedByUser READ getPausedByUser WRITE setPausedByUser NOTIFY statusChanged);
+ Q_PROPERTY(bool videoEnabled READ getVideoEnabled WRITE setVideoEnabled NOTIFY statusChanged);
+ Q_PROPERTY(bool updating READ getUpdating NOTIFY statusChanged)
+
+ Q_PROPERTY(bool recording READ getRecording NOTIFY recordingChanged);
+
+ Q_PROPERTY(QVariantList audioStats READ getAudioStats NOTIFY statsUpdated);
+ Q_PROPERTY(QVariantList videoStats READ getVideoStats NOTIFY statsUpdated);
+
+ Q_PROPERTY(CallEncryption encryption READ getEncryption NOTIFY securityUpdated);
+ Q_PROPERTY(bool isSecured READ isSecured NOTIFY securityUpdated);
+ Q_PROPERTY(QString localSas READ getLocalSas NOTIFY securityUpdated);
+ Q_PROPERTY(QString remoteSas READ getRemoteSas NOTIFY securityUpdated);
+ Q_PROPERTY(QString securedString READ getSecuredString NOTIFY securityUpdated);
+
+ Q_PROPERTY(QString transferAddress READ getTransferAddress WRITE setTransferAddress NOTIFY transferAddressChanged);
+
+
+
public:
- enum CallStatus {
- CallStatusConnected,
- CallStatusEnded,
- CallStatusIdle,
- CallStatusIncoming,
- CallStatusOutgoing,
- CallStatusPaused
- };
- Q_ENUM(CallStatus);
-
- enum CallEncryption {
- CallEncryptionNone = int(linphone::MediaEncryption::None),
- CallEncryptionDtls = int(linphone::MediaEncryption::DTLS),
- CallEncryptionSrtp = int(linphone::MediaEncryption::SRTP),
- CallEncryptionZrtp = int(linphone::MediaEncryption::ZRTP)
- };
- Q_ENUM(CallEncryption);
-
- CallModel (std::shared_ptr call);
- ~CallModel ();
-
- std::shared_ptr getCall () const {
- return mCall;
- }
-
- QString getPeerAddress () const;
- QString getLocalAddress () const;
- QString getFullPeerAddress () const;
- QString getFullLocalAddress () const;
-
- ContactModel *getContactModel() const;
-
- ChatRoomModel * getChatRoomModel() const;
-
- bool isInConference () const {
- return mIsInConference;
- }
-
- void setRecordFile (const std::shared_ptr &callParams);
- static void setRecordFile (const std::shared_ptr &callParams, const QString &to);
-
- void updateStats (const std::shared_ptr &callStats);
-
- void notifyCameraFirstFrameReceived (unsigned int width, unsigned int height);
-
- Q_INVOKABLE void accept ();
- Q_INVOKABLE void acceptWithVideo ();
- Q_INVOKABLE void terminate ();
-
- Q_INVOKABLE void askForTransfer ();
- Q_INVOKABLE bool transferTo (const QString &sipAddress);
-
- Q_INVOKABLE void acceptVideoRequest ();
- Q_INVOKABLE void rejectVideoRequest ();
-
- Q_INVOKABLE void takeSnapshot ();
-
- Q_INVOKABLE void startRecording ();
- Q_INVOKABLE void stopRecording ();
-
- Q_INVOKABLE void sendDtmf (const QString &dtmf);
-
- Q_INVOKABLE void verifyAuthenticationToken (bool verify);
-
- Q_INVOKABLE void updateStreams ();
-
- Q_INVOKABLE void toggleSpeakerMute();
-
- void setRemoteDisplayName(const std::string& name);
-
- static constexpr int DtmfSoundDelay = 200;
-
- std::shared_ptr mCall;
- std::shared_ptr mRemoteAddress;
- std::shared_ptr mMagicSearch;
-
+ enum CallStatus {
+ CallStatusConnected,
+ CallStatusEnded,
+ CallStatusIdle,
+ CallStatusIncoming,
+ CallStatusOutgoing,
+ CallStatusPaused
+ };
+ Q_ENUM(CallStatus);
+
+ enum CallEncryption {
+ CallEncryptionNone = int(linphone::MediaEncryption::None),
+ CallEncryptionDtls = int(linphone::MediaEncryption::DTLS),
+ CallEncryptionSrtp = int(linphone::MediaEncryption::SRTP),
+ CallEncryptionZrtp = int(linphone::MediaEncryption::ZRTP)
+ };
+ Q_ENUM(CallEncryption);
+
+ CallModel (std::shared_ptr call);
+ ~CallModel ();
+
+ std::shared_ptr getCall () const {
+ return mCall;
+ }
+
+ QString getPeerAddress () const;
+ QString getLocalAddress () const;
+ QString getFullPeerAddress () const;
+ QString getFullLocalAddress () const;
+
+ ContactModel *getContactModel() const;
+
+ ChatRoomModel * getChatRoomModel() const;
+
+ bool isInConference () const {
+ return mIsInConference;
+ }
+
+ void setRecordFile (const std::shared_ptr &callParams);
+ static void setRecordFile (const std::shared_ptr &callParams, const QString &to);
+
+ void updateStats (const std::shared_ptr &callStats);
+
+ void notifyCameraFirstFrameReceived (unsigned int width, unsigned int height);
+
+ Q_INVOKABLE void accept ();
+ Q_INVOKABLE void acceptWithVideo ();
+ Q_INVOKABLE void terminate ();
+
+ Q_INVOKABLE void askForTransfer ();
+ Q_INVOKABLE void askForAttendedTransfer ();
+ Q_INVOKABLE bool transferTo (const QString &sipAddress);
+ Q_INVOKABLE bool transferToAnother (const QString &peerAddress);
+
+ Q_INVOKABLE void acceptVideoRequest ();
+ Q_INVOKABLE void rejectVideoRequest ();
+
+ Q_INVOKABLE void takeSnapshot ();
+
+ Q_INVOKABLE void startRecording ();
+ Q_INVOKABLE void stopRecording ();
+
+ Q_INVOKABLE void sendDtmf (const QString &dtmf);
+
+ Q_INVOKABLE void verifyAuthenticationToken (bool verify);
+
+ Q_INVOKABLE void updateStreams ();
+
+ Q_INVOKABLE void toggleSpeakerMute();
+
+ void setRemoteDisplayName(const std::string& name);
+
+ QString getTransferAddress () const;
+ void setTransferAddress (const QString &transferAddress);
+ static void prepareTransfert(std::shared_ptr call, const QString& transfertAddress);
+
+ std::shared_ptr getRemoteAddress()const;
+
+ static constexpr int DtmfSoundDelay = 200;
+
+ std::shared_ptr mCall;
+ std::shared_ptr mRemoteAddress;
+ std::shared_ptr mMagicSearch;
+
public slots:
-// Set remote display name when a search has been done
- void searchReceived(std::list> results);
- void callEnded();
-
+ // Set remote display name when a search has been done
+ void searchReceived(std::list> results);
+ void callEnded();
+
signals:
- void callErrorChanged (const QString &callError);
- void isInConferenceChanged (bool status);
- void speakerMutedChanged (bool status);
- void microMutedChanged (bool status);
- void recordingChanged (bool status);
- void statsUpdated ();
- void statusChanged (CallStatus status);
- void videoRequested ();
- void securityUpdated ();
- void speakerVolumeGainChanged (float volume);
- void microVolumeGainChanged (float volume);
-
- void cameraFirstFrameReceived (unsigned int width, unsigned int height);
-
- void fullPeerAddressChanged();
-
+ void callErrorChanged (const QString &callError);
+ void isInConferenceChanged (bool status);
+ void speakerMutedChanged (bool status);
+ void microMutedChanged (bool status);
+ void recordingChanged (bool status);
+ void statsUpdated ();
+ void statusChanged (CallStatus status);
+ void videoRequested ();
+ void securityUpdated ();
+ void speakerVolumeGainChanged (float volume);
+ void microVolumeGainChanged (float volume);
+
+ void cameraFirstFrameReceived (unsigned int width, unsigned int height);
+
+ void fullPeerAddressChanged();
+ void transferAddressChanged (const QString &transferAddress);
+
private:
- void handleCallEncryptionChanged (const std::shared_ptr &call);
- void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state);
-
- void accept (bool withVideo);
-
- void stopAutoAnswerTimer () const;
-
- CallStatus getStatus () const;
-
- bool isOutgoing () const {
- return mCall->getDir() == linphone::Call::Dir::Outgoing;
- }
-
- void updateIsInConference ();
-
- void acceptWithAutoAnswerDelay ();
-
- QString getCallError () const;
- void setCallErrorFromReason (linphone::Reason reason);
-
- int getDuration () const;
- float getQuality () const;
- float getMicroVu () const;
- float getSpeakerVu () const;
-
- bool getSpeakerMuted () const;
- void setSpeakerMuted (bool status);
-
- bool getMicroMuted () const;
- void setMicroMuted (bool status);
-
- bool getPausedByUser () const;
- void setPausedByUser (bool status);
-
- bool getVideoEnabled () const;
- void setVideoEnabled (bool status);
-
- bool getUpdating () const;
-
- bool getRecording () const;
-
- CallEncryption getEncryption () const;
- bool isSecured () const;
-
- QString getLocalSas () const;
- QString getRemoteSas () const;
-
- QString getSecuredString () const;
-
- QVariantList getAudioStats () const;
- QVariantList getVideoStats () const;
- void updateStats (const std::shared_ptr &callStats, QVariantList &statsList);
-
- QString iceStateToString (linphone::IceState state) const;
-
- float getSpeakerVolumeGain () const;
- void setSpeakerVolumeGain (float volume);
-
- float getMicroVolumeGain () const;
- void setMicroVolumeGain (float volume);
-
- QString generateSavedFilename () const;
-
- static QString generateSavedFilename (const QString &from, const QString &to);
-
- bool mIsInConference = false;
-
- bool mPausedByRemote = false;
- bool mPausedByUser = false;
- bool mRecording = false;
-
- bool mWasConnected = false;
-
- bool mNotifyCameraFirstFrameReceived = true;
-
- QString mCallError;
-
- QVariantList mAudioStats;
- QVariantList mVideoStats;
- std::shared_ptr mSearch;
+ void handleCallEncryptionChanged (const std::shared_ptr &call);
+ void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state);
+
+ void accept (bool withVideo);
+
+ void stopAutoAnswerTimer () const;
+
+ CallStatus getStatus () const;
+
+ bool isOutgoing () const {
+ return mCall->getDir() == linphone::Call::Dir::Outgoing;
+ }
+
+ void updateIsInConference ();
+
+ void acceptWithAutoAnswerDelay ();
+
+ QString getCallError () const;
+ void setCallErrorFromReason (linphone::Reason reason);
+
+ int getDuration () const;
+ float getQuality () const;
+ float getMicroVu () const;
+ float getSpeakerVu () const;
+
+ bool getSpeakerMuted () const;
+ void setSpeakerMuted (bool status);
+
+ bool getMicroMuted () const;
+ void setMicroMuted (bool status);
+
+ bool getPausedByUser () const;
+ void setPausedByUser (bool status);
+
+ bool getVideoEnabled () const;
+ void setVideoEnabled (bool status);
+
+ bool getUpdating () const;
+
+ bool getRecording () const;
+
+ CallEncryption getEncryption () const;
+ bool isSecured () const;
+
+ QString getLocalSas () const;
+ QString getRemoteSas () const;
+
+ QString getSecuredString () const;
+
+ QVariantList getAudioStats () const;
+ QVariantList getVideoStats () const;
+ void updateStats (const std::shared_ptr &callStats, QVariantList &statsList);
+
+ QString iceStateToString (linphone::IceState state) const;
+
+ float getSpeakerVolumeGain () const;
+ void setSpeakerVolumeGain (float volume);
+
+ float getMicroVolumeGain () const;
+ void setMicroVolumeGain (float volume);
+
+ QString generateSavedFilename () const;
+
+ static QString generateSavedFilename (const QString &from, const QString &to);
+
+ bool mIsInConference = false;
+
+ bool mPausedByRemote = false;
+ bool mPausedByUser = false;
+ bool mRecording = false;
+
+ bool mWasConnected = false;
+
+ bool mNotifyCameraFirstFrameReceived = true;
+
+ QString mCallError;
+
+ QVariantList mAudioStats;
+ QVariantList mVideoStats;
+ std::shared_ptr mSearch;
+ QString mTransferAddress;
};
#endif // CALL_MODEL_H_
diff --git a/linphone-app/src/components/calls/CallsListModel.cpp b/linphone-app/src/components/calls/CallsListModel.cpp
index e4f969160..83cf410a9 100644
--- a/linphone-app/src/components/calls/CallsListModel.cpp
+++ b/linphone-app/src/components/calls/CallsListModel.cpp
@@ -93,15 +93,27 @@ QVariant CallsListModel::data (const QModelIndex &index, int role) const {
return QVariant();
}
+CallModel *CallsListModel::findCallModelFromPeerAddress (const QString &peerAddress) const {
+ std::shared_ptr address = Utils::interpretUrl(peerAddress);
+ auto it = find_if(mList.begin(), mList.end(), [address](CallModel *callModel) {
+ return callModel->getRemoteAddress()->weakEqual(address);
+ });
+ return it != mList.end() ? *it : nullptr;
+}
+
// -----------------------------------------------------------------------------
void CallsListModel::askForTransfer (CallModel *callModel) {
emit callTransferAsked(callModel);
}
+void CallsListModel::askForAttendedTransfer (CallModel *callModel) {
+ emit callAttendedTransferAsked(callModel);
+}
+
// -----------------------------------------------------------------------------
-void CallsListModel::launchAudioCall (const QString &sipAddress, const QHash &headers) const {
+void CallsListModel::launchAudioCall (const QString &sipAddress, const QString& prepareTransfertAddress, const QHash &headers) const {
CoreManager::getInstance()->getTimelineListModel()->mAutoSelectAfterCreation = true;
shared_ptr core = CoreManager::getInstance()->getCore();
@@ -122,23 +134,23 @@ void CallsListModel::launchAudioCall (const QString &sipAddress, const QHash currentProxyConfig = core->getDefaultProxyConfig();
if(currentProxyConfig){
if(!CoreManager::getInstance()->getSettingsModel()->getWaitRegistrationForCall() || currentProxyConfig->getState() == linphone::RegistrationState::Ok)
- core->inviteAddressWithParams(address, params);
+ CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
else{
QObject * context = new QObject();
QObject::connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::registrationStateChanged,context,
- [address,core,params,currentProxyConfig, context](const std::shared_ptr &proxyConfig, linphone::RegistrationState state) mutable {
+ [address,core,params,currentProxyConfig,prepareTransfertAddress, context](const std::shared_ptr &proxyConfig, linphone::RegistrationState state) mutable {
if(context && proxyConfig==currentProxyConfig && state==linphone::RegistrationState::Ok){
+ CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
delete context;
context = nullptr;
- core->inviteAddressWithParams(address, params);
}
});
}
}else
- core->inviteAddressWithParams(address, params);
+ CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
}
-void CallsListModel::launchSecureAudioCall (const QString &sipAddress, LinphoneEnums::MediaEncryption encryption, const QHash &headers) const {
+void CallsListModel::launchSecureAudioCall (const QString &sipAddress, LinphoneEnums::MediaEncryption encryption, const QHash &headers, const QString& prepareTransfertAddress) const {
CoreManager::getInstance()->getTimelineListModel()->mAutoSelectAfterCreation = true;
shared_ptr core = CoreManager::getInstance()->getCore();
@@ -160,28 +172,28 @@ void CallsListModel::launchSecureAudioCall (const QString &sipAddress, LinphoneE
params->setMediaEncryption(LinphoneEnums::toLinphone(encryption));
if(currentProxyConfig){
if(!CoreManager::getInstance()->getSettingsModel()->getWaitRegistrationForCall() || currentProxyConfig->getState() == linphone::RegistrationState::Ok)
- core->inviteAddressWithParams(address, params);
+ CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
else{
QObject * context = new QObject();
QObject::connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::registrationStateChanged,context,
- [address,core,params,currentProxyConfig, context](const std::shared_ptr &proxyConfig, linphone::RegistrationState state) mutable {
+ [address,core,params,currentProxyConfig,prepareTransfertAddress, context](const std::shared_ptr &proxyConfig, linphone::RegistrationState state) mutable {
if(context && proxyConfig==currentProxyConfig && state==linphone::RegistrationState::Ok){
+ CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
delete context;
context = nullptr;
- core->inviteAddressWithParams(address, params);
}
});
}
}else
- core->inviteAddressWithParams(address, params);
+ CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
}
-void CallsListModel::launchVideoCall (const QString &sipAddress) const {
+void CallsListModel::launchVideoCall (const QString &sipAddress, const QString& prepareTransfertAddress) const {
CoreManager::getInstance()->getTimelineListModel()->mAutoSelectAfterCreation = true;
shared_ptr core = CoreManager::getInstance()->getCore();
if (!core->videoSupported()) {
qWarning() << QStringLiteral("Unable to launch video call. (Video not supported.) Launching audio call...");
- launchAudioCall(sipAddress);
+ launchAudioCall(sipAddress, prepareTransfertAddress, {});
return;
}
@@ -193,7 +205,7 @@ void CallsListModel::launchVideoCall (const QString &sipAddress) const {
params->enableVideo(true);
params->setProxyConfig(core->getDefaultProxyConfig());
CallModel::setRecordFile(params, Utils::coreStringToAppString(address->getUsername()));
- core->inviteAddressWithParams(address, params);
+ CallModel::prepareTransfert(core->inviteAddressWithParams(address, params), prepareTransfertAddress);
}
ChatRoomModel* CallsListModel::launchSecureChat (const QString &sipAddress) const {
@@ -249,7 +261,7 @@ ChatRoomModel* CallsListModel::createChat (const QString &participantAddress) co
params->setBackend(linphone::ChatRoomBackend::Basic);
std::shared_ptr chatRoom = core->createChatRoom(params, localAddress, participants);
-
+
if( chatRoom != nullptr){
auto timelineList = CoreManager::getInstance()->getTimelineListModel();
auto timeline = timelineList->getTimeline(chatRoom, true);
@@ -315,7 +327,7 @@ QVariantMap CallsListModel::createChatRoom(const QString& subject, const int& se
address = Utils::interpretUrl(participant);
}
if( address)
- chatRoomParticipants.push_back( address );
+ chatRoomParticipants.push_back( address );
}
auto proxy = core->getDefaultProxyConfig();
params->enableEncryption(securityLevel>0);
@@ -344,7 +356,7 @@ QVariantMap CallsListModel::createChatRoom(const QString& subject, const int& se
chatRoom = core->createChatRoom(params, localAddress, chatRoomParticipants);
if(chatRoom != nullptr && admins.size() > 0)
ChatRoomInitializer::setAdminsAsync(params->getSubject(), params->getBackend(), params->groupEnabled(), admins );
- timeline = timelineList->getTimeline(chatRoom, false);
+ timeline = timelineList->getTimeline(chatRoom, false);
}else{
if(admins.size() > 0){
ChatRoomInitializer::setAdminsSync(chatRoom, admins);
@@ -391,6 +403,7 @@ void CallsListModel::terminateCall (const QString& sipAddress) const{
}
}
}
+
// -----------------------------------------------------------------------------
static void joinConference (const shared_ptr &call) {
diff --git a/linphone-app/src/components/calls/CallsListModel.hpp b/linphone-app/src/components/calls/CallsListModel.hpp
index c4c31af17..6e1fa5210 100644
--- a/linphone-app/src/components/calls/CallsListModel.hpp
+++ b/linphone-app/src/components/calls/CallsListModel.hpp
@@ -33,53 +33,56 @@ class ChatRoomModel;
class CoreHandlers;
class CallsListModel : public QAbstractListModel {
- Q_OBJECT
-
+ Q_OBJECT
+
public:
- CallsListModel (QObject *parent = Q_NULLPTR);
-
- int rowCount (const QModelIndex &index = QModelIndex()) const override;
-
- QHash roleNames () const override;
- QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
-
- void askForTransfer (CallModel *callModel);
-
- Q_INVOKABLE void launchAudioCall (const QString &sipAddress, const QHash &headers = {}) const;
- Q_INVOKABLE void launchSecureAudioCall (const QString &sipAddress, LinphoneEnums::MediaEncryption encryption, const QHash &headers = {}) const;
- Q_INVOKABLE void launchVideoCall (const QString &sipAddress) const;
- Q_INVOKABLE ChatRoomModel* launchSecureChat (const QString &sipAddress) const;
- Q_INVOKABLE QVariantMap launchChat(const QString &sipAddress, const int& securityLevel) const;
- Q_INVOKABLE ChatRoomModel* createChat (const QString &participantAddress) const;
- Q_INVOKABLE ChatRoomModel* createChat (const CallModel * ) const;
- Q_INVOKABLE bool createSecureChat (const QString& subject, const QString &participantAddress) const;
-
- Q_INVOKABLE QVariantMap createChatRoom(const QString& subject, const int& securityLevel, const QVariantList& participants, const bool& selectAfterCreation) const;
-
- Q_INVOKABLE int getRunningCallsNumber () const;
-
- Q_INVOKABLE void terminateAllCalls () const;
- Q_INVOKABLE void terminateCall (const QString& sipAddress) const;
-
+ CallsListModel (QObject *parent = Q_NULLPTR);
+
+ int rowCount (const QModelIndex &index = QModelIndex()) const override;
+
+ QHash roleNames () const override;
+ QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ CallModel *findCallModelFromPeerAddress (const QString &peerAddress) const;
+
+ void askForTransfer (CallModel *callModel);
+ void askForAttendedTransfer (CallModel *callModel);
+
+ Q_INVOKABLE void launchAudioCall (const QString &sipAddress, const QString& prepareTransfertAddress = "", const QHash &headers = {}) const;
+ Q_INVOKABLE void launchSecureAudioCall (const QString &sipAddress, LinphoneEnums::MediaEncryption encryption, const QHash &headers = {}, const QString& prepareTransfertAddress = "") const;
+ Q_INVOKABLE void launchVideoCall (const QString &sipAddress, const QString& prepareTransfertAddress = "") const;
+ Q_INVOKABLE ChatRoomModel* launchSecureChat (const QString &sipAddress) const;
+ Q_INVOKABLE QVariantMap launchChat(const QString &sipAddress, const int& securityLevel) const;
+ Q_INVOKABLE ChatRoomModel* createChat (const QString &participantAddress) const;
+ Q_INVOKABLE ChatRoomModel* createChat (const CallModel * ) const;
+ Q_INVOKABLE bool createSecureChat (const QString& subject, const QString &participantAddress) const;
+
+ Q_INVOKABLE QVariantMap createChatRoom(const QString& subject, const int& securityLevel, const QVariantList& participants, const bool& selectAfterCreation) const;
+
+ Q_INVOKABLE int getRunningCallsNumber () const;
+
+ Q_INVOKABLE void terminateAllCalls () const;
+ Q_INVOKABLE void terminateCall (const QString& sipAddress) const;
+
signals:
- void callRunning (int index, CallModel *callModel);
- void callTransferAsked (CallModel *callModel);
-
- void callMissed (CallModel *callModel);
-
+ void callRunning (int index, CallModel *callModel);
+ void callTransferAsked (CallModel *callModel);
+ void callAttendedTransferAsked (CallModel *callModel);
+
+ void callMissed (CallModel *callModel);
+
private:
- bool removeRow (int row, const QModelIndex &parent = QModelIndex());
- bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
-
- void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state);
-
- void addCall (const std::shared_ptr &call);
- void removeCall (const std::shared_ptr &call);
- void removeCallCb (CallModel *callModel);
-
- QList mList;
-
- std::shared_ptr mCoreHandlers;
+ bool removeRow (int row, const QModelIndex &parent = QModelIndex());
+ bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
+
+ void handleCallStateChanged (const std::shared_ptr &call, linphone::Call::State state);
+
+ void addCall (const std::shared_ptr &call);
+ void removeCall (const std::shared_ptr &call);
+ void removeCallCb (CallModel *callModel);
+
+ QList mList;
+
+ std::shared_ptr mCoreHandlers;
};
#endif // CALLS_LIST_MODEL_H_
diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
index e9270cae2..492e0f5cf 100644
--- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
+++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
@@ -139,17 +139,19 @@ void ChatRoomProxyModel::compose (const QString& text) {
// -----------------------------------------------------------------------------
void ChatRoomProxyModel::loadMoreEntries () {
- int count = rowCount();
- int parentCount = sourceModel()->rowCount();
- if (count == mMaxDisplayedEntries)
- mMaxDisplayedEntries += EntriesChunkSize;
-
- if (count + 10 >= parentCount) // Magic number : try to load more entries if near to max event count
- mChatRoomModel->loadMoreEntries();
- invalidateFilter();
- count = rowCount() - count;
- if (count > 0)
- emit moreEntriesLoaded(count);
+ if(mChatRoomModel ) {
+ int count = rowCount();
+ int parentCount = sourceModel()->rowCount();
+ if (count == mMaxDisplayedEntries)
+ mMaxDisplayedEntries += EntriesChunkSize;
+
+ if (count + 10 >= parentCount) // Magic number : try to load more entries if near to max event count
+ mChatRoomModel->loadMoreEntries();
+ invalidateFilter();
+ count = rowCount() - count;
+ if (count > 0)
+ emit moreEntriesLoaded(count);
+ }
}
void ChatRoomProxyModel::setEntryTypeFilter (int type) {
diff --git a/linphone-app/ui/modules/Linphone/Calls/Calls.js b/linphone-app/ui/modules/Linphone/Calls/Calls.js
index d942a8fe0..d2c9bb95f 100644
--- a/linphone-app/ui/modules/Linphone/Calls/Calls.js
+++ b/linphone-app/ui/modules/Linphone/Calls/Calls.js
@@ -30,123 +30,155 @@
// -----------------------------------------------------------------------------
function getParams (call) {
- if (!call) {
- return
- }
-
- var CallModel = Linphone.CallModel
- var status = call.status
-
- if (status === CallModel.CallStatusConnected) {
- var optActions = []
- if (Linphone.SettingsModel.callPauseEnabled) {
- optActions.push({
- handler: (function () { call.pausedByUser = true }),
- name: qsTr('callPause')
- })
- }
-
- return {
- actions: optActions.concat([{
- handler: call.askForTransfer,
- name: qsTr('transferCall')
- }, {
- handler: call.terminate,
- name: qsTr('terminateCall')
- }]),
- component: callActions,
- string: 'connected'
- }
- }
-
- if (status === CallModel.CallStatusEnded) {
- return {
- string: 'ended'
- }
- }
-
- if (status === CallModel.CallStatusIncoming) {
- var optActions = []
- if (Linphone.SettingsModel.videoSupported) {
- optActions.push({
- handler: call.acceptWithVideo,
- name: qsTr('acceptVideoCall')
- })
- }
-
- return {
- actions: [{
- handler: (function () { call.accept() }),
- name: qsTr('acceptAudioCall')
- }].concat(optActions).concat([{
- handler: call.terminate,
- name: qsTr('terminateCall')
- }]),
- component: callActions,
- string: 'incoming'
- }
- }
-
- if (status === CallModel.CallStatusOutgoing) {
- return {
- component: callAction,
- handler: call.terminate,
- icon: 'hangup',
- string: 'outgoing'
- }
- }
-
- if (status === CallModel.CallStatusPaused) {
- var optActions = []
- if (call.pausedByUser) {
- optActions.push({
- handler: (function () { call.pausedByUser = false }),
- name: qsTr('resumeCall')
- })
- } else if (Linphone.SettingsModel.callPauseEnabled) {
- optActions.push({
- handler: (function () { call.pausedByUser = true }),
- name: qsTr('callPause')
- })
- }
-
- return {
- actions: optActions.concat([{
- handler: call.askForTransfer,
- name: qsTr('transferCall')
- }, {
- handler: call.terminate,
- name: qsTr('terminateCall')
- }]),
- component: callActions,
- string: 'paused'
- }
- }
+ if (!call) {
+ return
+ }
+
+ var CallModel = Linphone.CallModel
+ var status = call.status
+
+ if (status === CallModel.CallStatusConnected) {
+ var optActions = []
+ if (Linphone.SettingsModel.callPauseEnabled) {
+ optActions.push({
+ handler: (function () { call.pausedByUser = true }),
+ name: qsTr('callPause')
+ })
+ }
+
+ if (call.transferAddress !== '') {
+ optActions.push({
+ handler: call.askForTransfer,
+ //: 'COMPLETE ATTENDED TRANSFER' : Title button, design is in uppercase.
+ name: qsTr('attendedTransferComplete')
+ })
+ }
+ else {
+ optActions.push({
+ handler: call.askForTransfer,
+ name: qsTr('transferCall')
+ })
+ optActions.push({
+ handler: call.askForAttendedTransfer,
+ //: 'ATTENDED TRANSFER CALL' : Title button, design is in uppercase.
+ name: qsTr('attendedTransferCall')
+ })
+ }
+
+ return {
+ actions: optActions.concat([{
+ handler: call.terminate,
+ name: qsTr('terminateCall')
+ }]),
+ component: callActions,
+ string: 'connected'
+ }
+ }
+
+ if (status === CallModel.CallStatusEnded) {
+ return {
+ string: 'ended'
+ }
+ }
+
+ if (status === CallModel.CallStatusIncoming) {
+ var optActions = []
+ if (Linphone.SettingsModel.videoSupported) {
+ optActions.push({
+ handler: call.acceptWithVideo,
+ name: qsTr('acceptVideoCall')
+ })
+ }
+
+ return {
+ actions: [{
+ handler: (function () { call.accept() }),
+ name: qsTr('acceptAudioCall')
+ }].concat(optActions).concat([{
+ handler: call.terminate,
+ name: qsTr('terminateCall')
+ }]),
+ component: callActions,
+ string: 'incoming'
+ }
+ }
+
+ if (status === CallModel.CallStatusOutgoing) {
+ return {
+ component: callAction,
+ handler: call.terminate,
+ icon: 'hangup',
+ string: 'outgoing'
+ }
+ }
+
+ if (status === CallModel.CallStatusPaused) {
+ var optActions = []
+ if (call.pausedByUser) {
+ optActions.push({
+ handler: (function () { call.pausedByUser = false }),
+ name: qsTr('resumeCall')
+ })
+ } else if (Linphone.SettingsModel.callPauseEnabled) {
+ optActions.push({
+ handler: (function () { call.pausedByUser = true }),
+ name: qsTr('callPause')
+ })
+ }
+
+ if (call.transferAddress !== '') {
+ optActions.push({
+ handler: call.askForTransfer,
+ //: 'COMPLETE ATTENDED TRANSFER' : Title button, design is in uppercase.
+ name: qsTr('attendedTransferComplete')
+ })
+ }
+ else {
+ optActions.push({
+ handler: call.askForTransfer,
+ name: qsTr('transferCall')
+ })
+ optActions.push({
+ handler: call.askForAttendedTransfer,
+ //: 'ATTENDED TRANSFER CALL' : Title button, design is in uppercase.
+ name: qsTr('attendedTransferCall')
+ })
+ }
+
+ return {
+ actions: optActions.concat([{
+ handler: call.terminate,
+ name: qsTr('terminateCall')
+ }]),
+ component: callActions,
+ string: 'paused'
+ }
+ }
}
function updateSelectedCall (call, index) {
- calls._selectedCall = call
- if (index != null) {
- calls.currentIndex = index
- }
+ calls._selectedCall = call
+ if (index != null) {
+ calls.currentIndex = index
+ }
}
function resetSelectedCall () {
- updateSelectedCall(null, -1)
+ updateSelectedCall(null, -1)
}
function setIndexWithCall (call) {
- var count = calls.count
- var model = calls.model
-
- for (var i = 0; i < count; i++) {
- if (call === model.data(model.index(i, 0))) {
- updateSelectedCall(call, i)
- return
- }
- }
-
- updateSelectedCall(call, -1)
+ var count = calls.count
+ var model = calls.model
+
+ for (var i = 0; i < count; i++) {
+ if (call === model.data(model.index(i, 0))) {
+ updateSelectedCall(call, i)
+ return
+ }
+ }
+
+ updateSelectedCall(call, -1)
}
// -----------------------------------------------------------------------------
@@ -154,23 +186,23 @@ function setIndexWithCall (call) {
// -----------------------------------------------------------------------------
function handleCountChanged (count) {
- if (count === 0) {
- return
- }
-
- var call = calls._selectedCall
-
- if (call == null) {
- if (calls.conferenceModel.count > 0) {
- return
- }
-
- var model = calls.model
- var index = count - 1
- updateSelectedCall(model.data(model.index(index, 0)), index)
- } else {
- setIndexWithCall(call)
- }
+ if (count === 0) {
+ return
+ }
+
+ var call = calls._selectedCall
+
+ if (call == null) {
+ if (calls.conferenceModel.count > 0) {
+ return
+ }
+
+ var model = calls.model
+ var index = count - 1
+ updateSelectedCall(model.data(model.index(index, 0)), index)
+ } else {
+ setIndexWithCall(call)
+ }
}
// -----------------------------------------------------------------------------
@@ -178,36 +210,36 @@ function handleCountChanged (count) {
// -----------------------------------------------------------------------------
function handleCallRunning (call) {
- if (!call.isInConference) {
- setIndexWithCall(call)
- }
+ if (!call.isInConference) {
+ setIndexWithCall(call)
+ }
}
function handleRowsAboutToBeRemoved (_, first, last) {
- var index = calls.currentIndex
-
- if (index >= first && index <= last) {
- resetSelectedCall()
- }
+ var index = calls.currentIndex
+
+ if (index >= first && index <= last) {
+ resetSelectedCall()
+ }
}
function handleRowsInserted (_, first, last) {
- // The last inserted outgoing element become the selected call.
- var model = calls.model
- for (var index = last; index >= first; index--) {
- var call = model.data(model.index(index, 0))
-
- if (call.isOutgoing && !call.isInConference) {
- updateSelectedCall(call)
- return
- }
- }
-
- // First received call.
- if (first === 0 && model.rowCount() === 1) {
- var call = model.data(model.index(0, 0))
- if (!call.isInConference) {
- updateSelectedCall(model.data(model.index(0, 0)))
- }
- }
+ // The last inserted outgoing element become the selected call.
+ var model = calls.model
+ for (var index = last; index >= first; index--) {
+ var call = model.data(model.index(index, 0))
+
+ if (call.isOutgoing && !call.isInConference) {
+ updateSelectedCall(call)
+ return
+ }
+ }
+
+ // First received call.
+ if (first === 0 && model.rowCount() === 1) {
+ var call = model.data(model.index(0, 0))
+ if (!call.isInConference) {
+ updateSelectedCall(model.data(model.index(0, 0)))
+ }
+ }
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/Chat.qml b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
index 97677b362..0d3210f28 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Chat.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
@@ -245,7 +245,7 @@ Rectangle {
borderColor: ChatStyle.sendArea.border.color
topWidth: ChatStyle.sendArea.border.width
- visible: SettingsModel.chatEnabled && !proxyModel.chatRoomModel.hasBeenLeft
+ visible: SettingsModel.chatEnabled && proxyModel.chatRoomModel && !proxyModel.chatRoomModel.hasBeenLeft
DroppableTextArea {
id: textArea
diff --git a/linphone-app/ui/views/App/Calls/CallsWindow.js b/linphone-app/ui/views/App/Calls/CallsWindow.js
index 825b96359..d8210f3e6 100644
--- a/linphone-app/ui/views/App/Calls/CallsWindow.js
+++ b/linphone-app/ui/views/App/Calls/CallsWindow.js
@@ -28,86 +28,109 @@
// =============================================================================
function handleClosing (close) {
- var callsList = Linphone.CallsListModel
-
- window.detachVirtualWindow()
-
- if (callsList.getRunningCallsNumber() === 0) {
- return
- }
-
- window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
- descriptionText: qsTr('acceptClosingDescription')
- }, function (status) {
- if (status) {
- callsList.terminateAllCalls()
- window.close()
- }
- })
-
- close.accepted = false
+ var callsList = Linphone.CallsListModel
+
+ window.detachVirtualWindow()
+
+ if (callsList.getRunningCallsNumber() === 0) {
+ return
+ }
+
+ window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
+ descriptionText: qsTr('acceptClosingDescription')
+ }, function (status) {
+ if (status) {
+ callsList.terminateAllCalls()
+ window.close()
+ }
+ })
+
+ close.accepted = false
}
// -----------------------------------------------------------------------------
function openCallSipAddress () {
- window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/CallSipAddress.qml'))
+ window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/CallSipAddress.qml'))
}
function openConferenceManager (params, exitHandler) {
- window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/ConferenceManager.qml'), params, exitHandler)
+ window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/ConferenceManager.qml'), params, exitHandler)
}
// -----------------------------------------------------------------------------
// Used to get Component based from Call Status
function getContent () {
- var call = window.call
- if (call == null) {
- return conference
- }
-
- var status = call.status
- if (status == null) {
- return calls.conferenceModel.count > 0 ? conference : null
- }
-
- var CallModel = Linphone.CallModel
- if (status === CallModel.CallStatusIncoming) {
- return incomingCall
- }
-
- if (status === CallModel.CallStatusOutgoing) {
- return outgoingCall
- }
-
- if (status === CallModel.CallStatusEnded) {
- return endedCall
- }
-
- return incall
+ var call = window.call
+ if (call == null) {
+ return conference
+ }
+
+ var status = call.status
+ if (status == null) {
+ return calls.conferenceModel.count > 0 ? conference : null
+ }
+
+ var CallModel = Linphone.CallModel
+ if (status === CallModel.CallStatusIncoming) {
+ return incomingCall
+ }
+
+ if (status === CallModel.CallStatusOutgoing) {
+ return outgoingCall
+ }
+
+ if (status === CallModel.CallStatusEnded) {
+ return endedCall
+ }
+
+ return incall
}
// -----------------------------------------------------------------------------
function handleCallTransferAsked (call) {
- if (!call) {
- return
- }
+ if (!call) {
+ return
+ }
+
+ if (call.transferAddress !== '') {
+ console.debug('Attended transfer to call ' + call.transferAddress)
+ call.transferToAnother(call.transferAddress)
+ return
+ }
+
+ window.detachVirtualWindow()
+ window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/CallTransfer.qml'), {
+ call: call,
+ attended: false
+ })
+}
- window.detachVirtualWindow()
- window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/CallTransfer.qml'), {
- call: call
- })
+function handleCallAttendedTransferAsked (call) {
+ if (!call) {
+ return
+ }
+ if (call.transferAddress !== '') {
+ console.debug('Attended transfer to call ' + call.transferAddress)
+ call.transferToAnother(call.transferAddress)
+ return
+ }
+ window.detachVirtualWindow()
+ window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/CallTransfer.qml'), {
+ call: call,
+ attended: true
+ })
}
function windowMustBeClosed () {
- return Linphone.CallsListModel.rowCount() === 0 && !window.virtualWindowVisible
+ return Linphone.CallsListModel.rowCount() === 0 && !window.virtualWindowVisible
}
function tryToCloseWindow () {
- if (windowMustBeClosed()) {
- // Workaround, it's necessary to use a timeout because at last call termination
- // a segfault is emit in `QOpenGLContext::functions() const ()`.
- Utils.setTimeout(window, 0, function () { windowMustBeClosed() && window.close() })
- }
+ if (windowMustBeClosed()) {
+ // Workaround, it's necessary to use a timeout because at last call termination
+ // a segfault is emit in `QOpenGLContext::functions() const ()`.
+ Utils.setTimeout(window, 0, function () { windowMustBeClosed() && window.close() })
+ }
}
diff --git a/linphone-app/ui/views/App/Calls/CallsWindow.qml b/linphone-app/ui/views/App/Calls/CallsWindow.qml
index 146719414..be7de2bc4 100644
--- a/linphone-app/ui/views/App/Calls/CallsWindow.qml
+++ b/linphone-app/ui/views/App/Calls/CallsWindow.qml
@@ -253,6 +253,7 @@ Window {
Connections {
target: CallsListModel
onCallTransferAsked: Logic.handleCallTransferAsked(callModel)
+ onCallAttendedTransferAsked: Logic.handleCallAttendedTransferAsked(callModel)
onRowsRemoved: Logic.tryToCloseWindow()
}
}
diff --git a/linphone-app/ui/views/App/Calls/Dialogs/CallSipAddress.qml b/linphone-app/ui/views/App/Calls/Dialogs/CallSipAddress.qml
index 98c19aaeb..1916e3a1e 100644
--- a/linphone-app/ui/views/App/Calls/Dialogs/CallSipAddress.qml
+++ b/linphone-app/ui/views/App/Calls/Dialogs/CallSipAddress.qml
@@ -72,7 +72,7 @@ DialogPlus {
secure:0,
visible:true,
handler: function (entry) {
- CallsListModel.launchAudioCall(entry.sipAddress)
+ CallsListModel.launchAudioCall(entry.sipAddress, "")
exit(1)
}
}]
diff --git a/linphone-app/ui/views/App/Calls/Dialogs/CallTransfer.qml b/linphone-app/ui/views/App/Calls/Dialogs/CallTransfer.qml
index 549e2cc27..8e1b14703 100644
--- a/linphone-app/ui/views/App/Calls/Dialogs/CallTransfer.qml
+++ b/linphone-app/ui/views/App/Calls/Dialogs/CallTransfer.qml
@@ -9,93 +9,98 @@ import App.Styles 1.0
// =============================================================================
DialogPlus {
- id: callTransfer
-
- // ---------------------------------------------------------------------------
-
- property var call
-
- // ---------------------------------------------------------------------------
-
- buttons: [
- TextButtonA {
- text: qsTr('cancel')
-
- onClicked: exit(0)
- }
- ]
-
- buttonsAlignment: Qt.AlignCenter
- descriptionText: qsTr('callTransferDescription')
-
- height: CallTransferStyle.height + 30
- width: CallTransferStyle.width
-
- onCallChanged: !call && exit(0)
-
- // ---------------------------------------------------------------------------
-
- ColumnLayout {
- anchors.fill: parent
- spacing: 0
-
- // -------------------------------------------------------------------------
- // Contact.
- // -------------------------------------------------------------------------
-
- Contact {
- Layout.fillWidth: true
-
- entry: SipAddressesModel.getSipAddressObserver(call ? call.fullPeerAddress : '', call ? call.fullLocalAddress : '')
- }
-
- // -------------------------------------------------------------------------
- // Address selector.
- // -------------------------------------------------------------------------
-
- Item {
- Layout.fillHeight: true
- Layout.fillWidth: true
-
- ColumnLayout {
- anchors.fill: parent
- spacing: CallTransferStyle.spacing
-
- TextField {
- id: filter
-
- Layout.fillWidth: true
-
- icon: 'search'
-
- onTextChanged: sipAddressesModel.setFilter(text)
- }
-
- ScrollableListViewField {
- Layout.fillHeight: true
- Layout.fillWidth: true
-
- SipAddressesView {
- anchors.fill: parent
-
- actions: [{
- icon: 'transfer',
- handler: function (entry) {
- callTransfer.call.transferTo(entry.sipAddress)
- exit(1)
- }
- }]
-
- genSipAddress: filter.text
-
- model: SearchSipAddressesModel {
- id: sipAddressesModel
- }
-
- onEntryClicked: actions[0].handler(entry)
- }
- }
- }
- }
- }
+ id: callTransfer
+
+ // ---------------------------------------------------------------------------
+
+ property var call
+ property bool attended: false
+
+ // ---------------------------------------------------------------------------
+
+ buttons: [
+ TextButtonA {
+ text: qsTr('cancel')
+
+ onClicked: exit(0)
+ }
+ ]
+
+ buttonsAlignment: Qt.AlignCenter
+ descriptionText: qsTr('callTransferDescription')
+
+ height: CallTransferStyle.height + 30
+ width: CallTransferStyle.width
+
+ onCallChanged: !call && exit(0)
+
+ // ---------------------------------------------------------------------------
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: 0
+
+ // -------------------------------------------------------------------------
+ // Contact.
+ // -------------------------------------------------------------------------
+
+ Contact {
+ Layout.fillWidth: true
+
+ entry: SipAddressesModel.getSipAddressObserver(call ? call.fullPeerAddress : '', call ? call.fullLocalAddress : '')
+ }
+
+ // -------------------------------------------------------------------------
+ // Address selector.
+ // -------------------------------------------------------------------------
+
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ ColumnLayout {
+ anchors.fill: parent
+ spacing: CallTransferStyle.spacing
+
+ TextField {
+ id: filter
+
+ Layout.fillWidth: true
+
+ icon: 'search'
+
+ onTextChanged: sipAddressesModel.setFilter(text)
+ }
+
+ ScrollableListViewField {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ SipAddressesView {
+ anchors.fill: parent
+
+ actions: [{
+ icon: 'transfer',
+ handler: function (entry) {
+ if (attended) {
+ var call = CallsListModel.launchAudioCall(entry.sipAddress, callTransfer.call.peerAddress)
+ } else {
+ callTransfer.call.transferTo(entry.sipAddress)
+ }
+ exit(1)
+ }
+ }]
+
+ genSipAddress: filter.text
+
+ model: SearchSipAddressesModel {
+ id: sipAddressesModel
+ }
+
+ onEntryClicked: actions[0].handler(entry)
+ }
+ }
+ }
+ }
+ }
}
diff --git a/linphone-app/ui/views/App/Main/Conversation.qml b/linphone-app/ui/views/App/Main/Conversation.qml
index 54ee317cf..f4cfb9ba7 100644
--- a/linphone-app/ui/views/App/Main/Conversation.qml
+++ b/linphone-app/ui/views/App/Main/Conversation.qml
@@ -259,7 +259,6 @@ ColumnLayout {
icon: 'group_chat'
visible: SettingsModel.outgoingCallsEnabled && conversation.haveMoreThanOneParticipants && conversation.haveLessThanMinParticipantsForCall && !conversation.hasBeenLeft
- //onClicked: CallsListModel.launchAudioCall(conversation.chatRoomModel)
onClicked: Logic.openConferenceManager({chatRoomModel:conversation.chatRoomModel, autoCall:true})
TooltipArea {
//: "Call all chat room's participants" : tooltip on a button for calling all participant in the current chat room
diff --git a/linphone-app/ui/views/App/Main/MainWindow.qml b/linphone-app/ui/views/App/Main/MainWindow.qml
index 4dcf69a77..9f82a79be 100644
--- a/linphone-app/ui/views/App/Main/MainWindow.qml
+++ b/linphone-app/ui/views/App/Main/MainWindow.qml
@@ -182,10 +182,10 @@ ApplicationWindow {
}
}
- onLaunchCall: CallsListModel.launchAudioCall(sipAddress)
+ onLaunchCall: CallsListModel.launchAudioCall(sipAddress, "")
onLaunchChat: CallsListModel.launchChat( sipAddress,0 )
onLaunchSecureChat: CallsListModel.launchChat( sipAddress,1 )
- onLaunchVideoCall: CallsListModel.launchVideoCall(sipAddress)
+ onLaunchVideoCall: CallsListModel.launchVideoCall(sipAddress, "")
}