From 0a2a3f27566a2ad23b3164f022feca454720dcfa Mon Sep 17 00:00:00 2001 From: Christian Stimming Date: Sun, 23 Oct 2011 20:43:51 +0000 Subject: [PATCH] [Gtkmm] Add gnc::GncInstance as wrapper for QofInstance, to be used as a base class for the derived qof classes. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@21483 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/optional/gtkmm/Makefile.am | 2 + src/optional/gtkmm/gncmm/Account.cpp | 4 +- src/optional/gtkmm/gncmm/Account.hpp | 2 +- src/optional/gtkmm/gncmm/Book.cpp | 4 +- src/optional/gtkmm/gncmm/Book.hpp | 14 +- src/optional/gtkmm/gncmm/Commodity.cpp | 4 +- src/optional/gtkmm/gncmm/Commodity.hpp | 2 +- src/optional/gtkmm/gncmm/GncInstance.cpp | 131 ++++++++++++++++++ src/optional/gtkmm/gncmm/GncInstance.hpp | 75 +++++++--- src/optional/gtkmm/gncmm/Split.cpp | 20 +-- src/optional/gtkmm/gncmm/Split.hpp | 2 +- src/optional/gtkmm/gncmm/Transaction.cpp | 8 +- src/optional/gtkmm/gncmm/Transaction.hpp | 2 +- .../gtkmm/gncmm/private/GncInstance_p.hpp | 48 +++++++ src/optional/gtkmm/gncmm/wrap_init.cpp | 4 + 15 files changed, 274 insertions(+), 48 deletions(-) create mode 100644 src/optional/gtkmm/gncmm/GncInstance.cpp create mode 100644 src/optional/gtkmm/gncmm/private/GncInstance_p.hpp diff --git a/src/optional/gtkmm/Makefile.am b/src/optional/gtkmm/Makefile.am index 9b60226b1c..57deb0be7b 100644 --- a/src/optional/gtkmm/Makefile.am +++ b/src/optional/gtkmm/Makefile.am @@ -6,6 +6,7 @@ libgncmod_gtkmm_la_SOURCES = \ gncmm/Account.cpp \ gncmm/Book.cpp \ gncmm/Commodity.cpp \ + gncmm/GncInstance.cpp \ gncmm/Numeric.cpp \ gncmm/Split.cpp \ gncmm/Transaction.cpp \ @@ -24,6 +25,7 @@ noinst_HEADERS = \ gncmm/private/Account_p.hpp \ gncmm/private/Book_p.hpp \ gncmm/private/Commodity_p.hpp \ + gncmm/private/GncInstance_p.hpp \ gncmm/private/Split_p.hpp \ gncmm/private/Transaction_p.hpp \ gncmm/wrap_init.hpp \ diff --git a/src/optional/gtkmm/gncmm/Account.cpp b/src/optional/gtkmm/gncmm/Account.cpp index 63019e9f42..2b02e24036 100644 --- a/src/optional/gtkmm/gncmm/Account.cpp +++ b/src/optional/gtkmm/gncmm/Account.cpp @@ -87,13 +87,13 @@ Glib::ObjectBase* Account_Class::wrap_new(GObject* object) } Account::Account(const Glib::ConstructParams& construct_params) - : Glib::Object(construct_params) + : GncInstance(construct_params) { } Account::Account(::Account* castitem) - : Glib::Object((GObject*)(castitem)) + : GncInstance((::QofInstance*)(castitem)) {} diff --git a/src/optional/gtkmm/gncmm/Account.hpp b/src/optional/gtkmm/gncmm/Account.hpp index e3d7699bd4..cdcfe6c599 100644 --- a/src/optional/gtkmm/gncmm/Account.hpp +++ b/src/optional/gtkmm/gncmm/Account.hpp @@ -49,7 +49,7 @@ class Commodity; /** Wrapper around a gnucash ::Account pointer with C++ methods for * easier setter and getter access. */ -class Account : public Glib::Object, public GncInstance +class Account : public GncInstance { #ifndef DOXYGEN_SHOULD_SKIP_THIS typedef Account CppObjectType; diff --git a/src/optional/gtkmm/gncmm/Book.cpp b/src/optional/gtkmm/gncmm/Book.cpp index f1dee36419..1a6a25c918 100644 --- a/src/optional/gtkmm/gncmm/Book.cpp +++ b/src/optional/gtkmm/gncmm/Book.cpp @@ -87,13 +87,13 @@ QofBook* Book::gobj_copy() } Book::Book(const Glib::ConstructParams& construct_params) - : Glib::Object(construct_params) + : GncInstance(construct_params) { } Book::Book(QofBook* castitem) - : Glib::Object((GObject*)(castitem)) + : GncInstance((::QofInstance*)(castitem)) {} diff --git a/src/optional/gtkmm/gncmm/Book.hpp b/src/optional/gtkmm/gncmm/Book.hpp index 0676b869fd..139e4a18fb 100644 --- a/src/optional/gtkmm/gncmm/Book.hpp +++ b/src/optional/gtkmm/gncmm/Book.hpp @@ -32,7 +32,7 @@ extern "C" } #include -//#include "GncInstance.hpp" +#include "GncInstance.hpp" namespace gnc { @@ -48,7 +48,7 @@ class Account; /** Wrapper around a gnucash ::QofBook pointer with C++ methods for * easier setter and getter access. */ -class Book : public Glib::Object //, public GncInstance +class Book : public GncInstance { #ifndef DOXYGEN_SHOULD_SKIP_THIS typedef Book CppObjectType; @@ -98,8 +98,14 @@ public: Glib::RefPtr get_root_account(); - bool is_readonly() const { return qof_book_is_readonly(gobj()); } - void mark_readonly() { qof_book_mark_readonly(gobj()); } + bool is_readonly() const + { + return qof_book_is_readonly(gobj()); + } + void mark_readonly() + { + qof_book_mark_readonly(gobj()); + } void set_string_option (const Glib::ustring& opt_name, const Glib::ustring& opt_val); Glib::ustring get_string_option (const Glib::ustring& opt_name) const; }; diff --git a/src/optional/gtkmm/gncmm/Commodity.cpp b/src/optional/gtkmm/gncmm/Commodity.cpp index b88ec0f999..6b291a5fa7 100644 --- a/src/optional/gtkmm/gncmm/Commodity.cpp +++ b/src/optional/gtkmm/gncmm/Commodity.cpp @@ -86,13 +86,13 @@ gnc_commodity* Commodity::gobj_copy() } Commodity::Commodity(const Glib::ConstructParams& construct_params) - : Glib::Object(construct_params) + : GncInstance(construct_params) { } Commodity::Commodity(gnc_commodity* castitem) - : Glib::Object((GObject*)(castitem)) + : GncInstance((::QofInstance*)(castitem)) {} diff --git a/src/optional/gtkmm/gncmm/Commodity.hpp b/src/optional/gtkmm/gncmm/Commodity.hpp index 2ba6ee2bd6..66975c6156 100644 --- a/src/optional/gtkmm/gncmm/Commodity.hpp +++ b/src/optional/gtkmm/gncmm/Commodity.hpp @@ -44,7 +44,7 @@ namespace gnc { /** Wrapper around a gnucash \ref gnc_commodity object */ -class Commodity : public Glib::Object, public GncInstance +class Commodity : public GncInstance { #ifndef DOXYGEN_SHOULD_SKIP_THIS typedef Commodity CppObjectType; diff --git a/src/optional/gtkmm/gncmm/GncInstance.cpp b/src/optional/gtkmm/gncmm/GncInstance.cpp new file mode 100644 index 0000000000..757196e0ee --- /dev/null +++ b/src/optional/gtkmm/gncmm/GncInstance.cpp @@ -0,0 +1,131 @@ +/* + * GncInstance.cpp + * Copyright (C) 2011 Christian Stimming + * + * 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, contact: + * + * Free Software Foundation Voice: +1-617-542-5942 + * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 + * Boston, MA 02110-1301, USA gnu@gnu.org + */ + +#include "GncInstance.hpp" +#include "private/GncInstance_p.hpp" +#include "Book.hpp" + + +namespace Glib +{ + +Glib::RefPtr wrap(::QofInstance* object, bool take_copy) +{ + return Glib::RefPtr( dynamic_cast (Glib::wrap_auto ((GObject*)(object), take_copy)) ); + //We use dynamic_cast<> in case of multiple inheritance. +} + +} /* namespace Glib */ + + +namespace gnc +{ + + +/* The *_Class implementation: */ + +const Glib::Class& GncInstance_Class::init() +{ + if (!gtype_) // create the GType if necessary + { + // Glib::Class has to know the class init function to clone custom types. + class_init_func_ = &GncInstance_Class::class_init_function; + + // This is actually just optimized away, apparently with no harm. + // Make sure that the parent type has been created. + //CppClassParent::CppObjectType::get_type(); + + // Create the wrapper type, with the same class/instance size as the base type. + register_derived_type(qof_instance_get_type()); + + // Add derived versions of interfaces, if the C type implements any interfaces: + + } + + return *this; +} + + +void GncInstance_Class::class_init_function(void* g_class, void* class_data) +{ + BaseClassType *const klass = static_cast(g_class); + CppClassParent::class_init_function(klass, class_data); +} + + +Glib::ObjectBase* GncInstance_Class::wrap_new(GObject* object) +{ + return new GncInstance((::QofInstance*)object); +} + + +/* The implementation: */ + +::QofInstance* GncInstance::gobj_copy() +{ + reference(); + return gobj(); +} + +GncInstance::GncInstance(const Glib::ConstructParams& construct_params) + : Glib::Object(construct_params) +{ + +} + +GncInstance::GncInstance(::QofInstance* castitem) + : Glib::Object((GObject*)(castitem)) +{} + + +GncInstance::~GncInstance() +{} + + +GncInstance::CppClassType GncInstance::gncInstance_class_; // initialize static member + +GType GncInstance::get_type() +{ + return gncInstance_class_.init().get_type(); +} + + +GType GncInstance::get_base_type() +{ + return qof_instance_get_type(); +} + +// //////////////////////////////////////// + +Glib::RefPtr GncInstance::getBook() const +{ + return Glib::wrap(qof_instance_get_book (gobj())); +} +void GncInstance::set_book(Glib::RefPtr book) +{ + g_assert (book); + qof_instance_set_book(gobj(), book->gobj()); +} + + + +} // END namespace gnc diff --git a/src/optional/gtkmm/gncmm/GncInstance.hpp b/src/optional/gtkmm/gncmm/GncInstance.hpp index be08f68a70..de7d734f14 100644 --- a/src/optional/gtkmm/gncmm/GncInstance.hpp +++ b/src/optional/gtkmm/gncmm/GncInstance.hpp @@ -36,60 +36,95 @@ namespace gnc { class Book; class GncInstance; +class GncInstance_Class; } // END namespace gnc -#include "Book.hpp" - namespace gnc { -/** Wrapper that should be used as an additional base class for those - * Glib::Object objects that are also derived from QofInstance. This +/** Wrapper for ::QofInstance + * This * base class offers some common methods. * * We cannot name it QofInstance because those stupid C macros (like * QOF_CHECK_TYPE) would always confuse our namespaced declaration * with the C declaration. I hate macros! */ -class GncInstance +class GncInstance : public Glib::Object { -public: - GncInstance() {} - virtual ~GncInstance() {} +#ifndef DOXYGEN_SHOULD_SKIP_THIS + typedef GncInstance CppObjectType; + typedef GncInstance_Class CppClassType; + typedef ::QofInstance BaseObjectType; + typedef ::QofInstanceClass BaseClassType; - Glib::RefPtr getBook() const +private: + friend class GncInstance_Class; + static CppClassType gncInstance_class_; + +private: + // noncopyable + GncInstance(const GncInstance&); + GncInstance& operator=(const GncInstance&); + +protected: + explicit GncInstance(const Glib::ConstructParams& construct_params); + explicit GncInstance(::QofInstance* castitem); + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ + +public: + virtual ~GncInstance(); +#ifndef DOXYGEN_SHOULD_SKIP_THIS + static GType get_type() G_GNUC_CONST; + static GType get_base_type() G_GNUC_CONST; +#endif + + ///Provides access to the underlying C GObject. + ::QofInstance* gobj() { - return Glib::wrap(qof_instance_get_book (get_instance())); + return reinterpret_cast< ::QofInstance*>(gobject_); } + + ///Provides access to the underlying C GObject. + const ::QofInstance* gobj() const + { + return reinterpret_cast< ::QofInstance*>(gobject_); + } + + ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs. + ::QofInstance* gobj_copy(); + +public: + + Glib::RefPtr getBook() const; + void set_book(Glib::RefPtr book); const ::GncGUID* getGUID() const { - return qof_entity_get_guid(get_instance()); + return qof_entity_get_guid(gobj_const()); } bool is_dirty() const { - return qof_instance_get_dirty(get_instance()); + return qof_instance_get_dirty(gobj_const()); } void set_dirty() { - return qof_instance_set_dirty(get_instance()); + return qof_instance_set_dirty(gobj()); } void mark_clean() { - return qof_instance_mark_clean(get_instance()); + return qof_instance_mark_clean(gobj()); } //bool check_type(const char* type_id) { return (0 == g_strcmp0(type_id, QOF_INSTANCE(base_class::get())->e_type)); } //Slots getSlots() const { return qof_instance_get_slots(QOF_INSTANCE(get())); } private: - ::QofInstance* get_instance() + /*const*/ + ::QofInstance* gobj_const() const { - return QOF_INSTANCE(dynamic_cast(*this).gobj()); - } - /*const*/ ::QofInstance* get_instance() const - { - return QOF_INSTANCE(dynamic_cast(*this).gobj()); + return const_cast< ::QofInstance*>(gobj()); } }; diff --git a/src/optional/gtkmm/gncmm/Split.cpp b/src/optional/gtkmm/gncmm/Split.cpp index 4375f69f8c..8aa4c2ec54 100644 --- a/src/optional/gtkmm/gncmm/Split.cpp +++ b/src/optional/gtkmm/gncmm/Split.cpp @@ -87,13 +87,13 @@ Glib::ObjectBase* Split_Class::wrap_new(GObject* object) } Split::Split(const Glib::ConstructParams& construct_params) - : Glib::Object(construct_params) + : GncInstance(construct_params) { } Split::Split(::Split* castitem) - : Glib::Object((GObject*)(castitem)) + : GncInstance((::QofInstance*)(castitem)) {} @@ -191,14 +191,14 @@ void TmpSplit::clear(::Account* account) void TmpSplit::copyInto(Transaction& t) const { - Glib::RefPtr s(Glib::wrap(xaccMallocSplit(t.getBook()->gobj()))); - s->setAccount(m_account); - s->setParent(t); - s->setMemo(m_memo); - s->setAction(m_action); - s->setReconcile(m_reconcile); - s->setAmount(m_amount); - s->setValue(m_value); +// Glib::RefPtr s(Glib::wrap(xaccMallocSplit(t.getBook()->gobj()))); +// s->setAccount(m_account); +// s->setParent(t); +// s->setMemo(m_memo); +// s->setAction(m_action); +// s->setReconcile(m_reconcile); +// s->setAmount(m_amount); +// s->setValue(m_value); } } // END namespace gnc diff --git a/src/optional/gtkmm/gncmm/Split.hpp b/src/optional/gtkmm/gncmm/Split.hpp index 5aee4cf2fc..1353244437 100644 --- a/src/optional/gtkmm/gncmm/Split.hpp +++ b/src/optional/gtkmm/gncmm/Split.hpp @@ -56,7 +56,7 @@ typedef std::vector< ::Split*> SplitQList; /** Wrapper around a gnucash ::Split pointer with C++ methods for * easier setter and getter access. */ -class Split : public Glib::Object, public GncInstance +class Split : public GncInstance { #ifndef DOXYGEN_SHOULD_SKIP_THIS typedef Split CppObjectType; diff --git a/src/optional/gtkmm/gncmm/Transaction.cpp b/src/optional/gtkmm/gncmm/Transaction.cpp index 89035d28bc..a7fef88c7f 100644 --- a/src/optional/gtkmm/gncmm/Transaction.cpp +++ b/src/optional/gtkmm/gncmm/Transaction.cpp @@ -89,13 +89,13 @@ Glib::ObjectBase* Transaction_Class::wrap_new(GObject* object) } Transaction::Transaction(const Glib::ConstructParams& construct_params) - : Glib::Object(construct_params) + : GncInstance(construct_params) { } Transaction::Transaction(::Transaction* castitem) - : Glib::Object((GObject*)(castitem)) + : GncInstance((::QofInstance*)(castitem)) {} @@ -202,7 +202,7 @@ void TmpTransaction::copyTo(Glib::RefPtr t) const //m_splits[i].copyInto(t); } } - +#if 0 Glib::RefPtr TmpTransaction::createAsReal() const { assert (!m_splits.empty()); @@ -216,7 +216,7 @@ Glib::RefPtr TmpTransaction::createAsReal() const trans->commitEdit(); return trans; } - +#endif void TmpTransaction::push_back(const TmpSplit& s) { m_splits.push_back(s); diff --git a/src/optional/gtkmm/gncmm/Transaction.hpp b/src/optional/gtkmm/gncmm/Transaction.hpp index dc056ecb9d..70f1019241 100644 --- a/src/optional/gtkmm/gncmm/Transaction.hpp +++ b/src/optional/gtkmm/gncmm/Transaction.hpp @@ -57,7 +57,7 @@ class TmpSplit; /** Wrapper around a gnucash ::Transaction pointer with C++ methods for * easier setter and getter access. */ -class Transaction : public Glib::Object, public GncInstance +class Transaction : public GncInstance { #ifndef DOXYGEN_SHOULD_SKIP_THIS typedef Transaction CppObjectType; diff --git a/src/optional/gtkmm/gncmm/private/GncInstance_p.hpp b/src/optional/gtkmm/gncmm/private/GncInstance_p.hpp new file mode 100644 index 0000000000..62b30a8164 --- /dev/null +++ b/src/optional/gtkmm/gncmm/private/GncInstance_p.hpp @@ -0,0 +1,48 @@ +// -*- c++ -*- +// Generated by gtkmmproc -- DO NOT MODIFY! +#ifndef _GNCMM_GNC_COMMODITY_P_H +#define _GNCMM_GNC_COMMODITY_P_H + + +#include + +#include + +namespace gnc +{ + +class GncInstance_Class : public Glib::Class +{ +public: +#ifndef DOXYGEN_SHOULD_SKIP_THIS + typedef GncInstance CppObjectType; + typedef ::QofInstance BaseObjectType; + typedef ::QofInstanceClass BaseClassType; + typedef Glib::Object_Class CppClassParent; + typedef GObjectClass BaseClassParent; + + friend class GncInstance; +#endif /* DOXYGEN_SHOULD_SKIP_THIS */ + + const Glib::Class& init(); + + + static void class_init_function(void* g_class, void* class_data); + + static Glib::ObjectBase* wrap_new(GObject*); + +protected: + + //Callbacks (default signal handlers): + //These will call the *_impl member methods, which will then call the existing default signal callbacks, if any. + //You could prevent the original default signal handlers being called by overriding the *_impl method. + + //Callbacks (virtual functions): +}; + + +} // namespace gnc + + +#endif /* _GNCMM_GNC_COMMODITY_P_H */ + diff --git a/src/optional/gtkmm/gncmm/wrap_init.cpp b/src/optional/gtkmm/gncmm/wrap_init.cpp index 6d2507501b..5090ef70e6 100644 --- a/src/optional/gtkmm/gncmm/wrap_init.cpp +++ b/src/optional/gtkmm/gncmm/wrap_init.cpp @@ -29,6 +29,7 @@ extern "C" GType gnc_commodity_get_type(void); GType gnc_split_get_type(void); GType gnc_transaction_get_type(void); + GType qof_instance_get_type (void); } // extern "C" //Declarations of the *_Class::wrap_new() methods, instead of including all the private headers: @@ -36,6 +37,7 @@ extern "C" namespace gnc { class Account_Class { public: static Glib::ObjectBase* wrap_new(GObject*); }; } namespace gnc { class Book_Class { public: static Glib::ObjectBase* wrap_new(GObject*); }; } namespace gnc { class Commodity_Class { public: static Glib::ObjectBase* wrap_new(GObject*); }; } +namespace gnc { class GncInstance_Class { public : static Glib::ObjectBase* wrap_new(GObject*); }; } namespace gnc { class Split_Class { public: static Glib::ObjectBase* wrap_new(GObject*); }; } namespace gnc { class Transaction_Class { public: static Glib::ObjectBase* wrap_new(GObject*); }; } @@ -47,6 +49,7 @@ void wrap_init() Glib::wrap_register(gnc_account_get_type(), &gnc::Account_Class::wrap_new); Glib::wrap_register(qof_book_get_type(), &gnc::Book_Class::wrap_new); Glib::wrap_register(gnc_commodity_get_type(), &gnc::Commodity_Class::wrap_new); + Glib::wrap_register(qof_instance_get_type(), &gnc::GncInstance_Class::wrap_new); Glib::wrap_register(gnc_split_get_type(), &gnc::Split_Class::wrap_new); Glib::wrap_register(gnc_transaction_get_type(), &gnc::Transaction_Class::wrap_new); @@ -54,6 +57,7 @@ void wrap_init() gnc::Account::get_type(); gnc::Book::get_type(); gnc::Commodity::get_type(); + gnc::GncInstance::get_type(); gnc::Split::get_type(); gnc::Transaction::get_type(); } // wrap_init()