blob: 58bdd905d5d8824d4403a7673eb71eadcde338b6 [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 {
Zhenkai Zhu591e8c32012-09-26 11:57:50 -070088 m_sock->remove(m_user.getPrefix().toStdString());
Zhenkai Zhu82a62752012-06-04 17:11:04 -070089 delete m_sock;
90 m_sock = NULL;
91 }
92}
93
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -070094void
95ChatDialog::setVisible(bool visible)
96{
97 minimizeAction->setEnabled(visible);
98 maximizeAction->setEnabled(!isMaximized());
99 restoreAction->setEnabled(isMaximized() || !visible);
100 QDialog::setVisible(visible);
101}
102
103void
104ChatDialog::closeEvent(QCloseEvent *e)
105{
106 if (trayIcon->isVisible())
107 {
108 QMessageBox::information(this, tr("Sync-Demo"),
109 tr("The program will keep running in the "
110 "system tray. To terminate the program"
111 "choose <b>Quit</b> in the context memu"
112 "of the system tray entry."));
113 hide();
114 e->ignore();
115 }
116}
117
118void
119ChatDialog::changeEvent(QEvent *e)
120{
121 switch(e->type())
122 {
123 case QEvent::ActivationChange:
124 if (isActiveWindow())
125 {
126 trayIcon->setIcon(QIcon(":/images/icon_small.png"));
127 }
128 break;
129 default:
130 break;
131 }
132}
133
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700134void
Zhenkai Zhu10ccb5a2012-06-04 21:55:14 -0700135ChatDialog::appendMessage(const SyncDemo::ChatMessage msg)
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700136{
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700137 boost::mutex::scoped_lock lock(m_msgMutex);
Zhenkai Zhub6338822012-05-31 13:27:24 -0700138
139 if (msg.type() != SyncDemo::ChatMessage::CHAT) {
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700140 return;
Zhenkai Zhub6338822012-05-31 13:27:24 -0700141 }
142
143 if (!msg.has_data()) {
144 return;
145 }
146
147 if (msg.from().empty() || msg.data().empty()) {
148 return;
149 }
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700150
151 QTextCursor cursor(textEdit->textCursor());
152 cursor.movePosition(QTextCursor::End);
153 QTextTableFormat tableFormat;
154 tableFormat.setBorder(0);
155 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
Zhenkai Zhub6338822012-05-31 13:27:24 -0700156 QString from = QString("<%1>: ").arg(msg.from().c_str());
157 table->cellAt(0, 0).firstCursorPosition().insertText(from);
158 table->cellAt(0, 1).firstCursorPosition().insertText(msg.data().c_str());
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700159 QScrollBar *bar = textEdit->verticalScrollBar();
160 bar->setValue(bar->maximum());
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -0700161 showMessage(from, msg.data().c_str());
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700162}
163
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700164void
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700165ChatDialog::processTreeUpdateWrapper(const std::vector<Sync::MissingDataInfo> v, Sync::SyncAppSocket *sock)
166{
167 emit treeUpdated(v);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700168#ifdef __DEBUG
169 std::cout << "<<< Tree update signal emitted" << std::endl;
170#endif
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700171}
172
173void
174ChatDialog::processTreeUpdate(const std::vector<Sync::MissingDataInfo> v)
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700175{
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700176#ifdef __DEBUG
177 std::cout << "<<< processing Tree Update" << std::endl;
178#endif
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700179 if (v.empty())
180 {
181 return;
182 }
183
184 // reflect the changes on digest tree
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700185 {
186 boost::mutex::scoped_lock lock(m_sceneMutex);
187 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
188 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700189
190 int n = v.size();
191 int totalMissingPackets = 0;
192 for (int i = 0; i < n; i++)
193 {
194 totalMissingPackets += v[i].high.getSeq() - v[i].low.getSeq() + 1;
195 }
196
197 if (totalMissingPackets < 10) {
198 for (int i = 0; i < n; i++)
199 {
200 for (Sync::SeqNo seq = v[i].low; seq <= v[i].high; ++seq)
201 {
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700202 m_sock->fetchRaw(v[i].prefix, seq, bind(&ChatDialog::processDataWrapper, this, _1, _2, _3), 2);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700203#ifdef __DEBUG
204 std::cout << "<<< Fetching " << v[i].prefix << "/" <<seq.getSession() <<"/" << seq.getSeq() << std::endl;
205#endif
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700206 }
207 }
208 }
209 else
210 {
211 // too bad; too many missing packets
212 // we may just join a new chatroom
213 // or some network patition just healed
214 // we don't try to fetch any data in this case (for now)
215 }
216
217 // adjust the view
218 fitView();
219
220}
221
222void
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700223ChatDialog::processDataWrapper(std::string name, const char *buf, size_t len)
224{
225 emit dataReceived(name.c_str(), buf, len);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700226#ifdef __DEBUG
227 std::cout <<"<<< " << name << " fetched" << std::endl;
228#endif
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700229}
230
231void
232ChatDialog::processData(QString name, const char *buf, size_t len)
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700233{
234 SyncDemo::ChatMessage msg;
235 if (!msg.ParseFromArray(buf, len))
236 {
237 std::cerr << "Errrrr.. Can not parse msg at "<<__FILE__ <<":"<<__LINE__<<". what is happening?" << std::endl;
238 abort();
239 }
240
Zhenkai Zhu10ccb5a2012-06-04 21:55:14 -0700241 // display msg received from network
242 // we have to do so; this function is called by ccnd thread
243 // so if we call appendMsg directly
244 // Qt crash as "QObject: Cannot create children for a parent that is in a different thread"
245 // the "cannonical" way to is use signal-slot
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700246 appendMessage(msg);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700247
248 // update the tree view
Zhenkai Zhu097bfe72012-06-05 14:30:17 -0700249 std::string stdStrName = name.toStdString();
250 std::string stdStrNameWithoutSeq = stdStrName.substr(0, stdStrName.find_last_of('/'));
251 std::string prefix = stdStrNameWithoutSeq.substr(0, stdStrNameWithoutSeq.find_last_of('/'));
252#ifdef __DEBUG
253 std::cout <<"<<< updating scene for" << prefix << ": " << msg.from() << std::endl;
254#endif
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700255 {
256 boost::mutex::scoped_lock lock(m_sceneMutex);
257 m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
258 }
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700259 fitView();
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700260}
261
262void
263ChatDialog::processRemove(std::string prefix)
264{
Zhenkai Zhu591e8c32012-09-26 11:57:50 -0700265#ifdef __DEBUG
266 std::cout << "<<< remove node for prefix" << prefix << std::endl;
267#endif
268 bool removed = m_scene->removeNode(QString(prefix.c_str()));
269 if (removed)
270 {
271 m_scene->plot(m_sock->getRootDigest().c_str());
272 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700273}
274
275void
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700276ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700277 msg.set_from(m_user.getNick().toStdString());
278 msg.set_to(m_user.getChatroom().toStdString());
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700279 msg.set_data(text.toStdString());
280 time_t seconds = time(NULL);
281 msg.set_timestamp(seconds);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700282 msg.set_type(SyncDemo::ChatMessage::CHAT);
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700283}
284
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700285bool
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700286ChatDialog::readSettings()
287{
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700288#ifndef __DEBUG
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700289 QSettings s(ORGANIZATION, APPLICATION);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700290 QString nick = s.value("nick", "").toString();
291 QString chatroom = s.value("chatroom", "").toString();
292 QString prefix = s.value("prefix", "").toString();
293 if (nick == "" || chatroom == "" || prefix == "") {
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700294 QTimer::singleShot(500, this, SLOT(buttonPressed()));
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700295 return false;
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700296 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700297 else {
298 m_user.setNick(nick);
299 m_user.setChatroom(chatroom);
300 m_user.setPrefix(prefix);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700301 return true;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700302 }
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700303#else
304 QTimer::singleShot(500, this, SLOT(buttonPressed()));
305 return false;
306#endif
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700307}
308
309void
310ChatDialog::writeSettings()
311{
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700312#ifndef __DEBUG
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700313 QSettings s(ORGANIZATION, APPLICATION);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700314 s.setValue("nick", m_user.getNick());
315 s.setValue("chatroom", m_user.getChatroom());
316 s.setValue("prefix", m_user.getPrefix());
Zhenkai Zhu64f9ede2012-06-05 11:32:00 -0700317#endif
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700318}
319
320void
321ChatDialog::updateLabels()
322{
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700323 QString settingDisp = QString("<User: %1>, <Chatroom: %2>").arg(m_user.getNick()).arg(m_user.getChatroom());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700324 infoLabel->setText(settingDisp);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700325 QString prefixDisp = QString("<Prefix: %1>").arg(m_user.getPrefix());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700326 prefixLabel->setText(prefixDisp);
327}
328
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700329void
330ChatDialog::returnPressed()
331{
332 QString text = lineEdit->text();
333 if (text.isEmpty())
334 return;
335
Zhenkai Zhub6338822012-05-31 13:27:24 -0700336 lineEdit->clear();
337
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700338 SyncDemo::ChatMessage msg;
339 formChatMessage(text, msg);
340
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700341 appendMessage(msg);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700342
343 // send msg
344 size_t size = msg.ByteSize();
345 char *buf = new char[size];
346 msg.SerializeToArray(buf, size);
347 if (!msg.IsInitialized())
348 {
349 std::cerr << "Errrrr.. msg was not probally initialized "<<__FILE__ <<":"<<__LINE__<<". what is happening?" << std::endl;
350 abort();
351 }
352 m_sock->publishRaw(m_user.getPrefix().toStdString(), m_session, buf, size, 60);
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700353
354 int nextSequence = m_sock->getNextSeq(m_user.getPrefix().toStdString(), m_session);
Zhenkai Zhud1c5a972012-06-05 14:07:41 -0700355 Sync::MissingDataInfo mdi = {m_user.getPrefix().toStdString(), Sync::SeqNo(0), Sync::SeqNo(nextSequence - 1)};
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700356 std::vector<Sync::MissingDataInfo> v;
357 v.push_back(mdi);
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700358 {
359 boost::mutex::scoped_lock lock(m_sceneMutex);
360 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
361 m_scene->msgReceived(m_user.getPrefix(), m_user.getNick());
362 }
Zhenkai Zhuc5470612012-06-05 12:28:59 -0700363 fitView();
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700364}
365
366void
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700367ChatDialog::buttonPressed()
368{
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700369 SettingDialog dialog(this, m_user.getNick(), m_user.getChatroom(), m_user.getPrefix());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700370 connect(&dialog, SIGNAL(updated(QString, QString, QString)), this, SLOT(settingUpdated(QString, QString, QString)));
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700371 dialog.exec();
Zhenkai Zhue837f792012-06-05 20:47:54 -0700372 QTimer::singleShot(100, this, SLOT(checkSetting()));
373}
374
375void
376ChatDialog::checkSetting()
377{
378 if (m_user.getPrefix().isEmpty() || m_user.getNick().isEmpty() || m_user.getChatroom().isEmpty())
379 {
380 buttonPressed();
381 }
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -0700382}
Zhenkai Zhue08afe02012-05-31 15:49:07 -0700383
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700384void
385ChatDialog::settingUpdated(QString nick, QString chatroom, QString prefix)
386{
387 bool needWrite = false;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700388 if (!nick.isEmpty() && nick != m_user.getNick()) {
389 m_user.setNick(nick);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700390 needWrite = true;
391 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700392 if (!prefix.isEmpty() && prefix != m_user.getPrefix()) {
393 m_user.setPrefix(prefix);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700394 needWrite = true;
395 // TODO: set the previous prefix as left?
396 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700397 if (!chatroom.isEmpty() && chatroom != m_user.getChatroom()) {
398 m_user.setChatroom(chatroom);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700399 needWrite = true;
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700400
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700401 {
402 boost::mutex::scoped_lock lock(m_sceneMutex);
403 m_scene->clearAll();
404 m_scene->plot("Empty");
405 }
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700406 // TODO: perhaps need to do a lot. e.g. use a new SyncAppSokcet
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700407 if (m_sock != NULL)
408 {
409 delete m_sock;
410 m_sock = NULL;
411 }
412 std::string syncPrefix = BROADCAST_PREFIX_FOR_SYNC_DEMO;
413 syncPrefix += "/";
414 syncPrefix += m_user.getChatroom().toStdString();
Zhenkai Zhua4fb1242012-06-05 20:26:05 -0700415 try
416 {
417 m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdateWrapper, this, _1, _2), bind(&ChatDialog::processRemove, this, _1));
418 }
419 catch (Sync::CcnxOperationException ex)
420 {
421 QMessageBox::critical(this, tr("Sync-Demo"), tr("Canno connect to ccnd.\n Have you started your ccnd?"), QMessageBox::Ok);
422 std::exit(1);
423 }
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700424
425 fitView();
426
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700427 }
428 if (needWrite) {
429 writeSettings();
430 updateLabels();
431 }
432}
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700433
Zhenkai Zhu3a008fc2012-06-08 17:36:39 -0700434void
435ChatDialog::iconActivated(QSystemTrayIcon::ActivationReason reason)
436{
437 switch (reason)
438 {
439 case QSystemTrayIcon::Trigger:
440 case QSystemTrayIcon::DoubleClick:
441 break;
442 case QSystemTrayIcon::MiddleClick:
443 // showMessage();
444 break;
445 default:;
446 }
447}
448
449void
450ChatDialog::showMessage(QString from, QString data)
451{
452 // std::cout <<"Showing Message: " << from.toStdString() << ": " << data.toStdString() << std::endl;
453 if (!isActiveWindow())
454 {
455 trayIcon->showMessage(QString("Chatroom %1 has a new message").arg(m_user.getChatroom()), QString("<%1>: %2").arg(from).arg(data), QSystemTrayIcon::Information, 20000);
456 trayIcon->setIcon(QIcon(":/images/note.png"));
457 }
458}
459
460void
461ChatDialog::messageClicked()
462{
463 this->showMaximized();
464}
465
466void
467ChatDialog::createActions()
468{
469 minimizeAction = new QAction(tr("Mi&nimize"), this);
470 connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
471
472 maximizeAction = new QAction(tr("Ma&ximize"), this);
473 connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
474
475 restoreAction = new QAction(tr("&Restore"), this);
476 connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
477
478 quitAction = new QAction(tr("Quit"), this);
479 connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
480}
481
482void
483ChatDialog::createTrayIcon()
484{
485 trayIconMenu = new QMenu(this);
486 trayIconMenu->addAction(minimizeAction);
487 trayIconMenu->addAction(maximizeAction);
488 trayIconMenu->addAction(restoreAction);
489 trayIconMenu->addSeparator();
490 trayIconMenu->addAction(quitAction);
491
492 trayIcon = new QSystemTrayIcon(this);
493 trayIcon->setContextMenu(trayIconMenu);
494
495 QIcon icon(":/images/icon_small.png");
496 trayIcon->setIcon(icon);
497 setWindowIcon(icon);
498 trayIcon->setToolTip("Sync-Demo System Tray Icon");
499 trayIcon->setVisible(true);
500}
501
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700502void
503ChatDialog::resizeEvent(QResizeEvent *e)
504{
505 fitView();
506}
507
508void
509ChatDialog::showEvent(QShowEvent *e)
510{
511 fitView();
512}
513
514void
515ChatDialog::fitView()
516{
Zhenkai Zhu44b43752012-06-05 21:18:37 -0700517 boost::mutex::scoped_lock lock(m_sceneMutex);
Zhenkai Zhu21d75f92012-06-04 21:23:34 -0700518 QRectF rect = m_scene->itemsBoundingRect();
519 m_scene->setSceneRect(rect);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700520 treeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700521}