~siretart/gnucash/ubuntu-fullsource

« back to all changes in this revision

Viewing changes to src/gnome-utils/gnc-recurrence.c

  • Committer: Reinhard Tartler
  • Date: 2008-08-03 07:25:46 UTC
  • Revision ID: siretart@tauware.de-20080803072546-y6p8xda8zpfi62ys
import gnucash_2.2.4.orig.tar.gz

The original tarball had the md5sum: 27e660297dc5b8ce574515779d05a5a5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* gnc-recurrence.c:
 
2
 *
 
3
 */
 
4
 
 
5
/* Copyright (C) 2005, Chris Shoemaker <c.shoemaker@cox.net>
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU General Public License as
 
9
 * published by the Free Software Foundation; either version 2 of
 
10
 * the License, or (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, contact:
 
19
 *
 
20
 * Free Software Foundation           Voice:  +1-617-542-5942
 
21
 * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
 
22
 * Boston, MA  02110-1301,  USA       gnu@gnu.org
 
23
 */
 
24
 
 
25
#include "config.h"
 
26
 
 
27
#include <gnome.h>
 
28
#include "glib-compat.h"
 
29
#include <glade/glade.h>
 
30
 
 
31
#include "dialog-utils.h"
 
32
#include "gnc-recurrence.h"
 
33
#include "Recurrence.h"
 
34
#include "gnc-engine.h"
 
35
#include "gnc-gdate-utils.h"
 
36
 
 
37
static QofLogModule log_module = GNC_MOD_GUI;
 
38
 
 
39
struct _GncRecurrence {
 
40
    GtkVBox widget;
 
41
 
 
42
    GnomeDateEdit *gde_start;
 
43
    GtkComboBox *gcb_period;
 
44
    GtkCheckButton *gcb_eom;
 
45
    GtkSpinButton *gsb_mult;
 
46
    GtkCheckButton *nth_weekday;
 
47
    GladeXML *xml;
 
48
 
 
49
    Recurrence recurrence;
 
50
};
 
51
 
 
52
typedef struct {
 
53
    GtkVBoxClass parent_class;
 
54
    void (*changed) (GncRecurrence *gr);
 
55
} GncRecurrenceClass;
 
56
 
 
57
typedef enum {
 
58
    GNCRECURRENCE_CHANGED,
 
59
    LAST_SIGNAL
 
60
} GNCR_Signals;
 
61
 
 
62
typedef enum {
 
63
    GNCR_DAY,
 
64
    GNCR_WEEK,
 
65
    GNCR_MONTH,
 
66
    GNCR_YEAR,
 
67
} UIPeriodType;
 
68
 
 
69
static GObjectClass *parent_class = NULL;
 
70
 
 
71
static UIPeriodType get_pt_ui(GncRecurrence *gr)
 
72
{
 
73
    return (gtk_combo_box_get_active(gr->gcb_period));
 
74
}
 
75
 
 
76
static void set_pt_ui(GncRecurrence *gr, PeriodType pt)
 
77
{
 
78
    UIPeriodType idx;
 
79
    switch (pt) {
 
80
    case PERIOD_DAY:
 
81
        idx = 0; break;
 
82
    case PERIOD_WEEK:
 
83
        idx = 1; break;
 
84
    case PERIOD_MONTH:
 
85
    case PERIOD_END_OF_MONTH:
 
86
    case PERIOD_NTH_WEEKDAY:
 
87
    case PERIOD_LAST_WEEKDAY:
 
88
        idx = 2; break;
 
89
    case PERIOD_YEAR:
 
90
        idx = 3; break;
 
91
    default: return;
 
92
    }
 
93
    gtk_combo_box_set_active(gr->gcb_period, idx);
 
94
 
 
95
    gtk_toggle_button_set_active(
 
96
        GTK_TOGGLE_BUTTON(gr->nth_weekday),
 
97
        (pt == PERIOD_NTH_WEEKDAY || pt == PERIOD_LAST_WEEKDAY));
 
98
 
 
99
    gtk_toggle_button_set_active(
 
100
        GTK_TOGGLE_BUTTON(gr->gcb_eom),
 
101
        (pt == PERIOD_END_OF_MONTH || pt == PERIOD_LAST_WEEKDAY));
 
102
}
 
