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_->setFormatting(WText::PlainFormatting);
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", this));
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(SLOT(sendButton_, WPushButton::disable));
00163 messageEdit_->enterPressed.connect(SLOT(messageEdit_, WTextArea::disable));
00164 messageEdit_->enterPressed.connect(SLOT(this, SimpleChatWidget::send));
00165
00166 b->clicked.connect(SLOT(this, SimpleChatWidget::logout));
00167
00168 WText *msg
00169 = new WText(false,
00170 "<span class='chat-info'>You are joining the conversation as "
00171 + user_ + "</span>", messages_);
00172 msg->setStyleClass("chat-msg");
00173
00174 updateUsers();
00175
00176 return true;
00177 } else
00178 return false;
00179 }
00180
00181 void SimpleChatWidget::send()
00182 {
00183 if (!messageEdit_->text().empty()) {
00184 server_.sendMessage(user_, messageEdit_->text());
00185 messageEdit_->setText("");
00186 }
00187
00188 messageEdit_->enable();
00189 messageEdit_->setFocus();
00190 sendButton_->enable();
00191 }
00192
00193 void SimpleChatWidget::updateUsers()
00194 {
00195 userList_->clear();
00196
00197 SimpleChatServer::UserSet users = server_.users();
00198
00199 WString usersStr;
00200
00201 for (SimpleChatServer::UserSet::iterator i = users.begin();
00202 i != users.end(); ++i) {
00203 if (*i == user_)
00204 usersStr += "<span class='chat-self'>" + *i + "</span><br />";
00205 else
00206 usersStr += *i + "<br />";
00207 }
00208
00209 userList_->addWidget(new WText(false, usersStr));
00210 }
00211
00212 void SimpleChatWidget::processChatEvent(const ChatEvent& event)
00213 {
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 WApplication::UpdateLock lock = app_->getUpdateLock();
00224
00225 WText *w = new WText(false, event.formattedHTML(user_), messages_);
00226 w->setStyleClass("chat-msg");
00227
00228
00229 if (messages_->count() > 100)
00230 delete messages_->children()[0];
00231
00232 if (event.type() != ChatEvent::Message)
00233 updateUsers();
00234
00235
00236
00237
00238 app_->doJavaScript(messages_->jsRef() + ".scrollTop += "
00239 + messages_->jsRef() + ".scrollHeight;");
00240
00241 app_->triggerUpdate();
00242 }