00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <gui_utils/plugin_tree_view.h>
00026 #include <netcomm/fawkes/client.h>
00027 #include <plugin/net/messages.h>
00028 #include <plugin/net/list_message.h>
00029 #include <gui_utils/twolines_cellrenderer.h>
00030
00031 #include <cstring>
00032 #include <string>
00033
00034 using namespace std;
00035
00036 namespace fawkes {
00037 #if 0
00038 }
00039 #endif
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 PluginTreeView::PluginTreeView()
00065 : m_dispatcher(FAWKES_CID_PLUGINMANAGER)
00066 {
00067 ctor();
00068 }
00069
00070 #ifdef HAVE_GLADEMM
00071
00072
00073
00074
00075 PluginTreeView::PluginTreeView(BaseObjectType* cobject,
00076 const Glib::RefPtr<Gnome::Glade::Xml> ref_xml)
00077 : Gtk::TreeView(cobject),
00078 m_dispatcher(FAWKES_CID_PLUGINMANAGER)
00079 {
00080 ctor();
00081 }
00082 #endif
00083
00084
00085 void
00086 PluginTreeView::ctor()
00087 {
00088 m_plugin_list = Gtk::ListStore::create(m_plugin_record);
00089 set_model(m_plugin_list);
00090 set_rules_hint(true);
00091 append_column("#", m_plugin_record.index);
00092 append_column_editable("Status", m_plugin_record.loaded);
00093 append_plugin_column();
00094
00095 on_name_clicked();
00096 Gtk::TreeViewColumn *column = get_column(0);
00097 column->signal_clicked().connect(sigc::mem_fun(*this, &PluginTreeView::on_id_clicked));
00098 column = get_column(1);
00099 column->signal_clicked().connect(sigc::mem_fun(*this, &PluginTreeView::on_status_clicked));
00100
00101 Gtk::CellRendererToggle* renderer;
00102 renderer = dynamic_cast<Gtk::CellRendererToggle*>( get_column_cell_renderer(1) );
00103 renderer->signal_toggled().connect( sigc::mem_fun(*this, &PluginTreeView::on_status_toggled));
00104
00105 m_dispatcher.signal_connected().connect(sigc::mem_fun(*this, &PluginTreeView::on_connected));
00106 m_dispatcher.signal_disconnected().connect(sigc::mem_fun(*this, &PluginTreeView::on_disconnected));
00107 m_dispatcher.signal_message_received().connect(sigc::mem_fun(*this, &PluginTreeView::on_message_received));
00108
00109 }
00110
00111
00112 PluginTreeView::~PluginTreeView()
00113 {
00114 if (m_dispatcher)
00115 {
00116
00117 FawkesNetworkMessage* msg = new FawkesNetworkMessage(FAWKES_CID_PLUGINMANAGER,
00118 MSG_PLUGIN_UNSUBSCRIBE_WATCH);
00119 m_dispatcher.get_client()->enqueue(msg);
00120
00121 m_dispatcher.get_client()->deregister_handler(FAWKES_CID_PLUGINMANAGER);
00122 }
00123
00124 #ifdef HAVE_GCONFMM
00125 if (__gconf) {
00126 # ifdef GLIBMM_EXCEPTIONS_ENABLED
00127 __gconf->remove_dir(__gconf_prefix);
00128 # else
00129 std::auto_ptr<Glib::Error> error;
00130 __gconf->remove_dir(__gconf_prefix, error);
00131 # endif
00132 }
00133 #endif
00134 }
00135
00136
00137
00138
00139
00140 void
00141 PluginTreeView::set_network_client(FawkesNetworkClient* client)
00142 {
00143 m_dispatcher.set_client(client);
00144 }
00145
00146
00147
00148
00149
00150 void
00151 PluginTreeView::set_gconf_prefix(Glib::ustring gconf_prefix)
00152 {
00153 #ifdef HAVE_GCONFMM
00154 if (! __gconf) {
00155 __gconf = Gnome::Conf::Client::get_default_client();
00156 } else {
00157 # ifdef GLIBMM_EXCEPTIONS_ENABLED
00158 __gconf->remove_dir(__gconf_prefix);
00159 # else
00160 std::auto_ptr<Glib::Error> error;
00161 __gconf->remove_dir(__gconf_prefix, error);
00162 # endif
00163 }
00164
00165 #ifdef GLIBMM_EXCEPTIONS_ENABLED
00166 __gconf->add_dir(gconf_prefix);
00167 #else
00168 std::auto_ptr<Glib::Error> error;
00169 __gconf->add_dir(gconf_prefix, Gnome::Conf::CLIENT_PRELOAD_NONE, error);
00170 #endif
00171 __gconf_prefix = gconf_prefix;
00172
00173 if (__gconf_connection) {
00174 __gconf_connection.disconnect();
00175 }
00176 __gconf_connection = __gconf->signal_value_changed().connect(sigc::hide(sigc::hide(sigc::mem_fun(*this, &PluginTreeView::on_config_changed))));
00177
00178 on_config_changed();
00179 #endif
00180 }
00181
00182 void
00183 PluginTreeView::on_connected()
00184 {
00185 try
00186 {
00187 FawkesNetworkClient *client = m_dispatcher.get_client();
00188
00189
00190 FawkesNetworkMessage* msg = new FawkesNetworkMessage(FAWKES_CID_PLUGINMANAGER,
00191 MSG_PLUGIN_SUBSCRIBE_WATCH);
00192 client->enqueue(msg);
00193
00194
00195 msg = new FawkesNetworkMessage(FAWKES_CID_PLUGINMANAGER,
00196 MSG_PLUGIN_LIST_AVAIL);
00197 client->enqueue(msg);
00198
00199
00200 msg = new FawkesNetworkMessage(FAWKES_CID_PLUGINMANAGER,
00201 MSG_PLUGIN_LIST_LOADED);
00202 client->enqueue(msg);
00203 }
00204 catch (Exception& e)
00205 {
00206 e.print_trace();
00207 }
00208 }
00209
00210
00211 void
00212 PluginTreeView::on_disconnected()
00213 {
00214 m_plugin_list->clear();
00215 }
00216
00217
00218 void
00219 PluginTreeView::on_message_received(fawkes::FawkesNetworkMessage* msg)
00220 {
00221 if (msg->cid() != FAWKES_CID_PLUGINMANAGER) return;
00222
00223
00224 unsigned int msgid = msg->msgid();
00225 if ( (msgid == MSG_PLUGIN_LOADED) ||
00226 (msgid == MSG_PLUGIN_LOAD_FAILED) ||
00227 (msgid == MSG_PLUGIN_UNLOADED) ||
00228 (msgid == MSG_PLUGIN_UNLOAD_FAILED) )
00229 {
00230 Glib::ustring name = "";
00231 bool loaded = false;
00232
00233 if ( msgid == MSG_PLUGIN_LOADED)
00234 {
00235 if ( msg->payload_size() != sizeof(plugin_loaded_msg_t) )
00236 {
00237 printf("Invalid message size (load succeeded)\n");
00238 }
00239 else
00240 {
00241 plugin_loaded_msg_t* m = (plugin_loaded_msg_t*) msg->payload();
00242 name = m->name;
00243 loaded = true;
00244 }
00245 }
00246 else if ( msgid == MSG_PLUGIN_LOAD_FAILED )
00247 {
00248 if ( msg->payload_size() != sizeof(plugin_load_failed_msg_t) )
00249 {
00250 printf("Invalid message size (load failed)\n");
00251 }
00252 else
00253 {
00254 plugin_load_failed_msg_t* m = (plugin_load_failed_msg_t*) msg->payload();
00255 name = m->name;
00256 loaded = false;
00257 }
00258 }
00259 else if ( msg->msgid() == MSG_PLUGIN_UNLOADED )
00260 {
00261 if ( msg->payload_size() != sizeof(plugin_unloaded_msg_t) )
00262 {
00263 printf("Invalid message size (unload succeeded)\n");
00264 }
00265 else
00266 {
00267 plugin_unloaded_msg_t* m = (plugin_unloaded_msg_t*) msg->payload();
00268 name = m->name;
00269 loaded = false;
00270 }
00271 }
00272 else if ( msg->msgid() == MSG_PLUGIN_UNLOAD_FAILED)
00273 {
00274 if ( msg->payload_size() != sizeof(plugin_unload_failed_msg_t) )
00275 {
00276 printf("Invalid message size (unload failed)\n");
00277 }
00278 else
00279 {
00280 plugin_unload_failed_msg_t* m = (plugin_unload_failed_msg_t*) msg->payload();
00281 name = m->name;
00282 loaded = true;
00283 }
00284 }
00285
00286 Gtk::TreeIter iter;
00287 for ( iter = m_plugin_list->children().begin();
00288 iter != m_plugin_list->children().end();
00289 ++iter )
00290 {
00291 Glib::ustring n = (*iter)[m_plugin_record.name];
00292 if ( n == name )
00293 {
00294 (*iter)[m_plugin_record.loaded] = loaded;
00295 break;
00296 }
00297 }
00298 }
00299 else if (msgid == MSG_PLUGIN_AVAIL_LIST)
00300 {
00301 m_plugin_list->clear();
00302 PluginListMessage* plm = msg->msgc<PluginListMessage>();
00303 while ( plm->has_next() )
00304 {
00305 char *plugin_name = plm->next();
00306 char *plugin_desc = NULL;
00307 if ( plm->has_next() ) {
00308 plugin_desc = plm->next();
00309 } else {
00310 plugin_desc = strdup("Unknown, malformed plugin list message?");
00311 }
00312
00313 Gtk::TreeModel::Row row = *m_plugin_list->append();
00314 unsigned int index = m_plugin_list->children().size();
00315 row[m_plugin_record.index] = index;
00316 row[m_plugin_record.name] = plugin_name;
00317 row[m_plugin_record.description] = plugin_desc;
00318 row[m_plugin_record.loaded] = false;
00319
00320 free(plugin_name);
00321 free(plugin_desc);
00322 }
00323 delete plm;
00324 }
00325 else if ( msg->msgid() == MSG_PLUGIN_AVAIL_LIST_FAILED)
00326 {
00327 printf("Obtaining list of available plugins failed\n");
00328 }
00329 else if (msg->msgid() == MSG_PLUGIN_LOADED_LIST )
00330 {
00331 PluginListMessage* plm = msg->msgc<PluginListMessage>();
00332 while ( plm->has_next() )
00333 {
00334 char* name = plm->next();
00335
00336 Gtk::TreeIter iter;
00337 for ( iter = m_plugin_list->children().begin();
00338 iter != m_plugin_list->children().end();
00339 ++iter )
00340 {
00341 Glib::ustring n = (*iter)[m_plugin_record.name];
00342 if ( n == name )
00343 {
00344 (*iter)[m_plugin_record.loaded] = true;
00345 break;
00346 }
00347 }
00348 free(name);
00349 }
00350 delete plm;
00351 }
00352 else if ( msg->msgid() == MSG_PLUGIN_LOADED_LIST_FAILED)
00353 {
00354 printf("Obtaining list of loaded plugins failed\n");
00355 }
00356
00357
00358 else
00359 {
00360 printf("received message with msg-id %d\n", msg->msgid());
00361 }
00362 }
00363
00364
00365
00366
00367
00368 void
00369 PluginTreeView::on_status_toggled(const Glib::ustring& path)
00370 {
00371 if ( ! m_dispatcher.get_client()->connected() ) return;
00372
00373 Gtk::TreeModel::Row row = *m_plugin_list->get_iter(path);
00374 Glib::ustring plugin_name = row[m_plugin_record.name];
00375 bool loaded = row[m_plugin_record.loaded];
00376
00377 if (loaded)
00378 {
00379 plugin_load_msg_t* m = (plugin_load_msg_t*) calloc(1, sizeof(plugin_load_msg_t));
00380 strncpy(m->name, plugin_name.c_str(), PLUGIN_MSG_NAME_LENGTH);
00381
00382 FawkesNetworkMessage *msg = new FawkesNetworkMessage(FAWKES_CID_PLUGINMANAGER,
00383 MSG_PLUGIN_LOAD,
00384 m, sizeof(plugin_load_msg_t));
00385 m_dispatcher.get_client()->enqueue(msg);
00386 }
00387 else
00388 {
00389 plugin_unload_msg_t* m = (plugin_unload_msg_t *)calloc(1, sizeof(plugin_unload_msg_t));
00390 strncpy(m->name, plugin_name.c_str(), PLUGIN_MSG_NAME_LENGTH);
00391
00392 FawkesNetworkMessage *msg = new FawkesNetworkMessage(FAWKES_CID_PLUGINMANAGER,
00393 MSG_PLUGIN_UNLOAD,
00394 m, sizeof(plugin_unload_msg_t));
00395 m_dispatcher.get_client()->enqueue(msg);
00396 }
00397 }
00398
00399
00400
00401
00402 void
00403 PluginTreeView::on_id_clicked()
00404 {
00405 m_plugin_list->set_sort_column(0, Gtk::SORT_ASCENDING);
00406 }
00407
00408
00409
00410
00411 void
00412 PluginTreeView::on_status_clicked()
00413 {
00414 m_plugin_list->set_sort_column(2, Gtk::SORT_DESCENDING);
00415 }
00416
00417
00418
00419
00420 void
00421 PluginTreeView::on_name_clicked()
00422 {
00423 m_plugin_list->set_sort_column(1, Gtk::SORT_ASCENDING);
00424 }
00425
00426
00427
00428
00429 void
00430 PluginTreeView::on_config_changed()
00431 {
00432 Gtk::TreeViewColumn *plugin_col = get_column(2);
00433 if (plugin_col) remove_column(*plugin_col);
00434
00435 append_plugin_column();
00436 }
00437
00438
00439
00440
00441 void
00442 PluginTreeView::append_plugin_column()
00443 {
00444 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 14 )
00445 bool description_as_tooltip = false;
00446 # ifdef HAVE_GCONFMM
00447 if ( __gconf )
00448 {
00449 # ifdef GLIBMM_EXCEPTIONS_ENABLED
00450 description_as_tooltip = __gconf->get_bool(__gconf_prefix + "/description_as_tooltip");
00451 # else
00452 std::auto_ptr<Glib::Error> error;
00453 description_as_tooltip = __gconf->get_bool(__gconf_prefix + "/description_as_tooltip", error);
00454 # endif
00455 }
00456 # endif
00457 #endif
00458
00459 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 14 )
00460 if (description_as_tooltip)
00461 {
00462 #endif
00463 append_column("Plugin", m_plugin_record.name);
00464 #if GTKMM_MAJOR_VERSION > 2 || ( GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION >= 14 )
00465 set_tooltip_column(2);
00466 }
00467 else
00468 {
00469 TwoLinesCellRenderer *twolines_renderer = new TwoLinesCellRenderer();
00470 Gtk::TreeViewColumn *tlcol = new Gtk::TreeViewColumn("Plugin", *Gtk::manage(twolines_renderer));
00471 append_column(*Gtk::manage(tlcol));
00472
00473 # ifdef GLIBMM_PROPERTIES_ENABLED
00474 tlcol->add_attribute(twolines_renderer->property_line1(), m_plugin_record.name);
00475 tlcol->add_attribute(twolines_renderer->property_line2(), m_plugin_record.description);
00476 # else
00477 tlcol->add_attribute(*twolines_renderer, "line1", m_plugin_record.name);
00478 tlcol->add_attribute(*twolines_renderer, "line2", m_plugin_record.description);
00479 # endif
00480
00481 set_tooltip_column(-1);
00482 }
00483 #endif
00484
00485 set_headers_clickable();
00486 Gtk::TreeViewColumn *plugin_col = get_column(2);
00487 if (plugin_col) plugin_col->signal_clicked().connect(sigc::mem_fun(*this, &PluginTreeView::on_name_clicked));
00488 }
00489
00490 }