// -*- c++ -*-
/*  Generated by gensig from itemfactory.gen_h. DO NOT MODIFY!!! */
#ifndef GTKMM_ITEMFACTORY_HEADER
#define GTKMM_ITEMFACTORY_HEADER
/* $Id: itemfactory.gen_h,v 1.39.2.4 1999/05/22 06:10:31 tdukes Exp $ */

/* itemfactory.h
 * 
 * Copyright (C) 1998-1999 
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <gtk--/object.h>
#include <gtk--/menubar.h>
#include <gtk--/menuitem.h>
#include <gtk--/checkmenuitem.h>
#include <gtk--/radiomenuitem.h>
#include <gtk--/optionmenu.h>
#include <gtk--/accelgroup.h>
#include <gtk/gtkitemfactory.h>
#include <iostream.h>
#include <stdio.h>

class Gtk_ItemFactory;

// modified from MenuFactoryConnector code (c) 1998 by Chris Cannam

class ItemFactoryConnectorBase
{
protected:
  friend class Gtk_ItemFactory;
  virtual void connectTo(Gtk_Widget*) const = 0;
  //  virtual void connectTo(Gtk_MenuItem *) const = 0;
  //  virtual void connectTo(Gtk_RadioMenuItem*) const = 0;
  //  virtual void connectTo(Gtk_CheckMenuItem*) const = 0;
  ItemFactoryConnectorBase() {};
  virtual ~ItemFactoryConnectorBase() {}
};

template <class T, class DT>
class ItemFactoryConnector : public ItemFactoryConnectorBase
{
public:
  ItemFactoryConnector(T *target_widget,
		       void (T::*target_method)(DT),
		       const DT &target_method_arg) :
    m_widget(target_widget),
    m_method(target_method),
    m_method_no_arg(0),
    m_method_arg(target_method_arg) {}

  ItemFactoryConnector(T *target_widget,
		       void (T::*target_method)()) :
    m_widget(target_widget),
    m_method(0),
    m_method_no_arg(target_method),
    m_method_arg(0) {}

  virtual ~ItemFactoryConnector() {}
protected:
  friend class Gtk_ItemFactory;
  virtual void connectTo(Gtk_Widget * m) const {
    if ( Gtk_MenuItem * p = dynamic_cast<Gtk_MenuItem*>(m)) {
      connectTo( p,0);
      return;
    }
    if ( Gtk_RadioMenuItem * p = dynamic_cast<Gtk_RadioMenuItem*>(m)) {
      connectTo( p, 0);
      return;
    }
    if ( Gtk_CheckMenuItem * p = dynamic_cast<Gtk_CheckMenuItem*>( m)) {
      connectTo( p, 0);
      return;
    }
    cout << __FILE__ << ":" << __LINE__ << " connectTo failed for type "
	 << gtk_type_name(m->type())
	 << endl;
  }
  template<class U>
  void connectTo( U * m, int /* x */) const {
    if (m_method) {
      Connection_impl * s = new Slot0cb<T,DT>(m_widget,m_method,m_method_arg);
      m->activate.sender->insert_connection(s);
      gint conn = m->activate.sender->
	signal_connect(m->activate.signal_name, GtkSignalFunc(Slot0cb<T,DT>::callback),s);
      s->setgtkconnection(m->activate.sender->gtkobj(),conn);
    } else {
      Connection_impl* s = new Slot0<T>(m_widget,m_method_no_arg);
      m->activate.sender->insert_connection(s);
      gint conn=m->activate.sender->
	signal_connect(m->activate.signal_name, GtkSignalFunc(Slot0<T>::callback),s);
      s->setgtkconnection(m->activate.sender->gtkobj(),conn);
    }
    /*
      connect_to_method((Signal_proxy0<void,Gtk_MenuItem,GtkObject>&)m->activate, 
      (T*)m_widget, (void(T::*)(DT))m_method, (DT)m_method_arg);
    */
  }

private:
  T *m_widget;
  void (T::*m_method)(DT);
  void (T::*m_method_no_arg)();
  DT m_method_arg;
};

class Gtk_ItemFactory_Class;
#line 116 "itemfactory.gen_h"


