Reworked design of offline chat messages in PopupChatDialog.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3592 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2010-10-02 22:42:30 +00:00
parent ccaebe2fae
commit 7664a82fd6
25 changed files with 514 additions and 223 deletions

View File

@ -2010,7 +2010,7 @@ void PeersDialog::statusColumn()
void PeersDialog::on_actionMessageHistory_triggered()
{
ImHistoryBrowser imBrowser(false, historyKeeper, ui.lineEdit, this);
ImHistoryBrowser imBrowser("", historyKeeper, ui.lineEdit, this);
imBrowser.exec();
}

View File

@ -34,7 +34,8 @@ enum enumGetStyle
GETSTYLE_INCOMING,
GETSTYLE_OUTGOING,
GETSTYLE_HINCOMING,
GETSTYLE_HOUTGOING
GETSTYLE_HOUTGOING,
GETSTYLE_OOUTGOING
};
/* Default constructor */
@ -96,10 +97,15 @@ bool ChatStyle::setStyleFromSettings(enumStyleType styleType)
m_styleType = styleType;
// reset cache
for (int i = 0; i < FORMATMSG_COUNT; i++) {
m_style[i].clear();
}
return result;
}
static QString getStyle(QDir &styleDir, QString styleVariant, enumGetStyle type)
static QString getStyle(const QDir &styleDir, const QString &styleVariant, enumGetStyle type)
{
QString style;
@ -121,6 +127,9 @@ static QString getStyle(QDir &styleDir, QString styleVariant, enumGetStyle type)
case GETSTYLE_HOUTGOING:
fileHtml.setFileName(QFileInfo(styleDir, "houtgoing.htm").absoluteFilePath());
break;
case GETSTYLE_OOUTGOING:
fileHtml.setFileName(QFileInfo(styleDir, "ooutgoing.htm").absoluteFilePath());
break;
default:
return "";
}
@ -153,7 +162,7 @@ static QString getStyle(QDir &styleDir, QString styleVariant, enumGetStyle type)
return style;
}
QString ChatStyle::formatText(QString &message, unsigned int flag)
QString ChatStyle::formatText(const QString &message, unsigned int flag)
{
if (flag == 0) {
// nothing to do
@ -174,28 +183,35 @@ QString ChatStyle::formatText(QString &message, unsigned int flag)
return doc.toString(-1); // -1 removes any annoying carriage return misinterpreted by QTextEdit
}
QString ChatStyle::formatMessage(enumFormatMessage type, QString &name, QDateTime &timestamp, QString &message, unsigned int flag)
QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, const QDateTime &timestamp, const QString &message, unsigned int flag)
{
QString style;
switch (type) {
case FORMATMSG_INCOMING:
style = getStyle(m_styleDir, m_styleVariant, GETSTYLE_INCOMING);
break;
case FORMATMSG_OUTGOING:
style = getStyle(m_styleDir, m_styleVariant, GETSTYLE_OUTGOING);
break;
case FORMATMSG_HINCOMING:
style = getStyle(m_styleDir, m_styleVariant, GETSTYLE_HINCOMING);
break;
case FORMATMSG_HOUTGOING:
style = getStyle(m_styleDir, m_styleVariant, GETSTYLE_HOUTGOING);
break;
}
QString style = m_style[type];
if (style.isEmpty()) {
// default style
style = "<table width='100%'><tr><td><b>%name%</b></td><td width='130' align='right'>%time%</td></tr></table><table width='100%'><tr><td>%message%</td></tr></table>";
switch (type) {
case FORMATMSG_INCOMING:
style = getStyle(m_styleDir, m_styleVariant, GETSTYLE_INCOMING);
break;
case FORMATMSG_OUTGOING:
style = getStyle(m_styleDir, m_styleVariant, GETSTYLE_OUTGOING);
break;
case FORMATMSG_HINCOMING:
style = getStyle(m_styleDir, m_styleVariant, GETSTYLE_HINCOMING);
break;
case FORMATMSG_HOUTGOING:
style = getStyle(m_styleDir, m_styleVariant, GETSTYLE_HOUTGOING);
break;
case FORMATMSG_OOUTGOING:
style = getStyle(m_styleDir, m_styleVariant, GETSTYLE_OOUTGOING);
break;
}
if (style.isEmpty()) {
// default style
style = "<table width='100%'><tr><td><b>%name%</b></td><td width='130' align='right'>%time%</td></tr></table><table width='100%'><tr><td>%message%</td></tr></table>";
}
m_style[type] = style;
}
unsigned int formatFlag = 0;

View File

@ -38,6 +38,8 @@
#define CHAT_FORMATTEXT_EMBED_SMILEYS 1
#define CHAT_FORMATTEXT_EMBED_LINKS 2
#define FORMATMSG_COUNT 5
class ChatStyleInfo
{
public:
@ -60,10 +62,12 @@ class ChatStyle : public QObject
public:
enum enumFormatMessage
{
FORMATMSG_INCOMING,
FORMATMSG_OUTGOING,
FORMATMSG_HINCOMING,
FORMATMSG_HOUTGOING
FORMATMSG_INCOMING = 0,
FORMATMSG_OUTGOING = 1,
FORMATMSG_HINCOMING = 2,
FORMATMSG_HOUTGOING = 3,
FORMATMSG_OOUTGOING = 4,
// FORMATMSG_COUNT
};
enum enumStyleType
@ -83,8 +87,8 @@ public:
bool setStylePath(const QString &stylePath, const QString &styleVariant);
bool setStyleFromSettings(enumStyleType styleType);
QString formatMessage(enumFormatMessage type, QString &name, QDateTime &timestamp, QString &message, unsigned int flag);
QString formatText(QString &message, unsigned int flag);
QString formatMessage(enumFormatMessage type, const QString &name, const QDateTime &timestamp, const QString &message, unsigned int flag);
QString formatText(const QString &message, unsigned int flag);
static bool getAvailableStyles(enumStyleType styleType, QList<ChatStyleInfo> &styles);
static bool getAvailableVariants(const QString &stylePath, QStringList &variants);
@ -97,6 +101,8 @@ private:
QDir m_styleDir;
QString m_styleVariant;
QString m_style[FORMATMSG_COUNT];
/** store default information for embedding HTML */
RsChat::EmbedInHtmlAhref defEmbedAhref;
};

View File

@ -35,12 +35,13 @@
#include <sys/stat.h>
#include "PopupChatDialog.h"
#include <gui/RetroShareLink.h>
#include "gui/RetroShareLink.h"
#include "rshare.h"
#include <retroshare/rspeers.h>
#include <retroshare/rsmsgs.h>
#include <retroshare/rsfiles.h>
#include "retroshare/rsinit.h"
#include <retroshare/rsnotify.h>
#include <retroshare/rsstatus.h>
#include <retroshare/rsiface.h>
@ -50,6 +51,7 @@
#include "../RsAutoUpdatePage.h"
#include "gui/common/StatusDefs.h"
#include "gui/common/Emoticons.h"
#include "gui/im_history/ImHistoryBrowser.h"
#include "gui/feeds/AttachFileItem.h"
#include "gui/msgs/MessageComposer.h"
@ -62,14 +64,11 @@
#define IMAGE_WINDOW ":/images/rstray3.png"
#define IMAGE_WINDOW_TYPING ":/images/typing.png"
/* Define the format used for displaying the date and time */
#define DATETIME_FMT "MMM dd hh:mm:ss"
/*****
* #define CHAT_DEBUG 1
*****/
static std::map<std::string, PopupChatDialog *> chatDialogs;
// play sound when recv a message
@ -104,6 +103,7 @@ PopupChatDialog::PopupChatDialog(std::string id, const QString name, QWidget *pa
this->move(qrand()%100, qrand()%100); //avoid to stack multiple popup chat windows on the same position
m_bInsertOnVisible = true;
m_manualDelete = false;
last_status_send_time = 0 ;
style.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
@ -131,7 +131,6 @@ PopupChatDialog::PopupChatDialog(std::string id, const QString name, QWidget *pa
connect(ui.actionClearOfflineMessages, SIGNAL(triggered()), this, SLOT(clearOfflineMessages()));
connect(ui.textBrowser, SIGNAL(anchorClicked(const QUrl &)), SLOT(anchorClicked(const QUrl &)));
connect(ui.offlineTextBrowser, SIGNAL(anchorClicked(const QUrl &)), SLOT(anchorClicked(const QUrl &)));
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&)));
@ -168,6 +167,7 @@ PopupChatDialog::PopupChatDialog(std::string id, const QString name, QWidget *pa
toolmenu->addAction(ui.actionClear_Chat);
toolmenu->addAction(ui.actionSave_Chat_History);
toolmenu->addAction(ui.actionClearOfflineMessages);
toolmenu->addAction(ui.actionMessageHistory);
//toolmenu->addAction(ui.action_Disable_Emoticons);
ui.pushtoolsButton->setMenu(toolmenu);
@ -201,10 +201,43 @@ PopupChatDialog::PopupChatDialog(std::string id, const QString name, QWidget *pa
QString customStateString = QString::fromStdString(rsMsgs->getCustomStateString(dialogId));
updatePeersCustomStateString(QString::fromStdString(dialogId), customStateString);
if (Settings->valueFromGroup("Chat", QString::fromUtf8("PrivateChat_History"), true).toBool()) {
historyKeeper.init(QString::fromStdString(RsInit::RsProfileConfigDirectory()) + "/chat_" + QString::fromStdString(dialogId) + ".xml");
// get offline chat messages
std::list<ChatInfo> offlineChat;
std::list<ChatInfo>::iterator offineChatIt;
rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, dialogId, offlineChat);
QList<IMHistoryItem> historyItems;
historyKeeper.getMessages(historyItems, 20);
foreach(IMHistoryItem item, historyItems) {
for(offineChatIt = offlineChat.begin(); offineChatIt != offlineChat.end(); offineChatIt++) {
/* are they public? */
if ((offineChatIt->chatflags & RS_CHAT_PRIVATE) == 0) {
/* this should not happen */
continue;
}
QDateTime sendTime = QDateTime::fromTime_t(offineChatIt->sendTime);
QString message = QString::fromStdWString(offineChatIt->msg);
if (IMHistoryKeeper::compareItem(item, false, offineChatIt->rsid, sendTime, message)) {
// don't show offline message out of the history
break;
}
}
if (offineChatIt == offlineChat.end()) {
addChatMsg(item.incoming, item.id, item.name, item.sendTime, item.messageText, TYPE_HISTORY, false);
}
}
}
ui.chattextEdit->installEventFilter(this);
// call once
onPrivateChatChanged(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD);
onPrivateChatChanged(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD, true);
}
/** Destructor. */
@ -395,7 +428,9 @@ void PopupChatDialog::chatFriend(std::string id)
}
/* info dialog */
if ((QMessageBox::question(NULL, tr("Friend not Online"),tr("Your Friend is offline \nDo you want to send them a Message instead"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes) {
QMessageBox mb(QMessageBox::Question, tr("Friend not Online"), tr("Your Friend is offline \nDo you want to send them a Message instead"), QMessageBox::Yes | QMessageBox::No);
mb.setWindowIcon(QIcon(":/images/rstray3.png"));
if (mb.exec() == QMessageBox::Yes) {
MessageComposer::msgFriend(id, false);
} else {
if (firstId.empty() == false) {
@ -517,37 +552,71 @@ void PopupChatDialog::closeEvent (QCloseEvent * event)
event->ignore();
}
void PopupChatDialog::updateChat()
void PopupChatDialog::onPrivateChatChanged(int list, int type, bool initial /*= false*/)
{
/* get chat off queue */
if (list == NOTIFY_LIST_PRIVATE_OUTGOING_CHAT) {
switch (type) {
case NOTIFY_TYPE_ADD:
{
m_savedOfflineChat.clear();
/* write it out */
std::list<ChatInfo> offlineChat;
if (rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, dialogId, offlineChat)) {
ui.actionClearOfflineMessages->setEnabled(true);
}
std::list<ChatInfo>::iterator it;
for(it = offlineChat.begin(); it != offlineChat.end(); it++) {
/* are they public? */
if ((it->chatflags & RS_CHAT_PRIVATE) == 0) {
/* this should not happen */
continue;
}
void PopupChatDialog::onPrivateChatChanged(int list, int type)
{
if (list == NOTIFY_LIST_PRIVATE_OUTGOING_CHAT && type) {
std::list<ChatInfo> offlineChat;
if (rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, dialogId, offlineChat)) {
ui.actionClearOfflineMessages->setEnabled(true);
ui.offlineTextBrowser->setVisible(true);
m_savedOfflineChat.push_back(*it);
std::list<ChatInfo>::iterator it;
for(it = offlineChat.begin(); it != offlineChat.end(); it++) {
/* are they public? */
if ((it->chatflags & RS_CHAT_PRIVATE) == 0) {
/* this should not happen */
continue;
QString name = QString::fromStdString(rsPeers->getPeerName(it->rsid));
QDateTime sendTime = QDateTime::fromTime_t(it->sendTime);
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, message, TYPE_OFFLINE, !existingMessage);
}
}
}
}
break;
case NOTIFY_TYPE_DEL:
{
if (m_manualDelete == false) {
// now show saved offline chat messages as sent
std::list<ChatInfo>::iterator it;
for(it = m_savedOfflineChat.begin(); it != m_savedOfflineChat.end(); it++) {
QString name = QString::fromStdString(rsPeers->getPeerName(it->rsid));
QDateTime sendTime = QDateTime::fromTime_t(it->sendTime);
QString message = QString::fromStdWString(it->msg);
addChatMsg(false, it->rsid, name, sendTime, message, TYPE_NORMAL, false);
}
}
addChatMsg(it->rsid, it->sendTime, it->msg, true);
m_savedOfflineChat.clear();
}
} else {
ui.actionClearOfflineMessages->setEnabled(false);
ui.offlineTextBrowser->setVisible(false);
ui.offlineTextBrowser->clear();
break;
}
ui.actionClearOfflineMessages->setEnabled(!m_savedOfflineChat.empty());
}
}
@ -577,7 +646,7 @@ void PopupChatDialog::insertChatMsgs()
continue;
}
addChatMsg(it->rsid, it->sendTime, it->msg, false);
addChatMsg(true, it->rsid, QString::fromStdString(rsPeers->getPeerName(it->rsid)), QDateTime::fromTime_t(it->sendTime), QString::fromStdWString(it->msg), TYPE_NORMAL, true);
}
rsMsgs->clearPrivateChatQueue(true, dialogId);
@ -586,13 +655,12 @@ void PopupChatDialog::insertChatMsgs()
QApplication::alert(this);
}
void PopupChatDialog::addChatMsg(std::string &id, uint sendTime, std::wstring &msg, bool offline)
void PopupChatDialog::addChatMsg(bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QString &message, enumChatType chatType, bool addToHistory)
{
std::string ownId = rsPeers->getOwnId();
QDateTime timestamp = QDateTime::fromTime_t(sendTime);
QString name = QString::fromStdString(rsPeers->getPeerName(offline ? ownId : id));
QString message = QString::fromStdWString(msg);
//...
// QString name = QString::fromStdString(rsPeers->getPeerName(offline ? ownId : id));
#ifdef CHAT_DEBUG
std::cout << "PopupChatDialog:addChatMsg message : " << message.toStdString() << std::endl;
@ -605,12 +673,23 @@ void PopupChatDialog::addChatMsg(std::string &id, uint sendTime, std::wstring &m
formatFlag |= CHAT_FORMATMSG_EMBED_SMILEYS;
}
ChatStyle::enumFormatMessage type = (offline == false && id == ownId) ? ChatStyle::FORMATMSG_INCOMING : ChatStyle::FORMATMSG_OUTGOING;
ChatStyle::enumFormatMessage type;
if (chatType == TYPE_OFFLINE) {
type = ChatStyle::FORMATMSG_OOUTGOING;
} else if (chatType == TYPE_HISTORY) {
type = incoming ? ChatStyle::FORMATMSG_HINCOMING : ChatStyle::FORMATMSG_HOUTGOING;
} else {
type = incoming ? ChatStyle::FORMATMSG_INCOMING : ChatStyle::FORMATMSG_OUTGOING;
}
QString formatMsg = style.formatMessage(type, name, timestamp, message, formatFlag);
QString formatMsg = style.formatMessage(type, name, sendTime, message, formatFlag);
if (offline) {
ui.offlineTextBrowser->append(formatMsg);
// if (offline) {
// ui.offlineTextBrowser->append(formatMsg);
// }
if (addToHistory) {
historyKeeper.addMessage(incoming, id, name, sendTime, message);
}
ui.textBrowser->append(formatMsg);
@ -682,7 +761,7 @@ void PopupChatDialog::sendChat()
#endif
if (rsMsgs->sendPrivateChat(dialogId, msg)) {
addChatMsg(ownId, time(NULL), msg, false);
addChatMsg(false, ownId, QString::fromStdString(rsPeers->getPeerName(ownId)), QDateTime::currentDateTime(), QString::fromStdWString(msg), TYPE_NORMAL, true);
}
chatWidget->clear();
@ -984,7 +1063,7 @@ void PopupChatDialog::fileHashingFinished(AttachFileItem* file)
std::wstring msg = message.toStdWString();
if (rsMsgs->sendPrivateChat(dialogId, msg)) {
addChatMsg(ownId, time(NULL), msg, false);
addChatMsg(false, ownId, QString::fromStdString(rsPeers->getPeerName(ownId)), QDateTime::currentDateTime(), QString::fromStdWString(msg), TYPE_NORMAL, true);
}
}
@ -1118,7 +1197,9 @@ void PopupChatDialog::setCurrentFileName(const QString &fileName)
void PopupChatDialog::clearOfflineMessages()
{
m_manualDelete = true;
rsMsgs->clearPrivateChatQueue(false, dialogId);
m_manualDelete = false;
}
void PopupChatDialog::updateStatus(const QString &peer_id, int status)
@ -1216,3 +1297,9 @@ void PopupChatDialog::updatePeersCustomStateString(const QString& peer_id, const
}
}
void PopupChatDialog::on_actionMessageHistory_triggered()
{
ImHistoryBrowser imBrowser(dialogId, historyKeeper, ui.chattextEdit, this);
imBrowser.exec();
}

View File

@ -31,12 +31,17 @@ class QTextCharFormat;
class AttachFileItem;
class ChatInfo;
#include <retroshare/rsmsgs.h>
#include "gui/im_history/IMHistoryKeeper.h"
#include "ChatStyle.h"
class PopupChatDialog : public QMainWindow
{
Q_OBJECT
public:
enum enumChatType { TYPE_NORMAL, TYPE_HISTORY, TYPE_OFFLINE };
public:
static PopupChatDialog *getPrivateChat(std::string id, uint chatflags);
static void cleanupChat();
@ -44,7 +49,6 @@ public:
static void updateAllAvatars();
static void privateChatChanged(int list, int type);
void updateChat();
void updatePeerAvatar(const std::string&);
public slots:
@ -82,13 +86,14 @@ protected:
bool eventFilter(QObject *obj, QEvent *ev);
void insertChatMsgs();
void addChatMsg(std::string &id, uint sendTime, std::wstring &msg, bool offline);
void addChatMsg(bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QString &message, enumChatType chatType, bool addToHistory);
void updateAvatar();
QPixmap picture;
private slots:
void on_actionMessageHistory_triggered();
void addExtraFile();
void addExtraPicture();
void showAvatarFrame(bool show);
@ -119,7 +124,7 @@ private:
void addAttachment(std::string,int flag);
void processSettings(bool bLoad);
void onPrivateChatChanged(int list, int type);
void onPrivateChatChanged(int list, int type, bool initial = false);
QAction *actionTextBold;
QAction *actionTextUnderline;
@ -135,12 +140,14 @@ private:
QColor mCurrentColor;
QFont mCurrentFont;
// QStringList history;
std::list<ChatInfo> m_savedOfflineChat;
QString wholeChat;
QString fileName;
bool m_bInsertOnVisible;
IMHistoryKeeper historyKeeper;
ChatStyle style;
bool m_manualDelete;
/** Qt Designer generated object */
Ui::PopupChatDialog ui;
@ -148,7 +155,3 @@ private:
};
#endif

View File

@ -304,7 +304,7 @@ stop:0 #FFFFD7, stop:1 #FFFFB2);}</string>
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/info16.png</pixmap>
<pixmap>:/images/info16.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
@ -421,7 +421,7 @@ border: 1px solid #CCCCCC;
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/configure.png</normaloff>:/images/configure.png</iconset>
</property>
<property name="iconSize">
@ -456,7 +456,7 @@ border: 1px solid #CCCCCC;
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/add_image24.png</normaloff>:/images/add_image24.png</iconset>
</property>
<property name="iconSize">
@ -485,7 +485,7 @@ border: 1px solid #CCCCCC;
<string/>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/add-share24.png</normaloff>:/images/add-share24.png</iconset>
</property>
<property name="iconSize">
@ -726,65 +726,38 @@ border: 1px solid #CCCCCC;
<widget class="QWidget" name="verticalLayoutWidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QTextBrowser{border: 1px solid #B8B6B1;
<widget class="QTextBrowser" name="textBrowser">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QTextBrowser{border: 1px solid #B8B6B1;
border-radius: 6px;
background: white;}</string>
</property>
<property name="html">
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
</property>
<property name="html">
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;&quot;&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="openLinks">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="offlineTextBrowser">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QTextBrowser{border: 1px solid #B8B6B1;
border-radius: 6px;
background: white;}</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="openLinks">
<bool>false</bool>
</property>
</widget>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="openLinks">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
@ -908,7 +881,7 @@ background: white;}</string>
</action>
<action name="actionAvatar">
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/no_avatar_70.png</normaloff>:/images/no_avatar_70.png</iconset>
</property>
<property name="text">
@ -920,7 +893,7 @@ background: white;}</string>
</action>
<action name="actionClear_Chat">
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/edit-clear-history.png</normaloff>:/images/edit-clear-history.png</iconset>
</property>
<property name="text">
@ -948,9 +921,15 @@ background: white;}</string>
<string>Clear offline messages</string>
</property>
</action>
<action name="actionMessageHistory">
<property name="text">
<string>Browse Message History</string>
</property>
<property name="toolTip">
<string>Browse History</string>
</property>
</action>
</widget>
<resources>
<include location="../images.qrc"/>
</resources>
<resources/>
<connections/>
</ui>

