/**********************************************************************
 *
 *   FreeDoko a Doppelkopf-Game
 *    
 *   Copyright (C) 2001-2004  by Diether Knof and Borg Enders
 *
 *   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 can find this license in the file 'gpl.txt'.
 *
 *   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
 *
 *  Contact:
 *    Diether Knof dknof@gmx.de
 *    Borg Enders  borg@borgsoft.de
 *
 *********************************************************************/

#include "constants.h"

#ifdef USE_UI_GTKMM

#include "ui.h"
#include "ui.gtkmmwrap.h"
#include "party_settings.h"
#include "preferences.h"
#include "table.h"
#include "party_points.h"
#include "main_window.h"
#include "bug_report.h"
#include "error.h"

#include "../help.h"
#include "../../basistypes.h"
#include "../../party/party.h"
#include "../../game/game.h"
#include "../../misc/setting.h"

#include "widgets/stock_button.h"

#include <gtkmm/main.h>
#include <gtkmm/messagedialog.h>
#include <gtkmm/stock.h>
#include <gtkmm/label.h>
#include <gtkmm/button.h>
#include <gtkmm/textview.h>
#include <gdk/gdkkeysyms.h>

namespace UI_GTKMM_NS {

  /**
   **
   ** updates the UI
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::update()
    {
      DEBUG_CALLING(INFO_GTKMM_UI && INFO_GTKMM_UPDATE,
		    "UI_GTKMM::update()");

      while(this->kit->events_pending())
	this->kit->iteration();

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI && INFO_GTKMM_UPDATE,
		      "UI_GTKMM::update()");
    } // void UI_GTKMM::update()

  /**
   **
   ** sleeps the given time
   ** (in miliseconds, UINT_MAX for infinity)
   **
   ** @param	slee_usec	time to sleep
   **
   ** @return	-
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   ** @todo	remove variable 'sleeping'
   **
   **/
  void
    UI_GTKMM::sleep(unsigned const sleep_usec)
    {
      DEBUG_CALLING(INFO_GTKMM_UI && INFO_GTKMM_UPDATE,
		    "UI_GTKMM::sleep(sleep_usec)");

      SigC::Connection timeout_connection
	= Glib::signal_timeout().connect(&UI_GTKMM::stop_sleeping,
					 //SigC::slot(*(this->kit),
					 //&Gtk::Main::quit),
					 sleep_usec);

      UI_GTKMM::sleeping = true;

      while (UI_GTKMM::sleeping)
	Gtk::Main::iteration();

      timeout_connection.disconnect();

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI && INFO_GTKMM_UPDATE,
		      "UI_GTKMM::sleep(usec)");
    } // void UI_GTKMM::sleep(unsigned const sleep_usec)

  /**
   **
   ** quits the innermost main loop of gtk
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::main_quit()
    {
      DEBUG_CALLING(INFO_GTKMM_UI && INFO_GTKMM_GAMEPLAY,
		    "UI_GTKMM::main_quit()");

      if (this->kit->level() > 0)
	this->kit->quit();

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI && INFO_GTKMM_GAMEPLAY,
		      "UI_GTKMM::main_quit()");
    } // void UI_GTKMM::main_quit()

  /**
   **
   ** quits the innermost main loop of gtk
   **
   ** @param	-
   **
   ** @return	true
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  bool
    UI_GTKMM::stop_sleeping()
    {
      DEBUG_CALLING(INFO_GTKMM_UI && INFO_GTKMM_GAMEPLAY,
		    "UI_GTKMM::stop_sleeping()");

      if (Gtk::Main::level() > 0)
	Gtk::Main::quit();

      UI_GTKMM::sleeping = false;

      DEBUG_RETURNING(true,
		      INFO_GTKMM_UI && INFO_GTKMM_GAMEPLAY,
		      "UI_GTKMM::stop_sleeping()");
    } // static bool UI_GTKMM::stop_sleeping()

  /**
   **
   ** quits the program
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::quit_program()
    {
      DEBUG_CALLING(INFO_GTKMM_UI && INFO_GTKMM_GAMEPLAY,
		    "UI_GTKMM::quit_program()");

      ::game_status = GAMESTATUS::QUIT;
      this->main_quit();

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI && INFO_GTKMM_GAMEPLAY,
		      "UI_GTKMM::quit_program()");
    } // void UI_GTKMM::quit_program()

  /**
   **
   ** a key has been pressed
   **
   ** @param	key	the key
   **
   ** @return	true (stop other handlers from being invoked for the event)
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   ** @todo	some shortcuts (search 'ToDo')
   **
   **/
  bool
    UI_GTKMM::key_press(GdkEventKey const* const key)
    {
      DEBUG_CALLING(INFO_GTKMM_UI && INFO_GTKMM_EVENT,
		    "UI_GTKMM::key_press(key)");

#if 0
      struct GdkEventKey {
	GdkEventType type;
	GdkWindow *window;
	gint8 send_event;
	guint32 time;
	guint state;
	guint keyval;
	gint length;
	gchar *string;
	guint16 hardware_keycode;
	guint8 group;
      };
#endif

#ifdef INFO_GTKMM_UI
      cout << "key: " << std::hex << key->keyval << endl;
#endif

      if (key->state == GDK_SHIFT_MASK) {
	switch (key->keyval) {
	case GDK_Escape: // quit the program
	  this->quit_program();
	  break;
	} // switch (key->keyval)
      } // if (key->state == GDK_SHIFT_MASK)

      if ((key->state & ~GDK_SHIFT_MASK) == 0) {
	switch (key->keyval) {
	case GDK_l: // show last trick
	  // -> menu.cpp
	  break;
	case GDK_n: // next announcement
	  if ((::game_status >= GAMESTATUS::GAME_PLAY)
	      && (::game_status < GAMESTATUS::GAME_FINISHED))
	    if (::party.game().humanno() == 1) {
	      Announcement const& last_announcement
		= ::party.game().announcement_of_team(::party.game().human_player()->team()).announcement;

	      if (last_announcement < ANNOUNCEMENT::NO0)
		if (last_announcement == ANNOUNCEMENT::NOANNOUNCEMENT)
		  ::party.game().announcement_make(ANNOUNCEMENT::NO120,
						   *(::party.game().human_player())
						  );
		else
		  ::party.game().announcement_make(Announcement(last_announcement
								+ 1),
						   *(::party.game().human_player())
						  );
	    } // if (only one human
	  break;
	case GDK_m: // announcement reply
	  if ((::game_status >= GAMESTATUS::GAME_PLAY)
	      && (::game_status < GAMESTATUS::GAME_FINISHED))
	    if (::party.game().humanno() == 1)
	      ::party.game().announcement_make(ANNOUNCEMENT::REPLY,
					       *(::party.game().human_player())
					      );
	  break;
	case GDK_h: // card suggestion
	  // -> menu.cpp
	  break;
	case GDK_r: // show the rules
	  // -> menu.cpp
	  break;
	case GDK_p: // show the party points
	  // -> menu.cpp
	  break;
	case GDK_F1: // show manual
	  // -> menu.cpp
	  break;
	case GDK_F2: // show preferences
	  // -> menu.cpp
	  break;
	case GDK_Pause: // create a bug report
	case GDK_Break: // create a bug report
	  this->bug_report->create_report();
	  break;
	case GDK_Escape:
	  break;
	} // switch (key->keyval)
      } // if (key->state == 0)

      if ((key->state & ~GDK_SHIFT_MASK) == GDK_CONTROL_MASK) {
	switch (key->keyval) {
	case GDK_a: // toggle 'show all hands'
	  // -> menu.cpp
	  break;
	case GDK_n: // start new party
	  // -> menu.cpp
	  break;
	case GDK_l: // load party
	  // -> menu.cpp
	  break;
	case GDK_s: // save party
	  // -> menu.cpp
	  break;
	case GDK_q: // quit the program
	  // -> menu.cpp
	  break;
	case GDK_r: // redraw all
	  this->redraw_all();
	  break;
	case GDK_0: // default card size
	  ::setting.set(Setting::ORIGINAL_CARDS_SIZE, true);
	  break;
	case GDK_plus: // increase card size
	  ::setting.set(Setting::CARDS_HEIGHT,
			::setting(Setting::CARDS_HEIGHT) + 1);
	  ::setting.set(Setting::ORIGINAL_CARDS_SIZE, false);
	  break;
	case GDK_minus: // decrease card size
	  ::setting.set(Setting::CARDS_HEIGHT,
			::setting(Setting::CARDS_HEIGHT) - 1);
	  ::setting.set(Setting::ORIGINAL_CARDS_SIZE, false);
	  break;
	} // switch (key->keyval)
      } // if (key->state == GDK_CONTROL_MASK)

      DEBUG_RETURNING(false,
		      INFO_GTKMM_UI && INFO_GTKMM_EVENT,
		      "UI_GTKMM::key_press(key)");
    } // bool UI_GTKMM::key_press(GdkEventKey const* const key)

  /**
   **
   ** load the page with the help
   **
   ** @param	page	the page to be loaded
   **
   ** @return	-
   **
   ** @version	0.5.2
   **
   ** @author	Diether Knof
   **
   ** @todo	all
   **
   **/
  void
    UI_GTKMM::help_load(string const& page)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::help_load(page)");

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::help_load(page)");
    } // void UI_GTKMM::help_load(string const& page)

  /**
   **
   ** shown the information
   **
   ** @param	message		message to display
   **
   ** @return	-
   **
   ** @version	0.6.2
   **
   ** @author	Diether Knof
   **
   ** @todo	remove memory leak
   ** @todo	add a parameter for a title
   **
   **/
  void
    UI_GTKMM::information(Translator::Translation const& message)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::information(message)");

      // memory leak: the dialog is never deleted
