show user coming and leaving
diff --git a/chatbuf.proto b/chatbuf.proto
index c8e4d35..6ea6ea4 100644
--- a/chatbuf.proto
+++ b/chatbuf.proto
@@ -7,7 +7,8 @@
CHAT = 0;
HELLO = 1;
LEAVE = 2;
- OTHER = 3;
+ JOIN = 3;
+ OTHER = 4;
}
required ChatMessageType type = 3 [default = CHAT];
optional string data = 4;
diff --git a/chatdialog.cpp b/chatdialog.cpp
index 4a6ae3f..0570985 100644
--- a/chatdialog.cpp
+++ b/chatdialog.cpp
@@ -14,7 +14,7 @@
static const int HELLO_INTERVAL = 90; // seconds
ChatDialog::ChatDialog(QWidget *parent)
- : QDialog(parent), m_sock(NULL), m_lastMsgTime(0), m_sendJoin(true)
+ : QDialog(parent), m_sock(NULL), m_lastMsgTime(0)
{
// have to register this, otherwise
// the signal-slot system won't recognize this type
@@ -53,12 +53,12 @@
connect(treeButton, SIGNAL(pressed()), this, SLOT(treeButtonPressed()));
connect(this, SIGNAL(dataReceived(QString, const char *, size_t, bool)), this, SLOT(processData(QString, const char *, size_t, bool)));
connect(this, SIGNAL(treeUpdated(const std::vector<Sync::MissingDataInfo>)), this, SLOT(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
- connect(this, SIGNAL(removeReceived(QString)), this, SLOT(processRemove(QString)));
+ //connect(this, SIGNAL(removeReceived(QString)), this, SLOT(processRemove(QString)));
connect(m_timer, SIGNAL(timeout()), this, SLOT(replot()));
connect(m_scene, SIGNAL(replot()), this, SLOT(replot()));
connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(showNormal()));
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
- connect(m_scene, SIGNAL(rosterChanged()), this, SLOT(updateRosterList()));
+ connect(m_scene, SIGNAL(rosterChanged(QStringList)), this, SLOT(updateRosterList(QStringList)));
// create sync socket
if(!m_user.getChatroom().isEmpty()) {
@@ -68,7 +68,7 @@
try
{
m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2), bind(&ChatDialog::processRemoveWrapper, this, _1));
- sendHello();
+ sendJoin();
m_timer->start(FRESHNESS * 2000);
}
catch (Sync::CcnxOperationException ex)
@@ -85,7 +85,16 @@
{
if (m_sock != NULL)
{
+ SyncDemo::ChatMessage msg;
+ formHelloMessage(msg);
+ msg.set_type(SyncDemo::ChatMessage::LEAVE);
+ sendMsg(msg);
+ usleep(100000);
m_sock->remove(m_user.getPrefix().toStdString());
+ usleep(100000);
+#ifdef __DEBUG
+ std::cout << "Sync REMOVE signal sent" << std::endl;
+#endif
delete m_sock;
m_sock = NULL;
}
@@ -99,11 +108,21 @@
}
void
-ChatDialog::updateRosterList()
+ChatDialog::updateRosterList(QStringList staleUserList)
{
boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
QStringList rosterList = m_scene->getRosterList();
m_rosterModel->setStringList(rosterList);
+ QString user;
+ QStringListIterator it(staleUserList);
+ while(it.hasNext())
+ {
+ SyncDemo::ChatMessage msg;
+ formHelloMessage(msg);
+ msg.set_type(SyncDemo::ChatMessage::LEAVE);
+ msg.set_from(it.next().toStdString());
+ appendMessage(msg);
+ }
}
void
@@ -151,77 +170,133 @@
{
boost::recursive_mutex::scoped_lock lock(m_msgMutex);
- if (msg.type() != SyncDemo::ChatMessage::CHAT) {
- return;
- }
-
- if (!msg.has_data()) {
- return;
- }
-
- if (msg.from().empty() || msg.data().empty()) {
- return;
- }
-
- if (!msg.has_timestamp())
+ if (msg.type() == SyncDemo::ChatMessage::CHAT)
{
- return;
- }
-#ifdef __DEBUG
- std::cout << "Displaying msg from: " << msg.from() << ", data is: " << msg.data() << std::endl;
-#endif
- QTextCharFormat nickFormat;
- nickFormat.setForeground(Qt::darkGreen);
- nickFormat.setFontWeight(QFont::Bold);
- nickFormat.setFontUnderline(true);
- nickFormat.setUnderlineColor(Qt::gray);
- QTextCharFormat timeFormat;
- timeFormat.setForeground(Qt::gray);
- timeFormat.setFontUnderline(true);
- timeFormat.setUnderlineColor(Qt::gray);
-
- QTextCursor cursor(textEdit->textCursor());
- cursor.movePosition(QTextCursor::End);
- QTextTableFormat tableFormat;
- tableFormat.setBorder(0);
- QTextTable *table = cursor.insertTable(1, 2, tableFormat);
- QString from = QString("%1 ").arg(msg.from().c_str());
- QTextTableCell fromCell = table->cellAt(0, 0);
- fromCell.setFormat(nickFormat);
- fromCell.firstCursorPosition().insertText(from);
- QTextTableCell timeCell = table->cellAt(0, 1);
- timeCell.setFormat(timeFormat);
- time_t timestamp = msg.timestamp();
- struct tm *tm_time = localtime(×tamp);
- int hour = tm_time->tm_hour;
- QString amOrPM;
- if (hour > 12)
- {
- hour -= 12;
- amOrPM = "PM";
- }
- else
- {
- amOrPM = "AM";
- if (hour == 0)
+ if (!msg.has_data())
{
- hour = 12;
+ return;
}
+
+ if (msg.from().empty() || msg.data().empty())
+ {
+ return;
+ }
+
+ if (!msg.has_timestamp())
+ {
+ return;
+ }
+
+ QTextCharFormat nickFormat;
+ nickFormat.setForeground(Qt::darkGreen);
+ nickFormat.setFontWeight(QFont::Bold);
+ nickFormat.setFontUnderline(true);
+ nickFormat.setUnderlineColor(Qt::gray);
+ QTextCharFormat timeFormat;
+ timeFormat.setForeground(Qt::gray);
+ timeFormat.setFontUnderline(true);
+ timeFormat.setUnderlineColor(Qt::gray);
+
+ QTextCursor cursor(textEdit->textCursor());
+ cursor.movePosition(QTextCursor::End);
+ QTextTableFormat tableFormat;
+ tableFormat.setBorder(0);
+ QTextTable *table = cursor.insertTable(1, 2, tableFormat);
+ QString from = QString("%1 ").arg(msg.from().c_str());
+ QTextTableCell fromCell = table->cellAt(0, 0);
+ fromCell.setFormat(nickFormat);
+ fromCell.firstCursorPosition().insertText(from);
+ QTextTableCell timeCell = table->cellAt(0, 1);
+ timeCell.setFormat(timeFormat);
+ time_t timestamp = msg.timestamp();
+ struct tm *tm_time = localtime(×tamp);
+ int hour = tm_time->tm_hour;
+ QString amOrPM;
+ if (hour > 12)
+ {
+ hour -= 12;
+ amOrPM = "PM";
+ }
+ else
+ {
+ amOrPM = "AM";
+ if (hour == 0)
+ {
+ hour = 12;
+ }
+ }
+
+ char textTime[12];
+ sprintf(textTime, "%d:%02d:%02d %s", hour, tm_time->tm_min, tm_time->tm_sec, amOrPM.toStdString().c_str());
+ timeCell.firstCursorPosition().insertText(textTime);
+
+
+ QTextCursor nextCursor(textEdit->textCursor());
+ nextCursor.movePosition(QTextCursor::End);
+ table = nextCursor.insertTable(1, 1, tableFormat);
+ table->cellAt(0, 0).firstCursorPosition().insertText(msg.data().c_str());
+ showMessage(from, msg.data().c_str());
}
- char textTime[12];
- sprintf(textTime, "%d:%02d:%02d %s", hour, tm_time->tm_min, tm_time->tm_sec, amOrPM.toStdString().c_str());
- timeCell.firstCursorPosition().insertText(textTime);
+ if (msg.type() == SyncDemo::ChatMessage::JOIN || msg.type() == SyncDemo::ChatMessage::LEAVE)
+ {
+ QTextCharFormat nickFormat;
+ nickFormat.setForeground(Qt::gray);
+ nickFormat.setFontWeight(QFont::Bold);
+ nickFormat.setFontUnderline(true);
+ nickFormat.setUnderlineColor(Qt::gray);
+ QTextCharFormat timeFormat;
+ timeFormat.setForeground(Qt::gray);
+ timeFormat.setFontUnderline(true);
+ timeFormat.setUnderlineColor(Qt::gray);
-
- QTextCursor nextCursor(textEdit->textCursor());
- nextCursor.movePosition(QTextCursor::End);
- table = nextCursor.insertTable(1, 1, tableFormat);
- table->cellAt(0, 0).firstCursorPosition().insertText(msg.data().c_str());
+ QTextCursor cursor(textEdit->textCursor());
+ cursor.movePosition(QTextCursor::End);
+ QTextTableFormat tableFormat;
+ tableFormat.setBorder(0);
+ QTextTable *table = cursor.insertTable(1, 2, tableFormat);
+ QString action;
+ if (msg.type() == SyncDemo::ChatMessage::JOIN)
+ {
+ action = "enters room";
+ }
+ else
+ {
+ action = "leaves room";
+ }
+
+ QString from = QString("%1 %2 ").arg(msg.from().c_str()).arg(action);
+ QTextTableCell fromCell = table->cellAt(0, 0);
+ fromCell.setFormat(nickFormat);
+ fromCell.firstCursorPosition().insertText(from);
+ QTextTableCell timeCell = table->cellAt(0, 1);
+ timeCell.setFormat(timeFormat);
+ time_t timestamp = msg.timestamp();
+ struct tm *tm_time = localtime(×tamp);
+ int hour = tm_time->tm_hour;
+ QString amOrPM;
+ if (hour > 12)
+ {
+ hour -= 12;
+ amOrPM = "PM";
+ }
+ else
+ {
+ amOrPM = "AM";
+ if (hour == 0)
+ {
+ hour = 12;
+ }
+ }
+
+ char textTime[12];
+ sprintf(textTime, "%d:%02d:%02d %s", hour, tm_time->tm_min, tm_time->tm_sec, amOrPM.toStdString().c_str());
+ timeCell.firstCursorPosition().insertText(textTime);
+ }
+
QScrollBar *bar = textEdit->verticalScrollBar();
bar->setValue(bar->maximum());
- showMessage(from, msg.data().c_str());
}
void
@@ -321,6 +396,11 @@
#ifdef __DEBUG
std::cout <<"<<< updating scene for" << prefix << ": " << msg.from() << std::endl;
#endif
+ if (msg.type() == SyncDemo::ChatMessage::LEAVE)
+ {
+ processRemove(prefix.c_str());
+ }
+ else
{
boost::recursive_mutex::scoped_lock lock(m_sceneMutex);
m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
@@ -331,7 +411,10 @@
void
ChatDialog::processRemoveWrapper(std::string prefix)
{
- emit removeReceived(prefix.c_str());
+#ifdef __DEBUG
+ std::cout << "Sync REMOVE signal received for prefix: " << prefix << std::endl;
+#endif
+ //emit removeReceived(prefix.c_str());
}
void
@@ -478,16 +561,25 @@
}
void
+ChatDialog::sendJoin()
+{
+ SyncDemo::ChatMessage msg;
+ formHelloMessage(msg);
+ msg.set_type(SyncDemo::ChatMessage::JOIN);
+ sendMsg(msg);
+ QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
+}
+
+void
ChatDialog::sendHello()
{
time_t now = time(NULL);
int elapsed = now - m_lastMsgTime;
- if (elapsed >= m_randomizedInterval / 1000 || m_sendJoin)
+ if (elapsed >= m_randomizedInterval / 1000)
{
SyncDemo::ChatMessage msg;
formHelloMessage(msg);
sendMsg(msg);
- m_sendJoin = false;
QTimer::singleShot(m_randomizedInterval, this, SLOT(sendHello()));
}
else
@@ -517,6 +609,8 @@
treeViewer->show();
treeButton->setText("Hide Sync Tree");
}
+
+ fitView();
}
void
@@ -574,8 +668,7 @@
try
{
m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2), bind(&ChatDialog::processRemoveWrapper, this, _1));
- m_sendJoin = true;
- sendHello();
+ sendJoin();
m_timer->start(FRESHNESS * 2000);
}
catch (Sync::CcnxOperationException ex)
diff --git a/chatdialog.h b/chatdialog.h
index b604b02..60e7c4b 100644
--- a/chatdialog.h
+++ b/chatdialog.h
@@ -63,8 +63,9 @@
void checkSetting();
void settingUpdated(QString, QString, QString);
void sendHello();
+ void sendJoin();
void replot();
- void updateRosterList();
+ void updateRosterList(QStringList);
// icon related
void iconActivated(QSystemTrayIcon::ActivationReason reason);
@@ -87,7 +88,6 @@
int m_randomizedInterval;
QTimer *m_timer;
QStringListModel *m_rosterModel;
- bool m_sendJoin;
// icon related
QAction *minimizeAction;
diff --git a/digesttreescene.cpp b/digesttreescene.cpp
index 5364f0f..79f5fe6 100644
--- a/digesttreescene.cpp
+++ b/digesttreescene.cpp
@@ -91,9 +91,6 @@
void
DigestTreeScene::msgReceived(QString prefix, QString nick)
{
-#ifdef __DEBUG
- std::cout << "Finding " << prefix.toStdString() << std::endl;
-#endif
Roster_iterator it = m_roster.find(prefix);
if (it != m_roster.end())
{
@@ -107,7 +104,7 @@
QRectF rectBR = nickRectItem->boundingRect();
QRectF nickBR = nickItem->boundingRect();
nickItem->setPos(rectBR.x() + (rectBR.width() - nickBR.width())/2, rectBR.y() + 5);
- emit rosterChanged();
+ emit rosterChanged(QStringList());
}
reDrawNode(p, Qt::red);
@@ -119,18 +116,6 @@
previouslyUpdatedUser = p;
}
-#ifdef __DEBUG
- else
- {
- std::cout << "Couldn't find prefix, " << prefix.toStdString() << ": let's check"<< std::endl;
- Roster_iterator ii = m_roster.begin();
- while (ii != m_roster.end())
- {
- std::cout <<"Prefix: " << ii.key().toStdString() << std::endl;
- ++ii;
- }
- }
-#endif
}
void
@@ -164,6 +149,7 @@
// do some cleaning, get rid of stale member info
Roster_iterator it = m_roster.begin();
+ QStringList staleUserList;
while (it != m_roster.end())
{
DisplayUserPtr p = it.value();
@@ -176,6 +162,7 @@
std::cout << "Removing user: " << p->getNick().toStdString() << std::endl;
std::cout << "now - last = " << now - p->getReceived() << std::endl;
#endif
+ staleUserList << p->getNick();
p = DisplayUserNullPtr;
it = m_roster.erase(it);
}
@@ -191,7 +178,7 @@
}
// for simpicity here, whenever we replot, we also redo the roster list
- emit rosterChanged();
+ emit rosterChanged(staleUserList);
int n = m_roster.size();
std::vector<TreeLayout::Coordinate> childNodesCo(n);
diff --git a/digesttreescene.h b/digesttreescene.h
index 0e2e0f7..33a4973 100644
--- a/digesttreescene.h
+++ b/digesttreescene.h
@@ -39,7 +39,7 @@
signals:
void replot();
- void rosterChanged();
+ void rosterChanged(QStringList);
private slots:
void emitReplot();