mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
37fe5ff3a3
Added queue for outgoing private offline chat messages. The queue is also saved until the private chat message could be delivered. It does not work in the short time between the shutdown of the peer and the switch of the state to offline for that peer. For this we need a response of the peer. Need recompile. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3517 b45a01b8-16f6-495d-af2f-9b41ad6348cc
1268 lines
42 KiB
C++
1268 lines
42 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 <QFile>
|
|
#include <QFileInfo>
|
|
#include <QWidgetAction>
|
|
#include <QTimer>
|
|
#include <QFileDialog>
|
|
#include "common/vmessagebox.h"
|
|
#include "common/StatusDefs.h"
|
|
|
|
#include <retroshare/rsiface.h>
|
|
#include <retroshare/rspeers.h>
|
|
#include <retroshare/rsmsgs.h>
|
|
#include <retroshare/rsstatus.h>
|
|
#include <retroshare/rsnotify.h>
|
|
|
|
#include "rshare.h"
|
|
#include "MessengerWindow.h"
|
|
#include "RsAutoUpdatePage.h"
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
#include "MainWindow.h"
|
|
#include "chat/PopupChatDialog.h"
|
|
#include "msgs/MessageComposer.h"
|
|
#include "ShareManager.h"
|
|
#include "notifyqt.h"
|
|
#include "connect/ConnectFriendWizard.h"
|
|
#endif // MINIMAL_RSGUI
|
|
#include "PeersDialog.h"
|
|
#include "connect/ConfCertDialog.h"
|
|
#include "util/PixmapMerging.h"
|
|
#include "LogoBar.h"
|
|
#include "util/Widget.h"
|
|
#include "settings/rsharesettings.h"
|
|
#include "common/RSTreeWidgetItem.h"
|
|
|
|
#include "RetroShareLink.h"
|
|
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <algorithm>
|
|
#include <set>
|
|
|
|
/* Images for context menu icons */
|
|
#define IMAGE_REMOVEFRIEND ":/images/removefriend16.png"
|
|
#define IMAGE_EXPIORTFRIEND ":/images/exportpeers_16x16.png"
|
|
#define IMAGE_CHAT ":/images/chat.png"
|
|
#define IMAGE_MSG ":/images/message-mail.png"
|
|
#define IMAGE_CONNECT ":/images/connect_friend.png"
|
|
#define IMAGE_PEERINFO ":/images/peerdetails_16x16.png"
|
|
#define IMAGE_AVAIBLE ":/images/user/identityavaiblecyan24.png"
|
|
#define IMAGE_CONNECT2 ":/images/reload24.png"
|
|
#define IMAGE_PASTELINK ":/images/pasterslink.png"
|
|
|
|
#define COLUMN_COUNT 3
|
|
#define COLUMN_NAME 0
|
|
#define COLUMN_STATE 1
|
|
#define COLUMN_INFO 2
|
|
|
|
#define COLUMN_DATA 0 // column for storing the userdata id
|
|
|
|
#define ROLE_SORT Qt::UserRole
|
|
#define ROLE_ID Qt::UserRole + 1
|
|
|
|
/******
|
|
* #define MSG_DEBUG 1
|
|
*****/
|
|
|
|
MessengerWindow* MessengerWindow::_instance = NULL;
|
|
static std::set<std::string> *expandedPeers = NULL;
|
|
|
|
/*static*/ void MessengerWindow::showYourself ()
|
|
{
|
|
if (_instance == NULL) {
|
|
_instance = new MessengerWindow();
|
|
}
|
|
|
|
_instance->show();
|
|
_instance->activateWindow();
|
|
}
|
|
|
|
MessengerWindow* MessengerWindow::getInstance()
|
|
{
|
|
return _instance;
|
|
}
|
|
|
|
void MessengerWindow::releaseInstance()
|
|
{
|
|
if (_instance) {
|
|
delete _instance;
|
|
}
|
|
if (expandedPeers) {
|
|
/* delete saved expanded peers */
|
|
delete(expandedPeers);
|
|
expandedPeers = NULL;
|
|
}
|
|
}
|
|
|
|
/** Constructor */
|
|
MessengerWindow::MessengerWindow(QWidget* parent, Qt::WFlags flags)
|
|
: RWindow("MessengerWindow", parent, flags)
|
|
{
|
|
/* Invoke the Qt Designer generated object setup routine */
|
|
ui.setupUi(this);
|
|
|
|
setAttribute ( Qt::WA_DeleteOnClose, true );
|
|
#ifdef MINIMAL_RSGUI
|
|
setAttribute (Qt::WA_QuitOnClose, true);
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
m_compareRole = new RSTreeWidgetItemCompareRole;
|
|
m_compareRole->addRole(COLUMN_NAME, ROLE_SORT);
|
|
|
|
connect( ui.messengertreeWidget, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( messengertreeWidgetCostumPopupMenu( QPoint ) ) );
|
|
#ifndef MINIMAL_RSGUI
|
|
connect( ui.messengertreeWidget, SIGNAL(itemDoubleClicked ( QTreeWidgetItem *, int)), this, SLOT(chatfriend(QTreeWidgetItem *)));
|
|
|
|
connect( ui.avatarButton, SIGNAL(clicked()), SLOT(getAvatar()));
|
|
connect( ui.shareButton, SIGNAL(clicked()), SLOT(openShareManager()));
|
|
connect( ui.addIMAccountButton, SIGNAL(clicked( bool ) ), this , SLOT( addFriend() ) );
|
|
#endif // MINIMAL_RSGUI
|
|
connect( ui.actionHide_Offline_Friends, SIGNAL(triggered()), this, SLOT(insertPeers()));
|
|
connect( ui.actionSort_by_State, SIGNAL(triggered()), this, SLOT(insertPeers()));
|
|
connect(ui.clearButton, SIGNAL(clicked()), this, SLOT(clearFilter()));
|
|
|
|
connect(ui.messagelineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(savestatusmessage()));
|
|
connect(ui.filterPatternLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterRegExpChanged()));
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
connect(NotifyQt::getInstance(), SIGNAL(friendsChanged()), this, SLOT(updateMessengerDisplay()));
|
|
connect(NotifyQt::getInstance(), SIGNAL(ownAvatarChanged()), this, SLOT(updateAvatar()));
|
|
connect(NotifyQt::getInstance(), SIGNAL(ownStatusMessageChanged()), this, SLOT(loadmystatusmessage()));
|
|
connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(QString,int)), this, SLOT(updateOwnStatus(QString,int)));
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
timer = new QTimer(this);
|
|
timer->connect(timer, SIGNAL(timeout()), this, SLOT(updateMessengerDisplay()));
|
|
timer->setInterval(1000); /* one second */
|
|
timer->setSingleShot(true);
|
|
|
|
/* to hide the header */
|
|
ui.messengertreeWidget->header()->hide();
|
|
|
|
/* Set header resize modes and initial section sizes */
|
|
ui.messengertreeWidget->setColumnCount(COLUMN_COUNT);
|
|
ui.messengertreeWidget->setColumnHidden ( COLUMN_INFO, true);
|
|
ui.messengertreeWidget->sortItems( COLUMN_NAME, Qt::AscendingOrder );
|
|
|
|
QHeaderView * _header = ui.messengertreeWidget->header () ;
|
|
_header->setResizeMode (COLUMN_NAME, QHeaderView::Stretch);
|
|
_header->setResizeMode (COLUMN_STATE, QHeaderView::Custom);
|
|
_header->setStretchLastSection(false);
|
|
|
|
_header->resizeSection ( COLUMN_NAME, 200 );
|
|
_header->resizeSection ( COLUMN_STATE, 42 );
|
|
|
|
//LogoBar
|
|
_rsLogoBarmessenger = NULL;
|
|
_rsLogoBarmessenger = new LogoBar(ui.logoframe);
|
|
Widget::createLayout(ui.logoframe)->addWidget(_rsLogoBarmessenger);
|
|
|
|
ui.messagelineEdit->setMinimumWidth(20);
|
|
|
|
itemFont = QFont("ARIAL", 10);
|
|
itemFont.setBold(true);
|
|
|
|
displayMenu();
|
|
|
|
// load settings
|
|
processSettings(true);
|
|
|
|
// add self nick
|
|
RsPeerDetails pd;
|
|
std::string ownId = rsPeers->getOwnId();
|
|
if (rsPeers->getPeerDetails(ownId, pd)) {
|
|
/* calculate only once */
|
|
m_nickName = QString::fromStdString(pd.name) + " - " + QString::fromStdString(pd.location);
|
|
#ifdef MINIMAL_RSGUI
|
|
ui.statusButton->setText(m_nickName);
|
|
#endif
|
|
}
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
/* Show nick and current state */
|
|
StatusInfo statusInfo;
|
|
rsStatus->getOwnStatus(statusInfo);
|
|
updateOwnStatus(QString::fromStdString(ownId), statusInfo.status);
|
|
|
|
MainWindow *pMainWindow = MainWindow::getInstance();
|
|
if (pMainWindow) {
|
|
QMenu *pStatusMenu = new QMenu();
|
|
pMainWindow->initializeStatusObject(pStatusMenu, true);
|
|
ui.statusButton->setMenu(pStatusMenu);
|
|
}
|
|
|
|
updateAvatar();
|
|
loadmystatusmessage();
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
insertPeers();
|
|
|
|
ui.clearButton->hide();
|
|
|
|
updateMessengerDisplay();
|
|
|
|
/* Hide platform specific features */
|
|
#ifdef Q_WS_WIN
|
|
#endif
|
|
}
|
|
|
|
MessengerWindow::~MessengerWindow ()
|
|
{
|
|
// save settings
|
|
processSettings(false);
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
MainWindow *pMainWindow = MainWindow::getInstance();
|
|
if (pMainWindow) {
|
|
pMainWindow->removeStatusObject(ui.statusButton);
|
|
}
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
delete(m_compareRole);
|
|
|
|
_instance = NULL;
|
|
}
|
|
|
|
void MessengerWindow::processSettings(bool bLoad)
|
|
{
|
|
QHeaderView *header = ui.messengertreeWidget->header ();
|
|
|
|
Settings->beginGroup(_name);
|
|
|
|
if (bLoad) {
|
|
// load settings
|
|
|
|
// state of messenger tree
|
|
header->restoreState(Settings->value("MessengerTree").toByteArray());
|
|
|
|
// state of actionHide_Offline_Friends
|
|
ui.actionHide_Offline_Friends->setChecked(Settings->value("hideOfflineFriends", false).toBool());
|
|
|
|
// state of actionSort_by_State
|
|
ui.actionSort_by_State->setChecked(Settings->value("sortByState", false).toBool());
|
|
|
|
// state of actionRoot_is_decorated
|
|
ui.actionRoot_is_decorated->setChecked(Settings->value("rootIsDecorated", true).toBool());
|
|
on_actionRoot_is_decorated_activated();
|
|
} else {
|
|
// save settings
|
|
|
|
// state of messenger tree
|
|
Settings->setValue("MessengerTree", header->saveState());
|
|
|
|
// state of actionSort_by_State
|
|
Settings->setValue("sortByState", ui.actionSort_by_State->isChecked());
|
|
|
|
// state of actionHide_Offline_Friends
|
|
Settings->setValue("hideOfflineFriends", ui.actionHide_Offline_Friends->isChecked());
|
|
|
|
// state of actionRoot_is_decorated
|
|
Settings->setValue("rootIsDecorated", ui.actionRoot_is_decorated->isChecked());
|
|
}
|
|
|
|
Settings->endGroup();
|
|
}
|
|
|
|
void MessengerWindow::messengertreeWidgetCostumPopupMenu( QPoint point )
|
|
{
|
|
QTreeWidgetItem *c = getCurrentPeer();
|
|
|
|
QMenu contextMnu( this );
|
|
|
|
QAction* expandAll = new QAction(tr( "Expand all" ), &contextMnu );
|
|
connect( expandAll , SIGNAL( triggered() ), ui.messengertreeWidget, SLOT (expandAll()) );
|
|
|
|
QAction* collapseAll = new QAction(tr( "Collapse all" ), &contextMnu );
|
|
connect( collapseAll , SIGNAL( triggered() ), ui.messengertreeWidget, SLOT(collapseAll()) );
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
QAction* chatAct = new QAction(QIcon(IMAGE_CHAT), tr( "Chat" ), &contextMnu );
|
|
if (c) {
|
|
connect( chatAct , SIGNAL( triggered() ), this, SLOT( chatfriendproxy() ) );
|
|
} else {
|
|
chatAct->setDisabled(true);
|
|
}
|
|
|
|
QAction* sendMessageAct = new QAction(QIcon(IMAGE_MSG), tr( "Message Friend" ), &contextMnu );
|
|
if (c) {
|
|
connect( sendMessageAct , SIGNAL( triggered() ), this, SLOT( sendMessage() ) );
|
|
} else {
|
|
sendMessageAct->setDisabled(true);
|
|
}
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
QAction* connectfriendAct = new QAction(QIcon(IMAGE_CONNECT), tr( "Connect To Friend" ), &contextMnu );
|
|
if (c) {
|
|
connect( connectfriendAct , SIGNAL( triggered() ), this, SLOT( connectfriend() ) );
|
|
} else {
|
|
connectfriendAct->setDisabled(true);
|
|
}
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
QAction* configurefriendAct = new QAction(QIcon(IMAGE_PEERINFO), tr( "Peer Details" ), &contextMnu );
|
|
if (c) {
|
|
connect( configurefriendAct , SIGNAL( triggered() ), this, SLOT( configurefriend() ) );
|
|
} else {
|
|
configurefriendAct->setDisabled(true);
|
|
}
|
|
|
|
QAction* recommendfriendAct = new QAction(QIcon(IMAGE_EXPIORTFRIEND), tr( "Recomend this Friend to..." ), &contextMnu );
|
|
if (c && c->type() == 0) {
|
|
connect( recommendfriendAct , SIGNAL( triggered() ), this, SLOT( recommendfriend() ) );
|
|
} else {
|
|
recommendfriendAct->setDisabled(true);
|
|
}
|
|
|
|
QAction* pastePersonAct = new QAction(QIcon(IMAGE_PASTELINK), tr( "Paste retroshare Link" ), &contextMnu );
|
|
if(!RSLinkClipboard::empty(RetroShareLink::TYPE_PERSON)) {
|
|
connect( pastePersonAct , SIGNAL( triggered() ), this, SLOT( pastePerson() ) );
|
|
} else {
|
|
pastePersonAct->setDisabled(true);
|
|
}
|
|
|
|
//QAction* profileviewAct = new QAction(QIcon(IMAGE_PEERINFO), tr( "Profile View" ), &contextMnu );
|
|
//connect( profileviewAct , SIGNAL( triggered() ), this, SLOT( viewprofile() ) );
|
|
|
|
QAction* exportfriendAct = new QAction(QIcon(IMAGE_EXPIORTFRIEND), tr( "Export Friend" ), &contextMnu );
|
|
if (c) {
|
|
connect( exportfriendAct , SIGNAL( triggered() ), this, SLOT( exportfriend() ) );
|
|
} else {
|
|
exportfriendAct->setDisabled(true);
|
|
}
|
|
|
|
QAction* removefriendAct = new QAction(QIcon(IMAGE_REMOVEFRIEND), tr( "Deny Friend" ), &contextMnu );
|
|
if (c) {
|
|
if (c->type() == 1) {
|
|
//this is a SSL key
|
|
removefriendAct->setText(tr( "Remove Friend Location"));
|
|
}
|
|
connect( removefriendAct , SIGNAL( triggered() ), this, SLOT( removefriend() ) );
|
|
} else {
|
|
removefriendAct->setDisabled(true);
|
|
}
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
QWidget *widget = new QWidget();
|
|
widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}");
|
|
|
|
QHBoxLayout *hbox = new QHBoxLayout(&contextMnu);
|
|
hbox->setMargin(0);
|
|
hbox->setSpacing(6);
|
|
|
|
QLabel *iconLabel = new QLabel(&contextMnu);
|
|
iconLabel->setPixmap(QPixmap(":/images/user/friends24.png"));
|
|
iconLabel->setMaximumSize( iconLabel->frameSize().height() + 24, 24 );
|
|
hbox->addWidget(iconLabel);
|
|
|
|
QLabel *textLabel;
|
|
textLabel = new QLabel( tr("<strong>RetroShare instance</strong>"), widget );
|
|
if (c && c->type() == 0) {
|
|
//this is a GPG key
|
|
textLabel->setText(tr("<strong>GPG Key</strong>"));
|
|
}
|
|
|
|
hbox->addWidget(textLabel);
|
|
|
|
QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
hbox->addItem(spacerItem);
|
|
|
|
widget->setLayout( hbox );
|
|
|
|
QWidgetAction *widgetAction = new QWidgetAction(this);
|
|
widgetAction->setDefaultWidget(widget);
|
|
|
|
contextMnu.addAction( widgetAction);
|
|
#ifndef MINIMAL_RSGUI
|
|
contextMnu.addAction( chatAct);
|
|
contextMnu.addAction( sendMessageAct);
|
|
contextMnu.addAction( configurefriendAct);
|
|
//contextMnu.addAction( profileviewAct);
|
|
contextMnu.addAction( recommendfriendAct);
|
|
#endif // MINIMAL_RSGUI
|
|
contextMnu.addAction( connectfriendAct);
|
|
#ifndef MINIMAL_RSGUI
|
|
contextMnu.addAction(pastePersonAct);
|
|
contextMnu.addAction( removefriendAct);
|
|
#endif // MINIMAL_RSGUI
|
|
//contextMnu.addAction( exportfriendAct);
|
|
contextMnu.addSeparator();
|
|
contextMnu.addAction( expandAll);
|
|
contextMnu.addAction( collapseAll);
|
|
contextMnu.exec(QCursor::pos());
|
|
}
|
|
|
|
void MessengerWindow::updateMessengerDisplay()
|
|
{
|
|
if (RsAutoUpdatePage::eventsLocked() == false) {
|
|
insertPeers();
|
|
}
|
|
|
|
timer->start();
|
|
}
|
|
|
|
/* get the list of peers from the RsIface. */
|
|
void MessengerWindow::insertPeers()
|
|
{
|
|
std::list<std::string> gpgFriends;
|
|
std::list<std::string>::iterator it;
|
|
std::list<StatusInfo> statusInfo;
|
|
#ifndef MINIMAL_RSGUI
|
|
rsStatus->getStatusList(statusInfo);
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
if (!rsPeers) {
|
|
/* not ready yet! */
|
|
std::cerr << "PeersDialog::insertPeers() not ready yet : rsPeers unintialized." << std::endl;
|
|
return;
|
|
}
|
|
|
|
std::list<std::string> privateChatIds;
|
|
#ifndef MINIMAL_RSGUI
|
|
rsMsgs->getPrivateChatQueueIds(true, privateChatIds);
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
rsPeers->getGPGAcceptedList(gpgFriends);
|
|
|
|
std::string sOwnId = rsPeers->getGPGOwnId();
|
|
|
|
//add own gpg id, if we have more than on location (ssl client)
|
|
std::list<std::string> ownSslContacts;
|
|
rsPeers->getSSLChildListOfGPGId(sOwnId, ownSslContacts);
|
|
if (ownSslContacts.size() > 0) {
|
|
gpgFriends.push_back(sOwnId);
|
|
}
|
|
|
|
/* get a link to the table */
|
|
QTreeWidget *peertreeWidget = ui.messengertreeWidget;
|
|
|
|
bool sortState = ui.actionSort_by_State->isChecked();
|
|
bool hideOfflineFriends = ui.actionHide_Offline_Friends->isChecked();
|
|
|
|
//remove items that are not fiends anymore
|
|
int itemCount = peertreeWidget->topLevelItemCount();
|
|
int index = 0;
|
|
while (index < itemCount) {
|
|
std::string gpg_widget_id = peertreeWidget->topLevelItem(index)->data(COLUMN_DATA, ROLE_ID).toString().toStdString();
|
|
if (std::find(gpgFriends.begin(), gpgFriends.end(), gpg_widget_id) == gpgFriends.end()) {
|
|
delete (peertreeWidget->takeTopLevelItem(index));
|
|
// count again
|
|
itemCount = peertreeWidget->topLevelItemCount();
|
|
} else {
|
|
index++;
|
|
}
|
|
}
|
|
|
|
//add the gpg friends
|
|
for(it = gpgFriends.begin(); it != gpgFriends.end(); it++) {
|
|
/* make a widget per friend */
|
|
QTreeWidgetItem *gpg_item = NULL;
|
|
QTreeWidgetItem *gpg_item_loop = NULL;
|
|
QString gpgid = QString::fromStdString(*it);
|
|
itemCount = peertreeWidget->topLevelItemCount();
|
|
for (int nIndex = 0; nIndex < itemCount; nIndex++) {
|
|
gpg_item_loop = peertreeWidget->topLevelItem(nIndex);
|
|
if (gpg_item_loop->data(COLUMN_DATA, ROLE_ID).toString() == gpgid) {
|
|
gpg_item = gpg_item_loop;
|
|
break;
|
|
}
|
|
}
|
|
|
|
RsPeerDetails detail;
|
|
if ((!rsPeers->getPeerDetails(*it, detail) || !detail.accept_connection)
|
|
&& detail.gpg_id != sOwnId) {
|
|
//don't accept anymore connection, remove from the view
|
|
delete (peertreeWidget->takeTopLevelItem(peertreeWidget->indexOfTopLevelItem(gpg_item)));
|
|
continue;
|
|
}
|
|
|
|
if (gpg_item == NULL) {
|
|
gpg_item = new RSTreeWidgetItem(m_compareRole, 0); //set type to 0 for custom popup menu
|
|
gpg_item->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
|
}
|
|
|
|
gpg_item -> setTextAlignment(COLUMN_NAME, Qt::AlignLeft | Qt::AlignVCenter );
|
|
gpg_item -> setSizeHint(COLUMN_NAME, QSize( 40,40 ) );
|
|
|
|
/* not displayed, used to find back the item */
|
|
gpg_item -> setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.id));
|
|
|
|
//remove items that are not friends anymore
|
|
int childCount = gpg_item->childCount();
|
|
int childIndex = 0;
|
|
while (childIndex < childCount) {
|
|
std::string ssl_id = gpg_item->child(childIndex)->data(COLUMN_DATA, ROLE_ID).toString().toStdString();
|
|
if (!rsPeers->isFriend(ssl_id)) {
|
|
delete (gpg_item->takeChild(childIndex));
|
|
// count again
|
|
childCount = gpg_item->childCount();
|
|
} else {
|
|
childIndex++;
|
|
}
|
|
}
|
|
|
|
//update the childs (ssl certs)
|
|
bool gpg_connected = false;
|
|
bool gpg_online = false;
|
|
bool gpg_hasPrivateChat = false;
|
|
std::list<std::string> sslContacts;
|
|
std::map<std::string, std::string> sslLocations;
|
|
std::map<std::string, QString> sslCustomStateStrings;
|
|
|
|
rsPeers->getSSLChildListOfGPGId(detail.gpg_id, sslContacts);
|
|
for(std::list<std::string>::iterator sslIt = sslContacts.begin(); sslIt != sslContacts.end(); sslIt++) {
|
|
QTreeWidgetItem *sslItem = NULL;
|
|
|
|
//find the corresponding sslItem child item of the gpg item
|
|
bool newChild = true;
|
|
childCount = gpg_item->childCount();
|
|
for (int childIndex = 0; childIndex < childCount; childIndex++) {
|
|
if (gpg_item->child(childIndex)->data(COLUMN_DATA, ROLE_ID).toString().toStdString() == *sslIt) {
|
|
sslItem = gpg_item->child(childIndex);
|
|
newChild = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
RsPeerDetails sslDetail;
|
|
if (!rsPeers->getPeerDetails(*sslIt, sslDetail) || !rsPeers->isFriend(*sslIt)) {
|
|
std::cerr << "Removing widget from the view : id : " << *sslIt << std::endl;
|
|
if (sslItem) {
|
|
//child has disappeared, remove it from the gpg_item
|
|
gpg_item->removeChild(sslItem);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (sslItem == NULL) {
|
|
sslItem = new RSTreeWidgetItem(m_compareRole, 1); //set type to 1 for custom popup menu
|
|
}
|
|
|
|
/* not displayed, used to find back the item */
|
|
sslItem -> setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(sslDetail.id));
|
|
|
|
/* store location */
|
|
sslLocations[sslDetail.id] = sslDetail.location;
|
|
|
|
QString sCustomString;
|
|
#ifndef MINIMAL_RSGUI
|
|
if (sslDetail.state & RS_PEER_STATE_CONNECTED) {
|
|
sCustomString = QString::fromStdString(rsMsgs->getCustomStateString(sslDetail.id));
|
|
}
|
|
#endif // MINIMAL_RSGUI
|
|
if (sCustomString.isEmpty()) {
|
|
sslItem -> setText( COLUMN_NAME, tr("location") + " : " + QString::fromStdString(sslDetail.location) + " " + QString::fromStdString(sslDetail.autoconnect));
|
|
sslItem -> setToolTip( COLUMN_NAME, tr("location") + " : " + QString::fromStdString(sslDetail.location));
|
|
} else {
|
|
sslItem -> setText( COLUMN_NAME, tr("location") + " : " + QString::fromStdString(sslDetail.location) + " " + QString::fromStdString(sslDetail.autoconnect) );
|
|
sslItem -> setToolTip( COLUMN_NAME, tr("location") + " : " + QString::fromStdString(sslDetail.location) + " - " + sCustomString);
|
|
|
|
/* store custom state string */
|
|
sslCustomStateStrings[sslDetail.id] = sCustomString;
|
|
}
|
|
|
|
QIcon sslIcon;
|
|
QFont sslFont;
|
|
QColor sslColor;
|
|
if (sslDetail.state & RS_PEER_STATE_CONNECTED) {
|
|
sslItem->setHidden(false);
|
|
gpg_connected = true;
|
|
|
|
#ifdef MINIMAL_RSGUI
|
|
// to show the gpg as online, remove it with MINIMAL_RSGUI
|
|
QFont font1;
|
|
font1.setBold(true);
|
|
|
|
gpg_item->setToolTip(COLUMN_NAME, StatusDefs::tooltip(RS_STATUS_ONLINE));
|
|
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(sortState, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE));
|
|
|
|
QColor textColor = StatusDefs::textColor(RS_STATUS_ONLINE);
|
|
QFont font = StatusDefs::font(RS_STATUS_ONLINE);
|
|
for(int i = 0; i < COLUMN_COUNT; i++) {
|
|
gpg_item -> setTextColor(i, textColor);
|
|
gpg_item -> setFont(i, font);
|
|
}
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
/* change color and icon */
|
|
sslIcon = QIcon(":/images/connect_established.png");
|
|
sslFont.setBold(true);
|
|
sslColor = Qt::darkBlue;
|
|
} else if (sslDetail.state & RS_PEER_STATE_ONLINE) {
|
|
sslItem->setHidden(hideOfflineFriends);
|
|
gpg_online = true;
|
|
|
|
sslFont.setBold(true);
|
|
sslColor = Qt::black;
|
|
} else {
|
|
sslItem->setHidden(hideOfflineFriends);
|
|
if (sslDetail.autoconnect !="Offline") {
|
|
sslIcon = QIcon(":/images/connect_creating.png");
|
|
} else {
|
|
sslIcon = QIcon(":/images/connect_no.png");
|
|
}
|
|
|
|
sslFont.setBold(false);
|
|
sslColor = Qt::black;
|
|
}
|
|
|
|
if (std::find(privateChatIds.begin(), privateChatIds.end(), sslDetail.id) != privateChatIds.end()) {
|
|
// private chat is available
|
|
sslIcon = QIcon(":/images/chat.png");
|
|
gpg_hasPrivateChat = true;
|
|
}
|
|
sslItem -> setIcon(COLUMN_NAME, sslIcon);
|
|
|
|
for (int i = 0; i < COLUMN_COUNT; i++) {
|
|
sslItem -> setTextColor(i, sslColor);
|
|
sslItem -> setFont(i, sslFont);
|
|
}
|
|
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "PeersDialog::insertPeers() inserting sslItem." << std::endl;
|
|
#endif
|
|
/* add sl child to the list. If item is already in the list, it won't be duplicated thanks to Qt */
|
|
gpg_item->addChild(sslItem);
|
|
if (newChild) {
|
|
gpg_item->setExpanded(true);
|
|
}
|
|
}
|
|
|
|
int i = 0;
|
|
QIcon gpgIcon;
|
|
|
|
if (gpg_connected) {
|
|
gpg_item->setHidden(false);
|
|
|
|
#ifdef MINIMAL_RSGUI
|
|
gpgIcon = QIcon(StatusDefs::imageIM(RS_STATUS_ONLINE));
|
|
#else
|
|
int bestPeerState = 0; // for gpg item
|
|
std::string bestSslId; // for gpg item
|
|
unsigned int bestRSState = 0; // for gpg item
|
|
|
|
std::list<StatusInfo>::iterator it = statusInfo.begin();
|
|
for(; it != statusInfo.end() ; it++){
|
|
|
|
// don't forget the kids
|
|
std::list<std::string>::iterator cont_it = sslContacts.begin();
|
|
for(; cont_it != sslContacts.end(); cont_it++){
|
|
|
|
if((it->id == *cont_it) && (rsPeers->isOnline(*cont_it))) {
|
|
|
|
int peerState = 0;
|
|
|
|
gpg_item -> setText(COLUMN_STATE, StatusDefs::name(it->status));
|
|
|
|
unsigned char *data = NULL;
|
|
int size = 0 ;
|
|
rsMsgs->getAvatarData(it->id ,data,size);
|
|
|
|
if(size != 0){
|
|
QPixmap avatar ;
|
|
avatar.loadFromData(data,size,"PNG") ;
|
|
QIcon avatar_icon(avatar);
|
|
gpg_item-> setIcon(COLUMN_STATE, avatar_icon);
|
|
delete[] data;
|
|
|
|
} else {
|
|
gpg_item -> setIcon(COLUMN_STATE,(QIcon(":/images/no_avatar_70.png")));
|
|
}
|
|
|
|
switch (it->status) {
|
|
case RS_STATUS_INACTIVE:
|
|
peerState = PEER_STATE_INACTIVE;
|
|
break;
|
|
|
|
case RS_STATUS_ONLINE:
|
|
peerState = PEER_STATE_ONLINE;
|
|
break;
|
|
|
|
case RS_STATUS_AWAY:
|
|
peerState = PEER_STATE_AWAY;
|
|
break;
|
|
|
|
case RS_STATUS_BUSY:
|
|
peerState = PEER_STATE_BUSY;
|
|
break;
|
|
}
|
|
|
|
/* find the best ssl contact for the gpg item */
|
|
if (bestPeerState == 0) {
|
|
/* first ssl contact */
|
|
bestPeerState = peerState;
|
|
bestSslId = *cont_it;
|
|
bestRSState = it->status;
|
|
} else if (peerState < bestPeerState) {
|
|
/* higher state */
|
|
bestPeerState = peerState;
|
|
bestSslId = *cont_it;
|
|
bestRSState = it->status;
|
|
} else if (peerState == bestPeerState) {
|
|
/* equal state */
|
|
|
|
/* use the ssl id with existing custom state string */
|
|
std::map<std::string, QString>::iterator it1 = sslCustomStateStrings.find(bestSslId);
|
|
std::map<std::string, QString>::iterator it2 = sslCustomStateStrings.find(*cont_it);
|
|
|
|
if (it1 == sslCustomStateStrings.end()) {
|
|
if (it2 == sslCustomStateStrings.end()) {
|
|
/* both with no custom state string ... use first */
|
|
} else {
|
|
/* second with a custom state string ... use second */
|
|
bestPeerState = peerState;
|
|
bestSslId = *cont_it;
|
|
}
|
|
} else {
|
|
/* use first */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bestPeerState == 0) {
|
|
// show as online
|
|
bestPeerState = PEER_STATE_ONLINE;
|
|
bestRSState = RS_STATUS_ONLINE;
|
|
}
|
|
|
|
QColor textColor = StatusDefs::textColor(bestRSState);
|
|
QFont font = StatusDefs::font(bestRSState);
|
|
for(i = 0; i < COLUMN_COUNT; i++) {
|
|
gpg_item -> setTextColor(i, textColor);
|
|
gpg_item -> setFont(i, font);
|
|
}
|
|
|
|
gpgIcon = QIcon(StatusDefs::imageIM(bestRSState));
|
|
|
|
gpg_item->setText(COLUMN_NAME, QString::fromStdString(detail.name));
|
|
gpg_item -> setToolTip(COLUMN_NAME, StatusDefs::tooltip(bestRSState));
|
|
|
|
std::map<std::string, QString>::iterator customStateString = sslCustomStateStrings.find(bestSslId);
|
|
if (customStateString == sslCustomStateStrings.end()) {
|
|
// std::map<std::string, std::string>::iterator location = sslLocations.find(bestSslId);
|
|
// if (location == sslLocations.end()) {
|
|
// /* show only the name */
|
|
// gpg_item->setText(COLUMN_NAME, QString::fromStdString(detail.name));
|
|
// } else {
|
|
// /* show the name with location */
|
|
// gpg_item->setText(COLUMN_NAME, QString::fromStdString(detail.name) + "\n" + QString::fromStdString(location->second));
|
|
// }
|
|
|
|
/* use state string for location */
|
|
QString stateString;
|
|
stateString = StatusDefs::name(bestRSState);
|
|
|
|
if (stateString.isEmpty()) {
|
|
/* show only the name */
|
|
gpg_item->setText(COLUMN_NAME, QString::fromStdString(detail.name));
|
|
} else {
|
|
/* show the name with location */
|
|
gpg_item->setText(COLUMN_NAME, QString::fromStdString(detail.name) + "\n" + stateString);
|
|
}
|
|
} else {
|
|
/* show the name with custom state string */
|
|
gpg_item->setText(COLUMN_NAME, QString::fromStdString(detail.name) + "\n" + customStateString->second);
|
|
}
|
|
|
|
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(sortState, gpg_item->text(COLUMN_NAME), bestPeerState));
|
|
|
|
#endif // MINIMAL_RSGUI
|
|
} else if (gpg_online) {
|
|
gpg_item->setHidden(hideOfflineFriends);
|
|
gpg_item->setText(COLUMN_NAME, QString::fromStdString(detail.name));
|
|
gpgIcon = QIcon(IMAGE_AVAIBLE);
|
|
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(sortState, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE));
|
|
QFont font;
|
|
font.setBold(true);
|
|
for(i = 0; i < COLUMN_COUNT; i++) {
|
|
gpg_item -> setTextColor(i,(Qt::black));
|
|
gpg_item -> setFont(i,font);
|
|
}
|
|
} else {
|
|
gpg_item->setHidden(hideOfflineFriends);
|
|
gpg_item->setText(COLUMN_NAME, QString::fromStdString(detail.name));
|
|
gpgIcon = QIcon(StatusDefs::imageIM(RS_STATUS_OFFLINE));
|
|
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(sortState, gpg_item->text(COLUMN_NAME), PEER_STATE_OFFLINE));
|
|
|
|
QColor textColor = StatusDefs::textColor(RS_STATUS_OFFLINE);
|
|
QFont font = StatusDefs::font(RS_STATUS_OFFLINE);
|
|
for(i = 0; i < COLUMN_COUNT; i++) {
|
|
gpg_item -> setTextColor(i, textColor);
|
|
gpg_item -> setFont(i, font);
|
|
}
|
|
}
|
|
|
|
if (gpg_hasPrivateChat) {
|
|
gpgIcon = QIcon(":/images/chat.png");
|
|
}
|
|
|
|
gpg_item -> setIcon(COLUMN_NAME, gpgIcon);
|
|
|
|
/* add gpg item to the list. If item is already in the list, it won't be duplicated thanks to Qt */
|
|
peertreeWidget->addTopLevelItem(gpg_item);
|
|
|
|
if (expandedPeers && expandedPeers->find(detail.gpg_id) != expandedPeers->end()) {
|
|
/* we have information about expanded peers and the peer was expanded */
|
|
gpg_item->setExpanded(true);
|
|
}
|
|
}
|
|
|
|
if (ui.filterPatternLineEdit->text().isEmpty() == false) {
|
|
FilterItems();
|
|
}
|
|
|
|
if (expandedPeers) {
|
|
/* we don't need the informations anymore */
|
|
delete(expandedPeers);
|
|
expandedPeers = NULL;
|
|
}
|
|
|
|
QTreeWidgetItem *c = getCurrentPeer();
|
|
if (c && c->isHidden()) {
|
|
// active item is hidden, deselect it
|
|
ui.messengertreeWidget->setCurrentItem(NULL);
|
|
}
|
|
}
|
|
|
|
/* Utility Fns */
|
|
std::string getPeersRsCertId(QTreeWidgetItem *i)
|
|
{
|
|
std::string id = i -> data(COLUMN_DATA, ROLE_ID).toString().toStdString();
|
|
return id;
|
|
}
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
/** Add a Friend ShortCut */
|
|
void MessengerWindow::addFriend()
|
|
{
|
|
ConnectFriendWizard connwiz (this);
|
|
|
|
connwiz.exec ();
|
|
}
|
|
|
|
/** Open a QFileDialog to browse for export a file. */
|
|
void MessengerWindow::exportfriend()
|
|
{
|
|
QTreeWidgetItem *c = getCurrentPeer();
|
|
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "PeersDialog::exportfriend()" << std::endl;
|
|
#endif
|
|
if (!c)
|
|
{
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "PeersDialog::exportfriend() None Selected -- sorry" << std::endl;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
std::string id = getPeersRsCertId(c);
|
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Certificate"), "",
|
|
tr("Certificates (*.pqi)"));
|
|
|
|
std::string file = fileName.toStdString();
|
|
if (file != "")
|
|
{
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "PeersDialog::exportfriend() Saving to: " << file << std::endl;
|
|
std::cerr << std::endl;
|
|
#endif
|
|
if (rsPeers)
|
|
{
|
|
rsPeers->saveCertificateToFile(id, file);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void MessengerWindow::chatfriendproxy()
|
|
{
|
|
chatfriend(getCurrentPeer());
|
|
}
|
|
|
|
void MessengerWindow::chatfriend(QTreeWidgetItem *pPeer)
|
|
{
|
|
if (pPeer == NULL) {
|
|
return;
|
|
}
|
|
|
|
std::string id = pPeer->data(COLUMN_DATA, ROLE_ID).toString().toStdString();
|
|
PopupChatDialog::chatFriend(id);
|
|
}
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
QTreeWidgetItem *MessengerWindow::getCurrentPeer()
|
|
{
|
|
/* get the current, and extract the Id */
|
|
|
|
/* get a link to the table */
|
|
QTreeWidget *peerWidget = ui.messengertreeWidget;
|
|
QTreeWidgetItem *item = peerWidget -> currentItem();
|
|
if (!item)
|
|
{
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "Invalid Current Item" << std::endl;
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef PEERS_DEBUG
|
|
/* Display the columns of this item. */
|
|
std::ostringstream out;
|
|
out << "CurrentPeerItem: " << std::endl;
|
|
|
|
for(int i = 1; i < 6; i++)
|
|
{
|
|
QString txt = item -> text(i);
|
|
out << "\t" << i << ":" << txt.toStdString() << std::endl;
|
|
}
|
|
std::cerr << out.str();
|
|
#endif
|
|
return item;
|
|
}
|
|
|
|
/* So from the Peers Dialog we can call the following control Functions:
|
|
* (1) Remove Current. FriendRemove(id)
|
|
* (2) Allow/DisAllow. FriendStatus(id, accept)
|
|
* (2) Connect. FriendConnectAttempt(id, accept)
|
|
* (3) Set Address. FriendSetAddress(id, str, port)
|
|
* (4) Set Trust. FriendTrustSignature(id, bool)
|
|
* (5) Configure (GUI Only) -> 3/4
|
|
*
|
|
* All of these rely on the finding of the current Id.
|
|
*/
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
void MessengerWindow::removefriend()
|
|
{
|
|
QTreeWidgetItem *c = getCurrentPeer();
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "PeersDialog::removefriend()" << std::endl;
|
|
#endif
|
|
if (!c)
|
|
{
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "PeersDialog::removefriend() Noone Selected -- sorry" << std::endl;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
if (rsPeers)
|
|
{
|
|
rsPeers->removeFriend(getPeersRsCertId(c));
|
|
emit friendsUpdated() ;
|
|
}
|
|
}
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
void MessengerWindow::connectfriend()
|
|
{
|
|
QTreeWidgetItem *c = getCurrentPeer();
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "PeersDialog::connectfriend()" << std::endl;
|
|
#endif
|
|
if (!c)
|
|
{
|
|
#ifdef PEERS_DEBUG
|
|
std::cerr << "PeersDialog::connectfriend() Noone Selected -- sorry" << std::endl;
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
if (rsPeers)
|
|
{
|
|
if (c->type() == 0) {
|
|
int childCount = c->childCount();
|
|
for (int childIndex = 0; childIndex < childCount; childIndex++) {
|
|
QTreeWidgetItem *item = c->child(childIndex);
|
|
if (item->type() == 1) {
|
|
rsPeers->connectAttempt(getPeersRsCertId(item));
|
|
item->setIcon(COLUMN_NAME,(QIcon(IMAGE_CONNECT2)));
|
|
}
|
|
}
|
|
} else {
|
|
//this is a SSL key
|
|
rsPeers->connectAttempt(getPeersRsCertId(c));
|
|
c->setIcon(COLUMN_NAME,(QIcon(IMAGE_CONNECT2)));
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
/* GUI stuff -> don't do anything directly with Control */
|
|
void MessengerWindow::configurefriend()
|
|
{
|
|
ConfCertDialog::show(getPeersRsCertId(getCurrentPeer()));
|
|
}
|
|
|
|
void MessengerWindow::recommendfriend()
|
|
{
|
|
QTreeWidgetItem *peer = getCurrentPeer();
|
|
|
|
if (!peer)
|
|
return;
|
|
|
|
std::list <std::string> ids;
|
|
ids.push_back(peer->data(COLUMN_DATA, ROLE_ID).toString().toStdString());
|
|
MessageComposer::recommendFriend(ids);
|
|
}
|
|
|
|
void MessengerWindow::pastePerson()
|
|
{
|
|
RSLinkClipboard::process(RetroShareLink::TYPE_PERSON, RSLINK_PROCESS_NOTIFY_ERROR);
|
|
}
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
//============================================================================
|
|
|
|
|
|
void MessengerWindow::closeEvent (QCloseEvent * event)
|
|
{
|
|
/* save the expanded peers */
|
|
if (expandedPeers == NULL) {
|
|
expandedPeers = new std::set<std::string>;
|
|
} else {
|
|
expandedPeers->clear();
|
|
}
|
|
|
|
for (int nIndex = 0; nIndex < ui.messengertreeWidget->topLevelItemCount(); nIndex++) {
|
|
QTreeWidgetItem *item = ui.messengertreeWidget->topLevelItem(nIndex);
|
|
if (item->isExpanded()) {
|
|
expandedPeers->insert(expandedPeers->end(), item->data(COLUMN_DATA, ROLE_ID).toString().toStdString());
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
LogoBar & MessengerWindow::getLogoBar() const {
|
|
return *_rsLogoBarmessenger;
|
|
}
|
|
|
|
#ifndef MINIMAL_RSGUI
|
|
/** Shows Share Manager */
|
|
void MessengerWindow::openShareManager()
|
|
{
|
|
ShareManager::showYourself();
|
|
}
|
|
|
|
void MessengerWindow::sendMessage()
|
|
{
|
|
QTreeWidgetItem *peer = getCurrentPeer();
|
|
|
|
if (!peer)
|
|
return;
|
|
|
|
std::string id = peer->data(COLUMN_DATA, ROLE_ID).toString().toStdString();
|
|
MessageComposer::msgFriend(id);
|
|
}
|
|
|
|
void MessengerWindow::changeAvatarClicked()
|
|
{
|
|
updateAvatar();
|
|
}
|
|
|
|
void MessengerWindow::updateAvatar()
|
|
{
|
|
unsigned char *data = NULL;
|
|
int size = 0 ;
|
|
|
|
rsMsgs->getOwnAvatarData(data,size);
|
|
|
|
std::cerr << "Image size = " << size << std::endl ;
|
|
|
|
if(size == 0)
|
|
std::cerr << "Got no image" << std::endl ;
|
|
|
|
// set the image
|
|
QPixmap pix ;
|
|
pix.loadFromData(data,size,"PNG") ;
|
|
ui.avatarButton->setIcon(pix); // writes image into ba in PNG format
|
|
|
|
delete[] data ;
|
|
}
|
|
|
|
void MessengerWindow::getAvatar()
|
|
{
|
|
QString fileName = QFileDialog::getOpenFileName(this, "Load File", QDir::homePath(), "Pictures (*.png *.xpm *.jpg)");
|
|
if(!fileName.isEmpty())
|
|
{
|
|
picture = QPixmap(fileName).scaled(96,96, Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
|
|
|
|
std::cerr << "Sending avatar image down the pipe" << std::endl ;
|
|
|
|
// send avatar down the pipe for other peers to get it.
|
|
QByteArray ba;
|
|
QBuffer buffer(&ba);
|
|
buffer.open(QIODevice::WriteOnly);
|
|
picture.save(&buffer, "PNG"); // writes image into ba in PNG format
|
|
|
|
std::cerr << "Image size = " << ba.size() << std::endl ;
|
|
|
|
rsMsgs->setOwnAvatarData((unsigned char *)(ba.data()),ba.size()) ; // last char 0 included.
|
|
|
|
updateAvatar() ;
|
|
}
|
|
}
|
|
|
|
/** Loads own personal status message */
|
|
void MessengerWindow::loadmystatusmessage()
|
|
{
|
|
ui.messagelineEdit->setText(QString::fromStdString(rsMsgs->getCustomStateString()));
|
|
}
|
|
|
|
/** Save own status message */
|
|
void MessengerWindow::savestatusmessage()
|
|
{
|
|
rsMsgs->setCustomStateString(ui.messagelineEdit->text().toStdString());
|
|
}
|
|
|
|
void MessengerWindow::updateOwnStatus(const QString &peer_id, int status)
|
|
{
|
|
// add self nick + own status
|
|
if (peer_id.toStdString() == rsPeers->getOwnId())
|
|
{
|
|
// my status has changed
|
|
|
|
ui.statusButton->setText(m_nickName + " (" + StatusDefs::name(status) + ")");
|
|
|
|
switch (status) {
|
|
case RS_STATUS_OFFLINE:
|
|
ui.avatarButton->setStyleSheet("QToolButton#avatarButton{border-image:url(:/images/mystatus_bg_offline.png); }");
|
|
break;
|
|
|
|
case RS_STATUS_INACTIVE:
|
|
ui.avatarButton->setStyleSheet("QToolButton#avatarButton{border-image:url(:/images/mystatus_bg_idle.png); }");
|
|
break;
|
|
|
|
case RS_STATUS_ONLINE:
|
|
ui.avatarButton->setStyleSheet("QToolButton#avatarButton{border-image:url(:/images/mystatus_bg_online.png); }");
|
|
break;
|
|
|
|
case RS_STATUS_AWAY:
|
|
ui.avatarButton->setStyleSheet("QToolButton#avatarButton{border-image:url(:/images/mystatus_bg_idle.png); }");
|
|
break;
|
|
|
|
case RS_STATUS_BUSY:
|
|
ui.avatarButton->setStyleSheet("QToolButton#avatarButton{border-image:url(:/images/mystatus_bg_busy.png); }");
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
#endif // MINIMAL_RSGUI
|
|
|
|
void MessengerWindow::on_actionSort_Peers_Descending_Order_activated()
|
|
{
|
|
ui.messengertreeWidget->sortItems ( COLUMN_NAME, Qt::DescendingOrder );
|
|
}
|
|
|
|
void MessengerWindow::on_actionSort_Peers_Ascending_Order_activated()
|
|
{
|
|
ui.messengertreeWidget->sortItems ( COLUMN_NAME, Qt::AscendingOrder );
|
|
}
|
|
|
|
void MessengerWindow::on_actionRoot_is_decorated_activated()
|
|
{
|
|
ui.messengertreeWidget->setRootIsDecorated(ui.actionRoot_is_decorated->isChecked());
|
|
}
|
|
|
|
void MessengerWindow::displayMenu()
|
|
{
|
|
QMenu *lookmenu = new QMenu();
|
|
lookmenu->addAction(ui.actionSort_Peers_Descending_Order);
|
|
lookmenu->addAction(ui.actionSort_Peers_Ascending_Order);
|
|
lookmenu->addAction(ui.actionSort_by_State);
|
|
lookmenu->addAction(ui.actionHide_Offline_Friends);
|
|
lookmenu->addAction(ui.actionRoot_is_decorated);
|
|
|
|
ui.displaypushButton->setMenu(lookmenu);
|
|
}
|
|
|
|
/* clear Filter */
|
|
void MessengerWindow::clearFilter()
|
|
{
|
|
ui.filterPatternLineEdit->clear();
|
|
ui.filterPatternLineEdit->setFocus();
|
|
}
|
|
|
|
void MessengerWindow::filterRegExpChanged()
|
|
{
|
|
|
|
QString text = ui.filterPatternLineEdit->text();
|
|
|
|
if (text.isEmpty()) {
|
|
ui.clearButton->hide();
|
|
} else {
|
|
ui.clearButton->show();
|
|
}
|
|
|
|
FilterItems();
|
|
}
|
|
|
|
void MessengerWindow::FilterItems()
|
|
{
|
|
QString sPattern = ui.filterPatternLineEdit->text();
|
|
|
|
int nCount = ui.messengertreeWidget->topLevelItemCount ();
|
|
for (int nIndex = 0; nIndex < nCount; nIndex++) {
|
|
FilterItem(ui.messengertreeWidget->topLevelItem(nIndex), sPattern);
|
|
}
|
|
|
|
QTreeWidgetItem *c = getCurrentPeer();
|
|
if (c && c->isHidden()) {
|
|
// active item is hidden, deselect it
|
|
ui.messengertreeWidget->setCurrentItem(NULL);
|
|
}
|
|
}
|
|
|
|
bool MessengerWindow::FilterItem(QTreeWidgetItem *pItem, QString &sPattern)
|
|
{
|
|
bool bVisible = true;
|
|
|
|
if (sPattern.isEmpty() == false) {
|
|
if (pItem->text(0).contains(sPattern, Qt::CaseInsensitive) == false) {
|
|
bVisible = false;
|
|
}
|
|
}
|
|
|
|
int nVisibleChildCount = 0;
|
|
int nCount = pItem->childCount();
|
|
for (int nIndex = 0; nIndex < nCount; nIndex++) {
|
|
if (FilterItem(pItem->child(nIndex), sPattern)) {
|
|
nVisibleChildCount++;
|
|
}
|
|
}
|
|
|
|
if (bVisible || nVisibleChildCount) {
|
|
pItem->setHidden(false);
|
|
} else {
|
|
pItem->setHidden(true);
|
|
}
|
|
|
|
return (bVisible || nVisibleChildCount);
|
|
}
|