[glom] Print Layout: Related Records: Expand according to min/max rows count.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] Print Layout: Related Records: Expand according to min/max rows count.
- Date: Tue, 11 Oct 2011 23:14:45 +0000 (UTC)
commit 80944392a44b96a95e30bfe5a244acc349c3f52f
Author: Murray Cumming <murrayc murrayc com>
Date: Wed Oct 12 01:14:39 2011 +0200
Print Layout: Related Records: Expand according to min/max rows count.
* glom/print_layout/canvas_layout_item.[h|cc]:
Moved get_canvas_table_cell_child() here from CanvasPrintLayout.
create_canvas_item_for_layout_item(): Move the table-child creation
code into add_portal_rows_if_necessary().
* glom/print_layout/canvas_print_layout.[h|cc]: fill_with_data_portal():
Add rows, up to the maximum, according to the number of database rows.
* glom/print_layout/print_layout_utils.cc: create_standard():
Set a simple default height for one row, but set a min of 1 and a max
of 100 so it will expand later.
ChangeLog | 14 ++
.../data_structure/layout/layoutitem_portal.cc | 4 +
glom/print_layout/canvas_layout_item.cc | 223 +++++++++++++-------
glom/print_layout/canvas_layout_item.h | 11 +
glom/print_layout/canvas_print_layout.cc | 68 +++----
glom/print_layout/canvas_print_layout.h | 2 -
glom/print_layout/print_layout_utils.cc | 18 +-
7 files changed, 213 insertions(+), 127 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 844237d..cce74dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2011-10-12 Murray Cumming <murrayc murrayc com>
+
+ Print Layout: Related Records: Expand according to min/max rows count.
+
+ * glom/print_layout/canvas_layout_item.[h|cc]:
+ Moved get_canvas_table_cell_child() here from CanvasPrintLayout.
+ create_canvas_item_for_layout_item(): Move the table-child creation
+ code into add_portal_rows_if_necessary().
+ * glom/print_layout/canvas_print_layout.[h|cc]: fill_with_data_portal():
+ Add rows, up to the maximum, according to the number of database rows.
+ * glom/print_layout/print_layout_utils.cc: create_standard():
+ Set a simple default height for one row, but set a min of 1 and a max
+ of 100 so it will expand later.
+
2011-10-11 Murray Cumming <murrayc murrayc com>
Update the example files for the portal rows count change.
diff --git a/glom/libglom/data_structure/layout/layoutitem_portal.cc b/glom/libglom/data_structure/layout/layoutitem_portal.cc
index 1af0fa8..339bdf6 100644
--- a/glom/libglom/data_structure/layout/layoutitem_portal.cc
+++ b/glom/libglom/data_structure/layout/layoutitem_portal.cc
@@ -193,6 +193,10 @@ void LayoutItem_Portal::set_rows_count(gulong rows_count_min, gulong rows_count_
{
m_rows_count_min = rows_count_min;
m_rows_count_max = rows_count_max;
+
+ //Keep the values sane:
+ if(m_rows_count_max < m_rows_count_min)
+ m_rows_count_max = m_rows_count_min;
}
double LayoutItem_Portal::get_print_layout_row_line_width() const
diff --git a/glom/print_layout/canvas_layout_item.cc b/glom/print_layout/canvas_layout_item.cc
index 02c5395..e5ce553 100644
--- a/glom/print_layout/canvas_layout_item.cc
+++ b/glom/print_layout/canvas_layout_item.cc
@@ -163,6 +163,7 @@ void CanvasLayoutItem::set_layout_item(const sharedptr<LayoutItem>& layout_item)
}
}
+//TODO: Remove this?
int CanvasLayoutItem::get_rows_count_for_portal(const sharedptr<const LayoutItem_Portal>& portal, double& row_height)
{
if(!portal)
@@ -182,6 +183,7 @@ int CanvasLayoutItem::get_rows_count_for_portal(const sharedptr<const LayoutItem
const double max_rows_fraction = total_height / row_height;
double max_rows = 0;
modf(max_rows_fraction, &max_rows);
+ std::cout << "debug: max_rows=" << max_rows << ", for total_height=" << total_height << ", row_height=" << row_height << std::endl;
return max_rows;
}
@@ -284,83 +286,10 @@ Glib::RefPtr<CanvasItemMovable> CanvasLayoutItem::create_canvas_item_for_layout_
portal->get_print_layout_column_line_width(),
portal->get_print_layout_line_color());
- //Show as many rows as can fit in the height.
- double row_height = 0;
- const int max_rows = get_rows_count_for_portal(portal, row_height);
- //std::cout << "DEBUG: max_rows=" << max_rows << ", row_height=" << row_height << std::endl;
-
- const LayoutGroup::type_list_items child_items = portal->get_items();
-
- for(guint row = 0; row < (guint)max_rows; ++row)
- {
- guint col = 0;
- const guint num_cols = child_items.size();
- bool something_expanded = false;
- for(LayoutGroup::type_list_items::const_iterator iter = child_items.begin(); iter != child_items.end(); ++iter)
- {
- sharedptr<LayoutItem> layout_item = *iter;
-
- //We use create_canvas_item_for_layout_item() instead of just
- //creating another CanvasLayoutItem, because that would be a group,
- //but goocanvas cannot yet support Groups inside Tables. murrayc.
- //TODO: Bug number.
- Glib::RefPtr<CanvasItemMovable> cell = create_canvas_item_for_layout_item(layout_item);
- Glib::RefPtr<Goocanvas::Item> cell_as_item = CanvasItemMovable::cast_to_item(cell);
-
- if(cell && cell_as_item)
- {
- const guint width = layout_item->get_display_width();
- bool expand = (width == 0);
-
- //If this is the last item, and no other item has expanded,
- //let this one expand,
- //Otherwise, we could allocate less space than the table has left.
- //TODO: Prevent the user from allocating _more_ space than the table has.
- if(!something_expanded && (col == (num_cols - 1)))
- {
- expand = true;
- }
-
- if(expand)
- {
- //Let the table allocate the width automatically:
-
- cell->set_width_height(-1, row_height);
- canvas_item->attach(cell_as_item,
- col /* left_attach */, col + 1 /* right_attach */,
- row /* top_attach */, row + 1 /* right_attach */,
- (Gtk::AttachOptions)(Gtk::FILL | Gtk::EXPAND), (Gtk::AttachOptions)(Gtk::FILL | Gtk::EXPAND));
-
- something_expanded = true;
- }
- else
- {
- //Enforce a width:
-
- //TODO: Add/Remove rows when resizing, instead of resizing the rows:
- cell->set_width_height(width, row_height);
-
- canvas_item->attach(cell_as_item,
- col /* left_attach */, col + 1 /* right_attach */,
- row /* top_attach */, row + 1 /* right_attach */,
- (Gtk::FILL), (Gtk::AttachOptions)(Gtk::FILL | Gtk::EXPAND));
-
- //Add a second item (an invisible rect) to make sure that the size is really used:
- Glib::RefPtr<Goocanvas::Rect> rect =
- Goocanvas::Rect::create(0, 0, width, row_height);
- //TODO: Find out why this doesn't work: rect->property_stroke_pattern() = Cairo::RefPtr<Cairo::Pattern>();
- g_object_set(rect->gobj(), "stroke-pattern", (void*)0, (void*)0);
-
- canvas_item->attach(rect,
- col /* left_attach */, col + 1 /* right_attach */,
- row /* top_attach */, row + 1 /* right_attach */,
- Gtk::SHRINK, Gtk::SHRINK);
- }
- }
-
- ++col;
- }
- }
+ gulong rows_count_min = 0;
+ gulong rows_count_max = 0;
+ portal->get_rows_count(rows_count_min, rows_count_max);
+ add_portal_rows_if_necessary(canvas_item, portal, rows_count_min);
child = canvas_item;
child_item = canvas_item;
@@ -381,6 +310,146 @@ Glib::RefPtr<CanvasItemMovable> CanvasLayoutItem::create_canvas_item_for_layout_
return child;
}
+
+Glib::RefPtr<Goocanvas::Item> CanvasLayoutItem::get_canvas_table_cell_child(const Glib::RefPtr<Goocanvas::Table>& table, int row, int col)
+{
+ Glib::RefPtr<Goocanvas::Item> result;
+
+ if(!table)
+ return result;
+
+ const int count = table->get_n_children();
+ for(int i = 0; i < count; ++i)
+ {
+ Glib::RefPtr<Goocanvas::Item> child = table->get_child(i);
+ if(!child)
+ continue;
+
+ int column_value = 0;
+ table->get_child_property(child, "column", column_value);
+ int row_value = 0;
+ table->get_child_property(child, "row", row_value);
+
+ //This assumes that all items occupy only one cell:
+ if( (column_value == col) &&
+ (row_value == row) )
+ {
+ return child;
+ }
+ }
+
+ return result;
+}
+
+void CanvasLayoutItem::add_portal_rows_if_necessary(guint rows_count)
+{
+ Glib::RefPtr<CanvasItemMovable> child = get_child();
+ Glib::RefPtr<CanvasTableMovable> canvas_table =
+ Glib::RefPtr<CanvasTableMovable>::cast_dynamic(child);
+ if(!canvas_table)
+ return;
+
+ sharedptr<LayoutItem_Portal> portal =
+ sharedptr<LayoutItem_Portal>::cast_dynamic(get_layout_item());
+ if(!portal)
+ {
+ std::cerr << G_STRFUNC << ": The layout item was not a portal." << std::endl;
+ return;
+ }
+
+ add_portal_rows_if_necessary(canvas_table, portal, rows_count);
+}
+
+void CanvasLayoutItem::add_portal_rows_if_necessary(const Glib::RefPtr<CanvasTableMovable>& canvas_table, const sharedptr<LayoutItem_Portal>& portal, guint rows_count)
+{
+ const double row_height = portal->get_print_layout_row_height();
+ const LayoutGroup::type_list_items child_items = portal->get_items();
+
+ for(guint row = 0; row < rows_count; ++row)
+ {
+ guint col = 0;
+ const guint num_cols = child_items.size();
+ bool something_expanded = false;
+ for(LayoutGroup::type_list_items::const_iterator iter = child_items.begin(); iter != child_items.end(); ++iter)
+ {
+ //std::cout << " row=" << row << ", col=" << col << std::endl;
+ sharedptr<LayoutItem> layout_item = *iter;
+
+ //Check if a child already exists:
+ Glib::RefPtr<Goocanvas::Item> existing_child =
+ get_canvas_table_cell_child(canvas_table, row, col);
+ if(existing_child)
+ {
+ //std::cout << " existing child" << std::endl;
+ col++;
+ continue;
+ }
+
+ //We use create_canvas_item_for_layout_item() instead of just
+ //creating another CanvasLayoutItem, because that would be a group,
+ //but goocanvas cannot yet support Groups inside Tables. murrayc.
+ //TODO: Bug number.
+ Glib::RefPtr<CanvasItemMovable> cell = create_canvas_item_for_layout_item(layout_item);
+ Glib::RefPtr<Goocanvas::Item> cell_as_item = CanvasItemMovable::cast_to_item(cell);
+
+ if(cell && cell_as_item)
+ {
+ std::cout << " creating child" << std::endl;
+
+ const guint width = layout_item->get_display_width();
+ bool expand = (width == 0);
+
+ //If this is the last item, and no other item has expanded,
+ //let this one expand,
+ //Otherwise, we could allocate less space than the table has left.
+ //TODO: Prevent the user from allocating _more_ space than the table has.
+ if(!something_expanded && (col == (num_cols - 1)))
+ {
+ expand = true;
+ }
+
+ if(expand)
+ {
+ //Let the table allocate the width automatically:
+
+ cell->set_width_height(-1, row_height);
+ canvas_table->attach(cell_as_item,
+ col /* left_attach */, col + 1 /* right_attach */,
+ row /* top_attach */, row + 1 /* right_attach */,
+ (Gtk::AttachOptions)(Gtk::FILL | Gtk::EXPAND), (Gtk::AttachOptions)(Gtk::FILL | Gtk::EXPAND));
+
+ something_expanded = true;
+ }
+ else
+ {
+ //Enforce a width:
+
+ //TODO: Add/Remove rows when resizing, instead of resizing the rows:
+ cell->set_width_height(width, row_height);
+
+ canvas_table->attach(cell_as_item,
+ col /* left_attach */, col + 1 /* right_attach */,
+ row /* top_attach */, row + 1 /* right_attach */,
+ (Gtk::FILL), (Gtk::AttachOptions)(Gtk::FILL | Gtk::EXPAND));
+
+ //Add a second item (an invisible rect) to make sure that the size is really used:
+ Glib::RefPtr<Goocanvas::Rect> rect =
+ Goocanvas::Rect::create(0, 0, width, row_height);
+ //TODO: Find out why this doesn't work: rect->property_stroke_pattern() = Cairo::RefPtr<Cairo::Pattern>();
+ g_object_set(rect->gobj(), "stroke-pattern", (void*)0, (void*)0);
+
+ canvas_table->attach(rect,
+ col /* left_attach */, col + 1 /* right_attach */,
+ row /* top_attach */, row + 1 /* right_attach */,
+ Gtk::SHRINK, Gtk::SHRINK);
+ }
+ }
+
+ ++col;
+ }
+ }
+}
+
void CanvasLayoutItem::set_db_data(const Gnome::Gda::Value& value)
{
sharedptr<LayoutItem_Field> field = sharedptr<LayoutItem_Field>::cast_dynamic(m_layout_item);
diff --git a/glom/print_layout/canvas_layout_item.h b/glom/print_layout/canvas_layout_item.h
index 954243b..7db7c08 100644
--- a/glom/print_layout/canvas_layout_item.h
+++ b/glom/print_layout/canvas_layout_item.h
@@ -24,11 +24,13 @@
#include <glom/utility_widgets/canvas/canvas_group_resizable.h>
#include <libglom/data_structure/layout/layoutitem_withformatting.h>
#include <libgdamm/value.h>
+#include <goocanvasmm/table.h>
namespace Glom
{
class CanvasTextMovable;
+class CanvasTableMovable;
class FieldFormatting;
class LayoutItem_Portal;
@@ -67,12 +69,21 @@ public:
*/
void update_layout_position_from_canvas();
+ /* Add table child items if any are missing,
+ * for instance if the table has been made bigger.
+ */
+ void add_portal_rows_if_necessary(guint rows_count);
+
+ static Glib::RefPtr<Goocanvas::Item> get_canvas_table_cell_child(const Glib::RefPtr<Goocanvas::Table>& table, int row, int col); //TODO: Add this to Goocanvas::Table.
+
private:
/// Create the appropriate inner canvas item to represent the layout item.
static Glib::RefPtr<CanvasItemMovable> create_canvas_item_for_layout_item(const sharedptr<LayoutItem>& layout_item);
static void apply_formatting(const Glib::RefPtr<CanvasTextMovable>& canvas_item, const sharedptr<const LayoutItem_WithFormatting>& layout_item);
+ static void add_portal_rows_if_necessary(const Glib::RefPtr<CanvasTableMovable>& canvas_table, const sharedptr<LayoutItem_Portal>& portal, guint rows_count);
+
void on_resized();
sharedptr<LayoutItem> m_layout_item;
diff --git a/glom/print_layout/canvas_print_layout.cc b/glom/print_layout/canvas_print_layout.cc
index 6927b9d..fe3a43e 100644
--- a/glom/print_layout/canvas_print_layout.cc
+++ b/glom/print_layout/canvas_print_layout.cc
@@ -894,17 +894,35 @@ void Canvas_PrintLayout::fill_with_data_portal(const Glib::RefPtr<CanvasLayoutIt
found_set.m_table_name = portal->get_table_used(Glib::ustring() /* parent table_name, not used. */);
set_found_set_where_clause_for_portal(found_set, portal, foreign_key_value);
- Glib::RefPtr<Gnome::Gda::SqlBuilder> sql_query = Utils::build_sql_select_with_where_clause(found_set.m_table_name, fields_shown, found_set.m_where_clause, found_set.m_extra_join, found_set.m_sort_clause);
+ const Glib::RefPtr<Gnome::Gda::SqlBuilder> sql_query = Utils::build_sql_select_with_where_clause(found_set.m_table_name, fields_shown, found_set.m_where_clause, found_set.m_extra_join, found_set.m_sort_clause);
//std::cout << "DEBUG: sql_query=" << sql_query << std::endl;
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel = DbUtils::query_execute_select(sql_query);
+ const Glib::RefPtr<const Gnome::Gda::DataModel> datamodel = DbUtils::query_execute_select(sql_query);
if(!(datamodel))
return;
- const int db_rows_count = datamodel->get_n_rows();
+ const int db_rows_count = datamodel->get_n_rows(); //TODO: Performance? COUNT them instead?
const int db_columns_count = datamodel->get_n_columns();
- double row_height_ignored = 0;
- const int rows_count = CanvasLayoutItem::get_rows_count_for_portal(portal, row_height_ignored);
+ //Show as many rows as needed, but not more than the maximum:
+ gulong rows_count_min = 0;
+ gulong rows_count_max = 0;
+ portal->get_rows_count(rows_count_min, rows_count_max);
+ int rows_count = std::min((int)rows_count_max, db_rows_count);
+ //Do not use less than the minimum:
+ rows_count = std::max(rows_count, (int)rows_count_min);
+
+ // TODO: Remove this method and/or change it to recalc the min when changing the height:
+ //CanvasLayoutItem::get_rows_count_for_portal(portal, row_height_ignored);
+ const double portal_height = rows_count * portal->get_print_layout_row_height();
+
+ double old_width = 0;
+ double old_height = 0;
+ canvas_item->get_width_height(old_width, old_height);
+ canvas_item->set_width_height(old_width, portal_height);
+ std::cout << G_STRFUNC << ": portal_height = " << portal_height << ", for rows_count=" << rows_count << std::endl;
+ canvas_item->add_portal_rows_if_necessary(rows_count);
+ //TODO: Move everything else down.
+
const int cols_count = child_layout_items.size();
//Set the DB value for each cell:
@@ -915,9 +933,13 @@ void Canvas_PrintLayout::fill_with_data_portal(const Glib::RefPtr<CanvasLayoutIt
for(int col = 0; col < cols_count; ++col)
{
//Glib::RefPtr<Goocanvas::Item> canvas_child = base_item->get_cell_child(row, col); //TODO: Add this to Goocanvas::Table.
- Glib::RefPtr<Goocanvas::Item> canvas_child = get_canvas_table_cell_child(canvas_table, row, col); //TODO: Add this to Goocanvas::Table.
+ Glib::RefPtr<Goocanvas::Item> canvas_child =
+ CanvasLayoutItem::get_canvas_table_cell_child(canvas_table, row, col); //TODO: Add this to Goocanvas::Table.
if(!canvas_child)
- std::cerr << G_STRFUNC << ": canvas_child is NULL." << std::endl;
+ {
+ std::cerr << G_STRFUNC << ": canvas_child is NULL for row=" << row << ", col=" << col << std::endl;
+ continue;
+ }
if(iter_child_layout_items == child_layout_items.end())
continue;
@@ -1016,38 +1038,6 @@ void Canvas_PrintLayout::set_grid_gap(double gap)
m_bounds_group->lower();
}
-Glib::RefPtr<Goocanvas::Item> Canvas_PrintLayout::get_canvas_table_cell_child(const Glib::RefPtr<Goocanvas::Table>& table, int row, int col)
-{
- Glib::RefPtr<Goocanvas::Item> result;
-
- if(!table)
- return result;
-
- const int count = table->get_n_children();
- for(int i = 0; i < count; ++i)
- {
- Glib::RefPtr<Goocanvas::Item> child = table->get_child(i);
- if(!child)
- continue;
-
- int column_value = 0;
- table->get_child_property(child, "column", column_value);
- int row_value = 0;
- table->get_child_property(child, "row", row_value);
-
- //This assumes that all items occupy only one cell:
- if( (column_value == col) &&
- (row_value == row) )
- {
- return child;
- }
- }
-
- return result;
-}
-
-
-
Base_DB::type_vecConstLayoutFields Canvas_PrintLayout::get_portal_fields_to_show(const sharedptr<LayoutItem_Portal>& portal)
{
const Document* document = get_document();
diff --git a/glom/print_layout/canvas_print_layout.h b/glom/print_layout/canvas_print_layout.h
index 4abea0f..50c1f84 100644
--- a/glom/print_layout/canvas_print_layout.h
+++ b/glom/print_layout/canvas_print_layout.h
@@ -103,8 +103,6 @@ private:
void fill_with_data(const Glib::RefPtr<Goocanvas::Group>& canvas_group, const FoundSet& found_set);
void fill_with_data_portal(const Glib::RefPtr<CanvasLayoutItem>& canvas_item, const Gnome::Gda::Value& foreign_key_value);
static void set_canvas_item_field_value(const Glib::RefPtr<Goocanvas::Item>& canvas_item, const sharedptr<const LayoutItem_Field>& field, const Gnome::Gda::Value& value);
-
- static Glib::RefPtr<Goocanvas::Item> get_canvas_table_cell_child(const Glib::RefPtr<Goocanvas::Table>& table, int row, int col); //TODO: Add this to Goocanvas::Table.
type_vecConstLayoutFields get_portal_fields_to_show(const sharedptr<LayoutItem_Portal>& portal);
diff --git a/glom/print_layout/print_layout_utils.cc b/glom/print_layout/print_layout_utils.cc
index 8312163..991bd42 100644
--- a/glom/print_layout/print_layout_utils.cc
+++ b/glom/print_layout/print_layout_utils.cc
@@ -115,15 +115,15 @@ static void create_standard(const sharedptr<const LayoutGroup>& layout_group, co
sharedptr<LayoutItem_Portal> portal_clone = glom_sharedptr_clone(portal);
portal_clone->set_print_layout_row_height(field_height); //Otherwise it will be 0, which is useless.
- double height = ITEM_HEIGHT;
- gulong rows_count_min = 0;
- gulong rows_count_max = 0;
- portal->get_rows_count(rows_count_min, rows_count_max);
- if(rows_count_min)
- height = ITEM_HEIGHT * rows_count_min; //TODO: Expand to max when necessary.
-
- portal_clone->set_print_layout_position(x, y, item_width, height); //TODO: Enough and no more.
- y += height + gap; //padding.
+ //We ignore the rows count for the details layout's portal,
+ //because that is only suitable for the on-screen layout,
+ //and because, on the print layout, we want to show (almost) all rows:
+ portal_clone->set_rows_count(1 /* min */, 100 /* max */);
+
+ //Set an initial default height, though this will be changed
+ //when we fill it with data:
+ portal_clone->set_print_layout_position(x, y, item_width, field_height);
+ y += field_height + gap; //padding.
print_layout_group->add_item(portal_clone);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]