#include <midori/midori.h>
-#include <glib/gi18n.h>
-
void
statusbar_features_app_add_browser_cb (MidoriApp* app,
MidoriBrowser* browser)
panel = katze_object_get_object (browser, "panel");
child = midori_view_new (NULL);
gtk_widget_show (child);
- midori_panel_append_page (MIDORI_PANEL (panel), child,
- NULL, GTK_STOCK_INDEX, "Tab Panel");
+ midori_panel_append_widget (MIDORI_PANEL (panel), child,
+ GTK_STOCK_INDEX, "Tab Panel", NULL);
}
static void
}
static void
-tab_panel_extension_init (TabPanelExtension* source)
+tab_panel_extension_init (TabPanelExtension* extension)
{
/* Nothing to do. */
}
#if 0
addon = midori_view_new (net);
gtk_widget_show (addon);
- midori_panel_append_page (MIDORI_PANEL (panel), addon, NULL,
- STOCK_TRANSFERS, _("Transfers"));
+ midori_panel_append_widget (MIDORI_PANEL (panel), addon,
+ STOCK_TRANSFERS, _("Transfers"), NULL);
#endif
/* Console */
gtk_widget_show (addon);
toolbar = midori_console_get_toolbar (MIDORI_CONSOLE (addon));
gtk_widget_show (toolbar);
- midori_panel_append_page (MIDORI_PANEL (panel), addon, toolbar,
- STOCK_CONSOLE, _("Console"));
+ midori_panel_append_widget (MIDORI_PANEL (panel), addon,
+ STOCK_CONSOLE, _("Console"), toolbar);
g_signal_connect (browser, "add-tab",
G_CALLBACK (midori_browser_add_tab_cb), addon);
gtk_widget_show (addon);
toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (addon));
gtk_widget_show (toolbar);
- midori_panel_append_page (MIDORI_PANEL (panel), addon, toolbar,
- STOCK_SCRIPTS, _("Userscripts"));
+ midori_panel_append_widget (MIDORI_PANEL (panel), addon,
+ STOCK_SCRIPTS, _("Userscripts"), toolbar);
/* Userstyles */
addon = midori_addons_new (MIDORI_ADDON_USER_STYLES, GTK_WIDGET (browser));
gtk_widget_show (addon);
toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (addon));
gtk_widget_show (toolbar);
- midori_panel_append_page (MIDORI_PANEL (panel), addon, toolbar,
- STOCK_STYLES, _("Userstyles"));
+ midori_panel_append_widget (MIDORI_PANEL (panel), addon,
+ STOCK_STYLES, _("Userstyles"), toolbar);
/* Extensions */
#if 0
gtk_widget_show (addon);
toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (addon));
gtk_widget_show (toolbar);
- midori_panel_append_page (MIDORI_PANEL (panel), addon, toolbar,
- STOCK_EXTENSIONS, _("Extensions"));
+ midori_panel_append_page (MIDORI_PANEL (panel), addon,
+ STOCK_EXTENSIONS, _("_Extensions"), toolbar);
#endif
}
gpointer instance;
};
+struct _MidoriAppClass
+{
+ GObjectClass parent_class;
+
+ /* Signals */
+ void
+ (*add_browser) (MidoriApp* app,
+ MidoriBrowser* browser);
+ void
+ (*quit) (MidoriApp* app);
+};
+
G_DEFINE_TYPE (MidoriApp, midori_app, G_TYPE_OBJECT)
enum
typedef struct _MidoriApp MidoriApp;
typedef struct _MidoriAppClass MidoriAppClass;
-struct _MidoriAppClass
-{
- GObjectClass parent_class;
-
- /* Signals */
- void
- (*add_browser) (MidoriApp* app,
- MidoriBrowser* browser);
- void
- (*quit) (MidoriApp* app);
-};
-
GType
midori_app_get_type (void);
_action_set_sensitive (browser, "BookmarkAdd", FALSE);
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
gtk_widget_show_all (toolbar);
- midori_panel_append_page (MIDORI_PANEL (browser->panel),
- box, toolbar,
- STOCK_BOOKMARKS, _("Bookmarks"));
+ midori_panel_append_widget (MIDORI_PANEL (browser->panel),
+ box, STOCK_BOOKMARKS, _("Bookmarks"), toolbar);
/* History */
box = gtk_vbox_new (FALSE, 0);
toolbar = gtk_ui_manager_get_widget (ui_manager, "/toolbar_history");
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
gtk_widget_show (toolbar);
- midori_panel_append_page (MIDORI_PANEL (browser->panel),
- box, toolbar,
- STOCK_HISTORY, _("History"));
+ midori_panel_append_widget (MIDORI_PANEL (browser->panel),
+ box, STOCK_HISTORY, _("History"), toolbar);
/* Pageholder */
browser->panel_pageholder = midori_view_new (browser->net);
midori_view_set_settings (MIDORI_VIEW (browser->panel_pageholder),
browser->settings);
gtk_widget_show (browser->panel_pageholder);
- midori_panel_append_page (MIDORI_PANEL (browser->panel),
- browser->panel_pageholder, NULL,
+ midori_panel_append_widget (MIDORI_PANEL (browser->panel),
+ browser->panel_pageholder,
/* i18n: A panel showing a user specified web page */
- STOCK_PAGE_HOLDER, _("Pageholder"));
+ STOCK_PAGE_HOLDER, _("Pageholder"), NULL);
/* Notebook, containing all views */
vpaned = gtk_vpaned_new ();
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-pane.h"
+
+#include <glib/gi18n.h>
+
+struct _MidoriPane
+{
+ GtkHBox parent_instance;
+};
+
+static void
+midori_pane_base_init (MidoriPaneIface* iface);
+
+GType
+midori_pane_get_type (void)
+{
+ static GType pane_type = 0;
+
+ if (!pane_type)
+ {
+ const GTypeInfo pane_info =
+ {
+ sizeof (MidoriPaneIface),
+ (GBaseInitFunc) midori_pane_base_init,
+ (GBaseFinalizeFunc) NULL,
+ };
+
+ pane_type = g_type_register_static (G_TYPE_INTERFACE,
+ "MidoriPane",
+ &pane_info, 0);
+ g_type_interface_add_prerequisite (pane_type, GTK_TYPE_WIDGET);
+ }
+
+ return pane_type;
+}
+
+static const gchar*
+midori_pane_default_get_stock_id (MidoriPane* pane)
+{
+ return NULL;
+}
+
+static const gchar*
+midori_pane_default_get_label (MidoriPane* pane)
+{
+ return NULL;
+}
+
+static GtkWidget*
+midori_pane_default_get_toolbar (MidoriPane* pane)
+{
+ return NULL;
+}
+
+static void
+midori_pane_base_init (MidoriPaneIface* iface)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized)
+ return;
+
+ iface->get_stock_id = midori_pane_default_get_stock_id;
+ iface->get_label = midori_pane_default_get_label;
+ iface->get_toolbar = midori_pane_default_get_toolbar;
+
+ initialized = TRUE;
+}
+
+/**
+ * midori_pane_get_stock_id:
+ * @pane: a #MidoriPane
+ *
+ * Retrieves the stock ID of the pane.
+ *
+ * Return value: a stock ID
+ **/
+const gchar*
+midori_pane_get_stock_id (MidoriPane* pane)
+{
+ g_return_val_if_fail (MIDORI_IS_PANE (pane), NULL);
+
+ return MIDORI_PANE_GET_IFACE (pane)->get_stock_id (pane);
+}
+
+/**
+ * midori_pane_get_label:
+ * @pane: a #MidoriPane
+ *
+ * Retrieves the label of the pane.
+ *
+ * Return value: a label string
+ **/
+const gchar*
+midori_pane_get_label (MidoriPane* pane)
+{
+ g_return_val_if_fail (MIDORI_IS_PANE (pane), NULL);
+
+ return MIDORI_PANE_GET_IFACE (pane)->get_label (pane);
+}
+
+/**
+ * midori_pane_get_toolbar:
+ * @pane: a #MidoriPane
+ *
+ * Retrieves the toolbar of the pane.
+ *
+ * Return value: a toolbar
+ **/
+GtkWidget*
+midori_pane_get_toolbar (MidoriPane* pane)
+{
+ GtkWidget* toolbar;
+
+ g_return_val_if_fail (MIDORI_IS_PANE (pane), NULL);
+
+ toolbar = MIDORI_PANE_GET_IFACE (pane)->get_toolbar (pane);
+ if (!toolbar)
+ toolbar = gtk_event_box_new ();
+ return toolbar;
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_PANE_H__
+#define __MIDORI_PANE_H__
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_PANE \
+ (midori_pane_get_type ())
+#define MIDORI_PANE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PANE, MidoriPane))
+#define MIDORI_IS_PANE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PANE))
+#define MIDORI_PANE_GET_IFACE(inst) \
+ (G_TYPE_INSTANCE_GET_INTERFACE ((inst), MIDORI_TYPE_PANE, MidoriPaneIface))
+
+typedef struct _MidoriPane MidoriPane;
+typedef struct _MidoriPaneIface MidoriPaneIface;
+
+struct _MidoriPaneIface
+{
+ GTypeInterface base_iface;
+
+ /* Virtual functions */
+ const gchar*
+ (*get_stock_id) (MidoriPane* pane);
+
+ const gchar*
+ (*get_label) (MidoriPane* pane);
+
+ GtkWidget*
+ (*get_toolbar) (MidoriPane* pane);
+};
+
+GType
+midori_pane_get_type (void);
+
+const gchar*
+midori_pane_get_stock_id (MidoriPane* pane);
+
+const gchar*
+midori_pane_get_label (MidoriPane* pane);
+
+GtkWidget*
+midori_pane_get_toolbar (MidoriPane* pane);
+
+G_END_DECLS
+
+#endif /* __MIDORI_PANE_H__ */
GtkMenu* menu;
};
+struct _MidoriPanelClass
+{
+ GtkHBoxClass parent_class;
+
+ /* Signals */
+ gboolean
+ (*close) (MidoriPanel* panel);
+};
+
G_DEFINE_TYPE (MidoriPanel, midori_panel, GTK_TYPE_HBOX)
enum
GParamSpec* pspec);
static gboolean
-midori_panel_close_cb (MidoriPanel* panel)
+midori_panel_close (MidoriPanel* panel)
{
gtk_widget_hide (GTK_WIDGET (panel));
return FALSE;
"switch-page",
G_TYPE_FROM_CLASS (class),
(GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriPanelClass, switch_page),
+ 0,
0,
NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1,
G_TYPE_INT);
- class->close = midori_panel_close_cb;
-
gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = midori_panel_finalize;
gobject_class->set_property = midori_panel_set_property;
gobject_class->get_property = midori_panel_get_property;
+ class->close = midori_panel_close;
+
flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
g_object_class_install_property (gobject_class,
MidoriPanel* panel)
{
GtkWidget* child;
- GtkToolItem* toolitem;
+ GtkToggleToolButton* toolitem;
guint n;
child = g_object_get_data (G_OBJECT (widget), "page");
if (toolitem)
{
- /* Unset the button before setting it ensures that
+ /* Unsetting the button before setting it ensures that
it will emit signals even if it was active before */
- gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (toolitem), FALSE);
- gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (toolitem), TRUE);
+ gtk_toggle_tool_button_set_active (toolitem, FALSE);
+ gtk_toggle_tool_button_set_active (toolitem, TRUE);
}
else
{
**/
gint
midori_panel_append_page (MidoriPanel* panel,
- GtkWidget* child,
- GtkWidget* toolbar,
- const gchar* stock_id,
- const gchar* label)
+ MidoriPane* pane)
{
GtkWidget* scrolled;
- GtkWidget* widget;
GObjectClass* gobject_class;
- guint n;
+ GtkWidget* widget;
+ GtkWidget* toolbar;
+ const gchar* label;
+ const gchar* stock_id;
GtkToolItem* toolitem;
GtkWidget* image;
GtkWidget* menuitem;
+ guint n;
g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
- g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
- g_return_val_if_fail (!toolbar || GTK_IS_WIDGET (toolbar), -1);
- g_return_val_if_fail (stock_id != NULL, -1);
- g_return_val_if_fail (label != NULL, -1);
+ g_return_val_if_fail (MIDORI_IS_PANE (pane), -1);
- if (GTK_IS_SCROLLED_WINDOW (child))
- scrolled = child;
+ if (GTK_IS_SCROLLED_WINDOW (pane))
+ scrolled = (GtkWidget*)pane;
else
{
scrolled = gtk_scrolled_window_new (NULL, NULL);
GTK_POLICY_AUTOMATIC);
GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
gtk_widget_show (scrolled);
- gobject_class = G_OBJECT_GET_CLASS (child);
+ gobject_class = G_OBJECT_GET_CLASS (pane);
if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
- widget = child;
+ widget = (GtkWidget*)pane;
else
{
widget = gtk_viewport_new (NULL, NULL);
gtk_widget_show (widget);
- gtk_container_add (GTK_CONTAINER (widget), child);
+ gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (pane));
}
gtk_container_add (GTK_CONTAINER (scrolled), widget);
}
gtk_container_add (GTK_CONTAINER (panel->notebook), scrolled);
- if (!toolbar)
- toolbar = gtk_event_box_new ();
+ toolbar = midori_pane_get_toolbar (pane);
gtk_widget_show (toolbar);
gtk_container_add (GTK_CONTAINER (panel->toolbook), toolbar);
n = midori_panel_page_num (panel, scrolled);
+ label = midori_pane_get_label (pane);
+ stock_id = midori_pane_get_stock_id (pane);
- g_object_set_data (G_OBJECT (child), "label", (gchar*)label);
-
- toolitem = gtk_radio_tool_button_new (panel->group);
+ toolitem = gtk_radio_tool_button_new_from_stock (panel->group, stock_id);
panel->group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (
- toolitem));
+ toolitem));
image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
- gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), label);
- gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), label);
- g_object_set_data (G_OBJECT (toolitem), "page", child);
+ if (label)
+ {
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), label);
+ gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), label);
+ }
+ g_object_set_data (G_OBJECT (toolitem), "page", pane);
g_signal_connect (toolitem, "clicked",
G_CALLBACK (midori_panel_menu_item_activate_cb), panel);
gtk_widget_show_all (GTK_WIDGET (toolitem));
{
menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL);
gtk_widget_show (menuitem);
- g_object_set_data (G_OBJECT (menuitem), "page", child);
+ g_object_set_data (G_OBJECT (menuitem), "page", pane);
g_object_set_data (G_OBJECT (menuitem), "toolitem", toolitem);
g_signal_connect (menuitem, "activate",
G_CALLBACK (midori_panel_menu_item_activate_cb),
midori_panel_set_current_page (MidoriPanel* panel,
gint n)
{
- GtkWidget* child;
+ GtkWidget* pane;
g_return_if_fail (MIDORI_IS_PANEL (panel));
gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->toolbook), n);
gtk_notebook_set_current_page (GTK_NOTEBOOK (panel->notebook), n);
- if ((child = midori_panel_get_nth_page (panel, n)))
+ if ((pane = midori_panel_get_nth_page (panel, n)))
{
- const gchar* label = g_object_get_data (G_OBJECT (child), "label");
+ const gchar* label = midori_pane_get_label (MIDORI_PANE (pane));
g_object_set (panel->toolbar_label, "label", label, NULL);
}
}
+
+typedef struct
+{
+ GtkAlignment parent_instance;
+
+ gchar* label;
+ gchar* stock_id;
+ GtkWidget* toolbar;
+} MidoriDummyPane;
+
+typedef struct
+{
+ GtkAlignmentClass parent_class;
+} MidoriDummyPaneClass;
+
+#define MIDORI_TYPE_DUMMY_PANE (midori_dummy_pane_get_type ())
+#define MIDORI_DUMMY_PANE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ MIDORI_TYPE_DUMMY_PANE, MidoriDummyPane))
+#define MIDORI_IS_DUMMY_PANE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_DUMMY_PANE))
+
+static void
+midori_dummy_pane_iface_init (MidoriPaneIface* iface);
+
+static void
+midori_dummy_pane_finalize (GObject* object);
+
+G_DEFINE_TYPE_WITH_CODE (MidoriDummyPane, midori_dummy_pane, GTK_TYPE_ALIGNMENT,
+ G_IMPLEMENT_INTERFACE (MIDORI_TYPE_PANE,
+ midori_dummy_pane_iface_init));
+
+static void
+midori_dummy_pane_class_init (MidoriDummyPaneClass* class)
+{
+ GObjectClass* gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_dummy_pane_finalize;
+}
+
+static const gchar*
+midori_dummy_pane_get_label (MidoriPane* pane)
+{
+ return MIDORI_DUMMY_PANE (pane)->label;
+}
+
+static const gchar*
+midori_dummy_pane_get_stock_id (MidoriPane* pane)
+{
+ return MIDORI_DUMMY_PANE (pane)->stock_id;
+}
+
+static GtkWidget*
+midori_dummy_pane_get_toolbar (MidoriPane* pane)
+{
+ return MIDORI_DUMMY_PANE (pane)->toolbar;
+}
+
+static void
+midori_dummy_pane_iface_init (MidoriPaneIface* iface)
+{
+ iface->get_stock_id = midori_dummy_pane_get_stock_id;
+ iface->get_label = midori_dummy_pane_get_label;
+ iface->get_toolbar = midori_dummy_pane_get_toolbar;
+}
+
+static void
+midori_dummy_pane_init (MidoriDummyPane* pane)
+{
+ pane->stock_id = NULL;
+ pane->label = NULL;
+ pane->toolbar = NULL;
+}
+
+static void
+midori_dummy_pane_finalize (GObject* object)
+{
+ MidoriDummyPane* pane = MIDORI_DUMMY_PANE (object);
+
+ katze_assign (pane->stock_id, NULL);
+ katze_assign (pane->label, NULL);
+
+ G_OBJECT_CLASS (midori_dummy_pane_parent_class)->finalize (object);
+}
+
+static GtkWidget*
+midori_dummy_pane_new (const gchar* stock_id,
+ const gchar* label,
+ GtkWidget* toolbar)
+{
+ GtkWidget* pane = g_object_new (MIDORI_TYPE_DUMMY_PANE, NULL);
+
+ MIDORI_DUMMY_PANE (pane)->stock_id = g_strdup (stock_id);
+ MIDORI_DUMMY_PANE (pane)->label = g_strdup (label);
+ MIDORI_DUMMY_PANE (pane)->toolbar = toolbar;
+
+ return pane;
+}
+
+/**
+ * midori_panel_append_widget:
+ * @panel: a #MidoriPanel
+ * @widget: the child widget
+ * @stock_id: a stock ID
+ * @label: a string to use as the label, or %NULL
+ * @toolbar: a toolbar widget, or %NULL
+ *
+ * Appends an arbitrary widget to the panel by wrapping it
+ * in a #MidoriPane created on the fly.
+ *
+ * Actually implementing #MidoriPane instead of using
+ * this convenience is recommended.
+ *
+ * In the case of an error, -1 is returned.
+ *
+ * Return value: the index of the new page, or -1
+ **/
+gint
+midori_panel_append_widget (MidoriPanel* panel,
+ GtkWidget* widget,
+ const gchar* stock_id,
+ const gchar* label,
+ GtkWidget* toolbar)
+{
+ GtkWidget* pane;
+
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
+
+ g_return_val_if_fail (stock_id != NULL, -1);
+ g_return_val_if_fail (!toolbar || GTK_IS_WIDGET (toolbar), -1);
+
+ pane = midori_dummy_pane_new (stock_id, label, toolbar);
+ gtk_widget_show (pane);
+ gtk_container_add (GTK_CONTAINER (pane), widget);
+ return midori_panel_append_page (panel, MIDORI_PANE (pane));
+}
#include <katze/katze.h>
+#include "midori-pane.h"
+
G_BEGIN_DECLS
#define MIDORI_TYPE_PANEL \
typedef struct _MidoriPanel MidoriPanel;
typedef struct _MidoriPanelClass MidoriPanelClass;
-struct _MidoriPanelClass
-{
- GtkHBoxClass parent_class;
-
- /* Signals */
- gboolean
- (*close) (MidoriPanel* panel);
-
- void
- (*switch_page) (MidoriPanel* panel,
- gint page);
-};
-
GType
midori_panel_get_type (void);
gint
midori_panel_append_page (MidoriPanel* panel,
- GtkWidget* child,
- GtkWidget* toolbar,
- const gchar* stock_id,
- const gchar* label);
+ MidoriPane* pane);
gint
midori_panel_get_current_page (MidoriPanel* panel);
midori_panel_set_current_page (MidoriPanel* panel,
gint n);
+gint
+midori_panel_append_widget (MidoriPanel* panel,
+ GtkWidget* widget,
+ const gchar* stock_id,
+ const gchar* label,
+ GtkWidget* toolbar);
+
G_END_DECLS
#endif /* __MIDORI_PANEL_H__ */
#include "midori-extension.h"
#include "midori-locationaction.h"
#include "midori-locationentry.h"
+#include "midori-pane.h"
#include "midori-panel.h"
#include "midori-preferences.h"
#include "midori-searchaction.h"
#include "midori-view.h"
#include "midori-websettings.h"
+/* For convenience, include localization header */
+#include <glib/gi18n.h>
+
#endif /* __MIDORI_H__ */