103
 
 
104
static gboolean
 
105
is_ambiguous_relative(const GDate *date)
 
106
{
 
107
    GDateDay d;
 
108
    guint8 dim;
 
109
 
 
110
    d = g_date_get_day(date);
 
111
    dim = g_date_get_days_in_month(
 
112
        g_date_get_month(date), g_date_get_year(date));
 
113
    return ((d - 1) / 7 == 3) && (dim - d < 7);
 
114
}
 
115
 
 
116
static gboolean
 
117
is_ambiguous_absolute(const GDate *date)
 
118
{
 
119
    return (g_date_is_last_of_month(date) &&
 
120
            (g_date_get_day(date) < 31));
 
121
}
 
122
 
 
123
static void
 
124
something_changed( GtkWidget *wid, gpointer d )
 
125
{
 
126
    UIPeriodType pt;
 
127
    GDate start;
 
128
    time_t t;
 
129
    gboolean show_last, use_wd;
 
130
    GncRecurrence *gr = GNC_RECURRENCE(d);
 
131
 
 
132
 
 
133
    pt = get_pt_ui(gr);
 
134
    t = gnome_date_edit_get_time(gr->gde_start);
 
135
    g_date_set_time_t(&start, t);
 
136
 
 
137
    if (pt == GNCR_MONTH)
 
138
        g_object_set(G_OBJECT(gr->nth_weekday), "visible", TRUE, NULL);
 
139
    else {
 
140
        g_object_set(G_OBJECT(gr->nth_weekday), "visible", FALSE, NULL);
 
141
        gtk_toggle_button_set_active(
 
142
            GTK_TOGGLE_BUTTON(gr->nth_weekday), FALSE);
 
143
    }
 
144
    use_wd = gtk_toggle_button_get_active(
 
145
        GTK_TOGGLE_BUTTON(gr->nth_weekday));
 
146
    //TODO: change label
 
147
 
 
148
    /* The case under which we show the "end of month" flag is very
 
149
       narrow, because we can almost always DTRT without it. */
 
150
    if (pt == GNCR_MONTH) {
 
151
        if (use_wd)
 
152
            show_last = is_ambiguous_relative(&start);
 
153
        else
 
154
            show_last = is_ambiguous_absolute(&start);
 
155
    } else {
 
156
        show_last = FALSE;
 
157
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gr->gcb_eom), FALSE);
 
158
    }
 
159
    g_object_set(G_OBJECT(gr->gcb_eom), "visible", show_last, NULL);
 
160
 
 
161
    g_signal_emit_by_name(d, "changed");
 
162
}
 
163
 
 
164
static void
 
165
gnc_recurrence_init( GncRecurrence *gr )
 
