Commit 9890d13a authored by Murray Cumming's avatar Murray Cumming Committed by Murray Cumming
Browse files

Moved value->pixbuf conversion code from here to:

2006-10-06  Murray Cumming  <murrayc@murrayc.com>

        * glom/utility_widgets/db_adddel/Makefile.am:
        * glom/utility_widgets/imageglom.cc: Moved value->pixbuf
        conversion code from here to:
        * glom/libglom/data_structure/glomconversions.cc:
        * glom/libglom/data_structure/glomconversions.h:
        * glom/utility_widgets/db_adddel/cellrenderer_button.cc:
        * glom/utility_widgets/db_adddel/cellrenderer_button.h: renamed
        to
        * glom/utility_widgets/db_adddel/cellrenderer_buttonimage.cc:
        * glom/utility_widgets/db_adddel/cellrenderer_buttonimage.h:
        Added:
        * glom/utility_widgets/db_adddel/cellrenderer_buttontext.cc:
        * glom/utility_widgets/db_adddel/cellrenderer_buttontext.h:

        * glom/utility_widgets/db_adddel/db_adddel.cc:
        * glom/utility_widgets/db_adddel/db_adddel.h: add_column() now
        take a LayoutItem rather than only a LayoutItem_Field, so that
        the list can in future show other items, such as buttons.
        * glom/libglom/data_structure/layout/layoutgroup.cc:
        * glom/libglom/data_structure/layout/layoutitem.cc:
        * glom/libglom/data_structure/layout/layoutitem.h:
        * glom/libglom/data_structure/layout/layoutitem_field.cc:
        * glom/libglom/data_structure/layout/layoutitem_field.h:
        * glom/libglom/data_structure/layout/layoutitem_image.h:
        * glom/libglom/data_structure/layout/layoutitem_portal.cc:
        * glom/libglom/data_structure/layout/layoutitem_portal.h:
        * glom/libglom/utils.cc:
        * glom/mode_data/box_data.cc:
        * glom/mode_data/box_data_list.cc:
        * glom/mode_data/box_data_list.h:
        * glom/mode_data/box_data_list_related.cc:
        * glom/mode_data/box_data_list_related.h: Adapted.
