From f14b529009f85327170fd04bdb1f97cc3ed6d98a Mon Sep 17 00:00:00 2001 From: thunder2 Date: Sat, 21 May 2011 16:26:00 +0000 Subject: [PATCH] Added tags to the MessageComposer. Added context menu to contact list in MessageComposer. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4213 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3msgservice.cc | 107 +++--- libretroshare/src/services/p3msgservice.h | 3 +- retroshare-gui/src/RetroShare.pro | 2 + retroshare-gui/src/gui/MessagesDialog.cpp | 315 +++++------------- retroshare-gui/src/gui/MessagesDialog.h | 11 +- .../src/gui/msgs/MessageComposer.cpp | 194 +++++++++-- retroshare-gui/src/gui/msgs/MessageComposer.h | 18 +- .../src/gui/msgs/MessageComposer.ui | 130 +++++--- retroshare-gui/src/gui/msgs/TagsMenu.cpp | 199 +++++++++++ retroshare-gui/src/gui/msgs/TagsMenu.h | 48 +++ .../src/gui/settings/MessagePage.cpp | 1 - retroshare-gui/src/lang/retroshare_de.qm | Bin 329140 -> 330661 bytes retroshare-gui/src/lang/retroshare_de.ts | 202 +++++++---- 13 files changed, 807 insertions(+), 423 deletions(-) create mode 100644 retroshare-gui/src/gui/msgs/TagsMenu.cpp create mode 100644 retroshare-gui/src/gui/msgs/TagsMenu.h diff --git a/libretroshare/src/services/p3msgservice.cc b/libretroshare/src/services/p3msgservice.cc index 99682ffae..9347478ea 100644 --- a/libretroshare/src/services/p3msgservice.cc +++ b/libretroshare/src/services/p3msgservice.cc @@ -124,7 +124,55 @@ int p3MsgService::status() return 1; } -int p3MsgService::incomingMsgs() +void p3MsgService::processMsg(RsMsgItem *mi) +{ + mi -> recvTime = time(NULL); + mi -> msgId = getNewUniqueMsgId(); + + std::string mesg; + + RsStackMutex stack(mMsgMtx); /*** STACK LOCKED MTX ***/ + + if (mi -> PeerId() == mConnMgr->getOwnId()) + { + /* from the loopback device */ + mi -> msgFlags |= RS_MSG_FLAGS_OUTGOING; + } + else + { + mi -> msgFlags = RS_MSG_FLAGS_NEW; + + /* from a peer */ + MsgInfoSummary mis; + initRsMIS(mi, mis); + + // msgNotifications.push_back(mis); + pqiNotify *notify = getPqiNotify(); + if (notify) + { + std::string message , title; + notify->AddPopupMessage(RS_POPUP_MSG, mi->PeerId(), + title.assign(mi->subject.begin(), mi->subject.end()), + message.assign(mi->message.begin(),mi->message.end())); + + std::ostringstream out; + out << mi->msgId; + notify->AddFeedItem(RS_FEED_ITEM_MESSAGE, out.str(), "", ""); + } + } + + imsg[mi->msgId] = mi; + RsMsgSrcId* msi = new RsMsgSrcId(); + msi->msgId = mi->msgId; + msi->srcId = mi->PeerId(); + mSrcIds.insert(std::pair(msi->msgId, msi)); + msgChanged.IndicateChanged(); + IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ + + /**** STACK UNLOCKED ***/ +} + +int p3MsgService::incomingMsgs() { RsMsgItem *mi; int i = 0; @@ -134,50 +182,8 @@ int p3MsgService::incomingMsgs() { changed = true ; ++i; - mi -> recvTime = time(NULL); - mi -> msgId = getNewUniqueMsgId(); - std::string mesg; - - RsStackMutex stack(mMsgMtx); /*** STACK LOCKED MTX ***/ - - if (mi -> PeerId() == mConnMgr->getOwnId()) - { - /* from the loopback device */ - mi -> msgFlags |= RS_MSG_FLAGS_OUTGOING; - } - else - { - mi -> msgFlags = RS_MSG_FLAGS_NEW; - - /* from a peer */ - MsgInfoSummary mis; - initRsMIS(mi, mis); - - // msgNotifications.push_back(mis); - pqiNotify *notify = getPqiNotify(); - if (notify) - { - std::string message , title; - notify->AddPopupMessage(RS_POPUP_MSG, mi->PeerId(), - title.assign(mi->subject.begin(), mi->subject.end()), - message.assign(mi->message.begin(),mi->message.end())); - - std::ostringstream out; - out << mi->msgId; - notify->AddFeedItem(RS_FEED_ITEM_MESSAGE, out.str(), "", ""); - } - } - - imsg[mi->msgId] = mi; - RsMsgSrcId* msi = new RsMsgSrcId(); - msi->msgId = mi->msgId; - msi->srcId = mi->PeerId(); - mSrcIds.insert(std::pair(msi->msgId, msi)); - msgChanged.IndicateChanged(); - IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ - - /**** STACK UNLOCKED ***/ + processMsg(mi); } if(changed) rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); @@ -307,8 +313,8 @@ bool p3MsgService::saveList(bool& cleanup, std::list& itemList) for(mit = msgOutgoing.begin(); mit != msgOutgoing.end(); mit++) itemList.push_back(mit->second) ; - for(mit2 = mTags.begin(); mit2 != mTags.end(); mit2++) - itemList.push_back(mit2->second); + for(mit2 = mTags.begin(); mit2 != mTags.end(); mit2++) + itemList.push_back(mit2->second); for(mit3 = mMsgTags.begin(); mit3 != mMsgTags.end(); mit3++) itemList.push_back(mit3->second); @@ -886,7 +892,14 @@ bool p3MsgService::MessageSend(MessageInfo &info) RsMsgItem *msg = initMIRsMsg(info, mConnMgr->getOwnId()); if (msg) { - sendMessage(msg); + /* use processMsg to get the new msgId */ +// sendMessage(msg); + processMsg(msg); + + // return new message id + std::ostringstream out; + out << msg->msgId; + info.msgId = out.str(); } return true; diff --git a/libretroshare/src/services/p3msgservice.h b/libretroshare/src/services/p3msgservice.h index 9968f6efb..aa92ebb63 100644 --- a/libretroshare/src/services/p3msgservice.h +++ b/libretroshare/src/services/p3msgservice.h @@ -105,6 +105,7 @@ int checkOutgoingMessages(); uint32_t getNewUniqueMsgId(); int sendMessage(RsMsgItem *item); int incomingMsgs(); +void processMsg(RsMsgItem *mi); void initRsMI(RsMsgItem *msg, MessageInfo &mi); void initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis); @@ -136,7 +137,7 @@ void initStandardTagTypes(); uint32_t mMsgUniqueId; // used delete msgSrcIds after config save - std::map mSrcIds; + std::map mSrcIds; // save the parent of the messages in draft for replied and forwarded std::map mParentId; diff --git a/retroshare-gui/src/RetroShare.pro b/retroshare-gui/src/RetroShare.pro index 373adf9fa..4ce32b86b 100644 --- a/retroshare-gui/src/RetroShare.pro +++ b/retroshare-gui/src/RetroShare.pro @@ -269,6 +269,7 @@ HEADERS += rshare.h \ gui/channels/ShareKey.h \ gui/connect/ConfCertDialog.h \ gui/msgs/MessageComposer.h \ + gui/msgs/TagsMenu.h \ gui/msgs/textformat.h \ gui/images/retroshare_win.rc.h \ gui/settings/rsharesettings.h \ @@ -499,6 +500,7 @@ SOURCES += main.cpp \ gui/chat/ChatStyle.cpp \ gui/connect/ConfCertDialog.cpp \ gui/msgs/MessageComposer.cpp \ + gui/msgs/TagsMenu.cpp \ gui/common/vmessagebox.cpp \ gui/common/rwindow.cpp \ gui/common/html.cpp \ diff --git a/retroshare-gui/src/gui/MessagesDialog.cpp b/retroshare-gui/src/gui/MessagesDialog.cpp index 7323b7784..c9724f1da 100644 --- a/retroshare-gui/src/gui/MessagesDialog.cpp +++ b/retroshare-gui/src/gui/MessagesDialog.cpp @@ -20,8 +20,6 @@ ****************************************************************/ #include -#include -#include #include #include #include @@ -30,9 +28,12 @@ #include #include #include +#include +#include #include "MessagesDialog.h" #include "msgs/MessageComposer.h" +#include "msgs/TagsMenu.h" #include "util/printpreview.h" #include "settings/rsharesettings.h" #include "util/misc.h" @@ -45,6 +46,7 @@ #include #include #include +#include #include @@ -85,61 +87,6 @@ #define ROW_SENTBOX 3 #define ROW_TRASHBOX 4 -#define ACTION_TAGSINDEX_SIZE 3 -#define ACTION_TAGSINDEX_TYPE "Type" -#define ACTION_TAGSINDEX_ID "ID" -#define ACTION_TAGSINDEX_COLOR "Color" - -#define ACTION_TAGS_REMOVEALL 0 -#define ACTION_TAGS_TAG 1 -#define ACTION_TAGS_NEWTAG 2 - -class MessagesMenu : public QMenu -{ -public: - MessagesMenu(const QString &title, QWidget *parent) : QMenu (title, parent) - { - } - -protected: - virtual void paintEvent(QPaintEvent *e) - { - QMenu::paintEvent(e); - - QPainter p(this); - QRegion emptyArea = QRegion(rect()); - - //draw the items with color - foreach (QAction *pAction, actions()) { - QRect adjustedActionRect = actionGeometry(pAction); - if (!e->rect().intersects(adjustedActionRect)) - continue; - - const QMap &Values = pAction->data().toMap(); - if (Values.size () != ACTION_TAGSINDEX_SIZE) { - continue; - } - if (Values [ACTION_TAGSINDEX_TYPE] != ACTION_TAGS_TAG) { - continue; - } - - //set the clip region to be extra safe (and adjust for the scrollers) - QRegion adjustedActionReg(adjustedActionRect); - emptyArea -= adjustedActionReg; - p.setClipRegion(adjustedActionReg); - - QStyleOptionMenuItem opt; - initStyleOption(&opt, pAction); - - opt.palette.setColor(QPalette::ButtonText, QColor(Values [ACTION_TAGSINDEX_COLOR].toInt())); - // needed for Cleanlooks - opt.palette.setColor(QPalette::Text, QColor(Values [ACTION_TAGSINDEX_COLOR].toInt())); - - opt.rect = adjustedActionRect; - style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this); - } - } -}; MessagesDialog::LockUpdate::LockUpdate (MessagesDialog *pDialog, bool bUpdate) { @@ -366,6 +313,14 @@ MessagesDialog::MessagesDialog(QWidget *parent) ui.listWidget->setCurrentRow(ROW_INBOX); // create tag menu + TagsMenu *menu = new TagsMenu (tr("Tags"), this); + connect(menu, SIGNAL(aboutToShow()), this, SLOT(tagAboutToShow())); + connect(menu, SIGNAL(tagSet(int, bool)), this, SLOT(tagSet(int, bool))); + connect(menu, SIGNAL(tagRemoveAll()), this, SLOT(tagRemoveAll())); + + ui.tagButton->setMenu(menu); + + // fill tags fillTags(); // create timer for navigation @@ -464,95 +419,46 @@ bool MessagesDialog::eventFilter(QObject *obj, QEvent *event) void MessagesDialog::fillTags() { - MsgTagType Tags; - rsMsgs->getMessageTagTypes(Tags); - std::map >::iterator Tag; + MsgTagType tags; + rsMsgs->getMessageTagTypes(tags); + std::map >::iterator tag; - // create tag menu - QMenu *pMenu = new MessagesMenu (tr("Tags"), this); - connect(pMenu, SIGNAL(triggered (QAction*)), this, SLOT(tagTriggered(QAction*))); - connect(pMenu, SIGNAL(aboutToShow()), this, SLOT(tagAboutToShow())); + // fill tags + m_bInChange = true; - bool bUser = false; + // save current selection + QListWidgetItem *item = ui.tagWidget->currentItem(); + uint32_t nSelectecTagId = 0; + if (item) { + nSelectecTagId = item->data(Qt::UserRole).toInt(); + } - QString text; - QAction *pAction; - QMap Values; + QListWidgetItem *itemToSelect = NULL; - if (Tags.types.size()) { - pAction = new QAction(tr("Remove All Tags"), pMenu); - Values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_REMOVEALL; - Values [ACTION_TAGSINDEX_ID] = 0; - Values [ACTION_TAGSINDEX_COLOR] = 0; - pAction->setData (Values); - pMenu->addAction(pAction); + QString text; - pMenu->addSeparator(); + ui.tagWidget->clear(); + for (tag = tags.types.begin(); tag != tags.types.end(); tag++) { + text = TagDefs::name(tag->first, tag->second.first); - for (Tag = Tags.types.begin(); Tag != Tags.types.end(); Tag++) { - text = TagDefs::name(Tag->first, Tag->second.first); + item = new QListWidgetItem (text, ui.tagWidget); + item->setForeground(QBrush(QColor(tag->second.second))); + item->setIcon(QIcon(":/images/foldermail.png")); + item->setData(Qt::UserRole, tag->first); + item->setData(Qt::UserRole + 1, text); // for updateMessageSummaryList - pAction = new QAction(text, pMenu); - Values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_TAG; - Values [ACTION_TAGSINDEX_ID] = Tag->first; - Values [ACTION_TAGSINDEX_COLOR] = QRgb(Tag->second.second); - pAction->setData (Values); - pAction->setCheckable(true); + if (tag->first == nSelectecTagId) { + itemToSelect = item; + } + } - if (Tag->first >= RS_MSGTAGTYPE_USER && bUser == false) { - bUser = true; - pMenu->addSeparator(); - } + if (itemToSelect) { + ui.tagWidget->setCurrentItem(itemToSelect); + } - pMenu->addAction(pAction); - } + m_bInChange = false; - pMenu->addSeparator(); - } - - pAction = new QAction(tr("New tag ..."), pMenu); - Values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_NEWTAG; - Values [ACTION_TAGSINDEX_ID] = 0; - Values [ACTION_TAGSINDEX_COLOR] = 0; - pAction->setData (Values); - pMenu->addAction(pAction); - - ui.tagButton->setMenu(pMenu); - - // fill tags - m_bInChange = true; - - // save current selection - QListWidgetItem *pItem = ui.tagWidget->currentItem(); - uint32_t nSelectecTagId = 0; - if (pItem) { - nSelectecTagId = pItem->data(Qt::UserRole).toInt(); - } - - QListWidgetItem *pItemToSelect = NULL; - - ui.tagWidget->clear(); - for (Tag = Tags.types.begin(); Tag != Tags.types.end(); Tag++) { - text = TagDefs::name(Tag->first, Tag->second.first); - - pItem = new QListWidgetItem (text, ui.tagWidget); - pItem->setForeground(QBrush(QColor(Tag->second.second))); - pItem->setIcon(QIcon(":/images/foldermail.png")); - pItem->setData(Qt::UserRole, Tag->first); - pItem->setData(Qt::UserRole + 1, text); // for updateMessageSummaryList - - if (Tag->first == nSelectecTagId) { - pItemToSelect = pItem; - } - } - - if (pItemToSelect) { - ui.tagWidget->setCurrentItem(pItemToSelect); - } - - m_bInChange = false; - - updateMessageSummaryList(); + updateMessageSummaryList(); } // replaced by shortcut @@ -982,6 +888,8 @@ void MessagesDialog::messagesTagsChanged() fillTags(); insertMessages(); + + showTagLabels(); } static void InitIconAndFont(QStandardItem *pItem [COLUMN_COUNT]) @@ -1533,6 +1441,7 @@ void MessagesDialog::showTagLabels() Tag = Tags.types.find(*tagId); if (Tag != Tags.types.end()) { QLabel *tagLabel = new QLabel(TagDefs::name(Tag->first, Tag->second.first), this); + tagLabel->setMaximumHeight(16); tagLabel->setStyleSheet(TagDefs::labelStyleSheet(Tag->second.second)); tagLabels.push_back(tagLabel); ui.taglayout->addWidget(tagLabel); @@ -2161,113 +2070,69 @@ void MessagesDialog::clearFilter() void MessagesDialog::tagAboutToShow() { - // activate actions from the first selected row - MsgTagInfo tagInfo; + TagsMenu *menu = dynamic_cast(ui.tagButton->menu()); + if (menu == NULL) { + return; + } - QList Rows; - getSelectedMsgCount (&Rows, NULL, NULL); + // activate actions from the first selected row + MsgTagInfo tagInfo; - if (Rows.size()) { - QStandardItem* pItem = MessagesModel->item(Rows [0], COLUMN_DATA); - std::string msgId = pItem->data(ROLE_MSGID).toString().toStdString(); + QList rows; + getSelectedMsgCount (&rows, NULL, NULL); - rsMsgs->getMessageTag(msgId, tagInfo); - } + if (rows.size()) { + QStandardItem* item = MessagesModel->item(rows [0], COLUMN_DATA); + std::string msgId = item->data(ROLE_MSGID).toString().toStdString(); - QMenu *pMenu = ui.tagButton->menu(); + rsMsgs->getMessageTag(msgId, tagInfo); + } - foreach(QObject *pObject, pMenu->children()) { - QAction *pAction = qobject_cast (pObject); - if (pAction == NULL) { - continue; - } - - const QMap &Values = pAction->data().toMap(); - if (Values.size () != ACTION_TAGSINDEX_SIZE) { - continue; - } - if (Values [ACTION_TAGSINDEX_TYPE] != ACTION_TAGS_TAG) { - continue; - } - - std::list::iterator tagId = std::find(tagInfo.tagIds.begin(), tagInfo.tagIds.end(), Values [ACTION_TAGSINDEX_ID]); - pAction->setChecked(tagId != tagInfo.tagIds.end()); - } + menu->activateActions(tagInfo.tagIds); } -void MessagesDialog::tagTriggered(QAction *pAction) +void MessagesDialog::tagRemoveAll() { - if (pAction == NULL) { - return; - } + LockUpdate Lock (this, false); - const QMap &Values = pAction->data().toMap(); - if (Values.size () != ACTION_TAGSINDEX_SIZE) { - return; - } + QList rows; + getSelectedMsgCount (&rows, NULL, NULL); + for (int row = 0; row < rows.size(); row++) { + QStandardItem* item = MessagesModel->item(rows [row], COLUMN_DATA); + std::string msgId = item->data(ROLE_MSGID).toString().toStdString(); - LockUpdate Lock (this, false); + rsMsgs->setMessageTag(msgId, 0, false); + Lock.setUpdate(true); + } - bool bRemoveAll = false; - int nId = 0; - bool bSet = false; + showTagLabels(); - if (Values [ACTION_TAGSINDEX_TYPE] == ACTION_TAGS_REMOVEALL) { - // remove all tags - bRemoveAll = true; - } else if (Values [ACTION_TAGSINDEX_TYPE] == ACTION_TAGS_NEWTAG) { - // new tag - MsgTagType Tags; - rsMsgs->getMessageTagTypes(Tags); + // LockUpdate -> insertMessages(); +} - NewTag TagDlg(Tags); - if (TagDlg.exec() == QDialog::Accepted && TagDlg.m_nId) { - std::map >::iterator Tag = Tags.types.find(TagDlg.m_nId); - if (Tag == Tags.types.end()) { - return; - } - if (rsMsgs->setMessageTagType(Tag->first, Tag->second.first, Tag->second.second) == false) { - return; - } - fillTags(); - nId = TagDlg.m_nId; - bSet = true; - } else { - return; - } - } else if (Values [ACTION_TAGSINDEX_TYPE].toInt() == ACTION_TAGS_TAG) { - nId = Values [ACTION_TAGSINDEX_ID].toInt(); - if (nId == 0) { - return; - } - bSet = pAction->isChecked(); - } else { - return; - } +void MessagesDialog::tagSet(int tagId, bool set) +{ + if (tagId == 0) { + return; + } - QList Rows; - getSelectedMsgCount (&Rows, NULL, NULL); - for (int nRow = 0; nRow < Rows.size(); nRow++) { - QStandardItem* pItem = MessagesModel->item(Rows [nRow], COLUMN_DATA); - std::string msgId = pItem->data(ROLE_MSGID).toString().toStdString(); + LockUpdate Lock (this, false); - if (bRemoveAll) { - // remove all - rsMsgs->setMessageTag(msgId, 0, false); - Lock.setUpdate(true); + QList rows; + getSelectedMsgCount (&rows, NULL, NULL); + for (int row = 0; row < rows.size(); row++) { + QStandardItem* item = MessagesModel->item(rows [row], COLUMN_DATA); + std::string msgId = item->data(ROLE_MSGID).toString().toStdString(); - } else { - // set or unset tag - MsgTagInfo tagInfo; - if (rsMsgs->setMessageTag(msgId, nId, bSet)) { - Lock.setUpdate(true); - } - } - } + if (rsMsgs->setMessageTag(msgId, tagId, set)) { + Lock.setUpdate(true); + } + } - showTagLabels(); - // LockUpdate -> insertMessages(); + showTagLabels(); + + // LockUpdate -> insertMessages(); } void MessagesDialog::emptyTrash() diff --git a/retroshare-gui/src/gui/MessagesDialog.h b/retroshare-gui/src/gui/MessagesDialog.h index 674f984c4..bca95de49 100644 --- a/retroshare-gui/src/gui/MessagesDialog.h +++ b/retroshare-gui/src/gui/MessagesDialog.h @@ -22,19 +22,11 @@ #ifndef _MESSAGESDIALOG_H #define _MESSAGESDIALOG_H -#include -#include -#include #include -#include - -#include #include "mainpage.h" #include "ui_MessagesDialog.h" -#include "settings/NewTag.h" - class MessagesDialog : public MainPage { Q_OBJECT @@ -105,8 +97,9 @@ private slots: void filterColumnChanged(); void clearFilter(); - void tagTriggered(QAction *pAction); void tagAboutToShow(); + void tagSet(int tagId, bool set); + void tagRemoveAll(); private: class LockUpdate diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.cpp b/retroshare-gui/src/gui/msgs/MessageComposer.cpp index 73409f625..d8156fc6b 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.cpp +++ b/retroshare-gui/src/gui/msgs/MessageComposer.cpp @@ -53,8 +53,12 @@ #include "gui/common/Emoticons.h" #include "textformat.h" #include "util/misc.h" +#include "TagsMenu.h" +#include "gui/common/TagDefs.h" +#include "gui/connect/ConfCertDialog.h" -#define IMAGE_GROUP16 ":/images/user/group16.png" +#define IMAGE_GROUP16 ":/images/user/group16.png" +#define IMAGE_FRIENDINFO ":/images/peerdetails_16x16.png" #define COLUMN_CONTACT_NAME 0 #define COLUMN_CONTACT_DATA 0 @@ -161,6 +165,7 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WFlags flags) connect(ui.msgText->document(), SIGNAL(redoAvailable(bool)), actionRedo, SLOT(setEnabled(bool))); connect(ui.msgFileList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuFileList(QPoint))); + connect(ui.msgSendList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuMsgSendList(QPoint))); setWindowModified(ui.msgText->document()->isModified()); actionSave->setEnabled(ui.msgText->document()->isModified()); @@ -182,11 +187,11 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WFlags flags) connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged())); - connect(ui.addToButton, SIGNAL(clicked(void)), this, SLOT(btnClickEvent())); - connect(ui.addCcButton, SIGNAL(clicked(void)), this, SLOT(btnClickEvent())); - connect(ui.addBccButton, SIGNAL(clicked(void)), this, SLOT(btnClickEvent())); - connect(ui.addRecommendButton, SIGNAL(clicked(void)), this, SLOT(recommendButtonClicked())); - connect(ui.msgSendList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(btnClickEvent())); + connect(ui.addToButton, SIGNAL(clicked(void)), this, SLOT(addTo())); + connect(ui.addCcButton, SIGNAL(clicked(void)), this, SLOT(addCc())); + connect(ui.addBccButton, SIGNAL(clicked(void)), this, SLOT(addBcc())); + connect(ui.addRecommendButton, SIGNAL(clicked(void)), this, SLOT(addRecommend())); + connect(ui.msgSendList, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(addTo())); connect(NotifyQt::getInstance(), SIGNAL(groupsChanged(int)), this, SLOT(groupsChanged(int))); connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(const QString&,int)), this, SLOT(peerStatusChanged(const QString&,int))); @@ -289,6 +294,14 @@ MessageComposer::MessageComposer(QWidget *parent, Qt::WFlags flags) /* set focus to subject */ ui.titleEdit->setFocus(); + // create tag menu + TagsMenu *menu = new TagsMenu (tr("Tags"), this); + connect(menu, SIGNAL(aboutToShow()), this, SLOT(tagAboutToShow())); + connect(menu, SIGNAL(tagSet(int, bool)), this, SLOT(tagSet(int, bool))); + connect(menu, SIGNAL(tagRemoveAll()), this, SLOT(tagRemoveAll())); + + ui.tagButton->setMenu(menu); + setAcceptDrops(true); #ifdef RS_RELEASE_VERSION @@ -473,6 +486,29 @@ void MessageComposer::contextMenuFileList(QPoint) contextMnu.exec(QCursor::pos()); } +void MessageComposer::contextMenuMsgSendList(QPoint) +{ + QMenu contextMnu(this); + + int selectedCount = ui.msgSendList->selectedItems().count(); + + QAction *action = contextMnu.addAction(QIcon(), tr("Add to \"To\""), this, SLOT(addTo())); + action->setEnabled(selectedCount); + action = contextMnu.addAction(QIcon(), tr("Add to \"CC\""), this, SLOT(addCc())); + action->setEnabled(selectedCount); + action = contextMnu.addAction(QIcon(), tr("Add to \"BCC\""), this, SLOT(addBcc())); + action->setEnabled(selectedCount); + action = contextMnu.addAction(QIcon(), tr("Add as Recommend"), this, SLOT(addRecommend())); + action->setEnabled(selectedCount); + + contextMnu.addSeparator(); + + action = contextMnu.addAction(QIcon(IMAGE_FRIENDINFO), tr("Friend Details"), this, SLOT(friendDetails())); + action->setEnabled(selectedCount == 1); + + contextMnu.exec(QCursor::pos()); +} + void MessageComposer::pasteRecommended() { std::vector links; @@ -943,6 +979,12 @@ MessageComposer *MessageComposer::newMsg(const std::string &msgId /*= ""*/) msgComposer->addRecipient(MessageComposer::BCC, *it, false) ; } + MsgTagInfo tagInfo; + rsMsgs->getMessageTag(msgId, tagInfo); + msgComposer->m_tagIds = tagInfo.tagIds; + + msgComposer->showTagLabels(); + msgComposer->ui.msgText->document()->setModified(false); } @@ -1261,6 +1303,25 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox) } } + if (mi.msgId.empty() == false) { + MsgTagInfo tagInfo; + rsMsgs->getMessageTag(mi.msgId, tagInfo); + + /* insert new tags */ + std::list::iterator tag; + for (tag = m_tagIds.begin(); tag != m_tagIds.end(); tag++) { + if (std::find(tagInfo.tagIds.begin(), tagInfo.tagIds.end(), *tag) == tagInfo.tagIds.end()) { + rsMsgs->setMessageTag(mi.msgId, *tag, true); + } else { + tagInfo.tagIds.remove(*tag); + } + } + + /* remove deleted tags */ + for (tag = tagInfo.tagIds.begin(); tag != tagInfo.tagIds.end(); tag++) { + rsMsgs->setMessageTag(mi.msgId, *tag, false); + } + } ui.msgText->document()->setModified(false); return true; } @@ -2302,19 +2363,8 @@ bool MessageComposer::FilterItem(QTreeWidgetItem *pItem, QString &sPattern) return (bVisible || nVisibleChildCount); } -void MessageComposer::btnClickEvent() +void MessageComposer::addContact(enumType type) { - enumType type; - if (QObject::sender() == ui.addToButton || QObject::sender() == ui.msgSendList) { - type = TO; - } else if (QObject::sender() == ui.addCcButton) { - type = CC; - } else if (QObject::sender() == ui.addBccButton) { - type = BCC; - } else { - return; - } - QTreeWidgetItemIterator itemIterator(ui.msgSendList); QTreeWidgetItem *item; while ((item = *itemIterator) != NULL) { @@ -2328,7 +2378,22 @@ void MessageComposer::btnClickEvent() } } -void MessageComposer::recommendButtonClicked() +void MessageComposer::addTo() +{ + addContact(TO); +} + +void MessageComposer::addCc() +{ + addContact(CC); +} + +void MessageComposer::addBcc() +{ + addContact(BCC); +} + +void MessageComposer::addRecommend() { std::list gpgIds; @@ -2375,6 +2440,22 @@ void MessageComposer::recommendButtonClicked() ui.msgText->setFocus(Qt::OtherFocusReason); } +void MessageComposer::friendDetails() +{ + QList selectedItems = ui.msgSendList->selectedItems(); + if (selectedItems.count() != 1) { + return; + } + + QTreeWidgetItem *item = selectedItems[0]; + if (item->type() == TYPE_GROUP) { + return; + } + + std::string id = item->data(COLUMN_CONTACT_DATA, ROLE_CONTACT_ID).toString().toStdString(); + ConfCertDialog::showIt(id, ConfCertDialog::PageDetails); +} + void MessageComposer::dragEnterEvent(QDragEnterEvent *event) { /* print out mimeType */ @@ -2450,3 +2531,78 @@ void MessageComposer::dropEvent(QDropEvent *event) event->setDropAction(Qt::CopyAction); event->accept(); } + +void MessageComposer::tagAboutToShow() +{ + TagsMenu *menu = dynamic_cast(ui.tagButton->menu()); + if (menu == NULL) { + return; + } + + menu->activateActions(m_tagIds); +} + +void MessageComposer::tagRemoveAll() +{ + m_tagIds.clear(); + + showTagLabels(); +} + +void MessageComposer::tagSet(int tagId, bool set) +{ + if (tagId == 0) { + return; + } + + std::list::iterator tag = std::find(m_tagIds.begin(), m_tagIds.end(), tagId); + if (tag == m_tagIds.end()) { + if (set) { + m_tagIds.push_back(tagId); + /* Keep the list sorted */ + m_tagIds.sort(); + } + } else { + if (set == false) { + m_tagIds.remove(tagId); + } + } + + showTagLabels(); +} + +void MessageComposer::clearTagLabels() +{ + /* clear all tags */ + while (tagLabels.size()) { + delete tagLabels.front(); + tagLabels.pop_front(); + } + while (ui.tagLayout->count()) { + delete ui.tagLayout->takeAt(0); + } +} + +void MessageComposer::showTagLabels() +{ + clearTagLabels(); + + if (m_tagIds.empty() == false) { + MsgTagType tags; + rsMsgs->getMessageTagTypes(tags); + + std::map >::iterator tag; + for (std::list::iterator tagId = m_tagIds.begin(); tagId != m_tagIds.end(); tagId++) { + tag = tags.types.find(*tagId); + if (tag != tags.types.end()) { + QLabel *tagLabel = new QLabel(TagDefs::name(tag->first, tag->second.first), this); + tagLabel->setMaximumHeight(16); + tagLabel->setStyleSheet(TagDefs::labelStyleSheet(tag->second.second)); + tagLabels.push_back(tagLabel); + ui.tagLayout->addWidget(tagLabel); + ui.tagLayout->addSpacing(3); + } + } + ui.tagLayout->addStretch(); + } +} diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.h b/retroshare-gui/src/gui/msgs/MessageComposer.h index a9b111a3f..fc34dfc28 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.h +++ b/retroshare-gui/src/gui/msgs/MessageComposer.h @@ -88,6 +88,7 @@ private slots: void contextMenu(QPoint); void pasteLink(); void contextMenuFileList(QPoint); + void contextMenuMsgSendList(QPoint); void pasteRecommended(); void on_contactsdockWidget_visibilityChanged(bool visible); void toggleContacts(); @@ -135,16 +136,24 @@ private slots: void titleChanged(); // Add to To/Cc/Bcc address fields - void btnClickEvent(); - void recommendButtonClicked(); + void addTo(); + void addCc(); + void addBcc(); + void addRecommend(); void editingRecipientFinished(); + void friendDetails(); void groupsChanged(int type); void peerStatusChanged(const QString& peer_id, int status); + void tagAboutToShow(); + void tagSet(int tagId, bool set); + void tagRemoveAll(); + private: void processSettings(bool bLoad); + void addContact(enumType type); void setTextColor(const QColor& col) ; void setupFileActions(); void setupEditActions(); @@ -173,6 +182,9 @@ private: bool getRecipientFromRow(int row, enumType &type, std::string &id, bool &group); void setRecipientToRow(int row, enumType type, std::string id, bool group); + void clearTagLabels(); + void showTagLabels(); + QAction *actionSave, *actionAlignLeft, *actionAlignCenter, @@ -201,6 +213,8 @@ private: std::string m_msgParentId; // parent message id std::string m_sDraftMsgId; // existing message id enumMessageType m_msgType; + std::list m_tagIds; + QList tagLabels; /* maps of files */ std::list mAttachments; diff --git a/retroshare-gui/src/gui/msgs/MessageComposer.ui b/retroshare-gui/src/gui/msgs/MessageComposer.ui index ede171600..516aa5ac9 100644 --- a/retroshare-gui/src/gui/msgs/MessageComposer.ui +++ b/retroshare-gui/src/gui/msgs/MessageComposer.ui @@ -17,7 +17,7 @@ Compose - + :/images/folder-draft.png:/images/folder-draft.png @@ -168,6 +168,9 @@ border-image: url(:/images/closepressed.png) 0 + + Qt::CustomContextMenu + QAbstractItemView::ExtendedSelection @@ -394,7 +397,7 @@ border: 1px solid #CCCCCC;} - + :/images/textedit/format_font_size_more.png:/images/textedit/format_font_size_more.png @@ -426,7 +429,7 @@ border: 1px solid #CCCCCC;} - + :/images/textedit/format_font_size_less.png:/images/textedit/format_font_size_less.png @@ -464,7 +467,7 @@ border: 1px solid #CCCCCC;} - + :/images/textedit/textbold.png:/images/textedit/textbold.png @@ -505,7 +508,7 @@ border: 1px solid #CCCCCC;} - + :/images/textedit/textitalic.png:/images/textedit/textitalic.png @@ -611,7 +614,7 @@ border: 1px solid #CCCCCC;} - + :/images/add_image24.png:/images/add_image24.png @@ -637,7 +640,7 @@ border: 1px solid #CCCCCC;} - + :/images/textedit/hi22-action-format-text-code.png:/images/textedit/hi22-action-format-text-code.png @@ -670,7 +673,7 @@ border: 1px solid #CCCCCC;} Qt::NoFocus - + :/images/emoticons/kopete/kopete020.png:/images/emoticons/kopete/kopete020.png @@ -708,7 +711,7 @@ border: 1px solid #CCCCCC;} - + :/images/textedit/textunder.png:/images/textedit/textunder.png @@ -746,33 +749,6 @@ border: 1px solid #CCCCCC;} - - - - 6 - - - QLayout::SetNoConstraint - - - - - - 10 - 75 - true - - - - Subject: - - - - - - - - @@ -819,6 +795,72 @@ border: 1px solid #CCCCCC;} + + + + QLayout::SetNoConstraint + + + + + Subject: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Tags: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + Tags + + + + :/images/tag24.png:/images/tag24.png + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + @@ -964,7 +1006,7 @@ border: 1px solid #CCCCCC;} - + :/images/send24.png:/images/send24.png @@ -976,7 +1018,7 @@ border: 1px solid #CCCCCC;} - + :/images/replymail24.png:/images/replymail24.png @@ -985,7 +1027,7 @@ border: 1px solid #CCCCCC;} - + :/images/contacts24.png:/images/contacts24.png @@ -997,7 +1039,7 @@ border: 1px solid #CCCCCC;} - + :/images/save24.png:/images/save24.png @@ -1009,7 +1051,7 @@ border: 1px solid #CCCCCC;} - + :/images/attach.png:/images/attach.png @@ -1024,7 +1066,7 @@ border: 1px solid #CCCCCC;} true - + :/images/quote_24.png:/images/quote_24.png @@ -1051,8 +1093,6 @@ border: 1px solid #CCCCCC;} comboFont hashBox - - - + diff --git a/retroshare-gui/src/gui/msgs/TagsMenu.cpp b/retroshare-gui/src/gui/msgs/TagsMenu.cpp new file mode 100644 index 000000000..cc4fcc181 --- /dev/null +++ b/retroshare-gui/src/gui/msgs/TagsMenu.cpp @@ -0,0 +1,199 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2006,2007 RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#include +#include +#include + +#include + +#include + +#include "TagsMenu.h" +#include "gui/common/TagDefs.h" +#include "gui/settings/NewTag.h" +#include "gui/notifyqt.h" + +#define ACTION_TAGSINDEX_SIZE 3 +#define ACTION_TAGSINDEX_TYPE "Type" +#define ACTION_TAGSINDEX_ID "ID" +#define ACTION_TAGSINDEX_COLOR "Color" + +#define ACTION_TAGS_REMOVEALL 0 +#define ACTION_TAGS_TAG 1 +#define ACTION_TAGS_NEWTAG 2 + +TagsMenu::TagsMenu(const QString &title, QWidget *parent) + : QMenu (title, parent) +{ + connect(this, SIGNAL(triggered (QAction*)), this, SLOT(tagTriggered(QAction*))); + connect(NotifyQt::getInstance(), SIGNAL(messagesTagsChanged()), this, SLOT(fillTags())); + + fillTags(); +} + +void TagsMenu::paintEvent(QPaintEvent *e) +{ + QMenu::paintEvent(e); + + QPainter p(this); + QRegion emptyArea = QRegion(rect()); + + //draw the items with color + foreach (QAction *action, actions()) { + QRect adjustedActionRect = actionGeometry(action); + if (!e->rect().intersects(adjustedActionRect)) + continue; + + const QMap &values = action->data().toMap(); + if (values.size () != ACTION_TAGSINDEX_SIZE) { + continue; + } + if (values [ACTION_TAGSINDEX_TYPE] != ACTION_TAGS_TAG) { + continue; + } + + //set the clip region to be extra safe (and adjust for the scrollers) + QRegion adjustedActionReg(adjustedActionRect); + emptyArea -= adjustedActionReg; + p.setClipRegion(adjustedActionReg); + + QStyleOptionMenuItem opt; + initStyleOption(&opt, action); + + opt.palette.setColor(QPalette::ButtonText, QColor(values [ACTION_TAGSINDEX_COLOR].toInt())); + // needed for Cleanlooks + opt.palette.setColor(QPalette::Text, QColor(values [ACTION_TAGSINDEX_COLOR].toInt())); + + opt.rect = adjustedActionRect; + style()->drawControl(QStyle::CE_MenuItem, &opt, &p, this); + } +} + +void TagsMenu::fillTags() +{ + clear(); + + MsgTagType tags; + rsMsgs->getMessageTagTypes(tags); + std::map >::iterator tag; + + bool user = false; + + QString text; + QAction *action; + QMap values; + + if (tags.types.size()) { + action = new QAction(tr("Remove All Tags"), this); + values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_REMOVEALL; + values [ACTION_TAGSINDEX_ID] = 0; + values [ACTION_TAGSINDEX_COLOR] = 0; + action->setData (values); + addAction(action); + + addSeparator(); + + for (tag = tags.types.begin(); tag != tags.types.end(); tag++) { + text = TagDefs::name(tag->first, tag->second.first); + + action = new QAction(text, this); + values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_TAG; + values [ACTION_TAGSINDEX_ID] = tag->first; + values [ACTION_TAGSINDEX_COLOR] = QRgb(tag->second.second); + action->setData (values); + action->setCheckable(true); + + if (tag->first >= RS_MSGTAGTYPE_USER && user == false) { + user = true; + addSeparator(); + } + + addAction(action); + } + + addSeparator(); + } + + action = new QAction(tr("New tag ..."), this); + values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_NEWTAG; + values [ACTION_TAGSINDEX_ID] = 0; + values [ACTION_TAGSINDEX_COLOR] = 0; + action->setData (values); + addAction(action); +} + +void TagsMenu::activateActions(std::list& tagIds) +{ + foreach(QObject *object, children()) { + QAction *action = qobject_cast (object); + if (action == NULL) { + continue; + } + + const QMap &values = action->data().toMap(); + if (values.size () != ACTION_TAGSINDEX_SIZE) { + continue; + } + if (values [ACTION_TAGSINDEX_TYPE] != ACTION_TAGS_TAG) { + continue; + } + + std::list::iterator tagId = std::find(tagIds.begin(), tagIds.end(), values [ACTION_TAGSINDEX_ID]); + action->setChecked(tagId != tagIds.end()); + } +} + +void TagsMenu::tagTriggered(QAction *action) +{ + if (action == NULL) { + return; + } + + const QMap &values = action->data().toMap(); + if (values.size () != ACTION_TAGSINDEX_SIZE) { + return; + } + + if (values [ACTION_TAGSINDEX_TYPE] == ACTION_TAGS_REMOVEALL) { + // remove all tags + emit tagRemoveAll(); + } else if (values [ACTION_TAGSINDEX_TYPE] == ACTION_TAGS_NEWTAG) { + // new tag + MsgTagType tags; + rsMsgs->getMessageTagTypes(tags); + + NewTag tagDlg(tags); + if (tagDlg.exec() == QDialog::Accepted && tagDlg.m_nId) { + std::map >::iterator tag = tags.types.find(tagDlg.m_nId); + if (tag != tags.types.end()) { + if (rsMsgs->setMessageTagType(tag->first, tag->second.first, tag->second.second)) { + emit tagSet(tagDlg.m_nId, true); + } + } + } + } else if (values [ACTION_TAGSINDEX_TYPE].toInt() == ACTION_TAGS_TAG) { + int tagId = values [ACTION_TAGSINDEX_ID].toInt(); + if (tagId) { + emit tagSet(tagId, action->isChecked()); + } + } +} diff --git a/retroshare-gui/src/gui/msgs/TagsMenu.h b/retroshare-gui/src/gui/msgs/TagsMenu.h new file mode 100644 index 000000000..142b48a57 --- /dev/null +++ b/retroshare-gui/src/gui/msgs/TagsMenu.h @@ -0,0 +1,48 @@ +/**************************************************************** + * RetroShare is distributed under the following license: + * + * Copyright (C) 2007, RetroShare Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ****************************************************************/ + +#ifndef _TAGSMENU_H +#define _TAGSMENU_H + +#include + +class TagsMenu : public QMenu +{ + Q_OBJECT + +public: + TagsMenu(const QString &title, QWidget *parent); + + void activateActions(std::list& tagIds); + +signals: + void tagSet(int tagId, bool set); + void tagRemoveAll(); + +protected: + virtual void paintEvent(QPaintEvent *e); + +private slots: + void fillTags(); + void tagTriggered(QAction *action); +}; + +#endif diff --git a/retroshare-gui/src/gui/settings/MessagePage.cpp b/retroshare-gui/src/gui/settings/MessagePage.cpp index 1f6a5e7b1..5e6ab761b 100644 --- a/retroshare-gui/src/gui/settings/MessagePage.cpp +++ b/retroshare-gui/src/gui/settings/MessagePage.cpp @@ -28,7 +28,6 @@ #include -#include "../MainWindow.h" #include "NewTag.h" MessagePage::MessagePage(QWidget * parent, Qt::WFlags flags) diff --git a/retroshare-gui/src/lang/retroshare_de.qm b/retroshare-gui/src/lang/retroshare_de.qm index d1e5d3f7ff73c3c366ea3bb9434db16297446508..0a472b90d350832005b3e77b9f91adcff84a29d2 100644 GIT binary patch delta 17597 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 aw)#IW1(8rDBv?#L)XYk0F4wuG>Hh*I9^<6| delta 16661 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 Qi`MbWU9vQH_=e{H0}WaM4gdfE diff --git a/retroshare-gui/src/lang/retroshare_de.ts b/retroshare-gui/src/lang/retroshare_de.ts index d9c2f19a5..0b2ba0727 100644 --- a/retroshare-gui/src/lang/retroshare_de.ts +++ b/retroshare-gui/src/lang/retroshare_de.ts @@ -1440,7 +1440,7 @@ p, li { white-space: pre-wrap; } ConfCertDialog - + Cancel Abbrechen @@ -1450,7 +1450,7 @@ p, li { white-space: pre-wrap; } OK - + Peer Info Nachbar Info @@ -1470,7 +1470,7 @@ p, li { white-space: pre-wrap; } Peer ID - + Peer Address Adresse des Nachbarn @@ -1511,7 +1511,7 @@ p, li { white-space: pre-wrap; } Nachbar Schlüssel ist unterzeichnet von: - + Last Contact Letzter Kontakt @@ -1531,7 +1531,7 @@ p, li { white-space: pre-wrap; } Ort - + Status Status @@ -1600,18 +1600,18 @@ p, li { white-space: pre-wrap; } - + RetroShare - - + + Error : cannot get peer details. Fehler: Kann Peer Details nicht ermitteln. - + Your key is signed by : Ihr Schlüssel ist unterzeichnet von: @@ -1658,7 +1658,7 @@ und meinen GPG Schlüssel unterzeichnet und meinen GPG Schlüssel nicht unterzeichnet - + Signature Failure Signatur Fehler @@ -1683,17 +1683,16 @@ und meinen GPG Schlüssel nicht unterzeichnet Zeige Hilfe - + RetroShare ID - Copy Peer - Kopiere Nachbar + Kopiere Nachbar - + Certificate Zertifikat @@ -5652,18 +5651,18 @@ Bitte gib etwas Speicher frei und drücke OK. MessageComposer - + Compose Verfassen - + Contacts Kontakte - + Search for Name: Suche Name: @@ -5673,7 +5672,7 @@ Bitte gib etwas Speicher frei und drücke OK. Zurücksetzen - + Send To: Senden an: @@ -5693,22 +5692,22 @@ Bitte gib etwas Speicher frei und drücke OK. >> Bcc - + Subject: Betreff: - + Paragraph Absatz - + Search Friends Suche Freunde - + >> Recommend >> Empfehlen @@ -5769,7 +5768,18 @@ Bitte gib etwas Speicher frei und drücke OK. Unterstrichen - + + Tags: + Schlagwörter: + + + + + Tags + Schlagwörter + + + Italic Kursiv @@ -5794,7 +5804,7 @@ Bitte gib etwas Speicher frei und drücke OK. Setzt Schriftart auf Codestil - + To An @@ -5809,7 +5819,7 @@ Bitte gib etwas Speicher frei und drücke OK. Bcc - + Recommended Files Empfohlene Dateien @@ -5879,7 +5889,7 @@ Bitte gib etwas Speicher frei und drücke OK. Blockquote hinzufügen - + &Left &Links @@ -5899,13 +5909,13 @@ Bitte gib etwas Speicher frei und drücke OK. &Blocksatz - - + + Save Message Nachricht speichern - + Message has not been Sent. Do you want to save message to draft box? Nachricht wurde noch nicht gesendet. @@ -5918,7 +5928,32 @@ Möchtest Du die Nachricht in den Entwürfen speichern? RetroShare Link einfügen - + + Add to "To" + Zu "An" hinzufügen + + + + Add to "CC" + Zu "Cc" hinzufügen + + + + Add to "BCC" + Zu "Bcc" hinzufügen + + + + Add as Recommend + Als empfohlen hinzufügen + + + + Friend Details + Freund-Details + + + Re: Re: @@ -5944,7 +5979,7 @@ Möchtest Du die Nachricht in den Entwürfen speichern? Bitte geben sie mindestens einen Empfänger ein. - + Unknown Unbekannt @@ -6107,7 +6142,7 @@ Willst Du die Nachricht speichern ? Zusätzliche Datei hinzufügen - + Drop file error. Dateifehler bei Drag'n'Drop. @@ -6123,7 +6158,7 @@ Willst Du die Nachricht speichern ? Datei nicht gefunden oder Dateiname nicht akzeptiert. - + Friend Recommendation(s) Freundempfehlung(en) @@ -6176,7 +6211,7 @@ Willst Du die Nachricht speichern ? Standard - + Edit Tag Schlagwort bearbeiten @@ -6208,7 +6243,7 @@ Willst Du die Nachricht speichern ? MessagesDialog - + New Message Neue Nachricht @@ -6224,14 +6259,14 @@ Willst Du die Nachricht speichern ? - + Date Datum - + From Von @@ -6316,15 +6351,15 @@ p, li { white-space: pre-wrap; } - + Inbox Posteingang - - + + Outbox Postausgang @@ -6336,7 +6371,7 @@ p, li { white-space: pre-wrap; } - + Sent Gesendet @@ -6403,13 +6438,13 @@ p, li { white-space: pre-wrap; } Speichern unter... - + Print Document Dokument drucken - + Subject Betreff @@ -6444,12 +6479,12 @@ p, li { white-space: pre-wrap; } Drucken - + Forward selected Message Gewählte Nachricht weiterleiten - + Remove Messages Löschen @@ -6459,31 +6494,38 @@ p, li { white-space: pre-wrap; } Weiterleiten + Click to sort by attachments - Klicken, um nach Anhang zu sortieren + Klicken, um nach Anhang zu sortieren + Click to sort by subject - Klicken, um nach Betreff zu sortieren + Klicken, um nach Betreff zu sortieren + Click to sort by read - Klicken, um nach Gelesen / Ungelesen zu sortieren + Klicken, um nach Gelesen / Ungelesen zu sortieren + + Click to sort by from - Klicken, um nach Von zu sortieren + Klicken, um nach Von zu sortieren + Click to sort by date - Klicken, um nach Datum zu sortieren + Klicken, um nach Datum zu sortieren + Click to sort by tags - Klicken, um nach Schlagwörter zu sortieren + Klicken, um nach Schlagwörter zu sortieren - + Download Herunterladen @@ -6498,11 +6540,12 @@ p, li { white-space: pre-wrap; } Empfohlene Dateien einblenden + Click to sort by to - Klicken, um nach Empfänger zu sortieren + Klicken, um nach Empfänger zu sortieren - + File Datei @@ -6522,8 +6565,8 @@ p, li { white-space: pre-wrap; } HTML-Dateien (*.htm *.html);;Alle Dateien (*) - - + + Reply to All Allen antworten @@ -6541,7 +6584,7 @@ p, li { white-space: pre-wrap; } - + Content Inhalt @@ -6549,7 +6592,7 @@ p, li { white-space: pre-wrap; } - + Tags Schlagwörter @@ -6560,8 +6603,8 @@ p, li { white-space: pre-wrap; } - - + + Trash Papierkorb @@ -6577,17 +6620,15 @@ p, li { white-space: pre-wrap; } Ordner - Remove All Tags - Alle Schlagwörter entfernen + Alle Schlagwörter entfernen - New tag ... - Neues Schlagwort... + Neues Schlagwort... - + Mark as read Als gelesen markieren @@ -6608,23 +6649,23 @@ p, li { white-space: pre-wrap; } - + Drafts Entwürfe - + To An - + Edit... Editieren... - + @@ -9019,7 +9060,7 @@ Lockdatei: Vielleicht ist das Passwort falsch - + File Request Confirmation Bestätigung der Dateianforderung @@ -9029,7 +9070,7 @@ Lockdatei: Die Datei wurde zur Downloadliste hinzugefügt. - + File Request canceled Dateianforderung abgebrochen @@ -9048,17 +9089,17 @@ Lockdatei: - + Friend Request Confirmation Freundanfrage bestätigen - + The friend is already in your list. Der Freund ist schon in Deiner Liste. - + The friend has been added to your list. Der Freund wurde zu Deiner Liste hinzugefügt. @@ -11490,6 +11531,19 @@ p, li { white-space: pre-wrap; } Später + + TagsMenu + + + Remove All Tags + Alle Schlagwörter entfernen + + + + New tag ... + Neues Schlagwort... + + TextPage