A Gnome::Db::Form
is in many ways similar to a Gnome::Db::Grid
except that it does not
show the data in a table but instead shows only one data set (usually one record) at a time using appropriate widgets. It features buttons to
navigate through the data set and can also be used to edit data if modification queries were given, as stated
in the Gnome::Db::Grid
section.
This examples creates a read-write Form with a query from an example sqlite database.
File: examplewindow.h
#include <gtkmm.h> #include <libgdamm.h> #include <libgdamm/datamodelquery.h> #include <libgnomedbmm.h> class ExampleWindow : public Gtk::Window { public: ExampleWindow(Glib::RefPtr<Gnome::Gda::Dict>& dict); ~ExampleWindow(); private: Glib::RefPtr<Gnome::Gda::DataModelQuery> m_model; Gtk::VBox m_box; Gtk::Label m_label; Gnome::Db::Form* m_form; };
File: examplewindow.cc
#include "examplewindow.h" #include <libgdamm/query.h> #include <libgdamm/datamodelquery.h> #include <libgdamm/datamodel.h> #include <iostream> ExampleWindow::ExampleWindow(Glib::RefPtr<Gnome::Gda::Dict>& dict) : m_label("The following Gnome::Db::Form widget displays data from the 'products' table.\n\n" "Because modification queries were provided, the data is writeable\n(except for the 'price' " "field, because these queries voluntarily omit that field)."), m_form(0) { m_box.set_border_width(6); m_box.pack_start(m_label, Gtk::PACK_SHRINK); Glib::RefPtr<Gnome::Gda::Query> query = Gnome::Gda::Query::create(dict); query->set_sql_text("SELECT ref, category, name, price, wh_stored FROM products"); // Create the demo widget: m_model = Gnome::Gda::DataModelQuery::create(query); try { //TODO: Explain what these SQL queries do: m_model->set_modification_query("UPDATE products set " "ref=##/*name:'+0' type:gchararray*/, " "category=##/*name:'+1' type:gint*/," "name=##/*name:'+2' type:gchararray*/, " "wh_stored=##/*name:'+4' type:gint*/ " "WHERE ref=##/*name:'-0' type:gchararray*/"); m_model->set_modification_query("DELETE FROM products WHERE ref=##/*name:'-0' type:gchararray*/"); m_model->set_modification_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*/)"); } catch(const Glib::Error& err) { std::cerr << "Exception Caught: " << err.what() << std::endl; exit(1); } m_form = new Gnome::Db::Form(m_model); m_box.pack_start(*m_form); add(m_box); show_all(); } ExampleWindow::~ExampleWindow() { delete m_form; }
File: main.cc
#include <libgnomedbmm.h> #include <libgdamm.h> #include <gtkmm.h> #include <iostream> #include "examplewindow.h" int main(int argc, char* argv[]) { Gtk::Main kit(argc, argv); Gnome::Db::init("Form example", "1.0", argc, argv); Glib::RefPtr<Gnome::Gda::Dict> dict = Gnome::Gda::Dict::create(); try { // We use a Gda::Dict here to read the information how to map DMBS types to Gda types from an xml file. // A Gda::Dict is a powerful repository to store informations about the underlying database and read/write them // to xml in an efficient way. Besides types it can also store other informations such as functions and aggregates. std::string filename = Glib::build_filename(LIBGNOMEDB_DATADIR, "demo_dict.xml"); dict->load_xml_file(filename); Glib::ustring connection_string = "DB_DIR=" LIBGNOMEDB_DATADIR ";DB_NAME=demo_db"; // Create a connection to the embedded sqlite database Glib::RefPtr<Gnome::Gda::Client> client = Gnome::Gda::Client::create(); Glib::RefPtr<Gnome::Gda::Connection> cnc = client->open_connection_from_string("SQLite" /* provider */, connection_string, "" /* username */, "" /* password */); // Associate the connection with the edit dict->set_connection(cnc); } catch(const Glib::Error& err) { std::cerr << err.what() << std::endl; exit(1); } ExampleWindow window(dict); kit.run(window); return 0; }
Often you might have fields in your database that should never be empty.
Gnome::Db::Form
can support you by adding a '*' next to every field
that is mandatory and showing an error message if the
user leaves this field empty. Empty in this case means an empty string or an empty
Gnome::Gda::Value
.
To set a field as mandatory you must access the underlying Gda::Parameter
of your Gda::DataModel
and set the parameter to not-null:
// Configure param to be mandatory: // Note that this must be done before the form is created. Glib::RefPtr<Gnome::Gda::DataModelIter> iter = m_model->create_iter(); Glib::RefPtr<Gnome::Gda::Parameter> param = iter->find_param("name"); param->set_not_null();
File: examplewindow.h
#include <gtkmm.h> #include <libgdamm.h> #include <libgdamm/datamodelquery.h> #include <libgnomedbmm.h> class ExampleWindow : public Gtk::Window { public: ExampleWindow(Glib::RefPtr<Gnome::Gda::Dict>& dict); ~ExampleWindow(); private: Glib::RefPtr<Gnome::Gda::DataModelQuery> m_model; Gtk::VBox m_box; Gtk::Label m_label; Gnome::Db::Form* m_form; };
File: examplewindow.cc
#include "examplewindow.h" #include <libgdamm/query.h> #include <libgdamm/datamodelquery.h> #include <libgdamm/datamodel.h> #include <iostream> ExampleWindow::ExampleWindow(Glib::RefPtr<Gnome::Gda::Dict>& dict) : m_label("The following Gnome::Db::Form widget displays data from the 'products' table.\n\n" "Because modification queries were provided, the data is writeable\n(except for the 'price' " "field, because these queries voluntarily omit that field)."), m_form(0) { m_box.set_border_width(6); m_box.pack_start(m_label, Gtk::PACK_SHRINK); Glib::RefPtr<Gnome::Gda::Query> query = Gnome::Gda::Query::create(dict); query->set_sql_text("SELECT id, name, country, city FROM warehouses"); // Create the demo widget: m_model = Gnome::Gda::DataModelQuery::create(query); try { //TODO: Explain what these SQL queries do: m_model->set_modification_query("UPDATE warehouses set " "id=##/*name:'+0' type:gint*/, " "name=##/*name:'+1' type:gchararray*/," "country=##/*name:'+2' type:gchararray*/, " "city=##/*name:'+3' type:gchararray*/ " "WHERE id=##/*name:'-0' type:gint*/"); m_model->set_modification_query("DELETE FROM warehouses WHERE id=##/*name:'-0' type:gint*/"); m_model->set_modification_query("INSERT INTO warehouses (id, name, country, city) " "VALUES (##/*name:'+0' type:gint*/, " "##/*name:'+1' type:gchararray*/, " "##/*name:'+2' type:gchararray*/, " "##/*name:'+3' type:gchararray*/)"); } catch(const Glib::Error& err) { std::cerr << "Exception Caught: " << err.what() << std::endl; exit(1); } // Configure param to be mandatory // Note that this has to be done before the form is created Glib::RefPtr<Gnome::Gda::DataModelIter> iter = m_model->create_iter(); Glib::RefPtr<Gnome::Gda::Parameter> param = iter->find_param("city"); if (param) { param->set_not_null(); } else { std::cerr << "Param not found" << std::endl; exit(1); } m_form = new Gnome::Db::Form(m_model); m_box.pack_start(*m_form); add(m_box); show_all(); } ExampleWindow::~ExampleWindow() { delete m_form; }
File: main.cc
#include <libgnomedbmm.h> #include <libgdamm.h> #include <gtkmm.h> #include <iostream> #include "examplewindow.h" int main(int argc, char* argv[]) { Gtk::Main kit(argc, argv); Gnome::Db::init("Mandatory example", "1.0", argc, argv); Glib::RefPtr<Gnome::Gda::Dict> dict = Gnome::Gda::Dict::create(); try { // We use a Gda::Dict here to read the information how to map DMBS types to Gda types from an xml file. // A Gda::Dict is a powerful repository to store informations about the underlying database and read/write them // to xml in an efficient way. Besides types it can also store other informations such as functions and aggregates. std::string filename = Glib::build_filename(LIBGNOMEDB_DATADIR, "demo_dict.xml"); dict->load_xml_file(filename); Glib::ustring connection_string = "DB_DIR=" LIBGNOMEDB_DATADIR ";DB_NAME=demo_db"; // Create a connection to the embedded sqlite database Glib::RefPtr<Gnome::Gda::Client> client = Gnome::Gda::Client::create(); Glib::RefPtr<Gnome::Gda::Connection> cnc = client->open_connection_from_string("SQLite" /* provider */, connection_string, "" /* username */, "" /* password */); // Associate the connection with the edit dict->set_connection(cnc); } catch(const Glib::Error& err) { std::cerr << err.what() << std::endl; exit(1); } ExampleWindow window(dict); kit.run(window); return 0; }