166
{
 
167
    GtkVBox *vb;
 
168
 
 
169
    recurrenceSet(&gr->recurrence, 1, PERIOD_MONTH, NULL);
 
170
 
 
171
    gr->xml = gnc_glade_xml_new("budget.glade", "RecurrenceEntryVBox");
 
172
    vb = GTK_VBOX(glade_xml_get_widget(gr->xml, "RecurrenceEntryVBox"));
 
173
    gr->gde_start = GNOME_DATE_EDIT(glade_xml_get_widget(gr->xml,
 
174
                                                         "GDE_StartDate"));
 
175
    gtk_widget_set_no_show_all(GTK_WIDGET(gr->gde_start), TRUE);
 
176
    gr->gcb_period = GTK_COMBO_BOX(glade_xml_get_widget(gr->xml,
 
177
                                                        "GCB_PeriodType"));
 
178
    gr->gsb_mult = GTK_SPIN_BUTTON(glade_xml_get_widget(gr->xml, "GSB_Mult"));
 
179
    gr->gcb_eom = GTK_CHECK_BUTTON(glade_xml_get_widget(gr->xml,
 
180
                                                        "GCB_EndOfMonth"));
 
181
    gr->nth_weekday = GTK_CHECK_BUTTON(glade_xml_get_widget(gr->xml,
 
182
                                                            "GCB_NthWeekday"));
 
183
    gtk_widget_set_no_show_all(GTK_WIDGET(gr->gcb_eom), TRUE);
 
184
    gtk_widget_set_no_show_all(GTK_WIDGET(gr->nth_weekday), TRUE);
 
185
 
 
186
 
 
187
    gtk_container_add( GTK_CONTAINER(&gr->widget), GTK_WIDGET(vb) );
 
188
 
 
189
    gnc_recurrence_set(gr, &gr->recurrence);
 
190
    something_changed( GTK_WIDGET(gr), gr);
 
191
 
 
192
    /* respond to changes */
 
193
    g_signal_connect( G_OBJECT(gr->gde_start), "date_changed",
 
194
                      G_CALLBACK(something_changed), gr );
 
195
    g_signal_connect( G_OBJECT(gr->gcb_period), "changed",
 
196
                      G_CALLBACK(something_changed), gr );
 
197
    g_signal_connect( G_OBJECT(gr->gsb_mult), "value-changed",
 
198
                      G_CALLBACK(something_changed), gr );
 
199
    g_signal_connect( G_OBJECT(gr->gcb_eom), "toggled",
 
200
                      G_CALLBACK(something_changed), gr );
 
201
    g_signal_connect( G_OBJECT(gr->nth_weekday), "toggled",
 
202
                      G_CALLBACK(something_changed), gr );
 
203
 
 
204
    gtk_widget_show_all( GTK_WIDGET(&gr->widget) );
 
205
}
 
206
 
 
207
void
 
208
gnc_recurrence_set(GncRecurrence *gr, const Recurrence *r)
 
209
{
 
210
    PeriodType pt;
 
211
    guint mult;
 
212
    GDate start;
 
213
 
 
214
    g_return_if_fail(gr && r);
 
215
    pt = recurrenceGetPeriodType(r);
 
216
    mult = recurrenceGetMultiplier(r);
 
217
    start = recurrenceGetDate(r);
 
218
 
 
219
    gtk_spin_button_set_value(gr->gsb_mult, (gdouble) mult);
 
220
 
 
221
    // is there some better way?
 
222
    {
 
223
        time_t t;
 
224
        t = gnc_timet_get_day_start_gdate (&start);
 
225
        gnome_date_edit_set_time(gr->gde_start, t);
 
226
    }
 
227
 
 
228
    set_pt_ui(gr, pt);
 
229
}
 
230
 
 
231
const Recurrence *
 
232
gnc_recurrence_get(GncRecurrence *gr)
 
233
{
 
234
    time_t t;
 
235
    guint mult;
 
236
    UIPeriodType period;
 
237
    PeriodType pt;
 
238
    GDate start;
 
239
    gboolean use_eom = FALSE, rel;
 
240
 
 
241
    mult = (guint) gtk_spin_button_get_value_as_int(gr->gsb_mult);
 
242
    t = gnome_date_edit_get_time(gr->gde_start);
 
243
    g_date_set_time_t(&start, t);
 
244
    period = get_pt_ui(gr);
 
245
 
 
246
    switch (period) {
 
247
    case GNCR_DAY:
 
248
        pt = PERIOD_DAY; break;
 
249
    case GNCR_WEEK:
 
250
        pt = PERIOD_WEEK; break;
 
251
    case GNCR_MONTH:
 
252
        rel = gtk_toggle_button_get_active(
 
253
            GTK_TOGGLE_BUTTON(gr->nth_weekday));
 
254
        if (rel) {
 
255
            if (is_ambiguous_relative(&start)) {
 
256
                use_eom = gtk_toggle_button_get_active(
 
257
                    GTK_TOGGLE_BUTTON(gr->gcb_eom));
 
258
            } else {
 
259
                GDateDay d;
 
260
                d = g_date_get_day(&start);
 
261
 
 
262
                use_eom = ((d - 1) / 7 == 4);
 
263
            }
 
264
            if (use_eom)
 
265
                pt = PERIOD_LAST_WEEKDAY;
 
266
            else pt = PERIOD_NTH_WEEKDAY;
 
267
        } else {
 
268
            if (g_date_is_last_of_month(&start) &&
 
269
                (g_date_get_day(&start) < 31)) {
 
270
                // ambiguous, need to examine the checkbox
 
271
                use_eom = gtk_toggle_button_get_active(
 
272
                    GTK_TOGGLE_BUTTON(gr->gcb_eom));
 
273
            } else {
 
274
                // if it's the last dom, use eom anyway because it's the 31st.
 
275
                use_eom = g_date_is_last_of_month(&start);
 
276
            }
 
277
            if (use_eom)
 
278
                pt = PERIOD_END_OF_MONTH;
 
279
            else pt = PERIOD_MONTH;
 
280
        }
 
281
        break;
 
282
    case GNCR_YEAR:
 
283
        pt = PERIOD_YEAR; break;
 
284
    default:
 
285
        pt = PERIOD_INVALID;
 
286
    }
 
287
 
 
288
 
 
289
    recurrenceSet(&gr->recurrence, mult, pt, &start);
 
290
    return &gr->recurrence;
 
291
 
 
292
}
 
