Fawkes API  Fawkes Development Version
config_tree_view.cpp
00001 
00002 /***************************************************************************
00003  *  config_tree_view.cpp - TreeView class for displaying the configuration
00004  *
00005  *  Created: Wed Sep 24 13:45:39 2008
00006  *  Copyright  2008  Daniel Beck
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include "config_tree_view.h"
00024 #include "config_edit_dialog.h"
00025 #include "config_add_dialog.h"
00026 #include "config_remove_dialog.h"
00027 #include "config_editor_plugin.h"
00028 
00029 #include <core/exceptions/system.h>
00030 #include <config/netconf.h>
00031 #include <config/sqlite.h>
00032 #include <netcomm/fawkes/client.h>
00033 
00034 #include <cstring>
00035 #include <iostream>
00036 #include <sstream>
00037 
00038 using namespace std;
00039 using namespace fawkes;
00040 
00041 /** @class ConfigTreeView tools/config_editor/config_tree_view.h
00042  * Treeview widget for displaying/editing config entries.
00043  *
00044  * @author Daniel Beck
00045  */
00046 
00047 /** @class ConfigTreeView::ConfigRecord tools/config_editor/config_tree_view.h
00048  * Column record class for the config TreeView.
00049  *
00050  * @author Daniel Beck
00051  */
00052 
00053 /** @var ConfigTreeView::m_config_record
00054  * Column record object to access the columns of the storage object.
00055  */
00056 
00057 /** @var ConfigTreeView::m_config_tree
00058  * Storage object.
00059  */
00060 
00061 /** @var ConfigTreeView::m_menu
00062  * A popup menu to edit the configuration.
00063  */
00064 
00065 /** @var ConfigTreeView::m_dlg_edit
00066  * A dialog to edit a config entry.
00067  */
00068 
00069 /** @var ConfigTreeView::m_dlg_add
00070  * A dialog to add a config entry.
00071  */
00072 
00073 /** @var ConfigTreeView::m_dlg_remove
00074  * A dialog to remove a config entry.
00075  */
00076 
00077 /** @var ConfigTreeView::m_config
00078  * The fawkes::Configuration that is displayed and editted.
00079  */
00080 
00081 /** @var ConfigTreeView::m_own_config
00082  * True if config was created by ConfigTreeView object.
00083  */
00084 
00085 /** @var ConfigTreeView::m_plugins
00086  * A map of registered plugins: config-prefix => config editor plugin.
00087  */
00088 
00089 /** Constructor.
00090  * @param cobject pointer to base object type
00091  * @param builder Gtk builder
00092  */
00093 ConfigTreeView::ConfigTreeView(BaseObjectType* cobject,
00094                                const Glib::RefPtr<Gtk::Builder> &builder)
00095   : Gtk::TreeView(cobject)
00096 {
00097   m_dlg_edit = NULL;
00098   builder->get_widget_derived("dlgConfigEdit", m_dlg_edit);
00099 
00100   m_dlg_add = NULL;
00101   builder->get_widget_derived("dlgConfigAdd", m_dlg_add);
00102 
00103   m_dlg_remove = NULL;
00104   builder->get_widget_derived("dlgConfigRemove", m_dlg_remove);
00105 
00106   m_config_tree = Gtk::TreeStore::create(m_config_record);
00107   m_config_tree->set_sort_column(0, Gtk::SORT_ASCENDING);
00108 
00109   set_model(m_config_tree);
00110   append_column("Path", m_config_record.node);
00111 
00112   Gtk::TreeViewColumn *column = get_column(0);
00113   Gtk::CellRendererText *cell =
00114 #if GTK_VERSION_GE(3,0)
00115     (Gtk::CellRendererText *)column->get_first_cell();
00116 #else
00117     (Gtk::CellRendererText *)column->get_first_cell_renderer();
00118 #endif
00119 #ifdef GLIBMM_PROPERTIES_ENABLED
00120   column->add_attribute(cell->property_underline(), m_config_record.is_default);
00121 #else
00122   column->add_attribute(*cell, "underline", m_config_record.is_default);
00123 #endif
00124 
00125   append_column("Value", m_config_record.value_string);
00126 
00127   /*
00128   Gtk::Menu::MenuList& menulist = m_menu.items();
00129 
00130   menulist.push_back( Gtk::Menu_Helpers::MenuElem("Edit", sigc::mem_fun( *this, &ConfigTreeView::on_menu_edit_selected) ) );
00131   menulist.push_back( Gtk::Menu_Helpers::MenuElem("Remove", sigc::mem_fun( *this, &ConfigTreeView::on_menu_remove_selected) ) );
00132   menulist.push_back( Gtk::Menu_Helpers::MenuElem("Add", sigc::mem_fun( *this, &ConfigTreeView::on_menu_add_selected) ) );
00133   */
00134 
00135   m_config = NULL;
00136   m_own_config = false;
00137 
00138   signal_button_press_event().connect_notify( sigc::mem_fun(*this, &ConfigTreeView::on_button_press_event_custom) );
00139 }
00140 
00141 /** Destructor. */
00142 ConfigTreeView::~ConfigTreeView()
00143 {
00144   if (m_own_config)
00145     { delete m_config; }
00146 
00147   for ( std::map< string, ConfigEditorPlugin* >::iterator iter = m_plugins.begin();
00148         iter != m_plugins.end();
00149         ++iter )
00150   { delete iter->second; }
00151 }
00152 
00153 /** Set the fawkes::Configuration to be displayed.
00154  * @param config the fawkes::Configuration; set it to NULL to signal
00155  * the unavailability of the config
00156  */
00157 void
00158 ConfigTreeView::set_config(Configuration* config)
00159 {
00160   if ( config )
00161   {
00162     m_config = config;
00163     m_own_config = false;
00164 
00165     // TODO: enable mirror mode if it is a netconf
00166     read_config();
00167   }
00168   else
00169   {
00170     delete m_config;
00171     m_config = NULL;
00172     m_config_tree->clear();
00173   }
00174 
00175   for ( std::map< string, ConfigEditorPlugin* >::iterator i = m_plugins.begin();
00176         i != m_plugins.end();
00177         ++i )
00178   { i->second->set_config( m_config ); }
00179 }
00180 
00181 /** Set a network client that is used to open a fawkes::NetworkConfiguration.
00182  * @param client a fawkes::NetworkClient; set it to NULL to signal the
00183  * unavailability of the client
00184  */
00185 void
00186 ConfigTreeView::set_network_client(FawkesNetworkClient* client)
00187 {
00188   if (client)
00189     {
00190       NetworkConfiguration* netconf = new NetworkConfiguration(client);
00191       netconf->set_mirror_mode(true);
00192       m_config = netconf;
00193       m_own_config = true;
00194 
00195       read_config();
00196     }
00197   else
00198     {
00199       delete m_config;
00200       m_config = NULL;
00201       m_config_tree->clear();
00202     }
00203 
00204   for ( std::map< string, ConfigEditorPlugin* >::iterator i = m_plugins.begin();
00205         i != m_plugins.end();
00206         ++i )
00207   { i->second->set_config( m_config ); }
00208 }
00209 
00210 /** Set the file to read the config from.
00211  * @param filename the filename of the database file
00212  */
00213 void
00214 ConfigTreeView::set_config_file(const char* filename)
00215 {
00216   m_config = new SQLiteConfiguration(filename);
00217   m_own_config = true;
00218 
00219   read_config();
00220 }
00221 
00222 /** Register a plugin.
00223  * This also initializes the plugin.
00224  * @param plugin the new plugin to register
00225  */
00226 void
00227 ConfigTreeView::register_plugin( ConfigEditorPlugin* plugin )
00228 {
00229   plugin->initialize();
00230   m_plugins[ plugin->get_config_path() ] = plugin;
00231 }
00232 
00233 /** Remove a plugin.
00234  * @param config_path the config prefix corresponding to the plugin to
00235  * be removed
00236  */
00237 void
00238 ConfigTreeView::remove_plugin( string config_path )
00239 {
00240   std::map< string, ConfigEditorPlugin* >::iterator iter = m_plugins.find( config_path );
00241 
00242   if ( iter != m_plugins.end() )
00243   {
00244     ConfigEditorPlugin* p = iter->second;
00245     m_plugins.erase( iter );
00246     delete p;
00247   }
00248 }
00249 
00250 void
00251 ConfigTreeView::read_config()
00252 {
00253   if ( !m_config )
00254     { return; }
00255 
00256   m_config_tree->clear();
00257 
00258   m_config->lock();
00259   Configuration::ValueIterator* cit = m_config->iterator();
00260   while ( cit->next() )
00261     {
00262       if ( cit->is_bool() )
00263         { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_bool()); }
00264       else if ( cit->is_int() )
00265         { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_int()); }
00266       else if ( cit->is_uint() )
00267         { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_uint()); }
00268       else if ( cit->is_float() )
00269         { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_float()); }
00270       else if ( cit->is_string() )
00271         { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_string()); }
00272     }
00273 
00274   delete cit;
00275   m_config->unlock();
00276 }
00277 
00278 
00279 /** Add a config entry to the TreeModel storage object.
00280  * @param path config path
00281  * @param type type of config entry
00282  * @param is_default true if config entry is in the default config
00283  * @param value the value of the config entry
00284  */
00285 void
00286 ConfigTreeView::set_value(const char* path, const char* type, bool is_default, bool value)
00287 {
00288   Gtk::TreeModel::Row row;
00289   row = *get_iter(path);
00290 
00291   row[m_config_record.type] = type;
00292   row[m_config_record.is_default] = is_default;
00293   row[m_config_record.value_bool] = value;
00294   row[m_config_record.value_string] = ( value ? "TRUE" : "FALSE" );
00295 }
00296 
00297 /** Add a config entry to the TreeModel storage object.
00298  * @param path config path
00299  * @param type type of config entry
00300  * @param is_default true if config entry is in the default config
00301  * @param value the value of the config entry
00302  */
00303 void
00304 ConfigTreeView::set_value(const char* path, const char* type, bool is_default, int value)
00305 {
00306   Gtk::TreeModel::Row row;
00307   row = *get_iter(path);
00308 
00309   row[m_config_record.type] = type;
00310   row[m_config_record.is_default] = is_default;
00311   row[m_config_record.value_int] = value;
00312 
00313   string val_str;
00314   stringstream ss;
00315   ss << value;
00316   ss >> val_str;
00317   row[m_config_record.value_string] = val_str;
00318 }
00319 
00320 /** Add a config entry to the TreeModel storage object.
00321  * @param path config path
00322  * @param type type of config entry
00323  * @param is_default true if config entry is in the default config
00324  * @param value the value of the config entry
00325  */
00326 void
00327 ConfigTreeView::set_value(const char* path, const char* type, bool is_default, uint value)
00328 {
00329   Gtk::TreeModel::Row row;
00330   row = *get_iter(path);
00331 
00332   row[m_config_record.type] = type;
00333   row[m_config_record.is_default] = is_default;
00334   row[m_config_record.value_uint] = value;
00335 
00336   string val_str;
00337   stringstream ss;
00338   ss << value;
00339   ss >> val_str;
00340   row[m_config_record.value_string] = val_str;
00341 }
00342 
00343 /** Add a config entry to the TreeModel storage object.
00344  * @param path config path
00345  * @param type type of config entry
00346  * @param is_default true if config entry is in the default config
00347  * @param value the value of the config entry
00348  */
00349 void
00350 ConfigTreeView::set_value(const char* path, const char* type, bool is_default, float value)
00351 {
00352   Gtk::TreeModel::Row row;
00353   row = *get_iter(path);
00354 
00355   row[m_config_record.type] = type;
00356   row[m_config_record.is_default] = is_default;
00357   row[m_config_record.value_float] = value;
00358 
00359   string val_str;
00360   stringstream ss;
00361   ss << value;
00362   ss >> val_str;
00363   row[m_config_record.value_string] = val_str;
00364 }
00365 
00366 /** Add a config entry to the TreeModel storage object.
00367  * @param path config path
00368  * @param type type of config entry
00369  * @param is_default true if config entry is in the default config
00370  * @param value the value of the config entry
00371  */
00372 void
00373 ConfigTreeView::set_value(const char* path, const char* type, bool is_default, std::string value)
00374 {
00375   Gtk::TreeModel::Row row;
00376   row = *get_iter(path);
00377 
00378   row[m_config_record.type] = type;
00379   row[m_config_record.is_default] = is_default;
00380   row[m_config_record.value_string] = value;
00381 }
00382 
00383 Gtk::TreeIter
00384 ConfigTreeView::get_iter(const char* p)
00385 {
00386   char* path;
00387   char* full_path;
00388 
00389   if (asprintf(&full_path, "%s", p) == -1) {
00390     throw OutOfMemoryException("get_iter(): asprintf() failed");
00391   }
00392   char* node = strtok(full_path, "/");
00393 
00394   if (asprintf(&path, "/%s", node) == -1) {
00395     throw OutOfMemoryException("get_iter(): asprintf() failed");
00396   }
00397 
00398   Gtk::TreeModel::Children children = m_config_tree->children();
00399   Gtk::TreeIter iter = children.begin();
00400 
00401   while ( node != NULL )
00402     {
00403       bool found = false;
00404       iter = children.begin();
00405 
00406       while ( !found && iter != children.end() )
00407         {
00408           Gtk::TreeModel::Row row = *iter;
00409 
00410           Glib::ustring r = row[m_config_record.node];
00411           if ( strcmp(r.c_str(), node) == 0 )
00412             {
00413               found = true;
00414               children = row.children();
00415               iter = children.begin();
00416             }
00417           else
00418             { ++iter; }
00419         }
00420 
00421       if ( !found )
00422       {
00423         iter = m_config_tree->append(children);
00424         Gtk::TreeModel::Row row = *iter;
00425         row[m_config_record.node] = Glib::ustring(node);
00426         row[m_config_record.path] = Glib::ustring(path);
00427         
00428         children = row.children();
00429       }
00430 
00431       node = strtok(NULL, "/");
00432 
00433       char* t;
00434       if (asprintf(&t, "%s/%s", path, node) == -1) {
00435         throw OutOfMemoryException("get_iter(): asprintf() failed");
00436       }
00437       free(path);
00438       path = t;
00439     }
00440 
00441   free(path);
00442   free(full_path);
00443 
00444   return iter;
00445 }
00446 
00447 Gtk::TreeIter
00448 ConfigTreeView::search_path( const char* path )
00449 {
00450   Gtk::TreeModel::Children children = m_config_tree->children();
00451   Gtk::TreeModel::iterator iter = children.begin();
00452   
00453   while ( iter != children.end() )
00454   {
00455     Gtk::TreeModel::Row row = *iter;
00456     Glib::ustring p = row[ m_config_record.path ];
00457     size_t len = strlen( p.c_str() );
00458 
00459     if ( strncmp( p.c_str(), path, len) == 0 )
00460     {
00461       if ( strcmp( p.c_str(), path ) == 0 )
00462       { return iter; }
00463       else
00464       { iter = iter->children().begin(); }
00465     }
00466     else
00467     { ++iter; }
00468   }
00469 
00470   return m_config_tree->children().end();
00471 }
00472 
00473 /** Signal handler for the button press event.
00474  * @param event a Gdk button event
00475  * @return true if signal has been handled, false otherwise
00476  */
00477 void
00478 ConfigTreeView::on_button_press_event_custom(GdkEventButton* event)
00479 {
00480   if (event->type == GDK_2BUTTON_PRESS)
00481   {
00482     Gtk::TreeModel::Row row = *( get_selection()->get_selected() );
00483     Glib::ustring path = row[ m_config_record.path ];
00484 
00485     std::map< string, ConfigEditorPlugin* >::iterator i = m_plugins.find( path.c_str() );
00486     if ( i != m_plugins.end() )
00487     { i->second->run(); }
00488     else
00489     { edit_entry( get_selection()->get_selected() ); }
00490   }
00491   else if ( event->type == GDK_BUTTON_PRESS && (event->button == 3) )
00492   {
00493     //m_menu.popup(event->button, event->time);
00494   }
00495 }
00496 
00497 /** Signal handler that is called when the 'edit' entry is selected
00498  * from popup menu.
00499  */
00500 void ConfigTreeView::on_menu_edit_selected()
00501 {
00502   edit_entry( get_selection()->get_selected() );
00503 }
00504 
00505 /** Signal handler that is called when the 'add' entry is selected
00506  * from popup menu.
00507  */
00508 void
00509 ConfigTreeView::on_menu_add_selected()
00510 {
00511   add_entry( get_selection()->get_selected() );
00512 }
00513 
00514 /** Signal handler that is called when the 'remove' entry is selected
00515  * from popup menu.
00516  */
00517 void
00518 ConfigTreeView::on_menu_remove_selected()
00519 {
00520   remove_entry( get_selection()->get_selected() );
00521 }
00522 
00523 bool
00524 ConfigTreeView::edit_entry(const Gtk::TreeIter& iter)
00525 {
00526   bool ret_val;
00527 
00528   Gtk::TreeModel::Row row = *iter;
00529   Glib::ustring type = row[m_config_record.type];
00530 
00531   if (type == "") //if type is empty the row is a directory...
00532     { ret_val = false; }
00533   else
00534     {
00535       int result;
00536       Glib::ustring path  = row[m_config_record.path];
00537       Glib::ustring value = row[m_config_record.value_string];
00538       bool is_default     = row[m_config_record.is_default];
00539 
00540       m_dlg_edit->init(path, type, value);
00541       Gtk::Window* parent = dynamic_cast<Gtk::Window*>( get_toplevel() );
00542       m_dlg_edit->set_transient_for(*parent);
00543       result = m_dlg_edit->run();
00544 
00545       switch (result)
00546         {
00547         case Gtk::RESPONSE_OK:
00548           {
00549             Glib::ustring value = m_dlg_edit->get_value();
00550 
00551             const char* p = path.c_str();
00552             const char* t = type.c_str();
00553 
00554             is_default = m_dlg_edit->get_is_default();
00555             if (is_default) m_config->erase(p);
00556 
00557             if ( m_config->is_bool(p) )
00558               {
00559                 bool b = false;
00560                 if (value == "TRUE")
00561                   { b = true; }
00562                 else if (value == "FALSE")
00563                   { b = false; }
00564 
00565                 if (!is_default) m_config->set_bool(p, b);
00566                 else m_config->set_default_bool(p, b);
00567                 set_value(p, t, is_default, b);
00568               }
00569             else if ( m_config->is_int(p) )
00570               {
00571                 int i;
00572                 i = atoi( value.c_str() );
00573 
00574                 if (!is_default) m_config->set_int(p, i);
00575                 else m_config->set_default_int(p, i);
00576                 set_value(p, t, is_default, i);
00577               }
00578             else if ( m_config->is_uint(p) )
00579               {
00580                 int i;
00581                 i = atoi( value.c_str() );
00582                 if ( 0 <= i)
00583                   {
00584                     if (!is_default) m_config->set_uint(p, (unsigned int) i);
00585                     else m_config->set_default_uint( p, (unsigned int) i );
00586                     set_value(p, t, is_default, (unsigned int) i);
00587                   }
00588               }
00589             else if ( m_config->is_float(p) )
00590               {
00591                 float f;
00592                 f = atof( value.c_str() );
00593 
00594                 if (!is_default) m_config->set_float(p, f);
00595                 else m_config->set_default_float(p, f);
00596                 set_value(p, t, is_default, f);
00597               }
00598             else if ( m_config->is_string(p) )
00599               {
00600                 string s( value.c_str() );
00601 
00602                 if (!is_default) m_config->set_string(p, s);
00603                 else m_config->set_default_string(p, s);
00604                 set_value(p, t, is_default, s);
00605               }
00606 
00607             ret_val = true;
00608 
00609             break;
00610           }
00611 
00612         default:
00613           ret_val = false;
00614           break;
00615         }
00616 
00617       m_dlg_edit->hide();
00618     }
00619 
00620   return ret_val;
00621 }
00622 
00623 bool
00624 ConfigTreeView::remove_entry(const Gtk::TreeIter& iter)
00625 {
00626   bool ret_val = false;
00627   int result;
00628   Gtk::TreeModel::Row row = *iter;
00629   Glib::ustring type = row[m_config_record.type];
00630   bool is_default = row[m_config_record.is_default];
00631 
00632   if (type == "") //if type is empty the row is a directory -> return
00633     { ret_val = false; }
00634   else
00635     {
00636       Glib::ustring path = row[m_config_record.path];
00637       m_dlg_remove->init(path, is_default);
00638 
00639       Gtk::Window* parent = dynamic_cast<Gtk::Window*>( get_toplevel() );
00640       m_dlg_remove->set_transient_for(*parent);
00641       result = m_dlg_remove->run();
00642 
00643       switch (result)
00644         {
00645         case Gtk::RESPONSE_OK:
00646           {
00647             const char* p = path.c_str();
00648             bool rem_default = m_dlg_remove->get_remove_default();
00649             m_config->erase(p);
00650             if (rem_default) m_config->erase_default(p);
00651 
00652             Gtk::TreePath tree_path = m_config_tree->get_path(iter);
00653             m_config_tree->erase(iter);
00654             m_config_tree->row_deleted(tree_path);
00655 
00656             Configuration::ValueIterator* cit = m_config->search(p);
00657             if (!rem_default && cit->next()) //reenter the default value
00658               {
00659                 if ( cit->is_bool() )
00660                   { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_bool()); }
00661                 else if ( cit->is_int() )
00662                   { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_int()); }
00663                 else if ( cit->is_uint() )
00664                   { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_uint()); }
00665                 else if ( cit->is_float() )
00666                   { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_float()); }
00667                 else if ( cit->is_string() )
00668                   { set_value(cit->path(), cit->type(), cit->is_default(), cit->get_string()); }
00669               }
00670 
00671             break;
00672           }
00673 
00674         default:
00675           ret_val = false;
00676           break;
00677         }
00678 
00679       m_dlg_remove->hide();
00680     }
00681 
00682   return ret_val;
00683 }
00684 
00685 bool
00686 ConfigTreeView::add_entry(const Gtk::TreeIter& iter)
00687 {
00688   bool ret_val = false;
00689   int result;
00690   Gtk::TreeModel::Row row = *iter;
00691   Glib::ustring path = row[m_config_record.path];
00692 
00693   m_dlg_add->init(path);
00694 
00695   Gtk::Window* parent = dynamic_cast<Gtk::Window*>( get_toplevel() );
00696   m_dlg_add->set_transient_for(*parent);
00697   result = m_dlg_add->run();
00698 
00699   switch (result)
00700     {
00701     case Gtk::RESPONSE_OK:
00702       {
00703         Glib::ustring type  = m_dlg_add->get_type();
00704         Glib::ustring path  = m_dlg_add->get_path();
00705         Glib::ustring value = m_dlg_add->get_value();
00706         bool is_default     = m_dlg_add->get_is_default();
00707 
00708         const char* t = type.c_str();
00709         const char* p = path.c_str();
00710 
00711         ret_val = true;
00712 
00713         if ( type == "bool" )
00714           {
00715             bool b = false;
00716 
00717             if ( value == "TRUE" || value == "true" )
00718               { b = true; }
00719             else if ( value == "FALSE" || value == "false" )
00720               { b = false; }
00721 
00722             if (!is_default) m_config->set_bool(p, b);
00723             else m_config->set_default_bool(p, b);
00724             set_value(p, t, is_default, b);
00725           }
00726 
00727         else if ( type == "int" )
00728           {
00729             int i;
00730             i = atoi( value.c_str() );
00731 
00732             if (!is_default) m_config->set_int(p, i);
00733             else m_config->set_default_int(p, i);
00734             set_value(p, t, is_default, i);
00735           }
00736 
00737         else if ( type == "uint" )
00738           {
00739             int i;
00740             i = atoi( value.c_str() );
00741             if ( 0 <= i)
00742               {
00743                 if (!is_default) m_config->set_uint(p, (unsigned int) i);
00744                 else m_config->set_default_uint( p, (unsigned int) i);
00745                 set_value(p, t, is_default, (unsigned int) i);
00746               }
00747           }
00748 
00749         else if ( type == "float" )
00750           {
00751             float f;
00752             f = atof( value.c_str() );
00753 
00754             if (!is_default) m_config->set_float(p, f);
00755             else m_config->set_default_float(p, f);
00756             set_value(p, t, is_default, f);
00757           }
00758 
00759         else if ( type == "string")
00760           {
00761             string s( value.c_str() );
00762 
00763             if (!is_default) m_config->set_string(p, s);
00764              else m_config->set_default_string(p, s);
00765             set_value(p, t, is_default, s);
00766           }
00767 
00768         else
00769           {
00770             ret_val = false;
00771             cout << "Unknown type." << endl;
00772           }
00773 
00774         break;
00775       }
00776 
00777     default:
00778       ret_val = false;
00779       break;
00780     }
00781 
00782   m_dlg_add->hide();
00783 
00784   return ret_val;
00785 }