GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dialog-query-view.c
1 /*
2  * dialog-query-view.c -- a simple dialog to display a query view and
3  * allow users to select items (or close the view)
4  *
5  * Created By: Derek Atkins <[email protected]>
6  * Copyright (c) 2003 Derek Atkins <[email protected]>
7  * Copyright (c) 2012 Robert Fewell
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, contact:
21  *
22  * Free Software Foundation Voice: +1-617-542-5942
23  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
24  * Boston, MA 02110-1301, USA [email protected]
25  */
26 
27 #include "config.h"
28 #include <gtk/gtk.h>
29 #include <glib/gi18n.h>
30 
31 #include "qof.h"
32 
33 #include "dialog-utils.h"
34 #include "gnc-component-manager.h"
35 
36 #include "dialog-query-view.h"
37 #include "gnc-query-view.h"
38 
40 {
41  GtkWidget * dialog;
42  GtkWidget * label;
43  GtkWidget * qview;
44  GtkWidget * button_box;
45  GNCDisplayViewButton * buttons;
46  gpointer user_data;
47  GList * books;
48  gint component_id;
49 };
50 
51 static void
52 dqv_clear_booklist (DialogQueryView *dqv)
53 {
54  GList *node;
55 
56  g_return_if_fail (dqv);
57 
58  for (node = dqv->books; node; node = node->next)
59  guid_free ((GncGUID*)node->data);
60  g_list_free (dqv->books);
61  dqv->books = NULL;
62 }
63 
64 static void
65 dqv_build_booklist (DialogQueryView *dqv, Query *q)
66 {
67  GList *node;
68 
69  g_return_if_fail (dqv);
70 
71  for (node = qof_query_get_books(q); node; node = node->next)
72  {
73  QofBook *book = node->data;
74  GncGUID *guid = guid_malloc();
75  *guid = *(qof_book_get_guid(book));
76  dqv->books = g_list_prepend(dqv->books, guid);
77  }
78 }
79 
80 static void
81 gnc_dialog_query_run_callback (GNCDisplayViewButton *cb, gpointer item,
82  DialogQueryView *dqv)
83 {
84  if (!cb)
85  return;
86 
87  if (cb->cb_fcn)
88  (cb->cb_fcn)(item, dqv->user_data);
89 }
90 
91 static void
92 gnc_dialog_query_view_button_clicked (GtkButton *button, DialogQueryView *dqv)
93 {
95  gpointer entry;
96 
97  g_return_if_fail (dqv);
98  entry = gnc_query_view_get_selected_entry (GNC_QUERY_VIEW (dqv->qview));
99  if (!entry)
100  return;
101 
102  cb = g_object_get_data (G_OBJECT (button), "data");
103  g_return_if_fail (cb);
104 
105  gnc_dialog_query_run_callback (cb, entry, dqv);
106 }
107 
108 static void
109 gnc_dialog_query_view_double_click_entry (GNCQueryView *qview, gpointer item,
110  gpointer user_data)
111 {
112  DialogQueryView *dqv = user_data;
113 
114  g_return_if_fail (dqv);
115  g_return_if_fail (item);
116 
117  if (!dqv->buttons)
118  return;
119 
120  gnc_dialog_query_run_callback (dqv->buttons, item, dqv);
121 }
122 
123 static int
124 gnc_dialog_query_view_delete_cb (GtkDialog *dialog, GdkEvent *event, DialogQueryView *dqv)
125 {
126  g_return_val_if_fail (dqv, TRUE);
127 
128  gnc_unregister_gui_component (dqv->component_id);
129 
130  /* destroy the book list */
131  dqv_clear_booklist (dqv);
132 
133  /* Destroy and exit */
134  gtk_widget_destroy(dqv->dialog);
135  g_free (dqv);
136  return FALSE;
137 }
138 
139 static void
140 close_handler (gpointer data)
141 {
142  DialogQueryView *dqv = data;
143 
144  g_return_if_fail (dqv);
145  gnc_dialog_query_view_delete_cb (GTK_DIALOG(dqv->dialog), NULL, dqv);
146 }
147 
148 static void
149 gnc_dialog_query_view_refresh_handler (GHashTable *changes, gpointer user_data)
150 {
151  DialogQueryView *dqv = (DialogQueryView *)user_data;
152  const EventInfo *info;
153  GList *node;
154 
155  if (changes)
156  {
157  for (node = dqv->books; node; node = node->next)
158  {
159  info = gnc_gui_get_entity_events (changes, (const GncGUID*)(node->data));
160  if (info && (info->event_mask & QOF_EVENT_DESTROY))
161  {
162  gnc_close_gui_component (dqv->component_id);
163  return;
164  }
165  }
166  }
167 }
168 
169 static void
170 gnc_dialog_query_view_close (GtkButton *button, DialogQueryView *dqv)
171 {
172  /* Don't select anything */
173  gnc_dialog_query_view_destroy (dqv);
174 }
175 
176 /*****************************************************************/
177 /* PUBLIC INTERFACES */
178 
180 gnc_dialog_query_view_new (GList *param_list, Query *q)
181 {
182  GtkBuilder *builder;
183  DialogQueryView *dqv;
184  GtkWidget *result_hbox, *close, *scrollWin, *frame, *but_hbox;
185  GList *node;
186 
187  dqv = g_new0 (DialogQueryView, 1);
188  builder = gtk_builder_new();
189  gnc_builder_add_from_file (builder, "dialog-query-view.glade", "Query View Dialog");
190 
191  /* Grab the dialog, save the dialog info */
192  dqv->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Query View Dialog"));
193  g_object_set_data (G_OBJECT (dqv->dialog), "dialog-info", dqv);
194 
195  /* grab the widgets */
196  dqv->label = GTK_WIDGET(gtk_builder_get_object (builder, "dialog_label"));
197  result_hbox = GTK_WIDGET(gtk_builder_get_object (builder, "result_hbox"));
198  close = GTK_WIDGET(gtk_builder_get_object (builder, "close_button"));
199 
200  /* build the query list */
201  dqv->qview = gnc_query_view_new (param_list, q);
202 
203  frame = gtk_frame_new(NULL);
204 
205  scrollWin = gtk_scrolled_window_new (NULL, NULL);
206  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrollWin),
207  GTK_POLICY_AUTOMATIC,
208  GTK_POLICY_AUTOMATIC);
209  gtk_container_set_border_width(GTK_CONTAINER(scrollWin), 5);
210 
211  gtk_container_add(GTK_CONTAINER(scrollWin), dqv->qview);
212  gtk_container_add(GTK_CONTAINER(frame), scrollWin);
213 
214  gtk_box_pack_start (GTK_BOX (result_hbox), frame, TRUE, TRUE, 3);
215 
216  /* Create the button_box */
217  dqv->button_box = gtk_vbox_new (FALSE, 2);
218  gtk_box_pack_start (GTK_BOX (result_hbox), dqv->button_box, FALSE, FALSE, 3);
219 
220  /* connect the double-click signal of the qview */
221  g_signal_connect (G_OBJECT (dqv->qview), "double_click_entry",
222  G_CALLBACK(gnc_dialog_query_view_double_click_entry), dqv);
223 
224  /* connect to the close button */
225  g_signal_connect (G_OBJECT (close), "clicked",
226  G_CALLBACK (gnc_dialog_query_view_close), dqv);
227 
228  /* connect to the cleanup */
229  g_signal_connect (G_OBJECT (dqv->dialog), "delete_event",
230  G_CALLBACK (gnc_dialog_query_view_delete_cb), dqv);
231 
232  /* register ourselves */
233  dqv->component_id = gnc_register_gui_component ("GNC Dialog Query View",
234  gnc_dialog_query_view_refresh_handler,
235  close_handler, dqv);
236 
237  /* Build the book list */
238  dqv_build_booklist (dqv, q);
239 
240  /* and register the books */
241  for (node = dqv->books; node; node = node->next)
242  gnc_gui_component_watch_entity (dqv->component_id, (GncGUID*)node->data,
243  QOF_EVENT_DESTROY);
244 
245  g_object_unref(G_OBJECT(builder));
246 
247  return dqv;
248 }
249 
250 void gnc_dialog_query_view_set_title (DialogQueryView *dqv, const char *title)
251 {
252  if (!dqv || !title) return;
253  gtk_window_set_title (GTK_WINDOW (dqv->dialog), title);
254 }
255 
256 void gnc_dialog_query_view_set_label (DialogQueryView *dqv, const char *label)
257 {
258  if (!dqv || !label) return;
259  gtk_label_set_text (GTK_LABEL(dqv->label), label);
260 }
261 
262 void gnc_dialog_query_view_set_buttons (DialogQueryView *dqv,
263  GNCDisplayViewButton *buttons,
264  gpointer user_data)
265 {
266  GtkWidget *button;
267  int i;
268 
269  if (!dqv || !buttons) return;
270  g_return_if_fail (dqv->buttons == NULL);
271 
272  dqv->buttons = buttons;
273  dqv->user_data = user_data;
274 
275  /* build up the buttons */
276  for (i = 0; buttons[i].label; i++)
277  {
278  /* Note: The "label" member of the GNCDisplayListButton still
279  * isn't translated. Hence, we must translate it here. */
280  button = gtk_button_new_with_label (_(buttons[i].label));
281  g_object_set_data (G_OBJECT (button), "data", &(dqv->buttons[i]));
282  g_signal_connect (G_OBJECT (button), "clicked",
283  G_CALLBACK(gnc_dialog_query_view_button_clicked), dqv);
284  gtk_box_pack_start (GTK_BOX (dqv->button_box), button, FALSE, FALSE, 3);
285  }
286 }
287 
288 void gnc_dialog_query_view_set_numerics (DialogQueryView *dqv, gboolean abs,
289  gboolean inv_sort)
290 {
291  if (!dqv) return;
292 
293  gnc_query_view_set_numerics (GNC_QUERY_VIEW(dqv->qview), abs, inv_sort);
294 }
295 
296 void gnc_dialog_query_view_refresh (DialogQueryView *dqv)
297 {
298  if (!dqv) return;
299 
300  gnc_query_view_refresh (GNC_QUERY_VIEW(dqv->qview));
301  gtk_widget_show_all (dqv->dialog);
302 }
303 
304 void gnc_dialog_query_view_destroy (DialogQueryView *dqv)
305 {
306  if (!dqv) return;
307  gnc_close_gui_component (dqv->component_id);
308 }
309 
311 gnc_dialog_query_view_create (GList *param_list, Query *q,
312  const char *title, const char *label,
313  gboolean abs, gboolean inv_sort,
314  gint sort_column, GtkSortType order,
315  GNCDisplayViewButton *buttons, gpointer user_data)
316 {
317  DialogQueryView *dqv;
318 
319  if (!param_list || !q)
320  return NULL;
321 
322  dqv = gnc_dialog_query_view_new (param_list, q);
323  if (!dqv)
324  return NULL;
325 
326  if (title)
327  gnc_dialog_query_view_set_title (dqv, title);
328 
329  if (label)
330  gnc_dialog_query_view_set_label (dqv, label);
331 
332  gnc_dialog_query_view_set_numerics (dqv, abs, inv_sort);
333 
334  if (buttons)
335  gnc_dialog_query_view_set_buttons (dqv, buttons, user_data);
336 
337  gnc_dialog_query_view_refresh (dqv);
338 
339  /* Set the sort order */
340  gnc_query_sort_order (GNC_QUERY_VIEW (dqv->qview), sort_column, order);
341 
342  /* Unselect all rows */
343  gnc_query_view_unselect_all (GNC_QUERY_VIEW (dqv->qview));
344 
345  return dqv;
346 }
Definition: guid.h:65
GncGUID * guid_malloc(void)
#define qof_book_get_guid(X)
Definition: qofbook.h:351
GList * qof_query_get_books(QofQuery *q)