1 /*
2  * Copyright (C) 2009 - 2012 Vivien Malerba <malerba@gnome-db.org>
3  * Copyright (C) 2010 David King <davidk@openismus.com>
4  * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 
21 #include <string.h>
22 #include <glib/gi18n-lib.h>
23 #include "schema-browser-perspective.h"
24 #include "favorite-selector.h"
25 #include "objects-index.h"
26 #include "../browser-window.h"
27 #include "table-info.h"
28 #include "../support.h"
29 #include "../browser-page.h"
30 #ifdef HAVE_GOOCANVAS
31 #include "relations-diagram.h"
32 #endif
33 #include <libgda/gda-debug-macros.h>
34 
35 /*
36  * Main static functions
37  */
38 static void schema_browser_perspective_class_init (SchemaBrowserPerspectiveClass *klass);
39 static void schema_browser_perspective_init (SchemaBrowserPerspective *stmt);
40 static void schema_browser_perspective_dispose (GObject *object);
41 
42 /* BrowserPerspective interface */
43 static void                 schema_browser_perspective_perspective_init (BrowserPerspectiveIface *iface);
44 static BrowserWindow       *schema_browser_perspective_get_window (BrowserPerspective *perspective);
45 static GtkActionGroup      *schema_browser_perspective_get_actions_group (BrowserPerspective *perspective);
46 static const gchar         *schema_browser_perspective_get_actions_ui (BrowserPerspective *perspective);
47 static void                 schema_browser_perspective_page_tab_label_change (BrowserPerspective *perspective, BrowserPage *page);
48 static void                 schema_browser_perspective_get_current_customization (BrowserPerspective *perspective,
49 										  GtkActionGroup **out_agroup,
50 										  const gchar **out_ui);
51 
52 /* get a pointer to the parents to be able to call their destructor */
53 static GObjectClass  *parent_class = NULL;
54 
55 struct _SchemaBrowserPerspectivePrivate {
56 	GtkWidget *notebook;
57 	GtkWidget *favorites;
58 	gboolean favorites_shown;
59 	BrowserWindow *bwin;
60 };
61 
62 GType
schema_browser_perspective_get_type(void)63 schema_browser_perspective_get_type (void)
64 {
65 	static GType type = 0;
66 
67 	if (G_UNLIKELY (type == 0)) {
68 		static GMutex registering;
69 		static const GTypeInfo info = {
70 			sizeof (SchemaBrowserPerspectiveClass),
71 			(GBaseInitFunc) NULL,
72 			(GBaseFinalizeFunc) NULL,
73 			(GClassInitFunc) schema_browser_perspective_class_init,
74 			NULL,
75 			NULL,
76 			sizeof (SchemaBrowserPerspective),
77 			0,
78 			(GInstanceInitFunc) schema_browser_perspective_init,
79 			0
80 		};
81 
82 		static GInterfaceInfo perspective_info = {
83                         (GInterfaceInitFunc) schema_browser_perspective_perspective_init,
84 			NULL,
85                         NULL
86                 };
87 
88 		g_mutex_lock (&registering);
89 		if (type == 0) {
90 			type = g_type_register_static (GTK_TYPE_BOX, "SchemaBrowserPerspective", &info, 0);
91 			g_type_add_interface_static (type, BROWSER_PERSPECTIVE_TYPE, &perspective_info);
92 		}
93 		g_mutex_unlock (&registering);
94 	}
95 	return type;
96 }
97 
98 static void
schema_browser_perspective_class_init(SchemaBrowserPerspectiveClass * klass)99 schema_browser_perspective_class_init (SchemaBrowserPerspectiveClass * klass)
100 {
101 	GObjectClass   *object_class = G_OBJECT_CLASS (klass);
102 	parent_class = g_type_class_peek_parent (klass);
103 
104 	object_class->dispose = schema_browser_perspective_dispose;
105 }
106 
107 static void
schema_browser_perspective_perspective_init(BrowserPerspectiveIface * iface)108 schema_browser_perspective_perspective_init (BrowserPerspectiveIface *iface)
109 {
110 	iface->i_get_window = schema_browser_perspective_get_window;
111 	iface->i_get_actions_group = schema_browser_perspective_get_actions_group;
112 	iface->i_get_actions_ui = schema_browser_perspective_get_actions_ui;
113 	iface->i_page_tab_label_change = schema_browser_perspective_page_tab_label_change;
114 	iface->i_get_current_customization = schema_browser_perspective_get_current_customization;
115 }
116 
117 
118 static void
schema_browser_perspective_init(SchemaBrowserPerspective * perspective)119 schema_browser_perspective_init (SchemaBrowserPerspective *perspective)
120 {
121 	perspective->priv = g_new0 (SchemaBrowserPerspectivePrivate, 1);
122 	perspective->priv->favorites_shown = TRUE;
123 
124 	gtk_orientable_set_orientation (GTK_ORIENTABLE (perspective), GTK_ORIENTATION_VERTICAL);
125 }
126 
127 static void fav_selection_changed_cb (GtkWidget *widget, gint fav_id, ToolsFavoritesType fav_type,
128 				      const gchar *selection, SchemaBrowserPerspective *bpers);
129 static void objects_index_selection_changed_cb (GtkWidget *widget, ToolsFavoritesType fav_type,
130 						const gchar *selection, SchemaBrowserPerspective *bpers);
131 /**
132  * schema_browser_perspective_new
133  *
134  * Creates new #BrowserPerspective widget which
135  */
136 BrowserPerspective *
schema_browser_perspective_new(BrowserWindow * bwin)137 schema_browser_perspective_new (BrowserWindow *bwin)
138 {
139 	BrowserConnection *bcnc;
140 	BrowserPerspective *bpers;
141 	SchemaBrowserPerspective *perspective;
142 	gboolean fav_supported;
143 
144 	bpers = (BrowserPerspective*) g_object_new (TYPE_SCHEMA_BROWSER_PERSPECTIVE, NULL);
145 	perspective = (SchemaBrowserPerspective*) bpers;
146 	bcnc = browser_window_get_connection (bwin);
147 	fav_supported = browser_connection_get_favorites (bcnc) ? TRUE : FALSE;
148 	perspective->priv->bwin = bwin;
149 
150 	/* contents */
151 	GtkWidget *paned, *wid, *nb;
152 	paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
153 	if (fav_supported) {
154 		wid = favorite_selector_new (bcnc);
155 		g_signal_connect (wid, "selection-changed",
156 				  G_CALLBACK (fav_selection_changed_cb), bpers);
157 		gtk_paned_add1 (GTK_PANED (paned), wid);
158 		gtk_paned_set_position (GTK_PANED (paned), DEFAULT_FAVORITES_SIZE);
159 		perspective->priv->favorites = wid;
160 	}
161 
162 	nb = gtk_notebook_new ();
163 	perspective->priv->notebook = nb;
164 	gtk_paned_add2 (GTK_PANED (paned), nb);
165 	gtk_notebook_set_scrollable (GTK_NOTEBOOK (nb), TRUE);
166 	gtk_notebook_popup_enable (GTK_NOTEBOOK (nb));
167 
168 	wid = objects_index_new (bcnc);
169 	g_signal_connect (wid, "selection-changed",
170 			  G_CALLBACK (objects_index_selection_changed_cb), bpers);
171 	gtk_notebook_append_page (GTK_NOTEBOOK (nb), wid,
172 				  browser_make_tab_label_with_stock (_("Index"), GTK_STOCK_ABOUT, FALSE,
173 								     NULL));
174 	gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (nb), wid, TRUE);
175 	gtk_notebook_set_group_name (GTK_NOTEBOOK (nb), "schema-browser");
176 
177 	gtk_notebook_set_menu_label (GTK_NOTEBOOK (nb), wid,
178 				     browser_make_tab_label_with_stock (_("Index"), GTK_STOCK_ABOUT, FALSE,
179 									NULL));
180 	gtk_box_pack_start (GTK_BOX (bpers), paned, TRUE, TRUE, 0);
181 	gtk_widget_show_all (paned);
182 
183 	if (perspective->priv->favorites && !perspective->priv->favorites_shown)
184 		gtk_widget_hide (perspective->priv->favorites);
185 
186 	browser_perspective_declare_notebook (bpers, GTK_NOTEBOOK (perspective->priv->notebook));
187 
188 	return bpers;
189 }
190 
191 static void
close_button_clicked_cb(G_GNUC_UNUSED GtkWidget * wid,GtkWidget * page_widget)192 close_button_clicked_cb (G_GNUC_UNUSED GtkWidget *wid, GtkWidget *page_widget)
193 {
194 	gtk_widget_destroy (page_widget);
195 }
196 
197 static void
objects_index_selection_changed_cb(GtkWidget * widget,ToolsFavoritesType fav_type,const gchar * selection,SchemaBrowserPerspective * bpers)198 objects_index_selection_changed_cb (GtkWidget *widget, ToolsFavoritesType fav_type,
199 				    const gchar *selection, SchemaBrowserPerspective *bpers)
200 {
201 	fav_selection_changed_cb (widget, -1, fav_type, selection, bpers);
202 }
203 
204 
205 static void
fav_selection_changed_cb(G_GNUC_UNUSED GtkWidget * widget,gint fav_id,ToolsFavoritesType fav_type,const gchar * selection,SchemaBrowserPerspective * bpers)206 fav_selection_changed_cb (G_GNUC_UNUSED GtkWidget *widget, gint fav_id, ToolsFavoritesType fav_type,
207 			  const gchar *selection, SchemaBrowserPerspective *bpers)
208 {
209 	if (fav_type == GDA_TOOLS_FAVORITES_TABLES) {
210 		GdaQuarkList *ql;
211 		const gchar *type;
212 		const gchar *schema = NULL, *table = NULL, *short_name = NULL;
213 
214 		ql = gda_quark_list_new_from_string (selection);
215 		if (ql) {
216 			type = gda_quark_list_find (ql, "OBJ_TYPE");
217 			schema = gda_quark_list_find (ql, "OBJ_SCHEMA");
218 			table = gda_quark_list_find (ql, "OBJ_NAME");
219 			short_name = gda_quark_list_find (ql, "OBJ_SHORT_NAME");
220 		}
221 
222 		if (!type || !schema || !table) {
223 			if (ql)
224 				gda_quark_list_free (ql);
225 			return;
226 		}
227 
228 		if (!strcmp (type, "table")) {
229 			schema_browser_perspective_display_table_info (bpers, schema, table, short_name);
230 		}
231 		else {
232 			gint ntabs, i;
233 			ntabs = gtk_notebook_get_n_pages (GTK_NOTEBOOK (bpers->priv->notebook));
234 			for (i = 0; i < ntabs; i++) {
235 				GtkWidget *child;
236 				child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (bpers->priv->notebook), i);
237 				if (IS_TABLE_INFO (child)) {
238 					if (!strcmp (schema, table_info_get_table_schema (TABLE_INFO (child))) &&
239 					    !strcmp (table, table_info_get_table_name (TABLE_INFO (child)))) {
240 						gtk_notebook_set_current_page (GTK_NOTEBOOK (bpers->priv->notebook), i);
241 						return;
242 					}
243 				}
244 			}
245 
246 			g_warning ("Non handled favorite type: %s", type);
247 			TO_IMPLEMENT;
248 		}
249 
250 		if (ql)
251 			gda_quark_list_free (ql);
252 	}
253 	else if (fav_type == GDA_TOOLS_FAVORITES_DIAGRAMS) {
254 #ifdef HAVE_GOOCANVAS
255 		schema_browser_perspective_display_diagram (bpers, fav_id);
256 #else
257 		g_warning ("Can't display diagram because canvas not compiled.");
258 #endif
259 	}
260 #ifdef GDA_DEBUG_NO
261 	g_print ("Reacted to selection fav_id=>%d type=>%u, contents=>%s\n", fav_id, fav_type, selection);
262 #endif
263 }
264 
265 static void
schema_browser_perspective_dispose(GObject * object)266 schema_browser_perspective_dispose (GObject *object)
267 {
268 	SchemaBrowserPerspective *perspective;
269 
270 	g_return_if_fail (object != NULL);
271 	g_return_if_fail (IS_SCHEMA_BROWSER_PERSPECTIVE (object));
272 
273 	perspective = SCHEMA_BROWSER_PERSPECTIVE (object);
274 	if (perspective->priv) {
275 		browser_perspective_declare_notebook ((BrowserPerspective*) perspective, NULL);
276 		g_free (perspective->priv);
277 		perspective->priv = NULL;
278 	}
279 
280 	/* parent class */
281 	parent_class->dispose (object);
282 }
283 
284 #ifdef HAVE_GOOCANVAS
285 static void
action_create_diagram_cb(G_GNUC_UNUSED GtkAction * action,SchemaBrowserPerspective * bpers)286 action_create_diagram_cb (G_GNUC_UNUSED GtkAction *action, SchemaBrowserPerspective *bpers)
287 {
288 	schema_browser_perspective_display_diagram (bpers, -1);
289 }
290 #endif
291 
292 static void
favorites_toggle_cb(GtkToggleAction * action,BrowserPerspective * bpers)293 favorites_toggle_cb (GtkToggleAction *action, BrowserPerspective *bpers)
294 {
295 	SchemaBrowserPerspective *perspective;
296 	perspective = SCHEMA_BROWSER_PERSPECTIVE (bpers);
297 	if (! perspective->priv->favorites)
298 		return;
299 
300 	perspective->priv->favorites_shown = gtk_toggle_action_get_active (action);
301 	if (perspective->priv->favorites_shown)
302 		gtk_widget_show (perspective->priv->favorites);
303 	else
304 		gtk_widget_hide (perspective->priv->favorites);
305 }
306 
307 static const GtkToggleActionEntry ui_toggle_actions [] =
308 {
309         { "SchemaToolsFavoritesShow", NULL, N_("_Show Favorites"), "F9", N_("Show or hide favorites"), G_CALLBACK (favorites_toggle_cb), FALSE }
310 };
311 
312 static GtkActionEntry ui_actions[] = {
313 #ifdef HAVE_GOOCANVAS
314         { "Schema", NULL, N_("_Schema"), NULL, N_("Schema"), NULL },
315         { "NewDiagram", GTK_STOCK_ADD, N_("_New Diagram"), NULL, N_("Create a new diagram"),
316           G_CALLBACK (action_create_diagram_cb)},
317 #endif
318 };
319 
320 static const gchar *ui_actions_info =
321         "<ui>"
322         "  <menubar name='MenuBar'>"
323 	"    <menu name='Display' action='Display'>"
324 	"      <menuitem name='SchemaToolsFavoritesShow' action='SchemaToolsFavoritesShow'/>"
325         "    </menu>"
326 #ifdef HAVE_GOOCANVAS
327         "    <placeholder name='MenuExtension'>"
328         "      <menu name='Schema' action='Schema'>"
329         "        <menuitem name='NewDiagram' action= 'NewDiagram'/>"
330         "      </menu>"
331         "    </placeholder>"
332 #endif
333         "  </menubar>"
334         "</ui>";
335 
336 static GtkActionGroup *
schema_browser_perspective_get_actions_group(BrowserPerspective * perspective)337 schema_browser_perspective_get_actions_group (BrowserPerspective *perspective)
338 {
339 	SchemaBrowserPerspective *bpers;
340 	GtkActionGroup *agroup;
341 	bpers = SCHEMA_BROWSER_PERSPECTIVE (perspective);
342 	agroup = gtk_action_group_new ("SchemaBrowserActions");
343 	gtk_action_group_set_translation_domain (agroup, GETTEXT_PACKAGE);
344 
345 	gtk_action_group_add_actions (agroup, ui_actions, G_N_ELEMENTS (ui_actions), bpers);
346 
347 	gtk_action_group_add_toggle_actions (agroup, ui_toggle_actions,
348 					     G_N_ELEMENTS (ui_toggle_actions),
349 					     bpers);
350 	GtkAction *action;
351 	action = gtk_action_group_get_action (agroup, "SchemaToolsFavoritesShow");
352 	if (bpers->priv->favorites)
353 		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
354 					      bpers->priv->favorites_shown);
355 	else
356 		gtk_action_set_sensitive (GTK_ACTION (action), FALSE);
357 
358 	return agroup;
359 }
360 
361 static const gchar *
schema_browser_perspective_get_actions_ui(G_GNUC_UNUSED BrowserPerspective * bpers)362 schema_browser_perspective_get_actions_ui (G_GNUC_UNUSED BrowserPerspective *bpers)
363 {
364 	return ui_actions_info;
365 }
366 
367 static void
schema_browser_perspective_page_tab_label_change(BrowserPerspective * perspective,BrowserPage * page)368 schema_browser_perspective_page_tab_label_change (BrowserPerspective *perspective, BrowserPage *page)
369 {
370 	SchemaBrowserPerspective *bpers;
371 	GtkWidget *tab_label;
372 	GtkWidget *close_btn;
373 
374 	bpers = SCHEMA_BROWSER_PERSPECTIVE (perspective);
375 	tab_label = browser_page_get_tab_label (page, &close_btn);
376 	if (tab_label) {
377 		gtk_notebook_set_tab_label (GTK_NOTEBOOK (bpers->priv->notebook),
378 					    GTK_WIDGET (page), tab_label);
379 		g_signal_connect (close_btn, "clicked",
380 				  G_CALLBACK (close_button_clicked_cb), page);
381 
382 		tab_label = browser_page_get_tab_label (page, NULL);
383 		gtk_notebook_set_menu_label (GTK_NOTEBOOK (bpers->priv->notebook),
384 					     GTK_WIDGET (page), tab_label);
385 	}
386 }
387 
388 #ifdef HAVE_GOOCANVAS
389 /**
390  * schema_browser_perspective_display_diagram
391  *
392  */
393 void
schema_browser_perspective_display_diagram(SchemaBrowserPerspective * bpers,gint fav_id)394 schema_browser_perspective_display_diagram (SchemaBrowserPerspective *bpers, gint fav_id)
395 {
396 	GtkWidget *diagram = NULL;
397 
398 	if (fav_id >= 0) {
399 		gint ntabs, i;
400 
401 		ntabs = gtk_notebook_get_n_pages (GTK_NOTEBOOK (bpers->priv->notebook));
402 		for (i = 0; i < ntabs; i++) {
403 			GtkWidget *child;
404 			child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (bpers->priv->notebook), i);
405 			if (IS_RELATIONS_DIAGRAM (child)) {
406 				if (relations_diagram_get_fav_id (RELATIONS_DIAGRAM (child)) == fav_id) {
407 					gtk_notebook_set_current_page (GTK_NOTEBOOK (bpers->priv->notebook), i);
408 					return;
409 				}
410 			}
411 		}
412 
413 		GError *error = NULL;
414 		diagram = relations_diagram_new_with_fav_id (browser_window_get_connection (bpers->priv->bwin),
415 							     fav_id, &error);
416 		if (! diagram) {
417 			browser_show_error ((GtkWindow*) gtk_widget_get_toplevel ((GtkWidget*) bpers),
418 					    error && error->message ? error->message :
419 					    _("Could not load diagram"));
420 			g_clear_error (&error);
421 		}
422 	}
423 	else
424 		diagram = relations_diagram_new (browser_window_get_connection (bpers->priv->bwin));
425 
426 	if (diagram) {
427 		GtkWidget *close_btn;
428 		GtkWidget *tab_label;
429 		gint i;
430 
431 		tab_label = browser_page_get_tab_label (BROWSER_PAGE (diagram), &close_btn);
432 		i = gtk_notebook_append_page (GTK_NOTEBOOK (bpers->priv->notebook), diagram, tab_label);
433 		g_signal_connect (close_btn, "clicked",
434 				  G_CALLBACK (close_button_clicked_cb), diagram);
435 
436 		gtk_widget_show (diagram);
437 
438 		tab_label = browser_page_get_tab_label (BROWSER_PAGE (diagram), NULL);
439 		gtk_notebook_set_menu_label (GTK_NOTEBOOK (bpers->priv->notebook), diagram, tab_label);
440 
441 		gtk_notebook_set_current_page (GTK_NOTEBOOK (bpers->priv->notebook), i);
442 		gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (bpers->priv->notebook), diagram,
443 						  TRUE);
444 		gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (bpers->priv->notebook), diagram,
445 						 TRUE);
446 	}
447 }
448 #endif
449 
450 
451 /**
452  * schema_browser_perspective_display_table_info
453  *
454  * Display (and create if necessary) a new page for the table's properties
455  */
456 void
schema_browser_perspective_display_table_info(SchemaBrowserPerspective * bpers,const gchar * table_schema,const gchar * table_name,G_GNUC_UNUSED const gchar * table_short_name)457 schema_browser_perspective_display_table_info (SchemaBrowserPerspective *bpers,
458 					       const gchar *table_schema,
459 					       const gchar *table_name,
460 					       G_GNUC_UNUSED const gchar *table_short_name)
461 {
462 	g_return_if_fail (IS_SCHEMA_BROWSER_PERSPECTIVE (bpers));
463 
464 	gint ntabs, i;
465 	ntabs = gtk_notebook_get_n_pages (GTK_NOTEBOOK (bpers->priv->notebook));
466 	for (i = 0; i < ntabs; i++) {
467 		GtkWidget *child;
468 		child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (bpers->priv->notebook), i);
469 		if (IS_TABLE_INFO (child)) {
470 			if (!strcmp (table_schema, table_info_get_table_schema (TABLE_INFO (child))) &&
471 			    !strcmp (table_name, table_info_get_table_name (TABLE_INFO (child)))) {
472 				gtk_notebook_set_current_page (GTK_NOTEBOOK (bpers->priv->notebook), i);
473 				return;
474 			}
475 		}
476 	}
477 
478 	GtkWidget *ti;
479 	ti = table_info_new (browser_window_get_connection (bpers->priv->bwin), table_schema, table_name);
480 	if (ti) {
481 		GtkWidget *close_btn;
482 		GtkWidget *tab_label;
483 		gint i;
484 
485 		tab_label = browser_page_get_tab_label (BROWSER_PAGE (ti), &close_btn);
486 		i = gtk_notebook_append_page (GTK_NOTEBOOK (bpers->priv->notebook), ti, tab_label);
487 		g_signal_connect (close_btn, "clicked",
488 				  G_CALLBACK (close_button_clicked_cb), ti);
489 
490 		gtk_widget_show (ti);
491 
492 		tab_label = browser_page_get_tab_label (BROWSER_PAGE (ti), NULL);
493 		gtk_notebook_set_menu_label (GTK_NOTEBOOK (bpers->priv->notebook), ti, tab_label);
494 
495 		gtk_notebook_set_current_page (GTK_NOTEBOOK (bpers->priv->notebook), i);
496 		gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (bpers->priv->notebook), ti,
497 						  TRUE);
498 		gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (bpers->priv->notebook), ti,
499 						 TRUE);
500 	}
501 }
502 
503 static void
schema_browser_perspective_get_current_customization(BrowserPerspective * perspective,GtkActionGroup ** out_agroup,const gchar ** out_ui)504 schema_browser_perspective_get_current_customization (BrowserPerspective *perspective,
505 						      GtkActionGroup **out_agroup,
506 						      const gchar **out_ui)
507 {
508 	SchemaBrowserPerspective *bpers;
509 	GtkWidget *page_contents;
510 
511 	bpers = SCHEMA_BROWSER_PERSPECTIVE (perspective);
512 	page_contents = gtk_notebook_get_nth_page (GTK_NOTEBOOK (bpers->priv->notebook),
513 						   gtk_notebook_get_current_page (GTK_NOTEBOOK (bpers->priv->notebook)));
514 	if (IS_BROWSER_PAGE (page_contents)) {
515 		*out_agroup = browser_page_get_actions_group (BROWSER_PAGE (page_contents));
516 		*out_ui = browser_page_get_actions_ui (BROWSER_PAGE (page_contents));
517 	}
518 }
519 
520 static BrowserWindow *
schema_browser_perspective_get_window(BrowserPerspective * perspective)521 schema_browser_perspective_get_window (BrowserPerspective *perspective)
522 {
523 	SchemaBrowserPerspective *bpers;
524 	bpers = SCHEMA_BROWSER_PERSPECTIVE (perspective);
525 	return bpers->priv->bwin;
526 }
527