00001
00002
00003
00004
00005
00006
00007 #include "SimpleChatWidget.h"
00008 #include "SimpleChatServer.h"
00009
00010 #include <Wt/WApplication>
00011 #include <Wt/WContainerWidget>
00012 #include <Wt/WHBoxLayout>
00013 #include <Wt/WVBoxLayout>
00014 #include <Wt/WLabel>
00015 #include <Wt/WLineEdit>
00016 #include <Wt/WText>
00017 #include <Wt/WTextArea>
00018 #include <Wt/WPushButton>
00019
00020 #include <iostream>
00021
00022 using namespace Wt;
00023
00024 SimpleChatWidget::SimpleChatWidget(SimpleChatServer& server,
00025 Wt::WContainerWidget *parent)
00026 : WContainerWidget(parent),
00027 server_(server),
00028 app_(WApplication::instance())
00029 {
00030 user_ = server_.suggestGuest();
00031 letLogin();
00032
00033 app_->enableUpdates();
00034 }
00035
00036 SimpleChatWidget::~SimpleChatWidget()
00037 {
00038 logout();
00039 }
00040
00041 void SimpleChatWidget::letLogin()
00042 {
00043 clear();
00044
00045 WVBoxLayout *vLayout = new WVBoxLayout();
00046 setLayout(vLayout, AlignLeft | AlignTop);
00047
00048 WHBoxLayout *hLayout = new WHBoxLayout();
00049 vLayout->addLayout(hLayout);
00050
00051 hLayout->addWidget(new WLabel("User name:"), 0, AlignMiddle);
00052 hLayout->addWidget(userNameEdit_ = new WLineEdit(user_), 0, AlignMiddle);
00053 userNameEdit_->setFocus();
00054
00055 WPushButton *b = new WPushButton("Login");
00056 hLayout->addWidget(b, 0, AlignMiddle);
00057 hLayout->addStretch(1);
00058
00059 b->clicked().connect(SLOT(this, SimpleChatWidget::login));
00060 userNameEdit_->enterPressed().connect(SLOT(this, SimpleChatWidget::login));
00061
00062 vLayout->addWidget(statusMsg_ = new WText());
00063 statusMsg_->setTextFormat(PlainText);
00064 }
00065
00066 void SimpleChatWidget::login()
00067 {
00068 WString name = WWebWidget::escapeText(userNameEdit_->text());
00069
00070 if (!startChat(name))
00071 statusMsg_->setText("Sorry, name '" + name + "' is already taken.");
00072 }
00073
00074 void SimpleChatWidget::logout()
00075 {
00076 if (eventConnection_.connected()) {
00077 eventConnection_.disconnect();
00078 server_.logout(user_);
00079
00080 letLogin();
00081 }
00082 }
00083
00084 bool SimpleChatWidget::startChat(const WString& user)
00085 {
00086 if (server_.login(user)) {
00087 eventConnection_
00088 = server_.chatEvent().connect(SLOT(this,
00089 SimpleChatWidget::processChatEvent));
00090 user_ = user;
00091
00092 clear();
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 WVBoxLayout *vLayout = new WVBoxLayout();
00113
00114
00115 WHBoxLayout *hLayout = new WHBoxLayout();
00116
00117
00118 hLayout->addWidget(messages_ = new WContainerWidget(), 1);
00119 messages_->setStyleClass("chat-msgs");
00120
00121 messages_->setOverflow(WContainerWidget::OverflowAuto);
00122
00123
00124 hLayout->addWidget(userList_ = new WContainerWidget());
00125 userList_->setStyleClass("chat-users");
00126 userList_->setOverflow(WContainerWidget::OverflowAuto);
00127
00128
00129 vLayout->addLayout(hLayout, 1);
00130
00131
00132 vLayout->addWidget(messageEdit_ = new WTextArea());
00133 messageEdit_->setStyleClass("chat-noedit");
00134 messageEdit_->setRows(2);
00135 messageEdit_->setFocus();
00136
00137
00138 hLayout = new WHBoxLayout();
00139
00140
00141 hLayout->addWidget(sendButton_ = new WPushButton("Send"));
00142 WPushButton *b;
00143
00144
00145 hLayout->addWidget(b = new WPushButton("Logout"));
00146
00147
00148 hLayout->addStretch(1);
00149
00150
00151 vLayout->addLayout(hLayout);
00152
00153 setLayout(vLayout);
00154
00155
00156
00157
00158 sendButton_->clicked().connect(SLOT(sendButton_, WPushButton::disable));
00159 sendButton_->clicked().connect(SLOT(messageEdit_, WTextArea::disable));
00160 sendButton_->clicked().connect(SLOT(this, SimpleChatWidget::send));
00161
00162 messageEdit_->enterPressed().connect
00163 (SLOT(sendButton_, WPushButton::disable));
00164 messageEdit_->enterPressed().connect
00165 (SLOT(messageEdit_, WTextArea::disable));
00166 messageEdit_->enterPressed().connect
00167 (SLOT(this, SimpleChatWidget::send));
00168
00169 b->clicked().connect(SLOT(this, SimpleChatWidget::logout));
00170
00171 WText *msg = new WText
00172 ("<div><span class='chat-info'>You are joining the conversation as "
00173 + user_ + "</span></div>", messages_);
00174 msg->setStyleClass("chat-msg");
00175
00176 updateUsers();
00177
00178 return true;
00179 } else
00180 return false;
00181 }
00182
00183 void SimpleChatWidget::send()
00184 {
00185 if (!messageEdit_->text().empty()) {
00186 server_.sendMessage(user_, messageEdit_->text());
00187 messageEdit_->setText("");
00188 }
00189
00190 messageEdit_->enable();
00191 messageEdit_->setFocus();
00192 sendButton_->enable();
00193 }
00194
00195 void SimpleChatWidget::updateUsers()
00196 {
00197 userList_->clear();
00198
00199 SimpleChatServer::UserSet users = server_.users();
00200
00201 WString usersStr;
00202
00203 for (SimpleChatServer::UserSet::iterator i = users.begin();
00204 i != users.end(); ++i) {
00205 if (*i == user_)
00206 usersStr += "<div><span class='chat-self'>" + *i + "</span></div>";
00207 else
00208 usersStr += "<div>" + *i + "</div>";
00209 }
00210
00211 userList_->addWidget(new WText(usersStr));
00212 }
00213
00214 void SimpleChatWidget::processChatEvent(const ChatEvent& event)
00215 {
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 WApplication::UpdateLock lock = app_->getUpdateLock();
00226
00227 WText *w = new WText(event.formattedHTML(user_), messages_);
00228 w->setInline(false);
00229 w->setStyleClass("chat-msg");
00230
00231
00232 if (messages_->count() > 100)
00233 delete messages_->children()[0];
00234
00235 if (event.type() != ChatEvent::Message)
00236 updateUsers();
00237
00238
00239
00240
00241 app_->doJavaScript(messages_->jsRef() + ".scrollTop += "
00242 + messages_->jsRef() + ".scrollHeight;");
00243
00244 app_->triggerUpdate();
00245 }