View File

@ -30,7 +30,7 @@ IMHistoryItem::IMHistoryItem()
//============================================================================
IMHistoryItem::IMHistoryItem(int hiidIn, bool incomingIn, std::string &idIn, const QString &nameIn, const QDateTime &sendTimeIn, const QString &messageTextIn)
IMHistoryItem::IMHistoryItem(int hiidIn, bool incomingIn, const std::string &idIn, const QString &nameIn, const QDateTime &sendTimeIn, const QString &messageTextIn)
{
hiid = hiidIn;
incoming = incomingIn;

View File

@ -30,7 +30,7 @@ class IMHistoryItem
public:
IMHistoryItem();
IMHistoryItem(int hiid, bool incoming, std::string &id, const QString &name, const QDateTime &sendTime, const QString &messageText);
IMHistoryItem(int hiid, bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QString &messageText);
int hiid;
bool incoming;

View File

@ -67,7 +67,7 @@ void IMHistoryKeeper::init(QString historyFileName)
//=============================================================================
void IMHistoryKeeper::addMessage(bool incoming, std::string &id, const QString &name, const QDateTime &sendTime, const QString &messageText)
void IMHistoryKeeper::addMessage(bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QString &messageText)
{
IMHistoryItem item(++lasthiid, incoming, id, name, sendTime, messageText);
@ -176,6 +176,41 @@ void IMHistoryKeeper::clear()
//=============================================================================
/*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;
@ -225,5 +260,7 @@ void IMHistoryKeeper::saveHistory()
IMHistoryWriter wri;
wri.write(hitems, hfName);
historyChanged = false;
}
}

View File

@ -78,11 +78,15 @@ public:
//! Adds new message to the history, but the message will be saved to
//! file only after destroing the object
void addMessage(bool incoming, std::string &id, const QString &name, const QDateTime &sendTime, const QString &messageText);
void addMessage(bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, 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);

View File

@ -64,7 +64,7 @@ bool IMHistoryWriter::write(QList<IMHistoryItem>& itemList, const QString fileNa
writeAttribute("id", QString::fromStdString(item.id));
writeAttribute("name", item.name);
writeAttribute("sendTime", QString::number(item.sendTime.toTime_t()));
writeCharacters(item.messageText);
writeCDATA(item.messageText);
writeEndElement();
}

View File

@ -34,18 +34,21 @@
#include "rshare.h"
#include "gui/settings/rsharesettings.h"
#include "gui/notifyqt.h"
#define ROLE_HIID Qt::UserRole
#define ROLE_PLAINTEXT Qt::UserRole + 1
#define ROLE_OFFLINE Qt::UserRole + 2
/** Default constructor */
ImHistoryBrowser::ImHistoryBrowser(bool isPrivateChatIn, IMHistoryKeeper &histKeeper, QTextEdit *edit, QWidget *parent, Qt::WFlags flags)
ImHistoryBrowser::ImHistoryBrowser(const std::string &peerId, IMHistoryKeeper &histKeeper, QTextEdit *edit, QWidget *parent, Qt::WFlags flags)
: QDialog(parent, flags), historyKeeper(histKeeper)
{
/* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this);
isPrivateChat = isPrivateChatIn;
m_peerId = peerId;
m_isPrivateChat = !m_peerId.empty();
textEdit = edit;
connect(&historyKeeper, SIGNAL(historyAdd(IMHistoryItem)), this, SLOT(historyAdd(IMHistoryItem)));
@ -61,19 +64,24 @@ ImHistoryBrowser::ImHistoryBrowser(bool isPrivateChatIn, IMHistoryKeeper &histKe
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 ?
if (isPrivateChat) {
embedSmileys = Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool();
if (m_isPrivateChat) {
embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_PrivatChat", true).toBool();
} else {
embedSmileys = Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_GroupChat"), true).toBool();
embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_GroupChat", true).toBool();
}
style.setStyleFromSettings(ChatStyle::TYPE_HISTORY);
ui.listWidget->setItemDelegate(new IMHistoryItemDelegate);
// call once
privateChatChanged(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD);
QList<IMHistoryItem> historyItems;
historyKeeper.getMessages(historyItems, 0);
foreach(IMHistoryItem item, historyItems) {
@ -89,7 +97,6 @@ ImHistoryBrowser::ImHistoryBrowser(bool isPrivateChatIn, IMHistoryKeeper &histKe
itemSelectionChanged();
ui.listWidget->installEventFilter(this);
}
ImHistoryBrowser::~ImHistoryBrowser()
@ -138,7 +145,7 @@ void ImHistoryBrowser::historyClear()
ui.listWidget->clear();
}
QListWidgetItem *ImHistoryBrowser::addItem(IMHistoryItem &item)
void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, IMHistoryItem &item)
{
unsigned int formatFlag = CHAT_FORMATMSG_EMBED_LINKS;
@ -146,25 +153,52 @@ QListWidgetItem *ImHistoryBrowser::addItem(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 (item.incoming) {
type = ChatStyle::FORMATMSG_INCOMING;
if (offineChatIt == m_savedOfflineChat.end()) {
if (item.incoming) {
type = ChatStyle::FORMATMSG_INCOMING;
} else {
type = ChatStyle::FORMATMSG_OUTGOING;
}
} else {
type = ChatStyle::FORMATMSG_OUTGOING;
type = ChatStyle::FORMATMSG_OOUTGOING;
}
QString formatMsg = style.formatMessage(type, item.name, item.sendTime, item.messageText, formatFlag);
QListWidgetItem *itemWidget = new QListWidgetItem;
itemWidget->setData(Qt::DisplayRole, qVariantFromValue(IMHistoryItemPainter(formatMsg)));
itemWidget->setData(ROLE_HIID, item.hiid);
itemWidget->setData(ROLE_OFFLINE, (type == ChatStyle::FORMATMSG_OOUTGOING) ? true : false);
/* calculate plain text */
QTextDocument doc;
doc.setHtml(item.messageText);
itemWidget->setData(ROLE_PLAINTEXT, doc.toPlainText());
ui.listWidget->addItem(itemWidget);
filterRegExpChanged();
}
QListWidgetItem *ImHistoryBrowser::addItem(IMHistoryItem &item)
{
QListWidgetItem *itemWidget = new QListWidgetItem;
ui.listWidget->addItem(itemWidget);
fillItem(itemWidget, item);
return itemWidget;
}
@ -343,3 +377,43 @@ 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);
}
}
}
}

