aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--embed/ephy-embed-shell.c185
-rw-r--r--embed/ephy-embed-shell.h38
-rw-r--r--embed/ephy-embed.c9
-rw-r--r--embed/ephy-embed.h166
-rw-r--r--src/ephy-tab.c13
5 files changed, 180 insertions, 231 deletions
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 9797751ea..00867ed8b 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
+ * Copyright (C) 2000-2003 Marco Pesenti Gritti
*
* 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
@@ -18,7 +18,9 @@
* $Id$
*/
-#include <config.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include "ephy-embed-shell.h"
#include "ephy-embed-factory.h"
@@ -30,8 +32,8 @@
#include "ephy-encodings.h"
#include "ephy-debug.h"
-#include <string.h>
#include <libxml/xmlreader.h>
+#include <string.h>
#define EPHY_EMBED_SHELL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EMBED_SHELL, EphyEmbedShellPrivate))
@@ -45,163 +47,119 @@ struct EphyEmbedShellPrivate
GHashTable *mime_table;
};
-static void
-ephy_embed_shell_class_init (EphyEmbedShellClass *klass);
-static void
-ephy_embed_shell_init (EphyEmbedShell *ges);
-static void
-ephy_embed_shell_finalize (GObject *object);
+static void ephy_embed_shell_class_init (EphyEmbedShellClass *klass);
+static void ephy_embed_shell_init (EphyEmbedShell *shell);
-static EphyHistory *
-impl_get_global_history (EphyEmbedShell *shell);
-static GObject *
-impl_get_downloader_view (EphyEmbedShell *shell);
+EphyEmbedShell *embed_shell = NULL;
static GObjectClass *parent_class = NULL;
-EphyEmbedShell *embed_shell;
-
GType
ephy_embed_shell_get_type (void)
{
- static GType ephy_embed_shell_type = 0;
-
- if (ephy_embed_shell_type == 0)
- {
- static const GTypeInfo our_info =
- {
- sizeof (EphyEmbedShellClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) ephy_embed_shell_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (EphyEmbedShell),
- 0, /* n_preallocs */
- (GInstanceInitFunc) ephy_embed_shell_init
- };
-
- ephy_embed_shell_type = g_type_register_static (G_TYPE_OBJECT,
- "EphyEmbedShell",
- &our_info, 0);
- }
-
- return ephy_embed_shell_type;
-}
-
-static void
-ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
-
- object_class->finalize = ephy_embed_shell_finalize;
-
- klass->get_downloader_view = impl_get_downloader_view;
- klass->get_global_history = impl_get_global_history;
+ static GType type = 0;
- g_type_class_add_private (object_class, sizeof(EphyEmbedShellPrivate));
-}
-
-static void
-ephy_embed_shell_init (EphyEmbedShell *ges)
-{
- /* Singleton, globally accessible */
- embed_shell = ges;
-
- ges->priv = EPHY_EMBED_SHELL_GET_PRIVATE (ges);
+ if (type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EphyEmbedShellClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) ephy_embed_shell_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EphyEmbedShell),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ephy_embed_shell_init
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "EphyEmbedShell",
+ &our_info, 0);
+ }
- ges->priv->global_history = NULL;
- ges->priv->downloader_view = NULL;
- ges->priv->favicon_cache = NULL;
- ges->priv->encodings = NULL;
- ges->priv->mime_table = NULL;
+ return type;
}
static void
ephy_embed_shell_finalize (GObject *object)
{
- EphyEmbedShell *ges = EPHY_EMBED_SHELL (object);
+ EphyEmbedShell *shell = EPHY_EMBED_SHELL (object);
LOG ("Unref history")
- if (ges->priv->global_history)
+ if (shell->priv->global_history)
{
- g_object_unref (ges->priv->global_history);
+ g_object_unref (shell->priv->global_history);
}
LOG ("Unref downloader")
- if (ges->priv->downloader_view)
+ if (shell->priv->downloader_view)
{
g_object_remove_weak_pointer
- (G_OBJECT(ges->priv->downloader_view),
- (gpointer *)&ges->priv->downloader_view);
- g_object_unref (ges->priv->downloader_view);
+ (G_OBJECT(shell->priv->downloader_view),
+ (gpointer *) &shell->priv->downloader_view);
+ g_object_unref (shell->priv->downloader_view);
}
LOG ("Unref favicon cache")
- if (ges->priv->favicon_cache)
+ if (shell->priv->favicon_cache)
{
- g_object_unref (G_OBJECT (ges->priv->favicon_cache));
+ g_object_unref (G_OBJECT (shell->priv->favicon_cache));
}
LOG ("Unref encodings")
- if (ges->priv->encodings)
+ if (shell->priv->encodings)
{
- g_object_unref (G_OBJECT (ges->priv->encodings));
+ g_object_unref (G_OBJECT (shell->priv->encodings));
}
LOG ("Unref embed single")
- if (ges->priv->embed_single)
+ if (shell->priv->embed_single)
{
- g_object_unref (G_OBJECT (ges->priv->embed_single));
+ g_object_unref (G_OBJECT (shell->priv->embed_single));
}
- if (ges->priv->mime_table)
+ LOG ("Destroying mime type hashtable")
+ if (shell->priv->mime_table)
{
- g_hash_table_destroy (ges->priv->mime_table);
+ g_hash_table_destroy (shell->priv->mime_table);
}
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-EphyEmbedShell *
-ephy_embed_shell_new (const char *type)
-{
- return g_object_new (EPHY_TYPE_EMBED_SHELL, NULL);
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
* ephy_embed_shell_get_favicon_cache:
- * @gs: a #EphyShell
+ * @shell: the #EphyEmbedShell
*
* Returns the favicons cache.
*
* Return value: the favicons cache
**/
GObject *
-ephy_embed_shell_get_favicon_cache (EphyEmbedShell *ees)
+ephy_embed_shell_get_favicon_cache (EphyEmbedShell *shell)
{
- if (ees->priv->favicon_cache == NULL)
+ if (shell->priv->favicon_cache == NULL)
{
- ees->priv->favicon_cache = ephy_favicon_cache_new ();
+ shell->priv->favicon_cache = ephy_favicon_cache_new ();
}
- return G_OBJECT (ees->priv->favicon_cache);
+ return G_OBJECT (shell->priv->favicon_cache);
}
EphyHistory *
ephy_embed_shell_get_global_history (EphyEmbedShell *shell)
{
EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell);
- return klass->get_global_history (shell);
+ return klass->get_global_history (shell);
}
GObject *
ephy_embed_shell_get_downloader_view (EphyEmbedShell *shell)
{
EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell);
- return klass->get_downloader_view (shell);
+ return klass->get_downloader_view (shell);
}
EphyEmbedSingle *
@@ -270,10 +228,10 @@ load_mime_from_xml (EphyEmbedShell *shell)
ret = xmlTextReaderRead (reader);
while (ret == 1)
{
- xmlChar *tag;
+ const xmlChar *tag;
xmlReaderTypes type;
- tag = xmlTextReaderName (reader);
+ tag = xmlTextReaderConstName (reader);
type = xmlTextReaderNodeType (reader);
if (xmlStrEqual (tag, "safe") && type == XML_READER_TYPE_ELEMENT)
@@ -293,8 +251,6 @@ load_mime_from_xml (EphyEmbedShell *shell)
type, GINT_TO_POINTER (permission));
}
- xmlFree (tag);
-
ret = xmlTextReaderRead (reader);
}
@@ -326,3 +282,34 @@ ephy_embed_shell_check_mime (EphyEmbedShell *shell, const char *mime_type)
return permission;
}
+
+static void
+ephy_embed_shell_init (EphyEmbedShell *shell)
+{
+ shell->priv = EPHY_EMBED_SHELL_GET_PRIVATE (shell);
+
+ /* globally accessible singleton */
+ g_assert (embed_shell == NULL);
+ embed_shell = shell;
+
+ shell->priv->global_history = NULL;
+ shell->priv->downloader_view = NULL;
+ shell->priv->favicon_cache = NULL;
+ shell->priv->encodings = NULL;
+ shell->priv->mime_table = NULL;
+}
+
+static void
+ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
+
+ object_class->finalize = ephy_embed_shell_finalize;
+
+ klass->get_downloader_view = impl_get_downloader_view;
+ klass->get_global_history = impl_get_global_history;
+
+ g_type_class_add_private (object_class, sizeof (EphyEmbedShellPrivate));
+}
diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h
index faac44746..3bff4327b 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -38,17 +38,17 @@ G_BEGIN_DECLS
#define EPHY_IS_EMBED_SHELL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_EMBED_SHELL))
#define EPHY_EMBED_SHELL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_EMBED_SHELL, EphyEmbedShellClass))
-typedef struct EphyEmbedShellClass EphyEmbedShellClass;
-typedef struct EphyEmbedShell EphyEmbedShell;
-typedef struct EphyEmbedShellPrivate EphyEmbedShellPrivate;
+typedef struct EphyEmbedShellClass EphyEmbedShellClass;
+typedef struct EphyEmbedShell EphyEmbedShell;
+typedef struct EphyEmbedShellPrivate EphyEmbedShellPrivate;
extern EphyEmbedShell *embed_shell;
typedef enum
{
- EPHY_MIME_PERMISSION_SAFE = 1,
- EPHY_MIME_PERMISSION_UNSAFE = 2,
- EPHY_MIME_PERMISSION_UNKNOWN = 3
+ EPHY_MIME_PERMISSION_SAFE = 1,
+ EPHY_MIME_PERMISSION_UNSAFE = 2,
+ EPHY_MIME_PERMISSION_UNKNOWN = 3
} EphyMimePermission;
struct EphyEmbedShell
@@ -61,31 +61,27 @@ struct EphyEmbedShell
struct EphyEmbedShellClass
{
- GObjectClass parent_class;
+ GObjectClass parent_class;
/* Methods */
- EphyHistory * (* get_global_history) (EphyEmbedShell *shell);
- GObject * (* get_downloader_view) (EphyEmbedShell *shell);
+ EphyHistory * (* get_global_history) (EphyEmbedShell *shell);
+ GObject * (* get_downloader_view) (EphyEmbedShell *shell);
};
-GType ephy_embed_shell_get_type (void);
+GType ephy_embed_shell_get_type (void);
-GType ephy_embed_shell_get_impl (void);
+GObject *ephy_embed_shell_get_favicon_cache (EphyEmbedShell *ges);
-EphyEmbedShell *ephy_embed_shell_new (const char *type);
+EphyHistory *ephy_embed_shell_get_global_history (EphyEmbedShell *shell);
-GObject *ephy_embed_shell_get_favicon_cache (EphyEmbedShell *ges);
+GObject *ephy_embed_shell_get_downloader_view (EphyEmbedShell *shell);
-EphyHistory *ephy_embed_shell_get_global_history (EphyEmbedShell *shell);
+GObject *ephy_embed_shell_get_encodings (EphyEmbedShell *shell);
-GObject *ephy_embed_shell_get_downloader_view (EphyEmbedShell *shell);
+EphyEmbedSingle *ephy_embed_shell_get_embed_single (EphyEmbedShell *shell);
-GObject *ephy_embed_shell_get_encodings (EphyEmbedShell *shell);
-
-EphyEmbedSingle *ephy_embed_shell_get_embed_single (EphyEmbedShell *shell);
-
-EphyMimePermission ephy_embed_shell_check_mime (EphyEmbedShell *shell,
- const char *mime_type);
+EphyMimePermission ephy_embed_shell_check_mime (EphyEmbedShell *shell,
+ const char *mime_type);
G_END_DECLS
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index 6028472fe..f6acc50e6 100644
--- a/embed/ephy-embed.c
+++ b/embed/ephy-embed.c
@@ -107,15 +107,6 @@ ephy_embed_base_init (gpointer g_class)
2,
G_TYPE_STRING,
G_TYPE_INT);
- g_signal_new ("ge_open_uri",
- EPHY_TYPE_EMBED,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (EphyEmbedClass, open_uri),
- NULL, NULL,
- ephy_marshal_INT__STRING,
- G_TYPE_INT,
- 1,
- G_TYPE_STRING);
g_signal_new ("ge_dom_mouse_click",
EPHY_TYPE_EMBED,
G_SIGNAL_RUN_LAST,
diff --git a/embed/ephy-embed.h b/embed/ephy-embed.h
index 8d16da850..4cd7a5371 100644
--- a/embed/ephy-embed.h
+++ b/embed/ephy-embed.h
@@ -37,56 +37,45 @@ G_BEGIN_DECLS
#define EPHY_IS_EMBED_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_EMBED))
#define EPHY_EMBED_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EPHY_TYPE_EMBED, EphyEmbedClass))
-typedef struct EphyEmbedClass EphyEmbedClass;
-typedef struct _EphyEmbed EphyEmbed;
+typedef struct EphyEmbedClass EphyEmbedClass;
+typedef struct _EphyEmbed EphyEmbed;
typedef enum
{
- EMBED_STATE_UNKNOWN = 0,
- EMBED_STATE_START = 1 << 0,
- EMBED_STATE_REDIRECTING = 1 << 1,
- EMBED_STATE_TRANSFERRING = 1 << 2,
- EMBED_STATE_NEGOTIATING = 1 << 3,
- EMBED_STATE_STOP = 1 << 4,
-
- EMBED_STATE_IS_REQUEST = 1 << 5,
- EMBED_STATE_IS_DOCUMENT = 1 << 6,
- EMBED_STATE_IS_NETWORK = 1 << 7,
- EMBED_STATE_IS_WINDOW = 1 << 8
+ EMBED_STATE_UNKNOWN = 0,
+ EMBED_STATE_START = 1 << 0,
+ EMBED_STATE_REDIRECTING = 1 << 1,
+ EMBED_STATE_TRANSFERRING = 1 << 2,
+ EMBED_STATE_NEGOTIATING = 1 << 3,
+ EMBED_STATE_STOP = 1 << 4,
+
+ EMBED_STATE_IS_REQUEST = 1 << 5,
+ EMBED_STATE_IS_DOCUMENT = 1 << 6,
+ EMBED_STATE_IS_NETWORK = 1 << 7,
+ EMBED_STATE_IS_WINDOW = 1 << 8
} EmbedState;
typedef enum
{
- EMBED_CHROME_NONE = 0,
- EMBED_CHROME_DEFAULT = 1 << 0,
- EMBED_CHROME_MENUBARON = 1 << 1,
- EMBED_CHROME_TOOLBARON = 1 << 2,
- EMBED_CHROME_BOOKMARKSBARON = 1 << 3,
- EMBED_CHROME_BOOKMARKSBAR_DEFAULT = 1 << 4,
- EMBED_CHROME_STATUSBARON = 1 << 5,
- EMBED_CHROME_WINDOWRAISED = 1 << 6,
- EMBED_CHROME_WINDOWLOWERED = 1 << 7,
- EMBED_CHROME_CENTERSCREEN = 1 << 8,
- EMBED_CHROME_OPENASDIALOG = 1 << 9,
- EMBED_CHROME_OPENASCHROME = 1 << 10,
- EMBED_CHROME_OPENASPOPUP = 1 << 11,
- EMBED_CHROME_PPVIEWTOOLBARON = 1 << 12
+ EMBED_CHROME_NONE = 0,
+ EMBED_CHROME_DEFAULT = 1 << 0,
+ EMBED_CHROME_MENUBARON = 1 << 1,
+ EMBED_CHROME_TOOLBARON = 1 << 2,
+ EMBED_CHROME_BOOKMARKSBARON = 1 << 3,
+ EMBED_CHROME_BOOKMARKSBAR_DEFAULT = 1 << 4,
+ EMBED_CHROME_STATUSBARON = 1 << 5,
+ EMBED_CHROME_WINDOWRAISED = 1 << 6,
+ EMBED_CHROME_WINDOWLOWERED = 1 << 7,
+ EMBED_CHROME_CENTERSCREEN = 1 << 8,
+ EMBED_CHROME_OPENASDIALOG = 1 << 9,
+ EMBED_CHROME_OPENASCHROME = 1 << 10,
+ EMBED_CHROME_OPENASPOPUP = 1 << 11,
+ EMBED_CHROME_PPVIEWTOOLBARON = 1 << 12
} EmbedChromeMask;
-typedef struct
-{
- char *modification_date;
-
- /* lists of hashtables with gvalues */
- GList *images; /* url, alt, title, width, height */
- GList *forms; /* action, type */
- GList *links; /* url, title, type */
- GList *stylesheets; /* url, title */
-} EmbedPageInfo;
-
typedef enum
{
- EMBED_RELOAD_NORMAL = 1 << 1,
+ EMBED_RELOAD_NORMAL = 1 << 1,
EMBED_RELOAD_BYPASSCACHE = 1 << 2,
EMBED_RELOAD_BYPASSPROXY = 1 << 3
} EmbedReloadFlags;
@@ -94,21 +83,22 @@ typedef enum
typedef struct
{
gboolean print_to_file;
- gchar *printer;
- gchar *file;
- gchar *paper;
- gint top_margin;
- gint bottom_margin;
- gint left_margin;
- gint right_margin;
- gint pages;
- gint from_page;
- gint to_page;
- gint frame_type;
- gint orientation;
+ char *printer;
+ char *file;
+ char *paper;
+ int top_margin;
+ int bottom_margin;
+ int left_margin;
+ int right_margin;
+ int pages;
+ int from_page;
+ int to_page;
+ int frame_type;
+ int orientation;
gboolean print_color;
+ gboolean preview;
- /*
+ /*
* &T - title
* &U - Document URL
* &D - Date/Time
@@ -118,24 +108,22 @@ typedef struct
* So, if headerLeftStr = "&T" the title and the document URL
* will be printed out on the top left-hand side of each page.
*/
- gchar *header_left_string;
- gchar *header_center_string;
- gchar *header_right_string;
- gchar *footer_left_string;
- gchar *footer_center_string;
- gchar *footer_right_string;
-
- gboolean preview;
+ char *header_left_string;
+ char *header_center_string;
+ char *header_right_string;
+ char *footer_left_string;
+ char *footer_center_string;
+ char *footer_right_string;
}
EmbedPrintInfo;
typedef enum
{
- PRINTPREVIEW_GOTO_PAGENUM = 0,
- PRINTPREVIEW_PREV_PAGE = 1,
- PRINTPREVIEW_NEXT_PAGE = 2,
- PRINTPREVIEW_HOME = 3,
- PRINTPREVIEW_END = 4
+ PRINTPREVIEW_GOTO_PAGENUM = 0,
+ PRINTPREVIEW_PREV_PAGE = 1,
+ PRINTPREVIEW_NEXT_PAGE = 2,
+ PRINTPREVIEW_HOME = 3,
+ PRINTPREVIEW_END = 4
} EmbedPrintPreviewNavType;
typedef enum
@@ -160,32 +148,32 @@ struct EphyEmbedClass
* gboolean visibility);
* void (* destroy_brsr) (EphyEmbed *embed);
* void (* size_to) (EphyEmbed *embed,
- * gint width,
- * gint height);
+ * int width,
+ * int height);
+ * gint (* open_uri) (EphyEmbed *embed,
+ * const char *url);
*/
- gint (* context_menu) (EphyEmbed *embed,
- EphyEmbedEvent *event);
- void (* favicon) (EphyEmbed *embed,
- const char *location);
- void (* location) (EphyEmbed *embed,
- const char *location);
- void (* net_state) (EphyEmbed *embed,
- const char *uri,
- EmbedState state);
- void (* new_window) (EphyEmbed *embed,
- EphyEmbed **new_embed,
- EmbedChromeMask chromemask);
- gint (* open_uri) (EphyEmbed *embed,
- const char *uri);
- gint (* dom_mouse_click) (EphyEmbed *embed,
- EphyEmbedEvent *event);
- gint (* dom_mouse_down) (EphyEmbed *embed,
- EphyEmbedEvent *event);
- void (* security_change) (EphyEmbed *embed,
- EmbedSecurityLevel level);
- void (* zoom_change) (EphyEmbed *embed,
- guint new_zoom);
+ int (* context_menu) (EphyEmbed *embed,
+ EphyEmbedEvent *event);
+ void (* favicon) (EphyEmbed *embed,
+ const char *location);
+ void (* location) (EphyEmbed *embed,
+ const char *location);
+ void (* net_state) (EphyEmbed *embed,
+ const char *uri,
+ EmbedState state);
+ void (* new_window) (EphyEmbed *embed,
+ EphyEmbed **new_embed,
+ EmbedChromeMask chromemask);
+ gboolean (* dom_mouse_click) (EphyEmbed *embed,
+ EphyEmbedEvent *event);
+ gboolean (* dom_mouse_down) (EphyEmbed *embed,
+ EphyEmbedEvent *event);
+ void (* security_change) (EphyEmbed *embed,
+ EmbedSecurityLevel level);
+ void (* zoom_change) (EphyEmbed *embed,
+ float new_zoom);
/* Methods */
void (* load_url) (EphyEmbed *embed,
diff --git a/src/ephy-tab.c b/src/ephy-tab.c
index 960090bd8..d0ce85908 100644
--- a/src/ephy-tab.c
+++ b/src/ephy-tab.c
@@ -911,16 +911,6 @@ ephy_tab_destroy_brsr_cb (EphyEmbed *embed, EphyTab *tab)
ephy_window_remove_tab (tab->priv->window, tab);
}
-static gint
-ephy_tab_open_uri_cb (EphyEmbed *embed, const char *uri,
- EphyTab *tab)
-{
- LOG ("ephy_tab_open_uri_cb %s", uri)
-
- /* FIXME: what is this function supposed to do ? */
- return FALSE;
-}
-
static void
ephy_tab_size_to_cb (EphyEmbed *embed, gint width, gint height,
EphyTab *tab)
@@ -1112,9 +1102,6 @@ ephy_tab_init (EphyTab *tab)
g_signal_connect (embed, "destroy_browser",
G_CALLBACK (ephy_tab_destroy_brsr_cb),
tab);
- g_signal_connect (embed, "ge_open_uri",
- G_CALLBACK (ephy_tab_open_uri_cb),
- tab);
g_signal_connect (embed, "size_to",
G_CALLBACK (ephy_tab_size_to_cb),
tab);