Added tabbed PopupChatWindow. You can switch to tabbed chat window in the settings (NotifyPage).

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3797 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2010-11-15 20:49:24 +00:00
parent 1e28183c2d
commit 39907c1afc
14 changed files with 1504 additions and 1036 deletions

View File

@ -52,6 +52,7 @@ const uint32_t RS_SYSTRAY_GROUP_MSG = 0x0010;
const uint32_t RS_CHAT_OPEN = 0x0001;
//const uint32_t free = 0x0002;
const uint32_t RS_CHAT_FOCUS = 0x0004;
const uint32_t RS_CHAT_TABBED_WINDOW = 0x0008;
const uint32_t RS_FEED_TYPE_PEER = 0x0010;
const uint32_t RS_FEED_TYPE_CHAN = 0x0020;

View File

@ -241,6 +241,7 @@ HEADERS += rshare.h \
gui/profile/ProfileEdit.h \
gui/profile/ProfileWidget.h \
gui/profile/StatusMessage.h \
gui/chat/PopupChatWindow.h \
gui/chat/PopupChatDialog.h \
gui/chat/HandleRichText.h \
gui/chat/ChatStyle.h \
@ -362,6 +363,7 @@ FORMS += gui/StartDialog.ui \
gui/channels/ChannelDetails.ui \
gui/channels/EditChanDetails.ui \
gui/channels/ShareKey.ui \
gui/chat/PopupChatWindow.ui \
gui/chat/PopupChatDialog.ui \
gui/connect/ConfCertDialog.ui \
gui/msgs/MessageComposer.ui \
@ -477,6 +479,7 @@ SOURCES += main.cpp \
gui/channels/ChannelDetails.cpp \
gui/channels/EditChanDetails.cpp \
gui/channels/ShareKey.cpp \
gui/chat/PopupChatWindow.cpp \
gui/chat/PopupChatDialog.cpp \
gui/chat/HandleRichText.cpp \
gui/chat/ChatStyle.cpp \

View File

