Commit 90c26844 authored by Murray Cumming's avatar Murray Cumming Committed by Murray Cumming
Browse files

Define the placeholder row as the last row, whose existance we cause just

2006-01-12  Murray Cumming   <murrayc@murrayc.com>

        * glom/utility_widgets/db_adddel/db_adddel.cc:
        * glom/utility_widgets/db_adddel/db_adddel.h:
        * glom/utility_widgets/db_adddel/glom_db_treemodel.cc:
        * glom/utility_widgets/db_adddel/glom_db_treemodel.h:
        Define the placeholder row as the last row, whose existance we
        cause just by increasing the number of rows, so that iter_next_vfunc() gives
        one more row, instead of marking a boolean. This simplifies things and
        prevents extra placeholder rows being generated.
        * glom/base_db.cc:
        * glom/frame_glom.cc:
        * glom/mode_data/box_data.cc:
        * glom/mode_data/box_data.h:
        * glom/mode_data/box_data_details.cc:
        * glom/mode_data/box_data_details.h:
        * glom/mode_data/box_data_list.cc:
        * glom/mode_data/box_data_list_related.cc:
        * glom/mode_data/box_data_list_related.h:
        * glom/mode_data/notebook_data.cc:
        * glom/mode_find/box_data_list_find.cc:
        * glom/utility_widgets/flowtablewithfields.cc:
        * glom/utility_widgets/imageglom.cc: Adapt to new API. And some changes to
        ensure that find results are shown in the appropriate view depending on whether
        there are >1 records found.
