mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
06fe72e0d8
Moved Info, About & Options to the Top ToolBar Moved Add Friend Button to Friends Dialog git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7311 b45a01b8-16f6-495d-af2f-9b41ad6348cc
911 lines
28 KiB
C++
911 lines
28 KiB
C++
/****************************************************************
|
|
* RetroShare is distributed under the following license:
|
|
*
|
|
* Copyright (C) 2006 - 2011 RetroShare Team
|
|
*
|
|
* 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 <time.h>
|
|
|
|
#include <QColorDialog>
|
|
#include <QDropEvent>
|
|
#include <QFontDialog>
|
|
#include <QMenu>
|
|
#include <QScrollBar>
|
|
#include <QTextStream>
|
|
#include <QTextCodec>
|
|
#include <QTimer>
|
|
#include <QMessageBox>
|
|
#include <QTextDocumentFragment>
|
|
|
|
#include "retroshare/rspeers.h"
|
|
#include <retroshare/rshistory.h>
|
|
|
|
#include "common/Emoticons.h"
|
|
#include "common/PeerDefs.h"
|
|
#include "chat/ChatUserNotify.h"
|
|
#include "connect/ConnectFriendWizard.h"
|
|
#include "groups/CreateGroup.h"
|
|
#include "im_history/ImHistoryBrowser.h"
|
|
#include "MainWindow.h"
|
|
#include "NewsFeed.h"
|
|
#include "notifyqt.h"
|
|
#include "profile/ProfileWidget.h"
|
|
#include "profile/StatusMessage.h"
|
|
#include "RetroShareLink.h"
|
|
#include "settings/rsharesettings.h"
|
|
#include "util/misc.h"
|
|
#include "util/HandleRichText.h"
|
|
#include "util/DateTime.h"
|
|
#include "FriendsDialog.h"
|
|
#include "NetworkView.h"
|
|
#include "NetworkDialog.h"
|
|
|
|
/* Images for Newsfeed icons */
|
|
#define IMAGE_NEWSFEED ""
|
|
#define IMAGE_NEWSFEED_NEW ":/images/message-state-new.png"
|
|
#define IMAGE_NETWORK2 ":/images/rs1.png"
|
|
#define IMAGE_PEERS ":/images/groupchat.png"
|
|
|
|
/******
|
|
* #define FRIENDS_DEBUG 1
|
|
*****/
|
|
|
|
static FriendsDialog *instance = NULL;
|
|
|
|
/** Constructor */
|
|
FriendsDialog::FriendsDialog(QWidget *parent)
|
|
: RsAutoUpdatePage(1500,parent)
|
|
{
|
|
/* Invoke the Qt Designer generated object setup routine */
|
|
ui.setupUi(this);
|
|
|
|
if (instance == NULL) {
|
|
instance = this;
|
|
}
|
|
|
|
last_status_send_time = 0 ;
|
|
inChatCharFormatChanged = false;
|
|
|
|
connect( ui.mypersonalstatusLabel, SIGNAL(clicked()), SLOT(statusmessage()));
|
|
connect( ui.actionSet_your_Avatar, SIGNAL(triggered()), this, SLOT(getAvatar()));
|
|
connect( ui.actionSet_your_Personal_Message, SIGNAL(triggered()), this, SLOT(statusmessage()));
|
|
connect( ui.addfileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile()));
|
|
connect( ui.actionAdd_Friend, SIGNAL(triggered()), this, SLOT(addFriend()));
|
|
|
|
ui.avatar->setFrameType(AvatarWidget::STATUS_FRAME);
|
|
ui.avatar->setOwnId();
|
|
|
|
ui.tabWidget->setTabPosition(QTabWidget::North);
|
|
ui.tabWidget->addTab(networkView = new NetworkView(),QIcon(IMAGE_NETWORK2), tr("Local network"));
|
|
ui.tabWidget->addTab(networkDialog = new NetworkDialog(),QIcon(IMAGE_PEERS), tr("Keyring"));
|
|
|
|
//ui.tabWidget->addTab(new ProfileWidget(), tr("Profile"));
|
|
//newsFeed = new NewsFeed();
|
|
//int newsFeedTabIndex = ui.tabWidget->insertTab(0, newsFeed, tr("News Feed"));
|
|
//ui.tabWidget->setCurrentIndex(newsFeedTabIndex);
|
|
|
|
ui.tabWidget->hideCloseButton(0);
|
|
ui.tabWidget->hideCloseButton(1);
|
|
ui.tabWidget->hideCloseButton(2);
|
|
ui.tabWidget->hideCloseButton(3);
|
|
|
|
/* get the current text and text color of the tab bar */
|
|
//newsFeedTabColor = ui.tabWidget->tabBar()->tabTextColor(newsFeedTabIndex);
|
|
//newsFeedText = ui.tabWidget->tabBar()->tabText(newsFeedTabIndex);
|
|
|
|
//connect(newsFeed, SIGNAL(newsFeedChanged(int)), this, SLOT(newsFeedChanged(int)));
|
|
|
|
connect(ui.Sendbtn, SIGNAL(clicked()), this, SLOT(sendMsg()));
|
|
connect(ui.emoticonBtn, SIGNAL(clicked()), this, SLOT(smileyWidgetgroupchat()));
|
|
|
|
connect(ui.msgText,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenuMsgText(QPoint)));
|
|
|
|
connect(ui.lineEdit,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
|
|
// reset text and color after removing all characters from the QTextEdit and after calling QTextEdit::clear
|
|
connect(ui.lineEdit, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this, SLOT(chatCharFormatChanged()));
|
|
|
|
connect(ui.textboldChatButton, SIGNAL(clicked()), this, SLOT(setFont()));
|
|
connect(ui.textunderlineChatButton, SIGNAL(clicked()), this, SLOT(setFont()));
|
|
connect(ui.textitalicChatButton, SIGNAL(clicked()), this, SLOT(setFont()));
|
|
connect(ui.fontsButton, SIGNAL(clicked()), this, SLOT(chooseFont()));
|
|
connect(ui.colorChatButton, SIGNAL(clicked()), this, SLOT(chooseColor()));
|
|
connect(ui.attachPictureButton, SIGNAL(clicked()), this, SLOT(addExtraPicture()));
|
|
connect(ui.actionSave_History, SIGNAL(triggered()), this, SLOT(fileSaveAs()));
|
|
|
|
connect(ui.hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
|
|
|
|
ui.fontsButton->setIcon(QIcon(QString(":/images/fonts.png")));
|
|
|
|
mCurrentColor = Qt::black;
|
|
mCurrentFont.fromString(Settings->getChatScreenFont());
|
|
|
|
colorChanged();
|
|
fontChanged();
|
|
setColorAndFont();
|
|
|
|
style.setStyleFromSettings(ChatStyle::TYPE_PUBLIC);
|
|
|
|
setChatInfo(tr("Retroshare broadcast chat: messages are sent to all connected friends."), QString::fromUtf8("blue"));
|
|
|
|
if (rsHistory->getEnable(true)) {
|
|
int messageCount = Settings->getPublicChatHistoryCount();
|
|
if (messageCount > 0) {
|
|
std::list<HistoryMsg> historyMsgs;
|
|
rsHistory->getMessages(RsPeerId(), historyMsgs, messageCount);
|
|
|
|
std::list<HistoryMsg>::iterator it;
|
|
for (it = historyMsgs.begin(); it != historyMsgs.end(); it++) {
|
|
addChatMsg(it->incoming, true, QString::fromUtf8(it->peerName.c_str()), QDateTime::fromTime_t(it->sendTime), QDateTime::fromTime_t(it->recvTime), QString::fromUtf8(it->message.c_str()));
|
|
}
|
|
}
|
|
}
|
|
|
|
QMenu *menu = new QMenu();
|
|
menu->addAction(ui.actionClear_Chat_History);
|
|
menu->addAction(ui.actionDelete_Chat_History);
|
|
menu->addAction(ui.actionSave_History);
|
|
menu->addAction(ui.actionMessageHistory);
|
|
ui.menuButton->setMenu(menu);
|
|
|
|
// menu = new QMenu();
|
|
// menu->addAction(ui.actionAdd_Friend);
|
|
// menu->addAction(ui.actionAdd_Group);
|
|
// menu->addAction(ui.actionCreate_new_Chat_lobby);
|
|
//
|
|
// menu->addSeparator();
|
|
// menu->addAction(ui.actionSet_your_Avatar);
|
|
// menu->addAction(ui.actionSet_your_Personal_Message);
|
|
//
|
|
// ui.menutoolButton->setMenu(menu);
|
|
|
|
QToolButton *addFriendButton = new QToolButton(this);
|
|
addFriendButton->setIcon(QIcon(":/images/user/add_user24.png"));
|
|
addFriendButton->setToolTip(tr("Add Friend"));
|
|
connect(addFriendButton, SIGNAL(clicked()), this, SLOT(addFriend()));
|
|
ui.friendList->addToolButton(addFriendButton);
|
|
|
|
setAcceptDrops(true);
|
|
ui.lineEdit->setAcceptDrops(false);
|
|
ui.hashBox->setDropWidget(this);
|
|
ui.hashBox->setAutoHide(true);
|
|
|
|
/* Set initial size the splitter */
|
|
QList<int> sizes;
|
|
sizes << height() << 100; // Qt calculates the right sizes
|
|
ui.splitter_2->setSizes(sizes);
|
|
|
|
loadmypersonalstatus();
|
|
|
|
// load settings
|
|
RsAutoUpdatePage::lockAllEvents();
|
|
ui.friendList->setShowStatusColumn(true);
|
|
ui.friendList->setShowLastContactColumn(false);
|
|
ui.friendList->setShowAvatarColumn(false);
|
|
ui.friendList->setShowIPColumn(false);
|
|
ui.friendList->setRootIsDecorated(true);
|
|
ui.friendList->setShowGroups(true);
|
|
processSettings(true);
|
|
RsAutoUpdatePage::unlockAllEvents();
|
|
|
|
ui.lineEdit->installEventFilter(this);
|
|
|
|
// add self nick and Avatar to Friends.
|
|
RsPeerDetails pd ;
|
|
if (rsPeers->getPeerDetails(rsPeers->getOwnId(),pd)) {
|
|
ui.nicknameLabel->setText(PeerDefs::nameWithLocation(pd));
|
|
}
|
|
|
|
QString hlp_str = tr(
|
|
" <h1><img width=\"32\" src=\":/images/64px_help.png\"> Friends</h1> \
|
|
<p>The Friends tab shows...your friends: the list of persons you have accepted to connect to. \
|
|
</p> \
|
|
<p>You can group friends together to allow a finer level of information access, for instance to only allow \
|
|
some friends to see some files.</p> \
|
|
<p>On the right, you will find 3 useful tabs: \
|
|
<ul> \
|
|
<li>Broadcast sends messages to all connected friends at once</li> \
|
|
<li>Local Network shows the network around you, including friends of your friends</li> \
|
|
<li>Keyring contains keys you collected, mostly forwarded to you by your friends</li> \
|
|
</ul> </p> \
|
|
") ;
|
|
|
|
registerHelpButton(ui.helpButton, hlp_str) ;
|
|
|
|
/* Hide platform specific features */
|
|
#ifdef Q_WS_WIN
|
|
|
|
#endif
|
|
|
|
#if QT_VERSION < 0x040700
|
|
// embedded images are not supported before QT 4.7.0
|
|
ui.attachPictureButton->setVisible(false);
|
|
#endif
|
|
}
|
|
|
|
FriendsDialog::~FriendsDialog ()
|
|
{
|
|
// save settings
|
|
processSettings(false);
|
|
|
|
if (this == instance) {
|
|
instance = NULL;
|
|
}
|
|
}
|
|
|
|
void FriendsDialog::activatePage(FriendsDialog::Page page)
|
|
{
|
|
switch(page)
|
|
{
|
|
case FriendsDialog::NetworkTab: ui.tabWidget->setCurrentWidget(networkDialog) ;
|
|
break ;
|
|
case FriendsDialog::BroadcastTab: ui.tabWidget->setCurrentWidget(networkDialog) ;
|
|
break ;
|
|
case FriendsDialog::NetworkViewTab: ui.tabWidget->setCurrentWidget(networkView) ;
|
|
break ;
|
|
}
|
|
}
|
|
|
|
UserNotify *FriendsDialog::getUserNotify(QObject *parent)
|
|
{
|
|
return new ChatUserNotify(parent);
|
|
}
|
|
|
|
void FriendsDialog::processSettings(bool bLoad)
|
|
{
|
|
Settings->beginGroup(QString("FriendsDialog"));
|
|
|
|
if (bLoad) {
|
|
// load settings
|
|
|
|
// state of splitter
|
|
ui.splitter->restoreState(Settings->value("Splitter").toByteArray());
|
|
ui.splitter_2->restoreState(Settings->value("GroupChatSplitter").toByteArray());
|
|
} else {
|
|
// save settings
|
|
|
|
// state of splitter
|
|
Settings->setValue("Splitter", ui.splitter->saveState());
|
|
Settings->setValue("GroupChatSplitter", ui.splitter_2->saveState());
|
|
}
|
|
|
|
ui.friendList->processSettings(bLoad);
|
|
|
|
Settings->endGroup();
|
|
}
|
|
|
|
void FriendsDialog::showEvent(QShowEvent *event)
|
|
{
|
|
static bool first = true;
|
|
if (first) {
|
|
// Workaround: now the scroll position is correct calculated
|
|
first = false;
|
|
QScrollBar *scrollbar = ui.msgText->verticalScrollBar();
|
|
scrollbar->setValue(scrollbar->maximum());
|
|
}
|
|
|
|
RsAutoUpdatePage::showEvent(event);
|
|
}
|
|
|
|
void FriendsDialog::pasteLink()
|
|
{
|
|
ui.lineEdit->insertHtml(RSLinkClipboard::toHtml()) ;
|
|
}
|
|
|
|
void FriendsDialog::contextMenuMsgText(QPoint point)
|
|
{
|
|
QMatrix matrix;
|
|
matrix.translate(ui.msgText->horizontalScrollBar()->value(), ui.msgText->verticalScrollBar()->value());
|
|
|
|
QMenu *contextMnu = ui.msgText->createStandardContextMenu(matrix.map(point));
|
|
|
|
contextMnu->addSeparator();
|
|
contextMnu->addAction(ui.actionClear_Chat_History);
|
|
|
|
contextMnu->exec(ui.msgText->viewport()->mapToGlobal(point));
|
|
delete(contextMnu);
|
|
}
|
|
|
|
void FriendsDialog::contextMenu(QPoint point)
|
|
{
|
|
QMenu *contextMnu = ui.lineEdit->createStandardContextMenu(point);
|
|
|
|
contextMnu->addSeparator();
|
|
QAction *action = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink()));
|
|
action->setDisabled(RSLinkClipboard::empty());
|
|
|
|
contextMnu->exec(QCursor::pos());
|
|
delete(contextMnu);
|
|
}
|
|
|
|
void FriendsDialog::chatCharFormatChanged()
|
|
{
|
|
if (inChatCharFormatChanged) {
|
|
return;
|
|
}
|
|
|
|
inChatCharFormatChanged = true;
|
|
|
|
// Reset font and color before inserting a character if edit box is empty
|
|
// (color info disappears when the user deletes all text)
|
|
if (ui.lineEdit->toPlainText().isEmpty()) {
|
|
setColorAndFont();
|
|
}
|
|
|
|
inChatCharFormatChanged = false;
|
|
}
|
|
|
|
void FriendsDialog::updateDisplay()
|
|
{
|
|
}
|
|
|
|
void FriendsDialog::addFriend()
|
|
{
|
|
std::string groupId = ui.friendList->getSelectedGroupId();
|
|
|
|
ConnectFriendWizard connwiz (this);
|
|
|
|
if (groupId.empty() == false) {
|
|
connwiz.setGroup(groupId);
|
|
}
|
|
|
|
connwiz.exec ();
|
|
}
|
|
|
|
void FriendsDialog::resetStatusBar()
|
|
{
|
|
#ifdef FRIENDS_DEBUG
|
|
std::cerr << "FriendsDialog: reseting status bar." << std::endl ;
|
|
#endif
|
|
|
|
ui.statusStringLabel->setText(QString("")) ;
|
|
}
|
|
|
|
void FriendsDialog::updateStatusTyping()
|
|
{
|
|
if(time(NULL) - last_status_send_time > 5) // limit 'peer is typing' packets to at most every 10 sec
|
|
{
|
|
#ifdef FRIENDS_DEBUG
|
|
std::cerr << "FriendsDialog: sending group chat typing info." << std::endl ;
|
|
#endif
|
|
|
|
#ifdef ONLY_FOR_LINGUIST
|
|
tr("is typing...");
|
|
#endif
|
|
|
|
rsMsgs->sendGroupChatStatusString("is typing...");
|
|
last_status_send_time = time(NULL) ;
|
|
}
|
|
}
|
|
|
|
// Called by libretroshare through notifyQt to display the peer's status
|
|
//
|
|
void FriendsDialog::updateStatusString(const QString& peer_id, const QString& status_string)
|
|
{
|
|
#ifdef FRIENDS_DEBUG
|
|
std::cerr << "FriendsDialog: received group chat typing info. updating gui." << std::endl ;
|
|
#endif
|
|
|
|
QString status = QString::fromUtf8(rsPeers->getPeerName(RsPeerId(peer_id.toStdString())).c_str()) + " " + tr(status_string.toLatin1());
|
|
ui.statusStringLabel->setText(status) ; // displays info for 5 secs.
|
|
|
|
QTimer::singleShot(5000,this,SLOT(resetStatusBar())) ;
|
|
}
|
|
|
|
void FriendsDialog::updatePeerStatusString(const QString& peer_id,const QString& status_string,bool is_private_chat)
|
|
{
|
|
if (!is_private_chat) {
|
|
#ifdef FRIENDS_DEBUG
|
|
std::cerr << "Updating public chat msg from peer " << rsPeers->getPeerName(peer_id.toStdString()) << ": " << status_string.toStdString() << std::endl ;
|
|
#endif
|
|
|
|
updateStatusString(peer_id, status_string);
|
|
}
|
|
}
|
|
|
|
void FriendsDialog::publicChatChanged(int type)
|
|
{
|
|
if (type == NOTIFY_TYPE_ADD) {
|
|
insertChat();
|
|
}
|
|
}
|
|
|
|
void FriendsDialog::addChatMsg(bool incoming, bool history, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message)
|
|
{
|
|
unsigned int formatTextFlag = RSHTML_FORMATTEXT_EMBED_LINKS | RSHTML_FORMATTEXT_OPTIMIZE;
|
|
|
|
// embed smileys ?
|
|
if (Settings->valueFromGroup("Chat", "Emoteicons_GroupChat", true).toBool()) {
|
|
formatTextFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS;
|
|
}
|
|
|
|
// Always fix colors
|
|
formatTextFlag |= RSHTML_FORMATTEXT_FIX_COLORS;
|
|
qreal desiredContrast = Settings->valueFromGroup("Chat", "MinimumContrast", 4.5).toDouble();
|
|
QColor backgroundColor = ui.groupChatTab->palette().base().color();
|
|
|
|
// Remove font name, size, bold, italics?
|
|
if (!Settings->valueFromGroup("Chat", "EnableCustomFonts", true).toBool()) {
|
|
formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY;
|
|
}
|
|
if (!Settings->valueFromGroup("Chat", "EnableCustomFontSize", true).toBool()) {
|
|
formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_SIZE;
|
|
}
|
|
if (!Settings->valueFromGroup("Chat", "EnableBold", true).toBool()) {
|
|
formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT;
|
|
}
|
|
if (!Settings->valueFromGroup("Chat", "EnableItalics", true).toBool()) {
|
|
formatTextFlag |= RSHTML_FORMATTEXT_REMOVE_FONT_STYLE;
|
|
}
|
|
|
|
ChatStyle::enumFormatMessage type;
|
|
if (incoming) {
|
|
if (history) {
|
|
type = ChatStyle::FORMATMSG_HINCOMING;
|
|
} else {
|
|
type = ChatStyle::FORMATMSG_INCOMING;
|
|
}
|
|
} else {
|
|
if (history) {
|
|
type = ChatStyle::FORMATMSG_HOUTGOING;
|
|
} else {
|
|
type = ChatStyle::FORMATMSG_OUTGOING;
|
|
}
|
|
}
|
|
|
|
QString formattedMessage = RsHtml().formatText(ui.msgText->document(), message, formatTextFlag, backgroundColor, desiredContrast);
|
|
QString formatMsg = style.formatMessage(type, name, incoming ? recvTime : sendTime, formattedMessage);
|
|
|
|
ui.msgText->append(formatMsg);
|
|
}
|
|
|
|
void FriendsDialog::insertChat()
|
|
{
|
|
std::list<ChatInfo> newchat;
|
|
if (!rsMsgs->getPublicChatQueue(newchat))
|
|
{
|
|
#ifdef FRIENDS_DEBUG
|
|
std::cerr << "no chat available." << std::endl ;
|
|
#endif
|
|
return;
|
|
}
|
|
#ifdef FRIENDS_DEBUG
|
|
std::cerr << "got new chat." << std::endl;
|
|
#endif
|
|
std::list<ChatInfo>::iterator it;
|
|
|
|
/* add in lines at the bottom */
|
|
for(it = newchat.begin(); it != newchat.end(); it++)
|
|
{
|
|
/* are they private? */
|
|
if (it->chatflags & RS_CHAT_PRIVATE)
|
|
{
|
|
/* this should not happen */
|
|
continue;
|
|
}
|
|
|
|
QDateTime sendTime = QDateTime::fromTime_t(it->sendTime);
|
|
QDateTime recvTime = QDateTime::fromTime_t(it->recvTime);
|
|
QString name = QString::fromUtf8(rsPeers->getPeerName(it->rsid).c_str());
|
|
QString msg = QString::fromUtf8(it->msg.c_str());
|
|
|
|
#ifdef FRIENDS_DEBUG
|
|
std::cerr << "FriendsDialog::insertChat(): " << msg.toStdString() << std::endl;
|
|
#endif
|
|
|
|
bool incoming = false;
|
|
|
|
// notify with a systray icon msg
|
|
if(it->rsid != rsPeers->getOwnId())
|
|
{
|
|
incoming = true;
|
|
|
|
// This is a trick to translate HTML into text.
|
|
QTextEdit editor;
|
|
editor.setHtml(msg);
|
|
QString notifyMsg = name + ": " + editor.toPlainText();
|
|
|
|
if(notifyMsg.length() > 30)
|
|
emit notifyGroupChat(tr("New group chat"), notifyMsg.left(30) + QString("..."));
|
|
else
|
|
emit notifyGroupChat(tr("New group chat"), notifyMsg);
|
|
}
|
|
|
|
addChatMsg(incoming, false, name, sendTime, recvTime, msg);
|
|
}
|
|
}
|
|
|
|
bool FriendsDialog::eventFilter(QObject *obj, QEvent *event)
|
|
{
|
|
if (obj == ui.lineEdit) {
|
|
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
|
|
sendMsg();
|
|
return true; // eat event
|
|
}
|
|
} else {
|
|
if (keyEvent->modifiers() & Qt::ControlModifier) {
|
|
// insert return
|
|
ui.lineEdit->textCursor().insertText("\n");
|
|
} else {
|
|
// send message with Enter
|
|
sendMsg();
|
|
}
|
|
return true; // eat event
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// pass the event on to the parent class
|
|
return RsAutoUpdatePage::eventFilter(obj, event);
|
|
}
|
|
|
|
void FriendsDialog::sendMsg()
|
|
{
|
|
QTextEdit *lineWidget = ui.lineEdit;
|
|
|
|
if (lineWidget->toPlainText().isEmpty()) {
|
|
// nothing to send
|
|
return;
|
|
}
|
|
|
|
QString text;
|
|
RsHtml::optimizeHtml(lineWidget, text);
|
|
std::string message = text.toUtf8().constData();
|
|
|
|
#ifdef FRIENDS_DEBUG
|
|
std::string msg(message.begin(), message.end());
|
|
std::cerr << "FriendsDialog::sendMsg(): " << msg << std::endl;
|
|
#endif
|
|
|
|
rsMsgs->sendPublicChat(message);
|
|
ui.lineEdit->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.
|
|
ui.lineEdit->setCurrentCharFormat(QTextCharFormat ());
|
|
|
|
/* redraw send list */
|
|
insertSendList();
|
|
}
|
|
|
|
void FriendsDialog::insertSendList()
|
|
{
|
|
#ifdef false
|
|
std::list<std::string> peers;
|
|
std::list<std::string>::iterator it;
|
|
|
|
if (!rsPeers)
|
|
{
|
|
/* not ready yet! */
|
|
return;
|
|
}
|
|
|
|
rsPeers->getOnlineList(peers);
|
|
|
|
/* get a link to the table */
|
|
//QTreeWidget *sendWidget = ui.msgSendList;
|
|
QList<QTreeWidgetItem *> items;
|
|
|
|
for(it = peers.begin(); it != peers.end(); it++)
|
|
{
|
|
|
|
RsPeerDetails details;
|
|
if (!rsPeers->getPeerDetails(*it, details))
|
|
{
|
|
continue; /* BAD */
|
|
}
|
|
|
|
/* make a widget per friend */
|
|
QTreeWidgetItem *item = new QTreeWidgetItem((QTreeWidget*)0);
|
|
|
|
/* add all the labels */
|
|
/* (0) Person */
|
|
item -> setText(0, QString::fromStdString(details.name));
|
|
|
|
item -> setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
|
|
//item -> setFlags(Qt::ItemIsUserCheckable);
|
|
|
|
item -> setCheckState(0, Qt::Checked);
|
|
|
|
if (rsicontrol->IsInChat(*it))
|
|
{
|
|
item -> setCheckState(0, Qt::Checked);
|
|
}
|
|
else
|
|
{
|
|
item -> setCheckState(0, Qt::Unchecked);
|
|
}
|
|
|
|
/* disable for the moment */
|
|
item -> setFlags(Qt::ItemIsUserCheckable);
|
|
item -> setCheckState(0, Qt::Checked);
|
|
|
|
/* add to the list */
|
|
items.append(item);
|
|
}
|
|
|
|
/* remove old items */
|
|
//sendWidget->clear();
|
|
//sendWidget->setColumnCount(1);
|
|
|
|
/* add the items in! */
|
|
//sendWidget->insertTopLevelItems(0, items);
|
|
|
|
//sendWidget->update(); /* update display */
|
|
#endif
|
|
}
|
|
|
|
|
|
/* to toggle the state */
|
|
|
|
|
|
//void FriendsDialog::toggleSendItem( QTreeWidgetItem *item, int col )
|
|
//{
|
|
//#ifdef FRIENDS_DEBUG
|
|
// std::cerr << "ToggleSendItem()" << std::endl;
|
|
//#endif
|
|
//
|
|
// /* extract id */
|
|
// std::string id = (item -> text(4)).toStdString();
|
|
//
|
|
// /* get state */
|
|
// bool inChat = (Qt::Checked == item -> checkState(0)); /* alway column 0 */
|
|
//
|
|
// /* call control fns */
|
|
//
|
|
// rsicontrol -> SetInChat(id, inChat);
|
|
// return;
|
|
//}
|
|
|
|
//============================================================================
|
|
|
|
void FriendsDialog::chooseColor()
|
|
{
|
|
bool ok;
|
|
QRgb color = QColorDialog::getRgba(ui.lineEdit->textColor().rgba(), &ok, this);
|
|
if (ok) {
|
|
mCurrentColor = QColor(color);
|
|
colorChanged();
|
|
setColorAndFont();
|
|
}
|
|
}
|
|
|
|
void FriendsDialog::colorChanged()
|
|
{
|
|
QPixmap pxm(16,16);
|
|
pxm.fill(mCurrentColor);
|
|
ui.colorChatButton->setIcon(pxm);
|
|
}
|
|
|
|
void FriendsDialog::chooseFont()
|
|
{
|
|
bool ok;
|
|
QFont font = QFontDialog::getFont(&ok, mCurrentFont, this);
|
|
if (ok) {
|
|
mCurrentFont = font;
|
|
fontChanged();
|
|
setFont();
|
|
}
|
|
}
|
|
|
|
void FriendsDialog::fontChanged()
|
|
{
|
|
ui.textboldChatButton->setChecked(mCurrentFont.bold());
|
|
ui.textunderlineChatButton->setChecked(mCurrentFont.underline());
|
|
ui.textitalicChatButton->setChecked(mCurrentFont.italic());
|
|
}
|
|
|
|
void FriendsDialog::setColorAndFont()
|
|
{
|
|
mCurrentFont.setBold(ui.textboldChatButton->isChecked());
|
|
mCurrentFont.setUnderline(ui.textunderlineChatButton->isChecked());
|
|
mCurrentFont.setItalic(ui.textitalicChatButton->isChecked());
|
|
|
|
ui.lineEdit->setFont(mCurrentFont);
|
|
ui.lineEdit->setTextColor(mCurrentColor);
|
|
|
|
ui.lineEdit->setFocus();
|
|
}
|
|
|
|
void FriendsDialog::setFont()
|
|
{
|
|
setColorAndFont();
|
|
Settings->setChatScreenFont(mCurrentFont.toString());
|
|
}
|
|
|
|
// Update Chat Info information
|
|
void FriendsDialog::setChatInfo(QString info, QColor color)
|
|
{
|
|
static unsigned int nbLines = 0;
|
|
++nbLines;
|
|
// Check log size, clear it if too big
|
|
if(nbLines > 200) {
|
|
ui.msgText->clear();
|
|
nbLines = 1;
|
|
}
|
|
ui.msgText->append("<font color='grey'>" + DateTime::formatTime(QTime::currentTime()) + "</font> - <font color='" + color.name() + "'><i>" + info + "</i></font>");
|
|
}
|
|
|
|
void FriendsDialog::on_actionClear_Chat_History_triggered()
|
|
{
|
|
ui.msgText->clear();
|
|
}
|
|
|
|
void FriendsDialog::on_actionDelete_Chat_History_triggered()
|
|
{
|
|
if ((QMessageBox::question(this, "RetroShare", tr("Do you really want to physically delete the history?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) == QMessageBox::Yes) {
|
|
on_actionClear_Chat_History_triggered();
|
|
rsHistory->clear(RsPeerId());
|
|
}
|
|
}
|
|
|
|
void FriendsDialog::smileyWidgetgroupchat()
|
|
{
|
|
Emoticons::showSmileyWidget(this, ui.emoticonBtn, SLOT(addSmileys()), true);
|
|
}
|
|
|
|
void FriendsDialog::addSmileys()
|
|
{
|
|
ui.lineEdit->textCursor().insertText(qobject_cast<QPushButton*>(sender())->toolTip().split("|").first());
|
|
}
|
|
|
|
void FriendsDialog::getAvatar()
|
|
{
|
|
QByteArray ba;
|
|
if (misc::getOpenAvatarPicture(this, ba))
|
|
{
|
|
#ifdef FRIENDS_DEBUG
|
|
std::cerr << "Avatar image size = " << ba.size() << std::endl ;
|
|
#endif
|
|
|
|
rsMsgs->setOwnAvatarData((unsigned char *)(ba.data()), ba.size()) ; // last char 0 included.
|
|
}
|
|
}
|
|
|
|
/** Loads own personal status */
|
|
void FriendsDialog::loadmypersonalstatus()
|
|
{
|
|
ui.mypersonalstatusLabel->setText(QString::fromUtf8(rsMsgs->getCustomStateString().c_str()));
|
|
}
|
|
|
|
void FriendsDialog::statusmessage()
|
|
{
|
|
StatusMessage statusmsgdialog (this);
|
|
statusmsgdialog.exec();
|
|
}
|
|
|
|
void FriendsDialog::addExtraFile()
|
|
{
|
|
QStringList files;
|
|
if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) {
|
|
ui.hashBox->addAttachments(files,TransferRequestFlags(0u)); // no anonymous routing, because it is for friends only!
|
|
}
|
|
}
|
|
|
|
void FriendsDialog::addExtraPicture()
|
|
{
|
|
// select a picture file
|
|
QString file;
|
|
if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg)", file)) {
|
|
QString encodedImage;
|
|
if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480)) {
|
|
QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage);
|
|
ui.lineEdit->textCursor().insertFragment(fragment);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FriendsDialog::fileHashingFinished(QList<HashedFile> hashedFiles)
|
|
{
|
|
std::cerr << "FriendsDialog::fileHashingFinished() started." << std::endl;
|
|
|
|
QString mesgString;
|
|
|
|
QList<HashedFile>::iterator it;
|
|
for (it = hashedFiles.begin(); it != hashedFiles.end(); ++it) {
|
|
HashedFile& hashedFile = *it;
|
|
RetroShareLink link;
|
|
|
|
if (!link.createExtraFile(hashedFile.filename, hashedFile.size, QString::fromStdString(hashedFile.hash.toStdString()),QString::fromStdString(rsPeers->getOwnId().toStdString())))
|
|
continue;
|
|
|
|
mesgString += link.toHtmlSize();
|
|
if (it!= hashedFiles.end()) {
|
|
mesgString += "<BR>";
|
|
}
|
|
}
|
|
|
|
#ifdef FRIENDS_DEBUG
|
|
std::cerr << "FriendsDialog::fileHashingFinished mesgString : " << mesgString.toStdString() << std::endl;
|
|
#endif
|
|
|
|
ui.lineEdit->insertHtml(mesgString);
|
|
}
|
|
|
|
bool FriendsDialog::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.msgText->document()->toPlainText();
|
|
ui.msgText->document()->setModified(false);
|
|
return true;
|
|
}
|
|
|
|
bool FriendsDialog::fileSaveAs()
|
|
{
|
|
QString fn;
|
|
if (misc::getSaveFileName(this, RshareSettings::LASTDIR_HISTORY, tr("Save as..."), tr("Text File (*.txt );;All Files (*)"), fn)) {
|
|
setCurrentFileName(fn);
|
|
return fileSave();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FriendsDialog::setCurrentFileName(const QString &fileName)
|
|
{
|
|
this->fileName = fileName;
|
|
ui.msgText->document()->setModified(false);
|
|
|
|
setWindowModified(false);
|
|
}
|
|
|
|
void FriendsDialog::on_actionMessageHistory_triggered()
|
|
{
|
|
ImHistoryBrowser imBrowser(RsPeerId(), ui.lineEdit, this);
|
|
imBrowser.exec();
|
|
}
|
|
|
|
/*static*/ bool FriendsDialog::isGroupChatActive()
|
|
{
|
|
FriendsDialog *friendsDialog = dynamic_cast<FriendsDialog*>(MainWindow::getPage(MainWindow::Friends));
|
|
if (!friendsDialog) {
|
|
return false;
|
|
}
|
|
|
|
if (friendsDialog->ui.tabWidget->currentWidget() == friendsDialog->ui.groupChatTab) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*static*/ void FriendsDialog::groupChatActivate()
|
|
{
|
|
FriendsDialog *friendsDialog = dynamic_cast<FriendsDialog*>(MainWindow::getPage(MainWindow::Friends));
|
|
if (!friendsDialog) {
|
|
return;
|
|
}
|
|
|
|
MainWindow::showWindow(MainWindow::Friends);
|
|
friendsDialog->ui.tabWidget->setCurrentWidget(friendsDialog->ui.groupChatTab);
|
|
friendsDialog->ui.lineEdit->setFocus();
|
|
}
|