mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Moved the chat history into the libretroshare.
Now the history is saved encrypted. Please delete all files with "chat*.xml" in your profile folder. Added new config p3HistoryMgr and interface p3History. Added new option to limit the count of the saved history items. Added new simple html optimizer "RsHtml::optimizeHtml" to reduce the size of the html strings. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4623 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
c6a68fe05e
commit
29c090fb44
@ -139,6 +139,7 @@ PUBLIC_HEADERS = retroshare/rsblogs.h \
|
||||
retroshare/rsexpr.h \
|
||||
retroshare/rsfiles.h \
|
||||
retroshare/rsforums.h \
|
||||
retroshare/rshistory.h \
|
||||
retroshare/rsiface.h \
|
||||
retroshare/rsinit.h \
|
||||
retroshare/rsplugin.h \
|
||||
@ -368,6 +369,7 @@ HEADERS += pqi/authssl.h \
|
||||
pqi/pqibin.h \
|
||||
pqi/pqihandler.h \
|
||||
pqi/pqihash.h \
|
||||
pqi/p3historymgr.h \
|
||||
pqi/pqiindic.h \
|
||||
pqi/pqiipset.h \
|
||||
pqi/pqilistener.h \
|
||||
@ -391,6 +393,7 @@ HEADERS += pqi/authssl.h \
|
||||
|
||||
HEADERS += rsserver/p3discovery.h \
|
||||
rsserver/p3face.h \
|
||||
rsserver/p3history.h \
|
||||
rsserver/p3msgs.h \
|
||||
rsserver/p3peers.h \
|
||||
rsserver/p3photo.h \
|
||||
@ -406,6 +409,7 @@ HEADERS += serialiser/rsbaseitems.h \
|
||||
serialiser/rsdistribitems.h \
|
||||
serialiser/rsforumitems.h \
|
||||
serialiser/rsgameitems.h \
|
||||
serialiser/rshistoryitems.h \
|
||||
serialiser/rsmsgitems.h \
|
||||
serialiser/rsphotoitems.h \
|
||||
serialiser/rsserial.h \
|
||||
@ -490,6 +494,7 @@ SOURCES += pqi/authgpg.cc \
|
||||
pqi/pqiarchive.cc \
|
||||
pqi/pqibin.cc \
|
||||
pqi/pqihandler.cc \
|
||||
pqi/p3historymgr.cc \
|
||||
pqi/pqiipset.cc \
|
||||
pqi/pqiloopback.cc \
|
||||
pqi/pqimonitor.cc \
|
||||
@ -512,6 +517,7 @@ SOURCES += rsserver/p3discovery.cc \
|
||||
rsserver/p3face-config.cc \
|
||||
rsserver/p3face-msgs.cc \
|
||||
rsserver/p3face-server.cc \
|
||||
rsserver/p3history.cc \
|
||||
rsserver/p3msgs.cc \
|
||||
rsserver/p3peers.cc \
|
||||
rsserver/p3photo.cc \
|
||||
@ -535,6 +541,7 @@ SOURCES += serialiser/rsbaseitems.cc \
|
||||
serialiser/rsdistribitems.cc \
|
||||
serialiser/rsforumitems.cc \
|
||||
serialiser/rsgameitems.cc \
|
||||
serialiser/rshistoryitems.cc \
|
||||
serialiser/rsmsgitems.cc \
|
||||
serialiser/rsphotoitems.cc \
|
||||
serialiser/rsserial.cc \
|
||||
|
@ -81,6 +81,7 @@ const uint32_t CONFIG_TYPE_AUTHSSL = 0x000C;
|
||||
const uint32_t CONFIG_TYPE_CHAT = 0x0012;
|
||||
const uint32_t CONFIG_TYPE_STATUS = 0x0013;
|
||||
const uint32_t CONFIG_TYPE_PLUGINS = 0x0014;
|
||||
const uint32_t CONFIG_TYPE_HISTORY = 0x0015;
|
||||
|
||||
/// turtle router
|
||||
const uint32_t CONFIG_TYPE_TURTLE = 0x0020;
|
||||
|
417
libretroshare/src/pqi/p3historymgr.cc
Normal file
417
libretroshare/src/pqi/p3historymgr.cc
Normal file
@ -0,0 +1,417 @@
|
||||
/*
|
||||
* libretroshare/src/services: p3HistoryMgr.cc
|
||||
*
|
||||
* RetroShare C++ .
|
||||
*
|
||||
* Copyright 2011 by Thunder.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "p3historymgr.h"
|
||||
#include "serialiser/rshistoryitems.h"
|
||||
#include "serialiser/rsconfigitems.h"
|
||||
#include "retroshare/rsiface.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
#include "serialiser/rsmsgitems.h"
|
||||
|
||||
RsHistory *rsHistory = NULL;
|
||||
|
||||
p3HistoryMgr::p3HistoryMgr()
|
||||
: p3Config(CONFIG_TYPE_HISTORY), mHistoryMtx("p3HistoryMgr")
|
||||
{
|
||||
nextMsgId = 1;
|
||||
|
||||
mPublicEnable = false;
|
||||
mPrivateEnable = true;
|
||||
|
||||
mPublicSaveCount = 0;
|
||||
mPrivateSaveCount = 0;
|
||||
}
|
||||
|
||||
p3HistoryMgr::~p3HistoryMgr()
|
||||
{
|
||||
}
|
||||
|
||||
/***** p3HistoryMgr *****/
|
||||
|
||||
void p3HistoryMgr::addMessage(bool incoming, const std::string &chatPeerId, const std::string &peerId, const RsChatMsgItem *chatItem)
|
||||
{
|
||||
RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
if (mPublicEnable == false && chatPeerId.empty()) {
|
||||
// public chat not enabled
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPrivateEnable == false && chatPeerId.empty() == false) {
|
||||
// private chat not enabled
|
||||
return;
|
||||
}
|
||||
|
||||
RsHistoryMsgItem* item = new RsHistoryMsgItem;
|
||||
item->chatPeerId = chatPeerId;
|
||||
item->incoming = incoming;
|
||||
item->peerId = peerId;
|
||||
item->peerName = rsPeers->getPeerName(item->peerId);
|
||||
item->sendTime = chatItem->sendTime;
|
||||
item->recvTime = chatItem->recvTime;
|
||||
item->message.assign(chatItem->message.begin(), chatItem->message.end());
|
||||
|
||||
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit = mMessages.find(item->chatPeerId);
|
||||
if (mit != mMessages.end()) {
|
||||
item->msgId = nextMsgId++;
|
||||
mit->second.insert(std::make_pair(item->msgId, item));
|
||||
|
||||
// check the limit
|
||||
uint32_t limit;
|
||||
if (chatPeerId.empty()) {
|
||||
limit = mPublicSaveCount;
|
||||
} else {
|
||||
limit = mPrivateSaveCount;
|
||||
}
|
||||
|
||||
if (limit) {
|
||||
while (mit->second.size() > limit) {
|
||||
delete(mit->second.begin()->second);
|
||||
mit->second.erase(mit->second.begin());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::map<uint32_t, RsHistoryMsgItem*> msgs;
|
||||
item->msgId = nextMsgId++;
|
||||
msgs.insert(std::make_pair(item->msgId, item));
|
||||
mMessages.insert(std::make_pair(item->chatPeerId, msgs));
|
||||
|
||||
// no need to check the limit
|
||||
}
|
||||
|
||||
IndicateConfigChanged();
|
||||
|
||||
rsicontrol->getNotify().notifyHistoryChanged(item->msgId, NOTIFY_TYPE_ADD);
|
||||
}
|
||||
|
||||
/***** p3Config *****/
|
||||
|
||||
RsSerialiser* p3HistoryMgr::setupSerialiser()
|
||||
{
|
||||
RsSerialiser *rss = new RsSerialiser;
|
||||
rss->addSerialType(new RsHistorySerialiser);
|
||||
rss->addSerialType(new RsGeneralConfigSerialiser());
|
||||
|
||||
return rss;
|
||||
}
|
||||
|
||||
bool p3HistoryMgr::saveList(bool& cleanup, std::list<RsItem*>& saveData)
|
||||
{
|
||||
cleanup = false;
|
||||
|
||||
mHistoryMtx.lock(); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit;
|
||||
std::map<uint32_t, RsHistoryMsgItem*>::iterator lit;
|
||||
for (mit = mMessages.begin(); mit != mMessages.end(); mit++) {
|
||||
for (lit = mit->second.begin(); lit != mit->second.end(); lit++) {
|
||||
saveData.push_back(lit->second);
|
||||
}
|
||||
}
|
||||
|
||||
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet;
|
||||
|
||||
RsTlvKeyValue kv;
|
||||
kv.key = "PUBLIC_ENABLE";
|
||||
kv.value = mPublicEnable ? "TRUE" : "FALSE";
|
||||
vitem->tlvkvs.pairs.push_back(kv);
|
||||
|
||||
kv.key = "PRIVATE_ENABLE";
|
||||
kv.value = mPrivateEnable ? "TRUE" : "FALSE";
|
||||
vitem->tlvkvs.pairs.push_back(kv);
|
||||
|
||||
kv.key = "PUBLIC_SAVECOUNT";
|
||||
std::ostringstream s1;
|
||||
s1 << mPublicSaveCount;
|
||||
kv.value = s1.str();
|
||||
vitem->tlvkvs.pairs.push_back(kv);
|
||||
|
||||
kv.key = "PRIVATE_SAVECOUNT";
|
||||
std::ostringstream s2;
|
||||
s2 << mPrivateSaveCount;
|
||||
kv.value = s2.str();
|
||||
vitem->tlvkvs.pairs.push_back(kv);
|
||||
|
||||
saveData.push_back(vitem);
|
||||
saveCleanupList.push_back(vitem);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void p3HistoryMgr::saveDone()
|
||||
{
|
||||
/* clean up the save List */
|
||||
std::list<RsItem*>::iterator it;
|
||||
for (it = saveCleanupList.begin(); it != saveCleanupList.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
saveCleanupList.clear();
|
||||
|
||||
/* unlock mutex */
|
||||
mHistoryMtx.unlock(); /****** MUTEX UNLOCKED *******/
|
||||
}
|
||||
|
||||
bool p3HistoryMgr::loadList(std::list<RsItem*>& load)
|
||||
{
|
||||
RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
RsHistoryMsgItem *msgItem;
|
||||
std::list<RsItem*>::iterator it;
|
||||
|
||||
for (it = load.begin(); it != load.end(); it++) {
|
||||
if (NULL != (msgItem = dynamic_cast<RsHistoryMsgItem*>(*it))) {
|
||||
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit = mMessages.find(msgItem->chatPeerId);
|
||||
msgItem->msgId = nextMsgId++;
|
||||
if (mit != mMessages.end()) {
|
||||
mit->second.insert(std::make_pair(msgItem->msgId, msgItem));
|
||||
} else {
|
||||
std::map<uint32_t, RsHistoryMsgItem*> msgs;
|
||||
msgs.insert(std::make_pair(msgItem->msgId, msgItem));
|
||||
mMessages.insert(std::make_pair(msgItem->chatPeerId, msgs));
|
||||
}
|
||||
|
||||
// don't delete the item !!
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
RsConfigKeyValueSet *rskv ;
|
||||
if (NULL != (rskv = dynamic_cast<RsConfigKeyValueSet*>(*it))) {
|
||||
for (std::list<RsTlvKeyValue>::const_iterator kit = rskv->tlvkvs.pairs.begin(); kit != rskv->tlvkvs.pairs.end(); kit++) {
|
||||
if (kit->key == "PUBLIC_ENABLE") {
|
||||
mPublicEnable = (kit->value == "TRUE") ? TRUE : FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kit->key == "PRIVATE_ENABLE") {
|
||||
mPrivateEnable = (kit->value == "TRUE") ? TRUE : FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kit->key == "PUBLIC_SAVECOUNT") {
|
||||
mPublicSaveCount = atoi(kit->value.c_str());
|
||||
continue;
|
||||
}
|
||||
if (kit->key == "PRIVATE_SAVECOUNT") {
|
||||
mPrivateSaveCount = atoi(kit->value.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
delete (*it);
|
||||
continue;
|
||||
}
|
||||
|
||||
// delete unknown items
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***** p3History *****/
|
||||
|
||||
static void convertMsg(const RsHistoryMsgItem* item, HistoryMsg &msg)
|
||||
{
|
||||
msg.msgId = item->msgId;
|
||||
msg.chatPeerId = item->chatPeerId;
|
||||
msg.incoming = item->incoming;
|
||||
msg.peerId = item->peerId;
|
||||
msg.peerName = item->peerName;
|
||||
msg.sendTime = item->sendTime;
|
||||
msg.recvTime = item->recvTime;
|
||||
msg.message = item->message;
|
||||
}
|
||||
|
||||
//static void convertMsg(const HistoryMsg &msg, RsHistoryMsgItem* item)
|
||||
//{
|
||||
// item->msgId = msg.msgId;
|
||||
// item->chatPeerId = msg.chatPeerId;
|
||||
// item->incoming = msg.incoming;
|
||||
// item->peerId = msg.peerId;
|
||||
// item->peerName = msg.peerName;
|
||||
// item->sendTime = msg.sendTime;
|
||||
// item->recvTime = msg.recvTime;
|
||||
// item->message = msg.message;
|
||||
//}
|
||||
|
||||
bool p3HistoryMgr::getMessages(const std::string &chatPeerId, std::list<HistoryMsg> &msgs, uint32_t loadCount)
|
||||
{
|
||||
msgs.clear();
|
||||
|
||||
RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
if (mPublicEnable == false && chatPeerId.empty()) {
|
||||
// public chat not enabled
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPrivateEnable == false && chatPeerId.empty() == false) {
|
||||
// private chat not enabled
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t foundCount = 0;
|
||||
|
||||
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit = mMessages.find(chatPeerId);
|
||||
if (mit != mMessages.end()) {
|
||||
std::map<uint32_t, RsHistoryMsgItem*>::reverse_iterator lit;
|
||||
for (lit = mit->second.rbegin(); lit != mit->second.rend(); lit++) {
|
||||
HistoryMsg msg;
|
||||
convertMsg(lit->second, msg);
|
||||
msgs.insert(msgs.begin(), msg);
|
||||
foundCount++;
|
||||
if (loadCount && foundCount >= loadCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3HistoryMgr::getMessage(uint32_t msgId, HistoryMsg &msg)
|
||||
{
|
||||
RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit;
|
||||
for (mit = mMessages.begin(); mit != mMessages.end(); mit++) {
|
||||
std::map<uint32_t, RsHistoryMsgItem*>::iterator lit = mit->second.find(msgId);
|
||||
if (lit != mit->second.end()) {
|
||||
convertMsg(lit->second, msg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void p3HistoryMgr::clear(const std::string &chatPeerId)
|
||||
{
|
||||
RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit = mMessages.find(chatPeerId);
|
||||
if (mit == mMessages.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<uint32_t, RsHistoryMsgItem*>::iterator lit;
|
||||
for (lit = mit->second.begin(); lit != mit->second.end(); lit++) {
|
||||
delete(lit->second);
|
||||
}
|
||||
mit->second.clear();
|
||||
mMessages.erase(mit);
|
||||
|
||||
IndicateConfigChanged();
|
||||
|
||||
rsicontrol->getNotify().notifyHistoryChanged(0, NOTIFY_TYPE_MOD);
|
||||
}
|
||||
|
||||
void p3HistoryMgr::removeMessages(const std::list<uint32_t> &msgIds)
|
||||
{
|
||||
std::list<uint32_t> ids = msgIds;
|
||||
std::list<uint32_t> removedIds;
|
||||
std::list<uint32_t>::iterator iit;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mHistoryMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit;
|
||||
for (mit = mMessages.begin(); mit != mMessages.end(); ++mit) {
|
||||
iit = ids.begin();
|
||||
while (iit != ids.end()) {
|
||||
std::map<uint32_t, RsHistoryMsgItem*>::iterator lit = mit->second.find(*iit);
|
||||
if (lit != mit->second.end()) {
|
||||
delete(lit->second);
|
||||
mit->second.erase(lit);
|
||||
|
||||
removedIds.push_back(*iit);
|
||||
iit = ids.erase(iit);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
++iit;
|
||||
}
|
||||
|
||||
if (ids.empty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (removedIds.empty() == false) {
|
||||
IndicateConfigChanged();
|
||||
|
||||
for (iit = removedIds.begin(); iit != removedIds.end(); ++iit) {
|
||||
rsicontrol->getNotify().notifyHistoryChanged(*iit, NOTIFY_TYPE_DEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool p3HistoryMgr::getEnable(bool ofPublic)
|
||||
{
|
||||
return ofPublic ? mPublicEnable : mPrivateEnable;
|
||||
}
|
||||
|
||||
void p3HistoryMgr::setEnable(bool forPublic, bool enable)
|
||||
{
|
||||
bool oldValue;
|
||||
|
||||
if (forPublic) {
|
||||
oldValue = mPublicEnable;
|
||||
mPublicEnable = enable;
|
||||
} else {
|
||||
oldValue = mPrivateEnable;
|
||||
mPrivateEnable = enable;
|
||||
}
|
||||
|
||||
if (oldValue != enable) {
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t p3HistoryMgr::getSaveCount(bool ofPublic)
|
||||
{
|
||||
return ofPublic ? mPublicSaveCount : mPrivateSaveCount;
|
||||
}
|
||||
|
||||
void p3HistoryMgr::setSaveCount(bool forPublic, uint32_t count)
|
||||
{
|
||||
uint32_t oldValue;
|
||||
|
||||
if (forPublic) {
|
||||
oldValue = mPublicSaveCount;
|
||||
mPublicSaveCount = count;
|
||||
} else {
|
||||
oldValue = mPrivateSaveCount;
|
||||
mPrivateSaveCount = count;
|
||||
}
|
||||
|
||||
if (oldValue != count) {
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
}
|
86
libretroshare/src/pqi/p3historymgr.h
Normal file
86
libretroshare/src/pqi/p3historymgr.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef RS_P3_HISTORY_MGR_H
|
||||
#define RS_P3_HISTORY_MGR_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/services: p3historymgr.h
|
||||
*
|
||||
* RetroShare C++
|
||||
*
|
||||
* Copyright 2011 by Thunder.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include "serialiser/rshistoryitems.h"
|
||||
#include "retroshare/rshistory.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
|
||||
class RsChatMsgItem;
|
||||
|
||||
//! handles history
|
||||
/*!
|
||||
* The is a retroshare service which allows peers
|
||||
* to store the history of the chat messages
|
||||
*/
|
||||
class p3HistoryMgr: public p3Config
|
||||
{
|
||||
public:
|
||||
p3HistoryMgr();
|
||||
virtual ~p3HistoryMgr();
|
||||
|
||||
/******** p3HistoryMgr *********/
|
||||
|
||||
void addMessage(bool incoming, const std::string &chatPeerId, const std::string &peerId, const RsChatMsgItem *chatItem);
|
||||
|
||||
/********* RsHistory ***********/
|
||||
|
||||
bool getMessages(const std::string &chatPeerId, std::list<HistoryMsg> &msgs, uint32_t loadCount);
|
||||
bool getMessage(uint32_t msgId, HistoryMsg &msg);
|
||||
void clear(const std::string &chatPeerId);
|
||||
void removeMessages(const std::list<uint32_t> &msgIds);
|
||||
bool getEnable(bool ofPublic);
|
||||
void setEnable(bool forPublic, bool enable);
|
||||
uint32_t getSaveCount(bool ofPublic);
|
||||
void setSaveCount(bool forPublic, uint32_t count);
|
||||
|
||||
/********* p3config ************/
|
||||
|
||||
virtual RsSerialiser *setupSerialiser();
|
||||
virtual bool saveList(bool& cleanup, std::list<RsItem*>& saveData);
|
||||
virtual void saveDone();
|
||||
virtual bool loadList(std::list<RsItem*>& load);
|
||||
|
||||
private:
|
||||
uint32_t nextMsgId;
|
||||
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> > mMessages;
|
||||
|
||||
bool mPublicEnable;
|
||||
bool mPrivateEnable;
|
||||
|
||||
uint32_t mPublicSaveCount;
|
||||
uint32_t mPrivateSaveCount;
|
||||
|
||||
std::list<RsItem*> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
|
||||
|
||||
RsMutex mHistoryMtx;
|
||||
};
|
||||
|
||||
#endif
|
@ -30,6 +30,7 @@
|
||||
#include "pqi/p3peermgr.h"
|
||||
#include "pqi/p3linkmgr.h"
|
||||
#include "pqi/p3netmgr.h"
|
||||
#include "pqi/p3historymgr.h"
|
||||
|
||||
//#include "pqi/p3dhtmgr.h" // Only need it for constants.
|
||||
//#include "tcponudp/tou.h"
|
||||
@ -109,6 +110,10 @@ p3PeerMgrIMPL::p3PeerMgrIMPL()
|
||||
{
|
||||
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
|
||||
|
||||
mLinkMgr = NULL;
|
||||
mNetMgr = NULL;
|
||||
mHistoryMgr = NULL;
|
||||
|
||||
/* setup basics of own state */
|
||||
mOwnState.id = AuthSSL::getAuthSSL()->OwnId();
|
||||
mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId();
|
||||
@ -130,10 +135,11 @@ p3PeerMgrIMPL::p3PeerMgrIMPL()
|
||||
return;
|
||||
}
|
||||
|
||||
void p3PeerMgrIMPL::setManagers(p3LinkMgrIMPL *linkMgr, p3NetMgrIMPL *netMgr)
|
||||
void p3PeerMgrIMPL::setManagers(p3LinkMgrIMPL *linkMgr, p3NetMgrIMPL *netMgr, p3HistoryMgr *historyMgr)
|
||||
{
|
||||
mLinkMgr = linkMgr;
|
||||
mNetMgr = netMgr;
|
||||
mHistoryMgr = historyMgr;
|
||||
}
|
||||
|
||||
void p3PeerMgrIMPL::setOwnNetworkMode(uint32_t netMode)
|
||||
@ -537,6 +543,7 @@ bool p3PeerMgrIMPL::removeFriend(const std::string &id)
|
||||
{
|
||||
if (mFriendList.end() != (it = mFriendList.find(*rit)))
|
||||
{
|
||||
mHistoryMgr->clear(it->second.id);
|
||||
mFriendList.erase(it);
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,7 @@ class p3NetMgr;
|
||||
|
||||
class p3LinkMgrIMPL;
|
||||
class p3NetMgrIMPL;
|
||||
class p3HistoryMgr;
|
||||
|
||||
class p3PeerMgr
|
||||
{
|
||||
@ -279,7 +280,7 @@ virtual bool haveOnceConnected();
|
||||
|
||||
p3PeerMgrIMPL();
|
||||
|
||||
void setManagers(p3LinkMgrIMPL *linkMgr, p3NetMgrIMPL *netMgr);
|
||||
void setManagers(p3LinkMgrIMPL *linkMgr, p3NetMgrIMPL *netMgr, p3HistoryMgr *historyMgr);
|
||||
|
||||
void tick();
|
||||
|
||||
@ -314,7 +315,7 @@ void printPeerLists(std::ostream &out);
|
||||
|
||||
p3LinkMgrIMPL *mLinkMgr;
|
||||
p3NetMgrIMPL *mNetMgr;
|
||||
|
||||
p3HistoryMgr *mHistoryMgr;
|
||||
|
||||
private:
|
||||
RsMutex mPeerMtx; /* protects below */
|
||||
|
83
libretroshare/src/retroshare/rshistory.h
Normal file
83
libretroshare/src/retroshare/rshistory.h
Normal file
@ -0,0 +1,83 @@
|
||||
#ifndef RS_HISTORY_INTERFACE_H
|
||||
#define RS_HISTORY_INTERFACE_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/retroshare: rshistory.h
|
||||
*
|
||||
* RetroShare C++ .
|
||||
*
|
||||
* Copyright 2011 by Thunder.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
class RsHistory;
|
||||
|
||||
extern RsHistory *rsHistory;
|
||||
|
||||
#include <string>
|
||||
#include <inttypes.h>
|
||||
#include <list>
|
||||
|
||||
//! data object for message history
|
||||
/*!
|
||||
* data object used for message history
|
||||
*/
|
||||
class HistoryMsg
|
||||
{
|
||||
public:
|
||||
HistoryMsg()
|
||||
{
|
||||
msgId = 0;
|
||||
incoming = false;
|
||||
sendTime = 0;
|
||||
recvTime = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
uint32_t msgId;
|
||||
std::string chatPeerId;
|
||||
bool incoming;
|
||||
std::string peerId;
|
||||
std::string peerName;
|
||||
uint32_t sendTime;
|
||||
uint32_t recvTime;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
//! Interface to retroshare for message history
|
||||
/*!
|
||||
* Provides an interface for retroshare's message history functionality
|
||||
*/
|
||||
class RsHistory
|
||||
{
|
||||
public:
|
||||
virtual bool getMessages(const std::string &chatPeerId, std::list<HistoryMsg> &msgs, uint32_t loadCount) = 0;
|
||||
virtual bool getMessage(uint32_t msgId, HistoryMsg &msg) = 0;
|
||||
virtual void removeMessages(const std::list<uint32_t> &msgIds) = 0;
|
||||
virtual void clear(const std::string &chatPeerId) = 0;
|
||||
|
||||
virtual bool getEnable(bool ofPublic) = 0;
|
||||
virtual void setEnable(bool forPublic, bool enable) = 0;
|
||||
|
||||
// 0 = no limit, >0 count of saved messages
|
||||
virtual uint32_t getSaveCount(bool ofPublic) = 0;
|
||||
virtual void setSaveCount(bool forPublic, uint32_t count) = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -185,7 +185,6 @@ class NotifyBase
|
||||
virtual void notifyListPreChange(int list, int type) { (void) list; (void) type; return; }
|
||||
virtual void notifyListChange(int list, int type) { (void) list; (void) type; return; }
|
||||
virtual void notifyErrorMsg(int list, int sev, std::string msg) { (void) list; (void) sev; (void) msg; return; }
|
||||
virtual void notifyChat() { return; }
|
||||
virtual void notifyChatStatus(const std::string& /* peer_id */, const std::string& /* status_string */ ,bool /* is_private */) {}
|
||||
virtual void notifyCustomState(const std::string& /* peer_id */, const std::string& /* status_string */) {}
|
||||
virtual void notifyHashingInfo(uint32_t type, const std::string& fileinfo) { (void) type; (void)fileinfo; }
|
||||
@ -202,6 +201,7 @@ class NotifyBase
|
||||
virtual void notifyDiscInfoChanged() {}
|
||||
virtual void notifyDownloadComplete(const std::string& /* fileHash */) {};
|
||||
virtual void notifyDownloadCompleteCount(uint32_t /* count */) {};
|
||||
virtual void notifyHistoryChanged(uint32_t /* msgId */, int /* type */) {}
|
||||
|
||||
virtual bool askForPassword(const std::string& /* key_details */, bool /* prev_is_bad */, std::string& /* password */ ) { return false ;}
|
||||
};
|
||||
|
@ -125,7 +125,7 @@ public:
|
||||
#define RS_CHAT_PRIVATE 0x0002
|
||||
#define RS_CHAT_AVATAR_AVAILABLE 0x0004
|
||||
|
||||
class ChatInfo
|
||||
class ChatInfo
|
||||
{
|
||||
public:
|
||||
std::string rsid;
|
||||
@ -140,6 +140,7 @@ std::ostream &operator<<(std::ostream &out, const ChatInfo &info);
|
||||
//std::ostream &operator<<(std::ostream &out, const MsgTagInfo);
|
||||
//std::ostream &operator<<(std::ostream &out, const MsgTagType);
|
||||
|
||||
bool operator==(const ChatInfo&, const ChatInfo&);
|
||||
|
||||
class RsMsgs;
|
||||
extern RsMsgs *rsMsgs;
|
||||
@ -183,14 +184,14 @@ virtual bool resetMessageStandardTagTypes(MsgTagType& tags) = 0;
|
||||
|
||||
/****************************************/
|
||||
/* Chat */
|
||||
virtual bool sendPublicChat(std::wstring msg) = 0;
|
||||
virtual bool sendPrivateChat(std::string id, std::wstring msg) = 0;
|
||||
virtual bool sendPublicChat(const std::wstring& msg) = 0;
|
||||
virtual bool sendPrivateChat(const std::string& id, const std::wstring& msg) = 0;
|
||||
virtual int getPublicChatQueueCount() = 0;
|
||||
virtual bool getPublicChatQueue(std::list<ChatInfo> &chats) = 0;
|
||||
virtual int getPrivateChatQueueCount(bool incoming) = 0;
|
||||
virtual bool getPrivateChatQueueIds(bool incoming, std::list<std::string> &ids) = 0;
|
||||
virtual bool getPrivateChatQueue(bool incoming, std::string id, std::list<ChatInfo> &chats) = 0;
|
||||
virtual bool clearPrivateChatQueue(bool incoming, std::string id) = 0;
|
||||
virtual bool getPrivateChatQueue(bool incoming, const std::string& id, std::list<ChatInfo> &chats) = 0;
|
||||
virtual bool clearPrivateChatQueue(bool incoming, const std::string& id) = 0;
|
||||
virtual void sendStatusString(const std::string& id,const std::string& status_string) = 0 ;
|
||||
virtual void sendGroupChatStatusString(const std::string& status_string) = 0 ;
|
||||
|
||||
@ -199,7 +200,7 @@ virtual std::string getCustomStateString() = 0 ;
|
||||
virtual std::string getCustomStateString(const std::string& peer_id) = 0 ;
|
||||
|
||||
// get avatar data for peer pid
|
||||
virtual void getAvatarData(std::string pid,unsigned char *& data,int& size) = 0 ;
|
||||
virtual void getAvatarData(const std::string& pid,unsigned char *& data,int& size) = 0 ;
|
||||
// set own avatar data
|
||||
virtual void setOwnAvatarData(const unsigned char *data,int size) = 0 ;
|
||||
virtual void getOwnAvatarData(unsigned char *& data,int& size) = 0 ;
|
||||
|
@ -48,7 +48,7 @@
|
||||
class p3PeerMgrIMPL;
|
||||
class p3LinkMgrIMPL;
|
||||
class p3NetMgrIMPL;
|
||||
|
||||
class p3HistoryMgr;
|
||||
|
||||
/* The Main Interface Class - for controlling the server */
|
||||
|
||||
@ -157,6 +157,7 @@ class RsServer: public RsControl, public RsThread
|
||||
p3PeerMgrIMPL *mPeerMgr;
|
||||
p3LinkMgrIMPL *mLinkMgr;
|
||||
p3NetMgrIMPL *mNetMgr;
|
||||
p3HistoryMgr *mHistoryMgr;
|
||||
|
||||
pqipersongrp *pqih;
|
||||
|
||||
|
77
libretroshare/src/rsserver/p3history.cc
Normal file
77
libretroshare/src/rsserver/p3history.cc
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* libretroshare/src/rsserver: p3history.h
|
||||
*
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2011 by Thunder.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "p3history.h"
|
||||
#include "pqi/p3historymgr.h"
|
||||
|
||||
p3History::p3History(p3HistoryMgr* historyMgr)
|
||||
: mHistoryMgr(historyMgr)
|
||||
{
|
||||
}
|
||||
|
||||
p3History::~p3History()
|
||||
{
|
||||
}
|
||||
|
||||
bool p3History::getMessages(const std::string &chatPeerId, std::list<HistoryMsg> &msgs, const uint32_t loadCount)
|
||||
{
|
||||
return mHistoryMgr->getMessages(chatPeerId, msgs, loadCount);
|
||||
}
|
||||
|
||||
bool p3History::getMessage(uint32_t msgId, HistoryMsg &msg)
|
||||
{
|
||||
return mHistoryMgr->getMessage(msgId, msg);
|
||||
}
|
||||
|
||||
void p3History::removeMessages(const std::list<uint32_t> &msgIds)
|
||||
{
|
||||
mHistoryMgr->removeMessages(msgIds);
|
||||
}
|
||||
|
||||
void p3History::clear(const std::string &chatPeerId)
|
||||
{
|
||||
mHistoryMgr->clear(chatPeerId);
|
||||
}
|
||||
|
||||
bool p3History::getEnable(bool ofPublic)
|
||||
{
|
||||
return mHistoryMgr->getEnable(ofPublic);
|
||||
}
|
||||
|
||||
void p3History::setEnable(bool forPublic, bool enable)
|
||||
{
|
||||
mHistoryMgr->setEnable(forPublic, enable);
|
||||
}
|
||||
|
||||
uint32_t p3History::getSaveCount(bool ofPublic)
|
||||
{
|
||||
return mHistoryMgr->getSaveCount(ofPublic);
|
||||
}
|
||||
|
||||
void p3History::setSaveCount(bool forPublic, uint32_t count)
|
||||
{
|
||||
mHistoryMgr->setSaveCount(forPublic, count);
|
||||
}
|
57
libretroshare/src/rsserver/p3history.h
Normal file
57
libretroshare/src/rsserver/p3history.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef RS_P3HISTORY_INTERFACE_H
|
||||
#define RS_P3HISTORY_INTERFACE_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/rsserver: p3history.h
|
||||
*
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2011 by Thunder.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "retroshare/rshistory.h"
|
||||
|
||||
class p3HistoryMgr;
|
||||
|
||||
//! Implements abstract interface rsHistory
|
||||
/*!
|
||||
* Interfaces with p3HistoryMsg
|
||||
*/
|
||||
class p3History : public RsHistory
|
||||
{
|
||||
public:
|
||||
|
||||
p3History(p3HistoryMgr* historyMgr);
|
||||
virtual ~p3History();
|
||||
|
||||
virtual bool getMessages(const std::string &chatPeerId, std::list<HistoryMsg> &msgs, uint32_t loadCount);
|
||||
virtual bool getMessage(uint32_t msgId, HistoryMsg &msg);
|
||||
virtual void removeMessages(const std::list<uint32_t> &msgIds);
|
||||
virtual void clear(const std::string &chatPeerId);
|
||||
virtual bool getEnable(bool ofPublic);
|
||||
virtual void setEnable(bool forPublic, bool enable);
|
||||
virtual uint32_t getSaveCount(bool ofPublic);
|
||||
virtual void setSaveCount(bool forPublic, uint32_t count);
|
||||
|
||||
private:
|
||||
p3HistoryMgr* mHistoryMgr;
|
||||
};
|
||||
|
||||
#endif /* RS_P3HISTORY_INTERFACE_H */
|
@ -50,6 +50,28 @@ RsMsgs *rsMsgs = NULL;
|
||||
/****************************************/
|
||||
/****************************************/
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const ChatInfo &info)
|
||||
{
|
||||
out << "ChatInfo: rsid: " << info.rsid << std::endl;
|
||||
out << "chatflags: " << info.chatflags << std::endl;
|
||||
out << "sendTime: " << info.sendTime << std::endl;
|
||||
out << "recvTime: " << info.recvTime << std::endl;
|
||||
std::string message;
|
||||
message.assign(info.msg.begin(), info.msg.end());
|
||||
out << "msg: " << message;
|
||||
return out;
|
||||
}
|
||||
|
||||
bool operator==(const ChatInfo& info1, const ChatInfo& info2)
|
||||
{
|
||||
return info1.rsid == info2.rsid &&
|
||||
info1.chatflags == info2.chatflags &&
|
||||
info1.sendTime == info2.sendTime &&
|
||||
info1.recvTime == info2.recvTime &&
|
||||
info1.msg == info2.msg;
|
||||
|
||||
}
|
||||
|
||||
bool p3Msgs::getMessageSummaries(std::list<MsgInfoSummary> &msgList)
|
||||
{
|
||||
return mMsgSrv->getMessageSummaries(msgList);
|
||||
@ -156,13 +178,13 @@ bool p3Msgs::resetMessageStandardTagTypes(MsgTagType& tags)
|
||||
|
||||
/****************************************/
|
||||
/****************************************/
|
||||
bool p3Msgs::sendPublicChat(std::wstring msg)
|
||||
bool p3Msgs::sendPublicChat(const std::wstring& msg)
|
||||
{
|
||||
/* send a message to all for now */
|
||||
return mChatSrv -> sendPublicChat(msg);
|
||||
}
|
||||
|
||||
bool p3Msgs::sendPrivateChat(std::string id, std::wstring msg)
|
||||
bool p3Msgs::sendPrivateChat(const std::string& id, const std::wstring& msg)
|
||||
{
|
||||
/* send a message to peer */
|
||||
return mChatSrv -> sendPrivateChat(id, msg);
|
||||
@ -172,9 +194,10 @@ void p3Msgs::sendGroupChatStatusString(const std::string& status_string)
|
||||
{
|
||||
mChatSrv->sendGroupChatStatusString(status_string);
|
||||
}
|
||||
void p3Msgs::sendStatusString(const std::string& peer_id,const std::string& status_string)
|
||||
|
||||
void p3Msgs::sendStatusString(const std::string& peer_id, const std::string& status_string)
|
||||
{
|
||||
mChatSrv->sendStatusString(peer_id,status_string);
|
||||
mChatSrv->sendStatusString(peer_id, status_string);
|
||||
}
|
||||
|
||||
int p3Msgs::getPublicChatQueueCount()
|
||||
@ -197,12 +220,12 @@ bool p3Msgs::getPrivateChatQueueIds(bool incoming, std::list<std::string> &ids
|
||||
return mChatSrv->getPrivateChatQueueIds(incoming, ids);
|
||||
}
|
||||
|
||||
bool p3Msgs::getPrivateChatQueue(bool incoming, std::string id, std::list<ChatInfo> &chats)
|
||||
bool p3Msgs::getPrivateChatQueue(bool incoming, const std::string& id, std::list<ChatInfo> &chats)
|
||||
{
|
||||
return mChatSrv->getPrivateChatQueue(incoming, id, chats);
|
||||
}
|
||||
|
||||
bool p3Msgs::clearPrivateChatQueue(bool incoming, std::string id)
|
||||
bool p3Msgs::clearPrivateChatQueue(bool incoming, const std::string& id)
|
||||
{
|
||||
return mChatSrv->clearPrivateChatQueue(incoming, id);
|
||||
}
|
||||
@ -217,7 +240,7 @@ void p3Msgs::setOwnAvatarData(const unsigned char *data,int size)
|
||||
mChatSrv->setOwnAvatarJpegData(data,size) ;
|
||||
}
|
||||
|
||||
void p3Msgs::getAvatarData(std::string pid,unsigned char *& data,int& size)
|
||||
void p3Msgs::getAvatarData(const std::string& pid,unsigned char *& data,int& size)
|
||||
{
|
||||
mChatSrv->getAvatarJpegData(pid,data,size) ;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class p3Msgs: public RsMsgs
|
||||
/*!
|
||||
* gets avatar from peer, image data in jpeg format
|
||||
*/
|
||||
virtual void getAvatarData(std::string pid,unsigned char *& data,int& size);
|
||||
virtual void getAvatarData(const std::string& pid,unsigned char *& data,int& size);
|
||||
|
||||
/*!
|
||||
* sets clients avatar, image data should be in jpeg format
|
||||
@ -111,13 +111,13 @@ class p3Msgs: public RsMsgs
|
||||
/*!
|
||||
* public chat sent to all peers
|
||||
*/
|
||||
virtual bool sendPublicChat(std::wstring msg);
|
||||
virtual bool sendPublicChat(const std::wstring& msg);
|
||||
|
||||
/*!
|
||||
* chat is sent to specifc peer
|
||||
* @param id peer to send chat msg to
|
||||
*/
|
||||
virtual bool sendPrivateChat(std::string id, std::wstring msg);
|
||||
virtual bool sendPrivateChat(const std::string& id, const std::wstring& msg);
|
||||
|
||||
/*!
|
||||
* returns the count of messages in public or private queue
|
||||
@ -145,19 +145,19 @@ class p3Msgs: public RsMsgs
|
||||
/*!
|
||||
* @param chats ref to list of received private chats is stored here
|
||||
*/
|
||||
virtual bool getPrivateChatQueue(bool incoming, std::string id, std::list<ChatInfo> &chats);
|
||||
virtual bool getPrivateChatQueue(bool incoming, const std::string& id, std::list<ChatInfo> &chats);
|
||||
|
||||
/*!
|
||||
* @param clear private chat queue
|
||||
*/
|
||||
virtual bool clearPrivateChatQueue(bool incoming, std::string id);
|
||||
virtual bool clearPrivateChatQueue(bool incoming, const std::string& id);
|
||||
|
||||
/*!
|
||||
* sends immediate status string to a specific peer, e.g. in a private chat
|
||||
* @param peer_id peer to send status string to
|
||||
* @param status_string immediate status to send
|
||||
*/
|
||||
virtual void sendStatusString(const std::string& peer_id,const std::string& status_string) ;
|
||||
virtual void sendStatusString(const std::string& peer_id, const std::string& status_string) ;
|
||||
|
||||
/*!
|
||||
* sends immediate status to all peers
|
||||
|
@ -1703,6 +1703,7 @@ RsTurtle *rsTurtle = NULL ;
|
||||
#include "pqi/pqisslpersongrp.h"
|
||||
#include "pqi/pqiloopback.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
#include "pqi/p3historymgr.h"
|
||||
|
||||
#include "util/rsdebug.h"
|
||||
#include "util/rsdir.h"
|
||||
@ -1741,6 +1742,7 @@ RsTurtle *rsTurtle = NULL ;
|
||||
#include "rsserver/p3discovery.h"
|
||||
#include "rsserver/p3photo.h"
|
||||
#include "rsserver/p3status.h"
|
||||
#include "rsserver/p3history.h"
|
||||
#include "rsserver/p3serverconfig.h"
|
||||
|
||||
#include "retroshare/rsgame.h"
|
||||
@ -1850,11 +1852,14 @@ int RsServer::StartupRetroShare()
|
||||
/* Setup Notify Early - So we can use it. */
|
||||
rsNotify = new p3Notify();
|
||||
|
||||
/* History Manager */
|
||||
mHistoryMgr = new p3HistoryMgr();
|
||||
|
||||
mPeerMgr = new p3PeerMgrIMPL();
|
||||
mNetMgr = new p3NetMgrIMPL();
|
||||
mLinkMgr = new p3LinkMgrIMPL(mPeerMgr, mNetMgr);
|
||||
|
||||
mPeerMgr->setManagers(mLinkMgr, mNetMgr);
|
||||
mPeerMgr->setManagers(mLinkMgr, mNetMgr, mHistoryMgr);
|
||||
mNetMgr->setManagers(mPeerMgr, mLinkMgr);
|
||||
|
||||
//load all the SSL certs as friends
|
||||
@ -2048,7 +2053,7 @@ int RsServer::StartupRetroShare()
|
||||
ad = new p3disc(mPeerMgr, mLinkMgr, pqih);
|
||||
#ifndef MINIMAL_LIBRS
|
||||
msgSrv = new p3MsgService(mLinkMgr);
|
||||
chatSrv = new p3ChatService(mLinkMgr);
|
||||
chatSrv = new p3ChatService(mLinkMgr, mHistoryMgr);
|
||||
mStatusSrv = new p3StatusService(mLinkMgr);
|
||||
#endif // MINIMAL_LIBRS
|
||||
|
||||
@ -2155,7 +2160,8 @@ int RsServer::StartupRetroShare()
|
||||
#ifndef MINIMAL_LIBRS
|
||||
mConfigMgr->addConfiguration("msgs.cfg", msgSrv);
|
||||
mConfigMgr->addConfiguration("chat.cfg", chatSrv);
|
||||
#ifdef RS_USE_BLOGS
|
||||
mConfigMgr->addConfiguration("p3History.cfg", mHistoryMgr);
|
||||
#ifdef RS_USE_BLOGS
|
||||
mConfigMgr->addConfiguration("blogs.cfg", mBlogs);
|
||||
#endif
|
||||
mConfigMgr->addConfiguration("forums.cfg", mForums);
|
||||
@ -2335,6 +2341,7 @@ int RsServer::StartupRetroShare()
|
||||
rsBlogs = mBlogs;
|
||||
#endif
|
||||
rsStatus = new p3Status(mStatusSrv);
|
||||
rsHistory = new p3History(mHistoryMgr);
|
||||
|
||||
#ifndef RS_RELEASE
|
||||
rsGameLauncher = gameLauncher;
|
||||
|
@ -42,6 +42,7 @@ const uint8_t RS_PKT_TYPE_PEER_CONFIG = 0x02;
|
||||
const uint8_t RS_PKT_TYPE_CACHE_CONFIG = 0x03;
|
||||
const uint8_t RS_PKT_TYPE_FILE_CONFIG = 0x04;
|
||||
const uint8_t RS_PKT_TYPE_PLUGIN_CONFIG = 0x05;
|
||||
const uint8_t RS_PKT_TYPE_HISTORY_CONFIG = 0x06;
|
||||
|
||||
/* GENERAL CONFIG SUBTYPES */
|
||||
const uint8_t RS_PKT_SUBTYPE_KEY_VALUE = 0x01;
|
||||
|
266
libretroshare/src/serialiser/rshistoryitems.cc
Normal file
266
libretroshare/src/serialiser/rshistoryitems.cc
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* libretroshare/src/serialiser: rshistoryitems.cc
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2011 by Thunder.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "serialiser/rshistoryitems.h"
|
||||
#include "serialiser/rsbaseserial.h"
|
||||
#include "serialiser/rstlvbase.h"
|
||||
#include "serialiser/rsconfigitems.h"
|
||||
|
||||
/***
|
||||
#define RSSERIAL_DEBUG 1
|
||||
***/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
RsHistoryMsgItem::RsHistoryMsgItem() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_HISTORY_CONFIG, RS_PKT_SUBTYPE_DEFAULT)
|
||||
{
|
||||
incoming = false;
|
||||
sendTime = 0;
|
||||
recvTime = 0;
|
||||
msgId = 0;
|
||||
}
|
||||
|
||||
RsHistoryMsgItem::~RsHistoryMsgItem()
|
||||
{
|
||||
}
|
||||
|
||||
void RsHistoryMsgItem::clear()
|
||||
{
|
||||
incoming = false;
|
||||
peerId.clear();
|
||||
peerName.clear();
|
||||
sendTime = 0;
|
||||
recvTime = 0;
|
||||
message.clear();
|
||||
msgId = 0;
|
||||
}
|
||||
|
||||
std::ostream& RsHistoryMsgItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsHistoryMsgItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "chatPeerid: " << chatPeerId << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "incoming: " << (incoming ? "1" : "0") << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "peerId: " << peerId << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "peerName: " << peerName << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "sendTime: " << sendTime << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "recvTime: " << recvTime << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
std::string cnv_message(message.begin(), message.end());
|
||||
out << "message: " << cnv_message << std::endl;
|
||||
|
||||
printRsItemEnd(out, "RsHistoryMsgItem", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
RsHistorySerialiser::RsHistorySerialiser() : RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_HISTORY_CONFIG)
|
||||
{
|
||||
}
|
||||
|
||||
RsHistorySerialiser::~RsHistorySerialiser()
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t RsHistorySerialiser::sizeHistoryMsgItem(RsHistoryMsgItem* item)
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
s += 2; /* version */
|
||||
s += GetTlvStringSize(item->chatPeerId);
|
||||
s += 1; /* incoming */
|
||||
s += GetTlvStringSize(item->peerId);
|
||||
s += GetTlvStringSize(item->peerName);
|
||||
s += 4; /* sendTime */
|
||||
s += 4; /* recvTime */
|
||||
s += GetTlvStringSize(item->message);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* serialise the data to the buffer */
|
||||
bool RsHistorySerialiser::serialiseHistoryMsgItem(RsHistoryMsgItem* item, void* data, uint32_t* pktsize)
|
||||
{
|
||||
uint32_t tlvsize = sizeHistoryMsgItem(item);
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (*pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
*pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
|
||||
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsHistorySerialiser::serialiseItem() Header: " << ok << std::endl;
|
||||
std::cerr << "RsHistorySerialiser::serialiseItem() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= setRawUInt16(data, tlvsize, &offset, 0); // version
|
||||
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LOCATION, item->chatPeerId);
|
||||
uint8_t dummy = item->incoming ? 1 : 0;
|
||||
ok &= setRawUInt8(data, tlvsize, &offset, dummy);
|
||||
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_PEERID, item->peerId);
|
||||
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, item->peerName);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, item->sendTime);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, item->recvTime);
|
||||
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_WSTR_MSG, item->message);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsHistorySerialiser::serialiseItem() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsHistoryMsgItem *RsHistorySerialiser::deserialiseHistoryMsgItem(void *data, uint32_t *pktsize)
|
||||
{
|
||||
/* get the type and size */
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
||||
uint32_t offset = 0;
|
||||
|
||||
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
|
||||
(RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) ||
|
||||
(RS_PKT_TYPE_HISTORY_CONFIG != getRsItemType(rstype)) ||
|
||||
(RS_PKT_SUBTYPE_DEFAULT != getRsItemSubType(rstype)))
|
||||
{
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
if (*pktsize < rssize) /* check size */
|
||||
return NULL; /* not enough data */
|
||||
|
||||
/* set the packet length */
|
||||
*pktsize = rssize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
RsHistoryMsgItem *item = new RsHistoryMsgItem();
|
||||
item->clear();
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* get mandatory parts first */
|
||||
uint16_t version = 0;
|
||||
ok &= getRawUInt16(data, rssize, &offset, &version);
|
||||
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_LOCATION, item->chatPeerId);
|
||||
uint8_t dummy;
|
||||
ok &= getRawUInt8(data, rssize, &offset, &dummy);
|
||||
item->incoming = (dummy == 1);
|
||||
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_PEERID, item->peerId);
|
||||
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_NAME, item->peerName);
|
||||
ok &= getRawUInt32(data, rssize, &offset, &(item->sendTime));
|
||||
ok &= getRawUInt32(data, rssize, &offset, &(item->recvTime));
|
||||
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_WSTR_MSG, item->message);
|
||||
|
||||
if (offset != rssize)
|
||||
{
|
||||
/* error */
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
uint32_t RsHistorySerialiser::size(RsItem *item)
|
||||
{
|
||||
RsHistoryMsgItem* hi;
|
||||
|
||||
if (NULL != (hi = dynamic_cast<RsHistoryMsgItem*>(item)))
|
||||
{
|
||||
return sizeHistoryMsgItem(hi);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool RsHistorySerialiser::serialise(RsItem *item, void *data, uint32_t *pktsize)
|
||||
{
|
||||
RsHistoryMsgItem* hi;
|
||||
|
||||
if (NULL != (hi = dynamic_cast<RsHistoryMsgItem*>(item)))
|
||||
{
|
||||
return serialiseHistoryMsgItem(hi, data, pktsize);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
RsItem* RsHistorySerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||
{
|
||||
/* get the type and size */
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
|
||||
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
|
||||
(RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) ||
|
||||
(RS_PKT_TYPE_HISTORY_CONFIG != getRsItemType(rstype)))
|
||||
{
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
switch(getRsItemSubType(rstype))
|
||||
{
|
||||
case RS_PKT_SUBTYPE_DEFAULT:
|
||||
return deserialiseHistoryMsgItem(data, pktsize);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
75
libretroshare/src/serialiser/rshistoryitems.h
Normal file
75
libretroshare/src/serialiser/rshistoryitems.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef RS_HISTORY_ITEMS_H
|
||||
#define RS_HISTORY_ITEMS_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/serialiser: rshistoryitems.h
|
||||
*
|
||||
* RetroShare Serialiser.
|
||||
*
|
||||
* Copyright 2007-2008 by Thunder.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "serialiser/rsserviceids.h"
|
||||
#include "serialiser/rsserial.h"
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
class RsHistoryMsgItem: public RsItem
|
||||
{
|
||||
public:
|
||||
RsHistoryMsgItem();
|
||||
virtual ~RsHistoryMsgItem();
|
||||
|
||||
virtual void clear();
|
||||
std::ostream& print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
std::string chatPeerId; // empty for global chat
|
||||
bool incoming;
|
||||
std::string peerId;
|
||||
std::string peerName;
|
||||
uint32_t sendTime;
|
||||
uint32_t recvTime;
|
||||
std::string message;
|
||||
|
||||
/* not serialised */
|
||||
uint32_t msgId;
|
||||
};
|
||||
|
||||
class RsHistorySerialiser: public RsSerialType
|
||||
{
|
||||
public:
|
||||
RsHistorySerialiser();
|
||||
virtual ~RsHistorySerialiser();
|
||||
|
||||
virtual uint32_t size(RsItem*);
|
||||
virtual bool serialise(RsItem* item, void* data, uint32_t* size);
|
||||
virtual RsItem* deserialise(void* data, uint32_t* size);
|
||||
|
||||
private:
|
||||
virtual uint32_t sizeHistoryMsgItem(RsHistoryMsgItem*);
|
||||
virtual bool serialiseHistoryMsgItem (RsHistoryMsgItem* item, void* data, uint32_t* size);
|
||||
virtual RsHistoryMsgItem* deserialiseHistoryMsgItem(void* data, uint32_t* size);
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
||||
#endif /* RS_HISTORY_ITEMS_H */
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "pqi/pqinotify.h"
|
||||
#include "pqi/pqistore.h"
|
||||
#include "pqi/p3linkmgr.h"
|
||||
#include "pqi/p3historymgr.h"
|
||||
|
||||
#include "services/p3chatservice.h"
|
||||
|
||||
@ -42,8 +43,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
p3ChatService::p3ChatService(p3LinkMgr *lm)
|
||||
:p3Service(RS_SERVICE_TYPE_CHAT), p3Config(CONFIG_TYPE_CHAT), mChatMtx("p3ChatService"), mLinkMgr(lm)
|
||||
p3ChatService::p3ChatService(p3LinkMgr *lm, p3HistoryMgr *historyMgr)
|
||||
:p3Service(RS_SERVICE_TYPE_CHAT), p3Config(CONFIG_TYPE_CHAT), mChatMtx("p3ChatService"), mLinkMgr(lm) , mHistoryMgr(historyMgr)
|
||||
{
|
||||
addSerialType(new RsChatSerialiser());
|
||||
|
||||
@ -67,7 +68,7 @@ int p3ChatService::status()
|
||||
|
||||
/***************** Chat Stuff **********************/
|
||||
|
||||
int p3ChatService::sendPublicChat(std::wstring &msg)
|
||||
int p3ChatService::sendPublicChat(const std::wstring &msg)
|
||||
{
|
||||
/* go through all the peers */
|
||||
|
||||
@ -76,7 +77,8 @@ int p3ChatService::sendPublicChat(std::wstring &msg)
|
||||
mLinkMgr->getOnlineList(ids);
|
||||
|
||||
/* add in own id -> so get reflection */
|
||||
ids.push_back(mLinkMgr->getOwnId());
|
||||
std::string ownId = mLinkMgr->getOwnId();
|
||||
ids.push_back(ownId);
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "p3ChatService::sendChat()";
|
||||
@ -92,7 +94,7 @@ int p3ChatService::sendPublicChat(std::wstring &msg)
|
||||
ci->sendTime = time(NULL);
|
||||
ci->recvTime = ci->sendTime;
|
||||
ci->message = msg;
|
||||
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "p3ChatService::sendChat() Item:";
|
||||
std::cerr << std::endl;
|
||||
@ -100,6 +102,9 @@ int p3ChatService::sendPublicChat(std::wstring &msg)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if (*it == ownId) {
|
||||
mHistoryMgr->addMessage(false, "", ownId, ci);
|
||||
}
|
||||
sendItem(ci);
|
||||
}
|
||||
|
||||
@ -220,7 +225,7 @@ void p3ChatService::checkSizeAndSendMessage(RsChatMsgItem *msg)
|
||||
sendItem(msg) ;
|
||||
}
|
||||
|
||||
bool p3ChatService::sendPrivateChat(std::string &id, std::wstring &msg)
|
||||
bool p3ChatService::sendPrivateChat(const std::string &id, const std::wstring &msg)
|
||||
{
|
||||
// make chat item....
|
||||
#ifdef CHAT_DEBUG
|
||||
@ -278,6 +283,8 @@ bool p3ChatService::sendPrivateChat(std::string &id, std::wstring &msg)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
mHistoryMgr->addMessage(false, id, mLinkMgr->getOwnId(), ci);
|
||||
|
||||
checkSizeAndSendMessage(ci);
|
||||
|
||||
// Check if custom state string has changed, in which case it should be sent to the peer.
|
||||
@ -428,9 +435,16 @@ void p3ChatService::receiveChatQueue()
|
||||
if (ci->chatFlags & RS_CHAT_FLAG_PRIVATE) {
|
||||
privateChanged = true;
|
||||
privateIncomingList.push_back(ci); // don't delete the item !!
|
||||
|
||||
mHistoryMgr->addMessage(true, ci->PeerId(), ci->PeerId(), ci);
|
||||
} else {
|
||||
publicChanged = true;
|
||||
publicList.push_back(ci); // don't delete the item !!
|
||||
|
||||
if (ci->PeerId() != mLinkMgr->getOwnId()) {
|
||||
/* not from loop back */
|
||||
mHistoryMgr->addMessage(true, "", ci->PeerId(), ci);
|
||||
}
|
||||
}
|
||||
} /* UNLOCK */
|
||||
}
|
||||
@ -1088,12 +1102,16 @@ void p3ChatService::statusChange(const std::list<pqipeer> &plist)
|
||||
if (privateOutgoingList.size()) {
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::string ownId = mLinkMgr->getOwnId();
|
||||
|
||||
std::list<RsChatMsgItem *>::iterator cit = privateOutgoingList.begin();
|
||||
while (cit != privateOutgoingList.end()) {
|
||||
RsChatMsgItem *c = *cit;
|
||||
|
||||
if (c->PeerId() == it->id) {
|
||||
sendItem(c); // delete item
|
||||
mHistoryMgr->addMessage(false, c->PeerId(), ownId, c);
|
||||
|
||||
checkSizeAndSendMessage(c); // delete item
|
||||
|
||||
changed = true;
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "retroshare/rsmsgs.h"
|
||||
|
||||
class p3LinkMgr;
|
||||
class p3HistoryMgr;
|
||||
|
||||
//!The basic Chat service.
|
||||
/**
|
||||
@ -46,7 +47,7 @@ class p3LinkMgr;
|
||||
class p3ChatService: public p3Service, public p3Config, public pqiMonitor
|
||||
{
|
||||
public:
|
||||
p3ChatService(p3LinkMgr *cm);
|
||||
p3ChatService(p3LinkMgr *cm, p3HistoryMgr *historyMgr);
|
||||
|
||||
/***** overloaded from p3Service *****/
|
||||
/*!
|
||||
@ -65,14 +66,14 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
|
||||
/*!
|
||||
* public chat sent to all peers
|
||||
*/
|
||||
int sendPublicChat(std::wstring &msg);
|
||||
int sendPublicChat(const std::wstring &msg);
|
||||
|
||||
/********* RsMsgs ***********/
|
||||
/*!
|
||||
* chat is sent to specifc peer
|
||||
* @param id peer to send chat msg to
|
||||
*/
|
||||
bool sendPrivateChat(std::string &id, std::wstring &msg);
|
||||
bool sendPrivateChat(const std::string &id, const std::wstring &msg);
|
||||
|
||||
/*!
|
||||
* can be used to send 'immediate' status msgs, these status updates are meant for immediate use by peer (not saved by rs)
|
||||
@ -201,6 +202,7 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
|
||||
RsChatStatusItem *makeOwnCustomStateStringItem() ;
|
||||
|
||||
p3LinkMgr *mLinkMgr;
|
||||
p3HistoryMgr *mHistoryMgr;
|
||||
|
||||
std::list<RsChatMsgItem *> publicList;
|
||||
std::list<RsChatMsgItem *> privateIncomingList;
|
||||
|
@ -242,12 +242,8 @@ HEADERS += rshare.h \
|
||||
gui/xprogressbar.h \
|
||||
gui/plugins/PluginInterface.h \
|
||||
gui/im_history/ImHistoryBrowser.h \
|
||||
gui/im_history/IMHistoryKeeper.h \
|
||||
gui/im_history/IMHistoryReader.h \
|
||||
gui/im_history/IMHistoryItem.h \
|
||||
gui/im_history/IMHistoryItemDelegate.h \
|
||||
gui/im_history/IMHistoryItemPainter.h \
|
||||
gui/im_history/IMHistoryWriter.h \
|
||||
lang/languagesupport.h \
|
||||
util/stringutil.h \
|
||||
util/win32.h \
|
||||
@ -491,12 +487,8 @@ SOURCES += main.cpp \
|
||||
gui/MessagesDialog.cpp \
|
||||
gui/FileTransferInfoWidget.cpp \
|
||||
gui/im_history/ImHistoryBrowser.cpp \
|
||||
gui/im_history/IMHistoryKeeper.cpp \
|
||||
gui/im_history/IMHistoryReader.cpp \
|
||||
gui/im_history/IMHistoryItem.cpp \
|
||||
gui/im_history/IMHistoryItemDelegate.cpp \
|
||||
gui/im_history/IMHistoryItemPainter.cpp \
|
||||
gui/im_history/IMHistoryWriter.cpp \
|
||||
gui/help/browser/helpbrowser.cpp \
|
||||
gui/help/browser/helptextbrowser.cpp \
|
||||
gui/HelpDialog.cpp \
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <retroshare/rspeers.h>
|
||||
#include <retroshare/rsstatus.h>
|
||||
#include <retroshare/rsmsgs.h>
|
||||
#include <retroshare/rshistory.h>
|
||||
#include <retroshare/rsnotify.h>
|
||||
#include "settings/rsharesettings.h"
|
||||
#include "notifyqt.h"
|
||||
@ -198,15 +199,15 @@ FriendsDialog::FriendsDialog(QWidget *parent)
|
||||
|
||||
setChatInfo(tr("Welcome to RetroShare's group chat."), QString::fromUtf8("blue"));
|
||||
|
||||
if (Settings->valueFromGroup("Chat", QString::fromUtf8("GroupChat_History"), true).toBool()) {
|
||||
historyKeeper.init(QString::fromStdString(RsInit::RsProfileConfigDirectory()) + "/chatPublic.xml");
|
||||
|
||||
if (rsHistory->getEnable(true)) {
|
||||
int messageCount = Settings->getPublicChatHistoryCount();
|
||||
if (messageCount > 0) {
|
||||
QList<IMHistoryItem> historyItems;
|
||||
historyKeeper.getMessages(historyItems, messageCount);
|
||||
foreach(IMHistoryItem item, historyItems) {
|
||||
addChatMsg(item.incoming, true, item.name, item.recvTime, item.messageText);
|
||||
std::list<HistoryMsg> historyMsgs;
|
||||
rsHistory->getMessages("", 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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1429,12 +1430,12 @@ void FriendsDialog::publicChatChanged(int type)
|
||||
}
|
||||
}
|
||||
|
||||
void FriendsDialog::addChatMsg(bool incoming, bool history, QString &name, QDateTime &recvTime, QString &message)
|
||||
void FriendsDialog::addChatMsg(bool incoming, bool history, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message)
|
||||
{
|
||||
unsigned int formatFlag = CHAT_FORMATMSG_EMBED_LINKS;
|
||||
|
||||
// embed smileys ?
|
||||
if (Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_GroupChat"), true).toBool()) {
|
||||
if (Settings->valueFromGroup("Chat", "Emoteicons_GroupChat", true).toBool()) {
|
||||
formatFlag |= CHAT_FORMATMSG_EMBED_SMILEYS;
|
||||
}
|
||||
|
||||
@ -1452,7 +1453,7 @@ void FriendsDialog::addChatMsg(bool incoming, bool history, QString &name, QDate
|
||||
type = ChatStyle::FORMATMSG_OUTGOING;
|
||||
}
|
||||
}
|
||||
QString formatMsg = style.formatMessage(type, name, recvTime, message, formatFlag);
|
||||
QString formatMsg = style.formatMessage(type, name, incoming ? recvTime : sendTime, message, formatFlag);
|
||||
|
||||
ui.msgText->append(formatMsg);
|
||||
}
|
||||
@ -1509,8 +1510,7 @@ void FriendsDialog::insertChat()
|
||||
emit notifyGroupChat(tr("New group chat"), notifyMsg);
|
||||
}
|
||||
|
||||
historyKeeper.addMessage(incoming, it->rsid, name, sendTime, recvTime, msg);
|
||||
addChatMsg(incoming, false, name, recvTime, msg);
|
||||
addChatMsg(incoming, false, name, sendTime, recvTime, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1555,7 +1555,9 @@ void FriendsDialog::sendMsg()
|
||||
return;
|
||||
}
|
||||
|
||||
std::wstring message = lineWidget->toHtml().toStdWString();
|
||||
QString text;
|
||||
RsHtml::optimizeHtml(lineWidget, text);
|
||||
std::wstring message = text.toStdWString();
|
||||
|
||||
#ifdef FRIENDS_DEBUG
|
||||
std::string msg(message.begin(), message.end());
|
||||
@ -1737,7 +1739,7 @@ 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();
|
||||
historyKeeper.clear();
|
||||
rsHistory->clear("");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2066,7 +2068,7 @@ void FriendsDialog::peerSortIndicatorChanged(int column, Qt::SortOrder)
|
||||
|
||||
void FriendsDialog::on_actionMessageHistory_triggered()
|
||||
{
|
||||
ImHistoryBrowser imBrowser("", historyKeeper, ui.lineEdit, this);
|
||||
ImHistoryBrowser imBrowser("", ui.lineEdit, this);
|
||||
imBrowser.exec();
|
||||
}
|
||||
|
||||
|
@ -27,8 +27,6 @@
|
||||
|
||||
#include "mainpage.h"
|
||||
|
||||
#include "im_history/IMHistoryKeeper.h"
|
||||
|
||||
// states for sorting (equal values are possible)
|
||||
// used in BuildSortString - state + name
|
||||
#define PEER_STATE_ONLINE 1
|
||||
@ -173,7 +171,7 @@ signals:
|
||||
|
||||
private:
|
||||
void processSettings(bool bLoad);
|
||||
void addChatMsg(bool incoming, bool history, QString &name, QDateTime &recvTime, QString &message);
|
||||
void addChatMsg(bool incoming, bool history, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message);
|
||||
|
||||
void colorChanged(const QColor &c);
|
||||
void fontChanged(const QFont &font);
|
||||
@ -199,7 +197,6 @@ private:
|
||||
/* (2) Utility Fns */
|
||||
QTreeWidgetItem *getCurrentPeer();
|
||||
|
||||
IMHistoryKeeper historyKeeper;
|
||||
ChatStyle style;
|
||||
|
||||
QColor mCurrentColor;
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "HandleRichText.h"
|
||||
#include "gui/RetroShareLink.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace RsHtml {
|
||||
|
||||
EmbedInHtmlImg defEmbedImg;
|
||||
@ -215,4 +217,56 @@ bool findAnchors(const QString &text, QStringList& urls)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void optimizeHtml(QDomDocument& doc, QDomElement& currentElement)
|
||||
{
|
||||
QDomNodeList children = currentElement.childNodes();
|
||||
for (uint index = 0; index < children.length(); ) {
|
||||
QDomNode node = children.item(index);
|
||||
if (node.isElement()) {
|
||||
QDomElement element = node.toElement();
|
||||
if (element.tagName().toLower() == "head") {
|
||||
// remove head
|
||||
currentElement.removeChild(node);
|
||||
continue;
|
||||
}
|
||||
QDomNode style = element.attributes().namedItem("style");
|
||||
if (style.isAttr()) {
|
||||
QDomAttr attr = style.toAttr();
|
||||
// compress style attribute
|
||||
QString value = attr.value().simplified();
|
||||
value.replace("margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;", "margin:0px 0px 0px 0px;");
|
||||
value.replace("; ", ";");
|
||||
attr.setValue(value);
|
||||
}
|
||||
optimizeHtml(doc, element);
|
||||
}
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
void optimizeHtml(QTextEdit *textEdit, QString &text)
|
||||
{
|
||||
if (textEdit->toHtml() == QTextDocument(textEdit->toPlainText()).toHtml()) {
|
||||
text = textEdit->toPlainText();
|
||||
std::cerr << "Optimized text to " << text.length() << " bytes , instead of " << textEdit->toHtml().length() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
text = textEdit->toHtml();
|
||||
|
||||
// remove doctype
|
||||
text.remove(QRegExp("<!DOCTYPE[^>]*>"));
|
||||
|
||||
QDomDocument doc;
|
||||
if (doc.setContent(text) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
QDomElement body = doc.documentElement();
|
||||
optimizeHtml(doc, body);
|
||||
text = doc.toString(-1);
|
||||
|
||||
std::cerr << "Optimized text to " << text.length() << " bytes , instead of " << textEdit->toHtml().length() << std::endl;
|
||||
}
|
||||
|
||||
} // namespace RsHtml
|
||||
|
@ -37,6 +37,8 @@
|
||||
#define RSHTML_FORMATTEXT_EMBED_SMILEYS 1
|
||||
#define RSHTML_FORMATTEXT_EMBED_LINKS 2
|
||||
|
||||
class QTextEdit;
|
||||
|
||||
namespace RsHtml {
|
||||
|
||||
|
||||
@ -111,6 +113,8 @@ extern EmbedInHtmlImg defEmbedImg;
|
||||
QString formatText(const QString &text, unsigned int flag);
|
||||
bool findAnchors(const QString &text, QStringList& urls);
|
||||
|
||||
void optimizeHtml(QTextEdit *textEdit, QString &text);
|
||||
|
||||
} // namespace RsHtml
|
||||
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "retroshare/rsinit.h"
|
||||
#include <retroshare/rsnotify.h>
|
||||
#include <retroshare/rsstatus.h>
|
||||
#include <retroshare/rshistory.h>
|
||||
#include <retroshare/rsiface.h>
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
#include "gui/settings/RsharePeerSettings.h"
|
||||
@ -60,6 +61,7 @@
|
||||
#include "gui/common/PeerDefs.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define appDir QApplication::applicationDirPath()
|
||||
|
||||
@ -96,138 +98,116 @@ PopupChatDialog::PopupChatDialog(const std::string &id, const QString &name, QWi
|
||||
lastChatTime(0), lastChatName("")
|
||||
|
||||
{
|
||||
/* Invoke Qt Designer generated QObject setup routine */
|
||||
ui.setupUi(this);
|
||||
/* Invoke Qt Designer generated QObject setup routine */
|
||||
ui.setupUi(this);
|
||||
|
||||
newMessages = false;
|
||||
typing = false;
|
||||
m_manualDelete = false;
|
||||
peerStatus = 0;
|
||||
newMessages = false;
|
||||
typing = false;
|
||||
manualDelete = false;
|
||||
peerStatus = 0;
|
||||
|
||||
last_status_send_time = 0 ;
|
||||
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
|
||||
last_status_send_time = 0 ;
|
||||
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
|
||||
|
||||
/* Hide or show the frames */
|
||||
showAvatarFrame(PeerSettings->getShowAvatarFrame(dialogId));
|
||||
ui.infoframe->setVisible(false);
|
||||
ui.statusmessagelabel->hide();
|
||||
/* Hide or show the frames */
|
||||
showAvatarFrame(PeerSettings->getShowAvatarFrame(dialogId));
|
||||
ui.infoframe->setVisible(false);
|
||||
ui.statusmessagelabel->hide();
|
||||
|
||||
connect(ui.avatarFrameButton, SIGNAL(toggled(bool)), this, SLOT(showAvatarFrame(bool)));
|
||||
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.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(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&)));
|
||||
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&)));
|
||||
|
||||
connect(ui.chattextEdit,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
|
||||
connect(ui.chattextEdit,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
|
||||
|
||||
ui.avatarWidget->setFrameType(AvatarWidget::STATUS_FRAME);
|
||||
ui.avatarWidget->setId(dialogId, false);
|
||||
ui.avatarWidget->setFrameType(AvatarWidget::STATUS_FRAME);
|
||||
ui.avatarWidget->setId(dialogId, false);
|
||||
|
||||
ui.ownAvatarWidget->setFrameType(AvatarWidget::STATUS_FRAME);
|
||||
ui.ownAvatarWidget->setOwnId();
|
||||
ui.ownAvatarWidget->setFrameType(AvatarWidget::STATUS_FRAME);
|
||||
ui.ownAvatarWidget->setOwnId();
|
||||
|
||||
// Create the status bar
|
||||
resetStatusBar();
|
||||
// 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);
|
||||
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")));
|
||||
|
||||
setAcceptDrops(true);
|
||||
ui.chattextEdit->setAcceptDrops(false);
|
||||
ui.textboldButton->setCheckable(true);
|
||||
ui.textunderlineButton->setCheckable(true);
|
||||
ui.textitalicButton->setCheckable(true);
|
||||
|
||||
QMenu * toolmenu = new QMenu();
|
||||
toolmenu->addAction(ui.actionClear_Chat_History);
|
||||
toolmenu->addAction(ui.actionDelete_Chat_History);
|
||||
toolmenu->addAction(ui.actionSave_Chat_History);
|
||||
toolmenu->addAction(ui.actionClearOfflineMessages);
|
||||
toolmenu->addAction(ui.actionMessageHistory);
|
||||
//toolmenu->addAction(ui.action_Disable_Emoticons);
|
||||
ui.pushtoolsButton->setMenu(toolmenu);
|
||||
setAcceptDrops(true);
|
||||
ui.chattextEdit->setAcceptDrops(false);
|
||||
|
||||
mCurrentColor.setNamedColor(PeerSettings->getPrivateChatColor(dialogId));
|
||||
mCurrentFont.fromString(PeerSettings->getPrivateChatFont(dialogId));
|
||||
QMenu * toolmenu = new QMenu();
|
||||
toolmenu->addAction(ui.actionClear_Chat_History);
|
||||
toolmenu->addAction(ui.actionDelete_Chat_History);
|
||||
toolmenu->addAction(ui.actionSave_Chat_History);
|
||||
toolmenu->addAction(ui.actionClearOfflineMessages);
|
||||
toolmenu->addAction(ui.actionMessageHistory);
|
||||
//toolmenu->addAction(ui.action_Disable_Emoticons);
|
||||
ui.pushtoolsButton->setMenu(toolmenu);
|
||||
|
||||
colorChanged(mCurrentColor);
|
||||
fontChanged(mCurrentFont);
|
||||
mCurrentColor.setNamedColor(PeerSettings->getPrivateChatColor(dialogId));
|
||||
mCurrentFont.fromString(PeerSettings->getPrivateChatFont(dialogId));
|
||||
|
||||
// load settings
|
||||
processSettings(true);
|
||||
colorChanged(mCurrentColor);
|
||||
fontChanged(mCurrentFont);
|
||||
|
||||
// load style
|
||||
PeerSettings->getStyle(dialogId, "PopupChatDialog", style);
|
||||
// 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);
|
||||
// load style
|
||||
PeerSettings->getStyle(dialogId, "PopupChatDialog", style);
|
||||
|
||||
// initialize first custom state string
|
||||
QString customStateString = QString::fromUtf8(rsMsgs->getCustomStateString(dialogId).c_str());
|
||||
updatePeersCustomStateString(QString::fromStdString(dialogId), customStateString);
|
||||
// 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);
|
||||
|
||||
if (Settings->valueFromGroup("Chat", QString::fromUtf8("PrivateChat_History"), true).toBool()) {
|
||||
historyKeeper.init(QString::fromStdString(RsInit::RsProfileConfigDirectory()) + "/chat_" + QString::fromStdString(dialogId) + ".xml");
|
||||
// initialize first custom state string
|
||||
QString customStateString = QString::fromUtf8(rsMsgs->getCustomStateString(dialogId).c_str());
|
||||
updatePeersCustomStateString(QString::fromStdString(dialogId), customStateString);
|
||||
|
||||
// get offline chat messages
|
||||
std::list<ChatInfo> offlineChat;
|
||||
std::list<ChatInfo>::iterator offineChatIt;
|
||||
rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, dialogId, offlineChat);
|
||||
if (rsHistory->getEnable(false)) {
|
||||
// get chat messages from history
|
||||
std::list<HistoryMsg> historyMsgs;
|
||||
int messageCount = Settings->getPrivateChatHistoryCount();
|
||||
if (messageCount > 0) {
|
||||
rsHistory->getMessages(dialogId, historyMsgs, messageCount);
|
||||
|
||||
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;
|
||||
}
|
||||
std::list<HistoryMsg>::iterator historyIt;
|
||||
for (historyIt = historyMsgs.begin(); historyIt != historyMsgs.end(); historyIt++) {
|
||||
addChatMsg(historyIt->incoming, QString::fromUtf8(historyIt->peerName.c_str()), QDateTime::fromTime_t(historyIt->sendTime), QDateTime::fromTime_t(historyIt->recvTime), QString::fromUtf8(historyIt->message.c_str()), TYPE_HISTORY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QDateTime sendTime = QDateTime::fromTime_t(offineChatIt->sendTime);
|
||||
QString message = QString::fromStdWString(offineChatIt->msg);
|
||||
ui.chattextEdit->installEventFilter(this);
|
||||
|
||||
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);
|
||||
// add offline chat messages
|
||||
onPrivateChatChanged(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD, true);
|
||||
|
||||
#ifdef RS_RELEASE_VERSION
|
||||
ui.attachPictureButton->setVisible(false);
|
||||
ui.attachPictureButton->setVisible(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -508,7 +488,7 @@ void PopupChatDialog::onPrivateChatChanged(int list, int type, bool initial /*=
|
||||
switch (type) {
|
||||
case NOTIFY_TYPE_ADD:
|
||||
{
|
||||
m_savedOfflineChat.clear();
|
||||
std::list<ChatInfo> savedOfflineChatNew;
|
||||
|
||||
QString name = QString::fromUtf8(rsPeers->getPeerName(rsPeers->getOwnId()).c_str());
|
||||
|
||||
@ -524,53 +504,45 @@ void PopupChatDialog::onPrivateChatChanged(int list, int type, bool initial /*=
|
||||
continue;
|
||||
}
|
||||
|
||||
m_savedOfflineChat.push_back(*it);
|
||||
savedOfflineChatNew.push_back(*it);
|
||||
|
||||
if (std::find(savedOfflineChat.begin(), savedOfflineChat.end(), *it) != savedOfflineChat.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
addChatMsg(false, name, sendTime, recvTime, message, TYPE_OFFLINE);
|
||||
}
|
||||
}
|
||||
|
||||
savedOfflineChat = savedOfflineChatNew;
|
||||
}
|
||||
break;
|
||||
case NOTIFY_TYPE_DEL:
|
||||
{
|
||||
if (m_manualDelete == false) {
|
||||
if (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++) {
|
||||
for(it = savedOfflineChat.begin(); it != 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);
|
||||
addChatMsg(false, name, sendTime, recvTime, message, TYPE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
m_savedOfflineChat.clear();
|
||||
savedOfflineChat.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ui.actionClearOfflineMessages->setEnabled(!m_savedOfflineChat.empty());
|
||||
ui.actionClearOfflineMessages->setEnabled(!savedOfflineChat.empty());
|
||||
}
|
||||
}
|
||||
|
||||
@ -593,7 +565,7 @@ void PopupChatDialog::insertChatMsgs()
|
||||
continue;
|
||||
}
|
||||
|
||||
addChatMsg(true, it->rsid, QString::fromUtf8(rsPeers->getPeerName(it->rsid).c_str()), QDateTime::fromTime_t(it->sendTime), QDateTime::fromTime_t(it->recvTime), QString::fromStdWString(it->msg), TYPE_NORMAL, true);
|
||||
addChatMsg(true, QString::fromUtf8(rsPeers->getPeerName(it->rsid).c_str()), QDateTime::fromTime_t(it->sendTime), QDateTime::fromTime_t(it->recvTime), QString::fromStdWString(it->msg), TYPE_NORMAL);
|
||||
}
|
||||
|
||||
rsMsgs->clearPrivateChatQueue(true, dialogId);
|
||||
@ -614,10 +586,8 @@ void PopupChatDialog::insertChatMsgs()
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
void PopupChatDialog::addChatMsg(bool incoming, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, enumChatType chatType)
|
||||
{
|
||||
std::string ownId = rsPeers->getOwnId();
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cout << "PopupChatDialog:addChatMsg message : " << message.toStdString() << std::endl;
|
||||
#endif
|
||||
@ -638,11 +608,7 @@ void PopupChatDialog::addChatMsg(bool incoming, const std::string &id, const QSt
|
||||
type = incoming ? ChatStyle::FORMATMSG_INCOMING : ChatStyle::FORMATMSG_OUTGOING;
|
||||
}
|
||||
|
||||
QString formatMsg = chatStyle.formatMessage(type, name, recvTime, message, formatFlag);
|
||||
|
||||
if (addToHistory) {
|
||||
historyKeeper.addMessage(incoming, id, name, sendTime, recvTime, message);
|
||||
}
|
||||
QString formatMsg = chatStyle.formatMessage(type, name, incoming ? sendTime : recvTime, message, formatFlag);
|
||||
|
||||
ui.textBrowser->append(formatMsg);
|
||||
|
||||
@ -694,7 +660,9 @@ void PopupChatDialog::sendChat()
|
||||
return;
|
||||
}
|
||||
|
||||
std::wstring msg = chatWidget->toHtml().toStdWString();
|
||||
QString text;
|
||||
RsHtml::optimizeHtml(chatWidget, text);
|
||||
std::wstring msg = text.toStdWString();
|
||||
|
||||
if (msg.empty()) {
|
||||
// nothing to send
|
||||
@ -718,7 +686,7 @@ void PopupChatDialog::sendChat()
|
||||
|
||||
if (rsMsgs->sendPrivateChat(dialogId, msg)) {
|
||||
QDateTime currentTime = QDateTime::currentDateTime();
|
||||
addChatMsg(false, ownId, QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()), currentTime, currentTime, QString::fromStdWString(msg), TYPE_NORMAL, true);
|
||||
addChatMsg(false, QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()), currentTime, currentTime, QString::fromStdWString(msg), TYPE_NORMAL);
|
||||
}
|
||||
|
||||
chatWidget->clear();
|
||||
@ -832,7 +800,7 @@ void PopupChatDialog::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();
|
||||
historyKeeper.clear();
|
||||
rsHistory->clear(dialogId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -953,7 +921,7 @@ void PopupChatDialog::fileHashingFinished(AttachFileItem* file)
|
||||
|
||||
if (rsMsgs->sendPrivateChat(dialogId, msg)) {
|
||||
QDateTime currentTime = QDateTime::currentDateTime();
|
||||
addChatMsg(false, ownId, QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()), currentTime, currentTime, QString::fromStdWString(msg), TYPE_NORMAL, true);
|
||||
addChatMsg(false, QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()), currentTime, currentTime, QString::fromStdWString(msg), TYPE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1076,9 +1044,9 @@ void PopupChatDialog::setCurrentFileName(const QString &fileName)
|
||||
|
||||
void PopupChatDialog::clearOfflineMessages()
|
||||
{
|
||||
m_manualDelete = true;
|
||||
manualDelete = true;
|
||||
rsMsgs->clearPrivateChatQueue(false, dialogId);
|
||||
m_manualDelete = false;
|
||||
manualDelete = false;
|
||||
}
|
||||
|
||||
void PopupChatDialog::updateStatus(const QString &peer_id, int status)
|
||||
@ -1150,7 +1118,7 @@ void PopupChatDialog::updatePeersCustomStateString(const QString& peer_id, const
|
||||
|
||||
void PopupChatDialog::on_actionMessageHistory_triggered()
|
||||
{
|
||||
ImHistoryBrowser imBrowser(dialogId, historyKeeper, ui.chattextEdit, window());
|
||||
ImHistoryBrowser imBrowser(dialogId, ui.chattextEdit, window());
|
||||
imBrowser.exec();
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,6 @@ class AttachFileItem;
|
||||
class ChatInfo;
|
||||
|
||||
#include <retroshare/rsmsgs.h>
|
||||
#include "gui/im_history/IMHistoryKeeper.h"
|
||||
#include "ChatStyle.h"
|
||||
#include "gui/style/RSStyle.h"
|
||||
|
||||
@ -77,7 +76,7 @@ protected:
|
||||
bool eventFilter(QObject *obj, QEvent *ev);
|
||||
|
||||
void insertChatMsgs();
|
||||
void addChatMsg(bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, enumChatType chatType, bool addToHistory);
|
||||
void addChatMsg(bool incoming, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, enumChatType chatType);
|
||||
|
||||
private slots:
|
||||
void pasteLink() ;
|
||||
@ -135,16 +134,15 @@ private:
|
||||
QColor mCurrentColor;
|
||||
QFont mCurrentFont;
|
||||
|
||||
std::list<ChatInfo> m_savedOfflineChat;
|
||||
std::list<ChatInfo> savedOfflineChat;
|
||||
QString wholeChat;
|
||||
QString fileName;
|
||||
|
||||
bool newMessages;
|
||||
bool typing;
|
||||
int peerStatus;
|
||||
IMHistoryKeeper historyKeeper;
|
||||
ChatStyle chatStyle;
|
||||
bool m_manualDelete;
|
||||
bool manualDelete;
|
||||
|
||||
RSStyle style;
|
||||
|
||||
|
@ -1,51 +0,0 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2009 The RetroShare Team, Oleksiy Bilyanskyy
|
||||
*
|
||||
* 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 "IMHistoryItem.h"
|
||||
|
||||
//============================================================================
|
||||
|
||||
IMHistoryItem::IMHistoryItem()
|
||||
{
|
||||
hiid = 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
IMHistoryItem::IMHistoryItem(int hiidIn, bool incomingIn, const std::string &idIn, const QString &nameIn, const QDateTime &sendTimeIn, const QDateTime &recvTimeIn, const QString &messageTextIn)
|
||||
{
|
||||
hiid = hiidIn;
|
||||
incoming = incomingIn;
|
||||
id = idIn;
|
||||
name = nameIn;
|
||||
sendTime = sendTimeIn;
|
||||
recvTime = recvTimeIn;
|
||||
messageText = messageTextIn;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
//! after qSort() older messages will become first
|
||||
bool
|
||||
IMHistoryItem::operator<(const IMHistoryItem& item) const
|
||||
{
|
||||
return (recvTime < item.recvTime) ;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2009 The RetroShare Team, Oleksiy Bilyanskyy
|
||||
*
|
||||
* 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.
|
||||
****************************************************************/
|
||||
|
||||
#ifndef __IM_history_item__
|
||||
#define __IM_history_item__
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
|
||||
class IMHistoryItem
|
||||
{
|
||||
public:
|
||||
IMHistoryItem();
|
||||
|
||||
IMHistoryItem(int hiid, bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &messageText);
|
||||
|
||||
int hiid;
|
||||
bool incoming;
|
||||
std::string id;
|
||||
QString name;
|
||||
QDateTime sendTime;
|
||||
QDateTime recvTime;
|
||||
QString messageText;
|
||||
|
||||
bool operator<(const IMHistoryItem& item) const;
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
@ -26,8 +26,6 @@
|
||||
#include <QString>
|
||||
#include <QStyleOption>
|
||||
|
||||
#include "IMHistoryItem.h"
|
||||
|
||||
class QPainter;
|
||||
|
||||
class IMHistoryItemPainter
|
||||
|
@ -1,267 +0,0 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2009 The RetroShare Team, Oleksiy Bilyanskyy
|
||||
*
|
||||
* 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 "IMHistoryKeeper.h"
|
||||
#include <iostream>
|
||||
|
||||
#include <QFile>
|
||||
#include <QIODevice>
|
||||
#include <QTimer>
|
||||
|
||||
#include <QtAlgorithms> //for qSort
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#include "IMHistoryReader.h"
|
||||
#include "IMHistoryWriter.h"
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
IMHistoryKeeper::IMHistoryKeeper()
|
||||
{
|
||||
historyChanged = false;
|
||||
|
||||
// save histroy every 10 seconds (when changed)
|
||||
saveTimer = new QTimer(this);
|
||||
saveTimer->connect(saveTimer, SIGNAL(timeout()), this, SLOT(saveHistory()));
|
||||
saveTimer->setInterval(10000);
|
||||
saveTimer->start();
|
||||
|
||||
lasthiid = 0;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
IMHistoryKeeper::~IMHistoryKeeper()
|
||||
{
|
||||
saveHistory();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void IMHistoryKeeper::init(QString historyFileName)
|
||||
{
|
||||
lasthiid = 0;
|
||||
|
||||
hfName = historyFileName;
|
||||
loadHistoryFile();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void IMHistoryKeeper::addMessage(bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &messageText)
|
||||
{
|
||||
IMHistoryItem item(++lasthiid, incoming, id, name, sendTime, recvTime, messageText);
|
||||
|
||||
hitems.append(item);
|
||||
|
||||
historyChanged = true;
|
||||
|
||||
emit historyAdd(item);
|
||||
|
||||
//std::cerr << "IMHistoryKeeper::addMessage "
|
||||
// << messageText.toStdString() << "\n";
|
||||
|
||||
//std::cerr << "IMHistoryKeeper::addMessage count is" << hitems.count();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
bool IMHistoryKeeper::loadHistoryFile()
|
||||
{
|
||||
qDebug() << " IMHistoryKeeper::loadHistoryFile is here";
|
||||
|
||||
if (hfName.isEmpty()) {
|
||||
lastErrorMessage = "history file not set";
|
||||
return false;
|
||||
}
|
||||
|
||||
QFile fl(hfName);
|
||||
if (!fl.exists()) {
|
||||
lastErrorMessage = QString("history file not found (%1)").arg(hfName) ;
|
||||
return false;
|
||||
}
|
||||
|
||||
IMHistoryReader hreader;
|
||||
if (!hreader.read(hitems, hfName, lasthiid)) {
|
||||
lastErrorMessage = hreader.errorMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
qSort(hitems.begin(), hitems.end());
|
||||
|
||||
qDebug() << " IMHistoryKeeper::loadHistoryFile finished";
|
||||
|
||||
historyChanged = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
QString IMHistoryKeeper::errorMessage()
|
||||
{
|
||||
QString errorMessage = lastErrorMessage;
|
||||
lastErrorMessage.clear();
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
bool IMHistoryKeeper::getMessages(QList<IMHistoryItem> &historyItems, const int messagesCount)
|
||||
{
|
||||
int messFound = 0;
|
||||
|
||||
historyItems.clear();
|
||||
|
||||
QListIterator<IMHistoryItem> hii(hitems);
|
||||
hii.toBack();
|
||||
while (hii.hasPrevious()) {
|
||||
IMHistoryItem hitem = hii.previous();
|
||||
|
||||
historyItems.insert(historyItems.begin(), hitem);
|
||||
messFound++;
|
||||
if (messagesCount && messFound >= messagesCount) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true; // successful end
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
bool IMHistoryKeeper::getMessage(int hiid, IMHistoryItem &item)
|
||||
{
|
||||
QList<IMHistoryItem>::iterator it;
|
||||
for (it = hitems.begin(); it != hitems.end(); it++) {
|
||||
if (it->hiid == hiid) {
|
||||
item = *it;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void IMHistoryKeeper::clear()
|
||||
{
|
||||
hitems.clear();
|
||||
historyChanged = true;
|
||||
|
||||
lasthiid = 0;
|
||||
|
||||
emit historyClear();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*static*/ bool IMHistoryKeeper::compareItem(const IMHistoryItem &item, bool incoming, const std::string &id, const QDateTime &sendTime, const QString &messageText)
|
||||
{
|
||||
// "\n" is not saved in xml
|
||||
QString copyMessage1(messageText);
|
||||
copyMessage1.replace("\n", "");
|
||||
|
||||
QString copyMessage2(item.messageText);
|
||||
copyMessage2.replace("\n", "");
|
||||
|
||||
if (item.incoming == incoming && item.id == id && item.sendTime == sendTime && copyMessage1 == copyMessage2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
bool IMHistoryKeeper::findMessage(bool incoming, const std::string &id, const QDateTime &sendTime, const QString &messageText, int &hiid)
|
||||
{
|
||||
hiid = 0;
|
||||
|
||||
QList<IMHistoryItem>::const_iterator it;
|
||||
for (it = hitems.begin(); it != hitems.end(); it++) {
|
||||
if (compareItem(*it, incoming, id, sendTime, messageText)) {
|
||||
hiid = it->hiid;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void IMHistoryKeeper::removeMessage(int hiid)
|
||||
{
|
||||
QList<IMHistoryItem>::iterator it;
|
||||
for (it = hitems.begin(); it != hitems.end(); it++) {
|
||||
if (it->hiid == hiid) {
|
||||
emit historyRemove(*it);
|
||||
hitems.erase(it);
|
||||
historyChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void IMHistoryKeeper::removeMessages(QList<int> &hiids)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
QList<IMHistoryItem>::iterator it = hitems.begin();
|
||||
while (it != hitems.end()) {
|
||||
if (qFind(hiids, it->hiid) != hiids.end()) {
|
||||
emit historyRemove(*it);
|
||||
|
||||
it = hitems.erase(it);
|
||||
|
||||
changed = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
historyChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void IMHistoryKeeper::saveHistory()
|
||||
{
|
||||
if (historyChanged && hfName.isEmpty() == false) {
|
||||
//=== we have to save all messages
|
||||
qSort( hitems.begin(), hitems.end() ) ; // not nesessary, but just in case...
|
||||
// it will not take a long time over ordered array
|
||||
|
||||
IMHistoryWriter wri;
|
||||
wri.write(hitems, hfName);
|
||||
|
||||
historyChanged = false;
|
||||
}
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2009 The RetroShare Team, Oleksiy Bilyanskyy
|
||||
*
|
||||
* 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.
|
||||
****************************************************************/
|
||||
|
||||
#ifndef _HISTORY_KEEPER_H_
|
||||
#define _HISTORY_KEEPER_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
|
||||
#include "IMHistoryItem.h"
|
||||
|
||||
class QTimer;
|
||||
|
||||
//! An engine for instant messaging history management
|
||||
|
||||
//! This class holds history for instant messages. It stores all messages
|
||||
//! in xml file. Something like
|
||||
//! <?xml version="1.0" encoding="UTF-8"?>
|
||||
//! <!DOCTYPE history_file>
|
||||
//! <history_file format_version="1.0">
|
||||
//! <message sendTime="10000" id="id" name="Name">manual message</message>
|
||||
//! ...
|
||||
//! other messages in <message..> ... </message> tags
|
||||
//! ...
|
||||
//! </history_file>
|
||||
//!
|
||||
//! The class loads all messages from the file after creation, and saves them
|
||||
//! at destruction. This means, the more history user has, the more memory
|
||||
//! will be used. Maybe it's not good, but it isn't so large, I think
|
||||
|
||||
class IMHistoryKeeper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IMHistoryKeeper();
|
||||
|
||||
//! A destructor
|
||||
|
||||
//! Warning: history messages will be saved to the file here. This means,
|
||||
//! a IMHistoryKeeper object must be deleted properly.
|
||||
virtual ~IMHistoryKeeper();
|
||||
|
||||
//! last error description
|
||||
QString errorMessage();
|
||||
|
||||
//! initialize history keeper
|
||||
void init(QString historyFileName);
|
||||
|
||||
//! Select messages from history
|
||||
|
||||
//! Fills given list with items
|
||||
bool getMessages(QList<IMHistoryItem> &historyItems, const int messagesCount);
|
||||
|
||||
//! Get message
|
||||
bool getMessage(int hiid, IMHistoryItem &item);
|
||||
|
||||
//! Adds new message to the history
|
||||
|
||||
//! Adds new message to the history, but the message will be saved to
|
||||
//! file only after destroing the object
|
||||
void addMessage(bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &messageText);
|
||||
|
||||
//! Clear the history
|
||||
void clear();
|
||||
|
||||
//! Find message
|
||||
static bool compareItem(const IMHistoryItem &item, bool incoming, const std::string &id, const QDateTime &sendTime, const QString &messageText);
|
||||
bool findMessage(bool incoming, const std::string &id, const QDateTime &sendTime, const QString &messageText, int &hiid);
|
||||
|
||||
//! Remove item
|
||||
void removeMessage(int hiid);
|
||||
|
||||
//! Remove items
|
||||
void removeMessages(QList<int> &hiids);
|
||||
|
||||
private:
|
||||
bool loadHistoryFile();
|
||||
|
||||
QList<IMHistoryItem> hitems;
|
||||
QString hfName ; //! history file name
|
||||
bool historyChanged;
|
||||
QString lastErrorMessage;
|
||||
QTimer *saveTimer;
|
||||
int lasthiid;
|
||||
|
||||
private slots:
|
||||
void saveHistory();
|
||||
|
||||
signals:
|
||||
void historyAdd(IMHistoryItem item) const;
|
||||
void historyRemove(IMHistoryItem item) const;
|
||||
void historyClear() const;
|
||||
};
|
||||
|
||||
#endif // _HISTORY_KEEPER_H_
|
@ -1,206 +0,0 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2009 The RetroShare Team, Oleksiy Bilyanskyy
|
||||
*
|
||||
* 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 "IMHistoryReader.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
//=============================================================================
|
||||
|
||||
IMHistoryReader::IMHistoryReader()
|
||||
:errMess("No error")
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
bool IMHistoryReader::read(QList<IMHistoryItem>& resultList, const QString fileName, int &lasthiid)
|
||||
{
|
||||
errMess = "No error";
|
||||
|
||||
resultList.clear();
|
||||
|
||||
//==== check for file and open it
|
||||
QFile fl(fileName);
|
||||
if (fl.exists()) {
|
||||
fl.open(QIODevice::ReadOnly);
|
||||
} else {
|
||||
errMess = QString("file not found (%1)").arg(fileName);
|
||||
return false ;
|
||||
}
|
||||
|
||||
//==== set the file, and check it once more
|
||||
setDevice(&fl);
|
||||
|
||||
if (atEnd()) {
|
||||
errMess = "end of document reached before anything happened";
|
||||
return false;
|
||||
}
|
||||
|
||||
//==== now, read the first element (it should be document element)
|
||||
while (!atEnd()) {
|
||||
readNext();
|
||||
if (isStartElement()) {
|
||||
if (name() == "history_file" && attributes().value("format_version") == "1.0") {
|
||||
readHistory(resultList, lasthiid);
|
||||
break;
|
||||
} else {
|
||||
errMess = "The file is not a history file with format version 1.0";
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error()) {
|
||||
errMess = errorString();
|
||||
// } else {
|
||||
// QList<IMHistoryItem>::const_iterator hii;//history items iterator
|
||||
// for (hii = result.constBegin(); hii != result.constEnd(); ++hii) {
|
||||
// resultList << *hii;
|
||||
// }
|
||||
}
|
||||
|
||||
return !error();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
QString IMHistoryReader::errorMessage()
|
||||
{
|
||||
QString result = errMess;
|
||||
errMess = "No error" ;
|
||||
return result;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void IMHistoryReader::readUnknownElement()
|
||||
{
|
||||
Q_ASSERT(isStartElement());
|
||||
|
||||
qDebug()<< " " << "unknown node " << name().toString();
|
||||
|
||||
while (!atEnd()) {
|
||||
readNext();
|
||||
if (isEndElement()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (isStartElement()) {
|
||||
readUnknownElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void IMHistoryReader::readHistory(QList<IMHistoryItem> &historyItems, int &lasthiid)
|
||||
{
|
||||
Q_ASSERT(isStartElement());
|
||||
|
||||
// qDebug()<< " " << "node with message " << name() ;
|
||||
|
||||
historyItems.clear();
|
||||
lasthiid = 0;
|
||||
|
||||
bool recalculate = false;
|
||||
|
||||
while (!atEnd()) {
|
||||
readNext();
|
||||
if (isEndElement()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (isStartElement()) {
|
||||
if ( name() == "message") {
|
||||
IMHistoryItem item;
|
||||
readMessage(item);
|
||||
if (item.hiid == 0) {
|
||||
recalculate = true;
|
||||
} else {
|
||||
if (item.hiid > lasthiid) {
|
||||
lasthiid = item.hiid;
|
||||
}
|
||||
}
|
||||
historyItems.append(item);
|
||||
} else {
|
||||
readUnknownElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recalculate) {
|
||||
// calculate hiid
|
||||
QList<IMHistoryItem>::iterator item = historyItems.begin();
|
||||
for (item = historyItems.begin(); item != historyItems.end(); item++) {
|
||||
if (item->hiid == 0) {
|
||||
item->hiid = ++lasthiid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void IMHistoryReader::readMessage(IMHistoryItem &historyItem)
|
||||
{
|
||||
// Q_ASSERT(isStartElement() );
|
||||
|
||||
if (isStartElement() && (name() == "message")) {
|
||||
//=== process attributes
|
||||
|
||||
historyItem.hiid = attributes().value("hiid").toString().toInt();
|
||||
historyItem.incoming = (attributes().value("incoming").toString().toInt() == 1);
|
||||
historyItem.id = attributes().value("id").toString().toStdString();
|
||||
historyItem.name = attributes().value("name").toString();
|
||||
|
||||
int ti = attributes().value("sendTime").toString().toInt();
|
||||
historyItem.sendTime = QDateTime::fromTime_t(ti);
|
||||
|
||||
ti = attributes().value("recvTime").toString().toInt();
|
||||
if (ti) {
|
||||
historyItem.recvTime = QDateTime::fromTime_t(ti);
|
||||
} else {
|
||||
historyItem.recvTime = historyItem.sendTime;
|
||||
}
|
||||
|
||||
//=== after processing attributes, read the message text
|
||||
QString tstr = readElementText();
|
||||
|
||||
//=== remove '\0' chars from the string. Is it a QXmlStuff bug,
|
||||
// if they appear?
|
||||
for (int i = 0; i< tstr.length(); i++) {
|
||||
if (tstr.at(i) == '\n') {
|
||||
tstr.remove(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
historyItem.messageText = tstr;
|
||||
|
||||
//qDebug() << QString(" readMessage: %1, %2, %3, %4" )
|
||||
// .arg(rez.text()).arg(rez.sender())
|
||||
// .arg(rez.receiver()).arg(ti) ;
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2009 The RetroShare Team, Oleksiy Bilyanskyy
|
||||
*
|
||||
* 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.
|
||||
****************************************************************/
|
||||
|
||||
#ifndef __IM_History_reader__
|
||||
#define __IM_History_reader__
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include "IMHistoryItem.h"
|
||||
|
||||
class IMHistoryReader : public QXmlStreamReader
|
||||
{
|
||||
public:
|
||||
IMHistoryReader();
|
||||
|
||||
bool read(QList<IMHistoryItem>& resultList, const QString fileName, int &lasthiid);
|
||||
|
||||
QString errorMessage();
|
||||
|
||||
private:
|
||||
void readUnknownElement();
|
||||
void readHistory(QList<IMHistoryItem> &historyItems, int &lasthiid);
|
||||
void readMessage(IMHistoryItem &historyItem);
|
||||
|
||||
QString errMess;
|
||||
} ;
|
||||
|
||||
#endif
|
||||
|
@ -1,93 +0,0 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2009 The RetroShare Team, Oleksiy Bilyanskyy
|
||||
*
|
||||
* 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 "IMHistoryWriter.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
|
||||
//=============================================================================
|
||||
|
||||
IMHistoryWriter::IMHistoryWriter()
|
||||
:errMess("No error")
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
bool IMHistoryWriter::write(QList<IMHistoryItem>& itemList, const QString fileName)
|
||||
{
|
||||
qDebug() << " IMHistoryWriter::write is here" ;
|
||||
|
||||
errMess = "No error";
|
||||
|
||||
if (itemList.size() == 0) {
|
||||
return remove(fileName);
|
||||
}
|
||||
|
||||
//==== check for file and open it
|
||||
QFile fl(fileName);
|
||||
if (fl.open(QIODevice::WriteOnly | QIODevice::Truncate) == false) {
|
||||
errMess = QString("error opening file %1 (code %2)")
|
||||
.arg(fileName).arg( fl.error() );
|
||||
return false;
|
||||
}
|
||||
|
||||
//==== set the file, and check it once more
|
||||
setDevice(&fl);
|
||||
|
||||
writeStartDocument();
|
||||
writeDTD("<!DOCTYPE history_file>");
|
||||
writeStartElement("history_file");
|
||||
writeAttribute("format_version", "1.0");
|
||||
|
||||
foreach(IMHistoryItem item, itemList) {
|
||||
writeStartElement("message");
|
||||
writeAttribute("hiid", QString::number(item.hiid));
|
||||
writeAttribute("incoming", QString::number(item.incoming ? 1 : 0));
|
||||
writeAttribute("id", QString::fromStdString(item.id));
|
||||
writeAttribute("name", item.name);
|
||||
writeAttribute("sendTime", QString::number(item.sendTime.toTime_t()));
|
||||
writeAttribute("recvTime", QString::number(item.recvTime.toTime_t()));
|
||||
writeCDATA(item.messageText);
|
||||
writeEndElement();
|
||||
}
|
||||
|
||||
writeEndDocument() ;
|
||||
|
||||
fl.close();
|
||||
|
||||
qDebug() << " IMHistoryWriter::write done" ;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IMHistoryWriter::remove(const QString &fileName)
|
||||
{
|
||||
if (!QFile::remove(fileName)) {
|
||||
qDebug() << " IMHistoryWriter::remove Failed to remove history file";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2009 The RetroShare Team, Oleksiy Bilyanskyy
|
||||
*
|
||||
* 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.
|
||||
****************************************************************/
|
||||
|
||||
#ifndef __IM_History_writer__
|
||||
#define __IM_History_writer__
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
#include <QString>
|
||||
//#include <QStringList>
|
||||
|
||||
#include "IMHistoryItem.h"
|
||||
|
||||
class IMHistoryWriter : public QXmlStreamWriter
|
||||
{
|
||||
public:
|
||||
IMHistoryWriter();
|
||||
|
||||
bool write(QList<IMHistoryItem>& itemList,
|
||||
const QString fileName );
|
||||
|
||||
//! remove history file
|
||||
bool remove(const QString& fileName);
|
||||
|
||||
QString errorMessage();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
QString errMess;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -34,16 +34,18 @@
|
||||
#include "IMHistoryItemPainter.h"
|
||||
|
||||
#include "rshare.h"
|
||||
#include <retroshare/rshistory.h>
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
#include "gui/notifyqt.h"
|
||||
|
||||
#define ROLE_HIID Qt::UserRole
|
||||
#define ROLE_MSGID Qt::UserRole
|
||||
#define ROLE_PLAINTEXT Qt::UserRole + 1
|
||||
#define ROLE_OFFLINE Qt::UserRole + 2
|
||||
|
||||
ImHistoryBrowserCreateItemsThread::ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, IMHistoryKeeper &histKeeper)
|
||||
: QThread(parent), m_historyKeeper(histKeeper)
|
||||
ImHistoryBrowserCreateItemsThread::ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, const std::string& peerId)
|
||||
: QThread(parent)
|
||||
{
|
||||
m_peerId = peerId;
|
||||
m_historyBrowser = parent;
|
||||
stopped = false;
|
||||
}
|
||||
@ -68,17 +70,18 @@ void ImHistoryBrowserCreateItemsThread::stop()
|
||||
|
||||
void ImHistoryBrowserCreateItemsThread::run()
|
||||
{
|
||||
QList<IMHistoryItem> historyItems;
|
||||
m_historyKeeper.getMessages(historyItems, 0);
|
||||
std::list<HistoryMsg> historyMsgs;
|
||||
rsHistory->getMessages(m_peerId, historyMsgs, 0);
|
||||
|
||||
int count = historyItems.count();
|
||||
int count = historyMsgs.size();
|
||||
int current = 0;
|
||||
|
||||
foreach(IMHistoryItem item, historyItems) {
|
||||
std::list<HistoryMsg>::iterator it;
|
||||
for (it = historyMsgs.begin(); it != historyMsgs.end(); it++) {
|
||||
if (stopped) {
|
||||
break;
|
||||
}
|
||||
QListWidgetItem *itemWidget = m_historyBrowser->createItem(item);
|
||||
QListWidgetItem *itemWidget = m_historyBrowser->createItem(*it);
|
||||
if (itemWidget) {
|
||||
m_items.push_back(itemWidget);
|
||||
emit progress(++current, count);
|
||||
@ -87,8 +90,8 @@ void ImHistoryBrowserCreateItemsThread::run()
|
||||
}
|
||||
|
||||
/** Default constructor */
|
||||
ImHistoryBrowser::ImHistoryBrowser(const std::string &peerId, IMHistoryKeeper &histKeeper, QTextEdit *edit, QWidget *parent, Qt::WFlags flags)
|
||||
: QDialog(parent, flags), historyKeeper(histKeeper)
|
||||
ImHistoryBrowser::ImHistoryBrowser(const std::string &peerId, QTextEdit *edit, QWidget *parent, Qt::WFlags flags)
|
||||
: QDialog(parent, flags)
|
||||
{
|
||||
/* Invoke Qt Designer generated QObject setup routine */
|
||||
ui.setupUi(this);
|
||||
@ -97,9 +100,7 @@ ImHistoryBrowser::ImHistoryBrowser(const std::string &peerId, IMHistoryKeeper &h
|
||||
m_isPrivateChat = !m_peerId.empty();
|
||||
textEdit = edit;
|
||||
|
||||
connect(&historyKeeper, SIGNAL(historyAdd(IMHistoryItem)), this, SLOT(historyAdd(IMHistoryItem)));
|
||||
connect(&historyKeeper, SIGNAL(historyRemove(IMHistoryItem)), this, SLOT(historyRemove(IMHistoryItem)));
|
||||
connect(&historyKeeper, SIGNAL(historyClear()), this, SLOT(historyClear()));
|
||||
connect(NotifyQt::getInstance(), SIGNAL(historyChanged(uint, int)), this, SLOT(historyChanged(uint, int)));
|
||||
|
||||
connect(ui.clearFilterButton, SIGNAL(clicked()), this, SLOT(clearFilter()));
|
||||
connect(ui.filterPatternLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterRegExpChanged()));
|
||||
@ -110,8 +111,6 @@ ImHistoryBrowser::ImHistoryBrowser(const std::string &peerId, IMHistoryKeeper &h
|
||||
connect(ui.listWidget, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
|
||||
connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customContextMenuRequested(QPoint)));
|
||||
|
||||
connect(NotifyQt::getInstance(), SIGNAL(privateChatChanged(int,int)), this, SLOT(privateChatChanged(int,int)));
|
||||
|
||||
ui.clearFilterButton->hide();
|
||||
|
||||
// embed smileys ?
|
||||
@ -125,9 +124,6 @@ ImHistoryBrowser::ImHistoryBrowser(const std::string &peerId, IMHistoryKeeper &h
|
||||
|
||||
ui.listWidget->setItemDelegate(new IMHistoryItemDelegate);
|
||||
|
||||
// call once
|
||||
privateChatChanged(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD);
|
||||
|
||||
QByteArray geometry = Settings->valueFromGroup("HistorieBrowser", "Geometry", QByteArray()).toByteArray();
|
||||
if (geometry.isEmpty() == false) {
|
||||
restoreGeometry(geometry);
|
||||
@ -138,7 +134,7 @@ ImHistoryBrowser::ImHistoryBrowser(const std::string &peerId, IMHistoryKeeper &h
|
||||
|
||||
ui.listWidget->installEventFilter(this);
|
||||
|
||||
m_createThread = new ImHistoryBrowserCreateItemsThread(this, historyKeeper);
|
||||
m_createThread = new ImHistoryBrowserCreateItemsThread(this, m_peerId);
|
||||
connect(m_createThread, SIGNAL(finished()), this, SLOT(createThreadFinished()));
|
||||
connect(m_createThread, SIGNAL(progress(int,int)), this, SLOT(createThreadProgress(int,int)));
|
||||
m_createThread->start();
|
||||
@ -178,11 +174,11 @@ void ImHistoryBrowser::createThreadFinished()
|
||||
m_createThread->deleteLater();
|
||||
m_createThread = NULL;
|
||||
|
||||
QList<IMHistoryItem>::iterator histIt;
|
||||
for (histIt = m_itemsAddedOnLoad.begin(); histIt != m_itemsAddedOnLoad.end(); histIt++) {
|
||||
QList<HistoryMsg>::iterator histIt;
|
||||
for (histIt = itemsAddedOnLoad.begin(); histIt != itemsAddedOnLoad.end(); histIt++) {
|
||||
historyAdd(*histIt);
|
||||
}
|
||||
m_itemsAddedOnLoad.clear();
|
||||
itemsAddedOnLoad.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,39 +206,56 @@ bool ImHistoryBrowser::eventFilter(QObject *obj, QEvent *event)
|
||||
return QDialog::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void ImHistoryBrowser::historyAdd(IMHistoryItem item)
|
||||
void ImHistoryBrowser::historyAdd(HistoryMsg& msg)
|
||||
{
|
||||
if (m_createThread) {
|
||||
// create later
|
||||
m_itemsAddedOnLoad.push_back(item);
|
||||
itemsAddedOnLoad.push_back(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
QListWidgetItem *itemWidget = createItem(item);
|
||||
QListWidgetItem *itemWidget = createItem(msg);
|
||||
if (itemWidget) {
|
||||
ui.listWidget->addItem(itemWidget);
|
||||
filterItems(itemWidget);
|
||||
}
|
||||
}
|
||||
|
||||
void ImHistoryBrowser::historyRemove(IMHistoryItem item)
|
||||
void ImHistoryBrowser::historyChanged(uint msgId, int type)
|
||||
{
|
||||
int count = ui.listWidget->count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
QListWidgetItem *itemWidget = ui.listWidget->item(i);
|
||||
if (itemWidget->data(ROLE_HIID).toString().toInt() == item.hiid) {
|
||||
delete(ui.listWidget->takeItem(i));
|
||||
break;
|
||||
if (type == NOTIFY_TYPE_ADD) {
|
||||
/* history message added */
|
||||
HistoryMsg msg;
|
||||
if (rsHistory->getMessage(msgId, msg) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
historyAdd(msg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == NOTIFY_TYPE_DEL) {
|
||||
/* history message removed */
|
||||
int count = ui.listWidget->count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
QListWidgetItem *itemWidget = ui.listWidget->item(i);
|
||||
if (itemWidget->data(ROLE_MSGID).toString().toUInt() == msgId) {
|
||||
delete(ui.listWidget->takeItem(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == NOTIFY_TYPE_MOD) {
|
||||
/* clear history */
|
||||
ui.listWidget->clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ImHistoryBrowser::historyClear()
|
||||
{
|
||||
ui.listWidget->clear();
|
||||
}
|
||||
|
||||
void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, IMHistoryItem &item)
|
||||
void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, HistoryMsg& msg)
|
||||
{
|
||||
unsigned int formatFlag = CHAT_FORMATMSG_EMBED_LINKS;
|
||||
|
||||
@ -250,49 +263,30 @@ void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, IMHistoryItem &item
|
||||
formatFlag |= CHAT_FORMATMSG_EMBED_SMILEYS;
|
||||
}
|
||||
|
||||
std::list<ChatInfo>::iterator offineChatIt;
|
||||
for(offineChatIt = m_savedOfflineChat.begin(); offineChatIt != m_savedOfflineChat.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)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ChatStyle::enumFormatMessage type;
|
||||
if (offineChatIt == m_savedOfflineChat.end()) {
|
||||
if (item.incoming) {
|
||||
type = ChatStyle::FORMATMSG_INCOMING;
|
||||
} else {
|
||||
type = ChatStyle::FORMATMSG_OUTGOING;
|
||||
}
|
||||
if (msg.incoming) {
|
||||
type = ChatStyle::FORMATMSG_INCOMING;
|
||||
} else {
|
||||
type = ChatStyle::FORMATMSG_OOUTGOING;
|
||||
type = ChatStyle::FORMATMSG_OUTGOING;
|
||||
}
|
||||
|
||||
QString formatMsg = style.formatMessage(type, item.name, item.sendTime, item.messageText, formatFlag);
|
||||
QString messageText = QString::fromUtf8(msg.message.c_str());
|
||||
QString formatMsg = style.formatMessage(type, QString::fromUtf8(msg.peerName.c_str()), QDateTime::fromTime_t(msg.sendTime), messageText, formatFlag);
|
||||
|
||||
itemWidget->setData(Qt::DisplayRole, qVariantFromValue(IMHistoryItemPainter(formatMsg)));
|
||||
itemWidget->setData(ROLE_HIID, item.hiid);
|
||||
itemWidget->setData(ROLE_MSGID, msg.msgId);
|
||||
itemWidget->setData(ROLE_OFFLINE, (type == ChatStyle::FORMATMSG_OOUTGOING) ? true : false);
|
||||
|
||||
/* calculate plain text */
|
||||
QTextDocument doc;
|
||||
doc.setHtml(item.messageText);
|
||||
doc.setHtml(messageText);
|
||||
itemWidget->setData(ROLE_PLAINTEXT, doc.toPlainText());
|
||||
}
|
||||
|
||||
QListWidgetItem *ImHistoryBrowser::createItem(IMHistoryItem &item)
|
||||
QListWidgetItem *ImHistoryBrowser::createItem(HistoryMsg& msg)
|
||||
{
|
||||
QListWidgetItem *itemWidget = new QListWidgetItem;
|
||||
fillItem(itemWidget, item);
|
||||
fillItem(itemWidget, msg);
|
||||
return itemWidget;
|
||||
}
|
||||
|
||||
@ -346,7 +340,7 @@ void ImHistoryBrowser::filterItems(QListWidgetItem *item)
|
||||
}
|
||||
}
|
||||
|
||||
void ImHistoryBrowser::getSelectedItems(QList<int> &items)
|
||||
void ImHistoryBrowser::getSelectedItems(std::list<uint32_t> &items)
|
||||
{
|
||||
QList<QListWidgetItem*> itemWidgets = ui.listWidget->selectedItems();
|
||||
|
||||
@ -356,16 +350,16 @@ void ImHistoryBrowser::getSelectedItems(QList<int> &items)
|
||||
if (item->isHidden()) {
|
||||
continue;
|
||||
}
|
||||
items.append(item->data(ROLE_HIID).toString().toInt());
|
||||
items.push_back(item->data(ROLE_MSGID).toString().toInt());
|
||||
}
|
||||
}
|
||||
|
||||
void ImHistoryBrowser::itemSelectionChanged()
|
||||
{
|
||||
QList<int> hiids;
|
||||
getSelectedItems(hiids);
|
||||
std::list<uint32_t> msgIds;
|
||||
getSelectedItems(msgIds);
|
||||
|
||||
if (hiids.size()) {
|
||||
if (msgIds.size()) {
|
||||
// activate buttons
|
||||
ui.copyButton->setEnabled(true);
|
||||
ui.removeButton->setEnabled(true);
|
||||
@ -378,8 +372,8 @@ void ImHistoryBrowser::itemSelectionChanged()
|
||||
|
||||
void ImHistoryBrowser::customContextMenuRequested(QPoint /*pos*/)
|
||||
{
|
||||
QList<int> hiids;
|
||||
getSelectedItems(hiids);
|
||||
std::list<uint32_t> msgIds;
|
||||
getSelectedItems(msgIds);
|
||||
|
||||
QListWidgetItem *currentItem = ui.listWidget->currentItem();
|
||||
|
||||
@ -400,7 +394,7 @@ void ImHistoryBrowser::customContextMenuRequested(QPoint /*pos*/)
|
||||
}
|
||||
}
|
||||
|
||||
if (hiids.size()) {
|
||||
if (msgIds.size()) {
|
||||
connect(selectAll, SIGNAL(triggered()), ui.listWidget, SLOT(selectAll()));
|
||||
connect(copyMessage, SIGNAL(triggered()), this, SLOT(copyMessage()));
|
||||
connect(removeMessages, SIGNAL(triggered()), this, SLOT(removeMessages()));
|
||||
@ -429,11 +423,11 @@ void ImHistoryBrowser::copyMessage()
|
||||
{
|
||||
QListWidgetItem *currentItem = ui.listWidget->currentItem();
|
||||
if (currentItem) {
|
||||
int hiid = currentItem->data(ROLE_HIID).toString().toInt();
|
||||
IMHistoryItem item;
|
||||
if (historyKeeper.getMessage(hiid, item)) {
|
||||
uint32_t msgId = currentItem->data(ROLE_MSGID).toString().toInt();
|
||||
HistoryMsg msg;
|
||||
if (rsHistory->getMessage(msgId, msg)) {
|
||||
QTextDocument doc;
|
||||
doc.setHtml(item.messageText);
|
||||
doc.setHtml(QString::fromUtf8(msg.message.c_str()));
|
||||
QApplication::clipboard()->setText(doc.toPlainText());
|
||||
}
|
||||
}
|
||||
@ -441,15 +435,15 @@ void ImHistoryBrowser::copyMessage()
|
||||
|
||||
void ImHistoryBrowser::removeMessages()
|
||||
{
|
||||
QList<int> hiids;
|
||||
getSelectedItems(hiids);
|
||||
std::list<uint32_t> msgIds;
|
||||
getSelectedItems(msgIds);
|
||||
|
||||
historyKeeper.removeMessages(hiids);
|
||||
rsHistory->removeMessages(msgIds);
|
||||
}
|
||||
|
||||
void ImHistoryBrowser::clearHistory()
|
||||
{
|
||||
historyKeeper.clear();
|
||||
rsHistory->clear(m_peerId);
|
||||
}
|
||||
|
||||
void ImHistoryBrowser::sendMessage()
|
||||
@ -457,11 +451,11 @@ void ImHistoryBrowser::sendMessage()
|
||||
if (textEdit) {
|
||||
QListWidgetItem *currentItem = ui.listWidget->currentItem();
|
||||
if (currentItem) {
|
||||
int hiid = currentItem->data(ROLE_HIID).toString().toInt();
|
||||
IMHistoryItem item;
|
||||
if (historyKeeper.getMessage(hiid, item)) {
|
||||
uint32_t msgId = currentItem->data(ROLE_MSGID).toString().toInt();
|
||||
HistoryMsg msg;
|
||||
if (rsHistory->getMessage(msgId, msg)) {
|
||||
textEdit->clear();
|
||||
textEdit->setText(item.messageText);
|
||||
textEdit->setText(QString::fromUtf8(msg.message.c_str()));
|
||||
textEdit->setFocus();
|
||||
QTextCursor cursor = textEdit->textCursor();
|
||||
cursor.movePosition(QTextCursor::End);
|
||||
@ -471,45 +465,3 @@ void ImHistoryBrowser::sendMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImHistoryBrowser::privateChatChanged(int list, int type)
|
||||
{
|
||||
if (m_isPrivateChat == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (list == NOTIFY_LIST_PRIVATE_OUTGOING_CHAT) {
|
||||
switch (type) {
|
||||
case NOTIFY_TYPE_ADD:
|
||||
{
|
||||
m_savedOfflineChat.clear();
|
||||
rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, m_peerId, m_savedOfflineChat);
|
||||
}
|
||||
break;
|
||||
case NOTIFY_TYPE_DEL:
|
||||
{
|
||||
m_savedOfflineChat.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// recalculate items in history
|
||||
int count = ui.listWidget->count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
QListWidgetItem *itemWidget = ui.listWidget->item(i);
|
||||
|
||||
if (itemWidget->data(ROLE_OFFLINE).toBool()) {
|
||||
int hiid = itemWidget->data(ROLE_HIID).toInt();
|
||||
|
||||
IMHistoryItem item;
|
||||
if (historyKeeper.getMessage(hiid, item) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fillItem(itemWidget, item);
|
||||
}
|
||||
}
|
||||
|
||||
filterRegExpChanged();
|
||||
}
|
||||
}
|
||||
|
@ -27,13 +27,13 @@
|
||||
#include <QThread>
|
||||
|
||||
#include <retroshare/rsmsgs.h>
|
||||
#include "IMHistoryKeeper.h"
|
||||
#include "gui/chat/ChatStyle.h"
|
||||
|
||||
#include "ui_ImHistoryBrowser.h"
|
||||
|
||||
class QTextEdit;
|
||||
class ImHistoryBrowserCreateItemsThread;
|
||||
class HistoryMsg;
|
||||
|
||||
class ImHistoryBrowser : public QDialog
|
||||
{
|
||||
@ -43,7 +43,7 @@ class ImHistoryBrowser : public QDialog
|
||||
|
||||
public:
|
||||
/** Default constructor */
|
||||
ImHistoryBrowser(const std::string &peerId, IMHistoryKeeper &histKeeper, QTextEdit *edit, QWidget *parent = 0, Qt::WFlags flags = 0);
|
||||
ImHistoryBrowser(const std::string &peerId, QTextEdit *edit, QWidget *parent = 0, Qt::WFlags flags = 0);
|
||||
/** Default destructor */
|
||||
virtual ~ImHistoryBrowser();
|
||||
|
||||
@ -54,9 +54,7 @@ private slots:
|
||||
void createThreadFinished();
|
||||
void createThreadProgress(int current, int count);
|
||||
|
||||
void historyAdd(IMHistoryItem item);
|
||||
void historyRemove(IMHistoryItem item);
|
||||
void historyClear();
|
||||
void historyChanged(uint msgId, int type);
|
||||
|
||||
void filterRegExpChanged();
|
||||
void clearFilter();
|
||||
@ -69,14 +67,15 @@ private slots:
|
||||
void clearHistory();
|
||||
void sendMessage();
|
||||
|
||||
void privateChatChanged(int list, int type);
|
||||
|
||||
private:
|
||||
QListWidgetItem *createItem(IMHistoryItem &item);
|
||||
void fillItem(QListWidgetItem *itemWidget, IMHistoryItem &item);
|
||||
void historyAdd(HistoryMsg& msg);
|
||||
|
||||
QListWidgetItem *createItem(HistoryMsg& msg);
|
||||
void fillItem(QListWidgetItem *itemWidget, HistoryMsg& msg);
|
||||
void filterItems(QListWidgetItem *item = NULL);
|
||||
|
||||
void getSelectedItems(QList<int> &items);
|
||||
void getSelectedItems(std::list<uint32_t> &items);
|
||||
|
||||
ImHistoryBrowserCreateItemsThread *m_createThread;
|
||||
|
||||
@ -84,11 +83,9 @@ private:
|
||||
bool m_isPrivateChat;
|
||||
QTextEdit *textEdit;
|
||||
bool embedSmileys;
|
||||
IMHistoryKeeper &historyKeeper;
|
||||
ChatStyle style;
|
||||
|
||||
std::list<ChatInfo> m_savedOfflineChat;
|
||||
QList<IMHistoryItem> m_itemsAddedOnLoad;
|
||||
QList<HistoryMsg> itemsAddedOnLoad;
|
||||
|
||||
/** Qt Designer generated object */
|
||||
Ui::ImHistoryBrowser ui;
|
||||
@ -99,7 +96,7 @@ class ImHistoryBrowserCreateItemsThread : public QThread
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, IMHistoryKeeper &histKeeper);
|
||||
ImHistoryBrowserCreateItemsThread(ImHistoryBrowser *parent, const std::string& peerId);
|
||||
~ImHistoryBrowserCreateItemsThread();
|
||||
|
||||
void run();
|
||||
@ -113,8 +110,8 @@ public:
|
||||
QList<QListWidgetItem*> m_items;
|
||||
|
||||
private:
|
||||
IMHistoryKeeper &m_historyKeeper;
|
||||
ImHistoryBrowser *m_historyBrowser;
|
||||
std::string m_peerId;
|
||||
volatile bool stopped;
|
||||
};
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "TagsMenu.h"
|
||||
#include "gui/common/TagDefs.h"
|
||||
#include "gui/connect/ConfCertDialog.h"
|
||||
#include "gui/chat/HandleRichText.h"
|
||||
|
||||
#define IMAGE_GROUP16 ":/images/user/group16.png"
|
||||
#define IMAGE_FRIENDINFO ":/images/peerdetails_16x16.png"
|
||||
@ -1164,12 +1165,9 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
|
||||
mi.title = misc::removeNewLine(ui.titleEdit->text()).toStdWString();
|
||||
mi.msg = ui.msgText->toHtml().toStdWString();
|
||||
|
||||
if(ui.msgText->toHtml() == QTextDocument(ui.msgText->toPlainText()).toHtml())
|
||||
{
|
||||
mi.msg = ui.msgText->toPlainText().toStdWString() ;
|
||||
std::cerr << "Optimized forum message to " << mi.msg.length() << " bytes , instead of " << ui.msgText->toHtml().length() << std::endl;
|
||||
}
|
||||
|
||||
QString text;
|
||||
RsHtml::optimizeHtml(ui.msgText, text);
|
||||
mi.msg = text.toStdWString() ;
|
||||
|
||||
/* check for existing title */
|
||||
if (bDraftbox == false && mi.title.empty()) {
|
||||
|
@ -277,11 +277,10 @@ void NotifyQt::notifyHashingInfo(uint32_t type, const std::string& fileinfo)
|
||||
emit hashingInfoChanged(info);
|
||||
}
|
||||
|
||||
//void NotifyQt::notifyChat()
|
||||
//{
|
||||
// std::cerr << "Received chat notification" << std::endl ;
|
||||
// return;
|
||||
//}
|
||||
void NotifyQt::notifyHistoryChanged(uint32_t msgId, int type)
|
||||
{
|
||||
emit historyChanged(msgId, type);
|
||||
}
|
||||
|
||||
void NotifyQt::notifyListChange(int list, int type)
|
||||
{
|
||||
|
@ -48,6 +48,7 @@ class NotifyQt: public QObject, public NotifyBase
|
||||
/* one or more peers has changed the states */
|
||||
virtual void notifyPeerStatusChangedSummary();
|
||||
virtual void notifyChannelMsgReadSatusChanged(const std::string& channelId, const std::string& msgId, uint32_t status);
|
||||
virtual void notifyHistoryChanged(uint32_t msgId, int type);
|
||||
|
||||
virtual void notifyDiscInfoChanged() ;
|
||||
virtual void notifyDownloadComplete(const std::string& fileHash);
|
||||
@ -90,6 +91,7 @@ class NotifyQt: public QObject, public NotifyBase
|
||||
void downloadComplete(const QString& /* fileHash */);
|
||||
void downloadCompleteCountChanged(int /* count */);
|
||||
void channelMsgReadSatusChanged(const QString& channelId, const QString& msgId, int status);
|
||||
void historyChanged(uint msgId, int type);
|
||||
|
||||
/* Notify from GUI */
|
||||
void chatStyleChanged(int /*ChatStyle::enumStyleType*/ styleType);
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "gui/notifyqt.h"
|
||||
#include "rsharesettings.h"
|
||||
|
||||
#include <retroshare/rshistory.h>
|
||||
|
||||
#define VARIANT_STANDARD "Standard"
|
||||
|
||||
static QString loadStyleInfo(ChatStyle::enumStyleType type, QListWidget *listWidget, QComboBox *comboBox, QString &styleVariant)
|
||||
@ -96,19 +98,22 @@ bool
|
||||
ChatPage::save(QString &/*errmsg*/)
|
||||
{
|
||||
Settings->beginGroup(QString("Chat"));
|
||||
|
||||
Settings->setValue(QString::fromUtf8("Emoteicons_PrivatChat"), ui.checkBox_emoteprivchat->isChecked());
|
||||
Settings->setValue(QString::fromUtf8("Emoteicons_GroupChat"), ui.checkBox_emotegroupchat->isChecked());
|
||||
Settings->setValue(QString::fromUtf8("GroupChat_History"), ui.checkBox_groupchathistory->isChecked());
|
||||
Settings->setValue(QString::fromUtf8("PrivateChat_History"), ui.checkBox_privatechathistory->isChecked());
|
||||
Settings->endGroup();
|
||||
|
||||
Settings->setChatScreenFont(fontTempChat.toString());
|
||||
|
||||
Settings->setChatSendMessageWithCtrlReturn(ui.sendMessageWithCtrlReturn->isChecked());
|
||||
|
||||
Settings->setPublicChatHistoryCount(ui.groupchatspinBox->value());
|
||||
Settings->setPrivateChatHistoryCount(ui.privatchatspinBox->value());
|
||||
Settings->setPublicChatHistoryCount(ui.publicChatLoadCount->value());
|
||||
Settings->setPrivateChatHistoryCount(ui.privateChatLoadCount->value());
|
||||
|
||||
rsHistory->setEnable(true, ui.publicChatEnable->isChecked());
|
||||
rsHistory->setEnable(false, ui.privateChatEnable->isChecked());
|
||||
|
||||
rsHistory->setSaveCount(true, ui.publicChatSaveCount->value());
|
||||
rsHistory->setSaveCount(false, ui.privateChatSaveCount->value());
|
||||
|
||||
ChatStyleInfo info;
|
||||
QListWidgetItem *item = ui.publicList->currentItem();
|
||||
@ -146,20 +151,22 @@ void
|
||||
ChatPage::load()
|
||||
{
|
||||
Settings->beginGroup(QString("Chat"));
|
||||
|
||||
ui.checkBox_emoteprivchat->setChecked(Settings->value(QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool());
|
||||
ui.checkBox_emotegroupchat->setChecked(Settings->value(QString::fromUtf8("Emoteicons_GroupChat"), true).toBool());
|
||||
ui.checkBox_groupchathistory->setChecked(Settings->value(QString::fromUtf8("GroupChat_History"), true).toBool());
|
||||
ui.checkBox_privatechathistory->setChecked(Settings->value(QString::fromUtf8("PrivateChat_History"), true).toBool());
|
||||
|
||||
Settings->endGroup();
|
||||
|
||||
fontTempChat.fromString(Settings->getChatScreenFont());
|
||||
|
||||
ui.sendMessageWithCtrlReturn->setChecked(Settings->getChatSendMessageWithCtrlReturn());
|
||||
|
||||
ui.groupchatspinBox->setValue(Settings->getPublicChatHistoryCount());
|
||||
ui.privatchatspinBox->setValue(Settings->getPrivateChatHistoryCount());
|
||||
ui.publicChatLoadCount->setValue(Settings->getPublicChatHistoryCount());
|
||||
ui.privateChatLoadCount->setValue(Settings->getPrivateChatHistoryCount());
|
||||
|
||||
ui.publicChatEnable->setChecked(rsHistory->getEnable(true));
|
||||
ui.privateChatEnable->setChecked(rsHistory->getEnable(false));
|
||||
|
||||
ui.publicChatSaveCount->setValue(rsHistory->getSaveCount(true));
|
||||
ui.privateChatSaveCount->setValue(rsHistory->getSaveCount(false));
|
||||
|
||||
ui.labelChatFontPreview->setText(fontTempChat.rawName());
|
||||
ui.labelChatFontPreview->setFont(fontTempChat);
|
||||
|
@ -532,7 +532,24 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="6">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_emotegroupchat">
|
||||
<property name="text">
|
||||
<string>Enable Emoticons Group Chat</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="sendMessageWithCtrlReturn">
|
||||
<property name="text">
|
||||
<string>Send message with Ctrl+Return</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="4">
|
||||
<widget class="QGroupBox" name="groupBoxIRCColors">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
@ -605,110 +622,161 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="history">
|
||||
<attribute name="title">
|
||||
<string>History</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="publicChat">
|
||||
<property name="title">
|
||||
<string>Group Chat</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="publicChatEnable">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_emotegroupchat">
|
||||
<property name="text">
|
||||
<string>Enable Emoticons Group Chat</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_privatechathistory">
|
||||
<property name="text">
|
||||
<string>Enable Private Chat History</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_groupchathistory">
|
||||
<property name="text">
|
||||
<string>Enable Group Chat History</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="sendMessageWithCtrlReturn">
|
||||
<property name="text">
|
||||
<string>Send message with Ctrl+Return</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Chat History</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Load number of messages (0 = off)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Group Chat</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="groupchatspinBox">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Private Chat</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="privatchatspinBox">
|
||||
<property name="maximum">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>176</width>
|
||||
<height>480</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label1">
|
||||
<property name="text">
|
||||
<string>Number of saved messages (0 = unlimited)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="publicChatSaveCount">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000000000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="publicChatLoadCount">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label2">
|
||||
<property name="text">
|
||||
<string>Load number of messages (0 = off)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="privateChat">
|
||||
<property name="title">
|
||||
<string>Private Chat</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="privateChatEnable">
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label3">
|
||||
<property name="text">
|
||||
<string>Number of saved messages (0 = unlimited)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="privateChatSaveCount">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000000000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="privateChatLoadCount">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label4">
|
||||
<property name="text">
|
||||
<string>Load number of messages (0 = off)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>176</width>
|
||||
<height>480</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="style">
|
||||
|
Binary file not shown.
@ -1131,7 +1131,7 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Emoticons für privaten Chat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+19"/>
|
||||
<location line="+36"/>
|
||||
<source>Chat Font</source>
|
||||
<translation>Chat Schriftart</translation>
|
||||
</message>
|
||||
@ -1146,32 +1146,38 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Chat Schriftart:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+30"/>
|
||||
<location line="-60"/>
|
||||
<source>Enable Emoticons Group Chat</source>
|
||||
<translation>Emoticons für Gruppenchat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+34"/>
|
||||
<source>Chat History</source>
|
||||
<translation>Chat History</translation>
|
||||
<translation type="obsolete">Chat History</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+6"/>
|
||||
<location line="+154"/>
|
||||
<location line="+66"/>
|
||||
<source>Load number of messages (0 = off)</source>
|
||||
<translation>Lade Anzahl von Nachrichten (0 = aus)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+9"/>
|
||||
<location line="-120"/>
|
||||
<source>Group Chat</source>
|
||||
<translation>Gruppenchat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+20"/>
|
||||
<location line="+15"/>
|
||||
<location line="+66"/>
|
||||
<source>Number of saved messages (0 = unlimited)</source>
|
||||
<translation>Anzahl der gespeicherten Nachrichten (0 = unbegrenzt)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-15"/>
|
||||
<source>Private Chat</source>
|
||||
<translation>Privater Chat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+49"/>
|
||||
<location line="+93"/>
|
||||
<source>Group chat</source>
|
||||
<translation>Gruppenchat</translation>
|
||||
</message>
|
||||
@ -1181,27 +1187,31 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Privater Chat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-354"/>
|
||||
<location line="-422"/>
|
||||
<source>General</source>
|
||||
<translation>Allgemein</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+118"/>
|
||||
<source>Enable Group Chat History</source>
|
||||
<translation>Chat Verlauf für Gruppenchat</translation>
|
||||
<translation type="obsolete">Chat Verlauf für Gruppenchat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+10"/>
|
||||
<location line="+38"/>
|
||||
<source>Send message with Ctrl+Return</source>
|
||||
<translation>Sende Nachricht mit Strg+Enter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-17"/>
|
||||
<source>Enable Private Chat History</source>
|
||||
<translation>Chat Verlauf für privaten Chat</translation>
|
||||
<translation type="obsolete">Chat Verlauf für privaten Chat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+95"/>
|
||||
<location line="+96"/>
|
||||
<location line="+66"/>
|
||||
<source>Enable</source>
|
||||
<translation>Aktiviert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+74"/>
|
||||
<source>Style</source>
|
||||
<translation>Stil</translation>
|
||||
</message>
|
||||
@ -1227,12 +1237,13 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Beschreibung:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-93"/>
|
||||
<location line="-528"/>
|
||||
<location line="+435"/>
|
||||
<source>History</source>
|
||||
<translation>Verlauf</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/settings/ChatPage.cpp" line="+197"/>
|
||||
<location filename="../gui/settings/ChatPage.cpp" line="+204"/>
|
||||
<source>Incoming message in history</source>
|
||||
<translation>Eingehehende Nachricht aus dem Verlauf</translation>
|
||||
</message>
|
||||
@ -2166,7 +2177,7 @@ p, li { white-space: pre-wrap; }
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:26pt; color:#ffffff;">Neuer Kanalbeitrag</span></p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+27"/>
|
||||
<location line="+36"/>
|
||||
<source>Channel Post</source>
|
||||
<translation>Kanalbeitrag</translation>
|
||||
</message>
|
||||
@ -2236,7 +2247,27 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Drag'n'Drop Dateien aus den Suchergebnissen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/channels/CreateChannelMsg.cpp" line="+162"/>
|
||||
<location filename="../gui/channels/CreateChannelMsg.cpp" line="+88"/>
|
||||
<source>Paste RetroShare Links</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+2"/>
|
||||
<source>Paste RetroShare Link</source>
|
||||
<translation type="unfinished">RetroShare Link einfügen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+30"/>
|
||||
<source>Channel security policy prevents you from posting files that you don't have. If you have these files, you need to share them before, or attach them explicitly:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+5"/>
|
||||
<source>You can only post files that you do have</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+98"/>
|
||||
<location line="+6"/>
|
||||
<source>Drop file error.</source>
|
||||
<translation>Dateifehler bei Drag'n'Drop.</translation>
|
||||
@ -3862,7 +3893,7 @@ p, li { white-space: pre-wrap; }
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+857"/>
|
||||
<location line="+872"/>
|
||||
<location line="+81"/>
|
||||
<source>RetroShare</source>
|
||||
<translation></translation>
|
||||
@ -3878,7 +3909,7 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Du kannst einem anonymen Autor nicht antworten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-1257"/>
|
||||
<location line="-1272"/>
|
||||
<source>Your Forums</source>
|
||||
<translation>Deine Foren</translation>
|
||||
</message>
|
||||
@ -4021,7 +4052,7 @@ p, li { white-space: pre-wrap; }
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/ForumsDialog.cpp" line="+146"/>
|
||||
<location line="+1032"/>
|
||||
<location line="+1047"/>
|
||||
<source>Start New Thread</source>
|
||||
<translation>Erstelle neues Thema</translation>
|
||||
</message>
|
||||
@ -4049,7 +4080,7 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Inhalt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/ForumsDialog.cpp" line="-1019"/>
|
||||
<location filename="../gui/ForumsDialog.cpp" line="-1034"/>
|
||||
<location line="+3"/>
|
||||
<source>Mark as read</source>
|
||||
<translation>Als gelesen markieren</translation>
|
||||
@ -4070,7 +4101,7 @@ p, li { white-space: pre-wrap; }
|
||||
<context>
|
||||
<name>ForumsFillThread</name>
|
||||
<message>
|
||||
<location line="+1399"/>
|
||||
<location line="+1419"/>
|
||||
<location line="+114"/>
|
||||
<source>Anonymous</source>
|
||||
<translation>Anonym</translation>
|
||||
@ -4184,7 +4215,7 @@ p, li { white-space: pre-wrap; }
|
||||
</message>
|
||||
<message>
|
||||
<location line="+9"/>
|
||||
<location filename="../gui/FriendsDialog.cpp" line="+451"/>
|
||||
<location filename="../gui/FriendsDialog.cpp" line="+452"/>
|
||||
<source>Add Friend</source>
|
||||
<translation>Freund hinzufügen</translation>
|
||||
</message>
|
||||
@ -4455,7 +4486,7 @@ p, li { white-space: pre-wrap; }
|
||||
<message>
|
||||
<location line="+131"/>
|
||||
<source>Do you want to remove this Friend?</source>
|
||||
<translation>Willst du diesen Freund entfernen?</translation>
|
||||
<translation>Möchtest du diesen Freund entfernen?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+84"/>
|
||||
@ -4469,9 +4500,9 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Neuer Gruppenchat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+229"/>
|
||||
<location line="+230"/>
|
||||
<source>Do you really want to physically delete the history?</source>
|
||||
<translation>Willst Du wirklich den Nachrichtenverlauf physisch löschen?</translation>
|
||||
<translation>Möchtest du wirklich den Nachrichtenverlauf physisch löschen?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+87"/>
|
||||
@ -5710,7 +5741,7 @@ p, li { white-space: pre-wrap; }
|
||||
</message>
|
||||
<message>
|
||||
<location line="+32"/>
|
||||
<location filename="../gui/im_history/ImHistoryBrowser.cpp" line="+389"/>
|
||||
<location filename="../gui/im_history/ImHistoryBrowser.cpp" line="+383"/>
|
||||
<source>Copy</source>
|
||||
<translation>Kopieren</translation>
|
||||
</message>
|
||||
@ -6116,7 +6147,7 @@ Die folgenden Wege sind möglich:</translation>
|
||||
<message>
|
||||
<location line="+859"/>
|
||||
<source>Do you really want to exit RetroShare ?</source>
|
||||
<translation>Willst Du RetroShare wirklich beenden?</translation>
|
||||
<translation>Möchtest du RetroShare wirklich beenden?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+2"/>
|
||||
@ -6161,7 +6192,7 @@ Bitte gib etwas Speicher frei und drücke OK.</translation>
|
||||
<name>MessageComposer</name>
|
||||
<message>
|
||||
<location filename="../gui/msgs/MessageComposer.ui" line="+17"/>
|
||||
<location filename="../gui/msgs/MessageComposer.cpp" line="+833"/>
|
||||
<location filename="../gui/msgs/MessageComposer.cpp" line="+832"/>
|
||||
<source>Compose</source>
|
||||
<translation>Verfassen</translation>
|
||||
</message>
|
||||
@ -6314,7 +6345,7 @@ Bitte gib etwas Speicher frei und drücke OK.</translation>
|
||||
<translation>Setzt Schriftart auf Codestil</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/msgs/MessageComposer.cpp" line="+1094"/>
|
||||
<location filename="../gui/msgs/MessageComposer.cpp" line="+1091"/>
|
||||
<source>To</source>
|
||||
<translation>An</translation>
|
||||
</message>
|
||||
@ -6399,7 +6430,7 @@ Bitte gib etwas Speicher frei und drücke OK.</translation>
|
||||
<translation>Blockquote hinzufügen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/msgs/MessageComposer.cpp" line="-1183"/>
|
||||
<location filename="../gui/msgs/MessageComposer.cpp" line="-1180"/>
|
||||
<source>&Left</source>
|
||||
<translation>&Links</translation>
|
||||
</message>
|
||||
@ -6420,12 +6451,12 @@ Bitte gib etwas Speicher frei und drücke OK.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+218"/>
|
||||
<location line="+1660"/>
|
||||
<location line="+1657"/>
|
||||
<source>Save Message</source>
|
||||
<translation>Nachricht speichern</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-1659"/>
|
||||
<location line="-1656"/>
|
||||
<source>Message has not been Sent.
|
||||
Do you want to save message to draft box?</source>
|
||||
<translation>Nachricht wurde noch nicht gesendet.
|
||||
@ -6473,7 +6504,7 @@ Möchtest Du die Nachricht in den Entwürfen speichern?</translation>
|
||||
<translation>Fwd:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+82"/>
|
||||
<location line="+79"/>
|
||||
<location line="+119"/>
|
||||
<source>RetroShare</source>
|
||||
<translation></translation>
|
||||
@ -6634,7 +6665,7 @@ Möchtest Du die Nachricht in den Entwürfen speichern?</translation>
|
||||
<source>Message has not been Sent.
|
||||
Do you want to save message ?</source>
|
||||
<translation>Nachricht noch nicht versandt.
|
||||
Willst Du die Nachricht speichern ?</translation>
|
||||
Möchtest du die Nachricht speichern ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+25"/>
|
||||
@ -6647,7 +6678,7 @@ Willst Du die Nachricht speichern ?</translation>
|
||||
<translation>Unterstützte Bilddateien (*.png *.jpeg *.jpg *.gif)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+119"/>
|
||||
<location line="+111"/>
|
||||
<source>Add Extra File</source>
|
||||
<translation>Zusätzliche Datei hinzufügen</translation>
|
||||
</message>
|
||||
@ -6668,7 +6699,7 @@ Willst Du die Nachricht speichern ?</translation>
|
||||
<translation>Datei nicht gefunden oder Dateiname nicht akzeptiert.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-2135"/>
|
||||
<location line="-2124"/>
|
||||
<source>Friend Recommendation(s)</source>
|
||||
<translation>Freundempfehlung(en)</translation>
|
||||
</message>
|
||||
@ -8751,7 +8782,7 @@ p, li { white-space: pre-wrap; }
|
||||
<context>
|
||||
<name>PopupChatDialog</name>
|
||||
<message>
|
||||
<location filename="../gui/chat/PopupChatDialog.cpp" line="+740"/>
|
||||
<location filename="../gui/chat/PopupChatDialog.cpp" line="+709"/>
|
||||
<source>Hide Avatar</source>
|
||||
<translation>Avatar verstecken</translation>
|
||||
</message>
|
||||
@ -8763,7 +8794,7 @@ p, li { white-space: pre-wrap; }
|
||||
<message>
|
||||
<location line="+88"/>
|
||||
<source>Do you really want to physically delete the history?</source>
|
||||
<translation>Willst Du wirklich den Nachrichtenverlauf physisch löschen?</translation>
|
||||
<translation>Möchtest du wirklich den Nachrichtenverlauf physisch löschen?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+18"/>
|
||||
@ -8891,10 +8922,10 @@ p, li { white-space: pre-wrap; }
|
||||
<translation>Text Datei (*.txt );;Alle Dateien (*)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-659"/>
|
||||
<location line="-647"/>
|
||||
<source>Your Friend is offline
|
||||
Do you want to send them a Message instead</source>
|
||||
<translation>Dein Freund ist Offline willst du ihm stattdessen eine Nachricht senden</translation>
|
||||
<translation>Dein Freund ist Offline. Möchtest du ihm stattdessen eine Nachricht senden</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/chat/PopupChatDialog.ui" line="-445"/>
|
||||
@ -8902,7 +8933,7 @@ Do you want to send them a Message instead</source>
|
||||
<translation>Bild anhängen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui/chat/PopupChatDialog.cpp" line="+698"/>
|
||||
<location filename="../gui/chat/PopupChatDialog.cpp" line="+686"/>
|
||||
<source>is Idle and may not reply</source>
|
||||
<translation>antwortet möglicherweise nicht, da der Status auf "Untätig" gesetzt wurde</translation>
|
||||
</message>
|
||||
@ -8922,7 +8953,7 @@ Do you want to send them a Message instead</source>
|
||||
<translation>ist Offline.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="-664"/>
|
||||
<location line="-652"/>
|
||||
<source>Paste RetroShare Link</source>
|
||||
<translation>RetroShare Link einfügen</translation>
|
||||
</message>
|
||||
@ -10729,7 +10760,7 @@ p, li { white-space: pre-wrap; }
|
||||
<message>
|
||||
<location line="+42"/>
|
||||
<source>Do you want to remove this Friend?</source>
|
||||
<translation>Willst du diesen Freund entfernen?</translation>
|
||||
<translation>Möchtest du diesen Freund entfernen?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+76"/>
|
||||
|
Loading…
Reference in New Issue
Block a user