View File

@ -25,6 +25,7 @@
#include <QDialog>
#include <retroshare/rsmsgs.h>
#include "IMHistoryKeeper.h"
#include "gui/chat/ChatStyle.h"
@ -38,7 +39,7 @@ class ImHistoryBrowser : public QDialog
public:
/** Default constructor */
ImHistoryBrowser(bool isPrivateChat, IMHistoryKeeper &histKeeper, QTextEdit *edit, QWidget *parent = 0, Qt::WFlags flags = 0);
ImHistoryBrowser(const std::string &peerId, IMHistoryKeeper &histKeeper, QTextEdit *edit, QWidget *parent = 0, Qt::WFlags flags = 0);
/** Default destructor */
virtual ~ImHistoryBrowser();
@ -61,21 +62,26 @@ private slots:
void clearHistory();
void sendMessage();
void privateChatChanged(int list, int type);
private:
QListWidgetItem *addItem(IMHistoryItem &item);
void fillItem(QListWidgetItem *itemWidget, IMHistoryItem &item);
void filterItems(QListWidgetItem *item = NULL);
void getSelectedItems(QList<int> &items);
bool isPrivateChat;
std::string m_peerId;
bool m_isPrivateChat;
QTextEdit *textEdit;
bool embedSmileys;
IMHistoryKeeper &historyKeeper;
ChatStyle style;
std::list<ChatInfo> m_savedOfflineChat;
/** Qt Designer generated object */
Ui::ImHistoryBrowser ui;
};
#endif

