From ed014b0d34e204defb9c723bc2498d343dc8757e Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 21 Mar 2015 21:25:17 +0000 Subject: [PATCH] added notification for VOIP calls (Patch from Phenom) git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@8063 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- plugins/VOIP/gui/VOIPChatWidgetHolder.cpp | 80 +++++- plugins/VOIP/gui/VOIPChatWidgetHolder.h | 7 + retroshare-gui/src/gui/chat/ChatWidget.cpp | 14 +- retroshare-gui/src/gui/chat/ChatWidget.h | 3 + .../src/gui/common/RsButtonOnText.cpp | 228 ++++++++++++++++++ .../src/gui/common/RsButtonOnText.h | 47 ++++ retroshare-gui/src/retroshare-gui.pro | 2 + 7 files changed, 377 insertions(+), 4 deletions(-) create mode 100644 retroshare-gui/src/gui/common/RsButtonOnText.cpp create mode 100644 retroshare-gui/src/gui/common/RsButtonOnText.h diff --git a/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp b/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp index 9652cca40..44b01f858 100644 --- a/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp +++ b/plugins/VOIP/gui/VOIPChatWidgetHolder.cpp @@ -135,6 +135,11 @@ VOIPChatWidgetHolder::~VOIPChatWidgetHolder() delete inputVideoDevice ; delete inputVideoProcessor ; delete outputVideoProcessor ; + + button_map::iterator it = buttonMapTakeVideo.begin(); + while (it != buttonMapTakeVideo.end()) { + it = buttonMapTakeVideo.erase(it); + } } void VOIPChatWidgetHolder::toggleAudioListen() @@ -204,6 +209,13 @@ void VOIPChatWidgetHolder::toggleAudioCapture() hangupButton->hide(); } } + +void VOIPChatWidgetHolder::startVideoCapture() +{ + videoCaptureToggleButton->setChecked(true); + toggleVideoCapture(); +} + void VOIPChatWidgetHolder::toggleVideoCapture() { if (videoCaptureToggleButton->isChecked()) @@ -216,7 +228,15 @@ void VOIPChatWidgetHolder::toggleVideoCapture() videoCaptureToggleButton->setToolTip(tr("Shut camera off")); if (mChatWidget) - mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("you're now sending video..."), ChatWidget::MSGTYPE_SYSTEM); + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("You're now sending video..."), ChatWidget::MSGTYPE_SYSTEM); + + button_map::iterator it = buttonMapTakeVideo.begin(); + while (it != buttonMapTakeVideo.end()) { + RSButtonOnText *button = it.value(); + delete button; + it = buttonMapTakeVideo.erase(it); + } } else { @@ -226,13 +246,69 @@ void VOIPChatWidgetHolder::toggleVideoCapture() videoWidget->hide(); if (mChatWidget) - mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime(), tr("Video call stopped"), ChatWidget::MSGTYPE_SYSTEM); + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("Video call stopped"), ChatWidget::MSGTYPE_SYSTEM); } } void VOIPChatWidgetHolder::addVideoData(const QString name, QByteArray* array) { outputVideoProcessor->receiveEncodedData((unsigned char *)array->data(),array->size()) ; + if (!videoCaptureToggleButton->isChecked()) { + if (mChatWidget) { + QString buttonName = name; + if (buttonName.isEmpty()) buttonName = "VoIP";//TODO maybe change all with GxsId + button_map::iterator it = buttonMapTakeVideo.find(buttonName); + if (it == buttonMapTakeVideo.end()){ + mChatWidget->addChatMsg(true, tr("VoIP Status"), QDateTime::currentDateTime(), QDateTime::currentDateTime() + , tr("Video call from: %1").arg(buttonName), ChatWidget::MSGTYPE_SYSTEM); + RSButtonOnText *button = mChatWidget->getNewButtonOnTextBrowser(tr("Take Video Call")); + button->setToolTip(tr("Activate camera")); + button->setStyleSheet(QString("background-color: green;") + .append("border-style: outset;") + .append("border-width: 5px;") + .append("border-radius: 5px;") + .append("border-color: beige;") + ); + + button->updateImage(); + + connect(button,SIGNAL(clicked()),this,SLOT(startVideoCapture())); + connect(button,SIGNAL(mouseEnter()),this,SLOT(botMouseEnter())); + connect(button,SIGNAL(mouseLeave()),this,SLOT(botMouseLeave())); + + buttonMapTakeVideo.insert(buttonName, button); + } + } + } +} + +void VOIPChatWidgetHolder::botMouseEnter() +{ + RSButtonOnText *source = qobject_cast(QObject::sender()); + if (source){ + source->setStyleSheet(QString("background-color: red;") + .append("border-style: outset;") + .append("border-width: 5px;") + .append("border-radius: 5px;") + .append("border-color: beige;") + ); + //source->setDown(true); + } +} + +void VOIPChatWidgetHolder::botMouseLeave() +{ + RSButtonOnText *source = qobject_cast(QObject::sender()); + if (source){ + source->setStyleSheet(QString("background-color: green;") + .append("border-style: outset;") + .append("border-width: 5px;") + .append("border-radius: 5px;") + .append("border-color: beige;") + ); + //source->setDown(false); + } } void VOIPChatWidgetHolder::setAcceptedBandwidth(const QString name, uint32_t bytes_per_sec) diff --git a/plugins/VOIP/gui/VOIPChatWidgetHolder.h b/plugins/VOIP/gui/VOIPChatWidgetHolder.h index 633f1395b..690b284b6 100644 --- a/plugins/VOIP/gui/VOIPChatWidgetHolder.h +++ b/plugins/VOIP/gui/VOIPChatWidgetHolder.h @@ -2,6 +2,7 @@ #include #include #include +#include class QToolButton; class QAudioInput; @@ -31,7 +32,10 @@ private slots: void toggleAudioListen(); void toggleAudioCapture(); void toggleVideoCapture(); + void startVideoCapture(); void hangupCall() ; + void botMouseEnter(); + void botMouseLeave(); public slots: void sendAudioData(); @@ -60,5 +64,8 @@ protected: QToolButton *audioCaptureToggleButton ; QToolButton *videoCaptureToggleButton ; QToolButton *hangupButton ; + + typedef QMap button_map; + button_map buttonMapTakeVideo; }; diff --git a/retroshare-gui/src/gui/chat/ChatWidget.cpp b/retroshare-gui/src/gui/chat/ChatWidget.cpp index 59d9f3d4d..8ed319ae4 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatWidget.cpp @@ -62,7 +62,7 @@ *****/ ChatWidget::ChatWidget(QWidget *parent) : - QWidget(parent), ui(new Ui::ChatWidget), sendingBlocked(false) + QWidget(parent), sendingBlocked(false), ui(new Ui::ChatWidget) { ui->setupUi(this); @@ -217,6 +217,16 @@ void ChatWidget::addVOIPBarWidget(QWidget *w) ui->titleBarFrame->layout()->addWidget(w) ; } +RSButtonOnText* ChatWidget::getNewButtonOnTextBrowser() +{ + return new RSButtonOnText(ui->textBrowser); +} + +RSButtonOnText* ChatWidget::getNewButtonOnTextBrowser(QString text) +{ + return new RSButtonOnText(text, ui->textBrowser); +} + void ChatWidget::init(const ChatId &chat_id, const QString &title) { @@ -255,7 +265,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title) } uint32_t hist_chat_type = 0xFFFF; // a value larger than the biggest RS_HISTORY_TYPE_* value - int messageCount; + int messageCount=0; if (chatType() == CHATTYPE_LOBBY) { hist_chat_type = RS_HISTORY_TYPE_LOBBY; diff --git a/retroshare-gui/src/gui/chat/ChatWidget.h b/retroshare-gui/src/gui/chat/ChatWidget.h index b433ba039..2950cba65 100644 --- a/retroshare-gui/src/gui/chat/ChatWidget.h +++ b/retroshare-gui/src/gui/chat/ChatWidget.h @@ -28,6 +28,7 @@ #include #include #include "gui/common/HashBox.h" +#include "gui/common/RsButtonOnText.h" #include "ChatStyle.h" #include "gui/style/RSStyle.h" @@ -105,6 +106,8 @@ public: void addVOIPBarWidget(QWidget *w); + RSButtonOnText* getNewButtonOnTextBrowser(); + RSButtonOnText* getNewButtonOnTextBrowser(QString text); // Adds a new horizonal widget in the layout of the chat window. void addChatHorizontalWidget(QWidget *w) ; diff --git a/retroshare-gui/src/gui/common/RsButtonOnText.cpp b/retroshare-gui/src/gui/common/RsButtonOnText.cpp new file mode 100644 index 000000000..2b6d51d97 --- /dev/null +++ b/retroshare-gui/src/gui/common/RsButtonOnText.cpp @@ -0,0 +1,228 @@ +#include "RsButtonOnText.h" + +#include +#include +#include +#include +#include +#include + +RSButtonOnText::RSButtonOnText(QWidget *parent) + : QPushButton(parent) +{ + _uuid = QUuid::createUuid(); + _lenght = -1; + _mouseOver = false; + _pressed = false; +} +RSButtonOnText::RSButtonOnText(const QString &text, QWidget *parent) + : QPushButton(parent) +{ + setText(text); +} + +RSButtonOnText::RSButtonOnText(const QIcon& icon, const QString &text, QWidget *parent) + : QPushButton(text, parent) +{ + setIcon(icon); +} + +RSButtonOnText::RSButtonOnText(QTextEdit *textEdit, QWidget *parent) + : QPushButton(parent) +{ + appendToText(textEdit); +} +/*RSButtonOnText::RSButtonOnText(QTextEdit *textEdit, QWidget *parent) + : QPushButton(parent) +{ + _uuid = QUuid::createUuid(); + _lenght = -1; + _mouseOver = false; + _pressed = false; + appendToText(textEdit); +}*/ + +RSButtonOnText::RSButtonOnText(const QString &text, QTextEdit *textEdit, QWidget *parent) + : QPushButton(parent) +{ + setText(text); + appendToText(textEdit); +} + +RSButtonOnText::RSButtonOnText(const QIcon& icon, const QString &text, QTextEdit *textEdit, QWidget *parent) + : QPushButton(parent) +{ + setText(text); + setIcon(icon); + appendToText(textEdit); +} + +RSButtonOnText::~RSButtonOnText() +{ + clear(); +} + +bool RSButtonOnText::eventFilter(QObject *obj, QEvent *event) +{ + QPointer guard(this); + QPoint point; + if (isEventForThis(obj, event, point)) { + if (event->type() == QEvent::ToolTip) { + QToolTip::showText(point, this->toolTip()); + event->ignore();//For other don't clear this one + return true; + } + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseButtonPress + ,QPoint(1,1),Qt::LeftButton,Qt::LeftButton,0); + QPushButton::mousePressEvent(mouseEvent); + delete mouseEvent; + _pressed = true; + //if (guard) emit pressed(); + if (guard) updateImage(); + } + if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseButtonPress + ,QPoint(1,1),Qt::LeftButton,Qt::LeftButton,0); + QPushButton::mouseReleaseEvent(mouseEvent); + delete mouseEvent; + _pressed = false; + //if (guard) emit released(); + //if (guard) emit clicked(); + //if (guard) if (isCheckable()) emit clicked(QPushButton::isChecked()); + //if (guard) if (isCheckable()) emit toggled(QPushButton::isChecked()); + if (guard) updateImage(); + } + if (event->type() == QEvent::MouseMove) { + if (!_mouseOver){ + //QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseButtonPress + // ,QPoint(1,1),Qt::LeftButton,Qt::LeftButton,0); + //QPushButton::enterEvent(mouseEvent);//Do nothing + //delete mouseEvent; + //QPushButton::setDown(true); + if (guard) emit mouseEnter(); + } + _mouseOver = true; + if (guard) updateImage(); + } + } else { + if (event->type() == QEvent::MouseMove) { + if (_mouseOver) { + //QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseButtonPress + // ,QPoint(1,1),Qt::LeftButton,Qt::LeftButton,0); + //QPushButton::leaveEvent(mouseEvent);//Do nothing + //delete mouseEvent; + //QPushButton::setDown(false); + _mouseOver = false; + if (guard) emit mouseLeave(); + if (guard) updateImage(); + } + if (_pressed){ + QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseButtonPress + ,QPoint(1,1),Qt::LeftButton,Qt::LeftButton,0); + QPushButton::mouseReleaseEvent(mouseEvent); + delete mouseEvent; + //if (guard) emit released(); + if (guard) updateImage(); + } + } + } + + // pass the event on to the parent class + return QWidget::eventFilter(obj, event); +} + +bool RSButtonOnText::isEventForThis(QObject *obj, QEvent *event, QPoint &point) +{ + switch (event->type()) { + case QEvent::MouseButtonPress://2 + case QEvent::MouseButtonRelease://3 + case QEvent::MouseButtonDblClick://4 + case QEvent::MouseMove://5 + { + QMouseEvent* mouseEvent = static_cast(event); + point = mouseEvent->pos(); + } + break; + case QEvent::ToolTip://110 + { + QHelpEvent* helpEvent = static_cast(event); + point = helpEvent->globalPos(); + } + break; + default: + return false; + } + + if (!event->isAccepted()) return false;//Already other take this event (true by default) + + if (obj ==_textEditViewPort) { + if (_textEdit){ + + QTextCursor cursor = _textEdit->cursorForPosition(point); + if ( (_textCursor->anchor() <= cursor.anchor()) + && (cursor.position() <= _textCursor->anchor()+_lenght)){ + return true; + } + } + } + return false; +} + +QString RSButtonOnText::uuid() +{ + return _uuid; +} + +QString RSButtonOnText::htmlText() +{ + return ""; +} + +void RSButtonOnText::appendToText(QTextEdit *textEdit) +{ + clear(); + _textEdit = textEdit; + _textEditViewPort = textEdit->viewport(); + + updateImage(); + + _textCursor = new QTextCursor(textEdit->textCursor()); + _textCursor->movePosition(QTextCursor::End); + _textEdit->insertPlainText(QString(QChar::Nbsp));//To get cursorForPosition, else it returns next char after middle + int textCursorSavePos = _textCursor->position(); + _textCursor->insertHtml(htmlText()); + _textCursor->setPosition(textCursorSavePos); + _textCursor->movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + _lenght = _textCursor->position() - _textCursor->anchor(); + _textEdit->insertPlainText(QString(QChar::Nbsp));//To get cursorForPosition, else it returns next char after middle + _textCursor->setPosition(textCursorSavePos); + + _textEditViewPort->installEventFilter(this); +} + +void RSButtonOnText::clear() +{ + if(_lenght > 0){ + _textCursor->setPosition(_textCursor->anchor()-1);//Remove Space too + _textCursor->setPosition(_textCursor->anchor() + _lenght + 2, QTextCursor::KeepAnchor); + _textCursor->deleteChar(); + _lenght = -1; + } +} + +void RSButtonOnText::updateImage() +{ + if (_textEdit){ + adjustSize(); + QPixmap pixmap; +#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) + pixmap = this->grab();//QT5 +#else + pixmap = QPixmap::grabWidget(this); +#endif + _textEdit->setUpdatesEnabled(false); + _textEdit->document()->addResource(QTextDocument::ImageResource,QUrl(_uuid),QVariant(pixmap)); + _textEdit->setUpdatesEnabled(true); + } +} diff --git a/retroshare-gui/src/gui/common/RsButtonOnText.h b/retroshare-gui/src/gui/common/RsButtonOnText.h new file mode 100644 index 000000000..63f5f3248 --- /dev/null +++ b/retroshare-gui/src/gui/common/RsButtonOnText.h @@ -0,0 +1,47 @@ +#ifndef RSBUTTONONTEXT_H +#define RSBUTTONONTEXT_H + +#include +#include +#include + +class RSButtonOnText : public QPushButton +{ + Q_OBJECT + +public: + explicit RSButtonOnText(QWidget *parent = 0); + explicit RSButtonOnText(const QString &text, QWidget *parent=0); + RSButtonOnText(const QIcon& icon, const QString &text, QWidget *parent=0); + RSButtonOnText(QTextEdit *textEdit, QWidget *parent = 0); + RSButtonOnText(const QString &text, QTextEdit *textEdit, QWidget *parent = 0); + RSButtonOnText(const QIcon& icon, const QString &text, QTextEdit *textEdit, QWidget *parent = 0); + ~RSButtonOnText(); + + QString uuid(); + QString htmlText(); + void appendToText(QTextEdit *textEdit); + void clear(); + void updateImage(); + +signals: + void mouseEnter(); + void mouseLeave(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private: + bool isEventForThis(QObject *obj, QEvent *event, QPoint &point); + + QString _uuid; + int _lenght;//Because cursor end position move durring editing + QTextEdit* _textEdit; + QWidget* _textEditViewPort; + QTextCursor* _textCursor; + bool _mouseOver; + bool _pressed; + +}; + +#endif // RSBUTTONONTEXT_H diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index 764aa56dc..30968e124 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -435,6 +435,7 @@ HEADERS += rshare.h \ gui/toaster/GroupChatToaster.h \ gui/toaster/ChatLobbyToaster.h \ gui/toaster/FriendRequestToaster.h \ + gui/common/RsButtonOnText.h \ gui/common/RSGraphWidget.h \ gui/common/ElidedLabel.h \ gui/common/vmessagebox.h \ @@ -735,6 +736,7 @@ SOURCES += main.cpp \ gui/msgs/MessageWindow.cpp \ gui/msgs/TagsMenu.cpp \ gui/msgs/MessageUserNotify.cpp \ + gui/common/RsButtonOnText.cpp \ gui/common/RSGraphWidget.cpp \ gui/common/ElidedLabel.cpp \ gui/common/vmessagebox.cpp \