diff options
-rw-r--r-- | src/gui/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/gui/icons.qrc | 2 | ||||
-rw-r--r-- | src/gui/images/popup_incoming_answer.png | bin | 0 -> 2143 bytes | |||
-rw-r--r-- | src/gui/images/popup_incoming_reject.png | bin | 0 -> 391 bytes | |||
-rw-r--r-- | src/gui/incoming_call_popup.cpp | 67 | ||||
-rw-r--r-- | src/gui/incoming_call_popup.h | 30 | ||||
-rw-r--r-- | src/gui/mphoneform.cpp | 238 | ||||
-rw-r--r-- | src/gui/mphoneform.h | 2 | ||||
-rw-r--r-- | src/gui/qml/TextImageButton.qml | 59 | ||||
-rw-r--r-- | src/gui/qml/incoming_call.qml | 62 | ||||
-rw-r--r-- | src/gui/qml/qml.qrc | 2 |
11 files changed, 357 insertions, 106 deletions
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index b75d7c8..624742d 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -109,6 +109,7 @@ set(TWINKLE_GUI-SRCS yesnodialog.cpp textbrowsernoautolink.cpp osd.cpp + incoming_call_popup.cpp $<TARGET_OBJECTS:libtwinkle> $<TARGET_OBJECTS:libtwinkle-audio> diff --git a/src/gui/icons.qrc b/src/gui/icons.qrc index 11ca260..f9d276a 100644 --- a/src/gui/icons.qrc +++ b/src/gui/icons.qrc @@ -164,5 +164,7 @@ <file>images/osd_hangup.png</file> <file>images/osd_mic_off.png</file> <file>images/osd_mic_on.png</file> + <file>images/popup_incoming_answer.png</file> + <file>images/popup_incoming_reject.png</file> </qresource> </RCC> diff --git a/src/gui/images/popup_incoming_answer.png b/src/gui/images/popup_incoming_answer.png Binary files differnew file mode 100644 index 0000000..3a06469 --- /dev/null +++ b/src/gui/images/popup_incoming_answer.png diff --git a/src/gui/images/popup_incoming_reject.png b/src/gui/images/popup_incoming_reject.png Binary files differnew file mode 100644 index 0000000..23d64e9 --- /dev/null +++ b/src/gui/images/popup_incoming_reject.png diff --git a/src/gui/incoming_call_popup.cpp b/src/gui/incoming_call_popup.cpp new file mode 100644 index 0000000..4dedea4 --- /dev/null +++ b/src/gui/incoming_call_popup.cpp @@ -0,0 +1,67 @@ +#include "incoming_call_popup.h" +#include <QDesktopWidget> +#include <QApplication> +#include <QDeclarativeContext> + +IncomingCallPopup::IncomingCallPopup(QObject *parent) : QObject(parent) +{ + m_view = new QDeclarativeView; + + // Qt5 QQuickView: setFlags() + m_view->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::ToolTip); + + m_view->setSource(QUrl("qrc:/qml/incoming_call.qml")); + + // Place into the middle of the screen + QDesktopWidget* desktop = qApp->desktop(); + QPoint pos; + + pos.setX(desktop->width()/2 - m_view->width()/2); + pos.setY(desktop->height()/2 - m_view->height()/2); + + m_view->move(pos); + + QObject* button; + + button = m_view->rootObject()->findChild<QObject*>("buttonAnswer"); + connect(button, SIGNAL(clicked()), this, SLOT(onAnswerClicked())); + + button = m_view->rootObject()->findChild<QObject*>("buttonReject"); + connect(button, SIGNAL(clicked()), this, SLOT(onRejectClicked())); + + m_callerText = m_view->rootObject()->findChild<QDeclarativeItem*>("callerText"); +} + +IncomingCallPopup::~IncomingCallPopup() +{ + delete m_view; +} + +void IncomingCallPopup::setCallerName(const QString& name) +{ + QString text = tr("%1 calling").arg(name); + m_callerText->setProperty("text", text); +} + +void IncomingCallPopup::onAnswerClicked() +{ + emit answerClicked(); + m_view->hide(); +} + +void IncomingCallPopup::onRejectClicked() +{ + emit rejectClicked(); + m_view->hide(); +} + +void IncomingCallPopup::show() +{ + m_view->show(); +} + +void IncomingCallPopup::hide() +{ + m_view->hide(); +} + diff --git a/src/gui/incoming_call_popup.h b/src/gui/incoming_call_popup.h new file mode 100644 index 0000000..e61d99a --- /dev/null +++ b/src/gui/incoming_call_popup.h @@ -0,0 +1,30 @@ +#ifndef T_INCOMING_CALL_POPUP_H +#define T_INCOMING_CALL_POPUP_H + +#include <QDeclarativeItem> +#include <QDeclarativeView> + +class IncomingCallPopup : public QObject +{ + Q_OBJECT +public: + explicit IncomingCallPopup(QObject *parent = 0); + virtual ~IncomingCallPopup(); + + void setCallerName(const QString& name); + void show(); + void hide(); + void setVisible(bool v) { if (v) show(); else hide(); } + +signals: + void answerClicked(); + void rejectClicked(); +public slots: + void onAnswerClicked(); + void onRejectClicked(); +private: + QDeclarativeView* m_view; + QDeclarativeItem* m_callerText; +}; + +#endif // T_INCOMING_CALL_POPUP_H diff --git a/src/gui/mphoneform.cpp b/src/gui/mphoneform.cpp index e761f6f..13f0d6e 100644 --- a/src/gui/mphoneform.cpp +++ b/src/gui/mphoneform.cpp @@ -57,6 +57,7 @@ #include "buddyform.h" #include "diamondcardprofileform.h" #include "osd.h" +#include "incoming_call_popup.h" // Time (s) that the conversation timer of a line should stay visible after @@ -175,6 +176,10 @@ void MphoneForm::init() osdWindow->move(desktop->width() - osdWindow->width() - 10, 10); connect(osdWindow, SIGNAL(hangupClicked()), this, SLOT(phoneBye())); connect(osdWindow, SIGNAL(muteClicked()), this, SLOT(osdMuteClicked())); + + incomingCallPopup = new IncomingCallPopup(this); + connect(incomingCallPopup, SIGNAL(answerClicked()), this, SLOT(phoneAnswer())); + connect(incomingCallPopup, SIGNAL(rejectClicked()), this, SLOT(phoneReject())); // A QComboBox accepts a new line through copy/paste. QRegExp rxNoNewLine("[^\\n\\r]*"); @@ -637,6 +642,7 @@ void MphoneForm::updateLineStatus(int line) statusTextLabel->setText(state); t_line_substate line_substate; + line_substate = phone->get_line_substate(line); switch (line_substate) { case LSSUB_IDLE: @@ -651,6 +657,7 @@ void MphoneForm::updateLineStatus(int line) case LSSUB_INCOMING_PROGRESS: statLabel->setPixmap(QPixmap(":/icons/images/stat_ringing.png")); statLabel->show(); + break; case LSSUB_ANSWERING: statLabel->setPixmap(QPixmap(":/icons/images/gear.png")); @@ -737,123 +744,142 @@ void MphoneForm::updateState() updateOSD(); + bool showIncomingCallPopup = false; + switch(line_substate) { - case LSSUB_IDLE: - enableCallOptions(true); - callAnswer->setEnabled(false); - callBye->setEnabled(false); - callReject->setEnabled(false); - callRedirect->setEnabled(false); - callTransfer->setEnabled(false); - callHold->setEnabled(false); - callConference->setEnabled(false); - callMute->setEnabled(false); - callDTMF->setEnabled(false); - callRedial->setEnabled(ui->can_redial()); - break; - case LSSUB_OUTGOING_PROGRESS: - enableCallOptions(false); - callAnswer->setEnabled(false); - callBye->setEnabled(true); - callReject->setEnabled(false); - callRedirect->setEnabled(false); - - if (is_transfer_consult && user_config->get_allow_transfer_consultation_inprog()) { - callTransfer->setEnabled(true); - } else { - callTransfer->setEnabled(false); - } - - callHold->setEnabled(false); - callConference->setEnabled(false); - callMute->setEnabled(false); - callDTMF->setEnabled(call_info.dtmf_supported); - callRedial->setEnabled(false); - break; - case LSSUB_INCOMING_PROGRESS: - enableCallOptions(false); - callAnswer->setEnabled(true); - callBye->setEnabled(false); - callReject->setEnabled(true); - callRedirect->setEnabled(true); - callTransfer->setEnabled(false); - callHold->setEnabled(false); - callConference->setEnabled(false); - callMute->setEnabled(false); - callDTMF->setEnabled(call_info.dtmf_supported); - callRedial->setEnabled(false); - break; - case LSSUB_ESTABLISHED: - enableCallOptions(false); - callInvite->setEnabled(false); - callAnswer->setEnabled(false); - callBye->setEnabled(true); - callReject->setEnabled(false); - callRedirect->setEnabled(false); - - if (in_conference) { + case LSSUB_IDLE: + enableCallOptions(true); + callAnswer->setEnabled(false); + callBye->setEnabled(false); + callReject->setEnabled(false); + callRedirect->setEnabled(false); callTransfer->setEnabled(false); callHold->setEnabled(false); callConference->setEnabled(false); + callMute->setEnabled(false); callDTMF->setEnabled(false); - } else { - callTransfer->setEnabled(has_media && - call_info.refer_supported && - refer_state == REFST_NULL && - !to_be_transferred); - callHold->setEnabled(has_media); + callRedial->setEnabled(ui->can_redial()); + break; + case LSSUB_OUTGOING_PROGRESS: + enableCallOptions(false); + callAnswer->setEnabled(false); + callBye->setEnabled(true); + callReject->setEnabled(false); + callRedirect->setEnabled(false); + + if (is_transfer_consult && user_config->get_allow_transfer_consultation_inprog()) { + callTransfer->setEnabled(true); + } else { + callTransfer->setEnabled(false); + } + + callHold->setEnabled(false); + callConference->setEnabled(false); + callMute->setEnabled(false); callDTMF->setEnabled(call_info.dtmf_supported); - - if (phone->get_line_substate(other_line) == - LSSUB_ESTABLISHED) - { - // If one of the lines is transferring a call, then a - // conference cannot be setup. - if (refer_state != REFST_NULL || - phone->get_line_refer_state(other_line) != REFST_NULL) + callRedial->setEnabled(false); + break; + case LSSUB_INCOMING_PROGRESS: + { + enableCallOptions(false); + callAnswer->setEnabled(true); + callBye->setEnabled(false); + callReject->setEnabled(true); + callRedirect->setEnabled(true); + callTransfer->setEnabled(false); + callHold->setEnabled(false); + callConference->setEnabled(false); + callMute->setEnabled(false); + callDTMF->setEnabled(call_info.dtmf_supported); + callRedial->setEnabled(false); + + std::string name; + t_call_record cr = phone->get_call_hist(line); + // t_user *user_config = phone->get_line_user(line); + + // name = ui->format_sip_address(user_config, cr.from_display, cr.from_uri); + name = cr.from_display; + if (name.empty()) + name = cr.from_uri.encode_no_params_hdrs(false); + + incomingCallPopup->setCallerName(QString::fromStdString(name)); + showIncomingCallPopup = true; + + break; + } + case LSSUB_ESTABLISHED: + enableCallOptions(false); + callInvite->setEnabled(false); + callAnswer->setEnabled(false); + callBye->setEnabled(true); + callReject->setEnabled(false); + callRedirect->setEnabled(false); + + if (in_conference) { + callTransfer->setEnabled(false); + callHold->setEnabled(false); + callConference->setEnabled(false); + callDTMF->setEnabled(false); + } else { + callTransfer->setEnabled(has_media && + call_info.refer_supported && + refer_state == REFST_NULL && + !to_be_transferred); + callHold->setEnabled(has_media); + callDTMF->setEnabled(call_info.dtmf_supported); + + if (phone->get_line_substate(other_line) == + LSSUB_ESTABLISHED) { - callConference->setEnabled(false); + // If one of the lines is transferring a call, then a + // conference cannot be setup. + if (refer_state != REFST_NULL || + phone->get_line_refer_state(other_line) != REFST_NULL) + { + callConference->setEnabled(false); + } else { + callConference->setEnabled(has_media); + } } else { - callConference->setEnabled(has_media); + callConference->setEnabled(false); } - } else { - callConference->setEnabled(false); } - } - - callMute->setEnabled(true); - callRedial->setEnabled(false); - break; - case LSSUB_SEIZED: - case LSSUB_ANSWERING: - case LSSUB_RELEASING: - // During dialing, answering and call release no other actions are - // possible - enableCallOptions(false); - callAnswer->setEnabled(false); - callBye->setEnabled(false); - callReject->setEnabled(false); - callRedirect->setEnabled(false); - callTransfer->setEnabled(false); - callHold->setEnabled(false); - callConference->setEnabled(false); - callMute->setEnabled(false); - callDTMF->setEnabled(false); - callRedial->setEnabled(false); - break; - default: - enableCallOptions(true); - callAnswer->setEnabled(true); - callBye->setEnabled(true); - callReject->setEnabled(true); - callRedirect->setEnabled(true); - callTransfer->setEnabled(true); - callHold->setEnabled(true); - callConference->setEnabled(false); - callMute->setEnabled(true); - callDTMF->setEnabled(true); - callRedial->setEnabled(ui->can_redial()); + + callMute->setEnabled(true); + callRedial->setEnabled(false); + break; + case LSSUB_SEIZED: + case LSSUB_ANSWERING: + case LSSUB_RELEASING: + // During dialing, answering and call release no other actions are + // possible + enableCallOptions(false); + callAnswer->setEnabled(false); + callBye->setEnabled(false); + callReject->setEnabled(false); + callRedirect->setEnabled(false); + callTransfer->setEnabled(false); + callHold->setEnabled(false); + callConference->setEnabled(false); + callMute->setEnabled(false); + callDTMF->setEnabled(false); + callRedial->setEnabled(false); + break; + default: + enableCallOptions(true); + callAnswer->setEnabled(true); + callBye->setEnabled(true); + callReject->setEnabled(true); + callRedirect->setEnabled(true); + callTransfer->setEnabled(true); + callHold->setEnabled(true); + callConference->setEnabled(false); + callMute->setEnabled(true); + callDTMF->setEnabled(true); + callRedial->setEnabled(ui->can_redial()); } + + incomingCallPopup->setVisible(showIncomingCallPopup); // Set hold action in correct state callHold->setChecked(on_hold); diff --git a/src/gui/mphoneform.h b/src/gui/mphoneform.h index 27be790..2695b34 100644 --- a/src/gui/mphoneform.h +++ b/src/gui/mphoneform.h @@ -27,6 +27,7 @@ class t_phone; extern t_phone *phone; class OSD; +class IncomingCallPopup; class MphoneForm : public QMainWindow, public Ui::MphoneForm { @@ -210,6 +211,7 @@ private: QMenu *changeAvailabilityPopupMenu; bool viewBuddyList; OSD *osdWindow; + IncomingCallPopup *incomingCallPopup; }; #endif diff --git a/src/gui/qml/TextImageButton.qml b/src/gui/qml/TextImageButton.qml new file mode 100644 index 0000000..3630029 --- /dev/null +++ b/src/gui/qml/TextImageButton.qml @@ -0,0 +1,59 @@ +import QtQuick 1.1 + +Rectangle { + id: backgroundRect + width: 150 + height: 30 + radius: 0 + + property alias image: img.source + property alias text: text.text + property alias color: backgroundRect.color + signal clicked + + color: "red" + z: 2 + + Image { + id: img + width: height + anchors.top: parent.top + anchors.topMargin: 2 + anchors.bottom: parent.bottom + anchors.bottomMargin: 2 + anchors.left: parent.left + anchors.leftMargin: 5 + smooth: true + source: "qrc:/qtquickplugin/images/template_image.png" + } + + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: parent.clicked() + } + + Text { + id: text + text: "Button text" + font.bold: true + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + anchors.right: parent.right + anchors.rightMargin: 0 + anchors.left: img.right + anchors.leftMargin: 5 + anchors.top: parent.top + anchors.topMargin: 0 + anchors.bottom: parent.bottom + anchors.bottomMargin: 0 + color: "white" + font.pixelSize: 12 + } + + states: State { + name: "pressed"; when: mouseArea.pressed + PropertyChanges { target: backgroundRect; color: Qt.darker(color) } + } +} + diff --git a/src/gui/qml/incoming_call.qml b/src/gui/qml/incoming_call.qml new file mode 100644 index 0000000..bdcb161 --- /dev/null +++ b/src/gui/qml/incoming_call.qml @@ -0,0 +1,62 @@ +import QtQuick 1.1 + +Rectangle { + id: rectangle1 + width: 400 + height: 70 + color: "black" + + Image { + id: image1 + anchors.bottom: parent.bottom + anchors.bottomMargin: 5 + anchors.top: parent.top + anchors.topMargin: 5 + anchors.left: parent.left + anchors.leftMargin: 5 + source: "qrc:/icons/images/twinkle48.png" + width: height + } + + Text { + id: callerText + objectName: "callerText" + height: 22 + color: "#ffffff" + text: "... calling" + anchors.top: parent.top + anchors.topMargin: 8 + anchors.left: image1.right + anchors.leftMargin: 9 + anchors.right: parent.right + anchors.rightMargin: 10 + font.pixelSize: 19 + } + + TextImageButton { + id: buttonAnswer + objectName: "buttonAnswer" + x: 74 + y: 36 + width: 120 + height: 26 + color: "#00aa00" + radius: 7 + text: qsTr("Answer") + image: "qrc:/icons/images/popup_incoming_answer.png" + } + + TextImageButton { + id: buttonReject + objectName: "buttonReject" + y: 36 + width: 120 + height: 26 + radius: 7 + text: qsTr("Reject") + anchors.left: buttonAnswer.right + anchors.leftMargin: 15 + image: "qrc:/icons/images/popup_incoming_reject.png" + } +} + diff --git a/src/gui/qml/qml.qrc b/src/gui/qml/qml.qrc index 95e8f77..87c5184 100644 --- a/src/gui/qml/qml.qrc +++ b/src/gui/qml/qml.qrc @@ -2,5 +2,7 @@ <qresource prefix="/qml"> <file>ImageButton.qml</file> <file>osd.qml</file> + <file>TextImageButton.qml</file> + <file>incoming_call.qml</file> </qresource> </RCC> |