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