2
0

mainwindow.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*
  2. * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  3. * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
  4. *
  5. * Version: MPL 1.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License Version
  8. * 1.1 (the "License"); you may not use this file except in compliance with
  9. * the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14. * for the specific language governing rights and limitations under the
  15. * License.
  16. *
  17. * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
  18. *
  19. * The Initial Developer of the Original Code is
  20. * Anthony Minessale II <anthm@freeswitch.org>
  21. * Portions created by the Initial Developer are Copyright (C)
  22. * the Initial Developer. All Rights Reserved.
  23. *
  24. * Contributor(s):
  25. *
  26. * Joao Mesquita <jmesquita@freeswitch.org>
  27. *
  28. */
  29. #include <QInputDialog>
  30. #include <QMessageBox>
  31. #include "mainwindow.h"
  32. #include "ui_mainwindow.h"
  33. #include <switch_version.h>
  34. MainWindow::MainWindow(QWidget *parent) :
  35. QMainWindow(parent),
  36. ui(new Ui::MainWindow),
  37. preferences(NULL),
  38. _consoleWindow(NULL),
  39. _stateDebugDialog(NULL)
  40. {
  41. ui->setupUi(this);
  42. /* Setup the taskbar icon */
  43. sysTray = new QSystemTrayIcon(QIcon(":/images/taskbar_icon"), this);
  44. sysTray->setToolTip(tr("FSComm"));
  45. /* Connect DTMF buttons */
  46. dialpadMapper = new QSignalMapper(this);
  47. connect(ui->dtmf0Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  48. connect(ui->dtmf1Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  49. connect(ui->dtmf2Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  50. connect(ui->dtmf3Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  51. connect(ui->dtmf4Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  52. connect(ui->dtmf5Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  53. connect(ui->dtmf6Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  54. connect(ui->dtmf7Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  55. connect(ui->dtmf8Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  56. connect(ui->dtmf9Btn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  57. connect(ui->dtmfABtn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  58. connect(ui->dtmfBBtn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  59. connect(ui->dtmfCBtn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  60. connect(ui->dtmfDBtn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  61. connect(ui->dtmfAstBtn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  62. connect(ui->dtmfPoundBtn, SIGNAL(clicked()), dialpadMapper, SLOT(map()));
  63. dialpadMapper->setMapping(ui->dtmf0Btn, QString("0"));
  64. dialpadMapper->setMapping(ui->dtmf1Btn, QString("1"));
  65. dialpadMapper->setMapping(ui->dtmf2Btn, QString("2"));
  66. dialpadMapper->setMapping(ui->dtmf3Btn, QString("3"));
  67. dialpadMapper->setMapping(ui->dtmf4Btn, QString("4"));
  68. dialpadMapper->setMapping(ui->dtmf5Btn, QString("5"));
  69. dialpadMapper->setMapping(ui->dtmf6Btn, QString("6"));
  70. dialpadMapper->setMapping(ui->dtmf7Btn, QString("7"));
  71. dialpadMapper->setMapping(ui->dtmf8Btn, QString("8"));
  72. dialpadMapper->setMapping(ui->dtmf9Btn, QString("9"));
  73. dialpadMapper->setMapping(ui->dtmfABtn, QString("A"));
  74. dialpadMapper->setMapping(ui->dtmfBBtn, QString("B"));
  75. dialpadMapper->setMapping(ui->dtmfCBtn, QString("C"));
  76. dialpadMapper->setMapping(ui->dtmfDBtn, QString("D"));
  77. dialpadMapper->setMapping(ui->dtmfAstBtn, QString("*"));
  78. dialpadMapper->setMapping(ui->dtmfPoundBtn, QString("#"));
  79. connect(dialpadMapper, SIGNAL(mapped(QString)), this, SLOT(sendDTMF(QString)));
  80. /* Connect events related to FreeSWITCH */
  81. connect(g_FSHost, SIGNAL(ready()),this, SLOT(fshostReady()));
  82. connect(g_FSHost, SIGNAL(ringing(QSharedPointer<Call>)), this, SLOT(ringing(QSharedPointer<Call>)));
  83. connect(g_FSHost, SIGNAL(answered(QSharedPointer<Call>)), this, SLOT(answered(QSharedPointer<Call>)));
  84. connect(g_FSHost, SIGNAL(hungup(QSharedPointer<Call>)), this, SLOT(hungup(QSharedPointer<Call>)));
  85. connect(g_FSHost, SIGNAL(newOutgoingCall(QSharedPointer<Call>)), this, SLOT(newOutgoingCall(QSharedPointer<Call>)));
  86. connect(g_FSHost, SIGNAL(callFailed(QSharedPointer<Call>)), this, SLOT(callFailed(QSharedPointer<Call>)));
  87. connect(g_FSHost, SIGNAL(accountStateChange(QSharedPointer<Account>)), this, SLOT(accountStateChanged(QSharedPointer<Account>)));
  88. connect(g_FSHost, SIGNAL(newAccount(QSharedPointer<Account>)), this, SLOT(accountAdd(QSharedPointer<Account>)));
  89. connect(g_FSHost, SIGNAL(delAccount(QSharedPointer<Account>)), this, SLOT(accountDel(QSharedPointer<Account>)));
  90. connect(g_FSHost, SIGNAL(coreLoadingError(QString)), this, SLOT(coreLoadingError(QString)));
  91. /* Connect call commands */
  92. connect(ui->newCallBtn, SIGNAL(clicked()), this, SLOT(makeCall()));
  93. connect(ui->answerBtn, SIGNAL(clicked()), this, SLOT(paAnswer()));
  94. connect(ui->hangupBtn, SIGNAL(clicked()), this, SLOT(paHangup()));
  95. connect(ui->recoredCallBtn, SIGNAL(toggled(bool)), SLOT(recordCall(bool)));
  96. connect(ui->btnHold, SIGNAL(toggled(bool)), this, SLOT(holdCall(bool)));
  97. /*connect(ui->btnTransfer, SIGNAL(clicked()), this, SLOT(transferCall()));*/
  98. connect(ui->tableCalls, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(callTableDoubleClick(QTableWidgetItem*)));
  99. connect(ui->action_Preferences, SIGNAL(triggered()), this, SLOT(prefTriggered()));
  100. connect(ui->action_Exit, SIGNAL(triggered()), this, SLOT(close()));
  101. connect(ui->actionConsole, SIGNAL(triggered()), this, SLOT(debugConsoleTriggered()));
  102. connect(ui->actionEvents, SIGNAL(triggered()), this, SLOT(debugEventsTriggered()));
  103. connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(showAbout()));
  104. connect(ui->actionSetDefaultAccount, SIGNAL(triggered(bool)), this, SLOT(setDefaultAccount()));
  105. connect(sysTray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(sysTrayActivated(QSystemTrayIcon::ActivationReason)));
  106. /* Set the context menus */
  107. ui->tableAccounts->addAction(ui->actionSetDefaultAccount);
  108. /* Set other properties */
  109. ui->tableAccounts->horizontalHeader()->setStretchLastSection(true);
  110. /* Set the call timer */
  111. callTimer = new QTimer(this);
  112. callTimer->setInterval(1000);
  113. connect(callTimer, SIGNAL(timeout()), this, SLOT(updateCallTimers()));
  114. callTimer->start();
  115. }
  116. MainWindow::~MainWindow()
  117. {
  118. delete ui;
  119. QString res;
  120. g_FSHost->sendCmd("fsctl", "shutdown", &res);
  121. g_FSHost->wait();
  122. }
  123. void MainWindow::updateCallTimers()
  124. {
  125. for(int row=0; row<ui->tableCalls->rowCount(); row++)
  126. {
  127. QTableWidgetItem* item = ui->tableCalls->item(row, 2);
  128. QSharedPointer<Call> call = g_FSHost->getCallByUUID(item->data(Qt::UserRole).toString());
  129. QTime time = call.data()->getCurrentStateTime();
  130. item->setText(time.toString("hh:mm:ss"));
  131. item->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
  132. }
  133. }
  134. void MainWindow::setDefaultAccount()
  135. {
  136. QString accName = ui->tableAccounts->item(ui->tableAccounts->selectedRanges()[0].topRow(), 0)->text();
  137. if (accName.isEmpty())
  138. return;
  139. ISettings *settings = new ISettings();
  140. //settings->beginGroup("FreeSWITCH/conf/globals");
  141. switch_core_set_variable("default_gateway", accName.toAscii().data());
  142. //settings->setValue("default_gateway", accName);
  143. //settings->endGroup();
  144. delete (settings);
  145. }
  146. void MainWindow::debugEventsTriggered()
  147. {
  148. if (!_stateDebugDialog)
  149. _stateDebugDialog = new StateDebugDialog();
  150. _stateDebugDialog->raise();
  151. _stateDebugDialog->show();
  152. _stateDebugDialog->activateWindow();
  153. }
  154. void MainWindow::debugConsoleTriggered()
  155. {
  156. if (!_consoleWindow)
  157. _consoleWindow = new ConsoleWindow();
  158. _consoleWindow->raise();
  159. _consoleWindow->show();
  160. _consoleWindow->activateWindow();
  161. }
  162. void MainWindow::applyPreprocessors(QStringList cmds)
  163. {
  164. if (g_FSHost->getCurrentActiveCall().isNull()) return;
  165. QString uuid = g_FSHost->getCurrentActiveCall().data()->getUuid();
  166. foreach(QString cmd, cmds)
  167. {
  168. switch_stream_handle_t stream = { 0 };
  169. SWITCH_STANDARD_STREAM(stream);
  170. switch_api_execute("uuid_preprocess", QString("%1 %2").arg(uuid, cmd).toAscii().data(), NULL, &stream);
  171. switch_safe_free(stream.data);
  172. }
  173. }
  174. void MainWindow::prefTriggered()
  175. {
  176. if (!preferences)
  177. {
  178. preferences = new PrefDialog();
  179. connect(preferences, SIGNAL(preprocessorsApplied(QStringList)), this, SLOT(applyPreprocessors(QStringList)));
  180. }
  181. preferences->raise();
  182. preferences->show();
  183. preferences->activateWindow();
  184. }
  185. void MainWindow::coreLoadingError(QString err)
  186. {
  187. QMessageBox::critical(this, tr("Core error!"),
  188. tr("The core failed to load. Please, ask for help as the softphone will not be useable. Error code: %1").arg(err),
  189. QMessageBox::Ok);
  190. }
  191. void MainWindow::accountAdd(QSharedPointer<Account> acc)
  192. {
  193. ui->tableAccounts->setRowCount(ui->tableAccounts->rowCount()+1);
  194. QTableWidgetItem *gwField = new QTableWidgetItem(acc.data()->getName());
  195. QTableWidgetItem *stField = new QTableWidgetItem(acc.data()->getStateName());
  196. ui->tableAccounts->setItem(ui->tableAccounts->rowCount()-1,0,gwField);
  197. ui->tableAccounts->setItem(ui->tableAccounts->rowCount()-1,1,stField);
  198. ui->tableAccounts->resizeColumnsToContents();
  199. ui->tableAccounts->resizeRowsToContents();
  200. ui->tableAccounts->horizontalHeader()->setStretchLastSection(true);
  201. }
  202. void MainWindow::accountDel(QSharedPointer<Account> acc)
  203. {
  204. foreach (QTableWidgetItem *i, ui->tableAccounts->findItems(acc.data()->getName(), Qt::MatchExactly))
  205. {
  206. if (i->text() == acc.data()->getName())
  207. {
  208. ui->tableAccounts->removeRow(i->row());
  209. //ui->tableAccounts->setRowCount(ui->tableAccounts->rowCount()-1);
  210. ui->tableAccounts->resizeColumnsToContents();
  211. ui->tableAccounts->resizeRowsToContents();
  212. ui->tableAccounts->horizontalHeader()->setStretchLastSection(true);
  213. break;
  214. }
  215. }
  216. }
  217. void MainWindow::accountStateChanged(QSharedPointer<Account> acc)
  218. {
  219. ui->statusBar->showMessage(tr("Account %1 is %2").arg(acc.data()->getName(), acc.data()->getStateName()));
  220. foreach (QTableWidgetItem *i, ui->tableAccounts->findItems(acc.data()->getName(), Qt::MatchExactly))
  221. {
  222. if (i->text() == acc.data()->getName())
  223. {
  224. ui->tableAccounts->item(i->row(), 1)->setText(acc.data()->getStateName());
  225. ui->tableAccounts->resizeColumnsToContents();
  226. ui->tableAccounts->resizeRowsToContents();
  227. ui->tableAccounts->horizontalHeader()->setStretchLastSection(true);
  228. return;
  229. }
  230. }
  231. }
  232. void MainWindow::sendDTMF(QString dtmf)
  233. {
  234. g_FSHost->getCurrentActiveCall().data()->sendDTMF(dtmf);
  235. }
  236. void MainWindow::callTableDoubleClick(QTableWidgetItem *item)
  237. {
  238. QSharedPointer<Call> lastCall = g_FSHost->getCurrentActiveCall();
  239. QSharedPointer<Call> call = g_FSHost->getCallByUUID(item->data(Qt::UserRole).toString());
  240. QString switch_str = QString("switch %1").arg(call.data()->getCallID());
  241. QString result;
  242. if (g_FSHost->sendCmd("pa", switch_str.toAscii(), &result) == SWITCH_STATUS_FALSE) {
  243. ui->textEdit->setText(QString("Error switching to call %1").arg(call.data()->getCallID()));
  244. return;
  245. }
  246. ui->hangupBtn->setEnabled(true);
  247. /* Last call was hungup and we are switching */
  248. if (!lastCall.isNull())
  249. lastCall.data()->setActive(false);
  250. call.data()->setActive(true);
  251. }
  252. void MainWindow::makeCall()
  253. {
  254. bool ok = true;
  255. QString dialstring = QInputDialog::getText(this, tr("Make new call"),
  256. tr("Number to dial:"), QLineEdit::Normal, NULL,&ok);
  257. QSharedPointer<Account> acc = g_FSHost->getCurrentDefaultAccount();
  258. if (!acc.isNull()) {
  259. /*QSettings *settings = fscommSettings();
  260. settings->beginGroup("FreeSWITCH/conf/sofia.conf/profiles/profile/gateways/");
  261. settings->beginGroup(acc.data()->getUUID());
  262. settings->beginGroup("gateway/global_vars");
  263. QString cidName = settings->value("caller_id_name").toString();
  264. QString cidNum = settings->value("caller_id_num").toString();
  265. settings->endGroup();
  266. settings->endGroup();
  267. settings->endGroup();
  268. if (cidName.isEmpty()) {
  269. settings->beginGroup("FreeSWITCH/conf/portaudio.conf/settings/params");
  270. cidName = settings->value("cid-name").toString();
  271. settings->endGroup();
  272. }
  273. if (cidNum.isEmpty()) {
  274. settings->beginGroup("FreeSWITCH/conf/portaudio.conf/settings/params");
  275. cidNum = settings->value("cid-num").toString();
  276. settings->endGroup();
  277. }*/
  278. /* Set the vars for this call */
  279. //switch_core_set_variable("fscomm_caller_id_name", cidName.toAscii().data());
  280. //switch_core_set_variable("fscomm_caller_id_num", cidNum.toAscii().data());
  281. //delete (settings);
  282. }
  283. if (ok && !dialstring.isEmpty())
  284. {
  285. paCall(dialstring);
  286. }
  287. }
  288. void MainWindow::fshostReady()
  289. {
  290. ui->statusBar->showMessage("Ready");
  291. ui->newCallBtn->setEnabled(true);
  292. ui->textEdit->setEnabled(true);
  293. ui->textEdit->setText("Ready to dial and receive calls!");
  294. sysTray->show();
  295. sysTray->showMessage(tr("Status"), tr("FSComm has initialized!"), QSystemTrayIcon::Information, 5000);
  296. if (!g_FSHost->isModuleLoaded("mod_sofia"))
  297. {
  298. QMessageBox::warning(this, tr("SIP not available"),
  299. tr("Sofia could not be loaded, therefore, SIP will not be available."),
  300. QMessageBox::Ok);
  301. }
  302. if (!g_FSHost->isModuleLoaded("mod_portaudio"))
  303. {
  304. QMessageBox::warning(this, tr("Audio not available"),
  305. tr("Portaudio could not be loaded. Please check if mod_portaudio is properly compiled."),
  306. QMessageBox::Ok);
  307. }
  308. }
  309. void MainWindow::paAnswer()
  310. {
  311. QString result;
  312. if (g_FSHost->sendCmd("pa", "answer", &result) == SWITCH_STATUS_FALSE) {
  313. ui->textEdit->setText("Error sending that command");
  314. }
  315. ui->textEdit->setText("Talking...");
  316. ui->hangupBtn->setEnabled(true);
  317. ui->answerBtn->setEnabled(false);
  318. }
  319. void MainWindow::paCall(QString dialstring)
  320. {
  321. QString result;
  322. QString callstring = QString("call %1").arg(dialstring);
  323. if (g_FSHost->sendCmd("pa", callstring.toAscii(), &result) == SWITCH_STATUS_FALSE) {
  324. ui->textEdit->setText("Error sending that command");
  325. }
  326. ui->hangupBtn->setEnabled(true);
  327. }
  328. void MainWindow::paHangup()
  329. {
  330. QString result;
  331. if (g_FSHost->sendCmd("pa", "hangup", &result) == SWITCH_STATUS_FALSE) {
  332. ui->textEdit->setText("Error sending that command");
  333. }
  334. ui->textEdit->setText("Click to dial number...");
  335. ui->statusBar->showMessage("Call hungup");
  336. ui->hangupBtn->setEnabled(false);
  337. }
  338. void MainWindow::holdCall(bool pressed)
  339. {
  340. QSharedPointer<Call> call = g_FSHost->getCurrentActiveCall();
  341. if (call.isNull())
  342. {
  343. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not hold call because there is not current active call!.\n");
  344. return;
  345. }
  346. if (call.data()->toggleHold(pressed) != SWITCH_STATUS_SUCCESS)
  347. {
  348. QMessageBox::warning(this,tr("Hold call"),
  349. tr("<p>Could not get active call to hold/unhold."
  350. "<p>Please report this bug."),
  351. QMessageBox::Ok);
  352. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not hold/unhold call [%s].\n", call.data()->getUuid().toAscii().data());
  353. return;
  354. }
  355. }
  356. void MainWindow::recordCall(bool pressed)
  357. {
  358. QSharedPointer<Call> call = g_FSHost->getCurrentActiveCall();
  359. if (call.isNull())
  360. {
  361. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not record call because there is not current active call!.\n");
  362. return;
  363. }
  364. if (call.data()->toggleRecord(pressed) != SWITCH_STATUS_SUCCESS)
  365. {
  366. QMessageBox::warning(this,tr("Record call"),
  367. tr("<p>Could not get active call to start/stop recording."
  368. "<p>Please report this bug."),
  369. QMessageBox::Ok);
  370. switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not record call [%s].\n", call.data()->getUuid().toAscii().data());
  371. return;
  372. }
  373. }
  374. void MainWindow::newOutgoingCall(QSharedPointer<Call> call)
  375. {
  376. ui->textEdit->setText(QString("Calling %1").arg(call.data()->getDestinationNumber()));
  377. ui->tableCalls->setRowCount(ui->tableCalls->rowCount()+1);
  378. QTableWidgetItem *item0 = new QTableWidgetItem(QString("%1").arg(call.data()->getDestinationNumber()));
  379. item0->setData(Qt::UserRole, call.data()->getUuid());
  380. ui->tableCalls->setItem(ui->tableCalls->rowCount()-1,0,item0);
  381. QTableWidgetItem *item1 = new QTableWidgetItem(tr("Dialing..."));
  382. item1->setData(Qt::UserRole, call.data()->getUuid());
  383. ui->tableCalls->setItem(ui->tableCalls->rowCount()-1,1,item1);
  384. QTableWidgetItem *item2 = new QTableWidgetItem("00:00:00");
  385. item2->setData(Qt::UserRole, call.data()->getUuid());
  386. ui->tableCalls->setItem(ui->tableCalls->rowCount()-1,2,item2);
  387. ui->tableCalls->resizeColumnsToContents();
  388. ui->tableCalls->resizeRowsToContents();
  389. ui->tableCalls->horizontalHeader()->setStretchLastSection(true);
  390. ui->hangupBtn->setEnabled(true);
  391. call.data()->setActive(true);
  392. }
  393. void MainWindow::ringing(QSharedPointer<Call> call)
  394. {
  395. for (int i=0; i<ui->tableCalls->rowCount(); i++)
  396. {
  397. QTableWidgetItem *item = ui->tableCalls->item(i, 1);
  398. if (item->data(Qt::UserRole).toString() == call.data()->getUuid())
  399. {
  400. item->setText(tr("Ringing"));
  401. if (call.data()->getDirection() == FSCOMM_CALL_DIRECTION_INBOUND)
  402. ui->textEdit->setText(QString("Call from %1 (%2)").arg(call.data()->getCidName(), call.data()->getCidNumber()));
  403. else
  404. ui->textEdit->setText(QString("Call to %1 is ringing.").arg(call.data()->getDestinationNumber()));
  405. return;
  406. }
  407. }
  408. if (call.data()->getDirection() == FSCOMM_CALL_DIRECTION_INBOUND)
  409. ui->textEdit->setText(QString("Call from %1 (%2)").arg(call.data()->getCidName(), call.data()->getCidNumber()));
  410. else
  411. ui->textEdit->setText(QString("Call to %1 is ringing.").arg(call.data()->getDestinationNumber()));
  412. ui->tableCalls->setRowCount(ui->tableCalls->rowCount()+1);
  413. QTableWidgetItem *item0 = new QTableWidgetItem(QString("%1 (%2)").arg(call.data()->getCidName(), call.data()->getCidNumber()));
  414. item0->setData(Qt::UserRole, call.data()->getUuid());
  415. ui->tableCalls->setItem(ui->tableCalls->rowCount()-1,0,item0);
  416. QTableWidgetItem *item1 = new QTableWidgetItem(tr("Ringing"));
  417. item1->setData(Qt::UserRole, call.data()->getUuid());
  418. ui->tableCalls->setItem(ui->tableCalls->rowCount()-1,1,item1);
  419. QTableWidgetItem *item2 = new QTableWidgetItem("00:00:00");
  420. item2->setData(Qt::UserRole, call.data()->getUuid());
  421. ui->tableCalls->setItem(ui->tableCalls->rowCount()-1,2,item2);
  422. ui->tableCalls->resizeColumnsToContents();
  423. ui->tableCalls->resizeRowsToContents();
  424. ui->tableCalls->horizontalHeader()->setStretchLastSection(true);
  425. ui->answerBtn->setEnabled(true);
  426. call.data()->setActive(true);
  427. }
  428. void MainWindow::answered(QSharedPointer<Call> call)
  429. {
  430. for (int i=0; i<ui->tableCalls->rowCount(); i++)
  431. {
  432. QTableWidgetItem *item = ui->tableCalls->item(i, 1);
  433. if (item->data(Qt::UserRole).toString() == call.data()->getUuid())
  434. {
  435. item->setText(tr("Answered"));
  436. ui->tableCalls->resizeColumnsToContents();
  437. ui->tableCalls->resizeRowsToContents();
  438. ui->tableCalls->horizontalHeader()->setStretchLastSection(true);
  439. break;
  440. }
  441. }
  442. ui->recoredCallBtn->setEnabled(true);
  443. ui->recoredCallBtn->setChecked(false);
  444. ui->btnHold->setEnabled(true);
  445. ui->btnHold->setChecked(false);
  446. ui->btnTransfer->setEnabled(true);
  447. ui->dtmf0Btn->setEnabled(true);
  448. ui->dtmf1Btn->setEnabled(true);
  449. ui->dtmf2Btn->setEnabled(true);
  450. ui->dtmf3Btn->setEnabled(true);
  451. ui->dtmf4Btn->setEnabled(true);
  452. ui->dtmf5Btn->setEnabled(true);
  453. ui->dtmf6Btn->setEnabled(true);
  454. ui->dtmf7Btn->setEnabled(true);
  455. ui->dtmf8Btn->setEnabled(true);
  456. ui->dtmf9Btn->setEnabled(true);
  457. ui->dtmfABtn->setEnabled(true);
  458. ui->dtmfBBtn->setEnabled(true);
  459. ui->dtmfCBtn->setEnabled(true);
  460. ui->dtmfDBtn->setEnabled(true);
  461. ui->dtmfAstBtn->setEnabled(true);
  462. ui->dtmfPoundBtn->setEnabled(true);
  463. }
  464. void MainWindow::callFailed(QSharedPointer<Call> call)
  465. {
  466. for (int i=0; i<ui->tableCalls->rowCount(); i++)
  467. {
  468. QTableWidgetItem *item = ui->tableCalls->item(i, 1);
  469. if (item->data(Qt::UserRole).toString() == call.data()->getUuid())
  470. {
  471. ui->tableCalls->removeRow(i);
  472. ui->tableCalls->resizeColumnsToContents();
  473. ui->tableCalls->resizeRowsToContents();
  474. ui->tableCalls->horizontalHeader()->setStretchLastSection(true);
  475. break;
  476. }
  477. }
  478. if (call.data()->getDirection() == FSCOMM_CALL_DIRECTION_INBOUND)
  479. {
  480. ui->textEdit->setText(tr("Call from %1 (%2) failed with reason %3.").arg(call.data()->getCidName(),
  481. call.data()->getCidNumber(),
  482. call.data()->getCause()));
  483. }
  484. else
  485. {
  486. ui->textEdit->setText(tr("Call to %1 failed with reason %3.").arg(call.data()->getCidName(),
  487. call.data()->getCidNumber(),
  488. call.data()->getCause()));
  489. }
  490. call.data()->setActive(false);
  491. /* TODO: Will cause problems if 2 calls are received at the same time */
  492. ui->recoredCallBtn->setEnabled(false);
  493. ui->recoredCallBtn->setChecked(false);
  494. ui->btnHold->setEnabled(false);
  495. ui->btnHold->setChecked(false);
  496. ui->btnTransfer->setEnabled(false);
  497. ui->answerBtn->setEnabled(false);
  498. ui->hangupBtn->setEnabled(false);
  499. ui->dtmf0Btn->setEnabled(false);
  500. ui->dtmf1Btn->setEnabled(false);
  501. ui->dtmf2Btn->setEnabled(false);
  502. ui->dtmf3Btn->setEnabled(false);
  503. ui->dtmf4Btn->setEnabled(false);
  504. ui->dtmf5Btn->setEnabled(false);
  505. ui->dtmf6Btn->setEnabled(false);
  506. ui->dtmf7Btn->setEnabled(false);
  507. ui->dtmf8Btn->setEnabled(false);
  508. ui->dtmf9Btn->setEnabled(false);
  509. ui->dtmfABtn->setEnabled(false);
  510. ui->dtmfBBtn->setEnabled(false);
  511. ui->dtmfCBtn->setEnabled(false);
  512. ui->dtmfDBtn->setEnabled(false);
  513. ui->dtmfAstBtn->setEnabled(false);
  514. ui->dtmfPoundBtn->setEnabled(false);
  515. }
  516. void MainWindow::hungup(QSharedPointer<Call> call)
  517. {
  518. for (int i=0; i<ui->tableCalls->rowCount(); i++)
  519. {
  520. QTableWidgetItem *item = ui->tableCalls->item(i, 1);
  521. if (item->data(Qt::UserRole).toString() == call.data()->getUuid())
  522. {
  523. ui->tableCalls->removeRow(i);
  524. ui->tableCalls->resizeColumnsToContents();
  525. ui->tableCalls->resizeRowsToContents();
  526. ui->tableCalls->horizontalHeader()->setStretchLastSection(true);
  527. break;
  528. }
  529. }
  530. call.data()->setActive(false);
  531. if (call.data()->getDirection() == FSCOMM_CALL_DIRECTION_INBOUND)
  532. {
  533. ui->textEdit->setText(tr("Call with %1 (%2) hungup.").arg(call.data()->getCidName(), call.data()->getCidNumber()));
  534. }
  535. else
  536. {
  537. ui->textEdit->setText(tr("Call with %1 hungup.").arg(call.data()->getDestinationNumber()));
  538. }
  539. /* TODO: Will cause problems if 2 calls are received at the same time */
  540. ui->recoredCallBtn->setEnabled(false);
  541. ui->recoredCallBtn->setChecked(false);
  542. ui->btnHold->setEnabled(false);
  543. ui->btnHold->setChecked(false);
  544. ui->btnTransfer->setEnabled(false);
  545. ui->answerBtn->setEnabled(false);
  546. ui->hangupBtn->setEnabled(false);
  547. ui->dtmf0Btn->setEnabled(false);
  548. ui->dtmf1Btn->setEnabled(false);
  549. ui->dtmf2Btn->setEnabled(false);
  550. ui->dtmf3Btn->setEnabled(false);
  551. ui->dtmf4Btn->setEnabled(false);
  552. ui->dtmf5Btn->setEnabled(false);
  553. ui->dtmf6Btn->setEnabled(false);
  554. ui->dtmf7Btn->setEnabled(false);
  555. ui->dtmf8Btn->setEnabled(false);
  556. ui->dtmf9Btn->setEnabled(false);
  557. ui->dtmfABtn->setEnabled(false);
  558. ui->dtmfBBtn->setEnabled(false);
  559. ui->dtmfCBtn->setEnabled(false);
  560. ui->dtmfDBtn->setEnabled(false);
  561. ui->dtmfAstBtn->setEnabled(false);
  562. ui->dtmfPoundBtn->setEnabled(false);
  563. }
  564. void MainWindow::changeEvent(QEvent *e)
  565. {
  566. QMainWindow::changeEvent(e);
  567. switch (e->type()) {
  568. case QEvent::LanguageChange:
  569. ui->retranslateUi(this);
  570. break;
  571. default:
  572. break;
  573. }
  574. }
  575. void MainWindow::showAbout()
  576. {
  577. QString result;
  578. g_FSHost->sendCmd("version", "", &result);
  579. QMessageBox::about(this, tr("About FSComm"),
  580. tr("<h2>FSComm</h2>"
  581. "<p>Author: Jo&atilde;o Mesquita &lt;jmesquita@freeswitch.org>"
  582. "<p>FsComm is a softphone based on libfreeswitch."
  583. "<p>The FreeSWITCH&trade; images and name are trademark of"
  584. " Anthony Minessale II, primary author of FreeSWITCH&trade;."
  585. "<p>Compiled FSComm version: %1"
  586. "<p>%2").arg(SWITCH_VERSION_FULL, result));
  587. }
  588. void MainWindow::sysTrayActivated(QSystemTrayIcon::ActivationReason reason)
  589. {
  590. switch(reason)
  591. {
  592. case QSystemTrayIcon::Trigger:
  593. {
  594. if (this->isVisible())
  595. this->hide();
  596. else {
  597. this->show();
  598. this->activateWindow();
  599. this->raise();
  600. }
  601. break;
  602. }
  603. default:
  604. break;
  605. }
  606. }