/*************************************************************************** * Copyright (C) 2015 by Savoir-Faire Linux * * Author: Edric Ladent Milaret * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * **************************************************************************/ #include "callwidget.h" #include "ui_callwidget.h" #include #include "imconversationmanager.h" #include "instantmessagingmodel.h" #include "audio/settings.h" #include "personmodel.h" #include "fallbackpersoncollection.h" #include "accountmodel.h" #include "categorizedcontactmodel.h" #include "windowscontactbackend.h" #include "historydelegate.h" #include "contactdelegate.h" #include "wizarddialog.h" CallWidget::CallWidget(QWidget *parent) : NavWidget(Main ,parent), ui(new Ui::CallWidget) { ui->setupUi(this); ui->holdButton->setCheckable(true); ui->muteMicButton->setCheckable(true); ui->muteSpeakerButton->setCheckable(true); ui->callInvite->setVisible(false); setActualCall(nullptr); videoRenderer_ = nullptr; try { callModel_ = CallModel::instance(); connect(callModel_, SIGNAL(incomingCall(Call*)), this, SLOT(callIncoming(Call*))); connect(callModel_, SIGNAL(callAdded(Call*,Call*)), this, SLOT(addedCall(Call*, Call*))); connect(callModel_, SIGNAL(callStateChanged(Call*, Call::State)), this, SLOT(callStateChanged(Call*, Call::State))); connect(AccountModel::instance() , SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector)) , this , SLOT(findRingAccount(QModelIndex, QModelIndex, QVector))); ui->callList->setModel(callModel_); CategorizedHistoryModel::instance()-> addCollection(LoadOptions::FORCE_ENABLED); PersonModel::instance()-> addCollection(LoadOptions::FORCE_ENABLED); PersonModel::instance()-> addCollection(LoadOptions::FORCE_ENABLED); auto historyModel = std::unique_ptr(new QSortFilterProxyModel()); historyModel->setSourceModel(CategorizedHistoryModel::instance()); historyModel->setSortRole(static_cast(Call::Role::Date)); historyModel->sort(0,Qt::DescendingOrder); ui->historyList->setModel(historyModel.get()); ui->historyList->setHeaderHidden(true); ui->historyList->setItemDelegate(new HistoryDelegate()); historyModel.release(); CategorizedContactModel::instance()->setSortAlphabetical(false); ui->contactView->setModel(CategorizedContactModel::instance()); ui->contactView->setItemDelegate(new ContactDelegate()); ui->speakerSlider->setValue(Audio::Settings::instance()->playbackVolume()); ui->micSlider->setValue(Audio::Settings::instance()->captureVolume()); findRingAccount(); } catch (...) { qDebug() << "INIT ERROR"; } } CallWidget::~CallWidget() { delete ui; } void CallWidget::findRingAccount(QModelIndex idx1, QModelIndex idx2, QVector vec) { Q_UNUSED(idx1) Q_UNUSED(idx2) Q_UNUSED(vec) auto a_count = AccountModel::instance()->rowCount(); auto found = false; for (int i = 0; i < a_count; ++i) { auto idx = AccountModel::instance()->index(i, 0); auto protocol = idx.data(static_cast(Account::Role::Proto)); if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) { auto username = idx.data(static_cast(Account::Role::Username)); ui->ringIdLabel->setText( "Your Ring ID: " + username.toString()); found = true; return; } } if (not found){ ui->ringIdLabel->setText("NO RING ACCOUNT FOUND"); } } void CallWidget::findRingAccount() { auto a_count = AccountModel::instance()->rowCount(); auto found = false; for (int i = 0; i < a_count; ++i) { auto idx = AccountModel::instance()->index(i, 0); auto protocol = idx.data(static_cast(Account::Role::Proto)); if ((Account::Protocol)protocol.toUInt() == Account::Protocol::RING) { auto username = idx.data(static_cast(Account::Role::Username)); ui->ringIdLabel->setText( ui->ringIdLabel->text() + " " + username.toString()); found = true; return; } } if (!found) { WizardDialog *wizardDialog = new WizardDialog(); wizardDialog->exec(); delete wizardDialog; } } void CallWidget::callIncoming(Call *call) { if (!call->account()->isAutoAnswer()) ui->callInvite->setVisible(true); setActualCall(call); } void CallWidget::on_acceptButton_clicked() { if (actualCall_ != nullptr) actualCall_->performAction(Call::Action::ACCEPT); ui->callInvite->setVisible(false); } void CallWidget::on_refuseButton_clicked() { if (actualCall_ == nullptr) return; actualCall_->performAction(Call::Action::REFUSE); setActualCall(nullptr); ui->callInvite->setVisible(false); } void CallWidget::on_holdButton_toggled(bool checked) { Q_UNUSED(checked) if (actualCall_ == nullptr) return; actualCall_->performAction(Call::Action::HOLD); } void CallWidget::on_hangupButton_clicked() { if (actualCall_ == nullptr) return; actualCall_->performAction(Call::Action::REFUSE); } void CallWidget::addedCall(Call* call, Call* parent) { Q_UNUSED(parent); if (call->direction() == Call::Direction::OUTGOING) { setActualCall(call); } } void CallWidget::callStateChanged(Call* call, Call::State previousState) { Q_UNUSED(previousState) if (call == nullptr) return; ui->callList->setCurrentIndex(callModel_->getIndex(actualCall_)); if (call->state() == Call::State::OVER || call->state() == Call::State::ERROR) { setActualCall(nullptr); ui->videoWidget->hide(); } else if (call->state() == Call::State::HOLD) { ui->videoWidget->hide(); } else if (call->state() == Call::State::CURRENT) { ui->videoWidget->show(); ui->messageOutput->setModel( IMConversationManager::instance()->getModel(actualCall_)); } ui->callStateLabel->setText("Call State : " + state.at((int)call->state())); } void CallWidget::on_callList_activated(const QModelIndex &index) { Call *callSelected = callModel_->getCall(index); if (actualCall_ != nullptr) { if (callSelected == actualCall_) return; ui->videoWidget->hide(); actualCall_->performAction(Call::Action::HOLD); } setActualCall(callSelected); actualCall_->performAction(Call::Action::HOLD); ui->videoWidget->show(); } void CallWidget::on_muteSpeakerButton_toggled(bool checked) { Audio::Settings::instance()->mutePlayback(checked); } void CallWidget::on_muteMicButton_toggled(bool checked) { Audio::Settings::instance()->muteCapture(checked); } void CallWidget::on_speakerSlider_sliderMoved(int position) { outputVolume_ = position; } void CallWidget::on_speakerSlider_sliderReleased() { emit Audio::Settings::instance()->setPlaybackVolume(outputVolume_); } void CallWidget::on_micSlider_sliderMoved(int position) { inputVolume_ = position; } void CallWidget::on_micSlider_sliderReleased() { emit Audio::Settings::instance()->setCaptureVolume(inputVolume_); } void CallWidget::atExit() { } void CallWidget::on_contactView_doubleClicked(const QModelIndex &index) { auto contact = index.data((int)ContactMethod::Role::Uri); QString uri; if (contact.isValid()) { uri = contact.toString(); } else { auto var = index.data((int)Person::Role::Object); if (var.isValid()) { Person* person = var.value(); if (person->phoneNumbers().size() > 0) { uri = person->phoneNumbers().at(0)->uri(); } } } if (not uri.isEmpty()) { auto outCall = CallModel::instance()->dialingCall(uri); outCall->setDialNumber(uri); outCall->performAction(Call::Action::ACCEPT); } } void CallWidget::on_historyList_doubleClicked(const QModelIndex &index) { QString number = index.model()->data(index, static_cast(Call::Role::Number)).toString(); if (not number.isEmpty()) { auto outCall = CallModel::instance()->dialingCall(number); outCall->setDialNumber(number); outCall->performAction(Call::Action::ACCEPT); } } void CallWidget::setActualCall(Call* value) { actualCall_ = value; ui->holdButton->setEnabled(actualCall_ != nullptr); ui->hangupButton->setEnabled(actualCall_ != nullptr); }