/********************************************************************** * * FreeDoko a Doppelkopf-Game * * Copyright (C) 2001-2007 by Diether Knof and Borg Enders * * This program 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 2 of * the License, or (at your option) any later version. * * This program 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 can find this license in the file 'gpl.txt'. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Contact: * Diether Knof dknof@gmx.de * Borg Enders borg@borgsoft.de * *********************************************************************/ #include "constants.h" #ifdef USE_UI_GTKMM #ifdef USE_NETWORK #include "network.h" #include "ui.h" #include "cards.h" #include "translations.h" #include "../../network/server.h" #include "../../network/listener.h" #include "../../network/connection.h" #include "../../party/rule.h" #include "../../misc/translations.h" #include "../../misc/setting.h" #include "../../utils/string.h" #include "widgets/stock_button.h" #include "widgets/labelspinbutton.h" #include "widgets/labelentry.h" #include #include #include #include #include #include #include #ifndef OUTDATED // will be outdated when the network support is finished, // t.i. with version 0.8.0 #include #endif namespace UI_GTKMM_NS { // how long an urgency hint is shown (in milisec) unsigned const Network::URGENCY_HINT_TIMEOUT = 5000; /** ** Constructor for the model ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ Network::ConnectionModel::ConnectionModel() : Gtk::TreeModel::ColumnRecord() { this->add(this->connection); this->add(this->name); this->add(this->address); this->add(this->port); this->add(this->relation); this->add(this->type); this->add(this->incoming_bytes); this->add(this->outgoing_bytes); #ifdef POSTPHONED this->add(this->found); this->add(this->color); this->add(this->accept); #endif return ; } // Network::ConnectionModel::ConnectionModel() /** ** Constructor for the model ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ Network::LocalAddressesModel::LocalAddressesModel() : Gtk::TreeModel::ColumnRecord() { this->add(this->name); return ; } // Network::LocalAddressesModel::LocalAddressesModel() /** ** Constructor for the model ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ Network::ListenersModel::ListenersModel() : Gtk::TreeModel::ColumnRecord() { this->add(this->port); return ; } // Network::ListenersModel::ListenersModel() /** ** Constructor for the model ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 **/ Network::RuleDiffsModel::RuleDiffsModel() : Gtk::TreeModel::ColumnRecord() { this->add(this->name); this->add(this->self_value); this->add(this->other_value); return ; } // Network::RuleDiffsModel::RuleDiffsModel() /** ** Constructor ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ Network::Network(Base* const parent) : Base(parent), StickyDialog("Network"), connection_model(NULL), connection_list(), connection_rows(), connection_treeview(NULL), new_connection_container(NULL), new_connection_address(NULL), new_connection_port(NULL), connect(NULL), listeners_model(NULL), listeners_list(), listeners_treeview(NULL), new_listener_container(NULL), create_listener(NULL), listener_port(NULL), standard_listener_port(NULL), local_addresses_model(NULL), local_addresses_list(), local_addresses_treeview(NULL), rule_diffs_label(NULL), rule_diffs_model(NULL), rule_diffs_list(), rule_diffs_treeview(NULL), sender(NULL), clear_button(NULL), rule_backup(NULL) { this->ui->add_window(*this); this->init(); this->signal_realize().connect(sigc::mem_fun(*this, &Network::recreate_connections_list)); this->signal_realize().connect(sigc::mem_fun(*this, &Network::recreate_listeners_list)); this->signal_realize().connect(sigc::mem_fun(*this, &Network::recreate_local_addresses_list)); this->signal_realize().connect(sigc::mem_fun(*this, &Network::update_sensitivity)); return ; } // Network::Network(Base* const parent) /** ** Destruktor ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ Network::~Network() { return ; } // Network::~Network() /** ** create all subelements ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::init() { this->set_icon(this->ui->icon); this->ui->translations->add(*this, ::translation("~network settings")); this->set_position(Gtk::WIN_POS_CENTER_ON_PARENT); { // action area Gtk::StockButton* close_button = Gtk::manage(new Gtk::StockButton(Gtk::Stock::CLOSE, "close")); this->ui->translations->add(*close_button->label, ::translation("close")); this->add_action_widget(*close_button, Gtk::RESPONSE_CLOSE); close_button->signal_clicked().connect(sigc::mem_fun(*this, &Gtk::Widget::hide)); } // action area { // the elements this->new_connection_address = Gtk::manage(new Gtk::LabelEntry("address")); this->ui->translations->add(this->new_connection_address->get_label(), ::translation("address") + ":"); this->new_connection_port = Gtk::manage(new Gtk::LabelSpinButton("port")); #ifdef RELEASE this->new_connection_port->set_range(1024, 65535); #else this->new_connection_port->set_range(1, 65535); #endif this->new_connection_port->set_value(::Network::Server::FREEDOKO_STANDARD_PORT); this->ui->translations->add(this->new_connection_port->get_label(), ::translation("port") + ":"); #if GTKMM_VERSION_GE(2,8) this->connect = Gtk::manage(new Gtk::StockButton(Gtk::Stock::CONNECT, "connect")); #else this->connect = Gtk::manage(new Gtk::StockButton("connect")); #endif this->ui->translations->add(*this->connect->label, ::translation("connect")); } // the elements { // the connection table this->connection_model = new ConnectionModel(); this->connection_treeview = Gtk::manage(new Gtk::TreeView(Gtk::ListStore::create(*this->connection_model))); this->connection_list = Gtk::ListStore::create(*this->connection_model); this->connection_treeview = Gtk::manage(new Gtk::TreeView(this->connection_list)); this->connection_treeview->get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); this->connection_treeview->append_column("name", this->connection_model->name); this->connection_treeview->append_column("address", this->connection_model->address); this->connection_treeview->append_column("port", this->connection_model->port); this->connection_treeview->append_column("relation", this->connection_model->relation); this->connection_treeview->append_column("type", this->connection_model->type); this->connection_treeview->append_column("incoming", this->connection_model->incoming_bytes); this->connection_treeview->append_column("outgoing", this->connection_model->outgoing_bytes); } // the connection table { // the listeners table this->create_listener = Gtk::manage(new Gtk::Button("create listener")); this->ui->translations->add(*this->create_listener, ::translation("create listener")); this->listener_port = Gtk::manage(new Gtk::LabelSpinButton("port")); #ifdef RELEASE this->listener_port->set_range(1024, 65535); #else this->listener_port->set_range(1, 65535); #endif this->listener_port->set_value(::Network::Server::FREEDOKO_STANDARD_PORT); this->ui->translations->add(this->listener_port->get_label(), ::translation("port") + ":"); this->standard_listener_port = Gtk::manage(new Gtk::StockButton("standard port")); this->ui->translations->add(*this->standard_listener_port->label, ::translation("standard port")); this->listeners_model = new ListenersModel(); this->listeners_treeview = Gtk::manage(new Gtk::TreeView(Gtk::ListStore::create(*this->listeners_model))); this->listeners_list = Gtk::ListStore::create(*this->listeners_model); this->listeners_treeview = Gtk::manage(new Gtk::TreeView(this->listeners_list)); this->listeners_treeview->append_column("port", this->listeners_model->port); this->listeners_treeview->get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); } // the listeners table { // the local addresses table this->local_addresses_model = new LocalAddressesModel(); this->local_addresses_treeview = Gtk::manage(new Gtk::TreeView(Gtk::ListStore::create(*this->local_addresses_model))); this->local_addresses_list = Gtk::ListStore::create(*this->local_addresses_model); this->local_addresses_treeview = Gtk::manage(new Gtk::TreeView(this->local_addresses_list)); this->local_addresses_treeview->append_column("address", this->local_addresses_model->name); this->local_addresses_treeview->get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); } // the local addresses table { // the rule differences this->rule_diffs_model = new RuleDiffsModel(); this->rule_diffs_treeview = Gtk::manage(new Gtk::TreeView(Gtk::ListStore::create(*this->rule_diffs_model))); this->rule_diffs_list = Gtk::ListStore::create(*this->rule_diffs_model); this->rule_diffs_treeview = Gtk::manage(new Gtk::TreeView(this->rule_diffs_list)); this->rule_diffs_treeview->append_column("rule", this->rule_diffs_model->name); this->rule_diffs_treeview->append_column("self value", this->rule_diffs_model->self_value); this->rule_diffs_treeview->get_column_cell_renderer(1)->property_xalign() = 0.5; this->rule_diffs_treeview->append_column("other value", this->rule_diffs_model->other_value); this->rule_diffs_treeview->get_column_cell_renderer(2)->property_xalign() = 0.5; this->rule_diffs_treeview->get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); this->rule_diffs_treeview->get_column_cell_renderer(0)->property_is_expander() = true; this->rule_diffs_treeview->get_column_cell_renderer(1)->property_is_expander() = false; this->rule_diffs_treeview->get_column_cell_renderer(2)->property_is_expander() = false; } // the rule differences { // Layout Gtk::VBox* vbox = Gtk::manage(new Gtk::VBox(false, 2 ex)); #ifndef OUTDATED // will be outdated when the network support is finished, // t.i. with version 0.8.0 { // network support message Gtk::TextView* message = Gtk::manage(new Gtk::TextView()); message->set_editable(false); message->set_wrap_mode(Gtk::WRAP_WORD); message->set_cursor_visible(false); this->ui->translations->add(*message, ::translation("Message::network support")); vbox->pack_start(*message, false, true); } // network support message #endif { // notebook Gtk::Notebook* notebook = Gtk::manage(new Gtk::Notebook); { // connections Gtk::Label* label = Gtk::manage(new Gtk::Label("connections")); this->ui->translations->add(*label, ::translation("connections")); Gtk::VBox* vbox = Gtk::manage(new Gtk::VBox(false, 2 ex)); { // connection list Gtk::ScrolledWindow* scrolled_window = Gtk::manage(new Gtk::ScrolledWindow); scrolled_window->set_border_width(1 ex); scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); scrolled_window->add(*this->connection_treeview); scrolled_window->set_hadjustment(this->connection_treeview->property_hadjustment()); scrolled_window->set_vadjustment(this->connection_treeview->property_vadjustment()); vbox->add(*scrolled_window); } // connection list { // sender this->sender = Gtk::manage(new Gtk::Entry()); this->sender->signal_activate().connect(sigc::mem_fun(*this, &Network::send_event)); #ifndef RELEASE vbox->pack_start(*this->sender, false, true); #endif } // sender { // create connection this->new_connection_container = Gtk::manage(new Gtk::Frame); Gtk::Label* label = Gtk::manage(new Gtk::Label("new connection")); this->ui->translations->add(*label, ::translation("new connection")); static_cast(this->new_connection_container )->set_label_widget(*label); Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox(false, 1 em)); hbox->set_border_width(1 ex); hbox->add(*this->new_connection_address); hbox->add(*this->new_connection_port); hbox->add(*this->connect); this->new_connection_container->add(*hbox); vbox->pack_end(*this->new_connection_container, false, false); } // create connection notebook->append_page(*vbox, *label); } // connections { // listeners Gtk::VBox* vbox = Gtk::manage(new Gtk::VBox(false, 1 ex)); Gtk::Label* label = Gtk::manage(new Gtk::Label("listeners")); this->ui->translations->add(*label, ::translation("listeners")); Gtk::ScrolledWindow* scrolled_window = Gtk::manage(new Gtk::ScrolledWindow); scrolled_window->set_border_width(1 ex); scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); scrolled_window->add(*this->listeners_treeview); scrolled_window->set_hadjustment(this->listeners_treeview->property_hadjustment()); scrolled_window->set_vadjustment(this->listeners_treeview->property_vadjustment()); { // new listener this->new_listener_container = Gtk::manage(new Gtk::Frame); Gtk::Label* label = Gtk::manage(new Gtk::Label("new listener")); this->ui->translations->add(*label, ::translation("new listener")); static_cast(this->new_listener_container )->set_label_widget(*label); Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox(false, 1 em)); hbox->set_border_width(1 ex); hbox->add(*this->standard_listener_port); hbox->add(*this->listener_port); hbox->add(*this->create_listener); this->new_listener_container->add(*hbox); vbox->pack_end(*this->new_listener_container, false, true); } // new listener vbox->add(*scrolled_window); notebook->append_page(*vbox, *label); } // listeners { // ip addresses Gtk::Label* label = Gtk::manage(new Gtk::Label("local addresses")); this->ui->translations->add(*label, ::translation("local addresses")); Gtk::ScrolledWindow* scrolled_window = Gtk::manage(new Gtk::ScrolledWindow); scrolled_window->set_border_width(1 ex); scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); scrolled_window->add(*this->local_addresses_treeview); scrolled_window->set_hadjustment(this->local_addresses_treeview->property_hadjustment()); scrolled_window->set_vadjustment(this->local_addresses_treeview->property_vadjustment()); notebook->append_page(*scrolled_window, *label); } // ip addresses { // rule differences this->rule_diffs_label = Gtk::manage(new Gtk::Label("rule differences")); this->ui->translations->add(*this->rule_diffs_label, ::translation("rule differences")); Gtk::ScrolledWindow* scrolled_window = Gtk::manage(new Gtk::ScrolledWindow); scrolled_window->set_border_width(1 ex); scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); scrolled_window->add(*this->rule_diffs_treeview); scrolled_window->set_hadjustment(this->rule_diffs_treeview->property_hadjustment()); scrolled_window->set_vadjustment(this->rule_diffs_treeview->property_vadjustment()); notebook->append_page(*scrolled_window, *this->rule_diffs_label); } // rule differences vbox->pack_start(*notebook, true, true); } // notebook { // clear Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, 0, 0)); this->clear_button = Gtk::manage(new Gtk::StockButton(Gtk::Stock::CLEAR, "clear")); this->ui->translations->add(*this->clear_button, ::translation("clear network")); dynamic_cast(this->clear_button->get_child() )->set_border_width(1 ex / 2); alignment->add(*this->clear_button); vbox->pack_end(*alignment, false, true); } // clear this->get_vbox()->add(*vbox); } // Layout #ifdef DKNOF this->new_connection_address->get_entry().set_text("localhost"); #endif { // signals this->signal_show().connect(sigc::mem_fun(*this, &Network::update_sensitivity)); this->new_connection_address->get_entry().signal_changed().connect(sigc::mem_fun(*this, &Network::update_sensitivity)); this->new_connection_address->get_entry().signal_activate().connect(sigc::mem_fun(*this, &Network::connect_event)); this->new_connection_port->get_spin_button().signal_value_changed().connect(sigc::mem_fun(*this, &Network::update_sensitivity)); this->connect->signal_clicked().connect(sigc::mem_fun(*this, &Network::connect_event)); this->listener_port->get_spin_button().signal_value_changed().connect(sigc::mem_fun(*this, &Network::update_sensitivity)); this->standard_listener_port->signal_clicked().connect(sigc::mem_fun(*this, &Network::reset_port_event)); this->create_listener->signal_clicked().connect(sigc::mem_fun(*this, &Network::create_listener_event)); this->clear_button->signal_clicked().connect(sigc::mem_fun(*this, &Network::clear_event)); } // signals this->language_update(); this->set_default_size(4 * this->ui->cards->width(), 4 * this->ui->cards->height()); this->show_all_children(); return ; } // void Network::init() /** ** the party has opened ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.3 **/ void Network::party_open() { // check whether this is the first listener if (::server->listeners().size() != 1) return ; // create a backup of the rules this->rule_backup = new Rule(this->ui->party().rule()); this->recreate_rule_differences_list(); this->update_sensitivity(); return ; } // void Network::party_open() /** ** updates the sensitivity ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::update_sensitivity() { { // new connection this->new_connection_container->set_sensitive(!::server->has_parent_connection()); { // check that the address is not already connected this->connect->set_sensitive(true); string const& address = this->new_connection_address->get_text(); if (address.empty()) this->connect->set_sensitive(false); else { // if !(address.empty()) unsigned const port = static_cast(this->new_connection_port->get_value_as_int()); for (vector< ::Network::Connection*>::const_iterator c = ::server->connections().begin(); c != ::server->connections().end(); ++c) { if ((address == (*c)->address()) && (port == (*c)->port())) { this->connect->set_sensitive(false); break; } } // for (c \in ::server.connections()) } // if !(address.empty()) } } // new connection { // listeners list const listener_ports = ::server->ports(); this->create_listener->set_sensitive(std::find(listener_ports.begin(), listener_ports.end(), static_cast(this->listener_port->get_value_as_int())) == listener_ports.end()); } // listeners return ; } // void Network::update_sensitivity() /** ** recreates the connections list ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::recreate_connections_list() { this->connection_list->clear(); this->connection_rows.clear(); if (::game_status == GAMESTATUS::PROGRAMSTART) return ; for (vector< ::Network::Connection*>::const_iterator c = ::server->connections().begin(); c != ::server->connections().end(); ++c) { Gtk::TreeModel::Row row = *this->connection_list->append(); this->connection_rows.push_back(row); row[this->connection_model->connection] = *c; row[this->connection_model->name] = (*c)->name(); row[this->connection_model->address] = (*c)->address(); row[this->connection_model->port] = (*c)->port(); row[this->connection_model->relation] = ::translation((*c)->relation()).translation(); row[this->connection_model->type] = ::translation((*c)->type()).translation(); row[this->connection_model->incoming_bytes] = "."; row[this->connection_model->outgoing_bytes] = "."; this->update_traffic(**c); } this->update_sensitivity(); return ; } // void Network::recreate_connections_list() /** ** recreates the connections list ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 ** ** @todo all **/ void Network::recreate_listeners_list() { this->listeners_list->clear(); for (vector< ::Network::Listener*>::const_iterator l = ::server->listeners().begin(); l != ::server->listeners().end(); ++l) { Gtk::TreeModel::Row row = *this->listeners_list->append(); row[this->listeners_model->port] = static_cast((*l)->port()); } return ; } // void Network::recreate_listeners_list(); /** ** recreates the local addresses list ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::recreate_local_addresses_list() { vector const local_addresses = ::server->local_addresses(); this->local_addresses_list->clear(); for (vector::const_iterator c = local_addresses.begin(); c != local_addresses.end(); ++c) { Gtk::TreeModel::Row row = *this->local_addresses_list->append(); row[this->local_addresses_model->name] = *c; } return ; } // void Network::recreate_local_addresses_list() /** ** recreates the rule differences ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 **/ void Network::recreate_rule_differences_list() { this->rule_diffs_list->clear(); if (!this->rule_backup) { this->ui->translations->change(*this->rule_diffs_label, ::translation("rule differences")); return ; } unsigned differences = 0; for (int t = Rule::BOOL_FIRST; t <= Rule::BOOL_LAST; ++t) { if ( this->ui->party().rule()(static_cast(t)) != (*this->rule_backup)(static_cast(t)) ) { Gtk::TreeModel::Row row = *this->rule_diffs_list->append(); row[this->rule_diffs_model->name] = ::translation(static_cast(t)).translation(); row[this->rule_diffs_model->self_value] = ( (*this->rule_backup)(static_cast(t)) ? ::translation("yes").translation() : ::translation("no").translation() ); row[this->rule_diffs_model->other_value] = ( this->ui->party().rule()(static_cast(t)) ? ::translation("yes").translation() : ::translation("no").translation() ); differences += 1; } } // for (t \in Rule::TypeBool) for (int t = Rule::UNSIGNED_FIRST; t <= Rule::UNSIGNED_LAST; ++t) { if ( this->ui->party().rule()(static_cast(t)) != (*this->rule_backup)(static_cast(t)) ) { Gtk::TreeModel::Row row = *this->rule_diffs_list->append(); row[this->rule_diffs_model->name] = ::translation(static_cast(t)).translation(); row[this->rule_diffs_model->self_value] = DK::Utils::String::to_string((*this->rule_backup)(static_cast(t))); row[this->rule_diffs_model->other_value] = DK::Utils::String::to_string(this->ui->party().rule()(static_cast(t))); differences += 1; } } // for (t \in Rule::TypeUnsigned) if ( this->ui->party().rule()(Rule::COUNTING) != (*this->rule_backup)(Rule::COUNTING) ) { Gtk::TreeModel::Row row = *this->rule_diffs_list->append(); row[this->rule_diffs_model->name] = ::translation(Rule::COUNTING).translation(); row[this->rule_diffs_model->self_value] = ::translation((*this->rule_backup)(Rule::COUNTING)).translation(); row[this->rule_diffs_model->other_value] = ::translation(this->ui->party().rule()(Rule::COUNTING)).translation(); differences += 1; } this->ui->translations->change(*this->rule_diffs_label, ::translation("rule differences") + " (" + DK::Utils::String::to_string(differences) + ")"); return ; } // void Network::recreate_rule_differences_list() /** ** a rule has changed ** ** @param type type of the changed rule ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 **/ void Network::rule_update(int const type) { this->recreate_rule_differences_list(); return ; } // void Network::rule_update(int type) /** ** the port is resettet to the standard port ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::reset_port_event() { this->listener_port->set_value(::Network::Server::FREEDOKO_STANDARD_PORT); return ; } // void Network::reset_port_event() /** ** there is a new listener ** ** @param listener new listener ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 **/ void Network::network_listener_new(::Network::Listener const& listener) { this->recreate_listeners_list(); // check whether this is the first listener if (::server->listeners().size() > 1) return ; if (::game_status == GAMESTATUS::PROGRAMSTART) return ; // the first listener if ( (::server->listeners().size() == 1) && ::server->connections().empty() && (::game_status != GAMESTATUS::PROGRAMSTART)) { DEBUG_ASSERTION((this->rule_backup == NULL), "UI_GTKMM::Network::network_listener_new(listener)\n" " rule backup does already exists"); // create a backup of the rules this->rule_backup = new Rule(this->ui->party().rule()); this->recreate_rule_differences_list(); this->update_sensitivity(); } // if (first listener) return ; } // void Network::network_listener_new(::Network::Listener listener) /** ** a listener is deleted ** ** @param listener deleted listener ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 **/ void Network::network_listener_deleted(::Network::Listener const& listener) { this->recreate_listeners_list(); // if the network is 'empty' reset all if (::server->empty()) { DEBUG_ASSERTION((this->rule_backup != NULL), "UI_GTKMM::Network::network_listener_deleted(listener)\n" " rule backup is empty"); // reset the rules delete this->rule_backup; this->rule_backup = NULL; this->recreate_rule_differences_list(); this->update_sensitivity(); } // if (::server->empty()) return ; } // void Network::network_listener_deleted(::Network::Listener listener) /** ** the connection 'connection' was opened ** ** @param connection new connection ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::network_connection_new(::Network::Connection const& connection) { this->recreate_connections_list(); // the first connection if ( ::server->listeners().empty() && (::server->connections().size() == 1) && (::game_status != GAMESTATUS::PROGRAMSTART)) { DEBUG_ASSERTION((this->rule_backup == NULL), "UI_GTKMM::Network::network_connection_new(connection)\n" " rule backup does already exists"); // make a backup of the rules this->rule_backup = new Rule(this->ui->party().rule()); this->recreate_rule_differences_list(); this->update_sensitivity(); } // if (first connection) #if GTKMM_VERSION_GE(2,8) if (::setting(Setting::NETWORK_CONNECTIONS_URGENCY_HINT)) { this->set_urgency_hint(); Glib::signal_timeout().connect(sigc::mem_fun(*this, &Network::stop_urgency_hint), URGENCY_HINT_TIMEOUT); } // if (::setting(Setting::NETWORK_CONNECTIONS_URGENCY_HINT)) #endif return ; } // Network::network_connection_new(::Network::Connection connection) /** ** the connection 'connection' was changed ** ** @param connection connection that was changed ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::network_connection_changed(::Network::Connection const& connection) { this->recreate_connections_list(); #if GTKMM_VERSION_GE(2,8) if (::setting(Setting::NETWORK_CONNECTIONS_URGENCY_HINT)) { this->set_urgency_hint(); Glib::signal_timeout().connect(sigc::mem_fun(*this, &Network::stop_urgency_hint), URGENCY_HINT_TIMEOUT); } // if (::setting(Setting::NETWORK_CONNECTIONS_URGENCY_HINT)) #endif return ; } // Network::network_connection_changed(::Network::Connection connection) /** ** the connection 'connection' was deleted ** ** @param connection deleted connection ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::network_connection_deleted(::Network::Connection const& connection) { this->recreate_connections_list(); // the first connection if (::server->empty()) { DEBUG_ASSERTION((this->rule_backup != NULL), "UI_GTKMM::Network::network_connection_deleted(connection)\n" " rule backup is empty"); // reset the rules delete this->rule_backup; this->rule_backup = NULL; this->recreate_rule_differences_list(); this->update_sensitivity(); } // if (::server->empty()) #if GTKMM_VERSION_GE(2,8) if (::setting(Setting::NETWORK_CONNECTIONS_URGENCY_HINT)) { this->set_urgency_hint(); Glib::signal_timeout().connect(sigc::mem_fun(*this, &Network::stop_urgency_hint), URGENCY_HINT_TIMEOUT); } // if (::setting(Setting::NETWORK_CONNECTIONS_URGENCY_HINT)) #endif return ; } // void Network::network_connection_deleted(::Network::Connection connection) /** ** there was some network traffic ** ** @param connection the connection ** @param traffic_type the type of the traffic ** @param text the sent text ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 **/ void Network::traffic(::Network::Connection const& connection, ::Network::TrafficType const traffic_type, string const& text) { this->update_traffic(connection); return ; } // void Network::traffic(time, name, text) /** ** the address of the new connection has changed ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::new_connection_address_change_event() { this->update_sensitivity(); return ; } // void Network::new_connection_address_change_event() /** ** a connection shall be made ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::connect_event() { string const& address = this->new_connection_address->get_text(); unsigned const port = static_cast(this->new_connection_port->get_value_as_int()); ::server->create_connection(address, port); return ; } // void Network::connect_event() /** ** send the text of the 'sender' entry to all connections ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 ** ** @todo only send to the selected connections **/ void Network::send_event() { string const text = this->sender->get_text(); this->sender->set_text(""); for (vector< ::Network::Connection*>::const_iterator c = ::server->connections().begin(); c != ::server->connections().end(); ++c) (*c)->send(text + "\n"); return ; } // void Network::send_event() /** ** creates a listener ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 **/ void Network::create_listener_event() { ::server->create_listener(static_cast(this->listener_port->get_value_as_int())); return ; } // void Network::create_listener_event() /** ** clear all listeners and connections ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 **/ void Network::clear_event() { ::server->clear(); return ; } // void Network::clear_event() /** ** update the traffic for the connection ** ** @param connection the connection ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.2 **/ void Network::update_traffic(::Network::Connection const& connection) { list::iterator r; for (r = this->connection_rows.begin(); r != this->connection_rows.end(); ++r) if ((*r)[this->connection_model->connection] == &connection) break; #ifdef WORKAROUND // the traffic is called before the connection is established if (r == this->connection_rows.end()) return ; #endif DEBUG_ASSERTION((r != this->connection_rows.end()), "Network::update_traffic(connection)\n" " connection '" << connection.name() << "' not found."); Gtk::TreeModel::Row& row = *r; if (connection.incoming_bytes() < 10 * 1024) row[this->connection_model->incoming_bytes] = DK::Utils::String::to_string(connection.incoming_bytes()); else row[this->connection_model->incoming_bytes] = (DK::Utils::String::to_string(connection.incoming_bytes() / 1024) + "K"); if (connection.outgoing_bytes() < 10 * 1024) row[this->connection_model->outgoing_bytes] = DK::Utils::String::to_string(connection.outgoing_bytes()); else row[this->connection_model->outgoing_bytes] = (DK::Utils::String::to_string(connection.outgoing_bytes() / 1024) + "K"); return ; } // void Network::update_traffic(connection) /** ** updates the language ** ** @param - ** ** @return - ** ** @author Diether Knof ** ** @version 0.7.0 **/ void Network::language_update() { this->connection_treeview->get_column(0)->set_title(::translation("Network::name").translation()); this->connection_treeview->get_column(1)->set_title(::translation("Network::address").translation()); this->connection_treeview->get_column(2)->set_title(::translation("Network::port").translation()); this->connection_treeview->get_column(3)->set_title(::translation("Network::Connection::relation").translation()); this->connection_treeview->get_column(4)->set_title(::translation("Network::Connection::type").translation()); this->connection_treeview->get_column(5)->set_title("<"); this->connection_treeview->get_column(6)->set_title(">"); this->local_addresses_treeview->get_column(0)->set_title(::translation("Network::address").translation()); this->listeners_treeview->get_column(0)->set_title(::translation("open port").translation()); this->rule_diffs_treeview->get_column(0)->set_title(::translation("rule").translation()); this->rule_diffs_treeview->get_column(1)->set_title(::translation("self value").translation()); this->rule_diffs_treeview->get_column(2)->set_title(::translation("server value").translation()); this->recreate_rule_differences_list(); return ; } // void Network::language_update() /** ** stop the urgency hint ** ** @param - ** ** @return false (stop the timeout signal) ** ** @author Diether Knof ** ** @version 0.7.3 **/ bool Network::stop_urgency_hint() { #if GTKMM_VERSION_GE(2,8) this->set_urgency_hint(false); #endif return false; } // bool Network::stop_urgency_hint() } // namespace UI_GTKMM_NS #endif // #ifdef USE_NETWORK #endif // #ifdef USE_UI_GTKMM