mirror of
https://github.com/RetroShare/RetroShare.git
synced 2026-09-14 11:06:01 +05:00
Merge 1d6811bf7e into f8553d2fd9
This commit is contained in:
commit
cd1e755752
@ -69,6 +69,7 @@
|
||||
#define ROLE_PRIVACYLEVEL Qt::UserRole + 3
|
||||
#define ROLE_AUTOSUBSCRIBE Qt::UserRole + 4
|
||||
#define ROLE_FLAGS Qt::UserRole + 5
|
||||
#define ROLE_BASE_NAME Qt::UserRole + 6 // name without the counters appended for display
|
||||
|
||||
|
||||
#define TYPE_FOLDER 0
|
||||
@ -173,6 +174,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
|
||||
|
||||
privateSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
||||
privateSubLobbyItem->setText(COLUMN_NAME, tr("Private Subscribed"));
|
||||
privateSubLobbyItem->setData(COLUMN_NAME, ROLE_BASE_NAME, tr("Private Subscribed"));
|
||||
privateSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "1");
|
||||
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
|
||||
privateSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
|
||||
@ -180,6 +182,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
|
||||
|
||||
publicSubLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
||||
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed"));
|
||||
publicSubLobbyItem->setData(COLUMN_NAME, ROLE_BASE_NAME, tr("Public Subscribed"));
|
||||
publicSubLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "2");
|
||||
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
|
||||
publicSubLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
|
||||
@ -187,6 +190,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
|
||||
|
||||
privateLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
||||
privateLobbyItem->setText(COLUMN_NAME, tr("Private"));
|
||||
privateLobbyItem->setData(COLUMN_NAME, ROLE_BASE_NAME, tr("Private"));
|
||||
privateLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "3");
|
||||
// privateLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PRIVATE));
|
||||
privateLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PRIVATE);
|
||||
@ -194,6 +198,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
|
||||
|
||||
publicLobbyItem = new RSTreeWidgetItem(compareRole, TYPE_FOLDER);
|
||||
publicLobbyItem->setText(COLUMN_NAME, tr("Public"));
|
||||
publicLobbyItem->setData(COLUMN_NAME, ROLE_BASE_NAME, tr("Public"));
|
||||
publicLobbyItem->setData(COLUMN_NAME, ROLE_SORT, "4");
|
||||
// publicLobbyItem->setIcon(COLUMN_NAME, QIcon(IMAGE_PUBLIC));
|
||||
publicLobbyItem->setData(COLUMN_DATA, ROLE_PRIVACYLEVEL, CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC);
|
||||
@ -291,6 +296,15 @@ UserNotify *ChatLobbyWidget::createUserNotify(QObject *parent)
|
||||
|
||||
void ChatLobbyWidget::updateNotify(ChatLobbyId id, unsigned int count)
|
||||
{
|
||||
// Keep the per room unread count, so that the tree can show it on the room and
|
||||
// on its parent branch. Do this before any early return below.
|
||||
if (count)
|
||||
_unread_counts[id] = count;
|
||||
else
|
||||
_unread_counts.erase(id);
|
||||
|
||||
updateUnreadCounters();
|
||||
|
||||
ChatLobbyDialog *dialog=NULL;
|
||||
dialog=_lobby_infos[id].dialog;
|
||||
if(!dialog) return;
|
||||
@ -307,6 +321,92 @@ void ChatLobbyWidget::updateNotify(ChatLobbyId id, unsigned int count)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Refresh the counters displayed in the room tree.
|
||||
*
|
||||
* Each room shows "[n]" when it holds n unread messages, and each branch shows the
|
||||
* number of rooms it contains "(n)" plus the total of unread messages of its rooms
|
||||
* "[n]". Counters that would be zero are simply omitted, and the item is put in bold
|
||||
* when it has unread messages, so that a collapsed branch still tells that something
|
||||
* is waiting inside.
|
||||
*/
|
||||
/*!
|
||||
* \brief Put an item of the room tree in bold, or back to normal.
|
||||
*
|
||||
* The tree itself carries the font size taken from the settings (see FontSizeHandler),
|
||||
* but QTreeWidgetItem::font() returns a default constructed font when the item has no
|
||||
* Qt::FontRole yet, and RSElidedItemDelegate paints the item with the model font as is,
|
||||
* without merging it into the font of the view. Deriving the bold font from the item
|
||||
* would therefore shrink the whole list down to the application font. So derive it from
|
||||
* the tree, and remove the role altogether when the item is not bold, so that it keeps
|
||||
* following the font size of the settings.
|
||||
*/
|
||||
static void setItemBold(QTreeWidget *treeWidget, QTreeWidgetItem *item, bool bold)
|
||||
{
|
||||
if(bold)
|
||||
{
|
||||
QFont font = treeWidget->font();
|
||||
font.setBold(true);
|
||||
item->setFont(COLUMN_NAME, font);
|
||||
}
|
||||
else
|
||||
item->setData(COLUMN_NAME, Qt::FontRole, QVariant());
|
||||
}
|
||||
|
||||
void ChatLobbyWidget::updateUnreadCounters()
|
||||
{
|
||||
QTreeWidgetItem *branches[4] = { privateSubLobbyItem, publicSubLobbyItem, privateLobbyItem, publicLobbyItem };
|
||||
|
||||
for(int b=0; b<4; ++b)
|
||||
{
|
||||
QTreeWidgetItem *branch = branches[b];
|
||||
|
||||
if(branch == NULL)
|
||||
continue;
|
||||
|
||||
unsigned int branch_unread = 0;
|
||||
int room_count = 0;
|
||||
|
||||
for(int c=0; c<branch->childCount(); ++c)
|
||||
{
|
||||
QTreeWidgetItem *item = branch->child(c);
|
||||
|
||||
if(item->type() != TYPE_LOBBY)
|
||||
continue;
|
||||
|
||||
++room_count;
|
||||
|
||||
ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
|
||||
std::map<ChatLobbyId,unsigned int>::const_iterator it = _unread_counts.find(id);
|
||||
unsigned int unread = (it == _unread_counts.end()) ? 0 : it->second;
|
||||
|
||||
branch_unread += unread;
|
||||
|
||||
QString name = item->data(COLUMN_NAME, ROLE_BASE_NAME).toString();
|
||||
|
||||
if(name.isEmpty()) // item not filled by updateItem() yet
|
||||
continue;
|
||||
|
||||
item->setText(COLUMN_NAME, unread ? QString("%1 [%2]").arg(name).arg(unread) : name);
|
||||
|
||||
setItemBold(ui.lobbyTreeWidget, item, unread > 0);
|
||||
}
|
||||
|
||||
QString label = branch->data(COLUMN_NAME, ROLE_BASE_NAME).toString();
|
||||
|
||||
if(room_count > 0)
|
||||
label += QString(" (%1)").arg(room_count);
|
||||
|
||||
if(branch_unread > 0)
|
||||
label += QString(" [%1]").arg(branch_unread);
|
||||
|
||||
branch->setText(COLUMN_NAME, label);
|
||||
branch->setToolTip(COLUMN_NAME, branch_unread ? tr("%n unread message(s)", "", branch_unread) : QString());
|
||||
|
||||
setItemBold(ui.lobbyTreeWidget, branch, branch_unread > 0);
|
||||
}
|
||||
}
|
||||
|
||||
static bool trimAnonIds(std::list<RsGxsId>& lst)
|
||||
{
|
||||
// trim down identities that are unsigned, because the lobby requires it.
|
||||
@ -418,6 +518,9 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
|
||||
{
|
||||
item->setText(COLUMN_NAME, QString::fromUtf8(name.c_str()));
|
||||
item->setData(COLUMN_NAME, ROLE_SORT, QString::fromUtf8(name.c_str()));
|
||||
// Keep the bare name aside: the displayed text gets an unread counter appended by
|
||||
// ChatLobbyWidget::updateUnreadCounters(), which needs to rebuild it from scratch.
|
||||
item->setData(COLUMN_NAME, ROLE_BASE_NAME, QString::fromUtf8(name.c_str()));
|
||||
|
||||
if(topic.empty())
|
||||
{
|
||||
@ -760,9 +863,10 @@ void ChatLobbyWidget::updateDisplay()
|
||||
}
|
||||
}
|
||||
publicSubLobbyItem->setHidden(publicSubLobbyItem->childCount()==0);
|
||||
publicSubLobbyItem->setText(COLUMN_NAME, tr("Public Subscribed")+ QString(" (") + QString::number(publicSubLobbyItem->childCount())+QString(")"));
|
||||
privateSubLobbyItem->setHidden(privateSubLobbyItem->childCount()==0);
|
||||
publicLobbyItem->setText(COLUMN_NAME, tr("Public")+ " (" + QString::number(publicLobbyItem->childCount())+QString(")"));
|
||||
|
||||
// re-append the counters, since updateItem() above has reset the room names
|
||||
updateUnreadCounters();
|
||||
}
|
||||
|
||||
void ChatLobbyWidget::createChatLobby()
|
||||
@ -1002,7 +1106,7 @@ void ChatLobbyWidget::copyItemLink()
|
||||
}
|
||||
|
||||
ChatLobbyId id = item->data(COLUMN_DATA, ROLE_ID).toULongLong();
|
||||
QString name = item->text(COLUMN_NAME);
|
||||
QString name = item->data(COLUMN_NAME, ROLE_BASE_NAME).toString(); // without the unread counter
|
||||
|
||||
RetroShareLink link = RetroShareLink::createChatRoom(ChatId(id),name);
|
||||
if (link.valid()) {
|
||||
|
||||
@ -121,6 +121,8 @@ private:
|
||||
|
||||
bool filterItem(QTreeWidgetItem *item, const QString &text, int filterColumn);
|
||||
|
||||
void updateUnreadCounters();
|
||||
|
||||
RSTreeWidgetItemCompareRole *compareRole;
|
||||
QTreeWidgetItem *privateLobbyItem;
|
||||
QTreeWidgetItem *publicLobbyItem;
|
||||
@ -132,6 +134,8 @@ private:
|
||||
|
||||
std::map<ChatLobbyId,ChatLobbyInfoStruct> _lobby_infos ;
|
||||
|
||||
std::map<ChatLobbyId,unsigned int> _unread_counts ; // unread messages per room, for the tree counters
|
||||
|
||||
std::map<QTreeWidgetItem*,time_t> _icon_changed_map ;
|
||||
|
||||
bool m_bProcessSettings;
|
||||
|
||||
@ -28,6 +28,16 @@
|
||||
|
||||
#include "gui/ChatLobbyWidget.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
// Set to 1 to trace chat unread-count bookkeeping to stderr (development diagnostics).
|
||||
#define DEBUG_CHAT_UNREAD_COUNT 0
|
||||
#if DEBUG_CHAT_UNREAD_COUNT
|
||||
# define CHATCOUNT_DBG RsDbg()
|
||||
#else
|
||||
# define CHATCOUNT_DBG while(false) RsDbg()
|
||||
#endif
|
||||
|
||||
#include "gui/SoundManager.h"
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
#include "util/DateTime.h"
|
||||
@ -140,7 +150,7 @@ QString ChatLobbyUserNotify::getTrayMessage(bool plural)
|
||||
|
||||
QString ChatLobbyUserNotify::getNotifyMessage(bool plural)
|
||||
{
|
||||
return plural ? tr("%1 mentions") : tr("%1 mention");
|
||||
return plural ? tr("%1 messages") : tr("%1 message");
|
||||
}
|
||||
|
||||
void ChatLobbyUserNotify::iconClicked()
|
||||
@ -303,12 +313,13 @@ void ChatLobbyUserNotify::chatLobbyNewMessage(ChatLobbyId lobby_id, QDateTime ti
|
||||
}
|
||||
|
||||
if ((bGetNickName || bFoundTextToNotify || _bCountUnRead)){
|
||||
QString strAnchor = DateTime::formatDateTime(time);
|
||||
QString strAnchor = DateTime::formatDate(time.date()) + " " + time.time().toString("HH:mm:ss");
|
||||
MsgData msgData;
|
||||
msgData.text=RsHtml::plainText(senderName) + ": " + msg;
|
||||
msgData.unread=!(bGetNickName || bFoundTextToNotify);
|
||||
|
||||
_listMsg[lobby_id][strAnchor]=msgData;
|
||||
CHATCOUNT_DBG << "CHATCOUNT: Incrementing count for lobby=" << lobby_id << " author='" << senderName.toStdString() << "' anchor='" << strAnchor.toStdString() << "' count=" << _listMsg[lobby_id].size() << std::endl;
|
||||
emit countChanged(lobby_id, _listMsg[lobby_id].size());
|
||||
updateIcon();
|
||||
SoundManager::play(SOUND_NEW_LOBBY_MESSAGE);
|
||||
@ -339,13 +350,23 @@ void ChatLobbyUserNotify::chatLobbyCleared(ChatLobbyId lobby_id, QString anchor,
|
||||
lobby_map::iterator itCL=_listMsg.find(lobby_id);
|
||||
if (itCL!=_listMsg.end()) {
|
||||
if (!anchor.isEmpty()) {
|
||||
CHATCOUNT_DBG << "CHATCOUNT: Received clear request for anchor='" << anchor.toStdString() << "' from lobby=" << lobby_id << std::endl;
|
||||
msg_map::iterator itMsg=itCL->second.find(anchor);
|
||||
if (itMsg!=itCL->second.end()) {
|
||||
MsgData msgData = itMsg->second;
|
||||
if(!onlyUnread || msgData.unread) {
|
||||
itCL->second.erase(itMsg);
|
||||
CHATCOUNT_DBG << "CHATCOUNT: Successfully erased anchor from map. New count=" << itCL->second.size() << std::endl;
|
||||
changed=true;
|
||||
}
|
||||
} else {
|
||||
// Help debug non-cleared messages by revealing that the search key did not match stored keys.
|
||||
// We skip printing for non-date anchors like "PERSONID:" to avoid spam.
|
||||
if (!anchor.startsWith("PERSONID:")) {
|
||||
CHATCOUNT_DBG << "CHATCOUNT: Failed to find anchor='" << anchor.toStdString() << "' in list. List keys: ";
|
||||
for(auto const& item : itCL->second) CHATCOUNT_DBG << "'" << item.first.toStdString() << "', ";
|
||||
CHATCOUNT_DBG << std::endl;
|
||||
}
|
||||
}
|
||||
count = itCL->second.size();
|
||||
}
|
||||
|
||||
@ -375,7 +375,7 @@ QString ChatStyle::formatMessage(enumFormatMessage type
|
||||
|
||||
QString strName = RsHtml::plainText(name).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
|
||||
QString strDate = DateTime::formatDate(timestamp.date()).prepend(QString("<a name=\"date\">")).append(QString("</a>"));
|
||||
QString strTime = DateTime::formatTime(timestamp.time()).prepend(QString("<a name=\"time\">")).append(QString("</a>"));
|
||||
QString strTime = timestamp.time().toString("HH:mm:ss").prepend(QString("<a name=\"time\">")).append(QString("</a>"));
|
||||
|
||||
int bi = name.lastIndexOf(QRegularExpression(" \\(.*\\)")); //trim location from the end
|
||||
QString strShortName = RsHtml::plainText(name.left(bi)).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
|
||||
|
||||
@ -38,6 +38,16 @@
|
||||
#include "util/HandleRichText.h"
|
||||
#include "gui/chat/ChatUserNotify.h"//For BradCast
|
||||
#include "util/DateTime.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
// Set to 1 to trace chat unread-count bookkeeping to stderr (development diagnostics).
|
||||
#define DEBUG_CHAT_UNREAD_COUNT 0
|
||||
#if DEBUG_CHAT_UNREAD_COUNT
|
||||
# define CHATCOUNT_DBG RsDbg()
|
||||
#else
|
||||
# define CHATCOUNT_DBG while(false) RsDbg()
|
||||
#endif
|
||||
|
||||
#include "util/imageutil.h"
|
||||
#include "util/qtthreadsutils.h"
|
||||
#include "gui/im_history/ImHistoryBrowser.h"
|
||||
@ -57,7 +67,11 @@
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
#include <QStringListModel>
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QTextCodec>
|
||||
#include <QTextDocument>
|
||||
#include <QTextBlock>
|
||||
#include <QTextFragment>
|
||||
#include <QTextDocumentFragment>
|
||||
#include <QTextStream>
|
||||
#include <QTimer>
|
||||
@ -158,6 +172,7 @@ ChatWidget::ChatWidget(QWidget *parent)
|
||||
connect(ui->attachPictureButton, SIGNAL(clicked()), this, SLOT(addExtraPicture()));
|
||||
connect(ui->addFileButton, SIGNAL(clicked()), this , SLOT(addExtraFile()));
|
||||
connect(ui->sendButton, SIGNAL(clicked()), this, SLOT(sendChat()));
|
||||
connect(ui->textBrowser->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(checkVisibleAnchors()), Qt::QueuedConnection);
|
||||
|
||||
connect(ui->actionSaveChatHistory, SIGNAL(triggered()), this, SLOT(fileSaveAs()));
|
||||
connect(ui->actionClearChatHistory, SIGNAL(triggered()), this, SLOT(clearChatHistory()));
|
||||
@ -578,39 +593,6 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
if (notify && chatType() == CHATTYPE_LOBBY) {
|
||||
if ((event->type() == QEvent::KeyPress)
|
||||
|| (event->type() == QEvent::MouseMove)
|
||||
|| (event->type() == QEvent::Enter)
|
||||
|| (event->type() == QEvent::Leave)
|
||||
|| (event->type() == QEvent::Wheel)
|
||||
|| (event->type() == QEvent::ToolTip) ) {
|
||||
|
||||
QTextCursor cursor = ui->textBrowser->cursorForPosition(QPoint(0, 0));
|
||||
QPoint bottom_right(ui->textBrowser->viewport()->width() - 1, ui->textBrowser->viewport()->height() - 1);
|
||||
int end_pos = ui->textBrowser->cursorForPosition(bottom_right).position();
|
||||
cursor.setPosition(end_pos, QTextCursor::KeepAnchor);
|
||||
if ((cursor.position() != lastUpdateCursorPos || cursor.selectionEnd() != lastUpdateCursorEnd) &&
|
||||
!cursor.selectedText().isEmpty()) {
|
||||
lastUpdateCursorPos = cursor.position();
|
||||
lastUpdateCursorEnd = cursor.selectionEnd();
|
||||
QRegExp rx("<a name=\"(.*)\"",Qt::CaseSensitive, QRegExp::RegExp2);
|
||||
rx.setMinimal(true);
|
||||
QString sel=cursor.selection().toHtml();
|
||||
QStringList anchors;
|
||||
int pos=0;
|
||||
while ((pos = rx.indexIn(sel,pos)) != -1) {
|
||||
anchors << rx.cap(1);
|
||||
pos += rx.matchedLength();
|
||||
}
|
||||
if (!anchors.isEmpty()){
|
||||
for (QStringList::iterator it=anchors.begin();it!=anchors.end();++it) {
|
||||
notify->chatLobbyCleared(chatId.toLobbyId(), *it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj == ui->textBrowser) {
|
||||
@ -793,6 +775,73 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
return QWidget::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the unread status of the messages currently displayed.
|
||||
*
|
||||
* Each message carries an anchor holding its timestamp. The blocks of the document
|
||||
* are walked and their geometry compared to the viewport, so that only the messages
|
||||
* really shown to the user are reported as read. Called on scroll, show and resize.
|
||||
*/
|
||||
void ChatWidget::checkVisibleAnchors()
|
||||
{
|
||||
CHATCOUNT_DBG << "CHATCOUNT: check requested, active=" << isActive() << " scroll=" << ui->textBrowser->verticalScrollBar()->value() << std::endl;
|
||||
if (notify && chatType() == CHATTYPE_LOBBY && isActive()) {
|
||||
QTextDocument *doc = ui->textBrowser->document();
|
||||
if (!doc || doc->isEmpty()) return;
|
||||
|
||||
// The layout may not be computed yet, in which case every block reports a null
|
||||
// geometry and would look visible. Give up and wait for the next call.
|
||||
qreal totalH = doc->documentLayout()->documentSize().height();
|
||||
if (totalH <= 0) return;
|
||||
|
||||
int viewH = ui->textBrowser->viewport()->height();
|
||||
int vScroll = ui->textBrowser->verticalScrollBar()->value();
|
||||
QStringList visibleAnchors;
|
||||
|
||||
QRegExp rx("<a name=\"(.*)\"", Qt::CaseSensitive, QRegExp::RegExp2);
|
||||
rx.setMinimal(true);
|
||||
|
||||
for (QTextBlock block = doc->begin(); block.isValid(); block = block.next()) {
|
||||
QRectF blockRect = doc->documentLayout()->blockBoundingRect(block);
|
||||
|
||||
// document coordinates -> viewport coordinates
|
||||
qreal vTop = blockRect.top() - vScroll;
|
||||
qreal vBottom = blockRect.bottom() - vScroll;
|
||||
|
||||
if (vTop > viewH) {
|
||||
break; // below the viewport: the next blocks are lower, stop here
|
||||
}
|
||||
|
||||
if (vBottom < 0) {
|
||||
continue; // above the viewport
|
||||
}
|
||||
|
||||
// visible block: collect the anchors it contains
|
||||
QTextCursor bCursor(block);
|
||||
bCursor.select(QTextCursor::BlockUnderCursor);
|
||||
QString blockHtml = bCursor.selection().toHtml();
|
||||
|
||||
int pos = 0;
|
||||
while ((pos = rx.indexIn(blockHtml, pos)) != -1) {
|
||||
QString name = rx.cap(1);
|
||||
if (!name.isEmpty()) {
|
||||
visibleAnchors << name;
|
||||
}
|
||||
pos += rx.matchedLength();
|
||||
}
|
||||
}
|
||||
|
||||
visibleAnchors.removeDuplicates();
|
||||
|
||||
if (!visibleAnchors.isEmpty()){
|
||||
CHATCOUNT_DBG << "CHATCOUNT: " << visibleAnchors.size() << " anchors visible in the viewport" << std::endl;
|
||||
for (const QString &anchor : visibleAnchors) {
|
||||
notify->chatLobbyCleared(chatId.toLobbyId(), anchor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Utility function for completeNickname.
|
||||
*/
|
||||
@ -964,6 +1013,7 @@ void ChatWidget::showEvent(QShowEvent */*event*/)
|
||||
QScrollBar *scrollbar2 = ui->textBrowser->verticalScrollBar();
|
||||
scrollbar2->setValue(scrollbar2->maximum());
|
||||
}
|
||||
QTimer::singleShot(0, this, SLOT(checkVisibleAnchors()));
|
||||
}
|
||||
|
||||
void ChatWidget::resizeEvent(QResizeEvent */*event*/)
|
||||
@ -976,6 +1026,7 @@ void ChatWidget::resizeEvent(QResizeEvent */*event*/)
|
||||
// Workaround: now the scroll position is correct calculated
|
||||
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
|
||||
scrollbar->setValue(scrollbar->maximum());
|
||||
QTimer::singleShot(0, this, SLOT(checkVisibleAnchors()));
|
||||
}
|
||||
|
||||
void ChatWidget::addToParent(QWidget *newParent)
|
||||
@ -1105,7 +1156,7 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const RsGxsId gx
|
||||
QString formattedMessage = RsHtml().formatText(ui->textBrowser->document(), message, formatTextFlag, backgroundColor, desiredContrast, desiredMinimumFontSize);
|
||||
QDateTime dtTimestamp=incoming ? sendTime : recvTime;
|
||||
QString formatMsg = chatStyle.formatMessage(type, name, dtTimestamp, formattedMessage, formatFlag, backgroundColor);
|
||||
QString timeStamp = DateTime::formatDateTime(dtTimestamp);
|
||||
QString timeStamp = DateTime::formatDate(dtTimestamp.date()) + " " + dtTimestamp.time().toString("HH:mm:ss");
|
||||
|
||||
//replace Date and Time anchors
|
||||
formatMsg.replace(QString("<a name=\"date\">"),QString("<a name=\"%1\">").arg(timeStamp));
|
||||
|
||||
@ -209,6 +209,7 @@ private slots:
|
||||
void quote();
|
||||
void dropPlacemark();
|
||||
void saveSticker();
|
||||
void checkVisibleAnchors();
|
||||
|
||||
private:
|
||||
bool findText(const QString& qsStringToFind);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user