293
static void
 
294
gnc_recurrence_finalize(GObject *o)
 
295
{
 
296
    GncRecurrence *gr = GNC_RECURRENCE(o);
 
297
 
 
298
    if (gr)
 
299
        G_OBJECT_CLASS (parent_class)->finalize (o);
 
300
}
 
301
 
 
302
static void
 
303
gnc_recurrence_class_init( GncRecurrenceClass *klass )
 
304
{
 
305
    GObjectClass *object_class;
 
306
    static gint signals[LAST_SIGNAL] = { 0 };
 
307
 
 
308
    object_class = G_OBJECT_CLASS (klass);
 
309
    signals[GNCRECURRENCE_CHANGED] =
 
310
        g_signal_new ("changed",
 
311
                      G_OBJECT_CLASS_TYPE (object_class),
 
312
                      G_SIGNAL_RUN_FIRST,
 
313
                      G_STRUCT_OFFSET (GncRecurrenceClass, changed),
 
314
                      NULL,
 
315
                      NULL,
 
316
                      g_cclosure_marshal_VOID__VOID,
 
317
                      G_TYPE_NONE,
 
318
                      0);
 
319
 
 
320
    parent_class = g_type_class_peek_parent (klass);
 
321
    object_class->finalize = gnc_recurrence_finalize;
 
322
}
 
323
 
 
324
GType
 
325
gnc_recurrence_get_type()
 
326
{
 
327
    static GType type = 0;
 
328
    if (type == 0) {
 
329
        static GTypeInfo typeinfo = {
 
330
            sizeof(GncRecurrenceClass),
 
331
            NULL, NULL,
 
332
            (GClassInitFunc)gnc_recurrence_class_init,
 
333
            NULL, NULL,
 
334
            sizeof(GncRecurrence),
 
335
            0,
 
336
            (GInstanceInitFunc)gnc_recurrence_init
 
337
        };
 
338
 
 
339
        type = g_type_register_static (GTK_TYPE_VBOX, "GncRecurrence",
 
340
                                       &typeinfo, 0);
 
341
    }
 
342
    return type;
 
343
}
 
344
 
 
345
GtkWidget *
 
346
gnc_recurrence_new()
 
347
{
 
348
    GncRecurrence *gr;
 
349
 
 
350
    ENTER(" ");
 
351
    gr = g_object_new(gnc_recurrence_get_type(), NULL);
 
352
    LEAVE(" ");
 
353
    return GTK_WIDGET(gr);
 
354
}
 
355
 
 
356
/* TODO: Maybe this stuff should go into another file.
 
357
 *
 
358
 */
 
359
 
 
360
struct _GncRecurrenceComp {
 
361
    GtkScrolledWindow widget;
 
362
 
 
363
    GtkVBox *vbox;
 
364
    GtkHBox *hbox;
 
365
    GtkHButtonBox *hbb;
 
366
    gint num_rec;
 
367
    GtkButton *buttRemove;
 
368
    GtkButton *buttAdd;
 
369
 
 
370
    GList *rlist;
 
371
};
 
372
 
 
373
typedef struct {
 
374
    GtkScrolledWindowClass parent_class;
 
375
    void (*changed) (GncRecurrenceComp *gr);
 
376
} GncRecurrenceCompClass;
 
