blob: 322c947f77ddb6b4f6ad81f41cf9fc94f414e421 [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 Zhu6d589aa2012-05-29 17:34:35 -07009
Zhenkai Zhu82a62752012-06-04 17:11:04 -070010#define BROADCAST_PREFIX_FOR_SYNC_DEMO "/ndn/broadcast/sync-demo"
11
Zhenkai Zhu21d75f92012-06-04 21:23:34 -070012void
13ChatDialog::testDraw()
14{
15 std::string prefix[5] = {"/ndn/1", "/ndn/2", "/ndn/3", "/ndn/4", "/ndn/5"};
16 std::string nick[5] = {"tom", "jerry", "jason", "michael", "hurry"};
17 std::vector<Sync::MissingDataInfo> v;
18 for (int i = 0; i < 5; i++)
19 {
20 Sync::MissingDataInfo mdi = {prefix[i], Sync::SeqNo(0), Sync::SeqNo(i * (2 << i) )};
21 v.push_back(mdi);
22 }
23
24 m_scene->processUpdate(v, "12341234@!#%!@");
25
26 for (int i = 0; i < 5; i++)
27 {
28 m_scene-> msgReceived(prefix[i].c_str(), nick[i].c_str());
29 }
30
31 fitView();
32}
33
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070034ChatDialog::ChatDialog(QWidget *parent)
Zhenkai Zhu82a62752012-06-04 17:11:04 -070035 : QDialog(parent), m_sock(NULL)
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070036{
Zhenkai Zhu10ccb5a2012-06-04 21:55:14 -070037 // have to register this, otherwise
38 // the signal-slot system won't recognize this type
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -070039 qRegisterMetaType<std::vector<Sync::MissingDataInfo> >("std::vector<Sync::MissingDataInfo>");
40 qRegisterMetaType<size_t>("size_t");
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070041 setupUi(this);
Zhenkai Zhu82a62752012-06-04 17:11:04 -070042 m_session = time(NULL);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -070043
44 readSettings();
Zhenkai Zhu82a62752012-06-04 17:11:04 -070045
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -070046 updateLabels();
47
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070048 lineEdit->setFocusPolicy(Qt::StrongFocus);
Zhenkai Zhu82a62752012-06-04 17:11:04 -070049 m_scene = new DigestTreeScene(this);
Zhenkai Zhub45e38a2012-06-01 15:44:36 -070050
Zhenkai Zhu82a62752012-06-04 17:11:04 -070051 treeViewer->setScene(m_scene);
52 m_scene->plot("Empty");
53 QRectF rect = m_scene->itemsBoundingRect();
54 m_scene->setSceneRect(rect);
55
56 // create sync socket
57 if(!m_user.getChatroom().isEmpty()) {
58 std::string syncPrefix = BROADCAST_PREFIX_FOR_SYNC_DEMO;
59 syncPrefix += "/";
60 syncPrefix += m_user.getChatroom().toStdString();
Zhenkai Zhua4fb1242012-06-05 20:26:05 -070061 try
62 {
63 m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2), bind(&ChatDialog::processRemove, this, _1));
64 }
65 catch (Sync::CcnxOperationException ex)
66 {
67 QMessageBox::critical(this, tr("Sync-Demo"), tr("Canno connect to ccnd.\n Have you started your ccnd?"), QMessageBox::Ok);
68 std::exit(1);
69 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -070070 }
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -070071
72 createActions();
73 createTrayIcon();
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070074 connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
Zhenkai Zhu85845d22012-06-01 23:10:43 -070075 connect(setButton, SIGNAL(pressed()), this, SLOT(buttonPressed()));
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -070076 connect(this, SIGNAL(dataReceived(QString, const char *, size_t)), this, SLOT(processData(QString, const char *, size_t)));
77 connect(this, SIGNAL(treeUpdated(const std::vector<Sync::MissingDataInfo>)), this, SLOT(processTreeUpdate(const std::vector<Sync::MissingDataInfo>)));
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -070078 connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(showNormal()));
79 connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
80
81//testDraw();
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070082}
83
Zhenkai Zhu82a62752012-06-04 17:11:04 -070084ChatDialog::~ChatDialog()
85{
86 if (m_sock != NULL)
87 {
88 delete m_sock;
89 m_sock = NULL;
90 }
91}
92
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -070093void
94ChatDialog::setVisible(bool visible)
95{
96 minimizeAction->setEnabled(visible);
97 maximizeAction->setEnabled(!isMaximized());
98 restoreAction->setEnabled(isMaximized() || !visible);
99 QDialog::setVisible(visible);
100}
101
102void
103ChatDialog::closeEvent(QCloseEvent *e)
104{
105 if (trayIcon->isVisible())
106 {
107 QMessageBox::information(this, tr("Sync-Demo"),
108 tr("The program will keep running in the "
109 "system tray. To terminate the program"
110 "choose <b>Quit</b> in the context memu"
111 "of the system tray entry."));
112 hide();
113 e->ignore();
114 }
115}
116
117void
118ChatDialog::changeEvent(QEvent *e)
119{
120 switch(e->type())
121 {
122 case QEvent::ActivationChange:
123 if (isActiveWindow())
124 {
125 trayIcon->setIcon(QIcon(":/images/icon_small.png"));
126 }
127 break;
128 default:
129 break;
130 }
131}
132
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700133void
Zhenkai Zhu10ccb5a2012-06-04 21:55:14 -0700134ChatDialog::appendMessage(const SyncDemo::ChatMessage msg)
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700135{
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700136 boost::mutex::scoped_lock lock(m_msgMutex);
Zhenkai Zhub6338822012-05-31 13:27:24 -0700137
138 if (msg.type() != SyncDemo::ChatMessage::CHAT) {
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700139 return;
Zhenkai Zhub6338822012-05-31 13:27:24 -0700140 }
141
142 if (!msg.has_data()) {
143 return;
144 }
145
146 if (msg.from().empty() || msg.data().empty()) {
147 return;
148 }
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700149
150 QTextCursor cursor(textEdit->textCursor());
151 cursor.movePosition(QTextCursor::End);
152 QTextTableFormat tableFormat;
153 tableFormat.setBorder(0);
154 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
Zhenkai Zhub6338822012-05-31 13:27:24 -0700155 QString from = QString("<%1>: ").arg(msg.from().c_str());
156 table->cellAt(0, 0).firstCursorPosition().insertText(from);
157 table->cellAt(0, 1).firstCursorPosition().insertText(msg.data().c_str());
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700158 QScrollBar *bar = textEdit->verticalScrollBar();
159 bar->setValue(bar->maximum());
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -0700160 showMessage(from, msg.data().c_str());
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700161}
162
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700163void
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700164ChatDialog::processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo> v, Sync::SyncAppSocket *sock)
165{
166 emit treeUpdated(v);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700167#ifdef __DEBUG
168 std::cout << "<<< Tree update signal emitted" << std::endl;
169#endif
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700170}
171
172void
173ChatDialog::processTreeUpdate(const std::vector<Sync::MissingDataInfo> v)
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700174{
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700175#ifdef __DEBUG
176 std::cout << "<<< processing Tree Update" << std::endl;
177#endif
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700178 if (v.empty())
179 {
180 return;
181 }
182
183 // reflect the changes on digest tree
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700184 {
185 boost::mutex::scoped_lock lock(m_sceneMutex);
186 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
187 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700188
189 int n = v.size();
190 int totalMissingPackets = 0;
191 for (int i = 0; i < n; i++)
192 {
193 totalMissingPackets += v[i].high.getSeq() - v[i].low.getSeq() + 1;
194 }
195
196 if (totalMissingPackets < 10) {
197 for (int i = 0; i < n; i++)
198 {
199 for (Sync::SeqNo seq = v[i].low; seq <= v[i].high; ++seq)
200 {
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700201 m_sock->fetchRaw(v[i].prefix, seq, bind(&ChatDialog::processDataWrapper, this, _1, _2, _3), 2);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700202#ifdef __DEBUG
203 std::cout << "<<< Fetching " << v[i].prefix << "/" <<seq.getSession() <<"/" << seq.getSeq() << std::endl;
204#endif
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700205 }
206 }
207 }
208 else
209 {
210 // too bad; too many missing packets
211 // we may just join a new chatroom
212 // or some network patition just healed
213 // we don't try to fetch any data in this case (for now)
214 }
215
216 // adjust the view
217 fitView();
218
219}
220
221void
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700222ChatDialog::processDataWrapper(std::string name, const char *buf, size_t len)
223{
224 emit dataReceived(name.c_str(), buf, len);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700225#ifdef __DEBUG
226 std::cout <<"<<< " << name << " fetched" << std::endl;
227#endif
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700228}
229
230void
231ChatDialog::processData(QString name, const char *buf, size_t len)
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700232{
233 SyncDemo::ChatMessage msg;
234 if (!msg.ParseFromArray(buf, len))
235 {
236 std::cerr << "Errrrr.. Can not parse msg at "<<__FILE__ <<":"<<__LINE__<<". what is happening?" << std::endl;
237 abort();
238 }
239
Zhenkai Zhu10ccb5a2012-06-04 21:55:14 -0700240 // display msg received from network
241 // we have to do so; this function is called by ccnd thread
242 // so if we call appendMsg directly
243 // Qt crash as "QObject: Cannot create children for a parent that is in a different thread"
244 // the "cannonical" way to is use signal-slot
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700245 appendMessage(msg);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700246
247 // update the tree view
Zhenkai Zhu097bfe72012-06-05 14:30:17 -0700248 std::string stdStrName = name.toStdString();
249 std::string stdStrNameWithoutSeq = stdStrName.substr(0, stdStrName.find_last_of('/'));
250 std::string prefix = stdStrNameWithoutSeq.substr(0, stdStrNameWithoutSeq.find_last_of('/'));
251#ifdef __DEBUG
252 std::cout <<"<<< updating scene for" << prefix << ": " << msg.from() << std::endl;
253#endif
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700254 {
255 boost::mutex::scoped_lock lock(m_sceneMutex);
256 m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
257 }
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700258 fitView();
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700259}
260
261void
262ChatDialog::processRemove(std::string prefix)
263{
264}
265
266void
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700267ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700268 msg.set_from(m_user.getNick().toStdString());
269 msg.set_to(m_user.getChatroom().toStdString());
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700270 msg.set_data(text.toStdString());
271 time_t seconds = time(NULL);
272 msg.set_timestamp(seconds);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700273 msg.set_type(SyncDemo::ChatMessage::CHAT);
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700274}
275
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700276bool
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700277ChatDialog::readSettings()
278{
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700279#ifndef __DEBUG
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700280 QSettings s(ORGANIZATION, APPLICATION);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700281 QString nick = s.value("nick", "").toString();
282 QString chatroom = s.value("chatroom", "").toString();
283 QString prefix = s.value("prefix", "").toString();
284 if (nick == "" || chatroom == "" || prefix == "") {
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700285 QTimer::singleShot(500, this, SLOT(buttonPressed()));
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700286 return false;
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700287 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700288 else {
289 m_user.setNick(nick);
290 m_user.setChatroom(chatroom);
291 m_user.setPrefix(prefix);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700292 return true;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700293 }
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700294#else
295 QTimer::singleShot(500, this, SLOT(buttonPressed()));
296 return false;
297#endif
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700298}
299
300void
301ChatDialog::writeSettings()
302{
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700303#ifndef __DEBUG
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700304 QSettings s(ORGANIZATION, APPLICATION);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700305 s.setValue("nick", m_user.getNick());
306 s.setValue("chatroom", m_user.getChatroom());
307 s.setValue("prefix", m_user.getPrefix());
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700308#endif
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700309}
310
311void
312ChatDialog::updateLabels()
313{
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700314 QString settingDisp = QString("<User: %1>, <Chatroom: %2>").arg(m_user.getNick()).arg(m_user.getChatroom());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700315 infoLabel->setText(settingDisp);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700316 QString prefixDisp = QString("<Prefix: %1>").arg(m_user.getPrefix());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700317 prefixLabel->setText(prefixDisp);
318}
319
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700320void
321ChatDialog::returnPressed()
322{
323 QString text = lineEdit->text();
324 if (text.isEmpty())
325 return;
326
Zhenkai Zhub6338822012-05-31 13:27:24 -0700327 lineEdit->clear();
328
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700329 SyncDemo::ChatMessage msg;
330 formChatMessage(text, msg);
331
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700332 appendMessage(msg);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700333
334 // send msg
335 size_t size = msg.ByteSize();
336 char *buf = new char[size];
337 msg.SerializeToArray(buf, size);
338 if (!msg.IsInitialized())
339 {
340 std::cerr << "Errrrr.. msg was not probally initialized "<<__FILE__ <<":"<<__LINE__<<". what is happening?" << std::endl;
341 abort();
342 }
343 m_sock->publishRaw(m_user.getPrefix().toStdString(), m_session, buf, size, 60);
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700344
345 int nextSequence = m_sock->getNextSeq(m_user.getPrefix().toStdString(), m_session);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700346 Sync::MissingDataInfo mdi = {m_user.getPrefix().toStdString(), Sync::SeqNo(0), Sync::SeqNo(nextSequence - 1)};
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700347 std::vector<Sync::MissingDataInfo> v;
348 v.push_back(mdi);
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700349 {
350 boost::mutex::scoped_lock lock(m_sceneMutex);
351 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
352 m_scene->msgReceived(m_user.getPrefix(), m_user.getNick());
353 }
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700354 fitView();
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700355}
356
357void
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700358ChatDialog::buttonPressed()
359{
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700360 SettingDialog dialog(this, m_user.getNick(), m_user.getChatroom(), m_user.getPrefix());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700361 connect(&dialog, SIGNAL(updated(QString, QString, QString)), this, SLOT(settingUpdated(QString, QString, QString)));
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700362 dialog.exec();
Zhenkai Zhue837f792012-06-05 20:47:54 -0700363 QTimer::singleShot(100, this, SLOT(checkSetting()));
364}
365
366void
367ChatDialog::checkSetting()
368{
369 if (m_user.getPrefix().isEmpty() || m_user.getNick().isEmpty() || m_user.getChatroom().isEmpty())
370 {
371 buttonPressed();
372 }
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -0700373}
Zhenkai Zhue08afe02012-05-31 15:49:07 -0700374
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700375void
376ChatDialog::settingUpdated(QString nick, QString chatroom, QString prefix)
377{
378 bool needWrite = false;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700379 if (!nick.isEmpty() && nick != m_user.getNick()) {
380 m_user.setNick(nick);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700381 needWrite = true;
382 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700383 if (!prefix.isEmpty() && prefix != m_user.getPrefix()) {
384 m_user.setPrefix(prefix);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700385 needWrite = true;
386 // TODO: set the previous prefix as left?
387 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700388 if (!chatroom.isEmpty() && chatroom != m_user.getChatroom()) {
389 m_user.setChatroom(chatroom);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700390 needWrite = true;
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700391
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700392 {
393 boost::mutex::scoped_lock lock(m_sceneMutex);
394 m_scene->clearAll();
395 m_scene->plot("Empty");
396 }
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700397 // TODO: perhaps need to do a lot. e.g. use a new SyncAppSokcet
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700398 if (m_sock != NULL)
399 {
400 delete m_sock;
401 m_sock = NULL;
402 }
403 std::string syncPrefix = BROADCAST_PREFIX_FOR_SYNC_DEMO;
404 syncPrefix += "/";
405 syncPrefix += m_user.getChatroom().toStdString();
Zhenkai Zhua4fb1242012-06-05 20:26:05 -0700406 try
407 {
408 m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2), bind(&ChatDialog::processRemove, this, _1));
409 }
410 catch (Sync::CcnxOperationException ex)
411 {
412 QMessageBox::critical(this, tr("Sync-Demo"), tr("Canno connect to ccnd.\n Have you started your ccnd?"), QMessageBox::Ok);
413 std::exit(1);
414 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700415
416 fitView();
417
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700418 }
419 if (needWrite) {
420 writeSettings();
421 updateLabels();
422 }
423}
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700424
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -0700425void
426ChatDialog::iconActivated(QSystemTrayIcon::ActivationReason reason)
427{
428 switch (reason)
429 {
430 case QSystemTrayIcon::Trigger:
431 case QSystemTrayIcon::DoubleClick:
432 break;
433 case QSystemTrayIcon::MiddleClick:
434 // showMessage();
435 break;
436 default:;
437 }
438}
439
440void
441ChatDialog::showMessage(QString from, QString data)
442{
443 // std::cout <<"Showing Message: " << from.toStdString() << ": " << data.toStdString() << std::endl;
444 if (!isActiveWindow())
445 {
446 trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(m_user.getChatroom()), QString("<%1>: %2").arg(from).arg(data), QSystemTrayIcon::Information, 20000);
447 trayIcon->setIcon(QIcon(":/images/note.png"));
448 }
449}
450
451void
452ChatDialog::messageClicked()
453{
454 this->showMaximized();
455}
456
457void
458ChatDialog::createActions()
459{
460 minimizeAction = new QAction(tr("Mi&nimize"), this);
461 connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
462
463 maximizeAction = new QAction(tr("Ma&ximize"), this);
464 connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
465
466 restoreAction = new QAction(tr("&Restore"), this);
467 connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
468
469 quitAction = new QAction(tr("Quit"), this);
470 connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
471}
472
473void
474ChatDialog::createTrayIcon()
475{
476 trayIconMenu = new QMenu(this);
477 trayIconMenu->addAction(minimizeAction);
478 trayIconMenu->addAction(maximizeAction);
479 trayIconMenu->addAction(restoreAction);
480 trayIconMenu->addSeparator();
481 trayIconMenu->addAction(quitAction);
482
483 trayIcon = new QSystemTrayIcon(this);
484 trayIcon->setContextMenu(trayIconMenu);
485
486 QIcon icon(":/images/icon_small.png");
487 trayIcon->setIcon(icon);
488 setWindowIcon(icon);
489 trayIcon->setToolTip("Sync-Demo System Tray Icon");
490 trayIcon->setVisible(true);
491}
492
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700493void
494ChatDialog::resizeEvent(QResizeEvent *e)
495{
496 fitView();
497}
498
499void
500ChatDialog::showEvent(QShowEvent *e)
501{
502 fitView();
503}
504
505void
506ChatDialog::fitView()
507{
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700508 boost::mutex::scoped_lock lock(m_sceneMutex);
Zhenkai Zhu21d75f92012-06-04 21:23:34 -0700509 QRectF rect = m_scene->itemsBoundingRect();
510 m_scene->setSceneRect(rect);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700511 treeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700512}