27
#include <QtCore/QFile>
28
#include <QtCore/QTimer>
27
#include "callmanager_interface_singleton.h"
28
#include "configurationmanager_interface_singleton.h"
29
#include "contactbackend.h"
32
#include "dbus/callmanager.h"
33
#include "dbus/configurationmanager.h"
34
#include "abstractcontactbackend.h"
30
35
#include "contact.h"
31
36
#include "account.h"
32
#include "accountlist.h"
37
#include "accountlistmodel.h"
33
38
#include "videomodel.h"
39
#include "historymodel.h"
34
40
#include "instantmessagingmodel.h"
37
const call_state Call::actionPerformedStateMap [13][5] =
39
// ACCEPT REFUSE TRANSFER HOLD RECORD /**/
40
/*INCOMING */ {CALL_STATE_INCOMING , CALL_STATE_INCOMING , CALL_STATE_ERROR , CALL_STATE_INCOMING , CALL_STATE_INCOMING },/**/
41
/*RINGING */ {CALL_STATE_ERROR , CALL_STATE_RINGING , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_RINGING },/**/
42
/*CURRENT */ {CALL_STATE_ERROR , CALL_STATE_CURRENT , CALL_STATE_TRANSFERRED , CALL_STATE_CURRENT , CALL_STATE_CURRENT },/**/
43
/*DIALING */ {CALL_STATE_DIALING , CALL_STATE_OVER , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR },/**/
44
/*HOLD */ {CALL_STATE_ERROR , CALL_STATE_HOLD , CALL_STATE_TRANSF_HOLD , CALL_STATE_HOLD , CALL_STATE_HOLD },/**/
45
/*FAILURE */ {CALL_STATE_ERROR , CALL_STATE_FAILURE , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR },/**/
46
/*BUSY */ {CALL_STATE_ERROR , CALL_STATE_BUSY , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR },/**/
47
/*TRANSFER */ {CALL_STATE_TRANSFERRED, CALL_STATE_TRANSFERRED , CALL_STATE_CURRENT , CALL_STATE_TRANSFERRED , CALL_STATE_TRANSFERRED },/**/
48
/*TRANSF_HOLD */ {CALL_STATE_TRANSF_HOLD, CALL_STATE_TRANSF_HOLD , CALL_STATE_HOLD , CALL_STATE_TRANSF_HOLD , CALL_STATE_TRANSF_HOLD },/**/
49
/*OVER */ {CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR },/**/
50
/*ERROR */ {CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR },/**/
51
/*CONF */ {CALL_STATE_ERROR , CALL_STATE_CURRENT , CALL_STATE_TRANSFERRED , CALL_STATE_CURRENT , CALL_STATE_CURRENT },/**/
52
/*CONF_HOLD */ {CALL_STATE_ERROR , CALL_STATE_HOLD , CALL_STATE_TRANSF_HOLD , CALL_STATE_HOLD , CALL_STATE_HOLD },/**/
56
const function Call::actionPerformedFunctionMap[13][5] =
58
// ACCEPT REFUSE TRANSFER HOLD RECORD /**/
59
/*INCOMING */ {&Call::accept , &Call::refuse , &Call::acceptTransf , &Call::acceptHold , &Call::setRecord },/**/
60
/*RINGING */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::setRecord },/**/
61
/*CURRENT */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::hold , &Call::setRecord },/**/
62
/*DIALING */ {&Call::call , &Call::cancel , &Call::nothing , &Call::nothing , &Call::nothing },/**/
63
/*HOLD */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::unhold , &Call::setRecord },/**/
64
/*FAILURE */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::nothing },/**/
65
/*BUSY */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::nothing },/**/
66
/*TRANSFERT */ {&Call::transfer , &Call::hangUp , &Call::transfer , &Call::hold , &Call::setRecord },/**/
67
/*TRANSFERT_HOLD */ {&Call::transfer , &Call::hangUp , &Call::transfer , &Call::unhold , &Call::setRecord },/**/
68
/*OVER */ {&Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing },/**/
69
/*ERROR */ {&Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing },/**/
70
/*CONF */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::hold , &Call::setRecord },/**/
71
/*CONF_HOLD */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::unhold , &Call::setRecord },/**/
75
const call_state Call::stateChangedStateMap [13][6] =
77
// RINGING CURRENT BUSY HOLD HUNGUP FAILURE /**/
78
/*INCOMING */ {CALL_STATE_INCOMING , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
79
/*RINGING */ {CALL_STATE_RINGING , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
80
/*CURRENT */ {CALL_STATE_CURRENT , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
81
/*DIALING */ {CALL_STATE_RINGING , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
82
/*HOLD */ {CALL_STATE_HOLD , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
83
/*FAILURE */ {CALL_STATE_FAILURE , CALL_STATE_FAILURE , CALL_STATE_BUSY , CALL_STATE_FAILURE , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
84
/*BUSY */ {CALL_STATE_BUSY , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_BUSY , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
85
/*TRANSFER */ {CALL_STATE_TRANSFERRED , CALL_STATE_TRANSFERRED, CALL_STATE_BUSY , CALL_STATE_TRANSF_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
86
/*TRANSF_HOLD */ {CALL_STATE_TRANSF_HOLD , CALL_STATE_TRANSFERRED, CALL_STATE_BUSY , CALL_STATE_TRANSF_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
87
/*OVER */ {CALL_STATE_OVER , CALL_STATE_OVER , CALL_STATE_OVER , CALL_STATE_OVER , CALL_STATE_OVER , CALL_STATE_OVER },/**/
88
/*ERROR */ {CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_ERROR },/**/
89
/*CONF */ {CALL_STATE_CURRENT , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
90
/*CONF_HOLD */ {CALL_STATE_HOLD , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },/**/
93
const function Call::stateChangedFunctionMap[13][6] =
41
#include "useractionmodel.h"
42
#include "callmodel.h"
43
#include "numbercategory.h"
44
#include "phonedirectorymodel.h"
45
#include "phonenumber.h"
46
#include "videorenderer.h"
47
#include "tlsmethodmodel.h"
48
#include "audiosettingsmodel.h"
50
const TypedStateMachine< TypedStateMachine< Call::State , Call::Action> , Call::State> Call::actionPerformedStateMap =
52
// ACCEPT REFUSE TRANSFER HOLD RECORD /**/
53
/*INCOMING */ {{Call::State::INCOMING , Call::State::INCOMING , Call::State::ERROR , Call::State::INCOMING , Call::State::INCOMING }},/**/
54
/*RINGING */ {{Call::State::ERROR , Call::State::RINGING , Call::State::ERROR , Call::State::ERROR , Call::State::RINGING }},/**/
55
/*CURRENT */ {{Call::State::ERROR , Call::State::CURRENT , Call::State::TRANSFERRED , Call::State::CURRENT , Call::State::CURRENT }},/**/
56
/*DIALING */ {{Call::State::DIALING , Call::State::OVER , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
57
/*HOLD */ {{Call::State::ERROR , Call::State::HOLD , Call::State::TRANSF_HOLD , Call::State::HOLD , Call::State::HOLD }},/**/
58
/*FAILURE */ {{Call::State::ERROR , Call::State::FAILURE , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
59
/*BUSY */ {{Call::State::ERROR , Call::State::BUSY , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
60
/*TRANSFER */ {{Call::State::TRANSFERRED, Call::State::TRANSFERRED , Call::State::CURRENT , Call::State::TRANSFERRED , Call::State::TRANSFERRED }},/**/
61
/*TRANSF_HOLD */ {{Call::State::TRANSF_HOLD, Call::State::TRANSF_HOLD , Call::State::HOLD , Call::State::TRANSF_HOLD , Call::State::TRANSF_HOLD }},/**/
62
/*OVER */ {{Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
63
/*ERROR */ {{Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
64
/*CONF */ {{Call::State::ERROR , Call::State::CURRENT , Call::State::TRANSFERRED , Call::State::CURRENT , Call::State::CURRENT }},/**/
65
/*CONF_HOLD */ {{Call::State::ERROR , Call::State::HOLD , Call::State::TRANSF_HOLD , Call::State::HOLD , Call::State::HOLD }},/**/
69
const TypedStateMachine< TypedStateMachine< function , Call::Action > , Call::State > Call::actionPerformedFunctionMap =
71
// ACCEPT REFUSE TRANSFER HOLD RECORD /**/
72
/*INCOMING */ {{&Call::accept , &Call::refuse , &Call::acceptTransf , &Call::acceptHold , &Call::setRecord }},/**/
73
/*RINGING */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::setRecord }},/**/
74
/*CURRENT */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::hold , &Call::setRecord }},/**/
75
/*DIALING */ {{&Call::call , &Call::cancel , &Call::nothing , &Call::nothing , &Call::nothing }},/**/
76
/*HOLD */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::unhold , &Call::setRecord }},/**/
77
/*FAILURE */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::nothing }},/**/
78
/*BUSY */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::nothing }},/**/
79
/*TRANSFERT */ {{&Call::transfer , &Call::hangUp , &Call::transfer , &Call::hold , &Call::setRecord }},/**/
80
/*TRANSFERT_HOLD */ {{&Call::transfer , &Call::hangUp , &Call::transfer , &Call::unhold , &Call::setRecord }},/**/
81
/*OVER */ {{&Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing }},/**/
82
/*ERROR */ {{&Call::nothing , &Call::remove , &Call::nothing , &Call::nothing , &Call::nothing }},/**/
83
/*CONF */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::hold , &Call::setRecord }},/**/
84
/*CONF_HOLD */ {{&Call::nothing , &Call::hangUp , &Call::nothing , &Call::unhold , &Call::setRecord }},/**/
88
const TypedStateMachine< TypedStateMachine< Call::State , Call::DaemonState> , Call::State> Call::stateChangedStateMap =
90
// RINGING CURRENT BUSY HOLD HUNGUP FAILURE /**/
91
/*INCOMING */ {{Call::State::INCOMING , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
92
/*RINGING */ {{Call::State::RINGING , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
93
/*CURRENT */ {{Call::State::CURRENT , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
94
/*DIALING */ {{Call::State::RINGING , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
95
/*HOLD */ {{Call::State::HOLD , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
96
/*FAILURE */ {{Call::State::FAILURE , Call::State::FAILURE , Call::State::BUSY , Call::State::FAILURE , Call::State::OVER , Call::State::FAILURE }},/**/
97
/*BUSY */ {{Call::State::BUSY , Call::State::CURRENT , Call::State::BUSY , Call::State::BUSY , Call::State::OVER , Call::State::FAILURE }},/**/
98
/*TRANSFER */ {{Call::State::TRANSFERRED , Call::State::TRANSFERRED, Call::State::BUSY , Call::State::TRANSF_HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
99
/*TRANSF_HOLD */ {{Call::State::TRANSF_HOLD , Call::State::TRANSFERRED, Call::State::BUSY , Call::State::TRANSF_HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
100
/*OVER */ {{Call::State::OVER , Call::State::OVER , Call::State::OVER , Call::State::OVER , Call::State::OVER , Call::State::OVER }},/**/
101
/*ERROR */ {{Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR , Call::State::ERROR }},/**/
102
/*CONF */ {{Call::State::CURRENT , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
103
/*CONF_HOLD */ {{Call::State::HOLD , Call::State::CURRENT , Call::State::BUSY , Call::State::HOLD , Call::State::OVER , Call::State::FAILURE }},/**/
106
const TypedStateMachine< TypedStateMachine< function , Call::DaemonState > , Call::State > Call::stateChangedFunctionMap =
95
108
// RINGING CURRENT BUSY HOLD HUNGUP FAILURE /**/
96
/*INCOMING */ {&Call::nothing , &Call::start , &Call::startWeird , &Call::startWeird , &Call::startStop , &Call::start },/**/
97
/*RINGING */ {&Call::nothing , &Call::start , &Call::start , &Call::start , &Call::startStop , &Call::start },/**/
98
/*CURRENT */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },/**/
99
/*DIALING */ {&Call::nothing , &Call::warning , &Call::warning , &Call::warning , &Call::stop , &Call::warning },/**/
100
/*HOLD */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },/**/
101
/*FAILURE */ {&Call::nothing , &Call::warning , &Call::warning , &Call::warning , &Call::stop , &Call::nothing },/**/
102
/*BUSY */ {&Call::nothing , &Call::nothing , &Call::nothing , &Call::warning , &Call::stop , &Call::nothing },/**/
103
/*TRANSFERT */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },/**/
104
/*TRANSFERT_HOLD */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },/**/
105
/*OVER */ {&Call::nothing , &Call::warning , &Call::warning , &Call::warning , &Call::stop , &Call::warning },/**/
106
/*ERROR */ {&Call::nothing , &Call::nothing , &Call::nothing , &Call::nothing , &Call::stop , &Call::nothing },/**/
107
/*CONF */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },/**/
108
/*CONF_HOLD */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },/**/
111
const char * Call::historyIcons[3] = {ICON_HISTORY_INCOMING, ICON_HISTORY_OUTGOING, ICON_HISTORY_MISSED};
113
ContactBackend* Call::m_pContactBackend = nullptr;
114
Call* Call::m_sSelectedCall = nullptr;
116
void Call::setContactBackend(ContactBackend* be)
109
/*INCOMING */ {{&Call::nothing , &Call::start , &Call::startWeird , &Call::startWeird , &Call::startStop , &Call::start }},/**/
110
/*RINGING */ {{&Call::nothing , &Call::start , &Call::start , &Call::start , &Call::startStop , &Call::start }},/**/
111
/*CURRENT */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
112
/*DIALING */ {{&Call::nothing , &Call::warning , &Call::warning , &Call::warning , &Call::stop , &Call::warning }},/**/
113
/*HOLD */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
114
/*FAILURE */ {{&Call::nothing , &Call::warning , &Call::warning , &Call::warning , &Call::stop , &Call::nothing }},/**/
115
/*BUSY */ {{&Call::nothing , &Call::nothing , &Call::nothing , &Call::warning , &Call::stop , &Call::nothing }},/**/
116
/*TRANSFERT */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
117
/*TRANSFERT_HOLD */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
118
/*OVER */ {{&Call::nothing , &Call::warning , &Call::warning , &Call::warning , &Call::stop , &Call::warning }},/**/
119
/*ERROR */ {{&Call::error , &Call::error , &Call::error , &Call::error , &Call::stop , &Call::error }},/**/
120
/*CONF */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
121
/*CONF_HOLD */ {{&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing }},/**/
124
QDebug LIB_EXPORT operator<<(QDebug dbg, const Call::State& c)
126
dbg.nospace() << QString(Call::toHumanStateName(c));
130
QDebug LIB_EXPORT operator<<(QDebug dbg, const Call::DaemonState& c)
132
dbg.nospace() << static_cast<int>(c);
136
QDebug LIB_EXPORT operator<<(QDebug dbg, const Call::Action& c)
138
dbg.nospace() << static_cast<int>(c);
142
AbstractContactBackend* Call::m_pContactBackend = nullptr;
143
Call* Call::m_sSelectedCall = nullptr;
145
void Call::setContactBackend(AbstractContactBackend* be)
118
147
m_pContactBackend = be;
150
AbstractContactBackend* Call::contactBackend ()
152
return m_pContactBackend;
122
Call::Call(call_state startState, QString callId, QString peerName, QString peerNumber, QString account)
123
: m_isConference(false),m_pStopTime(nullptr),m_pStartTime(nullptr),
124
m_ContactChanged(false),m_pContact(nullptr),m_pImModel(nullptr)
156
Call::Call(Call::State startState, const QString& callId, const QString& peerName, PhoneNumber* number, Account* account)
157
: QObject(CallModel::instance()), m_isConference(false),m_pStopTimeStamp(0),
158
m_pImModel(nullptr),m_pTimer(nullptr),m_Recording(false),m_Account(nullptr),
159
m_PeerName(peerName),m_pPeerPhoneNumber(number),m_HistoryConst(HistoryTimeCategoryModel::HistoryConst::Never),
160
m_CallId(callId),m_CurrentState(startState),m_pStartTimeStamp(0),m_pDialNumber(nullptr),m_pTransferNumber(nullptr),
161
m_History(false),m_Missed(false),m_Direction(Call::Direction::OUTGOING)
126
this->m_CallId = callId ;
127
this->m_PeerPhoneNumber = peerNumber ;
128
this->m_PeerName = peerName ;
129
this->m_Account = account ;
130
this->m_Recording = false ;
131
this->m_pStartTime = nullptr ;
132
this->m_pStopTime = nullptr ;
133
changeCurrentState(startState) ;
135
m_ContactChanged = true;
136
CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
137
connect(&callManager,SIGNAL(recordPlaybackStopped(QString)), this, SLOT(stopPlayback(QString)) );
138
connect(&callManager,SIGNAL(updatePlaybackScale(int,int)) , this, SLOT(updatePlayback(int,int)));
139
if (m_pContactBackend)
140
connect(m_pContactBackend,SIGNAL(collectionChanged()),this,SLOT(contactBackendChanged()));
164
Q_ASSERT(!callId.isEmpty());
165
setObjectName("Call:"+callId);
166
changeCurrentState(startState);
167
m_pUserActionModel = new UserActionModel(this);
143
170
emit changed(this);
175
215
///Build a call from its ID
176
216
Call* Call::buildExistingCall(QString callId)
178
CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
218
CallManagerInterface& callManager = DBus::CallManager::instance();
179
219
MapStringString details = callManager.getCallDetails(callId).value();
181
qDebug() << "Constructing existing call with details : " << details;
183
QString peerNumber = details[ CALL_PEER_NUMBER ];
184
QString peerName = details[ CALL_PEER_NAME ];
185
QString account = details[ CALL_ACCOUNTID ];
186
call_state startState = getStartStateFromDaemonCallState(details[CALL_STATE], details[CALL_TYPE]);
188
Call* call = new Call(startState, callId, peerName, peerNumber, account) ;
190
if (!details[ CALL_TIMESTAMP_START ].isEmpty())
191
call->m_pStartTime = new QDateTime(QDateTime::fromTime_t(details[ CALL_TIMESTAMP_START ].toInt())) ;
193
call->m_pStartTime = new QDateTime(QDateTime::currentDateTime()) ;
195
call->m_Recording = callManager.getIsRecording(callId) ;
196
call->m_HistoryState = getHistoryStateFromType(details[STATE_KEY]);
222
//qDebug() << "Constructing existing call with details : " << details;
224
const QString peerNumber = details[ Call::DetailsMapFields::PEER_NUMBER ];
225
const QString peerName = details[ Call::DetailsMapFields::PEER_NAME ];
226
const QString account = details[ Call::DetailsMapFields::ACCOUNT_ID ];
227
Call::State startState = startStateFromDaemonCallState(details[Call::DetailsMapFields::STATE], details[Call::DetailsMapFields::TYPE]);
228
Account* acc = AccountListModel::instance()->getAccountById(account);
229
PhoneNumber* nb = PhoneDirectoryModel::instance()->getNumber(peerNumber,acc);
230
Call* call = new Call(startState, callId, peerName, nb, acc);
231
call->m_Recording = callManager.getIsRecording(callId);
232
call->m_HistoryState = historyStateFromType(details[Call::HistoryMapFields::STATE]);
234
if (!details[ Call::DetailsMapFields::TIMESTAMP_START ].isEmpty())
235
call->setStartTimeStamp(details[ Call::DetailsMapFields::TIMESTAMP_START ].toInt());
239
call->setStartTimeStamp(curTime);
243
call->m_pTimer = new QTimer(CallModel::instance());
244
call->m_pTimer->setInterval(1000);
245
connect(call->m_pTimer,SIGNAL(timeout()),call,SLOT(updated()));
246
call->m_pTimer->start();
248
if (call->peerPhoneNumber()) {
249
call->peerPhoneNumber()->addCall(call);
199
253
} //buildExistingCall
201
255
///Build a call from a dialing call (a call that is about to exist)
202
Call* Call::buildDialingCall(QString callId, const QString & peerName, QString account)
256
Call* Call::buildDialingCall(const QString& callId, const QString & peerName, Account* account)
204
Call* call = new Call(CALL_STATE_DIALING, callId, peerName, "", account);
205
call->m_HistoryState = NONE;
258
Call* call = new Call(Call::State::DIALING, callId, peerName, nullptr, account);
259
call->m_HistoryState = Call::LegacyHistoryState::NONE;
260
call->m_Direction = Call::Direction::OUTGOING;
261
if (AudioSettingsModel::instance()->isRoomToneEnabled()) {
262
AudioSettingsModel::instance()->playRoomTone();
209
267
///Build a call from a dbus event
210
Call* Call::buildIncomingCall(const QString & callId)
268
Call* Call::buildIncomingCall(const QString& callId)
212
CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
270
CallManagerInterface & callManager = DBus::CallManager::instance();
213
271
MapStringString details = callManager.getCallDetails(callId).value();
215
QString from = details[ CALL_PEER_NUMBER ];
216
QString account = details[ CALL_ACCOUNTID ];
217
QString peerName = details[ CALL_PEER_NAME ];
219
Call* call = new Call(CALL_STATE_INCOMING, callId, peerName, from, account);
220
call->m_HistoryState = MISSED;
273
const QString from = details[ Call::DetailsMapFields::PEER_NUMBER ];
274
const QString account = details[ Call::DetailsMapFields::ACCOUNT_ID ];
275
const QString peerName = details[ Call::DetailsMapFields::PEER_NAME ];
276
Account* acc = AccountListModel::instance()->getAccountById(account);
277
PhoneNumber* nb = PhoneDirectoryModel::instance()->getNumber(from,acc);
278
Call* call = new Call(Call::State::INCOMING, callId, peerName, nb, acc);
279
call->m_HistoryState = Call::LegacyHistoryState::MISSED;
280
call->m_Direction = Call::Direction::INCOMING;
281
if (call->peerPhoneNumber()) {
282
call->peerPhoneNumber()->addCall(call);
222
285
} //buildIncomingCall
224
///Build a rigging call (from dbus)
287
///Build a ringing call (from dbus)
225
288
Call* Call::buildRingingCall(const QString & callId)
227
CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
290
CallManagerInterface& callManager = DBus::CallManager::instance();
228
291
MapStringString details = callManager.getCallDetails(callId).value();
230
QString from = details[ CALL_PEER_NUMBER ];
231
QString account = details[ CALL_ACCOUNTID ];
232
QString peerName = details[ CALL_PEER_NAME ];
234
Call* call = new Call(CALL_STATE_RINGING, callId, peerName, from, account);
235
call->m_HistoryState = OUTGOING;
293
const QString from = details[ Call::DetailsMapFields::PEER_NUMBER ];
294
const QString account = details[ Call::DetailsMapFields::ACCOUNT_ID ];
295
const QString peerName = details[ Call::DetailsMapFields::PEER_NAME ];
296
Account* acc = AccountListModel::instance()->getAccountById(account);
297
PhoneNumber* nb = PhoneDirectoryModel::instance()->getNumber(from,acc);
299
Call* call = new Call(Call::State::RINGING, callId, peerName, nb, acc);
300
call->m_HistoryState = LegacyHistoryState::OUTGOING;
301
call->m_Direction = Call::Direction::OUTGOING;
303
if (call->peerPhoneNumber()) {
304
call->peerPhoneNumber()->addCall(call);
237
307
} //buildRingingCall
239
310
/*****************************************************************************
243
314
****************************************************************************/
245
316
///Build a call that is already over
246
Call* Call::buildHistoryCall(const QString & callId, uint startTimeStamp, uint stopTimeStamp, QString account, QString name, QString number, QString type)
317
Call* Call::buildHistoryCall(const QMap<QString,QString>& hc)
248
if(name == "empty") name = "";
249
Call* call = new Call(CALL_STATE_OVER, callId, name, number, account );
251
QDateTime* start = new QDateTime(QDateTime::fromTime_t(startTimeStamp));
252
QDateTime* stop = new QDateTime(QDateTime::fromTime_t(stopTimeStamp));
255
call->m_pStartTime = start;
256
call->m_pStopTime = stop;
259
call->m_HistoryState = getHistoryStateFromType(type);
319
const QString& callId = hc[ Call::HistoryMapFields::CALLID ] ;
320
time_t startTimeStamp = hc[ Call::HistoryMapFields::TIMESTAMP_START ].toUInt() ;
321
time_t stopTimeStamp = hc[ Call::HistoryMapFields::TIMESTAMP_STOP ].toUInt() ;
322
const QString& accId = hc[ Call::HistoryMapFields::ACCOUNT_ID ] ;
323
const QString& name = hc[ Call::HistoryMapFields::DISPLAY_NAME ] ;
324
const QString& number = hc[ Call::HistoryMapFields::PEER_NUMBER ] ;
325
const QString& type = hc[ Call::HistoryMapFields::STATE ] ;
326
const QString& direction = hc[ Call::HistoryMapFields::DIRECTION ] ;
327
const bool missed = hc[ Call::HistoryMapFields::MISSED ] == "true";
329
Account* acc = AccountListModel::instance()->getAccountById(accId);
330
PhoneNumber* nb = PhoneDirectoryModel::instance()->getNumber(number,acc);
331
Call* call = new Call(Call::State::OVER, callId, (name == "empty")?QString():name, nb, acc );
333
call->m_pStopTimeStamp = stopTimeStamp ;
334
call->m_History = true;
335
call->setStartTimeStamp(startTimeStamp);
337
call->m_HistoryState = historyStateFromType(type);
338
call->m_Account = AccountListModel::instance()->getAccountById(accId);
340
//BEGIN In ~2015, remove the old logic and clean this
341
if (missed || call->m_HistoryState == Call::LegacyHistoryState::MISSED) {
342
call->m_Missed = true;
343
call->m_HistoryState = Call::LegacyHistoryState::MISSED;
345
if (!direction.isEmpty()) {
346
if (direction == HistoryStateName::INCOMING) {
347
call->m_Direction = Call::Direction::INCOMING ;
348
call->m_HistoryState = Call::LegacyHistoryState::INCOMING;
350
else if (direction == HistoryStateName::OUTGOING) {
351
call->m_Direction = Call::Direction::OUTGOING ;
352
call->m_HistoryState = Call::LegacyHistoryState::OUTGOING;
355
else if (call->m_HistoryState == Call::LegacyHistoryState::INCOMING)
356
call->m_Direction = Call::Direction::INCOMING ;
357
else if (call->m_HistoryState == Call::LegacyHistoryState::OUTGOING)
358
call->m_Direction = Call::Direction::OUTGOING ;
359
else //BUG Pick one, even if it is the wrong one
360
call->m_Direction = Call::Direction::OUTGOING ;
362
call->m_HistoryState = Call::LegacyHistoryState::MISSED;
365
call->setObjectName("History:"+call->m_CallId);
367
if (call->peerPhoneNumber()) {
368
call->peerPhoneNumber()->addCall(call);
369
connect(call->peerPhoneNumber(),SIGNAL(presentChanged(bool)),call,SLOT(updated()));
264
375
///Get the history state from the type (see Call.cpp header)
265
history_state Call::getHistoryStateFromType(QString type)
376
Call::LegacyHistoryState Call::historyStateFromType(const QString& type)
267
if(type == MISSED_STRING )
269
else if(type == OUTGOING_STRING )
271
else if(type == INCOMING_STRING )
378
if(type == Call::HistoryStateName::MISSED )
379
return Call::LegacyHistoryState::MISSED ;
380
else if(type == Call::HistoryStateName::OUTGOING )
381
return Call::LegacyHistoryState::OUTGOING ;
382
else if(type == Call::HistoryStateName::INCOMING )
383
return Call::LegacyHistoryState::INCOMING ;
384
return Call::LegacyHistoryState::NONE ;
276
387
///Get the start sate from the daemon state
277
call_state Call::getStartStateFromDaemonCallState(QString daemonCallState, QString daemonCallType)
388
Call::State Call::startStateFromDaemonCallState(const QString& daemonCallState, const QString& daemonCallType)
279
if(daemonCallState == DAEMON_CALL_STATE_INIT_CURRENT )
280
return CALL_STATE_CURRENT ;
281
else if(daemonCallState == DAEMON_CALL_STATE_INIT_HOLD )
282
return CALL_STATE_HOLD ;
283
else if(daemonCallState == DAEMON_CALL_STATE_INIT_BUSY )
284
return CALL_STATE_BUSY ;
285
else if(daemonCallState == DAEMON_CALL_STATE_INIT_INACTIVE && daemonCallType == DAEMON_CALL_TYPE_INCOMING )
286
return CALL_STATE_INCOMING ;
287
else if(daemonCallState == DAEMON_CALL_STATE_INIT_INACTIVE && daemonCallType == DAEMON_CALL_TYPE_OUTGOING )
288
return CALL_STATE_RINGING ;
289
else if(daemonCallState == DAEMON_CALL_STATE_INIT_INCOMING )
290
return CALL_STATE_INCOMING ;
291
else if(daemonCallState == DAEMON_CALL_STATE_INIT_RINGING )
292
return CALL_STATE_RINGING ;
390
if(daemonCallState == Call::DaemonStateInit::CURRENT )
391
return Call::State::CURRENT ;
392
else if(daemonCallState == Call::DaemonStateInit::HOLD )
393
return Call::State::HOLD ;
394
else if(daemonCallState == Call::DaemonStateInit::BUSY )
395
return Call::State::BUSY ;
396
else if(daemonCallState == Call::DaemonStateInit::INACTIVE && daemonCallType == Call::CallType::INCOMING )
397
return Call::State::INCOMING ;
398
else if(daemonCallState == Call::DaemonStateInit::INACTIVE && daemonCallType == Call::CallType::OUTGOING )
399
return Call::State::RINGING ;
400
else if(daemonCallState == Call::DaemonStateInit::INCOMING )
401
return Call::State::INCOMING ;
402
else if(daemonCallState == Call::DaemonStateInit::RINGING )
403
return Call::State::RINGING ;
294
return CALL_STATE_FAILURE ;
405
return Call::State::FAILURE ;
295
406
} //getStartStateFromDaemonCallState
297
409
/*****************************************************************************
301
413
****************************************************************************/
303
415
///Transfer state from internal to daemon internal syntaz
304
daemon_call_state Call::toDaemonCallState(const QString& stateName)
416
Call::DaemonState Call::toDaemonCallState(const QString& stateName)
306
if(stateName == QString(CALL_STATE_CHANGE_HUNG_UP) )
307
return DAEMON_CALL_STATE_HUNG_UP ;
308
if(stateName == QString(CALL_STATE_CHANGE_RINGING) )
309
return DAEMON_CALL_STATE_RINGING ;
310
if(stateName == QString(CALL_STATE_CHANGE_CURRENT) )
311
return DAEMON_CALL_STATE_CURRENT ;
312
if(stateName == QString(CALL_STATE_CHANGE_UNHOLD_CURRENT) )
313
return DAEMON_CALL_STATE_CURRENT ;
314
if(stateName == QString(CALL_STATE_CHANGE_HOLD) )
315
return DAEMON_CALL_STATE_HOLD ;
316
if(stateName == QString(CALL_STATE_CHANGE_BUSY) )
317
return DAEMON_CALL_STATE_BUSY ;
318
if(stateName == QString(CALL_STATE_CHANGE_FAILURE) )
319
return DAEMON_CALL_STATE_FAILURE ;
418
if(stateName == Call::StateChange::HUNG_UP )
419
return Call::DaemonState::HUNG_UP ;
420
if(stateName == Call::StateChange::RINGING )
421
return Call::DaemonState::RINGING ;
422
if(stateName == Call::StateChange::CURRENT )
423
return Call::DaemonState::CURRENT ;
424
if(stateName == Call::StateChange::UNHOLD_CURRENT )
425
return Call::DaemonState::CURRENT ;
426
if(stateName == Call::StateChange::HOLD )
427
return Call::DaemonState::HOLD ;
428
if(stateName == Call::StateChange::BUSY )
429
return Call::DaemonState::BUSY ;
430
if(stateName == Call::StateChange::FAILURE )
431
return Call::DaemonState::FAILURE ;
321
433
qDebug() << "stateChanged signal received with unknown state.";
322
return DAEMON_CALL_STATE_FAILURE ;
434
return Call::DaemonState::FAILURE ;
323
435
} //toDaemonCallState
325
437
///Transform a conference call state to a proper call state
326
call_state Call::confStatetoCallState(const QString& stateName)
438
Call::State Call::confStatetoCallState(const QString& stateName)
328
if ( stateName == CONF_STATE_CHANGE_HOLD )
329
return CALL_STATE_CONFERENCE_HOLD;
330
else if ( stateName == CONF_STATE_CHANGE_ACTIVE )
331
return CALL_STATE_CONFERENCE;
440
if ( stateName == Call::ConferenceStateChange::HOLD )
441
return Call::State::CONFERENCE_HOLD;
442
else if ( stateName == Call::ConferenceStateChange::ACTIVE )
443
return Call::State::CONFERENCE;
333
return CALL_STATE_ERROR; //Well, this may bug a little
445
return Call::State::ERROR; //Well, this may bug a little
336
448
///Transform a backend state into a translated string
337
const QString Call::toHumanStateName() const
449
const QString Call::toHumanStateName(const Call::State cur)
339
switch (m_CurrentState) {
340
case CALL_STATE_INCOMING:
341
return ( "Ringing (in)" );
343
case CALL_STATE_RINGING:
344
return ( "Ringing (out)" );
346
case CALL_STATE_CURRENT:
347
return ( "Talking" );
349
case CALL_STATE_DIALING:
350
return ( "Dialing" );
352
case CALL_STATE_HOLD:
355
case CALL_STATE_FAILURE:
358
case CALL_STATE_BUSY:
361
case CALL_STATE_TRANSFERRED:
362
return ( "Transfer" );
364
case CALL_STATE_TRANSF_HOLD:
365
return ( "Transfer hold" );
367
case CALL_STATE_OVER:
370
case CALL_STATE_ERROR:
373
case CALL_STATE_CONFERENCE:
374
return ( "Conference" );
376
case CALL_STATE_CONFERENCE_HOLD:
377
return ( "Conference (hold)" );
452
case Call::State::INCOMING:
453
return tr( "Ringing (in)" );
455
case Call::State::RINGING:
456
return tr( "Ringing (out)" );
458
case Call::State::CURRENT:
459
return tr( "Talking" );
461
case Call::State::DIALING:
462
return tr( "Dialing" );
464
case Call::State::HOLD:
467
case Call::State::FAILURE:
468
return tr( "Failed" );
470
case Call::State::BUSY:
473
case Call::State::TRANSFERRED:
474
return tr( "Transfer" );
476
case Call::State::TRANSF_HOLD:
477
return tr( "Transfer hold" );
479
case Call::State::OVER:
482
case Call::State::ERROR:
483
return tr( "Error" );
485
case Call::State::CONFERENCE:
486
return tr( "Conference" );
488
case Call::State::CONFERENCE_HOLD:
489
return tr( "Conference (hold)" );
490
case Call::State::COUNT:
491
return tr( "ERROR" );
493
return QString::number(static_cast<int>(cur));
497
QString Call::toHumanStateName() const
499
return toHumanStateName(state());
383
502
///Get the time (second from 1 jan 1970) when the call ended
384
QString Call::getStopTimeStamp() const
503
time_t Call::stopTimeStamp() const
386
if (m_pStopTime == nullptr)
388
return QString::number(m_pStopTime->toTime_t());
505
return m_pStopTimeStamp;
391
508
///Get the time (second from 1 jan 1970) when the call started
392
QString Call::getStartTimeStamp() const
509
time_t Call::startTimeStamp() const
394
if (m_pStartTime == nullptr)
396
return QString::number(m_pStartTime->toTime_t());
511
return m_pStartTimeStamp;
399
514
///Get the number where the call have been transferred
400
const QString Call::getTransferNumber() const
515
const QString Call::transferNumber() const
402
return m_TransferNumber;
517
return m_pTransferNumber?m_pTransferNumber->uri():QString();
405
520
///Get the call / peer number
406
const QString Call::getCallNumber() const
521
const QString Call::dialNumber() const
523
if (m_CurrentState != Call::State::DIALING) return QString();
524
if (!m_pDialNumber) {
525
const_cast<Call*>(this)->m_pDialNumber = new TemporaryPhoneNumber();
527
return m_pDialNumber->uri();
411
530
///Return the call id
412
const QString Call::getCallId() const
531
const QString Call::id() const
417
///Return the peer phone number
418
const QString Call::getPeerPhoneNumber() const
536
PhoneNumber* Call::peerPhoneNumber() const
420
return m_PeerPhoneNumber;
538
if (m_CurrentState == Call::State::DIALING) {
539
if (!m_pTransferNumber) {
540
const_cast<Call*>(this)->m_pTransferNumber = new TemporaryPhoneNumber(m_pPeerPhoneNumber);
543
const_cast<Call*>(this)->m_pDialNumber = new TemporaryPhoneNumber(m_pPeerPhoneNumber);
544
return m_pDialNumber;
546
return m_pPeerPhoneNumber?m_pPeerPhoneNumber:const_cast<PhoneNumber*>(PhoneNumber::BLANK());
423
549
///Get the peer name
424
const QString Call::getPeerName() const
550
const QString Call::peerName() const
426
552
return m_PeerName;
429
555
///Generate the best possible peer name
430
const QString Call::getFormattedName()
556
const QString Call::formattedName() const
432
558
if (isConference())
434
else if (m_pContact && !m_pContact->getFormattedName().isEmpty())
435
return m_pContact->getFormattedName();
436
else if (!getPeerName().isEmpty())
559
return tr("Conference");
560
else if (!peerPhoneNumber())
562
else if (peerPhoneNumber()->contact() && !peerPhoneNumber()->contact()->formattedName().isEmpty())
563
return peerPhoneNumber()->contact()->formattedName();
564
else if (!peerName().isEmpty())
437
565
return m_PeerName;
566
else if (peerPhoneNumber())
567
return peerPhoneNumber()->uri();
439
return m_PeerPhoneNumber;
569
return tr("Unknown");
442
572
///If the call have a valid record
443
bool Call::hasRecording() const
445
return !getRecordingPath().isEmpty() && QFile::exists(getRecordingPath());
573
bool Call::hasRecording() const
575
return !recordingPath().isEmpty() && QFile::exists(recordingPath());
578
///Generate an human readable string from the difference between StartTimeStamp and StopTimeStamp (or 'now')
579
QString Call::length() const
581
if (m_pStartTimeStamp == m_pStopTimeStamp) return QString(); //Invalid
583
if (m_pStopTimeStamp)
584
nsec = stopTimeStamp() - startTimeStamp();//If the call is over
588
nsec = curTime - m_pStartTimeStamp;
591
return QString("%1:%2:%3 ").arg((nsec%(3600*24))/3600).arg(((nsec%(3600*24))%3600)/60,2,10,QChar('0')).arg(((nsec%(3600*24))%3600)%60,2,10,QChar('0'));
593
return QString("%1:%2 ").arg(nsec/60,2,10,QChar('0')).arg(nsec%60,2,10,QChar('0'));
596
///Is this call part of history
597
bool Call::isHistory()
599
if (m_CurrentState == Call::State::OVER && !m_History)
604
///Is this call missed
605
bool Call::isMissed() const
610
///Is the call incoming or outgoing
611
Call::Direction Call::direction() const
448
616
///Get the current state
449
call_state Call::getCurrentState() const
617
Call::State Call::state() const
451
619
return m_CurrentState;
454
622
///Get the call recording
455
bool Call::getRecording() const
623
bool Call::isRecording() const
457
CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
458
((Call*) this)->m_Recording = callManager.getIsRecording(m_CallId);
459
625
return m_Recording;
462
628
///Get the call account id
463
Account* Call::getAccount() const
629
Account* Call::account() const
465
return AccountList::getInstance()->getAccountById(m_Account);
468
634
///Is this call a conference
469
bool Call::isConference() const
635
bool Call::isConference() const
471
637
return m_isConference;
474
640
///Get the conference ID
475
const QString Call::getConfId() const
641
const QString Call::confId() const
480
646
///Get the recording path
481
const QString Call::getRecordingPath() const
647
const QString Call::recordingPath() const
483
649
return m_RecordingPath;
486
652
///Get the current codec
487
QString Call::getCurrentCodecName() const
653
QString Call::currentCodecName() const
489
CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
655
CallManagerInterface& callManager = DBus::CallManager::instance();
490
656
return callManager.getCurrentAudioCodecName(m_CallId);
494
call_state Call::getState() const
496
return m_CurrentState;
499
659
///Get the history state
500
history_state Call::getHistoryState() const
660
Call::LegacyHistoryState Call::historyState() const
502
662
return m_HistoryState;
505
///Is this call over?
506
bool Call::isHistory() const
508
return (getState() == CALL_STATE_OVER);
511
///Is this call selected (useful for GUIs)
512
bool Call::isSelected() const
514
return m_sSelectedCall == this;
517
665
///This function could also be called mayBeSecure or haveChancesToBeEncryptedButWeCantTell.
518
bool Call::isSecure() const {
666
bool Call::isSecure() const
520
if (m_Account.isEmpty()) {
521
670
qDebug() << "Account not set, can't check security";
525
Account* currentAccount = AccountList::getInstance()->getAccountById(m_Account);
526
return currentAccount && ((currentAccount->isTlsEnable()) || (currentAccount->getTlsMethod()));
673
//BUG this doesn't work
674
return m_Account && ((m_Account->isTlsEnable()) || (m_Account->tlsMethod() != TlsMethodModel::Type::DEFAULT));
529
Contact* Call::getContact()
531
if (!m_pContact && m_ContactChanged) {
532
m_pContact = m_pContactBackend->getContactByPhone(m_PeerPhoneNumber,true,getAccount());
537
677
///Return the renderer associated with this call or nullptr
538
VideoRenderer* Call::getVideoRenderer()
678
VideoRenderer* Call::videoRenderer() const
540
680
#ifdef ENABLE_VIDEO
541
return VideoModel::getInstance()->getRenderer(this);
681
return VideoModel::instance()->getRenderer(this);
604
775
****************************************************************************/
606
777
///The call state just changed
607
call_state Call::stateChanged(const QString& newStateName)
778
Call::State Call::stateChanged(const QString& newStateName)
609
call_state previousState = m_CurrentState;
780
Call::State previousState = m_CurrentState;
610
781
if (!m_isConference) {
611
daemon_call_state dcs = toDaemonCallState(newStateName);
612
changeCurrentState(stateChangedStateMap[m_CurrentState][dcs]);
614
CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
782
Call::DaemonState dcs = toDaemonCallState(newStateName);
783
if (dcs == Call::DaemonState::COUNT || m_CurrentState == Call::State::COUNT) {
784
qDebug() << "Error: Invalid state change";
785
return Call::State::FAILURE;
789
changeCurrentState(stateChangedStateMap[m_CurrentState][dcs]);
791
catch(Call::State& state) {
792
qDebug() << "State change failed (stateChangedStateMap)" << state;
793
m_CurrentState = Call::State::ERROR;
796
return m_CurrentState;
798
catch(Call::DaemonState& state) {
799
qDebug() << "State change failed (stateChangedStateMap)" << state;
800
m_CurrentState = Call::State::ERROR;
803
return m_CurrentState;
806
qDebug() << "State change failed (stateChangedStateMap) other";;
807
m_CurrentState = Call::State::ERROR;
810
return m_CurrentState;
813
CallManagerInterface & callManager = DBus::CallManager::instance();
615
814
MapStringString details = callManager.getCallDetails(m_CallId).value();
616
if (details[CALL_PEER_NAME] != m_PeerName)
617
m_PeerName = details[CALL_PEER_NAME];
815
if (details[Call::DetailsMapFields::PEER_NAME] != m_PeerName)
816
m_PeerName = details[Call::DetailsMapFields::PEER_NAME];
619
(this->*(stateChangedFunctionMap[previousState][dcs]))();
819
(this->*(stateChangedFunctionMap[previousState][dcs]))();
821
catch(Call::State& state) {
822
qDebug() << "State change failed (stateChangedFunctionMap)" << state;
823
m_CurrentState = Call::State::ERROR;
826
return m_CurrentState;
828
catch(Call::DaemonState& state) {
829
qDebug() << "State change failed (stateChangedFunctionMap)" << state;
830
m_CurrentState = Call::State::ERROR;
833
return m_CurrentState;
836
qDebug() << "State change failed (stateChangedFunctionMap) other";;
837
m_CurrentState = Call::State::ERROR;
840
return m_CurrentState;
622
844
//Until now, it does not worth using stateChangedStateMap, conferences are quite simple
623
845
m_CurrentState = confStatetoCallState(newStateName);
848
if ((m_CurrentState == Call::State::HOLD || m_CurrentState == Call::State::CURRENT) && !m_pTimer) {
849
m_pTimer = new QTimer(this);
850
m_pTimer->setInterval(1000);
851
connect(m_pTimer,SIGNAL(timeout()),this,SLOT(updated()));
854
if (m_CurrentState != Call::State::DIALING && m_pDialNumber) {
855
if (!m_pPeerPhoneNumber)
856
m_pPeerPhoneNumber = PhoneDirectoryModel::instance()->fromTemporary(m_pDialNumber);
857
delete m_pDialNumber;
858
m_pDialNumber = nullptr;
625
862
qDebug() << "Calling stateChanged " << newStateName << " -> " << toDaemonCallState(newStateName) << " on call with state " << previousState << ". Become " << m_CurrentState;
626
863
return m_CurrentState;
629
866
///An account have been performed
630
call_state Call::actionPerformed(call_action action)
867
Call::State Call::performAction(Call::Action action)
632
call_state previousState = m_CurrentState;
869
const Call::State previousState = m_CurrentState;
633
870
//update the state
634
if (previousState < 13 && action < 5) {
635
872
changeCurrentState(actionPerformedStateMap[previousState][action]);
636
//execute the action associated with this transition
874
catch(Call::State& state) {
875
qDebug() << "State change failed (actionPerformedStateMap)" << state;
876
m_CurrentState = Call::State::ERROR;
879
return Call::State::ERROR;
882
qDebug() << "State change failed (actionPerformedStateMap) other";;
883
m_CurrentState = Call::State::ERROR;
886
return m_CurrentState;
889
//execute the action associated with this transition
637
891
(this->*(actionPerformedFunctionMap[previousState][action]))();
638
qDebug() << "Calling action " << action << " on call with state " << previousState << ". Become " << m_CurrentState;
639
//return the new state
893
catch(Call::State& state) {
894
qDebug() << "State change failed (actionPerformedFunctionMap)" << state;
895
m_CurrentState = Call::State::ERROR;
898
return Call::State::ERROR;
900
catch(Call::Action& action) {
901
qDebug() << "State change failed (actionPerformedFunctionMap)" << action;
902
m_CurrentState = Call::State::ERROR;
905
return Call::State::ERROR;
908
qDebug() << "State change failed (actionPerformedFunctionMap) other";;
909
m_CurrentState = Call::State::ERROR;
912
return m_CurrentState;
914
qDebug() << "Calling action " << action << " on call with state " << previousState << ". Become " << m_CurrentState;
641
915
return m_CurrentState;
642
916
} //actionPerformed
644
918
///Change the state
645
void Call::changeCurrentState(call_state newState)
919
void Call::changeCurrentState(Call::State newState)
921
if (newState == Call::State::COUNT) {
922
qDebug() << "Error: Call reach invalid state";
923
m_CurrentState = Call::State::ERROR;
647
927
m_CurrentState = newState;
650
931
emit changed(this);
652
if (m_CurrentState == CALL_STATE_OVER)
933
if (m_CurrentState == Call::State::OVER)
653
934
emit isOver(this);
937
///Set the start timestamp and update the cache
938
void Call::setStartTimeStamp(time_t stamp)
940
m_pStartTimeStamp = stamp;
941
//While the HistoryConst is not directly related to the call concept,
942
//It is called to often to ignore
943
m_HistoryConst = HistoryTimeCategoryModel::timeToHistoryConst(m_pStartTimeStamp);
656
946
///Send a text message
657
947
void Call::sendTextMessage(QString message)
659
CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
949
CallManagerInterface& callManager = DBus::CallManager::instance();
660
950
Q_NOREPLY callManager.sendTextMessage(isConference()?m_ConfId:m_CallId,message);
661
qDebug() << "MODEL IS" << m_pImModel;
662
951
if (!m_pImModel) {
663
m_pImModel = InstantMessagingModelManager::getInstance()->getModel(this);
952
m_pImModel = InstantMessagingModelManager::instance()->getModel(this);
665
qDebug() << "MODEL IS2" << m_pImModel;
666
954
m_pImModel->addOutgoingMessage(message);
669
///Private version of setStartTime
670
QDateTime* Call::setStartTime_private(QDateTime* time)
672
//if (m_pStartTime && time)
673
// delete m_pStartTime;
675
return m_pStartTime = time;
678
///Private version of setStopTime
679
QDateTime* Call::setStopTime_private(QDateTime* time)
681
//if (m_pStopTime && time)
682
// delete m_pStopTime;
683
return m_pStopTime = time;
686
958
/*****************************************************************************
945
1403
///Stop the record, if any
946
1404
void Call::stopRecording()
948
CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
949
Q_NOREPLY callManager.stopRecordedFilePlayback(getRecordingPath());
1406
CallManagerInterface& callManager = DBus::CallManager::instance();
1407
Q_NOREPLY callManager.stopRecordedFilePlayback(recordingPath());
950
1408
emit playbackStopped(); //TODO remove this, it is a workaround for bug #11942
953
1411
///seek the record, if any
954
1412
void Call::seekRecording(double position)
956
CallManagerInterface& callManager = CallManagerInterfaceSingleton::getInstance();
1414
CallManagerInterface& callManager = DBus::CallManager::instance();
957
1415
Q_NOREPLY callManager.recordPlaybackSeek(position);
960
1418
///Daemon record playback stopped
961
void Call::stopPlayback(QString filePath)
1419
void Call::stopPlayback(const QString& filePath)
963
if (filePath == getRecordingPath()) {
1421
if (filePath == recordingPath()) {
964
1422
emit playbackStopped();
968
1426
///Daemon playback position chnaged
969
void Call::updatePlayback(int position,int size)
971
emit playbackPositionChanged(position,size);
974
///Called to notice the call thatits contact might be outdated
975
void Call::contactBackendChanged()
977
m_ContactChanged = true;
1427
void Call::updatePlayback(const QString& path, int position,int size)
1429
if (path == m_RecordingPath) {
1430
emit playbackPositionChanged(position,size);
1434
UserActionModel* Call::userActionModel() const
1436
return m_pUserActionModel;
1439
///Common source for model data roles
1440
QVariant Call::roleData(int role) const
1442
const Contact* ct = peerPhoneNumber()?peerPhoneNumber()->contact():nullptr;
1444
case Call::Role::Name:
1445
case Qt::DisplayRole:
1447
return tr("Conference");
1448
else if (state() == Call::State::DIALING)
1449
return dialNumber();
1450
else if (m_PeerName.isEmpty())
1451
return ct?ct->formattedName():peerPhoneNumber()?peerPhoneNumber()->uri():dialNumber();
1453
return formattedName();
1456
return dialNumber();
1457
case Call::Role::Number:
1458
return peerPhoneNumber()->uri();
1460
case Call::Role::Direction2:
1461
return static_cast<int>(m_Direction);
1463
case Call::Role::Date:
1464
return (int)startTimeStamp();
1466
case Call::Role::Length:
1469
case Call::Role::FormattedDate:
1470
return QDateTime::fromTime_t(startTimeStamp()).toString();
1472
case Call::Role::HasRecording:
1473
return hasRecording();
1475
case Call::Role::Historystate:
1476
return static_cast<int>(historyState());
1478
case Call::Role::Filter: {
1479
QString normStripppedC;
1480
foreach(QChar char2,QString(static_cast<int>(historyState())+'\n'+roleData(Call::Role::Name).toString()+'\n'+
1481
roleData(Call::Role::Number).toString()).toLower().normalized(QString::NormalizationForm_KD) ) {
1482
if (!char2.combiningClass())
1483
normStripppedC += char2;
1485
return normStripppedC;
1488
case Call::Role::FuzzyDate:
1489
return (int)m_HistoryConst;
1491
case Call::Role::IsBookmark:
1494
case Call::Role::Security:
1497
case Call::Role::Department:
1498
return ct?ct->department():QVariant();
1500
case Call::Role::Email:
1501
return ct?ct->preferredEmail():QVariant();
1503
case Call::Role::Organisation:
1504
return ct?ct->organization():QVariant();
1506
case Call::Role::Codec:
1507
return currentCodecName();
1509
case Call::Role::IsConference:
1510
return isConference();
1512
case Call::Role::Object:
1513
return QVariant::fromValue(const_cast<Call*>(this));
1515
case Call::Role::PhoneNu:
1516
return QVariant::fromValue(const_cast<PhoneNumber*>(peerPhoneNumber()));
1518
case Call::Role::PhotoPtr:
1519
return QVariant::fromValue((void*)(ct?ct->photo():nullptr));
1521
case Call::Role::CallState:
1522
return static_cast<int>(state());
1524
case Call::Role::Id:
1525
return ((m_isConference)?confId():id());
1527
case Call::Role::StartTime:
1528
return (int) m_pStartTimeStamp;
1529
case Call::Role::StopTime:
1530
return (int) m_pStopTimeStamp;
1531
case Call::Role::IsRecording:
1532
return isRecording();
1533
case Call::Role::IsPresent:
1534
return peerPhoneNumber()->isPresent();
1535
case Call::Role::IsTracked:
1536
return peerPhoneNumber()->isTracked();
1537
case Call::Role::SupportPresence:
1538
return peerPhoneNumber()->supportPresence();
1539
case Call::Role::CategoryIcon:
1540
return peerPhoneNumber()->category()->icon(peerPhoneNumber()->isTracked(),peerPhoneNumber()->isPresent());
1541
case Call::Role::CallCount:
1542
return peerPhoneNumber()->callCount();
1543
case Call::Role::TotalSpentTime:
1544
return peerPhoneNumber()->totalSpentTime();
1545
case Call::Role::DropState:
1546
return property("dropState");
1548
case Call::Role::Missed:
1550
case Call::Role::DTMFAnimState:
1551
return property("DTMFAnimState");
1553
case Call::Role::LastDTMFidx:
1554
return property("latestDtmfIdx");
1556
case Call::Role::DropPosition:
1557
return property("dropPosition");
1566
void Call::playDTMF(const QString& str)
1568
Q_NOREPLY DBus::CallManager::instance().playDTMF(str);
1569
emit dtmfPlayed(str);