// Test case for Bug 731444 - gtkmm::builder - derived widget's destructor
// is not called -> memory leaks

#include <iostream>

using namespace std;

#include <gtkmm.h>

#define USE_DERIVED_WIDGET 1  // 0 or 1

const char gladefile[] = 
"<?xml version='1.0' encoding='UTF-8'?>"
"<interface>"
"  <!-- interface-requires gtk+ 3.0 -->"
"  <object class='GtkWindow' id='window1'>"
"    <property name='can_focus'>False</property>"
"    <child>"
"      <object class='GtkButton' id='button1'>"
"        <property name='label' translatable='yes'>button</property>"
"        <property name='use_action_appearance'>False</property>"
"        <property name='visible'>True</property>"
"        <property name='can_focus'>True</property>"
"        <property name='receives_default'>True</property>"
"        <property name='use_action_appearance'>False</property>"
"      </object>"
"    </child>"
"  </object>"
"</interface>";

#if USE_DERIVED_WIDGET
class DerivedButton : public Gtk::Button
{
public:
	DerivedButton(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refBuilder)
	: Gtk::Button(cobject)
	{
		cout << "DerivedButton::ctor" << endl;
	}
	
	virtual ~DerivedButton()
	{
		cout << "DerivedButton::dtor" << endl; // <--- This line never gets executed
	}
};
#endif // USE_DERIVED_WIDGET

class MainWindow : public Gtk::Window
{    	
//private:
public:
#if USE_DERIVED_WIDGET
  DerivedButton* m_pButton;
#else
  Gtk::Button* m_pButton;
#endif
public:
	MainWindow(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refBuilder) 
	: Gtk::Window(cobject) 
	, m_pButton(NULL)
	{
		cout << "MainWindow::ctor" << endl;

#if USE_DERIVED_WIDGET
    refBuilder->get_widget_derived("button1", m_pButton);
    refBuilder->get_widget_derived("button1", m_pButton);
#else
    refBuilder->get_widget("button1", m_pButton);
    refBuilder->get_widget("button1", m_pButton);
#endif	
	}
	virtual ~MainWindow() 
	{
		cout << "MainWindow::dtor" << endl;
	}
};

int main(int argc, char* argv[])
{
	Gtk::Main kit(argc,argv);

	Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create_from_string(gladefile);
	
	MainWindow* main_win = NULL;

	builder->get_widget_derived("window1", main_win);

  GObject* window = (GObject*)main_win->gobj();
  GObject* button = (GObject*)main_win->m_pButton->gobj();
  cout << "Before kit.run(*main_win)" << endl
	     << "  ref_count(main_win)=" << window->ref_count << endl
       << "  ref_count(m_pButton)=" << button->ref_count << endl;

	if (main_win)
	{
		kit.run(*main_win);
	}

  cout << "After kit.run(*main_win)" << endl
	     << "  ref_count(main_win)=" << window->ref_count << endl
       << "  ref_count(m_pButton)=" << button->ref_count << endl;

	delete main_win;

  cout << "After delete main_win" << endl
	     << "  ref_count(main_win)=" << window->ref_count << endl
       << "  ref_count(m_pButton)=" << button->ref_count << endl;

  builder.reset();

  // window and button shall have been deallocated. If Gtk::Builder works
  // correctly, we access unallocated memory, possibly with strange results.
  cout << "After builder.reset()" << endl
	     << "  ref_count(main_win)=" << window->ref_count << endl
       << "  ref_count(m_pButton)=" << button->ref_count << endl;

	return 0;
}