View File

@ -459,6 +459,7 @@
<file>qss/chat/private/outgoing.htm</file>
<file>qss/chat/private/hincoming.htm</file>
<file>qss/chat/private/houtgoing.htm</file>
<file>qss/chat/private/ooutgoing.htm</file>
<file>qss/chat/private/main.css</file>
<file>qss/chat/private/variants/Standard.css</file>
<file>qss/chat/public/info.xml</file>
@ -466,6 +467,7 @@
<file>qss/chat/public/outgoing.htm</file>
<file>qss/chat/public/hincoming.htm</file>
<file>qss/chat/public/houtgoing.htm</file>
<file>qss/chat/public/ooutgoing.htm</file>
<file>qss/chat/public/main.css</file>
<file>qss/chat/public/variants/Standard.css</file>
<file>qss/chat/history/info.xml</file>
@ -473,6 +475,7 @@
<file>qss/chat/history/outgoing.htm</file>
<file>qss/chat/history/hincoming.htm</file>
<file>qss/chat/history/houtgoing.htm</file>
<file>qss/chat/history/ooutgoing.htm</file>
<file>qss/chat/history/main.css</file>
<file>qss/chat/history/variants/Standard.css</file>
<file>smileys/amorous.png</file>

View File

@ -57,3 +57,15 @@
color: #244578;
}
.ooutgoingTable{
background-color:#ffbebe;
}
.ooutgoingHeader {
border-color:#fafafa #e3e3e3 #e3e3e3 #fafafa;
color: #244578;
}
.ooutgoingTime {
color: #244578;
}

