diff --git a/retroshare-gui/src/gui/chat/ChatTabWidget.cpp b/retroshare-gui/src/gui/chat/ChatTabWidget.cpp index 0e9bdb857..ec52ed40e 100644 --- a/retroshare-gui/src/gui/chat/ChatTabWidget.cpp +++ b/retroshare-gui/src/gui/chat/ChatTabWidget.cpp @@ -24,6 +24,7 @@ #include "ui_ChatTabWidget.h" #include "ChatDialog.h" #include "gui/common/StatusDefs.h" +#include "rshare.h" #define IMAGE_WINDOW ":/images/rstray3.png" #define IMAGE_TYPING ":/images/typing.png" @@ -35,12 +36,20 @@ ChatTabWidget::ChatTabWidget(QWidget *parent) : { ui->setupUi(this); - connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(tabClose(int))); - connect(this, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); + mEmptyIcon = NULL; + + connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(tabClose(int))); + connect(this, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); + + connect(rApp, SIGNAL(blink(bool)), this, SLOT(blink(bool))); } ChatTabWidget::~ChatTabWidget() { + if (mEmptyIcon) { + delete(mEmptyIcon); + } + delete ui; } @@ -91,12 +100,16 @@ void ChatTabWidget::tabInfoChanged(ChatDialog *dialog) int tab = indexOf(dialog); if (tab >= 0) { if (dialog->isTyping()) { + setBlinking(tab, false); setTabIcon(tab, QIcon(IMAGE_TYPING)); } else if (dialog->hasNewMessages()) { setTabIcon(tab, QIcon(IMAGE_CHAT)); + setBlinking(tab, true); } else if (dialog->hasPeerStatus()) { + setBlinking(tab, false); setTabIcon(tab, QIcon(StatusDefs::imageIM(dialog->getPeerStatus()))); } else { + setBlinking(tab, false); setTabIcon(tab, QIcon()); } } @@ -143,3 +156,39 @@ void ChatTabWidget::getInfo(bool &isTyping, bool &hasNewMessage, QIcon *icon) } } } + +void ChatTabWidget::setBlinking(int tab, bool blink) +{ + QIcon icon = tabBar()->tabData(tab).value(); + + if (blink) { + /* save current icon */ + tabBar()->setTabData(tab, tabIcon(tab)); + } else { + if (!icon.isNull()) { + /* reset icon */ + setTabIcon(tab, icon); + + /* remove icon */ + tabBar()->setTabData(tab, QVariant()); + } + } +} + +void ChatTabWidget::blink(bool on) +{ + int tabCount = tabBar()->count(); + for (int tab = 0; tab < tabCount; ++tab) { + QIcon icon = tabBar()->tabData(tab).value(); + + if (!icon.isNull()) { + if (mEmptyIcon == NULL) { + /* create empty icon */ + QPixmap pixmap(16, 16); + pixmap.fill(Qt::transparent); + mEmptyIcon = new QIcon(pixmap); + } + tabBar()->setTabIcon(tab, on ? icon : *mEmptyIcon); + } + } +} diff --git a/retroshare-gui/src/gui/chat/ChatTabWidget.h b/retroshare-gui/src/gui/chat/ChatTabWidget.h index 0ebede47c..aa9b1bb9e 100644 --- a/retroshare-gui/src/gui/chat/ChatTabWidget.h +++ b/retroshare-gui/src/gui/chat/ChatTabWidget.h @@ -43,6 +43,7 @@ public: void removeDialog(ChatDialog *dialog); void getInfo(bool &isTyping, bool &hasNewMessage, QIcon *icon); + void setBlinking(int tab, bool blink); signals: void tabChanged(ChatDialog *dialog); @@ -54,8 +55,11 @@ private slots: void tabChanged(int tab); void tabInfoChanged(ChatDialog *dialog); void dialogClose(ChatDialog *dialog); + void blink(bool on); private: + QIcon *mEmptyIcon; + Ui::ChatTabWidget *ui; }; diff --git a/retroshare-gui/src/gui/chat/PopupChatWindow.cpp b/retroshare-gui/src/gui/chat/PopupChatWindow.cpp index 2db434077..dbab1166a 100644 --- a/retroshare-gui/src/gui/chat/PopupChatWindow.cpp +++ b/retroshare-gui/src/gui/chat/PopupChatWindow.cpp @@ -29,7 +29,8 @@ #include "gui/settings/RsharePeerSettings.h" #include "gui/common/StatusDefs.h" #include "gui/style/RSStyle.h" -#include"util/misc.h" +#include "util/misc.h" +#include "rshare.h" #include #include @@ -70,6 +71,7 @@ PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WFlags flags) tabbedWindow = tabbed; firstShow = true; chatDialog = NULL; + mEmptyIcon = NULL; ui.tabWidget->setVisible(tabbedWindow); @@ -92,6 +94,8 @@ PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WFlags flags) connect(ui.tabWidget, SIGNAL(tabChanged(ChatDialog*)), this, SLOT(tabChanged(ChatDialog*))); connect(ui.tabWidget, SIGNAL(tabClosed(ChatDialog*)), this, SLOT(tabClosed(ChatDialog*))); + connect(rApp, SIGNAL(blink(bool)), this, SLOT(blink(bool))); + if (tabbedWindow) { /* signal toggled is called */ ui.actionSetOnTop->setChecked(Settings->valueFromGroup("ChatWindow", "OnTop", false).toBool()); @@ -105,6 +109,10 @@ PopupChatWindow::~PopupChatWindow() { saveSettings(); + if (mEmptyIcon) { + delete(mEmptyIcon); + } + if (this == instance) { instance = NULL; } @@ -263,10 +271,13 @@ void PopupChatWindow::calculateTitle(ChatDialog *dialog) QIcon icon; if (isTyping) { + mBlinkIcon = QIcon(); icon = QIcon(IMAGE_TYPING); } else if (hasNewMessages) { icon = QIcon(IMAGE_CHAT); + mBlinkIcon = icon; } else { + mBlinkIcon = QIcon(); if (cd && cd->hasPeerStatus()) { icon = QIcon(StatusDefs::imageIM(cd->getPeerStatus())); } else { @@ -405,3 +416,16 @@ void PopupChatWindow::calculateStyle(ChatDialog *dialog) ui.chatstatusbar->setStyleSheet(statusSheet); ui.chatcentralwidget->setStyleSheet(widgetSheet); } + +void PopupChatWindow::blink(bool on) +{ + if (!mBlinkIcon.isNull()) { + if (mEmptyIcon == NULL) { + /* create empty icon */ + QPixmap pixmap(16, 16); + pixmap.fill(Qt::transparent); + mEmptyIcon = new QIcon(pixmap); + } + setWindowIcon(on ? mBlinkIcon : *mEmptyIcon); + } +} diff --git a/retroshare-gui/src/gui/chat/PopupChatWindow.h b/retroshare-gui/src/gui/chat/PopupChatWindow.h index 4beb13387..40cfda860 100644 --- a/retroshare-gui/src/gui/chat/PopupChatWindow.h +++ b/retroshare-gui/src/gui/chat/PopupChatWindow.h @@ -63,12 +63,15 @@ private slots: void undockTab(); void setStyle(); void setOnTop(); + void blink(bool on); private: bool tabbedWindow; bool firstShow; std::string peerId; ChatDialog *chatDialog; + QIcon mBlinkIcon; + QIcon *mEmptyIcon; ChatDialog *getCurrentDialog(); void saveSettings(); diff --git a/retroshare-gui/src/gui/common/UserNotify.cpp b/retroshare-gui/src/gui/common/UserNotify.cpp index 2dba822bb..d33cb3992 100644 --- a/retroshare-gui/src/gui/common/UserNotify.cpp +++ b/retroshare-gui/src/gui/common/UserNotify.cpp @@ -22,9 +22,9 @@ #include #include #include -#include #include "UserNotify.h" +#include "rshare.h" UserNotify::UserNotify(QObject *parent) : QObject(parent) @@ -36,10 +36,7 @@ UserNotify::UserNotify(QObject *parent) : mNewCount = 0; mLastBlinking = false; - mTimer = new QTimer(this); - mTimer->setInterval(500); - - connect(mTimer, SIGNAL(timeout()), this, SLOT(timer())); + connect(rApp, SIGNAL(blink(bool)), this, SLOT(blink(bool))); } void UserNotify::initialize(QToolBar *mainToolBar, QAction *mainAction) @@ -109,11 +106,7 @@ void UserNotify::updateIcon() if (count) { mTrayIcon->setToolTip("RetroShare\n" + getTrayMessage(count > 1).arg(count)); mTrayIcon->show(); - if (!mTimer->isActive()) { - mTimer->start(); - } } else { - mTimer->stop(); mTrayIcon->hide(); } } @@ -152,18 +145,14 @@ void UserNotify::trayIconClicked(QSystemTrayIcon::ActivationReason e) } } -void UserNotify::timer() +void UserNotify::blink(bool on) { bool blinking = isBlinking(); if (mTrayIcon) { if (blinking) { /* blink icon */ - if (mTrayIcon->icon().isNull()) { - mTrayIcon->setIcon(getIcon()); - } else { - mTrayIcon->setIcon(QIcon()); - } + mTrayIcon->setIcon(on ? getIcon() : QIcon()); } else { if (mLastBlinking) { /* reset icon */ diff --git a/retroshare-gui/src/gui/common/UserNotify.h b/retroshare-gui/src/gui/common/UserNotify.h index b6bffdef9..0598a8de6 100644 --- a/retroshare-gui/src/gui/common/UserNotify.h +++ b/retroshare-gui/src/gui/common/UserNotify.h @@ -28,7 +28,6 @@ class QToolBar; class QToolButton; class QAction; -class QTimer; class UserNotify : public QObject { @@ -53,7 +52,7 @@ public slots: private slots: void trayIconClicked(QSystemTrayIcon::ActivationReason e = QSystemTrayIcon::Trigger); - void timer(); + void blink(bool on); private: virtual QIcon getIcon() { return QIcon(); } @@ -72,7 +71,6 @@ private: QAction *mNotifyIcon; unsigned int mNewCount; QString mButtonText; - QTimer *mTimer; bool mLastBlinking; }; diff --git a/retroshare-gui/src/rshare.cpp b/retroshare-gui/src/rshare.cpp index 50e887ad2..7b03dd03f 100644 --- a/retroshare-gui/src/rshare.cpp +++ b/retroshare-gui/src/rshare.cpp @@ -100,6 +100,11 @@ Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir) #endif + mBlink = true; + QTimer *timer = new QTimer(this); + timer->setInterval(500); + connect(timer, SIGNAL(timeout()), this, SLOT(blinkTimer())); + timer->start(); /* Read in all our command-line arguments. */ parseArguments(args); @@ -527,3 +532,9 @@ Rshare::createShortcut(const QKeySequence &key, QWidget *sender, QShortcut *s = new QShortcut(key, sender); connect(s, SIGNAL(activated()), receiver, slot); } + +void Rshare::blinkTimer() +{ + mBlink = !mBlink; + emit blink(mBlink); +} diff --git a/retroshare-gui/src/rshare.h b/retroshare-gui/src/rshare.h index d75751302..b3a866c76 100644 --- a/retroshare-gui/src/rshare.h +++ b/retroshare-gui/src/rshare.h @@ -130,6 +130,8 @@ signals: void running(); /** Signals that the application needs to shutdown now. */ void shutdown(); + /** Global blink timer */ + void blink(bool on); protected: #if defined(Q_OS_WIN) @@ -142,7 +144,7 @@ private slots: * will emit the running() signal to indicate that the application's event * loop is running. */ void onEventLoopStarted(); - + void blinkTimer(); private: /** Catches debugging messages from Qt and sends them to @@ -162,7 +164,7 @@ private: static bool useConfigDir; static QString configDir; - + bool mBlink; }; #endif