mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-10 15:09:42 -05:00
b0aa255ead
With receive of a new chat message in an inactive tab the input focus was set to the input field of that inactive tab. The current tab was still visible, but the input has gone to the invisible tab. This is a bug in Qt. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3820 b45a01b8-16f6-495d-af2f-9b41ad6348cc
1242 lines
40 KiB
C++
1242 lines
40 KiB
C++
/****************************************************************
|
|
*
|
|
* RetroShare is distributed under the following license:
|
|
*
|
|
* Copyright (C) 2006, crypton
|
|
*
|
|
* 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 2
|
|
* 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, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
****************************************************************/
|
|
|
|
#include <QMessageBox>
|
|
#include <QTimer>
|
|
#include <QScrollBar>
|
|
#include <QCloseEvent>
|
|
#include <QColorDialog>
|
|
#include <QDateTime>
|
|
#include <QFontDialog>
|
|
#include <QDir>
|
|
#include <QFileDialog>
|
|
#include <QBuffer>
|
|
#include <QTextCodec>
|
|
#include <QSound>
|
|
#include <sys/stat.h>
|
|
|
|
#include "PopupChatDialog.h"
|
|
#include "PopupChatWindow.h"
|
|
#include "gui/RetroShareLink.h"
|
|
#include "rshare.h"
|
|
|
|
#include <retroshare/rspeers.h>
|
|
#include <retroshare/rsmsgs.h>
|
|
#include <retroshare/rsfiles.h>
|
|
#include "retroshare/rsinit.h"
|
|
#include <retroshare/rsnotify.h>
|
|
#include <retroshare/rsstatus.h>
|
|
#include <retroshare/rsiface.h>
|
|
#include "gui/settings/rsharesettings.h"
|
|
#include "gui/settings/RsharePeerSettings.h"
|
|
#include "gui/notifyqt.h"
|
|
#include "../RsAutoUpdatePage.h"
|
|
#include "gui/common/StatusDefs.h"
|
|
#include "gui/common/Emoticons.h"
|
|
#include "gui/im_history/ImHistoryBrowser.h"
|
|
|
|
#include "gui/feeds/AttachFileItem.h"
|
|
#include "gui/msgs/MessageComposer.h"
|
|
#include "gui/common/PeerDefs.h"
|
|
|
|
#include <time.h>
|
|
|
|
#define appDir QApplication::applicationDirPath()
|
|
|
|
#define WINDOW(This) dynamic_cast<PopupChatWindow*>(This->window())
|
|
|
|
/*****
|
|
* #define CHAT_DEBUG 1
|
|
*****/
|
|
|
|
static std::map<std::string, PopupChatDialog *> chatDialogs;
|
|
|
|
// play sound when recv a message
|
|
void playsound()
|
|
{
|
|
Settings->beginGroup("Sound");
|
|
Settings->beginGroup("SoundFilePath");
|
|
QString OnlineSound = Settings->value("NewChatMessage","").toString();
|
|
Settings->endGroup();
|
|
Settings->beginGroup("Enable");
|
|
bool flag = Settings->value("NewChatMessage",false).toBool();
|
|
Settings->endGroup();
|
|
Settings->endGroup();
|
|
|
|
if (!OnlineSound.isEmpty() && flag) {
|
|
if (QSound::isAvailable()) {
|
|
QSound::play(OnlineSound);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Default constructor */
|
|
PopupChatDialog::PopupChatDialog(const std::string &id, const QString &name, QWidget *parent, Qt::WFlags flags)
|
|
: QWidget(parent, flags), dialogId(id), dialogName(name),
|
|
lastChatTime(0), lastChatName("")
|
|
|
|
{
|
|
/* Invoke Qt Designer generated QObject setup routine */
|
|
ui.setupUi(this);
|
|
|
|
newMessages = false;
|
|
typing = false;
|
|
m_manualDelete = false;
|
|
peerStatus = 0;
|
|
|
|
last_status_send_time = 0 ;
|
|
style.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
|
|
|
|
/* Hide or show the frames */
|
|
showAvatarFrame(true);
|
|
ui.infoframe->setVisible(false);
|
|
ui.statusmessagelabel->hide();
|
|
|
|
connect(ui.avatarFrameButton, SIGNAL(toggled(bool)), this, SLOT(showAvatarFrame(bool)));
|
|
|
|
connect(ui.sendButton, SIGNAL(clicked( ) ), this, SLOT(sendChat( ) ));
|
|
connect(ui.addFileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile()));
|
|
|
|
connect(ui.textboldButton, SIGNAL(clicked()), this, SLOT(setFont()));
|
|
connect(ui.textunderlineButton, SIGNAL(clicked()), this, SLOT(setFont()));
|
|
connect(ui.textitalicButton, SIGNAL(clicked()), this, SLOT(setFont()));
|
|
connect(ui.attachPictureButton, SIGNAL(clicked()), this, SLOT(addExtraPicture()));
|
|
connect(ui.fontButton, SIGNAL(clicked()), this, SLOT(getFont()));
|
|
connect(ui.colorButton, SIGNAL(clicked()), this, SLOT(setColor()));
|
|
connect(ui.emoteiconButton, SIGNAL(clicked()), this, SLOT(smileyWidget()));
|
|
connect(ui.actionSave_Chat_History, SIGNAL(triggered()), this, SLOT(fileSaveAs()));
|
|
connect(ui.actionClearOfflineMessages, SIGNAL(triggered()), this, SLOT(clearOfflineMessages()));
|
|
|
|
|
|
connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(const QString&, int)), this, SLOT(updateStatus(const QString&, int)));
|
|
connect(NotifyQt::getInstance(), SIGNAL(peerHasNewCustomStateString(const QString&, const QString&)), this, SLOT(updatePeersCustomStateString(const QString&, const QString&)));
|
|
|
|
std::cerr << "Connecting custom context menu" << std::endl;
|
|
ui.chattextEdit->setContextMenuPolicy(Qt::CustomContextMenu) ;
|
|
connect(ui.chattextEdit,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
|
|
|
|
// Create the status bar
|
|
resetStatusBar();
|
|
|
|
ui.textboldButton->setIcon(QIcon(QString(":/images/edit-bold.png")));
|
|
ui.textunderlineButton->setIcon(QIcon(QString(":/images/edit-underline.png")));
|
|
ui.textitalicButton->setIcon(QIcon(QString(":/images/edit-italic.png")));
|
|
ui.fontButton->setIcon(QIcon(QString(":/images/fonts.png")));
|
|
ui.emoteiconButton->setIcon(QIcon(QString(":/images/emoticons/kopete/kopete020.png")));
|
|
|
|
ui.textboldButton->setCheckable(true);
|
|
ui.textunderlineButton->setCheckable(true);
|
|
ui.textitalicButton->setCheckable(true);
|
|
|
|
setAcceptDrops(true);
|
|
ui.chattextEdit->setAcceptDrops(false);
|
|
|
|
QMenu * toolmenu = new QMenu();
|
|
toolmenu->addAction(ui.actionClear_Chat);
|
|
toolmenu->addAction(ui.actionSave_Chat_History);
|
|
toolmenu->addAction(ui.actionClearOfflineMessages);
|
|
toolmenu->addAction(ui.actionMessageHistory);
|
|
//toolmenu->addAction(ui.action_Disable_Emoticons);
|
|
ui.pushtoolsButton->setMenu(toolmenu);
|
|
|
|
mCurrentColor.setNamedColor(PeerSettings->getPrivateChatColor(dialogId));
|
|
mCurrentFont.fromString(PeerSettings->getPrivateChatFont(dialogId));
|
|
|
|
colorChanged(mCurrentColor);
|
|
fontChanged(mCurrentFont);
|
|
|
|
pasteLinkAct = new QAction(QIcon(":/images/pasterslink.png"), tr( "Paste retroshare Link" ), this );
|
|
connect( pasteLinkAct , SIGNAL( triggered() ), this, SLOT( pasteLink() ) );
|
|
|
|
updateAvatar() ;
|
|
updatePeerAvatar(id) ;
|
|
|
|
// load settings
|
|
processSettings(true);
|
|
|
|
// initialize first status
|
|
StatusInfo peerStatusInfo;
|
|
// No check of return value. Non existing status info is handled as offline.
|
|
rsStatus->getStatus(dialogId, peerStatusInfo);
|
|
updateStatus(QString::fromStdString(dialogId), peerStatusInfo.status);
|
|
|
|
StatusInfo ownStatusInfo;
|
|
if (rsStatus->getOwnStatus(ownStatusInfo)) {
|
|
updateStatus(QString::fromStdString(ownStatusInfo.id), ownStatusInfo.status);
|
|
}
|
|
|
|
// initialize first custom state string
|
|
QString customStateString = QString::fromStdString(rsMsgs->getCustomStateString(dialogId));
|
|
updatePeersCustomStateString(QString::fromStdString(dialogId), customStateString);
|
|
|
|
if (Settings->valueFromGroup("Chat", QString::fromUtf8("PrivateChat_History"), true).toBool()) {
|
|
historyKeeper.init(QString::fromStdString(RsInit::RsProfileConfigDirectory()) + "/chat_" + QString::fromStdString(dialogId) + ".xml");
|
|
|
|
// get offline chat messages
|
|
std::list<ChatInfo> offlineChat;
|
|
std::list<ChatInfo>::iterator offineChatIt;
|
|
rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, dialogId, offlineChat);
|
|
|
|
QList<IMHistoryItem> historyItems;
|
|
int messageCount = Settings->getPrivateChatHistoryCount();
|
|
if (messageCount > 0) {
|
|
historyKeeper.getMessages(historyItems, messageCount);
|
|
}
|
|
foreach(IMHistoryItem item, historyItems) {
|
|
for(offineChatIt = offlineChat.begin(); offineChatIt != offlineChat.end(); offineChatIt++) {
|
|
/* are they public? */
|
|
if ((offineChatIt->chatflags & RS_CHAT_PRIVATE) == 0) {
|
|
/* this should not happen */
|
|
continue;
|
|
}
|
|
|
|
QDateTime sendTime = QDateTime::fromTime_t(offineChatIt->sendTime);
|
|
QString message = QString::fromStdWString(offineChatIt->msg);
|
|
|
|
if (IMHistoryKeeper::compareItem(item, false, offineChatIt->rsid, sendTime, message)) {
|
|
// don't show offline message out of the history
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (offineChatIt == offlineChat.end()) {
|
|
addChatMsg(item.incoming, item.id, item.name, item.sendTime, item.recvTime, item.messageText, TYPE_HISTORY, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
ui.chattextEdit->installEventFilter(this);
|
|
|
|
// call once
|
|
onPrivateChatChanged(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD, true);
|
|
|
|
#ifdef RS_RELEASE_VERSION
|
|
ui.attachPictureButton->setVisible(false);
|
|
#endif
|
|
}
|
|
|
|
/** Destructor. */
|
|
PopupChatDialog::~PopupChatDialog()
|
|
{
|
|
// save settings
|
|
processSettings(false);
|
|
|
|
PopupChatWindow *window = WINDOW(this);
|
|
if (window) {
|
|
window->removeDialog(this);
|
|
window->calculateTitle(NULL);
|
|
}
|
|
|
|
std::map<std::string, PopupChatDialog *>::iterator it;
|
|
if (chatDialogs.end() != (it = chatDialogs.find(dialogId))) {
|
|
chatDialogs.erase(it);
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::processSettings(bool bLoad)
|
|
{
|
|
Settings->beginGroup(QString("ChatDialog"));
|
|
|
|
if (bLoad) {
|
|
// load settings
|
|
|
|
// state of splitter
|
|
ui.chatsplitter->restoreState(Settings->value("ChatSplitter").toByteArray());
|
|
} else {
|
|
// save settings
|
|
|
|
// state of splitter
|
|
Settings->setValue("ChatSplitter", ui.chatsplitter->saveState());
|
|
}
|
|
|
|
Settings->endGroup();
|
|
}
|
|
|
|
/*static*/ PopupChatDialog *PopupChatDialog::getExistingInstance(const std::string &id)
|
|
{
|
|
std::map<std::string, PopupChatDialog *>::iterator it;
|
|
if (chatDialogs.end() != (it = chatDialogs.find(id))) {
|
|
/* exists already */
|
|
return it->second;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*static*/ PopupChatDialog *PopupChatDialog::getPrivateChat(const std::string &id, uint chatflags)
|
|
{
|
|
/* see if it exists already */
|
|
PopupChatDialog *popupchatdialog = getExistingInstance(id);
|
|
if (popupchatdialog == NULL) {
|
|
if (chatflags & RS_CHAT_OPEN) {
|
|
RsPeerDetails sslDetails;
|
|
if (rsPeers->getPeerDetails(id, sslDetails)) {
|
|
popupchatdialog = new PopupChatDialog(id, PeerDefs::nameWithLocation(sslDetails));
|
|
chatDialogs[id] = popupchatdialog;
|
|
|
|
PopupChatWindow *window = PopupChatWindow::getWindow(false);
|
|
window->addDialog(popupchatdialog);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (popupchatdialog == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
popupchatdialog->insertChatMsgs();
|
|
|
|
PopupChatWindow *window = WINDOW(popupchatdialog);
|
|
if (window) {
|
|
window->showDialog(popupchatdialog, chatflags);
|
|
}
|
|
|
|
return popupchatdialog;
|
|
}
|
|
|
|
/*static*/ void PopupChatDialog::cleanupChat()
|
|
{
|
|
PopupChatWindow::cleanup();
|
|
|
|
/* PopupChatDialog destuctor removes the entry from the map */
|
|
std::list<PopupChatDialog*> list;
|
|
|
|
std::map<std::string, PopupChatDialog*>::iterator it;
|
|
for (it = chatDialogs.begin(); it != chatDialogs.end(); it++) {
|
|
if (it->second) {
|
|
list.push_back(it->second);
|
|
}
|
|
}
|
|
|
|
chatDialogs.clear();
|
|
|
|
std::list<PopupChatDialog*>::iterator it1;
|
|
for (it1 = list.begin(); it1 != list.end(); it1++) {
|
|
delete (*it1);
|
|
}
|
|
}
|
|
|
|
/*static*/ void PopupChatDialog::privateChatChanged(int list, int type)
|
|
{
|
|
if (list == NOTIFY_LIST_PRIVATE_INCOMING_CHAT && type == NOTIFY_TYPE_ADD) {
|
|
std::list<std::string> ids;
|
|
if (rsMsgs->getPrivateChatQueueIds(true, ids)) {
|
|
uint chatflags = Settings->getChatFlags();
|
|
|
|
std::list<std::string>::iterator id;
|
|
for (id = ids.begin(); id != ids.end(); id++) {
|
|
PopupChatDialog *pcd = getPrivateChat(*id, chatflags);
|
|
|
|
if (pcd) {
|
|
pcd->insertChatMsgs();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* now notify all open priavate chat windows */
|
|
std::map<std::string, PopupChatDialog *>::iterator it;
|
|
for (it = chatDialogs.begin (); it != chatDialogs.end(); it++) {
|
|
if (it->second) {
|
|
it->second->onPrivateChatChanged(list, type);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::chatFriend(const std::string &id)
|
|
{
|
|
if (id.empty()){
|
|
return;
|
|
}
|
|
std::cerr<<" popup dialog chat friend 1"<<std::endl;
|
|
|
|
RsPeerDetails detail;
|
|
if (!rsPeers->getPeerDetails(id, detail)) {
|
|
return;
|
|
}
|
|
|
|
std::string firstId;
|
|
|
|
if (detail.isOnlyGPGdetail) {
|
|
//let's get the ssl child details, and open all the chat boxes
|
|
std::list<std::string> sslIds;
|
|
rsPeers->getSSLChildListOfGPGId(detail.gpg_id, sslIds);
|
|
for (std::list<std::string>::iterator it = sslIds.begin(); it != sslIds.end(); it++) {
|
|
if (firstId.empty()) {
|
|
firstId = *it;
|
|
}
|
|
|
|
RsPeerDetails sslDetails;
|
|
if (rsPeers->getPeerDetails(*it, sslDetails)) {
|
|
if (sslDetails.state & RS_PEER_STATE_CONNECTED) {
|
|
getPrivateChat(*it, RS_CHAT_OPEN | RS_CHAT_FOCUS);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (detail.state & RS_PEER_STATE_CONNECTED) {
|
|
getPrivateChat(id, RS_CHAT_OPEN | RS_CHAT_FOCUS);
|
|
return;
|
|
}
|
|
firstId = id;
|
|
}
|
|
|
|
/* info dialog */
|
|
QMessageBox mb(QMessageBox::Question, tr("Friend not Online"), tr("Your Friend is offline \nDo you want to send them a Message instead"), QMessageBox::Yes | QMessageBox::No);
|
|
mb.setWindowIcon(QIcon(":/images/rstray3.png"));
|
|
if (mb.exec() == QMessageBox::Yes) {
|
|
MessageComposer::msgFriend(id, false);
|
|
} else {
|
|
if (firstId.empty() == false) {
|
|
getPrivateChat(firstId, RS_CHAT_OPEN | RS_CHAT_FOCUS);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*static*/ void PopupChatDialog::updateAllAvatars()
|
|
{
|
|
for(std::map<std::string, PopupChatDialog *>::const_iterator it(chatDialogs.begin());it!=chatDialogs.end();++it)
|
|
it->second->updateAvatar() ;
|
|
}
|
|
|
|
void PopupChatDialog::focusDialog()
|
|
{
|
|
ui.chattextEdit->setFocus();
|
|
}
|
|
|
|
void PopupChatDialog::pasteLink()
|
|
{
|
|
std::cerr << "In paste link" << std::endl ;
|
|
ui.chattextEdit->insertHtml(RSLinkClipboard::toHtml()) ;
|
|
}
|
|
|
|
void PopupChatDialog::contextMenu( QPoint point )
|
|
{
|
|
std::cerr << "In context menu" << std::endl ;
|
|
if(RSLinkClipboard::empty())
|
|
return ;
|
|
|
|
QMenu contextMnu(this);
|
|
contextMnu.addAction( pasteLinkAct);
|
|
|
|
contextMnu.exec(QCursor::pos());
|
|
}
|
|
|
|
void PopupChatDialog::resetStatusBar()
|
|
{
|
|
ui.statusLabel->clear();
|
|
ui.typingpixmapLabel->clear();
|
|
|
|
typing = false;
|
|
|
|
PopupChatWindow *window = WINDOW(this);
|
|
if (window) {
|
|
window->calculateTitle(this);
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::updateStatusTyping()
|
|
{
|
|
if (time(NULL) - last_status_send_time > 5) // limit 'peer is typing' packets to at most every 10 sec
|
|
{
|
|
#ifdef ONLY_FOR_LINGUIST
|
|
tr("is typing...");
|
|
#endif
|
|
|
|
rsMsgs->sendStatusString(dialogId, "is typing...");
|
|
last_status_send_time = time(NULL) ;
|
|
}
|
|
}
|
|
|
|
// Called by libretroshare through notifyQt to display the peer's status
|
|
//
|
|
void PopupChatDialog::updateStatusString(const QString& peer_id, const QString& status_string)
|
|
{
|
|
QString status = QString::fromStdString(rsPeers->getPeerName(peer_id.toStdString())) + " " + tr(status_string.toAscii());
|
|
ui.statusLabel->setText(status); // displays info for 5 secs.
|
|
ui.typingpixmapLabel->setPixmap(QPixmap(":images/typing.png") );
|
|
|
|
if (status_string == "is typing...") {
|
|
typing = true;
|
|
|
|
PopupChatWindow *window = WINDOW(this);
|
|
if (window) {
|
|
window->calculateTitle(this);
|
|
}
|
|
}
|
|
|
|
QTimer::singleShot(5000,this,SLOT(resetStatusBar())) ;
|
|
}
|
|
|
|
void PopupChatDialog::resizeEvent(QResizeEvent *event)
|
|
{
|
|
// Workaround: now the scroll position is correct calculated
|
|
QScrollBar *scrollbar = ui.textBrowser->verticalScrollBar();
|
|
scrollbar->setValue(scrollbar->maximum());
|
|
}
|
|
|
|
void PopupChatDialog::activate()
|
|
{
|
|
PopupChatWindow *window = WINDOW(this);
|
|
if (window) {
|
|
if (window->isActiveWindow()) {
|
|
newMessages = false;
|
|
window->calculateTitle(this);
|
|
focusDialog();
|
|
}
|
|
} else {
|
|
newMessages = false;
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::onPrivateChatChanged(int list, int type, bool initial /*= false*/)
|
|
{
|
|
if (list == NOTIFY_LIST_PRIVATE_OUTGOING_CHAT) {
|
|
switch (type) {
|
|
case NOTIFY_TYPE_ADD:
|
|
{
|
|
m_savedOfflineChat.clear();
|
|
|
|
QString name = QString::fromUtf8(rsPeers->getPeerName(rsPeers->getOwnId()).c_str());
|
|
|
|
std::list<ChatInfo> offlineChat;
|
|
if (rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, dialogId, offlineChat)) {
|
|
ui.actionClearOfflineMessages->setEnabled(true);
|
|
|
|
std::list<ChatInfo>::iterator it;
|
|
for(it = offlineChat.begin(); it != offlineChat.end(); it++) {
|
|
/* are they public? */
|
|
if ((it->chatflags & RS_CHAT_PRIVATE) == 0) {
|
|
/* this should not happen */
|
|
continue;
|
|
}
|
|
|
|
m_savedOfflineChat.push_back(*it);
|
|
|
|
QDateTime sendTime = QDateTime::fromTime_t(it->sendTime);
|
|
QDateTime recvTime = QDateTime::fromTime_t(it->recvTime);
|
|
QString message = QString::fromStdWString(it->msg);
|
|
|
|
bool existingMessage;
|
|
bool showMessage;
|
|
if (initial) {
|
|
// show all messages on startup
|
|
existingMessage = true;
|
|
showMessage = true;
|
|
} else {
|
|
int hiid;
|
|
existingMessage = historyKeeper.findMessage(false, it->rsid, sendTime, message, hiid);
|
|
showMessage = !existingMessage;
|
|
}
|
|
|
|
if (showMessage) {
|
|
addChatMsg(false, it->rsid, name, sendTime, recvTime, message, TYPE_OFFLINE, !existingMessage);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case NOTIFY_TYPE_DEL:
|
|
{
|
|
if (m_manualDelete == false) {
|
|
QString name = QString::fromUtf8(rsPeers->getPeerName(rsPeers->getOwnId()).c_str());
|
|
|
|
// now show saved offline chat messages as sent
|
|
std::list<ChatInfo>::iterator it;
|
|
for(it = m_savedOfflineChat.begin(); it != m_savedOfflineChat.end(); it++) {
|
|
QDateTime sendTime = QDateTime::fromTime_t(it->sendTime);
|
|
QDateTime recvTime = QDateTime::fromTime_t(it->recvTime);
|
|
QString message = QString::fromStdWString(it->msg);
|
|
|
|
addChatMsg(false, it->rsid, name, sendTime, recvTime, message, TYPE_NORMAL, false);
|
|
}
|
|
}
|
|
|
|
m_savedOfflineChat.clear();
|
|
}
|
|
break;
|
|
}
|
|
|
|
ui.actionClearOfflineMessages->setEnabled(!m_savedOfflineChat.empty());
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::insertChatMsgs()
|
|
{
|
|
std::list<ChatInfo> newchat;
|
|
if (!rsMsgs->getPrivateChatQueue(true, dialogId, newchat))
|
|
{
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "no chat for " << dialogId << " available." << std::endl ;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
std::list<ChatInfo>::iterator it;
|
|
for(it = newchat.begin(); it != newchat.end(); it++) {
|
|
/* are they public? */
|
|
if ((it->chatflags & RS_CHAT_PRIVATE) == 0) {
|
|
/* this should not happen */
|
|
continue;
|
|
}
|
|
|
|
addChatMsg(true, it->rsid, QString::fromStdString(rsPeers->getPeerName(it->rsid)), QDateTime::fromTime_t(it->sendTime), QDateTime::fromTime_t(it->recvTime), QString::fromStdWString(it->msg), TYPE_NORMAL, true);
|
|
}
|
|
|
|
rsMsgs->clearPrivateChatQueue(true, dialogId);
|
|
|
|
playsound();
|
|
|
|
PopupChatWindow *window = WINDOW(this);
|
|
if (window) {
|
|
window->alertDialog(this);
|
|
}
|
|
|
|
if (isVisible() == false || (window && window->isActiveWindow() == false)) {
|
|
newMessages = true;
|
|
|
|
if (window) {
|
|
window->calculateTitle(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::addChatMsg(bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, enumChatType chatType, bool addToHistory)
|
|
{
|
|
std::string ownId = rsPeers->getOwnId();
|
|
|
|
#ifdef CHAT_DEBUG
|
|
std::cout << "PopupChatDialog:addChatMsg message : " << message.toStdString() << std::endl;
|
|
#endif
|
|
|
|
unsigned int formatFlag = CHAT_FORMATMSG_EMBED_LINKS;
|
|
|
|
// embed smileys ?
|
|
if (Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool()) {
|
|
formatFlag |= CHAT_FORMATMSG_EMBED_SMILEYS;
|
|
}
|
|
|
|
ChatStyle::enumFormatMessage type;
|
|
if (chatType == TYPE_OFFLINE) {
|
|
type = ChatStyle::FORMATMSG_OOUTGOING;
|
|
} else if (chatType == TYPE_HISTORY) {
|
|
type = incoming ? ChatStyle::FORMATMSG_HINCOMING : ChatStyle::FORMATMSG_HOUTGOING;
|
|
} else {
|
|
type = incoming ? ChatStyle::FORMATMSG_INCOMING : ChatStyle::FORMATMSG_OUTGOING;
|
|
}
|
|
|
|
QString formatMsg = style.formatMessage(type, name, recvTime, message, formatFlag);
|
|
|
|
if (addToHistory) {
|
|
historyKeeper.addMessage(incoming, id, name, sendTime, recvTime, message);
|
|
}
|
|
|
|
ui.textBrowser->append(formatMsg);
|
|
|
|
/* Scroll to the end */
|
|
QScrollBar *scrollbar = ui.textBrowser->verticalScrollBar();
|
|
scrollbar->setValue(scrollbar->maximum());
|
|
|
|
resetStatusBar();
|
|
}
|
|
|
|
bool PopupChatDialog::eventFilter(QObject *obj, QEvent *event)
|
|
{
|
|
if (obj == ui.chattextEdit) {
|
|
if (event->type() == QEvent::KeyPress) {
|
|
updateStatusTyping() ;
|
|
|
|
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
|
if (keyEvent && (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return)) {
|
|
// Enter pressed
|
|
if (Settings->getChatSendMessageWithCtrlReturn()) {
|
|
if (keyEvent->modifiers() & Qt::ControlModifier) {
|
|
// send message with Ctrl+Enter
|
|
sendChat();
|
|
return true; // eat event
|
|
}
|
|
} else {
|
|
if (keyEvent->modifiers() & Qt::ControlModifier) {
|
|
// insert return
|
|
ui.chattextEdit->textCursor().insertText("\n");
|
|
} else {
|
|
// send message with Enter
|
|
sendChat();
|
|
}
|
|
return true; // eat event
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// pass the event on to the parent class
|
|
return QWidget::eventFilter(obj, event);
|
|
}
|
|
|
|
void PopupChatDialog::sendChat()
|
|
{
|
|
QTextEdit *chatWidget = ui.chattextEdit;
|
|
|
|
if (chatWidget->toPlainText().isEmpty()) {
|
|
// nothing to send
|
|
return;
|
|
}
|
|
|
|
std::wstring msg = chatWidget->toHtml().toStdWString();
|
|
|
|
if (msg.empty()) {
|
|
// nothing to send
|
|
return;
|
|
}
|
|
|
|
std::string ownId;
|
|
|
|
{
|
|
rsiface->lockData(); /* Lock Interface */
|
|
const RsConfig &conf = rsiface->getConfig();
|
|
|
|
ownId = conf.ownId;
|
|
|
|
rsiface->unlockData(); /* Unlock Interface */
|
|
}
|
|
|
|
#ifdef CHAT_DEBUG
|
|
std::cout << "PopupChatDialog:sendChat " << std::endl;
|
|
#endif
|
|
|
|
if (rsMsgs->sendPrivateChat(dialogId, msg)) {
|
|
QDateTime currentTime = QDateTime::currentDateTime();
|
|
addChatMsg(false, ownId, QString::fromStdString(rsPeers->getPeerName(ownId)), currentTime, currentTime, QString::fromStdWString(msg), TYPE_NORMAL, true);
|
|
}
|
|
|
|
chatWidget->clear();
|
|
// workaround for Qt bug - http://bugreports.qt.nokia.com/browse/QTBUG-2533
|
|
// QTextEdit::clear() does not reset the CharFormat if document contains hyperlinks that have been accessed.
|
|
chatWidget->setCurrentCharFormat(QTextCharFormat ());
|
|
|
|
setFont();
|
|
}
|
|
|
|
/**
|
|
Toggles the ToolBox on and off, changes toggle button text
|
|
*/
|
|
void PopupChatDialog::showAvatarFrame(bool show)
|
|
{
|
|
if (show) {
|
|
ui.avatarframe->setVisible(true);
|
|
ui.avatarFrameButton->setChecked(true);
|
|
ui.avatarFrameButton->setToolTip(tr("Hide Avatar"));
|
|
ui.avatarFrameButton->setIcon(QIcon(":images/hide_toolbox_frame.png"));
|
|
} else {
|
|
ui.avatarframe->setVisible(false);
|
|
ui.avatarFrameButton->setChecked(false);
|
|
ui.avatarFrameButton->setToolTip(tr("Show Avatar"));
|
|
ui.avatarFrameButton->setIcon(QIcon(":images/show_toolbox_frame.png"));
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::on_closeInfoFrameButton_clicked()
|
|
{
|
|
ui.infoframe->setVisible(false);
|
|
}
|
|
|
|
void PopupChatDialog::setColor()
|
|
{
|
|
bool ok;
|
|
QRgb color = QColorDialog::getRgba(ui.chattextEdit->textColor().rgba(), &ok, this);
|
|
if (ok) {
|
|
mCurrentColor = QColor(color);
|
|
PeerSettings->setPrivateChatColor(dialogId, mCurrentColor.name());
|
|
colorChanged(mCurrentColor);
|
|
}
|
|
setFont();
|
|
}
|
|
|
|
void PopupChatDialog::colorChanged(const QColor &c)
|
|
{
|
|
QPixmap pix(16, 16);
|
|
pix.fill(c);
|
|
ui.colorButton->setIcon(pix);
|
|
}
|
|
|
|
void PopupChatDialog::getFont()
|
|
{
|
|
bool ok;
|
|
QFont font = QFontDialog::getFont(&ok, mCurrentFont, this);
|
|
if (ok) {
|
|
fontChanged(font);
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::fontChanged(const QFont &font)
|
|
{
|
|
mCurrentFont = font;
|
|
|
|
ui.textboldButton->setChecked(mCurrentFont.bold());
|
|
ui.textunderlineButton->setChecked(mCurrentFont.underline());
|
|
ui.textitalicButton->setChecked(mCurrentFont.italic());
|
|
|
|
setFont();
|
|
}
|
|
|
|
void PopupChatDialog::setFont()
|
|
{
|
|
mCurrentFont.setBold(ui.textboldButton->isChecked());
|
|
mCurrentFont.setUnderline(ui.textunderlineButton->isChecked());
|
|
mCurrentFont.setItalic(ui.textitalicButton->isChecked());
|
|
|
|
ui.chattextEdit->setFont(mCurrentFont);
|
|
ui.chattextEdit->setTextColor(mCurrentColor);
|
|
|
|
ui.chattextEdit->setFocus();
|
|
|
|
PeerSettings->setPrivateChatFont(dialogId, mCurrentFont.toString());
|
|
}
|
|
|
|
//============================================================================
|
|
|
|
void PopupChatDialog::smileyWidget()
|
|
{
|
|
Emoticons::showSmileyWidget(this, ui.emoteiconButton, SLOT(addSmiley()), true);
|
|
}
|
|
|
|
//============================================================================
|
|
|
|
void PopupChatDialog::addSmiley()
|
|
{
|
|
ui.chattextEdit->textCursor().insertText(qobject_cast<QPushButton*>(sender())->toolTip().split("|").first());
|
|
}
|
|
|
|
//============================================================================
|
|
|
|
void PopupChatDialog::on_actionClear_Chat_triggered()
|
|
{
|
|
ui.textBrowser->clear();
|
|
}
|
|
|
|
void PopupChatDialog::updatePeerAvatar(const std::string& peer_id)
|
|
{
|
|
#ifdef CHAT_DEBUG
|
|
std::cerr << "popupchatDialog::updatePeerAvatar() updating avatar for peer " << peer_id << std::endl ;
|
|
std::cerr << "Requesting avatar image for peer " << peer_id << std::endl ;
|
|
#endif
|
|
|
|
unsigned char *data = NULL;
|
|
int size = 0 ;
|
|
|
|
rsMsgs->getAvatarData(peer_id,data,size);
|
|
|
|
#ifdef CHAT_DEBUG
|
|
std::cerr << "Image size = " << size << std::endl;
|
|
#endif
|
|
|
|
if(size == 0) {
|
|
#ifdef CHAT_DEBUG
|
|
std::cerr << "Got no image" << std::endl ;
|
|
#endif
|
|
ui.avatarlabel->setPixmap(QPixmap(":/images/no_avatar_background.png"));
|
|
return ;
|
|
}
|
|
|
|
// set the image
|
|
QPixmap pix ;
|
|
pix.loadFromData(data,size,"PNG") ;
|
|
ui.avatarlabel->setPixmap(pix); // writes image into ba in JPG format
|
|
|
|
delete[] data ;
|
|
}
|
|
|
|
void PopupChatDialog::updateAvatar()
|
|
{
|
|
unsigned char *data = NULL;
|
|
int size = 0 ;
|
|
|
|
rsMsgs->getOwnAvatarData(data,size);
|
|
|
|
#ifdef CHAT_DEBUG
|
|
std::cerr << "Image size = " << size << std::endl ;
|
|
#endif
|
|
|
|
if(size == 0) {
|
|
#ifdef CHAT_DEBUG
|
|
std::cerr << "Got no image" << std::endl ;
|
|
#endif
|
|
}
|
|
|
|
// set the image
|
|
QPixmap pix ;
|
|
pix.loadFromData(data,size,"PNG") ;
|
|
ui.myavatarlabel->setPixmap(pix); // writes image into ba in PNGformat
|
|
|
|
delete[] data ;
|
|
}
|
|
|
|
void PopupChatDialog::addExtraFile()
|
|
{
|
|
// select a file
|
|
QString qfile = QFileDialog::getOpenFileName(this, tr("Add Extra File"), "", "", 0,
|
|
QFileDialog::DontResolveSymlinks);
|
|
std::string filePath = qfile.toStdString();
|
|
if (filePath != "")
|
|
{
|
|
PopupChatDialog::addAttachment(filePath,0);
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::addExtraPicture()
|
|
{
|
|
// select a picture file
|
|
QString qfile = QFileDialog::getOpenFileName(this, "Load Picture File", QDir::homePath(), "Pictures (*.png *.xpm *.jpg)",0,
|
|
QFileDialog::DontResolveSymlinks);
|
|
std::string filePath=qfile.toStdString();
|
|
if(filePath!="")
|
|
{
|
|
PopupChatDialog::addAttachment(filePath,1); //picture
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::addAttachment(std::string filePath,int flag)
|
|
{
|
|
/* add a AttachFileItem to the attachment section */
|
|
std::cerr << "PopupChatDialog::addExtraFile() hashing file.";
|
|
std::cerr << std::endl;
|
|
|
|
/* add widget in for new destination */
|
|
AttachFileItem *file = new AttachFileItem(filePath);
|
|
//file->
|
|
|
|
if(flag==1)
|
|
file->setPicFlag(1);
|
|
|
|
ui.vboxLayout->addWidget(file, 1, 0);
|
|
|
|
//when the file is local or is finished hashing, call the fileHashingFinished method to send a chat message
|
|
if (file->getState() == AFI_STATE_LOCAL) {
|
|
fileHashingFinished(file);
|
|
} else {
|
|
QObject::connect(file,SIGNAL(fileFinished(AttachFileItem *)), SLOT(fileHashingFinished(AttachFileItem *))) ;
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::fileHashingFinished(AttachFileItem* file)
|
|
{
|
|
std::cerr << "PopupChatDialog::fileHashingFinished() started.";
|
|
std::cerr << std::endl;
|
|
|
|
//check that the file is ok tos end
|
|
if (file->getState() == AFI_STATE_ERROR) {
|
|
#ifdef CHAT_DEBUG
|
|
std::cerr << "PopupChatDialog::fileHashingFinished error file is not hashed.";
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
std::string ownId;
|
|
|
|
{
|
|
rsiface->lockData(); /* Lock Interface */
|
|
const RsConfig &conf = rsiface->getConfig();
|
|
|
|
ownId = conf.ownId;
|
|
|
|
rsiface->unlockData(); /* Unlock Interface */
|
|
}
|
|
|
|
QString message;
|
|
QString ext = QFileInfo(QString::fromStdString(file->FileName())).suffix();
|
|
|
|
if(file->getPicFlag()==1){
|
|
message+="<img src=\"file:///";
|
|
message+=file->FilePath().c_str();
|
|
message+="\" width=\"100\" height=\"100\">";
|
|
message+="<br>";
|
|
}
|
|
else if (ext == "ogg" || ext == "mp3" || ext == "MP3" || ext == "mp1" || ext == "mp2" || ext == "wav" || ext == "wma")
|
|
{
|
|
message+="<img src=\":/images/audio-x-monkey.png";
|
|
message+="\" width=\"48\" height=\"48\">";
|
|
message+="<br>";
|
|
}
|
|
else if (ext == "avi" || ext == "AVI" || ext == "mpg" || ext == "mpeg" || ext == "wmv" || ext == "ogm"
|
|
|| ext == "mkv" || ext == "mp4" || ext == "flv" || ext == "mov"
|
|
|| ext == "vob" || ext == "qt" || ext == "rm" || ext == "3gp")
|
|
{
|
|
message+="<img src=\":/images/video-x-generic.png";
|
|
message+="\" width=\"48\" height=\"48\">";
|
|
message+="<br>";
|
|
}
|
|
else if (ext == "tar" || ext == "bz2" || ext == "zip" || ext == "gz" || ext == "7z"
|
|
|| ext == "rar" || ext == "rpm" || ext == "deb")
|
|
{
|
|
message+="<img src=\":/images/application-x-rar.png";
|
|
message+="\" width=\"48\" height=\"48\">";
|
|
message+="<br>";
|
|
}
|
|
|
|
|
|
|
|
message+= RetroShareLink(QString::fromUtf8(file->FileName().c_str()),file->FileSize(),QString::fromStdString(file->FileHash())).toHtmlSize();
|
|
|
|
#ifdef CHAT_DEBUG
|
|
std::cerr << "PopupChatDialog::fileHashingFinished message : " << message.toStdString() << std::endl;
|
|
#endif
|
|
|
|
std::wstring msg = message.toStdWString();
|
|
|
|
if (rsMsgs->sendPrivateChat(dialogId, msg)) {
|
|
QDateTime currentTime = QDateTime::currentDateTime();
|
|
addChatMsg(false, ownId, QString::fromStdString(rsPeers->getPeerName(ownId)), currentTime, currentTime, QString::fromStdWString(msg), TYPE_NORMAL, true);
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::dropEvent(QDropEvent *event)
|
|
{
|
|
if (!(Qt::CopyAction & event->possibleActions()))
|
|
{
|
|
std::cerr << "PopupChatDialog::dropEvent() Rejecting uncopyable DropAction";
|
|
std::cerr << std::endl;
|
|
|
|
/* can't do it */
|
|
return;
|
|
}
|
|
|
|
std::cerr << "PopupChatDialog::dropEvent() Formats";
|
|
std::cerr << std::endl;
|
|
QStringList formats = event->mimeData()->formats();
|
|
QStringList::iterator it;
|
|
for(it = formats.begin(); it != formats.end(); it++)
|
|
{
|
|
std::cerr << "Format: " << (*it).toStdString();
|
|
std::cerr << std::endl;
|
|
}
|
|
|
|
if (event->mimeData()->hasUrls())
|
|
{
|
|
std::cerr << "PopupChatDialog::dropEvent() Urls:";
|
|
std::cerr << std::endl;
|
|
|
|
QList<QUrl> urls = event->mimeData()->urls();
|
|
QList<QUrl>::iterator uit;
|
|
for(uit = urls.begin(); uit != urls.end(); uit++)
|
|
{
|
|
QString localpath = uit->toLocalFile();
|
|
std::cerr << "Whole URL: " << uit->toString().toStdString() << std::endl;
|
|
std::cerr << "or As Local File: " << localpath.toStdString() << std::endl;
|
|
|
|
if (localpath.isEmpty() == false)
|
|
{
|
|
//Check that the file does exist and is not a directory
|
|
QDir dir(localpath);
|
|
if (dir.exists()) {
|
|
std::cerr << "PopupChatDialog::dropEvent() directory not accepted."<< std::endl;
|
|
QMessageBox mb(tr("Drop file error."), tr("Directory can't be dropped, only files are accepted."),QMessageBox::Information,QMessageBox::Ok,0,0,this);
|
|
mb.exec();
|
|
} else if (QFile::exists(localpath)) {
|
|
PopupChatDialog::addAttachment(localpath.toUtf8().constData(), false);
|
|
} else {
|
|
std::cerr << "PopupChatDialog::dropEvent() file does not exists."<< std::endl;
|
|
QMessageBox mb(tr("Drop file error."), tr("File not found or file name not accepted."),QMessageBox::Information,QMessageBox::Ok,0,0,this);
|
|
mb.exec();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
event->setDropAction(Qt::CopyAction);
|
|
event->accept();
|
|
}
|
|
|
|
void PopupChatDialog::dragEnterEvent(QDragEnterEvent *event)
|
|
{
|
|
/* print out mimeType */
|
|
std::cerr << "PopupChatDialog::dragEnterEvent() Formats";
|
|
std::cerr << std::endl;
|
|
QStringList formats = event->mimeData()->formats();
|
|
QStringList::iterator it;
|
|
for(it = formats.begin(); it != formats.end(); it++)
|
|
{
|
|
std::cerr << "Format: " << (*it).toStdString();
|
|
std::cerr << std::endl;
|
|
}
|
|
|
|
if (event->mimeData()->hasUrls())
|
|
{
|
|
std::cerr << "PopupChatDialog::dragEnterEvent() Accepting Urls";
|
|
std::cerr << std::endl;
|
|
event->acceptProposedAction();
|
|
}
|
|
else
|
|
{
|
|
std::cerr << "PopupChatDialog::dragEnterEvent() No Urls";
|
|
std::cerr << std::endl;
|
|
}
|
|
}
|
|
|
|
bool PopupChatDialog::fileSave()
|
|
{
|
|
if (fileName.isEmpty())
|
|
return fileSaveAs();
|
|
|
|
QFile file(fileName);
|
|
if (!file.open(QFile::WriteOnly))
|
|
return false;
|
|
QTextStream ts(&file);
|
|
ts.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
ts << ui.textBrowser->document()->toPlainText();
|
|
ui.textBrowser->document()->setModified(false);
|
|
return true;
|
|
}
|
|
|
|
bool PopupChatDialog::fileSaveAs()
|
|
{
|
|
QString fn = QFileDialog::getSaveFileName(this, tr("Save as..."),
|
|
QString(), tr("Text File (*.txt );;All Files (*)"));
|
|
if (fn.isEmpty())
|
|
return false;
|
|
setCurrentFileName(fn);
|
|
return fileSave();
|
|
}
|
|
|
|
void PopupChatDialog::setCurrentFileName(const QString &fileName)
|
|
{
|
|
this->fileName = fileName;
|
|
ui.textBrowser->document()->setModified(false);
|
|
|
|
setWindowModified(false);
|
|
}
|
|
|
|
void PopupChatDialog::clearOfflineMessages()
|
|
{
|
|
m_manualDelete = true;
|
|
rsMsgs->clearPrivateChatQueue(false, dialogId);
|
|
m_manualDelete = false;
|
|
}
|
|
|
|
void PopupChatDialog::updateStatus(const QString &peer_id, int status)
|
|
{
|
|
std::string stdPeerId = peer_id.toStdString();
|
|
|
|
/* set font size for status */
|
|
if (stdPeerId == dialogId) {
|
|
// the peers status has changed
|
|
|
|
switch (status) {
|
|
case RS_STATUS_OFFLINE:
|
|
ui.avatarlabel->setStyleSheet("QLabel#avatarlabel{ border-image:url(:/images/avatarstatus_bg_offline.png); }");
|
|
ui.avatarlabel->setEnabled(false);
|
|
ui.infoframe->setVisible(true);
|
|
ui.infolabel->setText(dialogName + " " + tr("apears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online"));
|
|
break;
|
|
|
|
case RS_STATUS_INACTIVE:
|
|
ui.avatarlabel->setStyleSheet("QLabel#avatarlabel{ border-image:url(:/images/avatarstatus_bg_away.png); }");
|
|
ui.avatarlabel->setEnabled(true);
|
|
ui.infoframe->setVisible(true);
|
|
ui.infolabel->setText(dialogName + " " + tr("is Idle and may not reply"));
|
|
break;
|
|
|
|
case RS_STATUS_ONLINE:
|
|
ui.avatarlabel->setStyleSheet("QLabel#avatarlabel{ border-image:url(:/images/avatarstatus_bg_online.png); }");
|
|
ui.avatarlabel->setEnabled(true);
|
|
ui.infoframe->setVisible(false);
|
|
break;
|
|
|
|
case RS_STATUS_AWAY:
|
|
ui.avatarlabel->setStyleSheet("QLabel#avatarlabel{ border-image:url(:/images/avatarstatus_bg_away.png); }");
|
|
ui.avatarlabel->setEnabled(true);
|
|
ui.infolabel->setText(dialogName + " " + tr("is Away and may not reply"));
|
|
ui.infoframe->setVisible(true);
|
|
break;
|
|
|
|
case RS_STATUS_BUSY:
|
|
ui.avatarlabel->setStyleSheet("QLabel#avatarlabel{ border-image:url(:/images/avatarstatus_bg_busy.png); }");
|
|
ui.avatarlabel->setEnabled(true);
|
|
ui.infolabel->setText(dialogName + " " + tr("is Busy and may not reply"));
|
|
ui.infoframe->setVisible(true);
|
|
break;
|
|
}
|
|
|
|
QString statusString("<span style=\"font-size:11pt; font-weight:500;""\">%1</span>");
|
|
ui.friendnamelabel->setText(dialogName + " (" + statusString.arg(StatusDefs::name(status)) + ")") ;
|
|
|
|
peerStatus = status;
|
|
|
|
PopupChatWindow *window = WINDOW(this);
|
|
if (window) {
|
|
window->calculateTitle(this);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (stdPeerId == rsPeers->getOwnId()) {
|
|
// my status has changed
|
|
|
|
switch (status) {
|
|
case RS_STATUS_OFFLINE:
|
|
ui.myavatarlabel->setStyleSheet("QLabel#myavatarlabel{border-image:url(:/images/avatarstatus_bg_offline.png); }");
|
|
break;
|
|
|
|
case RS_STATUS_INACTIVE:
|
|
ui.myavatarlabel->setStyleSheet("QLabel#myavatarlabel{border-image:url(:/images/avatarstatus_bg_away.png); }");
|
|
break;
|
|
|
|
case RS_STATUS_ONLINE:
|
|
ui.myavatarlabel->setStyleSheet("QLabel#myavatarlabel{border-image:url(:/images/avatarstatus_bg_online.png); }");
|
|
break;
|
|
|
|
case RS_STATUS_AWAY:
|
|
ui.myavatarlabel->setStyleSheet("QLabel#myavatarlabel{border-image:url(:/images/avatarstatus_bg_away.png); }");
|
|
break;
|
|
|
|
case RS_STATUS_BUSY:
|
|
ui.myavatarlabel->setStyleSheet("QLabel#myavatarlabel{border-image:url(:/images/avatarstatus_bg_busy.png); }");
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// ignore status change
|
|
}
|
|
|
|
void PopupChatDialog::updatePeersCustomStateString(const QString& peer_id, const QString& status_string)
|
|
{
|
|
std::string stdPeerId = peer_id.toStdString();
|
|
|
|
if (stdPeerId == dialogId) {
|
|
// the peers status string has changed
|
|
if (status_string.isEmpty()) {
|
|
ui.statusmessagelabel->hide();
|
|
} else {
|
|
ui.statusmessagelabel->show();
|
|
ui.statusmessagelabel->setText(status_string);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PopupChatDialog::on_actionMessageHistory_triggered()
|
|
{
|
|
ImHistoryBrowser imBrowser(dialogId, historyKeeper, ui.chattextEdit, this);
|
|
imBrowser.exec();
|
|
}
|