parent 3301f57c
2006-01-12 Murray Cumming <murrayc@murrayc.com>
* glom/utility_widgets/db_adddel/db_adddel.cc:
* glom/utility_widgets/db_adddel/db_adddel.h:
* glom/utility_widgets/db_adddel/glom_db_treemodel.cc:
* glom/utility_widgets/db_adddel/glom_db_treemodel.h:
Define the placeholder row as the last row, whose existance we
cause just by increasing the number of rows, so that iter_next_vfunc() gives
one more row, instead of marking a boolean. This simplifies things and
prevents extra placeholder rows being generated.
* glom/base_db.cc:
* glom/frame_glom.cc:
* glom/mode_data/box_data.cc:
* glom/mode_data/box_data.h:
* glom/mode_data/box_data_details.cc:
* glom/mode_data/box_data_details.h:
* glom/mode_data/box_data_list.cc:
* glom/mode_data/box_data_list_related.cc:
* glom/mode_data/box_data_list_related.h:
* glom/mode_data/notebook_data.cc:
* glom/mode_find/box_data_list_find.cc:
* glom/utility_widgets/flowtablewithfields.cc:
* glom/utility_widgets/imageglom.cc: Adapt to new API. And some changes to
ensure that find results are shown in the appropriate view depending on whether
there are >1 records found.
2006-01-11 Murray Cumming <murrayc@murrayc.com>
* glom/frame_glom.cc:
......
......@@ -20,4 +20,4 @@
</table><table name="staff" title="Staff"><fields><field name="staff_id" title="Staff ID" primary_key="true" unique="true" auto_increment="true" type="Number"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="name_title" title="Title" type="Text"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="name_first" title="First Name" type="Text"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="name_second" title="Second Name" type="Text"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="name_last" title="Last Name" type="Text"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="address_street" title="Street" type="Text"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="address_town" title="Town" type="Text"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="address_state" title="State" type="Text"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="address_country" title="Country" type="Text"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="address_postcode" title="Postcode" type="Text"><formatting format_thousands_separator="true" format_decimal_places="2"/></field><field name="date_of_birth" title="Date Of Birth" type="Date"><formatting format_thousands_separator="true" format_decimal_places="2"/></field></fields><relationships/><data_layouts><data_layout name="details" parent_table="staff"><data_layout_groups><data_layout_group name="header" title="Overview" columns_count="2" sequence="1"><data_layout_item name="staff_id" relationship="" use_default_formatting="true" sequence="1"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="name_last" relationship="" editable="true" use_default_formatting="true" sequence="2"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item></data_layout_group><data_layout_group name="main" title="" columns_count="2" sequence="2"><data_layout_group name="name" title="Name" columns_count="1" sequence="1"><data_layout_item name="name_title" relationship="" editable="true" use_default_formatting="true" sequence="1"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="name_first" relationship="" editable="true" use_default_formatting="true" sequence="2"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="name_second" relationship="" editable="true" use_default_formatting="true" sequence="3"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="name_last" relationship="" editable="true" use_default_formatting="true" sequence="4"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item></data_layout_group><data_layout_group name="address" title="Address" columns_count="1" sequence="2"><data_layout_item name="address_state" relationship="" editable="true" use_default_formatting="true" sequence="1"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="address_street" relationship="" editable="true" use_default_formatting="true" sequence="2"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="address_country" relationship="" editable="true" use_default_formatting="true" sequence="3"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="address_postcode" relationship="" editable="true" use_default_formatting="true" sequence="4"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="address_town" relationship="" editable="true" use_default_formatting="true" sequence="5"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item></data_layout_group><data_layout_item name="date_of_birth" relationship="" editable="true" use_default_formatting="true" sequence="3"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item></data_layout_group></data_layout_groups></data_layout><data_layout name="list" parent_table="staff"><data_layout_groups><data_layout_group name="main" title="" columns_count="1" sequence="1"><data_layout_item name="staff_id" relationship="" use_default_formatting="true" sequence="1"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="name_first" relationship="" editable="true" use_default_formatting="true" sequence="2"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="name_last" relationship="" editable="true" use_default_formatting="true" sequence="3"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="address_state" relationship="" editable="true" use_default_formatting="true" sequence="4"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="address_country" relationship="" editable="true" use_default_formatting="true" sequence="5"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item><data_layout_item name="date_of_birth" relationship="" editable="true" use_default_formatting="true" sequence="6"><formatting format_thousands_separator="true" format_decimal_places="2"/></data_layout_item></data_layout_group></data_layout_groups></data_layout></data_layouts><reports/>
</table><groups><!--These are only used when recreating a database from an example file. The actual access-control is on the server, of course.--><group name=""/><table_privs table_name="contacts" priv_view="true" priv_edit="true"/><table_privs table_name="invoice_lines" priv_view="true" priv_edit="true"/><table_privs table_name="invoices" priv_view="true" priv_edit="true"/><table_privs table_name="products" priv_view="true"/><table_privs table_name="staff" priv_view="true" priv_edit="true" priv_create="true" priv_delete="true"/><group name="accounts"/><table_privs table_name="contacts" priv_view="true" priv_edit="true"/><table_privs table_name="invoice_lines" priv_view="true" priv_edit="true"/><table_privs table_name="invoices" priv_view="true" priv_edit="true"/><table_privs table_name="products" priv_view="true"/><table_privs table_name="staff" priv_view="true" priv_edit="true" priv_create="true" priv_delete="true"/><group name="glom_developer" developer="true"/><group name="personnel_department"/><table_privs table_name="contacts" priv_view="true" priv_edit="true"/><table_privs table_name="invoice_lines" priv_view="true" priv_edit="true"/><table_privs table_name="invoices" priv_view="true" priv_edit="true"/><table_privs table_name="products" priv_view="true"/><table_privs table_name="staff" priv_view="true" priv_edit="true" priv_create="true" priv_delete="true"/></groups></glom_document>
</table><groups><!--These are only used when recreating a database from an example file. The actual access-control is on the server, of course.--><group name=""/><table_privs table_name="contacts" priv_view="true" priv_edit="true"/><table_privs table_name="invoice_lines" priv_view="true" priv_edit="true"/><table_privs table_name="invoices" priv_view="true" priv_edit="true"/><table_privs table_name="products" priv_view="true"/><table_privs table_name="staff" priv_view="true" priv_edit="true" priv_create="true" priv_delete="true"/><group name="accounts"/><table_privs table_name="contacts" priv_view="true" priv_edit="true"/><table_privs table_name="invoice_lines" priv_view="true" priv_edit="true"/><table_privs table_name="invoices" priv_view="true" priv_edit="true"/><table_privs table_name="products" priv_view="true"/><table_privs table_name="staff" priv_view="true" priv_edit="true" priv_create="true" priv_delete="true"/><group name="glom_developer" developer="true"/><table_privs table_name="contacts" priv_view="true" priv_edit="true"/><table_privs table_name="invoice_lines" priv_view="true" priv_edit="true"/><table_privs table_name="invoices" priv_view="true" priv_edit="true"/><table_privs table_name="products" priv_view="true"/><table_privs table_name="staff" priv_view="true" priv_edit="true" priv_create="true" priv_delete="true"/><group name="personnel_department"/><table_privs table_name="contacts" priv_view="true" priv_edit="true"/><table_privs table_name="invoice_lines" priv_view="true" priv_edit="true"/><table_privs table_name="invoices" priv_view="true" priv_edit="true"/><table_privs table_name="products" priv_view="true"/><table_privs table_name="staff" priv_view="true" priv_edit="true" priv_create="true" priv_delete="true"/></groups></glom_document>
......@@ -98,7 +98,7 @@ Glib::RefPtr<Gnome::Gda::DataModel> Base_DB::Query_execute(const Glib::ustring&
{
Glib::RefPtr<Gnome::Gda::Connection> gda_connection = sharedconnection->get_gda_connection();
/*
/**
try
{
std::cout << "Debug: Query_execute(): " << strQuery << std::endl;
......
......@@ -663,6 +663,7 @@ void Frame_Glom::on_button_quickfind()
else
{
Glib::ustring where_clause = get_find_where_clause_quick(Gnome::Gda::Value(criteria));
//std::cout << "Frame_Glom::on_button_quickfind(): where_clause=" << where_clause << std::endl;
on_notebook_find_criteria(where_clause);
}
}
......@@ -677,6 +678,7 @@ void Frame_Glom::on_notebook_find_criteria(const Glib::ustring& strWhereClause)
{
pApp->set_mode_data();
//std::cout << "Frame_Glom::on_notebook_find_criteria: where_clause=" << strWhereClause << std::endl;
bool records_found = m_Notebook_Data.init_db_details(m_strTableName, strWhereClause);
m_Notebook_Data.select_page_for_find_results();
......
......@@ -57,13 +57,20 @@ bool Box_Data::init_db_details(const Glib::ustring& strTableName, const Glib::us
return Box_DB_Table::init_db_details(strTableName); //Calls fill_from_database().
}
bool Box_Data::refresh_data_from_database(const Glib::ustring& strWhereClause)
bool Box_Data::refresh_data_from_database_with_where_clause(const Glib::ustring& strWhereClause)
{
std::cout << "Box_Data::refresh_data_from_database(): strWhereClause=" << strWhereClause << std::endl;
m_strWhereClause = strWhereClause;
return Box_DB_Table::refresh_data_from_database(); //Calls fill_from_database().
}
Glib::ustring Box_Data::get_where_clause() const
{
return m_strWhereClause;
}
Glib::ustring Box_Data::get_find_where_clause() const
{
Glib::ustring strClause;
......
......@@ -41,11 +41,14 @@ public:
///Create the layout for the database structure, and fill it with data from the database.
virtual bool init_db_details(const Glib::ustring& strTableName, const Glib::ustring& strWhereClause = Glib::ustring());
//Fill the existing layout with data from the databse.
virtual bool refresh_data_from_database(const Glib::ustring& strWhereClause = Glib::ustring());
//Fill the existing layout with data from the database:
virtual bool refresh_data_from_database_with_where_clause(const Glib::ustring& strWhereClause = Glib::ustring());
virtual void print_layout(); //A test, for now.
///Get the existing where clause, previously supplied to init_db_details().
Glib::ustring get_where_clause() const;
virtual Glib::ustring get_find_where_clause() const;
virtual void set_unstored_data(bool bVal);
......
......@@ -140,7 +140,7 @@ bool Box_Data_Details::init_db_details(const Glib::ustring& strTableName, const
return Box_Data::init_db_details(strTableName); //Calls create_layout(), then fill_from_database()
}
bool Box_Data_Details::refresh_data_from_database(const Gnome::Gda::Value& primary_key_value)
bool Box_Data_Details::refresh_data_from_database_with_primary_key(const Gnome::Gda::Value& primary_key_value)
{
m_primary_key_value = primary_key_value;
return fill_from_database();
......@@ -148,7 +148,7 @@ bool Box_Data_Details::refresh_data_from_database(const Gnome::Gda::Value& prima
bool Box_Data_Details::refresh_data_from_database_blank()
{
return refresh_data_from_database( Gnome::Gda::Value() );
return refresh_data_from_database_with_primary_key( Gnome::Gda::Value() );
}
void Box_Data_Details::create_layout()
......@@ -185,7 +185,7 @@ bool Box_Data_Details::fill_from_database()
const bool primary_key_is_empty = GlomConversions::value_is_empty(m_primary_key_value);
if(!primary_key_is_empty)
get_document()->set_layout_record_viewed(m_strTableName, m_layout_name, m_primary_key_value);
try
{
......@@ -298,7 +298,7 @@ void Box_Data_Details::on_button_new()
Gnome::Gda::Value primary_key_value = generate_next_auto_increment(m_strTableName, m_field_primary_key.get_name()); //TODO: This should return a Gda::Value
record_new(false /* use entered field data */, primary_key_value);
refresh_data_from_database(primary_key_value);
refresh_data_from_database_with_primary_key(primary_key_value);
}
else
{
......@@ -640,7 +640,7 @@ void Box_Data_Details::on_flowtable_field_edited(const LayoutItem_Field& layout_
Gnome::Gda::Value primary_key_value = generate_next_auto_increment(m_strTableName, m_field_primary_key.get_name());
record_new(true /* use entered field data */, primary_key_value);
refresh_data_from_database(primary_key_value);
refresh_data_from_database_with_primary_key(primary_key_value);
}
}
else
......
......@@ -33,7 +33,7 @@ public:
virtual ~Box_Data_Details();
virtual bool init_db_details(const Glib::ustring& strTableName, const Gnome::Gda::Value& primary_key_value);
virtual bool refresh_data_from_database(const Gnome::Gda::Value& primary_key_value);
virtual bool refresh_data_from_database_with_primary_key(const Gnome::Gda::Value& primary_key_value);
virtual bool refresh_data_from_database_blank();
virtual void print_layout();
......
......@@ -86,15 +86,17 @@ void Box_Data_List::enable_buttons()
allow_create = table_privs.m_create;
allow_delete = table_privs.m_delete;
}
m_AddDel.set_allow_add(allow_create);
m_AddDel.set_allow_delete(allow_delete);
m_AddDel.set_allow_view_details(table_privs.m_view);
}
bool Box_Data_List::fill_from_database()
{
//std::cout << "Box_Data_List::fill_from_database(): where_clause=" << m_strWhereClause << std::endl;
bool result = false;
Bakery::BusyCursor(*get_app_window());
......@@ -149,7 +151,7 @@ void Box_Data_List::on_adddel_user_requested_add()
{
if(m_FieldsShown.empty())
return; //Don't try to add a record to a list with no fields.
Gtk::TreeModel::iterator iter = m_AddDel.get_item_placeholder();
if(iter)
{
......@@ -180,10 +182,14 @@ void Box_Data_List::on_adddel_user_requested_add()
guint treemodel_column = 0;
bool test = get_field_column_index(m_FieldsShown[index_field_to_edit]->get_name(), treemodel_column);
if(test)
{
std::cout << "on_adddel_user_requested_add(): editing column=" << treemodel_column << std::endl;
m_AddDel.select_item(iter, treemodel_column, true /* start_editing */);
}
}
else
{
std::cout << "on_adddel_user_requested_add(): no editable rows." << std::endl;
//The only keys are non-editable, so just add a row:
on_adddel_user_added(iter, 0);
m_AddDel.select_item(iter); //without start_editing.
......@@ -223,6 +229,8 @@ void Box_Data_List::on_adddel_user_requested_delete(const Gtk::TreeModel::iterat
void Box_Data_List::on_adddel_user_added(const Gtk::TreeModel::iterator& row, guint col_with_first_value)
{
std::cout << "Box_Data_List::on_adddel_user_added" << std::endl;
Gnome::Gda::Value primary_key_value;
Field field_primary_key = m_AddDel.get_key_field();
......@@ -251,6 +259,8 @@ void Box_Data_List::on_adddel_user_added(const Gtk::TreeModel::iterator& row, gu
Glib::RefPtr<Gnome::Gda::DataModel> data_model = record_new(true /* use entered field data*/, primary_key_value);
if(data_model)
{
std::cout << "Box_Data_List::on_adddel_user_added debug `" << std::endl;
//Save the primary key value for later use:
m_AddDel.set_value_key(row, primary_key_value);
......@@ -259,6 +269,8 @@ void Box_Data_List::on_adddel_user_added(const Gtk::TreeModel::iterator& row, gu
//If it's an auto-increment, then get the value and show it:
if(field_primary_key.get_auto_increment())
{
std::cout << "Box_Data_List::on_adddel_user_added debug 2" << std::endl;
LayoutItem_Field layout_item;
layout_item.m_field = field_primary_key;
m_AddDel.set_value(row, layout_item, primary_key_value);
......@@ -266,6 +278,8 @@ void Box_Data_List::on_adddel_user_added(const Gtk::TreeModel::iterator& row, gu
on_record_added(primary_key_value);
std::cout << "Box_Data_List::on_adddel_user_added debug 3" << std::endl;
//Do any lookups, etc, trigerred by the change of value of the original changed field:
on_adddel_user_changed(row, col_with_first_value);
}
......@@ -274,6 +288,8 @@ void Box_Data_List::on_adddel_user_added(const Gtk::TreeModel::iterator& row, gu
}
else
{
std::cout << "Box_Data_List::on_adddel_user_added debug: add record failed." << std::endl;
//Add Record failed.
//Replace with correct values:
fill_from_database();
......@@ -371,6 +387,7 @@ void Box_Data_List::on_adddel_user_changed(const Gtk::TreeModel::iterator& row,
//Update the field in the record (the record with this primary key):
const Gnome::Gda::Value field_value = m_AddDel.get_value(row, layout_field);
std::cout << "Box_Data_List::on_adddel_user_changed(): field_value = " << field_value.to_string() << std::endl;
//const Field& field = layout_field.m_field;
//const Glib::ustring strFieldName = layout_field.get_name();
......@@ -683,7 +700,7 @@ void Box_Data_List::create_layout()
sharedptr<LayoutItem_Field> field = *iter;
if(m_read_only)
field->set_editable(false);
m_AddDel.add_column(*field);
}
......
......@@ -106,7 +106,7 @@ bool Box_Data_List_Related::init_db_details(const LayoutItem_Portal& portal)
return Box_Data_List::init_db_details(m_portal.m_relationship.get_to_table()); //Calls create_layout() and fill_from_database().
}
bool Box_Data_List_Related::refresh_data_from_database(const Gnome::Gda::Value& foreign_key_value)
bool Box_Data_List_Related::refresh_data_from_database_with_foreign_key(const Gnome::Gda::Value& foreign_key_value)
{
m_key_value = foreign_key_value;
......@@ -115,11 +115,11 @@ bool Box_Data_List_Related::refresh_data_from_database(const Gnome::Gda::Value&
Glib::ustring strWhereClause = m_key_field.get_name() + " = " + m_key_field.sql(m_key_value);
//g_warning("refresh_data_from_database(): where_clause=%s", strWhereClause.c_str());
return Box_Data_List::refresh_data_from_database(strWhereClause);
return Box_Data_List::refresh_data_from_database_with_where_clause(strWhereClause);
}
else
{
g_warning("Box_Data_List_Related::refresh_data_from_database(): m_key_value is NULL.");
g_warning("Box_Data_List_Related::refresh_data_from_database_with_foreign_key(): m_key_value is NULL.");
return false;
}
//TODO: Clear the list if there is no key value?
......
......@@ -43,7 +43,7 @@ public:
* @param foreign_key_value: The value that should be found in this table.
* @param from_table_primary_key_value The primary key of the parent record's table, used to associate new related records.
*/
virtual bool refresh_data_from_database(const Gnome::Gda::Value& foreign_key_value);
virtual bool refresh_data_from_database_with_foreign_key(const Gnome::Gda::Value& foreign_key_value);
virtual Relationship get_relationship() const;
virtual Field get_key_field() const;
......
......@@ -36,7 +36,7 @@ Notebook_Data::Notebook_Data()
//Allow List to ask Details to show a record.
m_Box_List.signal_user_requested_details().connect(sigc::mem_fun(*this, &Notebook_Data::on_list_user_requested_details));
//Allow Details to ask List to ask Details to show a different record:
m_Box_Details.signal_nav_first().connect(sigc::mem_fun(m_Box_List, &Box_Data_List::on_details_nav_first));
m_Box_Details.signal_nav_prev().connect(sigc::mem_fun(m_Box_List, &Box_Data_List::on_details_nav_previous));
......@@ -74,15 +74,24 @@ bool Notebook_Data::init_db_details(const Glib::ustring& strTableName, const Gli
{
sharedptr<SharedConnection> sharedconnection = connect_to_server();
const Glib::ustring old_where_clause = m_Box_List.get_where_clause();
//std::cout << " old_where_clause=" << old_where_clause << std::endl;
//std::cout << " strWhereClause=" << strWhereClause << std::endl;
const bool new_find_set = (strWhereClause != old_where_clause);
result = m_Box_List.init_db_details(m_table_name, strWhereClause);
//m_Box_List.load_from_document();
//Show the previously-shown record, if there is one,
//Show the previously-shown record, if there is one, if this is not a new found-set (via a new where_clause)
//so that returning to this table will return the user to the same record:
Document_Glom* document = get_document();
if(document)
{
Gnome::Gda::Value primary_key_for_details = document->get_layout_record_viewed(m_table_name, m_Box_Details.get_layout_name());
Gnome::Gda::Value primary_key_for_details;
if(!new_find_set)
{
primary_key_for_details = document->get_layout_record_viewed(m_table_name, m_Box_Details.get_layout_name());
}
if(GlomConversions::value_is_empty(primary_key_for_details))
{
......@@ -92,7 +101,7 @@ bool Notebook_Data::init_db_details(const Glib::ustring& strTableName, const Gli
primary_key_for_details = m_Box_List.get_primary_key_value_first();
}
m_Box_Details.init_db_details(m_table_name, primary_key_for_details);
m_Box_Details.init_db_details(m_table_name, primary_key_for_details);
}
}
......@@ -133,14 +142,14 @@ bool Notebook_Data::init_db_details(const Glib::ustring& strTableName, const Gli
void Notebook_Data::on_list_user_requested_details(const Gnome::Gda::Value& primary_key_value)
{
m_Box_Details.refresh_data_from_database(primary_key_value);
m_Box_Details.refresh_data_from_database_with_primary_key(primary_key_value);
set_current_page(m_iPage_Details);
}
void Notebook_Data::on_Details_user_requested_related_details(const Glib::ustring& strTableName, Gnome::Gda::Value primary_key_value)
{
signal_record_details_requested().emit(strTableName, primary_key_value);
/*
//Show a different table:
init_db_details(m_table_name);
......@@ -185,7 +194,7 @@ void Notebook_Data::do_menu_file_print()
Box_Data* pBox = dynamic_cast<Box_Data*>(pChild);
if(pBox)
pBox->print_layout();
}
}
}
enum dataview
......@@ -232,6 +241,7 @@ void Notebook_Data::on_switch_page_handler(GtkNotebookPage* pPage, guint uiPageN
//And refresh the list view whenever it is shown, to
//a) show any new records that were added via the details view, or via a related portal elsewhere.
//b) show changed field contents, changed elsewhere.
//TODO_Performance: This causes double refreshes (with database retrieval) when doing finds. We probably want to distinguish between user page-switches and programmatic page-switches.
if(box == &m_Box_List)
{
Gnome::Gda::Value primary_key_selected = m_Box_List.get_primary_key_value_selected();
......
......@@ -30,7 +30,7 @@ Box_Data_List_Find::Box_Data_List_Find()
pack_start(m_HBox, Gtk::PACK_SHRINK);
m_Button_Find.property_can_default() = true; //TODO: Make this a real method in gtkmm?
show_all_children();
}
......@@ -56,7 +56,7 @@ bool Box_Data_List_Find::fill_from_database()
m_FieldsShown = get_fields_to_show();
m_AddDel.add_item(Gnome::Gda::Value("find"));
//m_AddDel.add_item(Gnome::Gda::Value("find"));
return result;
}
......
......@@ -303,7 +303,7 @@ bool DbAddDel::on_button_press_event_Popup(GdkEventButton *event)
{
//Double-click means edit.
//Don't do this usually, because users sometimes double-click by accident when they just want to edit a cell.
//TODO: If the cell is not editable, handle the double-click as an edit/selection.
//on_MenuPopup_activate_Edit();
return false; //Not handled.
......@@ -316,56 +316,7 @@ bool DbAddDel::on_button_press_event_Popup(GdkEventButton *event)
Gtk::TreeModel::iterator DbAddDel::get_item_placeholder()
{
//Get the existing placeholder row, or add one if necessary:
Gtk::TreeModel::iterator iter = get_last_row();
if( get_is_placeholder_row(iter) )
{
return iter;
}
else
{
return add_item_placeholder();
}
}
Gtk::TreeModel::iterator DbAddDel::add_item_placeholder()
{
Gtk::TreeModel::iterator iter;
//Placeholder rows are for adding new records.
if(!m_allow_add)
return iter;
iter = m_refListStore->append();
if(iter)
{
m_refListStore->set_is_placeholder(iter, true);
m_refListStore->set_key_value(iter, Gnome::Gda::Value()); //Remove temporary key value.
}
return iter;
}
Gtk::TreeModel::iterator DbAddDel::add_item(const Gnome::Gda::Value& valKey)
{
if(!(get_model()))
return Gtk::TreeModel::iterator();
Gtk::TreeModel::iterator result = get_next_available_row_with_add_if_necessary();
if(result)
{
Gtk::TreeModel::Row treerow = *result;
if(treerow)
{
set_value_key(result, valKey);
m_refListStore->set_is_placeholder(result, false);
//treerow[*m_modelcolumn_placeholder] = false;
}
}
add_blank(); //if necessary
return result;
return m_refListStore->get_placeholder_row();
}
void DbAddDel::remove_all()
......@@ -478,7 +429,7 @@ bool DbAddDel::select_item(const Gtk::TreeModel::iterator& iter, guint column, b
if(refTreeSelection)
{
refTreeSelection->select(iter);
Gtk::TreeModel::Path path = m_refListStore->get_path(iter);
guint view_column_index = 0;
......@@ -518,35 +469,6 @@ guint DbAddDel::get_count() const
return iCount;
}
void DbAddDel::add_blank()
{
bool bPreventUserSignals = get_prevent_user_signals();
set_prevent_user_signals(true);
bool bAddNewBlank = false;
if(get_allow_user_actions()) //The extra blank line is only used if the user may add items:
{
Gtk::TreeModel::iterator iter = get_last_row();
if(get_is_placeholder_row(iter))
{
bAddNewBlank = false; //One already exists.
}
else
{
bAddNewBlank = true; // The last line isn't a placeholder. Add one.
}
}
if(bAddNewBlank)
{
add_item_placeholder();
}
set_prevent_user_signals(bPreventUserSignals);
}
guint DbAddDel::get_columns_count() const
{
return m_TreeView.get_columns().size();
......@@ -811,7 +733,7 @@ void DbAddDel::construct_specified_columns()
m_TreeView.columns_autosize();
//Make sure there's a blank row after the database rows that have just been added.
add_blank();
//add_blank();
}
bool DbAddDel::refresh_from_database()
......@@ -858,9 +780,9 @@ void DbAddDel::set_value(const Gtk::TreeModel::iterator& iter, const LayoutItem_
}
//Add extra blank if necessary:
add_blank();
//add_blank();
}
//g_warning("DbAddDel::set_value end");
}
......@@ -913,6 +835,11 @@ void DbAddDel::set_where_clause(const Glib::ustring& where_clause)
m_where_clause = where_clause;
}
Glib::ustring DbAddDel::get_where_clause() const
{
return m_where_clause;
}
void DbAddDel::set_columns_ready()
{
m_columns_ready = true;
......@@ -999,8 +926,7 @@ void DbAddDel::set_allow_delete(bool val)
{
m_allow_delete = val;
}
void DbAddDel::set_allow_user_actions(bool bVal)
{
m_bAllowUserActions = bVal;
......@@ -1226,10 +1152,9 @@ void DbAddDel::on_treeview_cell_edited(const Glib::ustring& path_string, const G
set_prevent_user_signals(true); //Stops extra signal_user_changed.
//Mark this row as no longer a placeholder, because it has data now. The client code must set an actual key for this in the signal_user_added() or m_signal_user_changed signal handlers.
//m_refListStore->set_is_placeholder(iter, false);
m_refListStore->set_is_not_placeholder(iter);
//Don't mark this as not a placeholder, because it's still a placeholder until it has a key value.
add_item_placeholder(); //Add the next blank for the next user add, if necessary.
set_prevent_user_signals(bPreventUserSignals);
bIsAdd = true; //Signal that a new key was added.
......@@ -1531,49 +1456,6 @@ bool DbAddDel::get_is_last_row(const Gtk::TreeModel::iterator& iter) const
return false;
}
Gtk::TreeModel::iterator DbAddDel::get_next_available_row_with_add_if_necessary()
{
Gtk::TreeModel::iterator result;
if(!m_refListStore)
return result;
bool bPreventUserSignals = get_prevent_user_signals();
set_prevent_user_signals(true);
if(get_allow_user_actions()) //The extra blank line is only used if the user may add items:
{
Gtk::TreeModel::iterator iter = get_last_row();
if(iter != get_model()->children().end())
{
//Look at the last row:
if( get_is_placeholder_row(iter))
{
result = iter;
}
else
{
// The last line isn't blank, so we cannot use it. Add another one.
result = m_refListStore->append();
}
}
else
{
// This is the first line.
result = m_refListStore->append();
}
}
else
{
result = m_refListStore->append(); //Add a new blank line. There are no blank lines.
}
set_prevent_user_signals(bPreventUserSignals);
return result;
}
Gtk::TreeModel::iterator DbAddDel::get_last_row() const
{