View File

@ -0,0 +1,15 @@
<style type="text/css">
%css-style%
</style>
<table class='ooutgoingTable' width='100%'>
<tr>
<td class='header ooutgoingHeader'>%name%</td>
<td width='130' align='right' class='time ooutgoingTime'>[%date% %time%]</td>
</tr>
</table>
<table class='ooutgoingTable' width='100%'>
<tr>
<td>%message%</td>
</tr>
</table>

View File

@ -20,11 +20,17 @@
.hincomingHeader {
background-color:#dfedff;
border-color:#fafafa #d1dfef #d1dfef #fafafa;
color: #295b07;
color: #88f042;
}
.houtgoingHeader {
background-color:#f5f5f5;
border-color:#fafafa #e3e3e3 #e3e3e3 #fafafa;
color: #6491d2;
}
.ooutgoingHeader {
background-color:#ffbebe;
border-color:#fafafa #e3e3e3 #e3e3e3 #fafafa;
color: #244578;
}

View File

@ -0,0 +1,14 @@
<style type="text/css">
%css-style%
</style>
<table class='ooutgoingHeader' width='100%'>
<tr>
<td class='name'>%name%</td>
<td width='130' align='right' class='time'>%time%</td>
</tr>
</table>
<table width='100%'>
<tr>
<td>%message%</td>
</tr>
</table>

