/* * vim: softtabstop=4 shiftwidth=4 cindent foldmethod=marker expandtab * * $LastChangedDate$ * $Revision$ * $LastChangedBy$ * $URL$ * * Copyright 2009-2011 Eric Connell * * This file is part of Mangler. * * Mangler is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Mangler is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Mangler. If not, see . */ #include "mangler.h" #include "manglerchat.h" #include "manglersettings.h" #include "manglerconfig.h" #include "manglercharset.h" ManglerChat::ManglerChat(Glib::RefPtr builder) {/*{{{*/ this->builder = builder; builder->get_widget("chatWindow", chatWindow); chatWindow->signal_show().connect(sigc::mem_fun(this, &ManglerChat::chatWindow_show_cb)); chatWindow->signal_hide().connect(sigc::mem_fun(this, &ManglerChat::chatWindow_hide_cb)); builder->get_widget("chatMessage", chatMessage); chatMessage->signal_activate().connect(sigc::mem_fun(this, &ManglerChat::chatMessage_activate_cb)); chatMessage->signal_key_press_event().connect(sigc::mem_fun(this, &ManglerChat::chatMessage_key_press_event_cb)); builder->get_widget("chatClear", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerChat::chatClear_clicked_cb)); builder->get_widget("chatClose", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerChat::chatClose_clicked_cb)); builder->get_widget("chatHide", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerChat::chatHide_clicked_cb)); builder->get_widget("chatUserListTreeView", chatUserListView); chatUserTreeModel = Gtk::ListStore::create(chatUserColumns); chatUserTreeModelFilter = Gtk::TreeModelFilter::create(chatUserTreeModel); chatUserTreeModelFilter->set_visible_func( sigc::mem_fun(*this, &ManglerChat::filterVisible) ); chatUserListView->set_model(chatUserTreeModelFilter); chatUserListView->append_column("Name", chatUserColumns.name); builder->get_widget("chatTimestampCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerChat::chatTimestampCheckButton_toggled_cb)); builder->get_widget("chatBox", chatBox); histCount = 0; histPos = 0; isOpen = false; isJoined = false; }/*}}}*/ void ManglerChat::chatTimestampCheckButton_toggled_cb(void) {/*{{{*/ builder->get_widget("chatTimestampCheckButton", checkbutton); Mangler::config["ChatTimestamps"] = checkbutton->get_active(); Mangler::config.config.save(); }/*}}}*/ void ManglerChat::chatWindow_show_cb(void) {/*{{{*/ isOpen = true; if (v3_is_loggedin() && !isJoined) { v3_join_chat(); isJoined = true; } chatMessage->grab_focus(); builder->get_widget("chatTimestampCheckButton", checkbutton); checkbutton->set_active(Mangler::config["ChatTimestamps"].toBool()); }/*}}}*/ void ManglerChat::chatWindow_hide_cb(void) {/*{{{*/ isOpen = false; }/*}}}*/ void ManglerChat::chatMessage_activate_cb(void) {/*{{{*/ if (chatMessage->get_text_length()) { histEntry[histCount] = chatMessage->get_text(); histEntry[histPos = ++histCount] = ""; v3_send_chat_message((char *)ustring_to_c(chatMessage->get_text()).c_str()); chatMessage->set_text(""); } }/*}}}*/ bool ManglerChat::chatMessage_key_press_event_cb(GdkEventKey* event) {/*{{{*/ switch (event->keyval) { case GDK_Up: if ((histIter = histEntry.find(histPos - 1)) != histEntry.end()) { if (histPos == histCount) { histEntry[histPos] = chatMessage->get_text(); } histPos--; chatMessage->set_text(histIter->second); chatMessage->set_position(histIter->second.length()); } return true; case GDK_Down: if ((histIter = histEntry.find(histPos + 1)) != histEntry.end()) { histPos++; chatMessage->set_text(histIter->second); chatMessage->set_position(histIter->second.length()); } return true; } return false; }/*}}}*/ void ManglerChat::chatClear_clicked_cb(void) {/*{{{*/ chatBox->get_buffer()->set_text(""); histEntry.clear(); histCount = 0; histPos = 0; }/*}}}*/ void ManglerChat::chatClose_clicked_cb(void) {/*{{{*/ if (v3_is_loggedin()) { v3_leave_chat(); } isJoined = false; chatWindow->hide(); }/*}}}*/ void ManglerChat::chatHide_clicked_cb(void) {/*{{{*/ chatWindow->hide(); }/*}}}*/ void ManglerChat::addMessage(Glib::ustring message) {/*{{{*/ char timestamp[200]; time_t t; struct tm *tmp; struct timeval tv; Glib::RefPtr buffer = chatBox->get_buffer(); if (Mangler::config["ChatTimestamps"].toBool()) { gettimeofday(&tv, NULL); t = tv.tv_sec; tmp = localtime(&t); if (strftime(timestamp, sizeof(timestamp), "%T", tmp) != 0) { message = "[" + Glib::ustring(timestamp) + "] " + message; } } buffer->insert(buffer->end(), message + "\n"); chatBox->scroll_to(buffer->create_mark(buffer->end()), 0.0); }/*}}}*/ Glib::ustring ManglerChat::nameFromId(uint16_t user_id) {/*{{{*/ Gtk::TreeModel::Children::iterator iter = chatUserTreeModel->children().begin(); while (iter != chatUserTreeModel->children().end()) { if (iter && (*iter)[chatUserColumns.id] == user_id) { return (*iter)[chatUserColumns.name]; } iter++; } return ""; }/*}}}*/ void ManglerChat::addChatMessage(uint16_t user_id, Glib::ustring message) {/*{{{*/ addMessage("[" + nameFromId(user_id) + "]: " + message); }/*}}}*/ void ManglerChat::addRconMessage(Glib::ustring message) {/*{{{*/ addMessage("* [RCON]: " + message); }/*}}}*/ void ManglerChat::addUser(uint16_t user_id) {/*{{{*/ if (isUserInChat(user_id)) { return; } v3_user *u; Glib::ustring name; if ((u = v3_get_user(user_id))) { name = c_to_ustring(u->name); v3_free_user(u); } else { return; } chatUserIter = chatUserTreeModel->append(); chatUserRow = *chatUserIter; chatUserRow[chatUserColumns.id] = user_id; chatUserRow[chatUserColumns.name] = name; chatUserRow[chatUserColumns.channel] = v3_get_user_channel(user_id); chatUserTreeModelFilter->refilter(); if (!isPerChannel || (v3_get_user_channel(user_id) == v3_get_user_channel(v3_get_user_id())) ) { addMessage("* " + name + " has joined the chat."); } }/*}}}*/ void ManglerChat::removeUser(uint16_t user_id) {/*{{{*/ Gtk::TreeModel::Row row; Gtk::TreeModel::Children::iterator iter = chatUserTreeModel->children().begin(); while (iter != chatUserTreeModel->children().end()) { row = *iter; uint32_t rowId = row[chatUserColumns.id]; if (rowId == user_id) { if (!isPerChannel || (v3_get_user_channel(user_id) == v3_get_user_channel(v3_get_user_id())) ) { addMessage("* " + row[chatUserColumns.name] + " has left the chat."); } chatUserTreeModel->erase(row); chatUserTreeModelFilter->refilter(); return; } iter++; } return; }/*}}}*/ bool ManglerChat::filterVisible(const Gtk::TreeIter& iter) {/*{{{*/ uint16_t theirChannel = (*iter)[chatUserColumns.channel]; if (((*iter)[chatUserColumns.id] == v3_get_user_id()) || !isPerChannel || (theirChannel == v3_get_user_channel(v3_get_user_id()))) { return true; } return false; }/*}}}*/ void ManglerChat::clear(void) {/*{{{*/ chatUserTreeModel->clear(); addMessage("*** disconnected from server"); isJoined = false; }/*}}}*/ bool ManglerChat::isUserInChat(uint16_t user_id) {/*{{{*/ Gtk::TreeModel::Row row; Gtk::TreeModel::Children::iterator iter = chatUserTreeModel->children().begin(); while (iter != chatUserTreeModel->children().end()) { row = *iter; uint32_t rowId = row[chatUserColumns.id]; if (rowId == user_id) { return true; } iter++; } return false; }/*}}}*/ void ManglerChat::updateUser(uint16_t user_id) {/*{{{*/ Gtk::TreeModel::Children::iterator iter = chatUserTreeModel->children().begin(); while (iter != chatUserTreeModel->children().end()) { if ((*iter)[chatUserColumns.id] == user_id) { (*iter)[chatUserColumns.channel] = v3_get_user_channel(user_id); return; } iter++; } return; }/*}}}*/