class Gtk_ItemFactory : public Gtk_Object 
{
  
public:
protected:
  typedef Gtk_ItemFactory_Class    CppClassType;
  typedef GtkItemFactory           BaseObjectType;
  typedef GtkItemFactoryClass      BaseClassType;

  virtual void *get_parent_class();

private:
  friend CppClassType;
  static CppClassType item_factory_class; 
  GtkType get_type(); 

public:



  Gtk_ItemFactory(GtkType type, 
		  const string &path,
		  Gtk_AccelGroup &_accel_group);

  Gtk_ItemFactory(GtkType type, const string &path);
  
  Gtk_ItemFactory(GtkItemFactory *castitem);

  ~Gtk_ItemFactory();

  static void parse_rc(const string &file_name);
  static void parse_rc_string(const string &rc_string);
  static void parse_rc_scanner(GScanner *scanner);

  static Gtk_ObjectHandle<Gtk_ItemFactory> from_widget(const Gtk_Widget &widget);

  static string path_from_widget(const Gtk_Widget &widget);
  
  static void dump_items(GtkPatternSpec *path_pspec, bool modified_only,
			 GtkPrintFunc print_func, gpointer func_data);
  static void dump_rc(const string &file_name,
		      GtkPatternSpec *path_pspec,
		      bool modified_only);
  static void print_func(FILE *fp, const string &str);
  

  void create_items(guint n_entries, GtkItemFactoryEntry *entries,
		    gpointer callback_data);

  // We check if the compiler supports template match with
  // memberfunction pointer... gcc2.7.2 does not compile this code...

#ifdef GTKMM_CXX_HAVE_MEMBER_TEMPLATES
  template <class RECEIVER, class ARG_TYPE>
  Gtk_Widget* create_item(const string &path,
			  const _gtk_string &accelerator,
			  const string &item_type,
			  RECEIVER *target_widget,
			  void (RECEIVER::*target_method)(ARG_TYPE),
			  ARG_TYPE target_method_arg);
#endif

  Gtk_Widget* create_item(const string & path,
			  const _gtk_string & accelerator, 
			  const string & item_type,
			  const ItemFactoryConnectorBase& connector);
  Gtk_Widget* create_item(const string & path,
			  const _gtk_string & accelerator,
			  const string & item_type, void (*target_func)());

  // NOTE: all the get_*_widget are here "just in case". They return a
  // handle which will auto-delete once it goes out of scope. In
  // contrast, the Gtk_Widget returned by create_item() is "logged"
  // internally, and will be deleted along with the Gtk_ItemFactory.
  Gtk_ObjectHandle<Gtk_Widget>        get_widget_by_action     (guint action) const;
  Gtk_ObjectHandle<Gtk_Widget>        get_widget               (const string &path) const;
  Gtk_ObjectHandle<Gtk_Menu>          get_menu_widget          (const string &path) const;
  Gtk_ObjectHandle<Gtk_MenuBar>       get_menubar_widget       (const string &path) const;
  Gtk_ObjectHandle<Gtk_MenuItem>      get_menuitem_widget      (const string &path) const;
  Gtk_ObjectHandle<Gtk_CheckMenuItem> get_checkmenuitem_widget (const string &path) const;
  Gtk_ObjectHandle<Gtk_RadioMenuItem> get_radiomenuitem_widget (const string &path) const;
  Gtk_ObjectHandle<Gtk_OptionMenu>    get_optionmenu_widget    (const string &path) const;

// GTKMM_CXX_HAVE_AUTO_PTR
//  Gtk_Menu *get_menu_widget(const string &path);
//  Gtk_MenuBar *get_menubar_widget(const string &path);

  void delete_item(const string &path);
  void delete_entry(GtkItemFactoryEntry *entry);
  void delete_entries(guint n_entries, GtkItemFactoryEntry *entries);
  void popup(guint x, guint y, guint mouse_button, guint32 time);

  //: FIXME : 'destroy' should be a method pointer
  void popup_with_data(gpointer popup_data, GtkDestroyNotify destroy,
		       guint x, guint y,
		       guint mouse_button, guint32 time);