377
 
 
378
typedef enum {
 
379
    GNCRECURRENCECOMP_CHANGED,
 
380
    GNCRC_LAST_SIGNAL
 
381
} GNCRC_Signals;
 
382
 
 
383
static void grc_changed(GtkWidget *w, gpointer data)
 
384
{
 
385
    g_signal_emit_by_name(data, "changed");
 
386
}
 
387
static void addRecurrence(GncRecurrenceComp *grc, GncRecurrence *gr)
 
388
{
 
389
 
 
390
    gtk_box_pack_start(GTK_BOX(grc->vbox), GTK_WIDGET(gr),
 
391
                       FALSE, FALSE, 3);
 
392
    g_signal_connect( G_OBJECT(gr), "changed",
 
393
                      G_CALLBACK(grc_changed), grc );
 
394
    grc->num_rec++;
 
395
 
 
396
    gtk_widget_set_sensitive(GTK_WIDGET(grc->buttRemove), (grc->num_rec > 1));
 
397
    g_signal_emit_by_name(G_OBJECT(grc), "changed");
 
398
 
 
399
 
 
400
}
 
401
static void removeRecurrence(GncRecurrenceComp *grc)
 
402
{
 
403
    GList *children, *last;
 
404
 
 
405
    grc->num_rec--;
 
406
 
 
407
    children = gtk_container_get_children(GTK_CONTAINER(grc->vbox));
 
408
    last = g_list_last(children);
 
409
    gtk_widget_destroy(GTK_WIDGET(last->data));
 
410
    g_list_free(children);
 
411
    g_signal_emit_by_name(G_OBJECT(grc), "changed");
 
412
 
 
413
 
 
414
    gtk_widget_set_sensitive(GTK_WIDGET(grc->buttRemove), (grc->num_rec > 1));
 
415
 
 
416
}
 
417
 
 
418
static void addClicked(GtkButton *b, gpointer data)
 
419
{
 
420
    GncRecurrenceComp *grc = data;
 
421
    GncRecurrence *gr;
 
422
 
 
423
    gr = GNC_RECURRENCE(gnc_recurrence_new());
 
424
    addRecurrence(grc, gr);
 
425
}
 
426
 
 
427
static void removeClicked(GtkButton *b, gpointer data)
 
428
{
 
429
    GncRecurrenceComp *grc = data;
 
430
 
 
431
    if (grc->num_rec > 1)
 
432
        removeRecurrence(grc);
 
433
}
 
434
 
 
435
void
 
436
gnc_recurrence_comp_set_list(GncRecurrenceComp *grc, const GList *rlist)
 
437
{
 
438
    const GList *iter;
 
439
 
 
440
    g_return_if_fail(grc);
 
441
 
 
442
    while (grc->num_rec > 0)
 
443
        removeRecurrence(grc);
 
444
 
 
445
    for (iter = rlist; iter; iter = iter->next) {
 
446
        GncRecurrence *gr = GNC_RECURRENCE(gnc_recurrence_new());
 
447
 
 
448
        gnc_recurrence_set(gr, (Recurrence *)iter->data);
 
449
        addRecurrence(grc, gr);
 
450
    }
 
451
}
 
452
 
 
453
GList *
 
454
gnc_recurrence_comp_get_list(GncRecurrenceComp *grc)
 
455
{
 
456
    GList *rlist = NULL, *children;
 
457
    gint i;
 
458
 
 
459
 
 
460
    children = gtk_container_get_children(GTK_CONTAINER(grc->vbox));
 
461
    for (i = 0; i < g_list_length(children); i++) {
 
462
        GncRecurrence *gr;
 
463
        const Recurrence *r;
 
464
        gr = GNC_RECURRENCE(g_list_nth_data(children, i));
 
465
        r = gnc_recurrence_get(gr);
 
466
        rlist = g_list_append(rlist, (gpointer)r);
 
467
    }
 
468
    g_list_free(children);
 
469
    return rlist;
 
470
}
 
471
 
 
472
 
 
473
static void
 
474
gnc_recurrence_comp_init(GncRecurrenceComp *grc)
 
