Special formatting

In some cases, special formatting of the displayed values is required. For example, the length of a string should be limited or only two decimals of a floating point value should be shown.

This can be achieved by setting so-called options on a parameter. Suppose you have a Gnome::Db::Form in a variable called form:

Glib::RefPtr<Gnome::Gda::ParameterList> paramlist = form.get_raw_form()->get_current_data();
Glib::RefPtr<Gnome::Gda::Parameter> param = paramlist->find_param("price");

The first line acquires the Gnome::Gda::ParameterList, via the underlaying Gnome::Db::RawForm as already shown in the Restricting Values section. Then, the parameter that corresponds to the 'price' field is looked up.

param->set_entry_plugin("textual:CURRENCY=EUR;NB_DECIMALS=2");

This line sets the plugin used to show the field in the form, and its options. The plugin used here is 'textual' which is also the default, but there are other plugins available (for example, a 'picture' plugin can show pictures within the form). The part behind the colon are the options for the plugin which have the same format as the connection string introduced earlier: An arbitrary amount of key/value pairs, separated by ';'.

The following keys are defined for the textual entry:

Table 6.1. Defined option keys for the 'textual' plugin

CURRENCY Defined for numeric values: Specifies a currency symbol that is displayed in front of the value.
NB_DECIMALS Defined for numeric values: Specifies the number of decimals to show. This can also be -1 indicating "unlimited" (which is the default).
THOUSAND_SEP Defined for numeric values: Can be either true or false. If true, the locale's thousand separator (if any) is used.
MULTILINE Defined for non-numeric values: Can be either true or false. If true, the text can be edited in a multiline text editing widget. This is not supported in a Gnome::Db::Grid.
MAX_SIZE Defined for non-numeric values: Specifies the maximum amount of characters to display.

Example

This example shows how to format a floating point field in a grid. It works completely similar for the form.

Source Code

File: examplewindow.h

#include <memory>

#include <gtkmm.h>
#include <libgdamm.h>
#include <libgnomedbmm.h>

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow(const Glib::RefPtr<Gnome::Gda::Dict>& dict);
    
private:
#ifdef GLIBMM_EXCEPTIONS_ENABLED
  void create_model(const Glib::RefPtr<Gnome::Gda::Dict>& dict);
#else
  void create_model(const Glib::RefPtr<Gnome::Gda::Dict>& dict, std::auto_ptr<Glib::Error>& error);
#endif
  Glib::RefPtr<Gnome::Gda::DataModelQuery> m_model;
    
  Gtk::VBox m_box;
  Gtk::Label m_label;
  Gnome::Db::Grid* m_grid;
};

File: main.cc

#include <libgnomedbmm.h>
#include <libgdamm.h>
#include <gtkmm.h>

#include <iostream>

#include "examplewindow.h"

#ifdef GLIBMM_EXCEPTIONS_ENABLED
Glib::RefPtr<Gnome::Gda::Dict> create_dict()
#else
Glib::RefPtr<Gnome::Gda::Dict> create_dict(std::auto_ptr<Glib::Error>& error)
#endif
{
  Glib::RefPtr<Gnome::Gda::Dict> dict = Gnome::Gda::Dict::create();
  Glib::RefPtr<Gnome::Gda::Client> client = Gnome::Gda::Client::create();
  Glib::ustring connection_string = "DB_DIR=" LIBGNOMEDB_DATADIR ";DB_NAME=demo_db";

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  Glib::RefPtr<Gnome::Gda::Connection> cnc = client->open_connection_from_string("SQLite", connection_string, "" /* username */, "" /* password */);
  dict->set_connection(cnc);
  dict->update_dbms_meta_data();
#else
  Glib::RefPtr<Gnome::Gda::Connection> cnc = client->open_connection_from_string("SQLite", connection_string, "", "", Gnome::Gda::ConnectionOptions(0), error);
  if(error.get() == NULL)
  {
    dict->set_connection(cnc);
    dict->update_dbms_meta_data(error);
  }
#endif

  return dict;
}