  gpointer popup_data();
  gpointer popup_data_from_widget(const Gtk_Widget *widget);
  static gpointer popup_data_from_widget(const Gtk_Widget &widget);

  void set_translate_func(GtkTranslateFunc     func,
			  gpointer             data,
			  GtkDestroyNotify     notify);

  
  // Compatibility functions for deprecated GtkMenuFactory code - DO NOT USE

  static Gtk_ObjectHandle<Gtk_ItemFactory> from_path(const string &path);
  static void create_menu_entries(guint n_entries, GtkMenuEntry *entries);
  static void path_delete(const string &ifactory_path, const string &path);

  Gtk_Widget* getGtk_MenuItemFromGtkWidget(GtkWidget * w);
  
  const Gtk_AccelGroup* get_accel_group();

protected:
  /* impl functions */
public:
  GtkItemFactory* gtkobj() { return GTK_ITEM_FACTORY(gtkobject); }
  const GtkItemFactory* gtkobj() const { return GTK_ITEM_FACTORY(gtkobject); }
  static bool isGtkItemFactory(Gtk_Object *checkcast);
#line 221 "itemfactory.gen_h"

  
protected:
  // This list is used to store the Gtk_Widgets constructed from the
  // created items so they can be properly destroyed along with the
  // Gtk_ItemFactory. New children are added by the
  // getGtk_MenuItemFromGtkWidget method.
  G_List<Gtk_Widget> *children_;
  Gtk_ObjectHandle<Gtk_AccelGroup> accel_group_;
};


class Gtk_ItemFactory_Menu : public Gtk_ItemFactory {
public:
  Gtk_ItemFactory_Menu(const string &path,
		       Gtk_AccelGroup &accel_group);
  Gtk_ItemFactory_Menu(const string &path);
};

class Gtk_ItemFactory_MenuBar : public Gtk_ItemFactory {
public:
  Gtk_ItemFactory_MenuBar(const string &path,
			  Gtk_AccelGroup &accel_group);
  Gtk_ItemFactory_MenuBar(const string &path);
};

class Gtk_ItemFactory_OptionMenu : public Gtk_ItemFactory {
public:
  Gtk_ItemFactory_OptionMenu(const string &path,
			     Gtk_AccelGroup &accel_group);
  Gtk_ItemFactory_OptionMenu(const string &path);
};


#ifdef GTKMM_CXX_HAVE_MEMBER_TEMPLATES
template <class RECEIVER, class ARG_TYPE>
Gtk_Widget*
Gtk_ItemFactory::create_item(const string &path,
			     const _gtk_string &accelerator,
			     const string &item_type,
			     RECEIVER *target_widget,
			     void (RECEIVER::*target_method)(ARG_TYPE),
			     ARG_TYPE target_method_arg)
{

  static GtkItemFactoryEntry entry = {0,0,0,0,0};
  Gtk_Widget* item_widget;
  entry.path = const_cast<char*>(path.c_str());
  entry.accelerator = const_cast<char*>(accelerator.gc_str());
  entry.item_type = const_cast<char*>(item_type.c_str());
  create_items(1, &entry, 0); // n_entries, entries, callback data

  // the following is cut/paste from gtk+ :)
  gchar *p,*q,*pth;
  pth = g_strdup(path.c_str());
  p=q=pth;
  while(*p) { if (*p!='_') { *q++=*p; } p++; } *q=0;
  
  item_widget = getGtk_MenuItemFromGtkWidget(gtk_item_factory_get_widget(gtkobj(),
									 pth));
  g_free(pth);
  if (target_method) {
    // First check that the created item is a Gtk_MenuItem (could be a
    // GtkMenu, in which case we can't do the connection)
    if(Gtk_MenuItem *menu_item = dynamic_cast<Gtk_MenuItem*>(item_widget))
      {
	// I assume that a compiler which is advanced enough to support member
	// templates will also support dynamic_cast<>

	connect_to_method(menu_item->activate, target_widget, 
			  target_method, target_method_arg);
      } else {
	cout <<  __FILE__ << ":" << __LINE__ << " couldn't connect type "
	     << gtk_type_name(item_widget->type()) << endl;
      }
  }
  
  children_->append(item_widget);
  return item_widget;
}

#endif


#endif