#if GTKMM_MINOR_VERSION < 4
      Gtk::MessageDialog* information
	= new Gtk::MessageDialog(Glib::locale_to_utf8(message.translation()),
				 Gtk::MESSAGE_INFO,
				 Gtk::BUTTONS_NONE,
				 false, true);
#else
      Gtk::MessageDialog* information
	= new Gtk::MessageDialog(Glib::locale_to_utf8(message.translation()),
				 false,
				 Gtk::MESSAGE_INFO,
				 Gtk::BUTTONS_NONE,
				 false);
#endif

      // memory leak: no call of 'ui->remove_from_translation(*close_button)'
      Gtk::Button* close_button
	= Gtk::manage(new Gtk::StockButton(Gtk::Stock::CLOSE, "close"));
      this->ui->add_for_translation(*close_button, ::translator("close"));
      information->add_action_widget(*close_button, Gtk::RESPONSE_CLOSE);
      close_button->show_all();

      close_button->signal_clicked().connect(SigC::slot(*information,
							&Gtk::Widget::hide)
					    );

      information->present();

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::information(message)");
    } // void UI_GTKMM::information(Translator::Translation const& message)

  /**
   **
   ** shown an error window
   ** and quit the program
   **
   ** @param	message		message to display
   **
   ** @return	-
   **
   ** @version	0.6.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::error(string const& message)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::error(message)");

      static bool already_running = false;

      if (already_running) {
	cerr << '\n'
	  << ::translator("Press <Return> to exit.").translation() << endl;
	cin.get();
      } else { // if !(already_running)

	already_running = true;

	Error error(message, this);
	error.run();
      } // if !(already_running)

#ifdef ASSERTION_GENERATES_SEGFAULT
      {
	cerr << ::translator("Creating segmentation fault.").translation() << endl;
	int const n = *(static_cast<int*>(NULL));
	(void)(n);
	cout << n << endl;
      }
#endif // #ifdef ASSERTION_GENERATES_SEGFAULT

      ::exit(EXIT_FAILURE);

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::error(message)");
    } // void UI_GTKMM::error(string const& message)

  /**
   **
   ** generate an error (for testings)
   **
   ** @param	error_message	error message
   **
   ** @return	-
   **
   ** @version	0.6.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::generate_error(string const error_message)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::generate_error(error_message)");

      ::generate_error(error_message);

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::generate_error(error_message)");
    } // void UI_GTKMM::generate_error(string const error_message)

  /**
   **
   ** add 'label' for automatic translation managed by the ui
   **
   ** @param	label		label to add
   ** @param	translation	translation for the label
   **
   ** @return	-
   **
   ** @version	0.6.5
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::add_for_translation(Gtk::Label& label,
				  Translator::Translation const& translation)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::add_for_translation(label, translation)");

      if (!label.is_realized()) {
	// postphone the adding till the label is realized
	label.signal_realize().connect(SigC::bind<Gtk::Label* const, Translator::Translation const >(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::add_label_for_translation), &label, translation));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::add_for_translation(label, translation)");
      } // if (label.is_realized())

      label.set_text(Glib::locale_to_utf8(translation.translation()));

      label.set_data("translation", new Translator::Translation(translation));

      this->translation_label.push_back(&label);

      label.signal_unrealize().connect(SigC::bind<Gtk::Widget const* const>(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::remove_from_translation), &label));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::add_for_translation(label, translation)");
    } // void UI_GTKMM::add_for_translation(Gtk::Label& label, Translator::Translation const& translation)

  /**
   **
   ** add 'button' for automatic translation managed by the ui
   **
   ** @param	button		button to add
   ** @param	translation	translation for the button text
   **
   ** @return	-
   **
   ** @version	0.6.5
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::add_for_translation(Gtk::Button& button,
				  Translator::Translation const& translation)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::add_for_translation(button, translation)");

      if (!button.is_realized()) {
	// postphone the adding till the button is realized
	button.signal_realize().connect(SigC::bind<Gtk::Button* const, Translator::Translation const >(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::add_button_for_translation), &button, translation));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::add_for_translation(button, translation)");
      } // if (button.is_realized())

      button.set_label(Glib::locale_to_utf8(translation.translation()));

      button.set_data("translation", new Translator::Translation(translation));
      this->translation_button.push_back(&button);

      button.signal_unrealize().connect(SigC::bind<Gtk::Widget const* const>(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::remove_from_translation), &button));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::add_for_translation(button, translation)");
    } // void UI_GTKMM::add_for_translation(Gtk::Button& button, Translator::Translation const& translation)

  /**
   **
   ** add 'window' for automatic translation of the title, managed by the ui
   ** The window has to be treated in a special way (mapped instead of realized)
   **
   ** @param	window	window to add
   ** @param	title	title of the window
   **
   ** @return	-
   **
   ** @version	0.6.5
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::add_for_translation(Gtk::Window& window,
				  Translator::Translation const& title)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::add_for_translation(window, title)");

      if (!window.is_mapped()) {
	// postphone the adding till the window is mapped
	window.signal_map().connect(SigC::bind<Gtk::Window* const, Translator::Translation const >(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::add_window_for_translation), &window, title));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::add_for_translation(window, translation)");
      } // if (window.is_mapped())

      window.set_title(Glib::locale_to_utf8(title.translation()));

      window.set_data("translation", new Translator::Translation(title));
      this->translation_window.push_back(&window);

      window.signal_unmap().connect(SigC::bind<Gtk::Widget const* const>(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::remove_from_translation), &window));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::add_for_translation(window, title)");
    } // void UI_GTKMM::add_for_translation(Gtk::Window& window, Translator::Translation const& title)

  /**
   **
   ** add 'text_view' for automatic translation of the text, managed by the ui
   **
   ** @param	text_view	text buffer to add
   ** @param	translation	translation for the text bufferk
   **
   ** @return	-
   **
   ** @version	0.6.5
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::add_for_translation(Gtk::TextView& text_view,
				  Translator::Translation const& translation)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::add_for_translation(text_view, translation)");

      if (!text_view.is_realized()) {
	// postphone the adding till the text_view is realized
	text_view.signal_realize().connect(SigC::bind<Gtk::TextView* const, Translator::Translation const >(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::add_text_view_for_translation), &text_view, translation));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::add_for_translation(text_view, translation)");
      } // if (text_view.is_realized())

      text_view.get_buffer()->set_text(Glib::locale_to_utf8(translation.translation()));

      text_view.set_data("translation", new Translator::Translation(translation));
      this->translation_text_view.push_back(&text_view);

      text_view.signal_unrealize().connect(SigC::bind<Gtk::Widget const* const>(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::remove_from_translation), &text_view));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::add_for_translation(text_view, translation)");
    } // void UI_GTKMM::add_for_translation(Gtk::TextView& text_view, Translator::Translation const& translation)

  /**
   **
   ** changes the translation for 'widget'
   **
   ** @param	widget		widget to change the translation for
   ** @param	translation	new translation
   **
   ** @return	-
   **
   ** @version	0.6.5
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::change_translation(Gtk::Widget& widget,
				 Translator::Translation const& translation)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::change_translation(widget, translation)");

      if (dynamic_cast<Gtk::Window*>(&widget)) {
	if (!static_cast<Gtk::Window&>(widget).is_mapped()) {
	  widget.signal_map().connect(SigC::bind<Gtk::Widget* const, Translator::Translation const >(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::change_translation), &widget, translation));
	  DEBUG_RETURNING(VOID,
			  INFO_GTKMM_UI,
			  "UI_GTKMM::change_translation(widget, translation)");
	} // if (widget not mapped)
      } else { // if (widget is Gt::Window)
	if (!widget.is_realized()) {
	  widget.signal_realize().connect(SigC::bind<Gtk::Widget* const, Translator::Translation const >(SigC::slot(*(this->ui_gtkmm_wrap), &UI_GTKMM_Wrap::change_translation), &widget, translation));
	  DEBUG_RETURNING(VOID,
			  INFO_GTKMM_UI,
			  "UI_GTKMM::change_translation(widget, translation)");
	} // if (widget not realized)
      } // if (widget is Gt::Window)

      DEBUG_ASSERTION((widget.get_data("translation") != NULL),
		      "UI_GTKMM::change_translation(widget, translation):\n"
		      "  'widget' does not contain a translation.\n"
		      "  New translation: '" << translation.translation()
		      << "'");

      delete static_cast<Translator::Translation*>(widget.get_data("translation"));
      widget.set_data("translation", new Translator::Translation(translation));

      if (dynamic_cast<Gtk::Label*>(&widget))
	static_cast<Gtk::Label&>(widget).set_text(Glib::locale_to_utf8(translation.translation()));
      else if (dynamic_cast<Gtk::Button*>(&widget))
	static_cast<Gtk::Button&>(widget).set_label(Glib::locale_to_utf8(translation.translation()));
      else if (dynamic_cast<Gtk::Window*>(&widget))
	static_cast<Gtk::Window&>(widget).set_title(Glib::locale_to_utf8(translation.translation()));
      else if (dynamic_cast<Gtk::TextView*>(&widget))
	static_cast<Gtk::TextView&>(widget).get_buffer()->set_text(Glib::locale_to_utf8(translation.translation()));
      else
	DEBUG_ASSERTION(false,
			"UI_GTKMM::Change_translation(object, translation):\n"
			"  object not found.\n"
			"  translation: " << translation.translation());

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::change_translation(widget, translation)");
    } // void UI_GTKMM::change_translation(Gtk::Widget& widget, Translator::Translation const& translation)

  /**
   **
   ** remove 'widget' from the automatic translation list
   **
   ** @param	widget	widget to remove
   **
   ** @return	-
   **
   ** @version	0.6.5
   **
   ** @author	Diether Knof
   **
   **/
  void
    UI_GTKMM::remove_from_translation(Gtk::Widget const& widget)
    {
      DEBUG_CALLING(INFO_GTKMM_UI,
		    "UI_GTKMM::remove_from_translation(widget)");

      for (vector<Gtk::Label*>::iterator l = this->translation_label.begin();
	   l != this->translation_label.end();
	  )
	if (*l == &widget)
	  l = this->translation_label.erase(l);
	else
	  ++l;

      for (vector<Gtk::Button*>::iterator b = this->translation_button.begin();
	   b != this->translation_button.end();
	  )
	if (*b == &widget)
	  b = this->translation_button.erase(b);
	else
	  ++b;

      for (vector<Gtk::Window*>::iterator w = this->translation_window.begin();
	   w != this->translation_window.end();
	  )
	if (*w == &widget)
	  w = this->translation_window.erase(w);
	else
	  ++w;

      for (vector<Gtk::TextView*>::iterator tv
	   = this->translation_text_view.begin();
	   tv != this->translation_text_view.end();
	  )
	if (*tv == &widget)
	  tv = this->translation_text_view.erase(tv);
	else
	  ++tv;

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_UI,
		      "UI_GTKMM::remove_from_translation(widget)");
    } // void UI_GTKMM::remove_from_translation(Gtk::Widget const& widget)

} // namespace UI_GTKMM_NS

#endif // #ifdef USE_UI_GTKMM