@ -35,6 +35,7 @@
#include <sys/stat.h>
#include "PopupChatDialog.h"
#include "PopupChatWindow.h"
#include "gui/RetroShareLink.h"
#include "rshare.h"
@ -61,9 +62,7 @@
#define appDir QApplication::applicationDirPath()
#define IMAGE_WINDOW ":/images/rstray3.png"
#define IMAGE_WINDOW_TYPING ":/images/typing.png"
#define WINDOW(This) dynamic_cast<PopupChatWindow*>(This->window())
/*****
* #define CHAT_DEBUG 1
@ -91,21 +90,18 @@ void playsound()
}
/** Default constructor */
PopupChatDialog::PopupChatDialog(std::string id, const QString name, QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags), dialogId(id), dialogName(name),
PopupChatDialog::PopupChatDialog(const std::string &id, const QString &name, QWidget *parent, Qt::WFlags flags)
: QWidget(parent, flags), dialogId(id), dialogName(name),
lastChatTime(0), lastChatName("")
{
/* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this);
firstShow = true;
Settings->loadWidgetInformation(this);
this->move(qrand()%100, qrand()%100); //avoid to stack multiple popup chat windows on the same position
m_bInsertOnVisible = true;
newMessages = false;
typing = false;
m_manualDelete = false;
peerStatus = 0;
last_status_send_time = 0 ;
style.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
@ -117,8 +113,6 @@ PopupChatDialog::PopupChatDialog(std::string id, const QString name, QWidget *pa
connect(ui.avatarFrameButton, SIGNAL(toggled(bool)), this, SLOT(showAvatarFrame(bool)));
connect(ui.actionAvatar, SIGNAL(triggered()),this, SLOT(getAvatar()));
connect(ui.sendButton, SIGNAL(clicked( ) ), this, SLOT(sendChat( ) ));
connect(ui.addFileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile()));
@ -142,16 +136,11 @@ PopupChatDialog::PopupChatDialog(std::string id, const QString name, QWidget *pa
connect(ui.chattextEdit,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
// Create the status bar
resetStatusBar() ;
resetStatusBar();
//ui.textBrowser->setOpenExternalLinks ( false );
//ui.textBrowser->setOpenLinks ( false );
QString title = tr("RetroShare") + " - " + name;
setWindowTitle(title);
setWindowIcon(QIcon(IMAGE_WINDOW));
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")));
@ -250,6 +239,17 @@ PopupChatDialog::~PopupChatDialog()
{
// save settings
processSettings(false);
PopupChatWindow *window = WINDOW(this);
if (window) {
window->removeDialog(this);
window->calculateTitle(NULL);
}
std::map<std::string, PopupChatDialog *>::iterator it;
if (chatDialogs.end() != (it = chatDialogs.find(dialogId))) {
chatDialogs.erase(it);
}
}
void PopupChatDialog::processSettings(bool bLoad)
@ -271,7 +271,7 @@ void PopupChatDialog::processSettings(bool bLoad)
Settings->endGroup();
}
/*static*/ PopupChatDialog *PopupChatDialog::getExistingInstance(std::string id)
/*static*/ PopupChatDialog *PopupChatDialog::getExistingInstance(const std::string &id)
{
std::map<std::string, PopupChatDialog *>::iterator it;
if (chatDialogs.end() != (it = chatDialogs.find(id))) {
@ -282,21 +282,19 @@ void PopupChatDialog::processSettings(bool bLoad)
return NULL;
}
/*static*/ PopupChatDialog *PopupChatDialog::getPrivateChat(std::string id, uint chatflags)
/*static*/ PopupChatDialog *PopupChatDialog::getPrivateChat(const std::string &id, uint chatflags)
{
/* see if it exists already */
PopupChatDialog *popupchatdialog = getExistingInstance(id);
if (popupchatdialog) {
if (popupchatdialog->isVisible() == false && (chatflags & RS_CHAT_OPEN) == 0) {
/* Window exists, but is hidden ... don't show it */
return popupchatdialog;
}
} else {
if (popupchatdialog == NULL) {
if (chatflags & RS_CHAT_OPEN) {
RsPeerDetails sslDetails;
if (rsPeers->getPeerDetails(id, sslDetails)) {
popupchatdialog = new PopupChatDialog(id, PeerDefs::nameWithLocation(sslDetails));
chatDialogs[id] = popupchatdialog;
PopupChatWindow *window = PopupChatWindow::getWindow(false);
window->addDialog(popupchatdialog);
}
}
}
@ -305,14 +303,11 @@ void PopupChatDialog::processSettings(bool bLoad)
return NULL;
}
if (chatflags & RS_CHAT_FOCUS) {
popupchatdialog->show();
popupchatdialog->getfocus();
} else {
if (popupchatdialog->isVisible() == false) {
popupchatdialog->showMinimized();
}
QApplication::alert(popupchatdialog);
popupchatdialog->insertChatMsgs();
PopupChatWindow *window = WINDOW(popupchatdialog);
if (window) {
window->showDialog(popupchatdialog, chatflags);
}
return popupchatdialog;
@ -320,14 +315,24 @@ void PopupChatDialog::processSettings(bool bLoad)
/*static*/ void PopupChatDialog::cleanupChat()
{
std::map<std::string, PopupChatDialog *>::iterator it;
PopupChatWindow::cleanup();
/* PopupChatDialog destuctor removes the entry from the map */
std::list<PopupChatDialog*> list;
std::map<std::string, PopupChatDialog*>::iterator it;
for (it = chatDialogs.begin(); it != chatDialogs.end(); it++) {
if (it->second) {
delete (it->second);
list.push_back(it->second);
}
}
chatDialogs.clear();
std::list<PopupChatDialog*>::iterator it1;
for (it1 = list.begin(); it1 != list.end(); it1++) {
delete (*it1);
}
}
/*static*/ void PopupChatDialog::privateChatChanged(int list, int type)
@ -357,7 +362,7 @@ void PopupChatDialog::processSettings(bool bLoad)
}
}
void PopupChatDialog::chatFriend(std::string id)
void PopupChatDialog::chatFriend(const std::string &id)
{
if (id.empty()){
return;
@ -414,6 +419,11 @@ void PopupChatDialog::chatFriend(std::string id)
it->second->updateAvatar() ;
}
void PopupChatDialog::focusDialog()
{
ui.chattextEdit->setFocus();
}
void PopupChatDialog::pasteLink()
{
std::cerr << "In paste link" << std::endl ;
@ -434,10 +444,15 @@ void PopupChatDialog::contextMenu( QPoint point )
void PopupChatDialog::resetStatusBar()
{
ui.statusLabel->clear();
ui.typingpixmapLabel->clear();
ui.statusLabel->clear();
ui.typingpixmapLabel->clear();
setWindowIcon(QIcon(IMAGE_WINDOW));
typing = false;
PopupChatWindow *window = WINDOW(this);
if (window) {
window->calculateTitle(this);
}
}
void PopupChatDialog::updateStatusTyping()
@ -458,45 +473,39 @@ void PopupChatDialog::updateStatusTyping()
void PopupChatDialog::updateStatusString(const QString& peer_id, const QString& status_string)
{
QString status = QString::fromStdString(rsPeers->getPeerName(peer_id.toStdString())) + " " + tr(status_string.toAscii());
ui.statusLabel->setText(status) ; // displays info for 5 secs.
ui.statusLabel->setText(status); // displays info for 5 secs.
ui.typingpixmapLabel->setPixmap(QPixmap(":images/typing.png") );
if (status_string == "is typing...") {
setWindowIcon(QIcon(IMAGE_WINDOW_TYPING));
typing = true;
PopupChatWindow *window = WINDOW(this);
if (window) {
window->calculateTitle(this);
}
}
QTimer::singleShot(5000,this,SLOT(resetStatusBar())) ;
}
void PopupChatDialog::getfocus()
void PopupChatDialog::resizeEvent(QResizeEvent *event)
{
activateWindow();
setWindowState((windowState() & (~Qt::WindowMinimized)) | Qt::WindowActive);
raise();
ui.chattextEdit->setFocus();
// Workaround: now the scroll position is correct calculated
QScrollBar *scrollbar = ui.textBrowser->verticalScrollBar();
scrollbar->setValue(scrollbar->maximum());
}
void PopupChatDialog::showEvent(QShowEvent *event)
void PopupChatDialog::activate()
{
if (m_bInsertOnVisible) {
insertChatMsgs();
PopupChatWindow *window = WINDOW(this);
if (window) {
if (window->isActiveWindow()) {
newMessages = false;
window->calculateTitle(this);
}
} else {
newMessages = false;
}
if (firstShow) {
firstShow = false;
// Workaround: now the scroll position is correct calculated
QScrollBar *scrollbar = ui.textBrowser->verticalScrollBar();
scrollbar->setValue(scrollbar->maximum());
}
}
void PopupChatDialog::closeEvent (QCloseEvent * event)
{
Settings->saveWidgetInformation(this);
hide();
event->ignore();
}
void PopupChatDialog::onPrivateChatChanged(int list, int type, bool initial /*= false*/)
@ -573,13 +582,6 @@ void PopupChatDialog::onPrivateChatChanged(int list, int type, bool initial /*=
void PopupChatDialog::insertChatMsgs()
{
if (isVisible() == false) {
m_bInsertOnVisible = true;
return;
}
m_bInsertOnVisible = false;
std::list<ChatInfo> newchat;
if (!rsMsgs->getPrivateChatQueue(true, dialogId, newchat))
{
@ -603,7 +605,19 @@ void PopupChatDialog::insertChatMsgs()
rsMsgs->clearPrivateChatQueue(true, dialogId);
playsound();
QApplication::alert(this);
PopupChatWindow *window = WINDOW(this);
if (window) {
window->alertDialog(this);
}
if (isVisible() == false || (window && window->isActiveWindow() == false)) {
newMessages = true;
if (window) {
window->calculateTitle(this);
}
}
}
void PopupChatDialog::addChatMsg(bool incoming, const std::string &id, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, enumChatType chatType, bool addToHistory)
@ -642,7 +656,7 @@ void PopupChatDialog::addChatMsg(bool incoming, const std::string &id, const QSt
QScrollBar *scrollbar = ui.textBrowser->verticalScrollBar();
scrollbar->setValue(scrollbar->maximum());
resetStatusBar() ;
resetStatusBar();
}
bool PopupChatDialog::eventFilter(QObject *obj, QEvent *event)
@ -674,7 +688,7 @@ bool PopupChatDialog::eventFilter(QObject *obj, QEvent *event)
}
}
// pass the event on to the parent class
return QMainWindow::eventFilter(obj, event);
return QWidget::eventFilter(obj, event);
}
void PopupChatDialog::sendChat()
@ -877,30 +891,6 @@ void PopupChatDialog::updateAvatar()
delete[] data ;
}
void PopupChatDialog::getAvatar()
{
QString fileName = QFileDialog::getOpenFileName(this, "Load File", QDir::homePath(), "Pictures (*.png *.xpm *.jpg)");
if(!fileName.isEmpty())
{
picture = QPixmap(fileName).scaled(96,96, Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
std::cerr << "Sending avatar image down the pipe" << std::endl ;
// send avatar down the pipe for other peers to get it.
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
picture.save(&buffer, "PNG"); // writes image into ba in PNG format
std::cerr << "Image size = " << ba.size() << std::endl ;
rsMsgs->setOwnAvatarData((unsigned char *)(ba.data()),ba.size()) ; // last char 0 included.
updateAvatar() ;
}
}
void PopupChatDialog::addExtraFile()
{
// select a file
@ -948,8 +938,6 @@ void PopupChatDialog::addAttachment(std::string filePath,int flag)
}
}
void PopupChatDialog::fileHashingFinished(AttachFileItem* file)
{
std::cerr << "PopupChatDialog::fileHashingFinished() started.";
@ -1163,6 +1151,7 @@ void PopupChatDialog::updateStatus(const QString &peer_id, int status)
/* set font size for status */
if (stdPeerId == dialogId) {
// the peers status has changed
switch (status) {
case RS_STATUS_OFFLINE:
ui.avatarlabel->setStyleSheet("QLabel#avatarlabel{ border-image:url(:/images/avatarstatus_bg_offline.png); }");
@ -1202,6 +1191,13 @@ void PopupChatDialog::updateStatus(const QString &peer_id, int status)
QString statusString("<span style=\"font-size:11pt; font-weight:500;""\">%1</span>");
ui.friendnamelabel->setText(dialogName + " (" + statusString.arg(StatusDefs::name(status)) + ")") ;
peerStatus = status;
PopupChatWindow *window = WINDOW(this);
if (window) {
window->calculateTitle(this);
}
return;
}
@ -1251,7 +1247,6 @@ void PopupChatDialog::updatePeersCustomStateString(const QString& peer_id, const
}
}
void PopupChatDialog::on_actionMessageHistory_triggered()
{
ImHistoryBrowser imBrowser(dialogId, historyKeeper, ui.chattextEdit, this);

View File

@ -35,7 +35,7 @@ class ChatInfo;
#include "gui/im_history/IMHistoryKeeper.h"
#include "ChatStyle.h"
class PopupChatDialog : public QMainWindow
class PopupChatDialog : public QWidget
{
Q_OBJECT
@ -43,17 +43,23 @@ public:
enum enumChatType { TYPE_NORMAL, TYPE_HISTORY, TYPE_OFFLINE };
public:
static PopupChatDialog *getExistingInstance(std::string id);
static PopupChatDialog *getPrivateChat(std::string id, uint chatflags);
static PopupChatDialog *getExistingInstance(const std::string &id);
static PopupChatDialog *getPrivateChat(const std::string &id, uint chatflags);
static void cleanupChat();
static void chatFriend(std::string id);
static void chatFriend(const std::string &id);
static void updateAllAvatars();
static void privateChatChanged(int list, int type);
void updatePeerAvatar(const std::string&);
std::string getPeerId() { return dialogId; }
QString getTitle() { return dialogName; }
bool hasNewMessages() { return newMessages; }
bool isTyping() { return typing; }
int getPeerStatus() { return peerStatus; }
void focusDialog();
void activate();
public slots:
void getfocus();
void pasteLink() ;
void contextMenu(QPoint) ;
@ -71,12 +77,11 @@ public slots:
protected:
/** Default constructor */
PopupChatDialog(std::string id, const QString name, QWidget *parent = 0, Qt::WFlags flags = 0);
PopupChatDialog(const std::string &id, const QString &name, QWidget *parent = 0, Qt::WFlags flags = 0);
/** Default destructor */
~PopupChatDialog();
void closeEvent (QCloseEvent * event);
void showEvent (QShowEvent * event);
virtual void resizeEvent(QResizeEvent *event);
virtual void dragEnterEvent(QDragEnterEvent *event);
virtual void dropEvent(QDropEvent *event);
@ -87,8 +92,6 @@ protected:
void updateAvatar();
QPixmap picture;
private slots:
void on_actionMessageHistory_triggered();
void addExtraFile();
@ -103,7 +106,6 @@ private slots:
void sendChat();
void updatePeersCustomStateString(const QString& peer_id, const QString& status_string) ;
void getAvatar();
void on_actionClear_Chat_triggered();
@ -139,13 +141,13 @@ private:
QString wholeChat;
QString fileName;
bool m_bInsertOnVisible;
bool newMessages;
bool typing;
int peerStatus;
IMHistoryKeeper historyKeeper;
ChatStyle style;
bool m_manualDelete;
bool firstShow;
/** Qt Designer generated object */
Ui::PopupChatDialog ui;
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,331 @@
/****************************************************************
*
* RetroShare is distributed under the following license:
*
* Copyright (C) 2006, crypton
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include <QPixmap>
#include <QFileDialog>
#include "PopupChatWindow.h"
#include "PopupChatDialog.h"
#include "gui/settings/rsharesettings.h"
#include "gui/settings/RsharePeerSettings.h"
#include "gui/common/StatusDefs.h"
#include <retroshare/rsmsgs.h>
#include <retroshare/rsnotify.h>
#define IMAGE_WINDOW ":/images/rstray3.png"
#define IMAGE_TYPING ":/images/typing.png"
#define IMAGE_CHAT ":/images/chat.png"
static PopupChatWindow *instance = NULL;
/*static*/ PopupChatWindow *PopupChatWindow::getWindow(bool needSingleWindow)
{
if (needSingleWindow == false && (Settings->getChatFlags() & RS_CHAT_TABBED_WINDOW)) {
if (instance == NULL) {
instance = new PopupChatWindow(true);
}
return instance;
}
return new PopupChatWindow(false);
}
/*static*/ void PopupChatWindow::cleanup()
{
if (instance) {
delete(instance);
instance = NULL;
}
}
/** Default constructor */
PopupChatWindow::PopupChatWindow(bool tabbed, QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags)
{
/* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this);
tabbedWindow = tabbed;
firstShow = true;
chatDialog = NULL;
ui.tabWidget->setVisible(tabbedWindow);
if (Settings->getChatFlags() & RS_CHAT_TABBED_WINDOW) {
ui.actionDockTab->setVisible(tabbedWindow == false);
ui.actionUndockTab->setVisible(tabbedWindow);
} else {
ui.actionDockTab->setVisible(false);
ui.actionUndockTab->setVisible(false);
}
setAttribute(Qt::WA_DeleteOnClose, true);
connect(ui.actionAvatar, SIGNAL(triggered()),this, SLOT(getAvatar()));
connect(ui.actionDockTab, SIGNAL(triggered()), this, SLOT(dockTab()));
connect(ui.actionUndockTab, SIGNAL(triggered()), this, SLOT(undockTab()));
connect(ui.tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(tabCloseRequested(int)));
connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabCurrentChanged(int)));
setWindowIcon(QIcon(IMAGE_WINDOW));
}
/** Destructor. */
PopupChatWindow::~PopupChatWindow()
{
if (tabbedWindow) {
Settings->saveWidgetInformation(this);
} else {
PeerSettings->saveWidgetInformation(peerId, this);
}
if (this == instance) {
instance = NULL;
}
}
void PopupChatWindow::showEvent(QShowEvent *event)
{
if (firstShow) {
firstShow = false;
if (tabbedWindow) {
Settings->loadWidgetInformation(this);
} else {
this->move(qrand()%100, qrand()%100); //avoid to stack multiple popup chat windows on the same position
PeerSettings->loadWidgetInformation(peerId, this);
}
}
}
void PopupChatWindow::changeEvent(QEvent *event)
{
if (event->type() == QEvent::ActivationChange) {
if (tabbedWindow) {
PopupChatDialog *pcd = dynamic_cast<PopupChatDialog*>(ui.tabWidget->currentWidget());
if (pcd) {
pcd->activate();
}
} else {
if (chatDialog) {
chatDialog->activate();
}
}
}
}
void PopupChatWindow::addDialog(PopupChatDialog *dialog)
{
if (tabbedWindow) {
ui.tabWidget->addTab(dialog, dialog->getTitle());
} else {
ui.horizontalLayout->addWidget(dialog);
peerId = dialog->getPeerId();
chatDialog = dialog;
}
}
void PopupChatWindow::removeDialog(PopupChatDialog *dialog)
{
if (tabbedWindow) {
int tab = ui.tabWidget->indexOf(dialog);
if (tab >= 0) {
ui.tabWidget->removeTab(tab);
}
if (ui.tabWidget->count() == 0) {
deleteLater();
}
} else {
if (chatDialog == dialog) {
ui.horizontalLayout->removeWidget(dialog);
chatDialog = NULL;
deleteLater();
}
}
}
void PopupChatWindow::showDialog(PopupChatDialog *dialog, uint chatflags)
{
if (chatflags & RS_CHAT_FOCUS) {
if (tabbedWindow) {
ui.tabWidget->setCurrentWidget(dialog);
}
show();
activateWindow();
setWindowState((windowState() & (~Qt::WindowMinimized)) | Qt::WindowActive);
raise();
} else {
if (isVisible() == false) {
showMinimized();
}
alertDialog(dialog);
}
dialog->focusDialog();
}
void PopupChatWindow::alertDialog(PopupChatDialog *dialog)
{
QApplication::alert(this);
}
void PopupChatWindow::calculateTitle(PopupChatDialog *dialog)
{
if (dialog) {
if (ui.tabWidget->isVisible()) {
int tab = ui.tabWidget->indexOf(dialog);
if (tab >= 0) {
if (dialog->isTyping()) {
ui.tabWidget->setTabIcon(tab, QIcon(IMAGE_TYPING));
} else if (dialog->hasNewMessages()) {
ui.tabWidget->setTabIcon(tab, QIcon(IMAGE_CHAT));
} else {
ui.tabWidget->setTabIcon(tab, QIcon(StatusDefs::imageIM(dialog->getPeerStatus())));
}
}
}
}
bool hasNewMessages = false;
PopupChatDialog *pcd;
/* is typing */
bool isTyping = false;
if (ui.tabWidget->isVisible()) {
int tabCount = ui.tabWidget->count();
for (int i = 0; i < tabCount; i++) {
pcd = dynamic_cast<PopupChatDialog*>(ui.tabWidget->widget(i));
if (pcd) {
if (pcd->isTyping()) {
isTyping = true;
}
if (pcd->hasNewMessages()) {
hasNewMessages = true;
}
}
}
} else {
if (dialog) {
isTyping = dialog->isTyping();
hasNewMessages = dialog->hasNewMessages();
}
}
if (ui.tabWidget->isVisible()) {
pcd = dynamic_cast<PopupChatDialog*>(ui.tabWidget->currentWidget());
} else {
pcd = dialog;
}
QIcon icon;
if (isTyping) {
icon = QIcon(IMAGE_TYPING);
} else if (hasNewMessages) {
icon = QIcon(IMAGE_CHAT);
} else {
if (pcd) {
icon = QIcon(StatusDefs::imageIM(pcd->getPeerStatus()));
} else {
icon = QIcon(IMAGE_WINDOW);
}
}
setWindowIcon(icon);
if (pcd) {
setWindowTitle(pcd->getTitle() + " (" + StatusDefs::name(pcd->getPeerStatus()) + ")");
} else {
setWindowTitle(tr("RetroShare"));
}
}
void PopupChatWindow::getAvatar()
{
QString fileName = QFileDialog::getOpenFileName(this, "Load File", QDir::homePath(), "Pictures (*.png *.xpm *.jpg)");
if(!fileName.isEmpty()) {
QPixmap picture = QPixmap(fileName).scaled(96,96, Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
std::cerr << "Sending avatar image down the pipe" << std::endl;
// send avatar down the pipe for other peers to get it.
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
picture.save(&buffer, "PNG"); // writes image into ba in PNG format
std::cerr << "Image size = " << ba.size() << std::endl;
rsMsgs->setOwnAvatarData((unsigned char *)(ba.data()), ba.size()); // last char 0 included.
}
}
void PopupChatWindow::tabCloseRequested(int tab)
{
QWidget *widget = ui.tabWidget->widget(tab);
if (widget) {
widget->deleteLater();
}
}
void PopupChatWindow::tabCurrentChanged(int tab)
{
PopupChatDialog *pcd = dynamic_cast<PopupChatDialog*>(ui.tabWidget->widget(tab));
if (pcd) {
pcd->activate();
}
}
void PopupChatWindow::dockTab()
{
if ((Settings->getChatFlags() & RS_CHAT_TABBED_WINDOW) && chatDialog) {
PopupChatWindow *pcw = getWindow(false);
if (pcw) {
PopupChatDialog *pcd = chatDialog;
removeDialog(pcd);
pcw->addDialog(pcd);
pcw->show();
pcw->calculateTitle(pcd);
}
}
}
void PopupChatWindow::undockTab()
{
PopupChatDialog *pcd = dynamic_cast<PopupChatDialog*>(ui.tabWidget->currentWidget());
if (pcd) {
PopupChatWindow *pcw = getWindow(true);
if (pcw) {
removeDialog(pcd);
pcw->addDialog(pcd);
pcd->show();
pcw->show();
pcw->calculateTitle(pcd);
}
}
}

View File

@ -0,0 +1,72 @@
/****************************************************************
* RetroShare is distributed under the following license:
*
* Copyright (C) 2006, crypton
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#ifndef _POPUPCHATWINDOW_H
#define _POPUPCHATWINDOW_H
#include <QTimer>
#include "ui_PopupChatWindow.h"
class PopupChatDialog;
class PopupChatWindow : public QMainWindow
{
Q_OBJECT
public:
static PopupChatWindow *getWindow(bool needSingleWindow);
static void cleanup();
public:
void addDialog(PopupChatDialog *dialog);
void removeDialog(PopupChatDialog *dialog);
void showDialog(PopupChatDialog *dialog, uint chatflags);
void alertDialog(PopupChatDialog *dialog);
void calculateTitle(PopupChatDialog *dialog);
protected:
/** Default constructor */
PopupChatWindow(bool tabbed, QWidget *parent = 0, Qt::WFlags flags = 0);
/** Default destructor */
~PopupChatWindow();
virtual void showEvent(QShowEvent *event);
virtual void changeEvent(QEvent *event);
private slots:
void getAvatar();
void tabCloseRequested(int tab);
void tabCurrentChanged(int tab);
void dockTab();
void undockTab();
private:
bool tabbedWindow;
bool firstShow;
std::string peerId;
PopupChatDialog *chatDialog;
/** Qt Designer generated object */
Ui::PopupChatWindow ui;
};
#endif

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PopupChatWindow</class>
<widget class="QMainWindow" name="PopupChatWindow">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>531</width>
<height>451</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">MainWindow</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<widget class="QWidget" name="chatcentralwidget">
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>1</number>
</property>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="tabsClosable">
<bool>true</bool>
</property>
<property name="movable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="chatstatusbar"/>
<widget class="QToolBar" name="chattoolBar">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>32</height>
</size>
</property>
<property name="movable">
<bool>false</bool>
</property>
<property name="allowedAreas">
<set>Qt::LeftToolBarArea|Qt::TopToolBarArea</set>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="floatable">
<bool>false</bool>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionAvatar"/>
<addaction name="actionDockTab"/>
<addaction name="actionUndockTab"/>
</widget>
<action name="actionAvatar">
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/no_avatar_70.png</normaloff>:/images/no_avatar_70.png</iconset>
</property>
<property name="text">
<string>Avatar</string>
</property>
<property name="toolTip">
<string>Set your Avatar Picture</string>
</property>
</action>
<action name="actionDockTab">
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/uploads.png</normaloff>:/images/uploads.png</iconset>
</property>
<property name="text">
<string>Dock tab</string>
</property>
<property name="toolTip">
<string>Dock tab</string>
</property>
</action>
<action name="actionUndockTab">
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/download.png</normaloff>:/images/download.png</iconset>
</property>
<property name="text">
<string>Undock tab</string>
</property>
<property name="toolTip">
<string>Undock tab</string>
</property>
</action>
</widget>
<resources>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -101,6 +101,8 @@ NotifyPage::save(QString &errmsg)
chatflags |= RS_CHAT_OPEN;
if (ui.chat_Focus->isChecked())
chatflags |= RS_CHAT_FOCUS;
if (ui.chat_tabbedWindow->isChecked())
chatflags |= RS_CHAT_TABBED_WINDOW;
if (ui.trayNotify_PrivateChat->isChecked())
traynotifyflags |= TRAYNOTIFY_PRIVATECHAT;
@ -150,6 +152,7 @@ void NotifyPage::load()
ui.chat_NewWindow->setChecked(chatflags & RS_CHAT_OPEN);
ui.chat_Focus->setChecked(chatflags & RS_CHAT_FOCUS);
ui.chat_tabbedWindow->setChecked(chatflags & RS_CHAT_TABBED_WINDOW);
ui.systray_GroupChat->setChecked(Settings->getDisplayTrayGroupChat());

View File

@ -678,6 +678,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chat_tabbedWindow">
<property name="text">
<string>Use a single tabbed window</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -22,6 +22,7 @@
#include <QColor>
#include <QFont>
#include <QDateTime>
#include <QWidget>
#include <string>
#include <list>
@ -155,3 +156,43 @@ void RsharePeerSettings::setPrivateChatFont(const std::string &peerId, const QSt
{
set(peerId, "PrivateChatFont", value);
}
void RsharePeerSettings::saveWidgetInformation(const std::string &peerId, QWidget *widget)
{
std::string gpgId;
if (getGpgIdOfSslId(peerId, gpgId) == false) {
/* gpg id not found */
return;
}
beginGroup(QString::fromStdString(gpgId));
beginGroup("widgetInformation");
beginGroup(widget->objectName());
setValue("size", widget->size());
setValue("pos", widget->pos());
endGroup();
endGroup();
endGroup();
}
void RsharePeerSettings::loadWidgetInformation(const std::string &peerId, QWidget *widget)
{
std::string gpgId;
if (getGpgIdOfSslId(peerId, gpgId) == false) {
/* gpg id not found */
return;
}
beginGroup(QString::fromStdString(gpgId));
beginGroup("widgetInformation");
beginGroup(widget->objectName());
widget->resize(value("size", widget->size()).toSize());
widget->move(value("pos", QPoint(200, 200)).toPoint());
endGroup();
endGroup();
endGroup();
}

View File

@ -37,6 +37,9 @@ public:
QString getPrivateChatFont(const std::string &peerId);
void setPrivateChatFont(const std::string &peerId, const QString &value);
void saveWidgetInformation(const std::string &peerId, QWidget *widget);
void loadWidgetInformation(const std::string &peerId, QWidget *widget);
protected:
/** Default constructor. */
RsharePeerSettings();

View File

@ -1139,14 +1139,6 @@ p, li { white-space: pre-wrap; }
<source>Share Channel</source>
<translation>Verteile Kanal</translation>
</message>
<message>
<source>Popularity: %1
Fetches: %2
Available: %3</source>
<translation type="obsolete">Popularität: %1
Abgeholt: %2
Verfügbar: %3</translation>
</message>
<message>
<location line="+482"/>
<source>No Channel Selected</source>
@ -3571,7 +3563,7 @@ p, li { white-space: pre-wrap; }
<translation>Beliebtheit:</translation>
</message>
<message>
<location line="+326"/>
<location line="+339"/>
<location line="+107"/>
<source>Anonymous</source>
<translation>Anonym</translation>
@ -3605,7 +3597,7 @@ p, li { white-space: pre-wrap; }
<translation>Du kannst einem anonymen Autor nicht antworten</translation>
</message>
<message>
<location line="-1485"/>
<location line="-1498"/>
<source>Your Forums</source>
<translation>Deine Foren</translation>
</message>
@ -3748,7 +3740,7 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../gui/ForumsDialog.cpp" line="+127"/>
<location line="+1251"/>
<location line="+1264"/>
<source>Start New Thread</source>
<translation>Erstelle neues Thema</translation>
</message>
@ -3776,7 +3768,7 @@ p, li { white-space: pre-wrap; }
<translation>Inhalt</translation>
</message>
<message>
<location filename="../gui/ForumsDialog.cpp" line="-1238"/>
<location filename="../gui/ForumsDialog.cpp" line="-1251"/>
<location line="+3"/>
<source>Mark as read</source>
<translation>Als gelesen markieren</translation>
@ -5495,10 +5487,6 @@ Bitte gib etwas Speicher frei und drücke OK.</translation>
<source>Size</source>
<translation>Grösse</translation>
</message>
<message>
<source>Sources</source>
<translation type="obsolete">Quellen</translation>
</message>
<message>
<location line="+5"/>
<source>Hash</source>
@ -6092,10 +6080,6 @@ p, li { white-space: pre-wrap; }
<source>File Name</source>
<translation>Dateiname</translation>
</message>
<message>
<source>Sources</source>
<translation type="obsolete">Quellen</translation>
</message>
<message>
<location line="+10"/>
<source>Hash</source>
@ -6755,14 +6739,6 @@ p, li { white-space: pre-wrap; }
<source>DHT is off.</source>
<translation>DHT ist ausgeschaltet.</translation>
</message>
<message>
<source>UPNP NOT FOUND.</source>
<translation type="obsolete">UPNP wurde nicht gefunden.</translation>
</message>
<message>
<source>DHT OK.</source>
<translation type="obsolete">DHT OK.</translation>
</message>
<message>
<location line="+5"/>
<source>Stun external address detection is working.</source>
@ -6793,10 +6769,6 @@ p, li { white-space: pre-wrap; }
<source>external address finder didn&apos;t found anything</source>
<translation>Externer IP Adress-Finder hat nichts gefunden</translation>
</message>
<message>
<source>DHT is not working (down).</source>
<translation type="obsolete">DHT läuft nicht.</translation>
</message>
<message>
<location filename="../gui/NetworkDialog.ui" line="-165"/>
<source>Network Status</source>
@ -6868,14 +6840,6 @@ p, li { white-space: pre-wrap; }
</context>
<context>
<name>NetworkView</name>
<message>
<source>Hide Settings</source>
<translation type="obsolete">Einstellungen verbergen</translation>
</message>
<message>
<source>Show Settings</source>
<translation type="obsolete">Einstellungen anzeigen</translation>
</message>
<message>
<location filename="../gui/NetworkView.ui" line="+14"/>
<source>Form</source>
@ -6921,18 +6885,6 @@ p, li { white-space: pre-wrap; }
<source>Edge length:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Settings</source>
<translation type="obsolete">Einstellungen</translation>
</message>
<message>
<source>Show Friends of Friends</source>
<translation type="obsolete">Zeige Freunde von Freunden</translation>
</message>
<message>
<source>Draw Friend Connections</source>
<translation type="obsolete">Zeichne Verbindungen zwischen Freunden</translation>
</message>
</context>
<context>
<name>NewTag</name>
@ -7070,23 +7022,16 @@ p, li { white-space: pre-wrap; }
<source>Open Window for new chat</source>
<translation>Öffne Fenster für neuen Chat</translation>
</message>
<message>
<source>Open Window for new Peer Chat</source>
<translation type="obsolete">Öffne Fenster für neuen Peer</translation>
</message>
<message>
<source>Reopen if closed by user</source>
<translation type="obsolete">Wiederöffnen, wenn von Benutzer geschlossen</translation>
</message>
<message>
<source>Reopen if closed by user:</source>
<translation type="obsolete">Wiederöffnen, wenn von Benutzer geschlossen:</translation>
</message>
<message>
<location line="+7"/>
<source>Grab Focus when chat arrives</source>
<translation>Fokus auf neues Chatfenster legen</translation>
</message>
<message>
<location line="+7"/>
<source>Use a single tabbed window</source>
<translation>Ein Fenster mit Tabs verwenden</translation>
</message>
<message>
<location line="+10"/>
<source>Group chat</source>
@ -7098,7 +7043,7 @@ p, li { white-space: pre-wrap; }
<translation>Zeige Systemabschnitts-Nachricht an</translation>
</message>
<message>
<location line="-122"/>
<location line="-129"/>
<source>Add feeds at end</source>
<translation>Feeds am Ende anfügen</translation>
</message>
@ -7986,7 +7931,7 @@ p, li { white-space: pre-wrap; }
<context>
<name>PopupChatDialog</name>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+745"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+748"/>
<source>Hide Avatar</source>
<translation>Avatar verstecken</translation>
</message>
@ -7996,35 +7941,35 @@ p, li { white-space: pre-wrap; }
<translation>Avatar zeigen</translation>
</message>
<message>
<location line="+342"/>
<location line="+316"/>
<source>File not found or file name not accepted.</source>
<translation>Datei nicht gefunden oder Dateiname nicht akzeptiert.</translation>
</message>
<message>
<location line="+90"/>
<location line="+91"/>
<source>Messages you send will be delivered after Friend is again Online</source>
<translation>Nachrichten, die Du versendest gehen bei diesem Freund erst wieder ein wenn er Online ist</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.ui" line="+566"/>
<location line="+293"/>
<location filename="../gui/chat/PopupChatDialog.ui" line="+564"/>
<location line="+263"/>
<source>Bold</source>
<translation>Fett</translation>
</message>
<message>
<location line="-261"/>
<location line="+271"/>
<location line="-231"/>
<location line="+241"/>
<source>Underline</source>
<translation>Unterstrichen</translation>
</message>
<message>
<location line="-239"/>
<location line="+234"/>
<location line="-209"/>
<location line="+204"/>
<source>Italic</source>
<translation>Kursiv</translation>
</message>
<message>
<location line="-202"/>
<location line="-172"/>
<source>Set Font</source>
<translation>Schriftart setzen</translation>
</message>
@ -8034,7 +7979,7 @@ p, li { white-space: pre-wrap; }
<translation>Textfarbe</translation>
</message>
<message>
<location line="+222"/>
<location line="+180"/>
<source>Clear offline messages</source>
<translation>Entferne offline Nachrichten</translation>
</message>
@ -8049,12 +7994,12 @@ p, li { white-space: pre-wrap; }
<translation>Nachrichtenverlauf</translation>
</message>
<message>
<location line="-411"/>
<location line="-369"/>
<source>Send</source>
<translation>Senden</translation>
</message>
<message>
<location line="+382"/>
<location line="+340"/>
<source>Clear Chat</source>
<translation>Chat-Chronik löschen</translation>
</message>
@ -8064,32 +8009,22 @@ p, li { white-space: pre-wrap; }
<translation>Deaktiviere Emoticons</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="-1002"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="-989"/>
<source>Paste retroshare Link</source>
<translation>RetroShare Link einfügen</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.ui" line="-29"/>
<location filename="../gui/chat/PopupChatDialog.ui" line="-17"/>
<source>Strike</source>
<translation>Durchgestrichen</translation>
</message>
<message>
<location line="+9"/>
<source>Avatar</source>
<translation></translation>
</message>
<message>
<location line="+3"/>
<source>Set your Avatar Picture</source>
<translation>Wähle dein Avatar Bild aus</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+738"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+726"/>
<source>Add Extra File</source>
<translation>Zusätzlich eine Datei hinzufügen</translation>
</message>
<message>
<location line="+167"/>
<location line="+165"/>
<location line="+7"/>
<source>Drop file error.</source>
<translation>Dateifehler bei Drag&apos;n&apos;Drop.</translation>
@ -8100,12 +8035,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="-409"/>
<location filename="../gui/chat/PopupChatDialog.ui" line="-367"/>
<source>Add a File for your Friend</source>
<translation>Füge eine Datei für deinen Freund hinzu</translation>
</message>
<message>
<location line="+431"/>
<location line="+389"/>
<location line="+3"/>
<source>Save Chat History</source>
<translation>Chat Verlauf speichern</translation>
@ -8121,13 +8056,13 @@ p, li { white-space: pre-wrap; }
<translation>Text Datei (*.txt );;Alle Dateien (*)</translation>
</message>
<message>
<location line="-728"/>
<location line="-720"/>
<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="-463"/>
<location filename="../gui/chat/PopupChatDialog.ui" line="-421"/>
<source>Attach a Picture</source>
<translation>Bild anhängen</translation>
</message>
@ -8138,7 +8073,7 @@ Do you want to send them a Message instead</source>
<translation></translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+769"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="+762"/>
<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>
@ -8158,7 +8093,7 @@ Do you want to send them a Message instead</source>
<translation>ist Offline.</translation>
</message>
<message>
<location line="-714"/>
<location line="-697"/>
<source>is typing...</source>
<translation>tippt...</translation>
</message>
@ -8168,16 +8103,41 @@ Do you want to send them a Message instead</source>
<translation>Schliessen</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatDialog.cpp" line="-320"/>
<source>RetroShare</source>
<translation></translation>
</message>
<message>
<location line="+272"/>
<location filename="../gui/chat/PopupChatDialog.cpp" line="-58"/>
<source>Friend not Online</source>
<translation>Freund ist nicht online</translation>
</message>
</context>
<context>
<name>PopupChatWindow</name>
<message>
<location filename="../gui/chat/PopupChatWindow.ui" line="+94"/>
<source>Avatar</source>
<translation>Avatar</translation>
</message>
<message>
<location line="+3"/>
<source>Set your Avatar Picture</source>
<translation>Wähle dein Avatar Bild</translation>
</message>
<message>
<location line="+9"/>
<location line="+3"/>
<source>Dock tab</source>
<translation>Docke Tab an</translation>
</message>
<message>
<location line="+9"/>
<location line="+3"/>
<source>Undock tab</source>
<translation>Docke Tab ab</translation>
</message>
<message>
<location filename="../gui/chat/PopupChatWindow.cpp" line="+260"/>
<source>RetroShare</source>
<translation>RetroShare</translation>
</message>
</context>
<context>
<name>PrintPreview</name>
<message>
@ -8600,18 +8560,6 @@ p, li { white-space: pre-wrap; }
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; color:#76746c;&quot;&gt;Externe Adresse:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>&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:&apos;DejaVu Sans&apos;; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:8pt; color:#76746c;&quot;&gt;Dynamic DSN:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="obsolete">&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:&apos;DejaVu Sans&apos;; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:8pt; color:#76746c;&quot;&gt;Dynamisches DSN:&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location line="+119"/>
@ -8837,14 +8785,6 @@ p, li { white-space: pre-wrap; }
<source>Discovery :</source>
<translation>Entdeckung :</translation>
</message>
<message>
<source>Share Ip and information with your friend (Disc On)</source>
<translation type="obsolete">Teile IP und Informationen mit Freunden (Disc On)</translation>
</message>
<message>
<source>Don&apos;t share any information (Disc Off)</source>
<translation type="obsolete">Teile keine Informationen (Disc Off)</translation>
</message>
<message>
<location line="+94"/>
<location line="+235"/>
@ -10120,22 +10060,6 @@ p, li { white-space: pre-wrap; }
<source>Send retroshare Link</source>
<translation>Sende RetroShare Link</translation>
</message>
<message>
<source>%1 recommends a list of files to you</source>
<translation type="obsolete">%1 empfiehlt Dir eine Liste von Dateien</translation>
</message>
<message>
<source>%1 recommends a file to you</source>
<translation type="obsolete">%1 empfiehlt Dir eine Datei</translation>
</message>
<message>
<source>Recommend (Automated message) To </source>
<translation type="obsolete">Empfehle (automatisch) in einer Nachricht an </translation>
</message>
<message>
<source>Recommend in a message to </source>
<translation type="obsolete">Empfehle in einer Nachricht an </translation>
</message>
<message>
<location line="-100"/>
<source>Copy retroshare Links to Clipboard</source>