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/WTable>
00017 #include <Wt/WTableCell>
00018 #include <Wt/WText>
00019 #include <Wt/WTextArea>
00020 #include <Wt/WPushButton>
00021
00022 #include <iostream>
00023
00024 using namespace Wt;
00025
00026 SimpleChatWidget::SimpleChatWidget(SimpleChatServer& server,
00027 Wt::WContainerWidget *parent)
00028 : WContainerWidget(parent),
00029 server_(server),
00030 app_(WApplication::instance())
00031 {
00032 user_ = server_.suggestGuest();
00033 letLogin();
00034
00035 app_->enableUpdates();
00036 }
00037
00038 SimpleChatWidget::~SimpleChatWidget()
00039 {
00040 logout();
00041 }
00042
00043 void SimpleChatWidget::letLogin()
00044 {
00045 clear();
00046
00047 WVBoxLayout *vLayout = new WVBoxLayout();
00048 setLayout(vLayout, AlignLeft | AlignTop);
00049
00050 WHBoxLayout *hLayout = new WHBoxLayout();
00051 vLayout->addLayout(hLayout);
00052
00053 hLayout->addWidget(new WLabel("User name:"), 0, AlignMiddle);
00054 hLayout->addWidget(userNameEdit_ = new WLineEdit(user_), 0, AlignMiddle);
00055 userNameEdit_->setFocus();
00056
00057 WPushButton *b = new WPushButton("Login");
00058 hLayout->addWidget(b, 0, AlignMiddle);
00059 hLayout->addStretch(1);
00060
00061 b->clicked.connect(SLOT(this, SimpleChatWidget::login));
00062 userNameEdit_->enterPressed.connect(SLOT(this, SimpleChatWidget::login));
00063
00064 vLayout->addWidget(statusMsg_ = new WText());
00065 statusMsg_->setFormatting(WText::PlainFormatting);
00066 }
00067
00068 void SimpleChatWidget::login()
00069 {
00070 WString name = WWebWidget::escapeText(userNameEdit_->text());
00071
00072 if (!startChat(name))
00073 statusMsg_->setText("Sorry, name '" + name + "' is already taken.");
00074 }
00075
00076 void SimpleChatWidget::logout()
00077 {
00078 if (eventConnection_.connected()) {
00079 eventConnection_.disconnect();
00080 server_.logout(user_);
00081
00082 letLogin();
00083 }
00084 }
00085
00086 bool SimpleChatWidget::startChat(const WString& user)
00087 {
00088 if (server_.login(user)) {
00089 eventConnection_
00090 = server_.chatEvent.connect(SLOT(this,
00091 SimpleChatWidget::processChatEvent));
00092 user_ = user;
00093
00094 clear();
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 WVBoxLayout *vLayout = new WVBoxLayout();
00115
00116
00117 WHBoxLayout *hLayout = new WHBoxLayout();
00118
00119
00120 hLayout->addWidget(messages_ = new WContainerWidget(), 1);
00121 messages_->setStyleClass("chat-msgs");
00122
00123 messages_->setOverflow(WContainerWidget::OverflowAuto);
00124
00125
00126 hLayout->addWidget(userList_ = new WContainerWidget());
00127 userList_->setStyleClass("chat-users");
00128 userList_->setOverflow(WContainerWidget::OverflowAuto);
00129
00130
00131 vLayout->addLayout(hLayout, 1);
00132
00133
00134 vLayout->addWidget(messageEdit_ = new WTextArea());
00135 messageEdit_->setStyleClass("chat-noedit");
00136 messageEdit_->setRows(2);
00137 messageEdit_->setFocus();
00138
00139
00140 hLayout = new WHBoxLayout();
00141
00142
00143 hLayout->addWidget(sendButton_ = new WPushButton("Send"));
00144 WPushButton *b;
00145
00146
00147 hLayout->addWidget(b = new WPushButton("Logout", this));
00148
00149
00150 hLayout->addStretch(1);
00151
00152
00153 vLayout->addLayout(hLayout);
00154
00155 setLayout(vLayout);
00156
00157
00158
00159
00160 sendButton_->clicked.connect(SLOT(sendButton_, WPushButton::disable));
00161 sendButton_->clicked.connect(SLOT(messageEdit_, WTextArea::disable));
00162 sendButton_->clicked.connect(SLOT(this, SimpleChatWidget::send));
00163
00164 messageEdit_->enterPressed.connect(SLOT(sendButton_, WPushButton::disable));
00165 messageEdit_->enterPressed.connect(SLOT(messageEdit_, WTextArea::disable));
00166 messageEdit_->enterPressed.connect(SLOT(this, SimpleChatWidget::send));
00167
00168 b->clicked.connect(SLOT(this, SimpleChatWidget::logout));
00169
00170 WText *msg
00171 = new WText(false,
00172 "<span class='chat-info'>You are joining the conversation as "
00173 + user_ + "</span>", 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 += "<span class='chat-self'>" + *i + "</span><br />";
00207 else
00208 usersStr += *i + "<br />";
00209 }
00210
00211 userList_->addWidget(new WText(false, 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(false, event.formattedHTML(user_), messages_);
00228 w->setStyleClass("chat-msg");
00229
00230
00231 if (messages_->count() > 100)
00232 delete messages_->children()[0];
00233
00234 if (event.type() != ChatEvent::Message)
00235 updateUsers();
00236
00237
00238
00239
00240 app_->doJavaScript(messages_->jsRef() + ".scrollTop += "
00241 + messages_->jsRef() + ".scrollHeight;");
00242
00243 app_->triggerUpdate();
00244 }