Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com
Answertopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Gtk+/Gnome Application Development
Prev Home Next

Iteration Example from gnome-apt

Here's an example from gnome-apt, a C++ application used to manage packages on Debian systems. gnome-apt loads and saves the position of some columns in a tree display. The columns are identified by the GAptPkgTree::ColumnType enumeration. GAptPkgTree::ColumnTypeEnd is the last element in the column type enumeration, and equal to the number of valid column types. This example is frighteningly "real world" and checks for a number of error conditions.


static void
load_column_order(vector<GAptPkgTree::ColumnType> & columns)
{
  gpointer config_iterator;
  guint loaded = 0;

  config_iterator = gnome_config_init_iterator("/gnome-apt/ColumnOrder");

  if (config_iterator != 0)
    {
      gchar * col, * pos;
      columns.reserve(GAptPkgTree::ColumnTypeEnd);
      
      loaded = 0;
      while ((config_iterator = 
              gnome_config_iterator_next(config_iterator, 
                                         &col, &pos))) 
        {
          // shouldn't happen, but I'm paranoid
          if (pos == 0 || col == 0)
            {
              if (pos) g_free(pos);
              if (col) g_free(col);
              continue;
            }
          
          GAptPkgTree::ColumnType ct = string_to_column(col);
          
          gint index = atoi(pos);

          g_free(pos); pos = 0;
          g_free(col); col = 0;
          
          // the user could mangle the config file to make this happen
          if (static_cast<guint>(index) >= columns.size()) 
            continue;
          
          columns[index] = ct;
          
          ++loaded;
        }
    }

  if (loaded != static_cast<guint>(GAptPkgTree::ColumnTypeEnd))
    {
      // Either there was no saved order, or something is busted - use
      // default order
      columns.clear();
      
      int i = 0;
      while (i < GAptPkgTree::ColumnTypeEnd)
        {
          columns.push_back(static_cast<GAptPkgTree::ColumnType>(i));
          ++i;
        }

      // Clean the section - otherwise an old entry could 
      //  remain forever and keep screwing us up in the future.
      gnome_config_clean_section("/gnome-apt/ColumnOrder");
      gnome_config_sync();
    }
  
  g_return_if_fail(columns.size() == 
                   static_cast<guint>(GAptPkgTree::ColumnTypeEnd));
}

It might be helpful to see the function that saves the column positions:


static void
save_column_order(const vector<GAptPkgTree::ColumnType> & columns)
{
  g_return_if_fail(columns.size() == 
                   static_cast<guint>(GAptPkgTree::ColumnTypeEnd));

  int position = 0;
  vector<GAptPkgTree::ColumnType>::const_iterator i = columns.begin();
  while (i != columns.end())
    {
      gchar key[256];
      g_snprintf(key, 255, "/gnome-apt/ColumnOrder/%s", column_to_string(*i));
      gchar val[30];
      g_snprintf(val, 29, "%d", position);
      gnome_config_set_string(key, val);
      
      ++position;
      ++i;
    }

  gnome_config_sync();
}

When writing this code, the decision was made to store enumeration values as strings rather than integers. The column_to_string() and string_to_column() functions use a simple array of column names indexed by the enumeration values to convert back and forth. There are two reasons to do this: it will not break when the enumeration is altered in future versions of the program, and it keeps the configuration file human-editable.

You may also notice that the column positions are stored with gnome_config_set_string() instead of gnome_config_set_int(). This is because gnome_config_iterator_next() returns a string representation of the stored information, as found in the file. Most likely, gnome_config_set_int() stores integers as strings atoi() would understand (in fact it does), but it is technically not guaranteed by the API. If the code used gnome_config_set_int(), it would have to obtain only the key from gnome_config_iterator_next() and then call gnome_config_get_int() to obtain the integer value. Using atoi() on the string value would make unwarranted assumptions about gnome-config's implementation.

Gtk+/Gnome Application Development
Prev Home Next

 
 
  Published under free license. Design by Interspire