blob: 10c7af0bcfd647372735c14055d416bebb204cb4 [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 Zhu6d589aa2012-05-29 17:34:35 -07007
Zhenkai Zhu82a62752012-06-04 17:11:04 -07008#define BROADCAST_PREFIX_FOR_SYNC_DEMO "/ndn/broadcast/sync-demo"
9
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070010ChatDialog::ChatDialog(QWidget *parent)
Zhenkai Zhu82a62752012-06-04 17:11:04 -070011 : QDialog(parent), m_sock(NULL)
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070012{
13 setupUi(this);
Zhenkai Zhu82a62752012-06-04 17:11:04 -070014 m_session = time(NULL);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -070015
16 readSettings();
Zhenkai Zhu82a62752012-06-04 17:11:04 -070017
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -070018 updateLabels();
19
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -070020 lineEdit->setFocusPolicy(Qt::StrongFocus);
Zhenkai Zhu82a62752012-06-04 17:11:04 -070021 m_scene = new DigestTreeScene(this);
Zhenkai Zhub45e38a2012-06-01 15:44:36 -070022
Zhenkai Zhu82a62752012-06-04 17:11:04 -070023 treeViewer->setScene(m_scene);
24 m_scene->plot("Empty");
25 QRectF rect = m_scene->itemsBoundingRect();
26 m_scene->setSceneRect(rect);
27
28 // create sync socket
29 if(!m_user.getChatroom().isEmpty()) {
30 std::string syncPrefix = BROADCAST_PREFIX_FOR_SYNC_DEMO;
31 syncPrefix += "/";
32 syncPrefix += m_user.getChatroom().toStdString();
33 m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdate, this, _1, _2), bind(&ChatDialog::processRemove, this, _1));
34 }
Zhenkai Zhub45e38a2012-06-01 15:44:36 -070035
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070036 connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
Zhenkai Zhu85845d22012-06-01 23:10:43 -070037 connect(setButton, SIGNAL(pressed()), this, SLOT(buttonPressed()));
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070038}
39
Zhenkai Zhu82a62752012-06-04 17:11:04 -070040ChatDialog::~ChatDialog()
41{
42 if (m_sock != NULL)
43 {
44 delete m_sock;
45 m_sock = NULL;
46 }
47}
48
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070049void
50ChatDialog::appendMessage(const SyncDemo::ChatMessage &msg)
51{
Zhenkai Zhub6338822012-05-31 13:27:24 -070052
53 if (msg.type() != SyncDemo::ChatMessage::CHAT) {
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070054 return;
Zhenkai Zhub6338822012-05-31 13:27:24 -070055 }
56
57 if (!msg.has_data()) {
58 return;
59 }
60
61 if (msg.from().empty() || msg.data().empty()) {
62 return;
63 }
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070064
65 QTextCursor cursor(textEdit->textCursor());
66 cursor.movePosition(QTextCursor::End);
67 QTextTableFormat tableFormat;
68 tableFormat.setBorder(0);
69 QTextTable *table = cursor.insertTable(1, 2, tableFormat);
Zhenkai Zhub6338822012-05-31 13:27:24 -070070 QString from = QString("<%1>: ").arg(msg.from().c_str());
71 table->cellAt(0, 0).firstCursorPosition().insertText(from);
72 table->cellAt(0, 1).firstCursorPosition().insertText(msg.data().c_str());
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -070073 QScrollBar *bar = textEdit->verticalScrollBar();
74 bar->setValue(bar->maximum());
75}
76
Zhenkai Zhu85845d22012-06-01 23:10:43 -070077void
Zhenkai Zhu82a62752012-06-04 17:11:04 -070078ChatDialog::processTreeUpdate(const std::vector<Sync::MissingDataInfo> &v, Sync::SyncAppSocket *)
79{
80 if (v.empty())
81 {
82 return;
83 }
84
85 // reflect the changes on digest tree
86 m_scene->processUpdate(v, m_sock->getRootDigest().c_str());
87
88 int n = v.size();
89 int totalMissingPackets = 0;
90 for (int i = 0; i < n; i++)
91 {
92 totalMissingPackets += v[i].high.getSeq() - v[i].low.getSeq() + 1;
93 }
94
95 if (totalMissingPackets < 10) {
96 for (int i = 0; i < n; i++)
97 {
98 for (Sync::SeqNo seq = v[i].low; seq <= v[i].high; ++seq)
99 {
100 m_sock->fetchRaw(v[i].prefix, seq, bind(&ChatDialog::processData, this, _1, _2, _3), 2);
101 }
102 }
103 }
104 else
105 {
106 // too bad; too many missing packets
107 // we may just join a new chatroom
108 // or some network patition just healed
109 // we don't try to fetch any data in this case (for now)
110 }
111
112 // adjust the view
113 fitView();
114
115}
116
117void
118ChatDialog::processData(std::string name, const char *buf, size_t len)
119{
120 SyncDemo::ChatMessage msg;
121 if (!msg.ParseFromArray(buf, len))
122 {
123 std::cerr << "Errrrr.. Can not parse msg at "<<__FILE__ <<":"<<__LINE__<<". what is happening?" << std::endl;
124 abort();
125 }
126
127 // display
128 appendMessage(msg);
129
130 // update the tree view
131 std::string prefix = name.substr(0, name.find_last_of('/'));
132 m_scene->msgReceived(prefix.c_str(), msg.from().c_str());
133}
134
135void
136ChatDialog::processRemove(std::string prefix)
137{
138}
139
140void
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700141ChatDialog::formChatMessage(const QString &text, SyncDemo::ChatMessage &msg) {
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700142 msg.set_from(m_user.getNick().toStdString());
143 msg.set_to(m_user.getChatroom().toStdString());
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700144 msg.set_data(text.toStdString());
145 time_t seconds = time(NULL);
146 msg.set_timestamp(seconds);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700147 msg.set_type(SyncDemo::ChatMessage::CHAT);
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700148}
149
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700150bool
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700151ChatDialog::readSettings()
152{
153 QSettings s(ORGANIZATION, APPLICATION);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700154 QString nick = s.value("nick", "").toString();
155 QString chatroom = s.value("chatroom", "").toString();
156 QString prefix = s.value("prefix", "").toString();
157 if (nick == "" || chatroom == "" || prefix == "") {
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700158 QTimer::singleShot(500, this, SLOT(buttonPressed()));
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700159 return false;
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700160 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700161 else {
162 m_user.setNick(nick);
163 m_user.setChatroom(chatroom);
164 m_user.setPrefix(prefix);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700165 return true;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700166 }
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700167}
168
169void
170ChatDialog::writeSettings()
171{
172 QSettings s(ORGANIZATION, APPLICATION);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700173 s.setValue("nick", m_user.getNick());
174 s.setValue("chatroom", m_user.getChatroom());
175 s.setValue("prefix", m_user.getPrefix());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700176}
177
178void
179ChatDialog::updateLabels()
180{
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700181 QString settingDisp = QString("<User: %1>, <Chatroom: %2>").arg(m_user.getNick()).arg(m_user.getChatroom());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700182 infoLabel->setText(settingDisp);
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700183 QString prefixDisp = QString("<Prefix: %1>").arg(m_user.getPrefix());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700184 prefixLabel->setText(prefixDisp);
185}
186
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700187void
188ChatDialog::returnPressed()
189{
190 QString text = lineEdit->text();
191 if (text.isEmpty())
192 return;
193
Zhenkai Zhub6338822012-05-31 13:27:24 -0700194 lineEdit->clear();
195
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700196 SyncDemo::ChatMessage msg;
197 formChatMessage(text, msg);
198
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700199 appendMessage(msg);
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700200
201 // send msg
202 size_t size = msg.ByteSize();
203 char *buf = new char[size];
204 msg.SerializeToArray(buf, size);
205 if (!msg.IsInitialized())
206 {
207 std::cerr << "Errrrr.. msg was not probally initialized "<<__FILE__ <<":"<<__LINE__<<". what is happening?" << std::endl;
208 abort();
209 }
210 m_sock->publishRaw(m_user.getPrefix().toStdString(), m_session, buf, size, 60);
Zhenkai Zhub6338822012-05-31 13:27:24 -0700211
Zhenkai Zhu5a8d5aa2012-05-30 21:25:23 -0700212}
213
214void
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700215ChatDialog::buttonPressed()
216{
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700217 SettingDialog dialog(this, m_user.getNick(), m_user.getChatroom(), m_user.getPrefix());
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700218 connect(&dialog, SIGNAL(updated(QString, QString, QString)), this, SLOT(settingUpdated(QString, QString, QString)));
Zhenkai Zhu85845d22012-06-01 23:10:43 -0700219 dialog.exec();
Zhenkai Zhu6d589aa2012-05-29 17:34:35 -0700220}
Zhenkai Zhue08afe02012-05-31 15:49:07 -0700221
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700222void
223ChatDialog::settingUpdated(QString nick, QString chatroom, QString prefix)
224{
225 bool needWrite = false;
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700226 if (!nick.isEmpty() && nick != m_user.getNick()) {
227 m_user.setNick(nick);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700228 needWrite = true;
229 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700230 if (!prefix.isEmpty() && prefix != m_user.getPrefix()) {
231 m_user.setPrefix(prefix);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700232 needWrite = true;
233 // TODO: set the previous prefix as left?
234 }
Zhenkai Zhu71b42cb2012-06-04 09:42:53 -0700235 if (!chatroom.isEmpty() && chatroom != m_user.getChatroom()) {
236 m_user.setChatroom(chatroom);
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700237 needWrite = true;
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700238
239 m_scene->clearAll();
240 m_scene->plot("Empty");
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700241 // TODO: perhaps need to do a lot. e.g. use a new SyncAppSokcet
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700242 if (m_sock != NULL)
243 {
244 delete m_sock;
245 m_sock = NULL;
246 }
247 std::string syncPrefix = BROADCAST_PREFIX_FOR_SYNC_DEMO;
248 syncPrefix += "/";
249 syncPrefix += m_user.getChatroom().toStdString();
250 m_sock = new Sync::SyncAppSocket(syncPrefix, bind(&ChatDialog::processTreeUpdate, this, _1, _2), bind(&ChatDialog::processRemove, this, _1));
251
252 fitView();
253
Zhenkai Zhu7e9b06d2012-06-02 00:44:42 -0700254 }
255 if (needWrite) {
256 writeSettings();
257 updateLabels();
258 }
259}
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700260
261void
262ChatDialog::resizeEvent(QResizeEvent *e)
263{
264 fitView();
265}
266
267void
268ChatDialog::showEvent(QShowEvent *e)
269{
270 fitView();
271}
272
273void
274ChatDialog::fitView()
275{
Zhenkai Zhu82a62752012-06-04 17:11:04 -0700276 treeViewer->fitInView(m_scene->itemsBoundingRect(), Qt::KeepAspectRatio);
Zhenkai Zhud13acd02012-06-04 15:25:20 -0700277}