View File

@ -29,3 +29,12 @@
.houtgoingName{
color:#1E5684;
}
.ooutgoingTime {
color:#C00000;
}
.ooutgoingName{
color:#2D84C9;
}

View File

@ -0,0 +1,7 @@
<style type="text/css">
%css-style%
</style>
<span class='ooutgoingTime'>%time%</span>
<span class='ooutgoingName'><strong>%name%</strong></span>
%message%

View File

@ -103,9 +103,10 @@ ChatPage::save(QString &errmsg)
{
Settings->beginGroup(QString("Chat"));
Settings->setValue(QString::fromUtf8("Emoteicons_PrivatChat"), emotePrivatChat());
Settings->setValue(QString::fromUtf8("Emoteicons_GroupChat"), emoteGroupChat());
Settings->setValue(QString::fromUtf8("GroupChat_History"), groupchatHistory());
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());
@ -152,6 +153,7 @@ ChatPage::load()
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();
@ -168,21 +170,6 @@ ChatPage::load()
historyStylePath = loadStyleInfo(ChatStyle::TYPE_HISTORY, ui.historyList, ui.historyComboBoxVariant, historyStyleVariant);
}
bool ChatPage::emotePrivatChat() const {
if(ui.checkBox_emoteprivchat->isChecked()) return true;
return ui.checkBox_emoteprivchat->isChecked();
}
bool ChatPage::emoteGroupChat() const {
if(ui.checkBox_emotegroupchat->isChecked()) return true;
return ui.checkBox_emotegroupchat->isChecked();
}
bool ChatPage::groupchatHistory() const {
if(ui.checkBox_groupchathistory->isChecked()) return true;
return ui.checkBox_groupchathistory->isChecked();
}
void ChatPage::on_pushButtonChangeChatFont_clicked()
{
bool ok;
@ -219,6 +206,9 @@ void ChatPage::setPreviewMessages(QString &stylePath, QString styleVariant, QTex
textEdit.setText(tr("Outgoing message"));
message = textEdit.toHtml();
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OUTGOING, nameOutgoing, timestmp, message, CHAT_FORMATTEXT_EMBED_SMILEYS));
textEdit.setText(tr("Outgoing offline message"));
message = textEdit.toHtml();
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OOUTGOING, nameOutgoing, timestmp, message, CHAT_FORMATTEXT_EMBED_SMILEYS));
}
void ChatPage::fillPreview(QListWidget *listWidget, QComboBox *comboBox, QTextBrowser *textBrowser)

