GnuCash  5.6-150-g038405b370+
gnc-embedded-window.c
1 /*
2  * gnc-main-window.c -- GtkWindow which represents the
3  * GnuCash main window.
4  *
5  * Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de>
6  * Copyright (C) 2003 David Hampton <hampton@employees.org>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, contact:
20  *
21  * Free Software Foundation Voice: +1-617-542-5942
22  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
23  * Boston, MA 02110-1301, USA gnu@gnu.org
24  */
25 
26 #include <config.h>
27 
28 #include <gtk/gtk.h>
29 
30 #include "gnc-embedded-window.h"
31 
32 #include "gnc-engine.h"
33 #include "gnc-filepath-utils.h"
34 #include "gnc-gnome-utils.h"
35 #include "gnc-gobject-utils.h"
36 #include "gnc-gui-query.h"
37 #include "gnc-plugin.h"
38 #include "gnc-plugin-manager.h"
39 #include "gnc-ui.h"
40 #include "gnc-window.h"
41 #include "dialog-utils.h"
42 #include "gnc-gtk-utils.h"
43 
45 enum
46 {
47  PAGE_CHANGED,
48  LAST_SIGNAL
49 };
50 
51 /* Static Globals *******************************************************/
52 
54 static QofLogModule log_module = GNC_MOD_GUI;
55 
56 
57 /* Declarations *********************************************************/
58 static void gnc_embedded_window_constructed (GObject *object);
59 static void gnc_embedded_window_finalize (GObject *object);
60 static void gnc_embedded_window_dispose (GObject *object);
61 
62 static void gnc_window_embedded_window_init (GncWindowInterface *iface);
63 
64 static void gnc_embedded_window_setup_window (GncEmbeddedWindow *window);
65 
68 {
70  GtkBox vbox;
71 
76  GtkWidget *menu_dock;
78  GtkWidget *menubar;
80  GMenuModel *menubar_model;
83  GtkWidget *toolbar;
87  GtkWidget *statusbar;
88 
92  GSimpleActionGroup *simple_action_group;
93 
96  GtkAccelGroup *accel_group;
97 
102  GtkWidget *parent_window;
103 };
104 
105 G_DEFINE_TYPE_WITH_CODE(GncEmbeddedWindow, gnc_embedded_window, GTK_TYPE_BOX,
106  G_IMPLEMENT_INTERFACE(GNC_TYPE_WINDOW,
107  gnc_window_embedded_window_init))
108 
109 
111 static guint embedded_window_signals[LAST_SIGNAL] = { 0 };
112 
113 /* Display a data plugin page in a window. */
114 void
115 gnc_embedded_window_open_page (GncEmbeddedWindow *window,
116  GncPluginPage *page)
117 {
118  g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (window));
119  g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
120  g_return_if_fail (window->page == NULL);
121 
122  ENTER("window %p, page %p", window, page);
123  window->page = page;
124  page->window = GTK_WIDGET(window);
126 
127  gtk_box_pack_end(GTK_BOX(window), page->notebook_page, TRUE, TRUE, 2);
128  gnc_plugin_page_inserted (page);
129  LEAVE(" ");
130 }
131 
132 
133 /* Remove a data plugin page from a window. */
134 void
135 gnc_embedded_window_close_page (GncEmbeddedWindow *window,
136  GncPluginPage *page)
137 {
138  g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (window));
139  g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
140  g_return_if_fail (window->page == page);
141 
142  ENTER("window %p, page %p", window, page);
143 
144  if (!page->notebook_page)
145  {
146  LEAVE("no displayed widget");
147  return;
148  }
149 
150  gtk_container_remove (GTK_CONTAINER(window), GTK_WIDGET(page->notebook_page));
151  window->page = NULL;
152  gnc_plugin_page_removed (page);
153 
155  g_object_unref(page);
156  LEAVE(" ");
157 }
158 
159 
160 /* Retrieve the plugin that is embedded in the specified window. */
162 gnc_embedded_window_get_page (GncEmbeddedWindow *window)
163 {
164  return window->page;
165 }
166 
167 
174 static void
175 gnc_embedded_window_class_init (GncEmbeddedWindowClass *klass)
176 {
177  GObjectClass *object_class;
178  ENTER("klass %p", klass);
179  object_class = G_OBJECT_CLASS (klass);
180 
181  object_class->constructed = gnc_embedded_window_constructed;
182  object_class->finalize = gnc_embedded_window_finalize;
183  object_class->dispose = gnc_embedded_window_dispose;
184 
195  embedded_window_signals[PAGE_CHANGED] =
196  g_signal_new ("page_changed",
197  G_OBJECT_CLASS_TYPE (object_class),
198  G_SIGNAL_RUN_FIRST,
199  0,
200  NULL, NULL,
201  g_cclosure_marshal_VOID__OBJECT,
202  G_TYPE_NONE, 1,
203  G_TYPE_OBJECT);
204 
205  LEAVE(" ");
206 }
207 
208 
215 static void
216 gnc_embedded_window_init (GncEmbeddedWindow *window)
217 {
218  ENTER("window %p", window);
219 
220  gtk_orientable_set_orientation (GTK_ORIENTABLE(window), GTK_ORIENTATION_VERTICAL);
221 
222  // Set the name for this dialog so it can be easily manipulated with css
223  gtk_widget_set_name (GTK_WIDGET(window), "gnc-id-embedded-window");
224 
225  gnc_embedded_window_setup_window (window);
226 
227  LEAVE(" ");
228 }
229 
236  static void
237 gnc_embedded_window_constructed (GObject *obj)
238 {
240 
241  G_OBJECT_CLASS (gnc_embedded_window_parent_class)->constructed (obj);
242 }
243 
247 static void
248 gnc_embedded_window_finalize (GObject *object)
249 {
250  g_return_if_fail (object != NULL);
251  g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (object));
252 
253  ENTER("object %p", object);
255  G_OBJECT_CLASS (gnc_embedded_window_parent_class)->finalize (object);
256  LEAVE(" ");
257 }
258 
259 
264 static void
265 gnc_embedded_window_dispose (GObject *object)
266 {
267  GncEmbeddedWindow *window;
268 
269  g_return_if_fail (object != NULL);
270  g_return_if_fail (GNC_IS_EMBEDDED_WINDOW (object));
271 
272  ENTER("object %p", object);
273  window = GNC_EMBEDDED_WINDOW (object);
274 
275  if (window->page)
276  {
277  DEBUG("unreffing page %p (count currently %d)", window->page,
278  G_OBJECT(window->page)->ref_count);
279  g_object_unref(window->page);
280  window->page = NULL;
281  }
282 
283  G_OBJECT_CLASS (gnc_embedded_window_parent_class)->dispose (object);
284  LEAVE(" ");
285 }
286 
287 
291 static void
292 gnc_embedded_window_setup_window (GncEmbeddedWindow *window)
293 {
294  ENTER("window %p", window);
295 
296  /* Create widgets and add them to the window */
297  gtk_widget_show (GTK_WIDGET(window));
298 
299  window->menu_dock = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
300  gtk_box_set_homogeneous (GTK_BOX (window->menu_dock), FALSE);
301  gtk_widget_show (window->menu_dock);
302  gtk_box_pack_start (GTK_BOX (window), window->menu_dock, FALSE, TRUE, 0);
303 
304  window->statusbar = gtk_statusbar_new ();
305  gtk_widget_show (window->statusbar);
306  gtk_box_pack_end (GTK_BOX (window), window->statusbar, FALSE, TRUE, 0);
307 
308  window->simple_action_group = NULL;
309  LEAVE(" ");
310 }
311 
312 
314 GncEmbeddedWindow *
315 gnc_embedded_window_new (const gchar *action_group_name,
316  GActionEntry *action_entries,
317  gint n_action_entries,
318  const gchar *ui_filename,
319  GtkWidget *enclosing_win,
320  gboolean add_accelerators,
321  gpointer user_data)
322 {
323  GncEmbeddedWindow *window;
324  gchar *ui_fullname;
325  GError *error = NULL;
326  GtkBuilder *builder;
327 
328  ENTER("group %s, first %p, num %d, ui file %s, parent %p, add accelerators %d, user data %p",
329  action_group_name, action_entries, n_action_entries, ui_filename,
330  enclosing_win, add_accelerators, user_data);
331 
332  window = g_object_new (GNC_TYPE_EMBEDDED_WINDOW, NULL);
333 
334  builder = gtk_builder_new ();
335  gtk_builder_set_translation_domain (builder, PROJECT_NAME);
336 
337  ui_fullname = g_strconcat (GNUCASH_RESOURCE_PREFIX "/", ui_filename, NULL);
338 
339  gtk_builder_add_from_resource (builder, ui_fullname, &error);
340 
341  if (error)
342  {
343  g_critical ("Failed to load, Error %s", error->message);
344  g_error_free (error);
345  return NULL;
346  }
347 
348  window->menubar_model = (GMenuModel *)gtk_builder_get_object (builder, "embeddedwin-menu");
349 
350  window->menubar = gtk_menu_bar_new_from_model (window->menubar_model);
351  gtk_container_add (GTK_CONTAINER(window->menu_dock), window->menubar);
352  gtk_widget_show (GTK_WIDGET(window->menubar));
353 
354  window->toolbar = (GtkWidget *)gtk_builder_get_object (builder, "embeddedwin-toolbar");
355  g_object_set (window->toolbar, "toolbar-style", GTK_TOOLBAR_BOTH, NULL);
356  gtk_container_add (GTK_CONTAINER(window->menu_dock), GTK_WIDGET(window->toolbar));
357  gtk_widget_show (GTK_WIDGET(window->toolbar));
358 
359  g_object_unref (builder);
360 
361  window->simple_action_group = g_simple_action_group_new ();
362 
363  g_action_map_add_action_entries (G_ACTION_MAP(window->simple_action_group),
364  action_entries,
365  n_action_entries,
366  user_data);
367 
368  gtk_widget_insert_action_group (GTK_WIDGET(window), "embeddedwin",
369  G_ACTION_GROUP(window->simple_action_group));
370 
371  window->parent_window = enclosing_win;
372 
373  // need to add the accelerator keys
374  window->accel_group = gtk_accel_group_new ();
375  gtk_window_add_accel_group (GTK_WINDOW(enclosing_win), window->accel_group);
376  gnc_add_accelerator_keys_for_menu (GTK_WIDGET(window->menubar), window->menubar_model, window->accel_group);
377 
378  g_free (ui_fullname);
379  LEAVE("window %p", window);
380  return window;
381 }
382 
383 
389 static GtkWindow *
390 gnc_embedded_window_get_gtk_window (GncWindow *window_in)
391 {
392  GncEmbeddedWindow *window;
393 
394  g_return_val_if_fail (GNC_IS_EMBEDDED_WINDOW (window_in), NULL);
395 
396  window = GNC_EMBEDDED_WINDOW(window_in);
397  return GTK_WINDOW(window->parent_window);
398 }
399 
400 
406 static GtkWidget *
407 gnc_embedded_window_get_statusbar (GncWindow *window_in)
408 {
409  GncEmbeddedWindow *window;
410 
411  g_return_val_if_fail (GNC_IS_EMBEDDED_WINDOW (window_in), NULL);
412 
413  window = GNC_EMBEDDED_WINDOW(window_in);
414  return window->statusbar;
415 }
416 
417 
423 static GtkWidget *
424 gnc_embedded_window_get_menubar (GncWindow *window)
425 {
426  g_return_val_if_fail (GNC_IS_EMBEDDED_WINDOW(window), NULL);
427 
428  return GNC_EMBEDDED_WINDOW (window)->menubar;
429 }
430 
436 static GtkWidget *
437 gnc_embedded_window_get_toolbar (GncWindow *window)
438 {
439  g_return_val_if_fail (GNC_IS_EMBEDDED_WINDOW(window), NULL);
440 
441  return GNC_EMBEDDED_WINDOW (window)->toolbar;
442 }
443 
449 static GMenuModel *
450 gnc_embedded_window_get_menubar_model (GncWindow *window)
451 {
452  g_return_val_if_fail (GNC_IS_EMBEDDED_WINDOW(window), NULL);
453 
454  return GNC_EMBEDDED_WINDOW (window)->menubar_model;
455 }
456 
462 static GtkAccelGroup *
463 gnc_embedded_window_get_accel_group (GncWindow *window)
464 {
465  g_return_val_if_fail (GNC_IS_EMBEDDED_WINDOW(window), NULL);
466 
467  return GNC_EMBEDDED_WINDOW (window)->accel_group;
468 }
469 
474 static void
475 gnc_window_embedded_window_init (GncWindowInterface *iface)
476 {
477  iface->get_gtk_window = gnc_embedded_window_get_gtk_window;
478  iface->get_statusbar = gnc_embedded_window_get_statusbar;
479  iface->get_menubar = gnc_embedded_window_get_menubar;
480  iface->get_toolbar = gnc_embedded_window_get_toolbar;
481  iface->get_menubar_model = gnc_embedded_window_get_menubar_model;
482  iface->get_accel_group = gnc_embedded_window_get_accel_group;
483 }
GtkWidget * menubar
The menubar.
void gnc_plugin_page_destroy_widget(GncPluginPage *plugin_page)
Destroy the display widget that corresponds to this plugin.
The instance data structure for a content plugin.
GtkAccelGroup * accel_group
The accelerator group of all actions provided by the embedded window.
gtk helper routines.
void gnc_embedded_window_close_page(GncEmbeddedWindow *window, GncPluginPage *page)
Remove a data plugin page from a window.
void gnc_gobject_tracking_forget(GObject *object)
Tell gnucash to remember this object in the database.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
Functions that are supported by all types of windows.
void gnc_embedded_window_open_page(GncEmbeddedWindow *window, GncPluginPage *page)
Display a data plugin page in a window.
Plugin management functions for the GnuCash UI.
GtkWidget * window
The window that contains the display widget for this plugin.
GtkWidget * toolbar
The toolbar.
The instance data structure for an embedded window object.
GncPluginPage * page
The currently selected page.
GncEmbeddedWindow * gnc_embedded_window_new(const gchar *action_group_name, GActionEntry *action_entries, gint n_action_entries, const gchar *ui_filename, GtkWidget *enclosing_win, gboolean add_accelerators, gpointer user_data)
Create a new gnc embedded window plugin.
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
G_DEFINE_TYPE_WITH_CODE(GncMainWindow, gnc_main_window, GTK_TYPE_APPLICATION_WINDOW, G_IMPLEMENT_INTERFACE(GNC_TYPE_WINDOW, gnc_window_main_window_init)) static guint main_window_signals[LAST_SIGNAL]
A holding place for all the signals generated by the main window code.
void gnc_gobject_tracking_remember(GObject *object)
Tell gnucash to remember this object in the database.
Gobject helper routines.
GtkWidget * statusbar
A pointer to the status bar at the bottom edge of the window.
Gnome specific utility functions.
All type declarations for the whole Gnucash engine.
void gnc_add_accelerator_keys_for_menu(GtkWidget *menu, GMenuModel *model, GtkAccelGroup *accel_group)
Add accelerator keys for menu item widgets.
GncPluginPage * gnc_embedded_window_get_page(GncEmbeddedWindow *window)
Retrieve the plugin that is embedded in the specified window.
GtkWidget * menu_dock
The dock (vbox) at the top of the window containing the menubar and toolbar.
GtkWidget * parent_window
The parent of this embedded "window".
GMenuModel * menubar_model
The menubar_model.
GSimpleActionGroup * simple_action_group
The group of all actions provided by the embedded window itself.
Functions that are supported by all types of windows.
Functions for adding plugins to a GnuCash window.
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
File path resolution utility functions.
GtkWidget * notebook_page
The display widget for this plugin.
GtkWidget * gnc_plugin_page_create_widget(GncPluginPage *plugin_page)
Create the display widget that corresponds to this plugin.
GtkBox vbox
The parent object for an embedded window.