GnuCash c935c2f+
Loading...
Searching...
No Matches
gnc-plugin-budget.c
1/* Copyright (C) 2005 Chris Shoemaker <c.shoemaker@cox.net>
2 *
3 * gnc-plugin-budget.c --
4 * (based on gnc-plugin-account-tree.c)
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 as
8 * published by the Free Software Foundation; either version 2 of
9 * 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, contact:
18 *
19 * Free Software Foundation Voice: +1-617-542-5942
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21 * Boston, MA 02110-1301, USA gnu@gnu.org
22 */
23
24#include <config.h>
25
26#include <gtk/gtk.h>
27#include <glib/gi18n.h>
28#include <string.h>
29
30#include "gnc-plugin-budget.h"
33
34#include "qof.h"
35#include "gnc-features.h"
36#include "gnc-ui-util.h"
37#include "gnc-ui.h"
38#include "gnc-component-manager.h"
39
40#define PLUGIN_ACTIONS_NAME "gnc-plugin-budget-actions"
41#define PLUGIN_UI_FILENAME "gnc-plugin-budget.ui"
42
43static QofLogModule log_module = GNC_MOD_GUI;
44
45static void gnc_plugin_budget_finalize (GObject *object);
46
47/* Command Callbacks */
48static void gnc_plugin_budget_cmd_new_budget (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
49static void gnc_plugin_budget_cmd_open_budget (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
50static void gnc_plugin_budget_cmd_copy_budget (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
51static void gnc_plugin_budget_cmd_delete_budget (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
52
53static GActionEntry gnc_plugin_actions [] =
54{
55 { "ActionsBudgetAction", NULL, NULL, NULL, NULL },
56 { "NewBudgetAction", gnc_plugin_budget_cmd_new_budget, NULL, NULL, NULL },
57 { "OpenBudgetAction", gnc_plugin_budget_cmd_open_budget, NULL, NULL, NULL },
58 { "CopyBudgetAction", gnc_plugin_budget_cmd_copy_budget, NULL, NULL, NULL },
59 { "DeleteBudgetAction", gnc_plugin_budget_cmd_delete_budget, NULL, NULL, NULL },
60
61};
63static guint gnc_plugin_n_actions = G_N_ELEMENTS(gnc_plugin_actions);
64
66static const gchar *gnc_plugin_load_ui_items [] =
67{
68 "ActionsPlaceholder3",
69 NULL,
70};
71
72static const gchar *plugin_writeable_actions[] =
73{
74 /* actions which must be disabled on a readonly book. */
75 "NewBudgetAction",
76 "CopyBudgetAction",
77 "DeleteBudgetAction",
78 NULL
79};
80
82{
83 GncPlugin gnc_plugin;
84};
85
86GncPlugin *
87gnc_plugin_budget_new (void)
88{
89 GncPluginBudget *plugin;
90 ENTER(" ");
91
92 /* Reference the budget page plugin to ensure it exists in the gtk
93 * type system. */
94 GNC_TYPE_PLUGIN_PAGE_BUDGET;
95
96 plugin = g_object_new (GNC_TYPE_PLUGIN_BUDGET, NULL);
97 LEAVE(" ");
98 return GNC_PLUGIN(plugin);
99}
100
101static void
102page_changed (GncMainWindow *window, GncPluginPage *page, gpointer user_data)
103{
104 GSimpleActionGroup *simple_action_group =
105 gnc_main_window_get_action_group (window, PLUGIN_ACTIONS_NAME);
106
107 if (qof_book_is_readonly (gnc_get_current_book()))
108 gnc_plugin_set_actions_enabled (G_ACTION_MAP(simple_action_group), plugin_writeable_actions,
109 FALSE);
110}
111
112static void
113add_to_window (GncPlugin *plugin, GncMainWindow *mainwindow, GQuark type)
114{
115 g_signal_connect (mainwindow, "page_changed", G_CALLBACK (page_changed), plugin);
116}
117
118static void
119remove_from_window (GncPlugin *plugin, GncMainWindow *window, GQuark type)
120{
121 g_signal_handlers_disconnect_by_func (window, G_CALLBACK(page_changed), plugin);
122}
123
124G_DEFINE_TYPE(GncPluginBudget, gnc_plugin_budget, GNC_TYPE_PLUGIN)
125
126static void
127gnc_plugin_budget_class_init (GncPluginBudgetClass *klass)
128{
129 GObjectClass *object_class = G_OBJECT_CLASS(klass);
130 GncPluginClass *plugin_class = GNC_PLUGIN_CLASS(klass);
131
132 ENTER (" ");
133 object_class->finalize = gnc_plugin_budget_finalize;
134
135 plugin_class->plugin_name = GNC_PLUGIN_BUDGET_NAME;
136 plugin_class->actions_name = PLUGIN_ACTIONS_NAME;
137 plugin_class->actions = gnc_plugin_actions;
138 plugin_class->n_actions = gnc_plugin_n_actions;
139 plugin_class->ui_filename = PLUGIN_UI_FILENAME;
140 plugin_class->ui_updates = gnc_plugin_load_ui_items;
141 plugin_class->add_to_window = add_to_window;
142 plugin_class->remove_from_window = remove_from_window;
143
144 LEAVE (" ");
145}
146
147static void
148gnc_plugin_budget_init (GncPluginBudget *plugin)
149{
150}
151
152static void
153gnc_plugin_budget_finalize (GObject *object)
154{
155 g_return_if_fail (GNC_IS_PLUGIN_BUDGET(object));
156
157 ENTER(" ");
158 G_OBJECT_CLASS (gnc_plugin_budget_parent_class)->finalize(object);
159 LEAVE(" ");
160
161}
162
163/************************************************************
164 * Command Callbacks *
165 ************************************************************/
166
167/* Make a new budget; put it in a page; open the page. */
168static void
169gnc_plugin_budget_cmd_new_budget (GSimpleAction *simple,
170 GVariant *parameter,
171 gpointer user_data)
172{
173 GncMainWindowActionData *data = user_data;
174 GncBudget *budget;
175 GncPluginPage *page;
176 gchar *description, *date;
177 QofBook *book = gnc_get_current_book();
178
179 g_return_if_fail (data != NULL);
180
181 if (!gnc_features_check_used (book, GNC_FEATURE_BUDGET_UNREVERSED))
182 {
183 gnc_features_set_used (book, GNC_FEATURE_BUDGET_UNREVERSED);
184 PWARN ("Setting feature BUDGET_UNREVERSED. This book now requires \
185GnuCash 3.8 or later.");
186 }
187
188 budget = gnc_budget_new (gnc_get_current_book());
189 page = gnc_plugin_page_budget_new (budget);
190
192 description = g_strdup_printf ("%s: %s", _("Created"), date);
193 gnc_budget_set_description (budget, description);
194 g_free (description);
195 g_free (date);
196
197 gnc_main_window_open_page (data->window, page);
198}
199
200/* If only one budget exists, open it; otherwise user selects one to open */
201static void
202gnc_plugin_budget_cmd_open_budget (GSimpleAction *simple,
203 GVariant *parameter,
204 gpointer user_data)
205{
206 GncMainWindowActionData *data = user_data;
207 guint count;
208 QofBook *book;
209 GncBudget *bgt = NULL;
210 QofCollection *col;
211
212 g_return_if_fail (data != NULL);
213
214 book = gnc_get_current_book ();
215 col = qof_book_get_collection (book, GNC_ID_BUDGET);
216 count = qof_collection_count (col);
217 if (count > 0)
218 {
219 if (count == 1)
220 bgt = gnc_budget_get_default (book);
221 else
222 bgt = gnc_budget_gui_select_budget (GTK_WINDOW(data->window), book);
223
224 if (bgt)
225 gnc_main_window_open_page (data->window,
227 }
228 else /* if no budgets exist yet, just open a new budget */
229 gnc_plugin_budget_cmd_new_budget (simple, parameter, user_data);
230}
231
232/* If only one budget exists, create a copy of it; otherwise user selects one to copy */
233static void
234gnc_plugin_budget_cmd_copy_budget (GSimpleAction *simple,
235 GVariant *parameter,
236 gpointer user_data)
237{
238 GncMainWindowActionData *data = user_data;
239 guint count;
240 QofBook *book;
241 GncBudget *bgt = NULL;
242 QofCollection *col;
243
244 g_return_if_fail (data != NULL);
245
246 book = gnc_get_current_book ();
247 col = qof_book_get_collection (book, GNC_ID_BUDGET);
248 count = qof_collection_count (col);
249 if (count > 0)
250 {
251 if (count == 1)
252 bgt = gnc_budget_get_default(book);
253 else
254 bgt = gnc_budget_gui_select_budget (GTK_WINDOW(data->window), book);
255
256 if (bgt)
257 {
258 GncBudget* copy;
259 gchar* name;
260
261 copy = gnc_budget_clone (bgt);
262 name = g_strdup_printf ("Copy of %s", gnc_budget_get_name (bgt));
263 gnc_budget_set_name (copy, name);
264 g_free (name);
265
266 gnc_main_window_open_page (data->window,
268 }
269 }
270 else /* if no budgets exist yet, just open a new budget */
271 gnc_plugin_budget_cmd_new_budget (simple, parameter, user_data);
272}
273
274/* user selects budget to delete */
275static void
276gnc_plugin_budget_cmd_delete_budget (GSimpleAction *simple,
277 GVariant *parameter,
278 gpointer user_data)
279{
280 GncMainWindowActionData *data = user_data;
281 GncBudget *bgt;
282 QofBook *book;
283
284 g_return_if_fail (data != NULL);
285
286 book = gnc_get_current_book ();
287 if (qof_collection_count (qof_book_get_collection (book, GNC_ID_BUDGET)) == 0)
288 return;
289
290 bgt = gnc_budget_gui_select_budget (GTK_WINDOW(data->window), book);
291 if (!bgt) return;
292
293 gnc_budget_gui_delete_budget (bgt);
294}
295
296/************************************************************
297 * Other Functions *
298 ************************************************************/
299
300static void
301row_activated_cb (GtkTreeView *tv, GtkTreePath *path,
302 GtkTreeViewColumn *column, gpointer user_data)
303{
304 gtk_dialog_response (GTK_DIALOG(user_data), GTK_RESPONSE_OK);
305}
306
307GncBudget *
308gnc_budget_gui_select_budget (GtkWindow *parent, QofBook *book)
309{
310 GncBudget *bgt;
311 GtkDialog *dlg;
312 GtkTreeView *tv;
313 GtkTreeIter iter;
314 GtkTreeSelection *sel;
315 GtkTreeModel *tm;
316 gint response;
317 gboolean ok;
318
319 dlg = GTK_DIALOG(gtk_dialog_new_with_buttons (
320 _("Select a Budget"), parent, GTK_DIALOG_MODAL,
321 _("_Cancel"), GTK_RESPONSE_CANCEL,
322 _("_OK"), GTK_RESPONSE_OK, NULL));
323
324 tv = GTK_TREE_VIEW(gtk_tree_view_new ());
325 sel = gtk_tree_view_get_selection (tv);
326 gtk_tree_selection_set_mode (sel, GTK_SELECTION_BROWSE);
327 g_signal_connect (tv, "row-activated", G_CALLBACK(row_activated_cb), dlg);
328 tm = gnc_tree_model_budget_new (book);
329 gnc_tree_view_budget_set_model (tv, tm);
330 g_object_unref (tm);
331 gtk_container_add (GTK_CONTAINER(gtk_dialog_get_content_area (dlg)), GTK_WIDGET(tv));
332 gtk_widget_show_all (GTK_WIDGET(dlg));
333
334 // Preselect the default budget
335 bgt = gnc_budget_get_default (book);
336
337 if (bgt && gnc_tree_model_budget_get_iter_for_budget (tm, &iter, bgt))
338 {
339 GtkTreePath *path = gtk_tree_model_get_path (tm, &iter);
340 gtk_tree_view_set_cursor (tv, path, NULL, FALSE);
341 gtk_tree_path_free (path);
342 }
343
344 bgt = NULL;
345 response = gtk_dialog_run (dlg);
346 switch (response)
347 {
348 case GTK_RESPONSE_OK:
349 ok = gtk_tree_selection_get_selected (sel, &tm, &iter);
350 if (ok)
351 bgt = gnc_tree_model_budget_get_budget (tm, &iter);
352 break;
353 default:
354 break;
355 }
356
357 gtk_widget_destroy (GTK_WIDGET(dlg));
358 return bgt;
359}
360
Utility functions for file access.
provides some utilities for working with the list of budgets in a book.
utility functions for the GnuCash UI
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
Definition qofbook.cpp:521
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
Definition qofbook.cpp:497
char * gnc_print_time64(time64 time, const char *format)
print a time64 as a date string per format
Definition gnc-date.cpp:370
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
const gchar * qof_date_format_get_string(QofDateFormat df)
This function returns a strftime formatting string for printing an all numeric date (e....
Definition gnc-date.cpp:502
@ QOF_DATE_FORMAT_LOCALE
Take from locale information.
Definition gnc-date.h:128
guint qof_collection_count(const QofCollection *col)
return the number of entities in the collection.
Definition qofid.cpp:221
GSimpleActionGroup * gnc_main_window_get_action_group(GncMainWindow *window, const gchar *group_name)
Retrieve a specific set of user interface actions from a window.
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Display a data plugin page in a window.
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define PWARN(format, args...)
Log a warning.
Definition qoflog.h:250
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272
void gnc_plugin_set_actions_enabled(GActionMap *action_map, const gchar **action_names, gboolean enable)
This function sets the sensitivity of a GAction in a specific group.
Definition gnc-plugin.c:250
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.
GncBudget * gnc_budget_new(QofBook *book)
Creates and initializes a Budget.
GncPluginPage * gnc_plugin_page_budget_new(GncBudget *budget)
Create a new "budget" plugin page.
GncBudget * gnc_budget_clone(const GncBudget *old_b)
Clones a budget creating a copy.
void gnc_budget_set_description(GncBudget *budget, const gchar *description)
Set/Get the description of the Budget.
void gnc_budget_set_name(GncBudget *budget, const gchar *name)
Set/Get the name of the Budget.
The instance data structure for a content plugin.
QofBook reference.
Definition qofbook-p.hpp:47