View File

@ -40,12 +40,6 @@ class ChatPage : public ConfigPage
/** Loads the settings for this page */
void load();
bool emotePrivatChat() const;
bool emoteGroupChat() const;
bool groupchatHistory() const;
QFont fontTempChat;
private slots:
void on_historyComboBoxVariant_currentIndexChanged(int index);
void on_privateComboBoxVariant_currentIndexChanged(int index);
@ -60,6 +54,8 @@ class ChatPage : public ConfigPage
void setPreviewMessages(QString &stylePath, QString styleVariant, QTextBrowser *textBrowser);
void fillPreview(QListWidget *listWidget, QComboBox *comboBox, QTextBrowser *textBrowser);
QFont fontTempChat;
QString publicStylePath;
QString publicStyleVariant;
QString privateStylePath;

View File

@ -532,7 +532,7 @@
</property>
</widget>
</item>
<item row="0" column="1" rowspan="5">
<item row="0" column="1" rowspan="6">
<widget class="QGroupBox" name="groupBoxIRCColors">
<property name="maximumSize">
<size>
@ -615,24 +615,24 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QCheckBox" name="checkBox_groupchathistory">
<property name="text">
<string>Enable GroupChat History</string>
<string>Enable Group Chat History</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<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="4" column="0">
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -645,6 +645,13 @@
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBox_privatechathistory">
<property name="text">
<string>Enable Private Chat History</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -856,7 +856,7 @@ p, li { white-space: pre-wrap; }
<context>
<name>ChanMsgItem</name>
<message>
<location filename="../gui/feeds/ChanMsgItem.ui" line="+218"/>
<location filename="../gui/feeds/ChanMsgItem.ui" line="+221"/>
<source>Remove Item</source>
<translation>Eintrag entfernen</translation>
</message>
@ -1198,12 +1198,7 @@ Keine Beschreibung</translation>
<translation>Emoticons für Gruppenchat</translation>
</message>
<message>
<location line="+10"/>
<source>Enable GroupChat History</source>
<translation>Chat Verlauf für Gruppenchat</translation>
</message>
<message>
<location line="+47"/>
<location line="+64"/>
<source>Group chat</source>
<translation>Gruppenchat</translation>
</message>
@ -1213,17 +1208,27 @@ Keine Beschreibung</translation>
<translation>Privater Chat</translation>
</message>
<message>
<location line="-293"/>
<location line="-300"/>
<source>General</source>
<translation>Allgemein</translation>
</message>
<message>
<location line="+121"/>
<location line="+111"/>
<source>Enable Group Chat History</source>
<translation>Chat Verlauf für Gruppenchat</translation>
</message>
<message>
<location line="+10"/>
<source>Send message with Ctrl+Return</source>
<translation>Sende Nachricht mit Strg+Enter</translation>
</message>
<message>
<location line="+24"/>
<location line="+20"/>
<source>Enable Private Chat History</source>
<translation>Chat Verlauf für privaten Chat</translation>
</message>
<message>
<location line="+11"/>
<source>Style</source>
<translation>Stil</translation>
</message>
@ -1254,7 +1259,7 @@ Keine Beschreibung</translation>
<translation>Verlauf</translation>
</message>
<message>
<location filename="../gui/settings/ChatPage.cpp" line="+210"/>
<location filename="../gui/settings/ChatPage.cpp" line="+197"/>
<source>Incoming message in history</source>
<translation>Eingehehende Nachricht aus dem Verlauf</translation>
</message>
@ -1273,11 +1278,16 @@ Keine Beschreibung</translation>
<source>Outgoing message</source>
<translation>Ausgehehende Nachricht</translation>
</message>
<message>
<location line="+3"/>
<source>Outgoing offline message</source>
<translation>Ausgehehende offline Nachricht</translation>
</message>
</context>
<context>
<name>ChatStyle</name>
<message>
<location filename="../gui/chat/ChatStyle.cpp" line="+367"/>
<location filename="../gui/chat/ChatStyle.cpp" line="+381"/>
<source>Standard style for group chat</source>
<translation>Standard Stil für den Gruppenchat</translation>
</message>
@ -4578,7 +4588,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location line="+32"/>
<location filename="../gui/im_history/ImHistoryBrowser.cpp" line="+261"/>
<location filename="../gui/im_history/ImHistoryBrowser.cpp" line="+295"/>
<source>Copy</source>
<translation>Kopieren</translation>
</message>
@ -6090,7 +6100,7 @@ p, li { white-space: pre-wrap; }
<context>
<name>MessengerWindow</name>
<message>
<location filename="../gui/MessengerWindow.cpp" line="+294"/>
<location filename="../gui/MessengerWindow.cpp" line="+293"/>
<source>Expand all</source>
<translation>Alle erweitern</translation>
</message>
@ -7734,7 +7744,7 @@ p, li { white-space: pre-wrap; }
<context>
<name>PopupChatDialog</name>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+702"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+778"/>
<source>Hide Avatar</source>
<translation>Avatar verstecken</translation>
</message>
@ -7755,24 +7765,24 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.ui" line="+571"/>
<location line="+320"/>
<location line="+293"/>
<source>Bold</source>
<translation>Fett</translation>
</message>
<message>
<location line="-288"/>
<location line="+298"/>
<location line="-261"/>
<location line="+271"/>
<source>Underline</source>
<translation>Unterstrichen</translation>
</message>
<message>
<location line="-266"/>
<location line="+261"/>
<location line="-239"/>
<location line="+234"/>
<source>Italic</source>
<translation>Kursiv</translation>
</message>
<message>
<location line="-229"/>
<location line="-202"/>
<source>Set Font</source>
<translation>Schriftart setzen</translation>
</message>
@ -7782,17 +7792,27 @@ p, li { white-space: pre-wrap; }
<translation>Textfarbe</translation>
</message>
<message>
<location line="+249"/>
<location line="+222"/>
<source>Clear offline messages</source>
<translation>Entferne offline Nachrichten</translation>
</message>
<message>
<location line="-430"/>
<location line="+5"/>
<source>Browse Message History</source>
<translation>Nachrichtenverlauf anzeigen</translation>
</message>
<message>
<location line="+3"/>
<source>Browse History</source>
<translation>Nachrichtenverlauf</translation>
</message>
<message>
<location line="-411"/>
<source>Send</source>
<translation>Senden</translation>
</message>
<message>
<location line="+409"/>
<location line="+382"/>
<source>Clear Chat</source>
<translation>Chat-Chronik löschen</translation>
</message>
@ -7802,7 +7822,7 @@ p, li { white-space: pre-wrap; }
<translation>Deaktiviere Emoticons</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="-956"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="-1033"/>
<source>Paste retroshare Link</source>
<translation>RetroShare Link einfügen</translation>
</message>
@ -7822,7 +7842,7 @@ p, li { white-space: pre-wrap; }
<translation>Wähle dein Avatar Bild aus</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+695"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+772"/>
<source>Add Extra File</source>
<translation>Zusätzlich eine Datei hinzufügen</translation>
</message>
@ -7838,12 +7858,12 @@ p, li { white-space: pre-wrap; }
<translation>Ordner können nicht für Drag&apos;n&apos;Drop genutzt werden. Nur Dateien werden akzeptiert.</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.ui" line="-436"/>
<location filename="../gui/chat/PopupChatDialog.ui" line="-409"/>
<source>Add a File for your Friend</source>
<translation>Füge eine Datei für deinen Freund hinzu</translation>
</message>
<message>
<location line="+458"/>
<location line="+431"/>
<location line="+3"/>
<source>Save Chat History</source>
<translation>Chat Verlauf speichern</translation>
@ -7859,13 +7879,13 @@ p, li { white-space: pre-wrap; }
<translation>Text Datei (*.txt );;Alle Dateien (*)</translation>
</message>
<message>
<location line="-706"/>
<location line="-750"/>
<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>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.ui" line="-490"/>
<location filename="../gui/chat/PopupChatDialog.ui" line="-463"/>
<source>Attach a Picture</source>
<translation>Bild anhängen</translation>
</message>
@ -7876,7 +7896,7 @@ Do you want to send them a Message instead</source>
<translation></translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+745"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+789"/>
<source>is Idle and may not reply</source>
<translation>antwortet möglicherweise nicht, da der Status auf &quot;Untätig&quot; gesetzt wurde</translation>
</message>
@ -7896,7 +7916,7 @@ Do you want to send them a Message instead</source>
<translation>ist Offline.</translation>
</message>
<message>
<location line="-692"/>
<location line="-734"/>
<source>is typing...</source>
<translation>tippt...</translation>
</message>
@ -7906,12 +7926,12 @@ Do you want to send them a Message instead</source>
<translation>Schliessen</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="-295"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="-331"/>
<source>RetroShare</source>
<translation></translation>
</message>
<message>
<location line="+249"/>
<location line="+283"/>
<source>Friend not Online</source>
<translation>Freund ist nicht online</translation>
</message>