parent 2de6ba5b
2006-10-06 Murray Cumming <murrayc@murrayc.com>
* glom/utility_widgets/db_adddel/Makefile.am:
* glom/utility_widgets/imageglom.cc: Moved value->pixbuf
conversion code from here to:
* glom/libglom/data_structure/glomconversions.cc:
* glom/libglom/data_structure/glomconversions.h:
* glom/utility_widgets/db_adddel/cellrenderer_button.cc:
* glom/utility_widgets/db_adddel/cellrenderer_button.h: renamed
to
* glom/utility_widgets/db_adddel/cellrenderer_buttonimage.cc:
* glom/utility_widgets/db_adddel/cellrenderer_buttonimage.h:
Added:
* glom/utility_widgets/db_adddel/cellrenderer_buttontext.cc:
* glom/utility_widgets/db_adddel/cellrenderer_buttontext.h:
* glom/utility_widgets/db_adddel/db_adddel.cc:
* glom/utility_widgets/db_adddel/db_adddel.h: add_column() now
take a LayoutItem rather than only a LayoutItem_Field, so that
the list can in future show other items, such as buttons.
* glom/libglom/data_structure/layout/layoutgroup.cc:
* glom/libglom/data_structure/layout/layoutitem.cc:
* glom/libglom/data_structure/layout/layoutitem.h:
* glom/libglom/data_structure/layout/layoutitem_field.cc:
* glom/libglom/data_structure/layout/layoutitem_field.h:
* glom/libglom/data_structure/layout/layoutitem_image.h:
* glom/libglom/data_structure/layout/layoutitem_portal.cc:
* glom/libglom/data_structure/layout/layoutitem_portal.h:
* glom/libglom/utils.cc:
* glom/mode_data/box_data.cc:
* glom/mode_data/box_data_list.cc:
* glom/mode_data/box_data_list.h:
* glom/mode_data/box_data_list_related.cc:
* glom/mode_data/box_data_list_related.h: Adapted.
2006-10-06 Murray Cumming <murrayc@murrayc.com>
* glom/utility_widgets/adddel/adddel.cc:
......
......@@ -21,6 +21,8 @@
#include "glomconversions.h"
#include <glom/libglom/connectionpool.h>
#include <glom/libglom/utils.h>
#include <gdkmm/pixbufloader.h>
#include <glom/libglom/data_structure/layout/layoutitem_image.h> // For GLOM_IMAGE_FORMAT
#include <glibmm/i18n.h>
#include <sstream> //For stringstream
......@@ -901,5 +903,89 @@ Gnome::Gda::Value Conversions::convert_value(const Gnome::Gda::Value& value, Fie
return value;
}
Glib::RefPtr<Gdk::Pixbuf> Conversions::get_pixbuf_for_gda_value(const Gnome::Gda::Value& value)
{
Glib::RefPtr<Gdk::Pixbuf> result;
if(value.get_value_type() == Gnome::Gda::VALUE_TYPE_BINARY)
{
glong size = 0;
const gpointer pData = value.get_binary(size);
if(size && pData)
{
//libgda does not currently properly unescape binary data,
//so pData is actually a null terminated string, of escaped binary data.
//This workaround should be removed when libgda is fixed:
//(It is fixed in libgd-2.0 but is unlikely to be fixed in libgda-1.2)
size_t buffer_binary_length = 0;
guchar* buffer_binary = Glom_PQunescapeBytea((const guchar*)pData /* must be null-terminated */, &buffer_binary_length); //freed by us later.
if(buffer_binary)
{
//typedef std::list<Gdk::PixbufFormat> type_list_formats;
//const type_list_formats formats = Gdk::Pixbuf::get_formats();
//std::cout << "Debug: Supported pixbuf formats:" << std::endl;
//for(type_list_formats::const_iterator iter = formats.begin(); iter != formats.end(); ++iter)
//{
// std::cout << " name=" << iter->get_name() << ", writable=" << iter->is_writable() << std::endl;
//}
Glib::RefPtr<Gdk::PixbufLoader> refPixbufLoader;
// PixbufLoader::create() is broken in gtkmm before 2.6.something,
// so let's do this in C so it works with all 2.6 versions:
GError* error = 0;
GdkPixbufLoader* loader = gdk_pixbuf_loader_new_with_type(GLOM_IMAGE_FORMAT, &error);
if(!error)
refPixbufLoader = Glib::wrap(loader);
else
std::cerr << "ImageGlom::set_value(): Error while calling gdk_pixbuf_loader_new_with_type()." << std::endl;
/*
try
{
refPixbufLoader = Gdk::PixbufLoader::create(GLOM_IMAGE_FORMAT);
g_warning("debug a1");
}
catch(const Gdk::PixbufError& ex)
{
refPixbufLoader.clear();
g_warning("PixbufLoader::create failed: %s",ex.what().c_str());
}
*/
if(refPixbufLoader)
{
try
{
guint8* puiData = (guint8*)buffer_binary;
//g_warning("ImageGlom::set_value(): debug: from db: ");
//for(int i = 0; i < 10; ++i)
// g_warning("%02X (%c), ", (guint8)puiData[i], (char)puiData[i]);
refPixbufLoader->write(puiData, (glong)buffer_binary_length);
result = refPixbufLoader->get_pixbuf();
refPixbufLoader->close(); //This throws if write() threw, so it must be inside the try block.
}
catch(const Glib::Exception& ex)
{
g_warning("ImageGlom::set_value(): PixbufLoader::write() failed: %s", ex.what().c_str());
}
free(buffer_binary);
}
}
//TODO: load the image, using the mime type stored elsewhere.
//pixbuf = Gdk::Pixbuf::create_from_data(
}
}
return result;
}
} //namespace Glom
......@@ -26,6 +26,7 @@
#include <glom/libglom/data_structure/layout/layoutitem_field.h>
#include <libxml++/libxml++.h>
#include <gdkmm/pixbuf.h>
namespace Glom
{
......@@ -62,6 +63,9 @@ namespace Conversions
Gnome::Gda::Value parse_escaped_binary_data(const Glib::ustring& escaped_data);
Gnome::Gda::Value convert_value(const Gnome::Gda::Value& value, Field::glom_field_type target_glom_type);
Glib::RefPtr<Gdk::Pixbuf> get_pixbuf_for_gda_value(const Gnome::Gda::Value& value);
}
//Copied from Postgres's PQunescapeBytea() so I don't have the trouble of finding and linking to the
......
......@@ -409,25 +409,32 @@ guint LayoutGroup::get_items_count() const
/*
void LayoutGroup::debug(guint level) const
{
g_warning("LayoutGroup::debug() level =%d", level);
for(int i = 0; i < level; ++i)
std::cout << " ";
std::cout << "LayoutGroup::debug() level =" << level << std::endl;
for(type_map_items::const_iterator iter = m_map_items.begin(); iter != m_map_items.end(); ++iter)
{
const LayoutGroup* group = dynamic_cast<const LayoutGroup*>(iter->second);
sharedptr<LayoutGroup> group = sharedptr<LayoutGroup>::cast_dynamic(iter->second);
if(group)
group->debug(level + 1);
else
{
const LayoutItem_Field* field = dynamic_cast<const LayoutItem_Field*>(iter->second);
sharedptr<LayoutItem_Field> field = sharedptr<LayoutItem_Field>::cast_dynamic(iter->second);
if(field)
{
g_warning(" field: name=%s, relationship=%s", field->get_name().c_str(), field->get_relationship_name().c_str());
for(int i = 0; i < level; ++i)
std::cout << " ";
std::cout << " field: name=" << field->get_name() << ", relationship=" << field->get_relationship_name() << std::endl;
}
}
}
}
*/
double LayoutGroup::get_border_width() const
{
return m_border_width;
......
......@@ -25,7 +25,8 @@ namespace Glom
LayoutItem::LayoutItem()
: m_sequence(0),
m_editable(true)
m_editable(true),
m_display_width(0)
{
m_translatable_item_type = TRANSLATABLE_TYPE_LAYOUT_ITEM;
}
......@@ -33,7 +34,8 @@ LayoutItem::LayoutItem()
LayoutItem::LayoutItem(const LayoutItem& src)
: TranslatableItem(src),
m_sequence(src.m_sequence),
m_editable(src.m_editable)
m_editable(src.m_editable),
m_display_width(src.m_display_width)
{
}
......@@ -47,6 +49,7 @@ LayoutItem& LayoutItem::operator=(const LayoutItem& src)
m_sequence = src.m_sequence;
m_editable = src.m_editable;
m_display_width = src.m_display_width;
return *this;
}
......@@ -55,7 +58,8 @@ bool LayoutItem::operator==(const LayoutItem& src) const
{
return (TranslatableItem::operator==(src)) &&
(m_sequence == src.m_sequence) &&
(m_editable == src.m_editable);
(m_editable == src.m_editable) &&
(m_display_width == src.m_display_width); //careful of this - it's not saved in the document.
}
bool LayoutItem::get_editable() const
......@@ -78,5 +82,18 @@ Glib::ustring LayoutItem::get_report_part_id() const
return "unexpected_report_part_id"; //This should never be used.
}
bool LayoutItem::get_display_width(guint& width) const
{
//Initialize output variable:
width = m_display_width;
return (m_display_width != 0); //Tell the caller whether a display width has even been specified.
}
void LayoutItem::set_display_width(guint value)
{
m_display_width = value;
}
} //namespace Glom
......@@ -54,12 +54,18 @@ public:
*/
virtual Glib::ustring get_report_part_id() const;
bool get_display_width(guint& width) const;
void set_display_width(guint value);
guint m_sequence;
//bool m_hidden;
protected:
Glib::ustring m_name;
bool m_editable;
//Not saved in document:
guint m_display_width; //In pixels.
};
} //namespace Glom
......
......@@ -29,8 +29,7 @@ LayoutItem_Field::LayoutItem_Field()
m_priv_edit(false),
m_field_cache_valid(false),
m_hidden(false),
m_formatting_use_default(true),
m_display_width(0)
m_formatting_use_default(true)
{
}
......@@ -44,8 +43,7 @@ LayoutItem_Field::LayoutItem_Field(const LayoutItem_Field& src)
m_field_cache_valid(src.m_field_cache_valid),
m_hidden(src.m_hidden),
m_formatting_use_default(src.m_formatting_use_default),
m_title_custom(src.m_title_custom),
m_display_width(src.m_display_width)
m_title_custom(src.m_title_custom)
{
//g_warning("LayoutItem_Field::LayoutItem_Field: m_choices_related_relationship=%s, src.m_choices_related_relationship=%s", m_choices_related_relationship.c_str(), src.m_choices_related_relationship.c_str());
......@@ -70,8 +68,7 @@ bool LayoutItem_Field::operator==(const LayoutItem_Field& src) const
(m_hidden == src.m_hidden) &&
(m_formatting_use_default == src.m_formatting_use_default) &&
(m_formatting == src.m_formatting) &&
(m_field_cache_valid == src.m_field_cache_valid) &&
(m_display_width == src.m_display_width); //careful of this - it's not saved in the document.
(m_field_cache_valid == src.m_field_cache_valid);
if(m_field && src.m_field)
result == result && (*m_field == *(src.m_field));
......@@ -105,8 +102,6 @@ LayoutItem_Field& LayoutItem_Field::operator=(const LayoutItem_Field& src)
m_title_custom = src.m_title_custom;
m_display_width = src.m_display_width;
return *this;
}
......@@ -280,18 +275,6 @@ bool LayoutItem_Field::is_same_field(const sharedptr<const LayoutItem_Field>& fi
(get_related_relationship_name() == field->get_related_relationship_name());
}
bool LayoutItem_Field::get_display_width(guint& width) const
{
//Initialize output variable:
width = m_display_width;
return (m_display_width != 0); //Tell the caller whether a display width has even been specified.
}
void LayoutItem_Field::set_display_width(guint value)
{
m_display_width = value;
}
} //namespace Glom
......
......@@ -94,9 +94,6 @@ public:
const FieldFormatting& get_formatting_used() const;
bool get_display_width(guint& width) const;
void set_display_width(guint value);
/** Compare the name, relationship, and related_relationship.
*/
bool is_same_field(const sharedptr<const LayoutItem_Field>& field) const;
......@@ -110,9 +107,6 @@ protected:
bool m_hidden;
bool m_formatting_use_default;
sharedptr<CustomTitle> m_title_custom; //translatable.
//Not saved in document:
guint m_display_width; //In pixels.
};
} //namespace Glom
......
......@@ -27,11 +27,16 @@
namespace Glom
{
//JPEG seems to give ugly results when saved to the database and shown again.
//#define GLOM_IMAGE_FORMAT "jpeg"
//#define GLOM_IMAGE_FORMAT_MIME_TYPE "image/jpeg"
#define GLOM_IMAGE_FORMAT "png"
#define GLOM_IMAGE_FORMAT_MIME_TYPE "image/png"
class LayoutItem_Image
: public LayoutItem
{
public:
LayoutItem_Image();
LayoutItem_Image(const LayoutItem_Image& src);
LayoutItem_Image& operator=(const LayoutItem_Image& src);
......
......@@ -92,10 +92,12 @@ void LayoutItem_Portal::change_field_item_name(const Glib::ustring& table_name,
}
}
/*
void LayoutItem_Portal::debug(guint level) const
{
g_warning("LayoutItem_Portal::debug: level = %d", level);
//LayoutGroup::debug(level);
}
*/
} //namespace Glom
......@@ -46,7 +46,7 @@ public:
virtual void change_field_item_name(const Glib::ustring& table_name, const Glib::ustring& field_name, const Glib::ustring& field_name_new);
virtual void change_related_field_item_name(const Glib::ustring& table_name, const Glib::ustring& field_name, const Glib::ustring& field_name_new);
virtual void debug(guint level = 0) const;
//virtual void debug(guint level = 0) const;
protected:
......
......@@ -762,4 +762,5 @@ Glib::ustring Utils::string_remove_suffix(const Glib::ustring& str, const Glib::
return str;
}
} //namespace Glom
......@@ -522,6 +522,9 @@ Document_Glom::type_mapLayoutGroupSequence Box_Data::get_data_layout_groups(cons
for(Document_Glom::type_mapLayoutGroupSequence::iterator iterGroups = layout_groups.begin(); iterGroups != layout_groups.end(); ++iterGroups)
{
fill_layout_group_field_info(iterGroups->second, table_privs);
//std::cout << "debug: Box_Data::get_data_layout_groups: " << std::endl;
//iterGroups->second->debug();
}
}
}
......
......@@ -612,6 +612,40 @@ bool Box_Data_List::get_showing_multiple_records() const
return m_AddDel.get_count() > 1;
}
void Box_Data_List::create_layout_add_group(const sharedptr<LayoutGroup>& layout_group)
{
if(!layout_group)
return;
LayoutGroup::type_map_items child_items = layout_group->get_items();
for(LayoutGroup::type_map_items::const_iterator iter = child_items.begin(); iter != child_items.end(); ++iter)
{
sharedptr<LayoutItem> child_item = iter->second;
sharedptr<LayoutGroup> child_group = sharedptr<LayoutGroup>::cast_dynamic(child_item);
if(child_group)
{
//std::cout << "debug: Start Adding child group." << std::endl;
create_layout_add_group(child_group);
//std::cout << "debug: End Adding child group." << std::endl;
}
else
{
if(m_read_only)
child_item->set_editable(false);
//std::cout << "debug: adding column: " << child_item->get_name() << std::endl;
m_AddDel.add_column(child_item);
}
}
}
Document_Glom::type_mapLayoutGroupSequence Box_Data_List::create_layout_get_layout()
{
//Overriden in Box_Data_List_Related:
return get_data_layout_groups(m_layout_name);
}
void Box_Data_List::create_layout()
{
Box_Data::create_layout(); //Fills m_TableFields.
......@@ -625,6 +659,7 @@ void Box_Data_List::create_layout()
m_AddDel.set_table_name(m_table_name);
sharedptr<Field> field_primary_key = get_field_primary_key_for_table(m_table_name);
if(!field_primary_key)
{
......@@ -633,32 +668,36 @@ void Box_Data_List::create_layout()
else
{
m_AddDel.set_key_field(field_primary_key);
//This map of layout groups will also contain the field information from the database:
Document_Glom::type_mapLayoutGroupSequence layout_groups = create_layout_get_layout();
m_FieldsShown = get_fields_to_show();
//int debug_count = 0;
for(Document_Glom::type_mapLayoutGroupSequence::const_iterator iter = layout_groups.begin(); iter != layout_groups.end(); ++iter)
{
//std::cout << "Box_Data_List::create_layout() group number=" << debug_count;
//debug_count++;
//iter->second->debug();
//Add extra possibly-non-visible columns that we need:
//TODO: Only add it if it is not already there.
sharedptr<LayoutItem_Field> layout_item = sharedptr<LayoutItem_Field>::create();
layout_item->set_hidden();
layout_item->set_full_field_details(m_AddDel.get_key_field());
m_FieldsShown.push_back(layout_item);
create_layout_add_group(iter->second);
}
}
//Add a column for each table field:
for(type_vecLayoutFields::iterator iter = m_FieldsShown.begin(); iter != m_FieldsShown.end(); ++iter)
{
sharedptr<LayoutItem_Field> field = *iter;
if(m_read_only)
field->set_editable(false);
m_FieldsShown = get_fields_to_show();
//std::cout << "Adding field: name=" << field->get_name() << ", titleorname=" << field->get_title_or_name() << std::endl;
m_AddDel.add_column(field);
}
//Add extra possibly-non-visible columns that we need:
//TODO: Only add it if it is not already there.
sharedptr<LayoutItem_Field> layout_item = sharedptr<LayoutItem_Field>::create();
layout_item->set_hidden();
layout_item->set_full_field_details(m_AddDel.get_key_field());
m_FieldsShown.push_back(layout_item);
m_AddDel.add_column(layout_item);
m_AddDel.set_found_set(m_found_set);
m_AddDel.set_found_set(m_found_set);
m_AddDel.set_columns_ready();
}
m_AddDel.set_columns_ready();
}
}
......
......@@ -71,6 +71,8 @@ public:
protected:
virtual void create_layout(); //override
virtual Document_Glom::type_mapLayoutGroupSequence create_layout_get_layout(); //overriden in Box_Data_List_Related.
void create_layout_add_group(const sharedptr<LayoutGroup>& layout_group);
virtual bool fill_from_database(); //override.
virtual void enable_buttons();
......
......@@ -586,4 +586,15 @@ void Box_Data_List_Related::get_suitable_record_to_view_details(const Gnome::Gda
}
}
Document_Glom::type_mapLayoutGroupSequence Box_Data_List_Related::create_layout_get_layout()
{
Document_Glom::type_mapLayoutGroupSequence result;
if(m_portal)
result[0] = m_portal;
return result;
}
} //namespace Glom
......@@ -79,6 +79,8 @@ protected:
virtual void enable_buttons(); //override
protected:
virtual Document_Glom::type_mapLayoutGroupSequence create_layout_get_layout(); //override.
Gtk::Frame m_Frame;
Gtk::Alignment m_Alignment;
Gtk::Label m_Label;
......
......@@ -6,6 +6,7 @@ noinst_LIBRARIES = libutility_widgets_db_adddel.a
libutility_widgets_db_adddel_a_SOURCES = db_adddel.cc db_adddel.h db_adddel_withbuttons.cc db_adddel_withbuttons.h \
db_treeviewcolumn_glom.cc db_treeviewcolumn_glom.h \
glom_db_treemodel.h glom_db_treemodel.cc \
cellrenderer_button.h cellrenderer_button.cc
cellrenderer_buttonimage.h cellrenderer_buttonimage.cc \
cellrenderer_buttontext.h cellrenderer_buttontext.cc
/* Glom
*
* Copyright (C) 2001-2005 Murray Cumming
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "cellrenderer_button.h"
#include <gtkmm/stock.h>
namespace Glom
{
GlomCellRenderer_Button::GlomCellRenderer_Button()
{
const Gtk::StockID stock_id = Gtk::Stock::OPEN;
property_stock_id() = stock_id.get_string();
property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; //So that it calls activate_vfunc().
}
GlomCellRenderer_Button::~GlomCellRenderer_Button()
{}
GlomCellRenderer_Button::type_signal_clicked GlomCellRenderer_Button::signal_clicked()
{
return m_signal_clicked;
}
bool GlomCellRenderer_Button::activate_vfunc(GdkEvent* event, Gtk::Widget& widget, const Glib::ustring& path, const Gdk::Rectangle& background_area, const Gdk::Rectangle& cell_area, Gtk::CellRendererState flags)
{
//TODO: It would be nice to depress this like a real button.
//Call base class:
bool result = CellRendererPixbuf::activate_vfunc(event, widget, path, background_area, cell_area, flags);
m_signal_clicked.emit( Gtk::TreeModel::Path(path) );