475
{
 
476
    GtkWidget *vb;
 
477
 
 
478
    grc->hbb = GTK_HBUTTON_BOX(gtk_hbutton_box_new());
 
479
    grc->vbox = GTK_VBOX(gtk_vbox_new(FALSE, 1));
 
480
    grc->rlist = NULL;
 
481
 
 
482
    grc->buttAdd = GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_ADD));
 
483
    g_signal_connect(G_OBJECT(grc->buttAdd), "clicked",
 
484
                     G_CALLBACK(addClicked), grc);
 
485
    grc->buttRemove = GTK_BUTTON(gtk_button_new_from_stock(GTK_STOCK_REMOVE));
 
486
    g_signal_connect(G_OBJECT(grc->buttRemove), "clicked",
 
487
                     G_CALLBACK(removeClicked), grc);
 
488
 
 
489
    gtk_box_pack_start(GTK_BOX(grc->hbb), GTK_WIDGET(grc->buttAdd),
 
490
                     FALSE, FALSE, 3);
 
491
    gtk_box_pack_start(GTK_BOX(grc->hbb), GTK_WIDGET(grc->buttRemove),
 
492
                     FALSE, FALSE, 3);
 
493
 
 
494
    vb = gtk_vbox_new(FALSE, 1);
 
495
    gtk_box_pack_start(GTK_BOX(vb), GTK_WIDGET(grc->hbb),
 
496
                       FALSE, FALSE, 3);
 
497
    gtk_box_pack_start(GTK_BOX(vb), GTK_WIDGET(grc->vbox),
 
498
                       FALSE, FALSE, 3);
 
499
 
 
500
    gtk_scrolled_window_add_with_viewport(
 
501
        GTK_SCROLLED_WINDOW(grc), GTK_WIDGET(vb));
 
502
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(grc),
 
503
                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 
504
 
 
505
    grc->num_rec = 0;
 
506
    gtk_widget_show_all(GTK_WIDGET(grc));
 
507
    addClicked(NULL, grc);
 
508
}
 
509
 
 
510
static void
 
511
gnc_recurrence_comp_class_init( GncRecurrenceCompClass *klass )
 
512
{
 
513
    GObjectClass *object_class;
 
514
    static gint signals[GNCRC_LAST_SIGNAL] = { 0 };
 
515
 
 
516
    object_class = G_OBJECT_CLASS (klass);
 
517
    signals[GNCRECURRENCECOMP_CHANGED] =
 
518
        g_signal_new ("changed",
 
519
                      G_OBJECT_CLASS_TYPE (object_class),
 
520
                      G_SIGNAL_RUN_FIRST,
 
521
                      G_STRUCT_OFFSET (GncRecurrenceCompClass, changed),
 
522
                      NULL,
 
523
                      NULL,
 
524
                      g_cclosure_marshal_VOID__VOID,
 
525
                      G_TYPE_NONE,
 
526
                      0);
 
527
 
 
528
    //parent_class = g_type_class_peek_parent (klass);
 
529
    //object_class->finalize = gnc_recurrence_finalize;
 
530
}
 
531
 
 
532
GType
 
533
gnc_recurrence_comp_get_type()
 
534
{
 
535
    static GType type = 0;
 
536
    if (type == 0) {
 
537
        static GTypeInfo typeinfo = {
 
538
            sizeof(GncRecurrenceCompClass),
 
539
            NULL, NULL,
 
540
            (GClassInitFunc)gnc_recurrence_comp_class_init,
 
541
            NULL, NULL,
 
542
            sizeof(GncRecurrenceComp),
 
543
            0,
 
544
            (GInstanceInitFunc)gnc_recurrence_comp_init
 
545
        };
 
546
 
 
547
        type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW,
 
548
                                       "GncRecurrenceComp", &typeinfo, 0);
 
549
    }
 
550
    return type;
 
551
}
 
552
 
 
553
GtkWidget *
 
554
gnc_recurrence_comp_new()
 
555
{
 
556
    GncRecurrenceComp *grc;
 
557
    grc = g_object_new(gnc_recurrence_comp_get_type(), NULL);
 
558
    return GTK_WIDGET(grc);
 
559
}
 
560
 
 
561
/* ========================= END OF FILE =========================== */