int main(int argc, char* argv[])
{
  Gtk::Main kit(argc, argv);
  Gnome::Db::init("Grid example", "1.0", argc, argv);

  Glib::RefPtr<Gnome::Gda::Dict> dict;

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  try
  {
    dict = create_dict();
  }
  catch(const Glib::Error& err)
  {
    std::cerr << "Exception caught: " << err.what() << std::endl;
    return 1;
  }
#else
  std::auto_ptr<Glib::Error> error;
  dict = create_dict(error);
  if(error.get() != NULL)
  {
    std::cerr << "Exception caught: " << error->what() << std::endl;
    return 1;
  }
#endif

  ExampleWindow window(dict);

  kit.run(window);
  return 0;
}

File: examplewindow.cc

#include "examplewindow.h" 

#include <libgdamm.h>
#include <iostream>

#ifdef GLIBMM_EXCEPTIONS_ENABLED
void ExampleWindow::create_model(const Glib::RefPtr<Gnome::Gda::Dict>& dict)
#else
void ExampleWindow::create_model(const Glib::RefPtr<Gnome::Gda::Dict>& dict, std::auto_ptr<Glib::Error>& error)
#endif // GLIBMM_EXCEPTIONS_ENABLED
{
  Glib::RefPtr<Gnome::Gda::Query> query = Gnome::Gda::Query::create(dict);

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  query->set_sql_text("SELECT ref, category, name, price, wh_stored FROM products");
#else
  query->set_sql_text("SELECT ref, category, name, price, wh_stored FROM products", error);
  if(error.get() != NULL) return;
#endif // GLIBMM_EXCEPTIONS_ENABLED
  
  m_model = Gnome::Gda::DataModelQuery::create(query);

  const Glib::ustring update_query =
                 "UPDATE products set "
                 "ref=##/*name:'+0' type:gchararray*/, "
                 "category=##/*name:'+1' type:gint*/,"
                 "name=##/*name:'+2' type:gchararray*/, "
		 "price=##/*name:'+3' type:gdouble*/, "
                 "wh_stored=##/*name:'+4' type:gint*/ "
                 "WHERE ref=##/*name:'-0' type:gchararray*/";

  const Glib::ustring delete_query =
                 "DELETE FROM products WHERE ref=##/*name:'-0' type:gchararray*/";

  const Glib::ustring insert_query =
                 "INSERT INTO products (ref, category, name, price, wh_stored) "
                 "VALUES (##/*name:'+0' type:gchararray*/, "
                 "##/*name:'+1' type:gint*/, "
                 "##/*name:'+2' type:gchararray*/, "
                 "1.0, "
                 "##/*name:'+4' type:gint*/)";

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  m_model->set_modification_query(update_query);
  m_model->set_modification_query(delete_query);
  m_model->set_modification_query(insert_query);
#else
  m_model->set_modification_query(update_query, error);
  m_model->set_modification_query(delete_query, error);
  m_model->set_modification_query(insert_query, error);
#endif
}

ExampleWindow::ExampleWindow(const Glib::RefPtr<Gnome::Gda::Dict>& dict) :
  m_label("The following Gnome::Db::Grid widget displays data from the 'products' table.\n\n"
          "The 'price' field has special formatting rules:\nIt always shows two decimal places and the 'EUR' currency symbol.")
{    
  m_box.set_border_width(6);
  m_box.pack_start(m_label, Gtk::PACK_SHRINK);

#ifdef GLIBMM_EXCEPTIONS_ENABLED
  try
  {
    create_model(dict);
  }
  catch(const Glib::Error& err)
  {
    std::cerr << "Exception caught: " << err.what() << std::endl;
    exit(1);
  }
#else
  std::auto_ptr<Glib::Error> error;
  create_model(dict, error);
  if(error.get() != NULL)
  {
    std::cerr << "Exception caught: " << error->what() << std::endl;
    exit(1);
  }
#endif

  /* Create the demo widget */
  m_grid = Gtk::manage(new Gnome::Db::Grid(m_model));
  /* Get the underlaying RawGrid */
  Gnome::Db::RawGrid* rawgrid = m_grid->get_raw_grid();
  /* Find the Gda::Parameter for the price field */
  Glib::RefPtr<Gnome::Gda::Parameter> param = rawgrid->get_current_data()->find_param("price");
  /* Set options for the plugin */
  param->set_entry_plugin("textual:CURRENCY=EUR;NB_DECIMALS=2;THOUSANDS_SEP=t");

  m_box.pack_start(*m_grid);
  add(m_box);
  set_default_size(0, 400);
  show_all();
}