blob: 57de04e7540f3ba9351b3cfd873835b89b82737d [file] [log] [blame]
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -07001#include <QtGui>
2#include "chatdialog.h"
Zhenkai Zhu85845d22012-06-01 23:10:43 -07003#include "settingdialog.h"
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -07004#include <ctime>
Zhenkai Zhub6338822012-05-31 13:27:24 -07005#include <iostream>
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -07006#include <QTimer>
Zhenkai Zhu10ccb5a2012-06-04 21:55:14 -07007#include <QMetaType>
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -07008#include <QMessageBox>
Zhenkai Zhu59245aa2012-09-26 16:07:04 -07009#include <boost/random/random_device.hpp>
10#include <boost/random/uniform_int_distribution.hpp>
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070011
Zhenkai Zhu82a62752012-06-04 17:11:04 -070012#define BROADCAST_PREFIX_FOR_SYNC_DEMO "/ndn/broadcast/sync-demo"
13
Zhenkai Zhu21d75f92012-06-04 21:23:34 -070014void
15ChatDialog::testDraw()
16{
17 std::string prefix[5] = {"/ndn/1", "/ndn/2", "/ndn/3", "/ndn/4", "/ndn/5"};
18 std::string nick[5] = {"tom", "jerry", "jason", "michael", "hurry"};
19 std::vector<Sync::MissingDataInfo> v;
20 for (int i = 0; i < 5; i++)
21 {
22 Sync::MissingDataInfo mdi = {prefix[i], Sync::SeqNo(0), Sync::SeqNo(i * (2 << i) )};
23 v.push_back(mdi);
24 }
25
26 m_scene->processUpdate(v, "12341234@!#%!@");
27
28 for (int i = 0; i < 5; i++)
29 {
30 m_scene-> msgReceived(prefix[i].c_str(), nick[i].c_str());
31 }
32
33 fitView();
34}
35
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070036ChatDialog::ChatDialog(QWidget *parent)
Zhenkai Zhu82a62752012-06-04 17:11:04 -070037 : QDialog(parent), m_sock(NULL)
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070038{
Zhenkai Zhu10ccb5a2012-06-04 21:55:14 -070039 // have to register this, otherwise
40 // the signal-slot system won't recognize this type
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -070041 qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
42 qRegisterMetaType<size_t>("size_t");
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070043 setupUi(this);
Zhenkai Zhu82a62752012-06-04 17:11:04 -070044 m_session = time(NULL);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -070045
46 readSettings();
Zhenkai Zhu82a62752012-06-04 17:11:04 -070047
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -070048 updateLabels();
49
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070050 lineEdit->setFocusPolicy(Qt::StrongFocus);
Zhenkai Zhu82a62752012-06-04 17:11:04 -070051 m_scene = new DigestTreeScene(this);
Zhenkai Zhub45e38a2012-06-01 15:44:36 -070052
Zhenkai Zhu82a62752012-06-04 17:11:04 -070053 treeViewer->setScene(m_scene);
54 m_scene->plot("Empty");
55 QRectF rect = m_scene->itemsBoundingRect();
56 m_scene->setSceneRect(rect);
57
58 // create sync socket
59 if(!m_user.getChatroom().isEmpty()) {
60 std::string syncPrefix = BROADCAST_PREFIX_FOR_SYNC_DEMO;
61 syncPrefix += "/";
62 syncPrefix += m_user.getChatroom().toStdString();
Zhenkai Zhua4fb1242012-06-05 20:26:05 -070063 try
64 {
65 m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2), bind(&ChatDialog::processRemove, this, _1));
66 }
67 catch (Sync::CcnxOperationException ex)
68 {
69 QMessageBox::critical(this, tr("Sync-Demo"), tr("Canno connect to ccnd.\n Have you started your ccnd?"), QMessageBox::Ok);
70 std::exit(1);
71 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -070072 }
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -070073
74 createActions();
75 createTrayIcon();
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070076 connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
Zhenkai Zhu85845d22012-06-01 23:10:43 -070077 connect(setButton, SIGNAL(pressed()), this, SLOT(buttonPressed()));
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -070078 connect(this, SIGNAL(dataReceived(QString, const char *, size_t)), this, SLOT(processData(QString, const char *, size_t)));
79 connect(this, SIGNAL(treeUpdated(const std::vector<Sync::MissingDataInfo>)), this, SLOT(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -070080 connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(showNormal()));
81 connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
82
83//testDraw();
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070084}
85
Zhenkai Zhu82a62752012-06-04 17:11:04 -070086ChatDialog::~ChatDialog()
87{
88 if (m_sock != NULL)
89 {
Zhenkai Zhu591e8c32012-09-26 11:57:50 -070090 m_sock->remove(m_user.getPrefix().toStdString());
Zhenkai Zhu82a62752012-06-04 17:11:04 -070091 delete m_sock;
92 m_sock = NULL;
93 }
94}
95
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -070096void
97ChatDialog::setVisible(bool visible)
98{
99 minimizeAction->setEnabled(visible);
100 maximizeAction->setEnabled(!isMaximized());
101 restoreAction->setEnabled(isMaximized() || !visible);
102 QDialog::setVisible(visible);
103}
104
105void
106ChatDialog::closeEvent(QCloseEvent *e)
107{
108 if (trayIcon->isVisible())
109 {
110 QMessageBox::information(this, tr("Sync-Demo"),
111 tr("The program will keep running in the "
112 "system tray. To terminate the program"
113 "choose <b>Quit</b> in the context memu"
114 "of the system tray entry."));
115 hide();
116 e->ignore();
117 }
118}
119
120void
121ChatDialog::changeEvent(QEvent *e)
122{
123 switch(e->type())
124 {
125 case QEvent::ActivationChange:
126 if (isActiveWindow())
127 {
128 trayIcon->setIcon(QIcon(":/images/icon_small.png"));
129 }
130 break;
131 default:
132 break;
133 }
134}
135
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700136void
Zhenkai Zhu10ccb5a2012-06-04 21:55:14 -0700137ChatDialog::appendMessage(const SyncDemo::ChatMessage msg)
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700138{
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700139 boost::mutex::scoped_lock lock(m_msgMutex);
Zhenkai Zhub6338822012-05-31 13:27:24 -0700140
141 if (msg.type() != SyncDemo::ChatMessage::CHAT) {
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700142 return;
Zhenkai Zhub6338822012-05-31 13:27:24 -0700143 }
144
145 if (!msg.has_data()) {
146 return;
147 }
148
149 if (msg.from().empty() || msg.data().empty()) {
150 return;
151 }
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700152
153 QTextCursor cursor(textEdit->textCursor());
154 cursor.movePosition(QTextCursor::End);
155 QTextTableFormat tableFormat;
156 tableFormat.setBorder(0);
157 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
Zhenkai Zhub6338822012-05-31 13:27:24 -0700158 QString from = QString("<%1>: ").arg(msg.from().c_str());
159 table->cellAt(0, 0).firstCursorPosition().insertText(from);
160 table->cellAt(0, 1).firstCursorPosition().insertText(msg.data().c_str());
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700161 QScrollBar *bar = textEdit->verticalScrollBar();
162 bar->setValue(bar->maximum());
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -0700163 showMessage(from, msg.data().c_str());
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700164}
165
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700166void
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700167ChatDialog::processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo> v, Sync::SyncAppSocket *sock)
168{
169 emit treeUpdated(v);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700170#ifdef __DEBUG
171 std::cout << "<<< Tree update signal emitted" << std::endl;
172#endif
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700173}
174
175void
176ChatDialog::processTreeUpdate(const std::vector<Sync::MissingDataInfo> v)
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700177{
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700178#ifdef __DEBUG
179 std::cout << "<<< processing Tree Update" << std::endl;
180#endif
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700181 if (v.empty())
182 {
183 return;
184 }
185
186 // reflect the changes on digest tree
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700187 {
188 boost::mutex::scoped_lock lock(m_sceneMutex);
189 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
190 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700191
192 int n = v.size();
193 int totalMissingPackets = 0;
194 for (int i = 0; i < n; i++)
195 {
196 totalMissingPackets += v[i].high.getSeq() - v[i].low.getSeq() + 1;
197 }
198
199 if (totalMissingPackets < 10) {
200 for (int i = 0; i < n; i++)
201 {
202 for (Sync::SeqNo seq = v[i].low; seq <= v[i].high; ++seq)
203 {
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700204 m_sock->fetchRaw(v[i].prefix, seq, bind(&ChatDialog::processDataWrapper, this, _1, _2, _3), 2);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700205#ifdef __DEBUG
206 std::cout << "<<< Fetching " << v[i].prefix << "/" <<seq.getSession() <<"/" << seq.getSeq() << std::endl;
207#endif
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700208 }
209 }
210 }
211 else
212 {
213 // too bad; too many missing packets
214 // we may just join a new chatroom
215 // or some network patition just healed
216 // we don't try to fetch any data in this case (for now)
217 }
218
219 // adjust the view
220 fitView();
221
222}
223
224void
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700225ChatDialog::processDataWrapper(std::string name, const char *buf, size_t len)
226{
227 emit dataReceived(name.c_str(), buf, len);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700228#ifdef __DEBUG
229 std::cout <<"<<< " << name << " fetched" << std::endl;
230#endif
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700231}
232
233void
234ChatDialog::processData(QString name, const char *buf, size_t len)
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700235{
236 SyncDemo::ChatMessage msg;
237 if (!msg.ParseFromArray(buf, len))
238 {
239 std::cerr << "Errrrr.. Can not parse msg at "<<__FILE__ <<":"<<__LINE__<<". what is happening?" << std::endl;
240 abort();
241 }
242
Zhenkai Zhu10ccb5a2012-06-04 21:55:14 -0700243 // display msg received from network
244 // we have to do so; this function is called by ccnd thread
245 // so if we call appendMsg directly
246 // Qt crash as "QObject: Cannot create children for a parent that is in a different thread"
247 // the "cannonical" way to is use signal-slot
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700248 appendMessage(msg);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700249
250 // update the tree view
Zhenkai Zhu097bfe72012-06-05 14:30:17 -0700251 std::string stdStrName = name.toStdString();
252 std::string stdStrNameWithoutSeq = stdStrName.substr(0, stdStrName.find_last_of('/'));
253 std::string prefix = stdStrNameWithoutSeq.substr(0, stdStrNameWithoutSeq.find_last_of('/'));
254#ifdef __DEBUG
255 std::cout <<"<<< updating scene for" << prefix << ": " << msg.from() << std::endl;
256#endif
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700257 {
258 boost::mutex::scoped_lock lock(m_sceneMutex);
259 m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
260 }
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700261 fitView();
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700262}
263
264void
265ChatDialog::processRemove(std::string prefix)
266{
Zhenkai Zhu591e8c32012-09-26 11:57:50 -0700267#ifdef __DEBUG
268 std::cout << "<<< remove node for prefix" << prefix << std::endl;
269#endif
270 bool removed = m_scene->removeNode(QString(prefix.c_str()));
271 if (removed)
272 {
273 m_scene->plot(m_sock->getRootDigest().c_str());
274 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700275}
276
277void
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700278ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700279 msg.set_from(m_user.getNick().toStdString());
280 msg.set_to(m_user.getChatroom().toStdString());
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700281 msg.set_data(text.toStdString());
282 time_t seconds = time(NULL);
283 msg.set_timestamp(seconds);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700284 msg.set_type(SyncDemo::ChatMessage::CHAT);
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700285}
286
Zhenkai Zhu59245aa2012-09-26 16:07:04 -0700287static std::string chars("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789");
288
289QString
290ChatDialog::getRandomString()
291{
292 std::string randStr;
293 boost::random::random_device rng;
294 boost::random::uniform_int_distribution<> index_dist(0, chars.size() - 1);
295 for (int i = 0; i < 10; i ++)
296 {
297 randStr += chars[index_dist(rng)];
298 }
299 return randStr.c_str();
300}
301
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700302bool
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700303ChatDialog::readSettings()
304{
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700305#ifndef __DEBUG
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700306 QSettings s(ORGANIZATION, APPLICATION);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700307 QString nick = s.value("nick", "").toString();
308 QString chatroom = s.value("chatroom", "").toString();
309 QString prefix = s.value("prefix", "").toString();
310 if (nick == "" || chatroom == "" || prefix == "") {
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700311 QTimer::singleShot(500, this, SLOT(buttonPressed()));
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700312 return false;
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700313 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700314 else {
315 m_user.setNick(nick);
316 m_user.setChatroom(chatroom);
317 m_user.setPrefix(prefix);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700318 return true;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700319 }
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700320#else
321 QTimer::singleShot(500, this, SLOT(buttonPressed()));
322 return false;
323#endif
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700324}
325
326void
327ChatDialog::writeSettings()
328{
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700329#ifndef __DEBUG
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700330 QSettings s(ORGANIZATION, APPLICATION);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700331 s.setValue("nick", m_user.getNick());
332 s.setValue("chatroom", m_user.getChatroom());
333 s.setValue("prefix", m_user.getPrefix());
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700334#endif
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700335}
336
337void
338ChatDialog::updateLabels()
339{
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700340 QString settingDisp = QString("<User: %1>, <Chatroom: %2>").arg(m_user.getNick()).arg(m_user.getChatroom());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700341 infoLabel->setText(settingDisp);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700342 QString prefixDisp = QString("<Prefix: %1>").arg(m_user.getPrefix());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700343 prefixLabel->setText(prefixDisp);
344}
345
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700346void
347ChatDialog::returnPressed()
348{
349 QString text = lineEdit->text();
350 if (text.isEmpty())
351 return;
352
Zhenkai Zhub6338822012-05-31 13:27:24 -0700353 lineEdit->clear();
354
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700355 SyncDemo::ChatMessage msg;
356 formChatMessage(text, msg);
357
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700358 appendMessage(msg);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700359
360 // send msg
361 size_t size = msg.ByteSize();
362 char *buf = new char[size];
363 msg.SerializeToArray(buf, size);
364 if (!msg.IsInitialized())
365 {
366 std::cerr << "Errrrr.. msg was not probally initialized "<<__FILE__ <<":"<<__LINE__<<". what is happening?" << std::endl;
367 abort();
368 }
369 m_sock->publishRaw(m_user.getPrefix().toStdString(), m_session, buf, size, 60);
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700370
371 int nextSequence = m_sock->getNextSeq(m_user.getPrefix().toStdString(), m_session);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700372 Sync::MissingDataInfo mdi = {m_user.getPrefix().toStdString(), Sync::SeqNo(0), Sync::SeqNo(nextSequence - 1)};
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700373 std::vector<Sync::MissingDataInfo> v;
374 v.push_back(mdi);
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700375 {
376 boost::mutex::scoped_lock lock(m_sceneMutex);
377 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
378 m_scene->msgReceived(m_user.getPrefix(), m_user.getNick());
379 }
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700380 fitView();
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700381}
382
383void
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700384ChatDialog::buttonPressed()
385{
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700386 SettingDialog dialog(this, m_user.getNick(), m_user.getChatroom(), m_user.getPrefix());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700387 connect(&dialog, SIGNAL(updated(QString, QString, QString)), this, SLOT(settingUpdated(QString, QString, QString)));
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700388 dialog.exec();
Zhenkai Zhue837f792012-06-05 20:47:54 -0700389 QTimer::singleShot(100, this, SLOT(checkSetting()));
390}
391
392void
393ChatDialog::checkSetting()
394{
395 if (m_user.getPrefix().isEmpty() || m_user.getNick().isEmpty() || m_user.getChatroom().isEmpty())
396 {
397 buttonPressed();
398 }
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -0700399}
Zhenkai Zhue08afe02012-05-31 15:49:07 -0700400
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700401void
402ChatDialog::settingUpdated(QString nick, QString chatroom, QString prefix)
403{
404 bool needWrite = false;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700405 if (!nick.isEmpty() && nick != m_user.getNick()) {
406 m_user.setNick(nick);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700407 needWrite = true;
408 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700409 if (!prefix.isEmpty() && prefix != m_user.getPrefix()) {
Zhenkai Zhu59245aa2012-09-26 16:07:04 -0700410 m_user.setPrefix(prefix + "/" + getRandomString());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700411 needWrite = true;
412 // TODO: set the previous prefix as left?
413 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700414 if (!chatroom.isEmpty() && chatroom != m_user.getChatroom()) {
415 m_user.setChatroom(chatroom);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700416 needWrite = true;
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700417
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700418 {
419 boost::mutex::scoped_lock lock(m_sceneMutex);
420 m_scene->clearAll();
421 m_scene->plot("Empty");
422 }
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700423 // TODO: perhaps need to do a lot. e.g. use a new SyncAppSokcet
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700424 if (m_sock != NULL)
425 {
426 delete m_sock;
427 m_sock = NULL;
428 }
429 std::string syncPrefix = BROADCAST_PREFIX_FOR_SYNC_DEMO;
430 syncPrefix += "/";
431 syncPrefix += m_user.getChatroom().toStdString();
Zhenkai Zhua4fb1242012-06-05 20:26:05 -0700432 try
433 {
434 m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2), bind(&ChatDialog::processRemove, this, _1));
435 }
436 catch (Sync::CcnxOperationException ex)
437 {
438 QMessageBox::critical(this, tr("Sync-Demo"), tr("Canno connect to ccnd.\n Have you started your ccnd?"), QMessageBox::Ok);
439 std::exit(1);
440 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700441
442 fitView();
443
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700444 }
445 if (needWrite) {
446 writeSettings();
447 updateLabels();
448 }
449}
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700450
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -0700451void
452ChatDialog::iconActivated(QSystemTrayIcon::ActivationReason reason)
453{
454 switch (reason)
455 {
456 case QSystemTrayIcon::Trigger:
457 case QSystemTrayIcon::DoubleClick:
458 break;
459 case QSystemTrayIcon::MiddleClick:
460 // showMessage();
461 break;
462 default:;
463 }
464}
465
466void
467ChatDialog::showMessage(QString from, QString data)
468{
469 // std::cout <<"Showing Message: " << from.toStdString() << ": " << data.toStdString() << std::endl;
470 if (!isActiveWindow())
471 {
472 trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(m_user.getChatroom()), QString("<%1>: %2").arg(from).arg(data), QSystemTrayIcon::Information, 20000);
473 trayIcon->setIcon(QIcon(":/images/note.png"));
474 }
475}
476
477void
478ChatDialog::messageClicked()
479{
480 this->showMaximized();
481}
482
483void
484ChatDialog::createActions()
485{
486 minimizeAction = new QAction(tr("Mi&nimize"), this);
487 connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
488
489 maximizeAction = new QAction(tr("Ma&ximize"), this);
490 connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
491
492 restoreAction = new QAction(tr("&Restore"), this);
493 connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
494
495 quitAction = new QAction(tr("Quit"), this);
496 connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
497}
498
499void
500ChatDialog::createTrayIcon()
501{
502 trayIconMenu = new QMenu(this);
503 trayIconMenu->addAction(minimizeAction);
504 trayIconMenu->addAction(maximizeAction);
505 trayIconMenu->addAction(restoreAction);
506 trayIconMenu->addSeparator();
507 trayIconMenu->addAction(quitAction);
508
509 trayIcon = new QSystemTrayIcon(this);
510 trayIcon->setContextMenu(trayIconMenu);
511
512 QIcon icon(":/images/icon_small.png");
513 trayIcon->setIcon(icon);
514 setWindowIcon(icon);
515 trayIcon->setToolTip("Sync-Demo System Tray Icon");
516 trayIcon->setVisible(true);
517}
518
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700519void
520ChatDialog::resizeEvent(QResizeEvent *e)
521{
522 fitView();
523}
524
525void
526ChatDialog::showEvent(QShowEvent *e)
527{
528 fitView();
529}
530
531void
532ChatDialog::fitView()
533{
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700534 boost::mutex::scoped_lock lock(m_sceneMutex);
Zhenkai Zhu21d75f92012-06-04 21:23:34 -0700535 QRectF rect = m_scene->itemsBoundingRect();
536 m_scene->setSceneRect(rect);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700537 treeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700538}