#include "precomp.h" #include "chatview.h" #include "chat.h" #include "ircconnection.h" ///////////////////////////////////////////////////////////////////////////// // ChatView construction: ChatView::ChatView(IRCConnection *connection, const std::string &filter, MainFrame *mainframe) : View(mainframe, filter.empty() ? "Status" : filter), chat(0), inputbox(0), userlist(0), connection(connection) { chat = new Chat(connection, filter, this); inputbox = new CL_InputBox(this); userlist = new CL_ListBox(this); inputbox->set_focus(); // Only show userlist for channels: if (filter.substr(0, 1) != "#") userlist->show(false); slots.connect(sig_resize(), this, &ChatView::on_resize); slots.connect(sig_paint(), this, &ChatView::on_paint); slots.connect(inputbox->sig_return_pressed(), this, &ChatView::on_inputbox_return_pressed); slots.connect(inputbox->sig_changed(), this, &ChatView::on_inputbox_changed); slots.connect(userlist->sig_activated(), this, &ChatView::on_userlist_activated); slots.connect(userlist->sig_key_up(), this, &ChatView::on_userlist_key_up); slots.connect(userlist->sig_mouse_up(), this, &ChatView::on_userlist_mouse_up); slots.connect(connection->sig_numeric_reply(), this, &ChatView::on_connection_numeric_reply); slots.connect(connection->sig_nick(), this, &ChatView::on_connection_nick); slots.connect(connection->sig_join(), this, &ChatView::on_connection_join); slots.connect(connection->sig_part(), this, &ChatView::on_connection_part); } ChatView::~ChatView() { } ///////////////////////////////////////////////////////////////////////////// // ChatView attributes: ///////////////////////////////////////////////////////////////////////////// // ChatView operations: ///////////////////////////////////////////////////////////////////////////// // ChatView implementation: void ChatView::on_resize(int old_width, int old_height) { int inputbox_height = 16; int userlist_width = 150; if (userlist->is_visible() == false) userlist_width = 0; chat->set_position(CL_Rect(0, 0, get_width()-userlist_width, get_height()-inputbox_height)); userlist->set_position(CL_Rect(get_width()-userlist_width, 0, get_width(), get_height()-inputbox_height)); inputbox->set_position(CL_Rect(0, get_height()-inputbox_height, get_width(), get_height())); } void ChatView::on_paint() { } void ChatView::on_inputbox_return_pressed() { std::string command_line = inputbox->get_text(); if (command_line.empty()) return; if (command_line[0] != '/') // not a command { connection->send_privmsg(chat->get_filter(), command_line); chat->add_line(connection->get_nick(), command_line, chat->color_text); } else // its a command { std::vector args = CL_String::tokenize(command_line, " "); if (args[0] == "/nick") { if (args.size() > 1) { connection->send_nick(args[1]); } } else if (args[0] == "/oper") { // void send_oper(const std::string &user, const std::string &password); } else if (args[0] == "/quit") { if (args.size() == 1) { connection->send_quit("ClanLib - the biggest overkill library ever written for an IRC client!"); } else if (args.size() >= 2) { std::string reason; for (unsigned int i=1; i 1) reason += " "; reason += args[i]; } connection->send_quit(reason); } quit(); } else if (args[0] == "/join") { if (args.size() == 2) { connection->send_join(args[1]); } else if (args.size() == 3) { connection->send_join(args[1], args[2]); } else { chat->add_line("syntax: /join [key]", chat->color_system); } } else if (args[0] == "/part") { if (args.size() == 2) { connection->send_part(args[1]); } else if (args.size() >= 3) { std::string reason; for (unsigned int i=2; i 2) reason += " "; reason += args[i]; } connection->send_part(args[1], reason); } else { chat->add_line("syntax: /part [reason]", chat->color_system); } } else if (args[0] == "/mode") { if (args.size() >= 3) { std::vector remaining_args; for (unsigned int i=3; isend_mode(args[1], args[2], remaining_args); } else { chat->add_line("syntax: /mode [args]", chat->color_system); } } else if (args[0] == "/topic") { if (args.size() == 2) { connection->send_topic(args[1]); } else if (args.size() > 2) { std::string new_topic; for (unsigned int i=2; i 2) new_topic += " "; new_topic += args[i]; } connection->send_topic(args[1], new_topic); } else { chat->add_line("syntax: /topic [new topic]", chat->color_system); } } else if (args[0] == "/names") { if (args.size() == 2) { connection->send_names(args[1]); } else { chat->add_line("syntax: /names ", chat->color_system); } } else if (args[0] == "/list") { if (args.size() == 1) { connection->send_list(); } else if (args.size() == 2) { connection->send_list(args[1]); } else if (args.size() == 3) { connection->send_list(args[1], args[2]); } else { chat->add_line("syntax: /list [channel] [server]", chat->color_system); } } else if (args[0] == "/invite") { if (args.size() == 3) { connection->send_invite(args[1], args[2]); } else { chat->add_line("syntax: /invite ", chat->color_system); } } else if (args[0] == "/kick") { if (args.size() >= 3) { std::string comment; for (unsigned int i=2; i 2) comment += " "; comment += args[i]; } connection->send_kick(args[1], args[2], comment); } else { chat->add_line("syntax: /kick [comment]", chat->color_system); } } else if (args[0] == "/send_version") { if (args.size() == 1) { connection->send_version(); } else if (args.size() == 2) { connection->send_version(args[1]); } else { chat->add_line("syntax: /send_version [server]", chat->color_system); } } else if (args[0] == "/stats") { if (args.size() == 1) { connection->send_stats(); } else if (args.size() == 2) { connection->send_stats(args[1]); } else if (args.size() == 3) { connection->send_stats(args[1], args[2]); } else { chat->add_line("syntax: /stats [query] [server]", chat->color_system); } } else if (args[0] == "/links") { if (args.size() == 1) { connection->send_links(); } else if (args.size() == 2) { connection->send_links(args[1]); } else if (args.size() == 3) { connection->send_links(args[1], args[2]); } else { chat->add_line("syntax: /links [remote server] [server mask]", chat->color_system); } } else if (args[0] == "/send_time") { if (args.size() == 1) { connection->send_time(); } else if (args.size() == 2) { connection->send_time(args[1]); } else { chat->add_line("syntax: /send_time [server]", chat->color_system); } } else if (args[0] == "/connect") { if (args.size() == 2) { connection->send_connect(args[1]); } else if (args.size() == 3) { connection->send_connect(args[1], CL_String::to_int(args[2])); } else if (args.size() == 4) { connection->send_connect(args[1], CL_String::to_int(args[2]), args[3]); } else { chat->add_line("syntax: /connect [port] [remote server]", chat->color_system); } } else if (args[0] == "/trace") { if (args.size() == 1) { connection->send_trace(); } else if (args.size() == 2) { connection->send_trace(args[1]); } else { chat->add_line("syntax: /trace [server]", chat->color_system); } } else if (args[0] == "/admin") { if (args.size() == 1) { connection->send_admin(""); } else if (args.size() == 2) { connection->send_admin(args[1]); } else { chat->add_line("syntax: /admin [server]", chat->color_system); } } else if (args[0] == "/info") { if (args.size() == 1) { connection->send_info(); } else if (args.size() == 2) { connection->send_info(args[1]); } else { chat->add_line("syntax: /info [server]", chat->color_system); } } else if (args[0] == "/privmsg") { if (args.size() >= 2) { std::string text; for (unsigned int i=2; i 2) text += " "; text += args[i]; } connection->send_privmsg(args[1], text); } else { chat->add_line("syntax: /privmsg ", chat->color_system); } } else if (args[0] == "/ctcp" || args[0] == "/privmsg_ctcp") { if (args.size() >= 3) { std::string data; for (unsigned int i=3; i 3) data += " "; data += args[i]; } connection->send_privmsg_ctcp(args[1], args[2], data); } else { chat->add_line("syntax: /ctcp [data]", chat->color_system); } } else if (args[0] == "/notice") { if (args.size() >= 2) { std::string text; for (unsigned int i=2; i 2) text += " "; text += args[i]; } connection->send_notice(args[1], text); } else { chat->add_line("syntax: /notice ", chat->color_system); } } else if (args[0] == "/notice_ctcp") { if (args.size() >= 3) { std::string data; for (unsigned int i=3; i 3) data += " "; data += args[i]; } connection->send_notice_ctcp(args[1], args[2], data); } else { chat->add_line("syntax: /notice_ctcp [data]", chat->color_system); } } else if (args[0] == "/who") { if (args.size() == 2) { connection->send_who(args[1]); } else if (args.size() == 3) { connection->send_who(args[1], args[2] == "true"); } else { chat->add_line("syntax: /whois [oper = false]", chat->color_system); } } else if (args[0] == "/whois") { if (args.size() == 2) { connection->send_whois(args[1]); } else if (args.size() == 3) { connection->send_whois(args[1], args[2]); } else { chat->add_line("syntax: /whois ", chat->color_system); chat->add_line("syntax: /whois ", chat->color_system); } } else if (args[0] == "/whowas") { if (args.size() == 2) { connection->send_whowas(args[1]); } else if (args.size() == 3) { connection->send_whowas(args[1], CL_String::to_int(args[2])); } else if (args.size() == 4) { connection->send_whowas(args[1], CL_String::to_int(args[2]), args[3]); } else { chat->add_line("syntax: /whowas [count] [server]", chat->color_system); } } else if (args[0] == "/kill") { if (args.size() >= 3) { std::string text; for (unsigned int i=2; i 2) text += " "; text += args[i]; } connection->send_kill(args[1], text); } else { chat->add_line("syntax: /kill ", chat->color_system); } } else if (args[0] == "/me" || args[0] == "/action") { std::string text; for (std::string::size_type i=1; i 1) text += " "; text += args[i]; } connection->send_privmsg_ctcp(chat->get_filter(), "ACTION", text); chat->add_line(std::string("*CTalk ")+text, chat->color_text); } else if (args[0] == "/dcc") { } else if (args[0] == "/finger") { if (args.size() == 2) { connection->send_privmsg_ctcp(args[1], "FINGER", std::string()); } else { chat->add_line("syntax: /finger ", chat->color_system); } } else if (args[0] == "/version") { if (args.size() == 2) { connection->send_privmsg_ctcp(args[1], "VERSION", std::string()); } else { chat->add_line("syntax: /version ", chat->color_system); } } else if (args[0] == "/userinfo") { if (args.size() == 2) { connection->send_privmsg_ctcp(args[1], "USERINFO", std::string()); } else { chat->add_line("syntax: /userinfo ", chat->color_system); } } else if (args[0] == "/clientinfo") { if (args.size() == 2) { connection->send_privmsg_ctcp(args[1], "CLIENTINFO", std::string()); } else { chat->add_line("syntax: /clientinfo ", chat->color_system); } } else if (args[0] == "/ping") { if (args.size() == 2) { connection->send_privmsg_ctcp(args[1], "PING", CL_String::from_int(CL_System::get_time())); } else { chat->add_line("syntax: /ping ", chat->color_system); } } else if (args[0] == "/time") { if (args.size() == 2) { connection->send_privmsg_ctcp(args[1], "TIME", std::string()); } else { chat->add_line("syntax: /time ", chat->color_system); } } } inputbox->set_text(""); connection->send_type_packet(chat->get_filter(), ""); } void ChatView::on_inputbox_changed(const std::string &text) { //why was this sending a packet on every keystroke? No need. --mrfun Sep 22 2006 //connection->send_type_packet(chat->get_filter(), text); } void ChatView::on_userlist_activated(int item_id) { // todo: spawn private conversation with user } void ChatView::on_userlist_key_up(const CL_InputEvent &event) { if (event.id == CL_KEY_APPS) { on_userlist_contextmenu(); } } void ChatView::on_userlist_mouse_up(const CL_InputEvent &event) { if (event.id == CL_MOUSE_RIGHT) { on_userlist_contextmenu(); } } void ChatView::on_userlist_contextmenu() { // todo: show popup menu } void ChatView::on_connection_numeric_reply( const std::string &prefix, int command, const std::vector ¶ms) { if (command == RPL_NAMREPLY && params.size() >= 4) { std::string channel = params[2]; std::string nicks = params[3]; if (channel != chat->get_filter()) return; std::vector nick_list = CL_String::tokenize(nicks, " "); for (unsigned int i=0; iinsert_item(nick); } userlist->sort(); } else if (command == RPL_ENDOFNAMES) { // hmm do we need to do anything here? } } void ChatView::on_connection_nick(const std::string &_old_nick, const std::string &_new_nick) { std::string old_nick = CL_IRCConnection::extract_nick(_old_nick); std::string new_nick = CL_IRCConnection::extract_nick(_new_nick); std::vector &items = userlist->get_items(); for (unsigned int i=0; istr == old_nick) { userlist->remove_item(i); userlist->insert_item(new_nick); userlist->sort(); return; } } } void ChatView::on_connection_join(const std::string &nick, const std::string &channel) { if (channel == chat->get_filter()) { // If its us ourselves joining a channel, clear the userlist // (we will be expecting a set of RPL commands about the users) if (CL_IRCConnection::extract_nick(nick) == connection->get_nick()) { userlist->clear(); return; } // Check if we are already in userlist: std::vector &items = userlist->get_items(); for (unsigned int i=0; istr == old_nick) { return; } } userlist->insert_item(CL_IRCConnection::extract_nick(nick)); userlist->sort(); } } void ChatView::on_connection_part(const std::string &nick, const std::string &channel, const std::string &reason) { if (channel == chat->get_filter()) { std::vector &items = userlist->get_items(); for (unsigned int i=0; istr == old_nick) { userlist->remove_item(i); return; } } } }