summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/CMakeLists.txt1
-rw-r--r--src/gui/icons.qrc2
-rw-r--r--src/gui/images/popup_incoming_answer.pngbin0 -> 2143 bytes
-rw-r--r--src/gui/images/popup_incoming_reject.pngbin0 -> 391 bytes
-rw-r--r--src/gui/incoming_call_popup.cpp67
-rw-r--r--src/gui/incoming_call_popup.h30
-rw-r--r--src/gui/mphoneform.cpp238
-rw-r--r--src/gui/mphoneform.h2
-rw-r--r--src/gui/qml/TextImageButton.qml59
-rw-r--r--src/gui/qml/incoming_call.qml62
-rw-r--r--src/gui/qml/qml.qrc2
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
new file mode 100644
index 0000000..3a06469
--- /dev/null
+++ b/src/gui/images/popup_incoming_answer.png
Binary files differ
diff --git a/src/gui/images/popup_incoming_reject.png b/src/gui/images/popup_incoming_reject.png
new file mode 100644
index 0000000..23d64e9
--- /dev/null
+++ b/src/gui/images/popup_incoming_reject.png
Binary files differ
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>