~mdoyen/homebank/5.2.x

« back to all changes in this revision

Viewing changes to src/hub-scheduled.c

  • Committer: Maxime Doyen
  • Date: 2019-04-11 20:36:11 UTC
  • Revision ID: homebank@free.fr-20190411203611-pby791lywld1op5a
5.2.4 release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  HomeBank -- Free, easy, personal accounting for everyone.
 
2
 *  Copyright (C) 1995-2019 Maxime DOYEN
 
3
 *
 
4
 *  This file is part of HomeBank.
 
5
 *
 
6
 *  HomeBank is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  HomeBank 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, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
 
 
21
#include "homebank.h"
 
22
 
 
23
#include "dsp-mainwindow.h"
 
24
#include "list-scheduled.h"
 
25
#include "hub-scheduled.h"
 
26
 
 
27
#include "ui-transaction.h"
 
28
 
 
29
 
 
30
/****************************************************************************/
 
31
/* Debug macros                                                             */
 
32
/****************************************************************************/
 
33
#define MYDEBUG 0
 
34
 
 
35
#if MYDEBUG
 
36
#define DB(x) (x);
 
37
#else
 
38
#define DB(x);
 
39
#endif
 
40
 
 
41
/* our global datas */
 
42
extern struct HomeBank *GLOBALS;
 
43
extern struct Preferences *PREFS;
 
44
 
 
45
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
 
46
/* scheduled */
 
47
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
 
48
static Archive *
 
49
ui_hub_scheduled_get_selected_item(GtkTreeView *treeview)
 
50
{
 
51
GtkTreeSelection *treeselection;
 
52
GtkTreeModel             *model;
 
53
GtkTreeIter                      iter;
 
54
 
 
55
        treeselection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
 
56
        if( gtk_tree_selection_get_selected(treeselection, &model, &iter) )
 
57
        {
 
58
        Archive *arc;
 
59
 
 
60
                gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, LST_DSPUPC_DATAS, &arc, -1);
 
61
                return arc;
 
62
        }
 
63
 
 
64
        return NULL;
 
65
}
 
66
 
 
67
 
 
68
static void ui_hub_scheduled_onRowActivated (GtkTreeView        *treeview,
 
69
                       GtkTreePath        *path,
 
70
                       GtkTreeViewColumn  *col,
 
71
                       gpointer            userdata)
 
72
{
 
73
//struct hbfile_data *data;
 
74
Archive *arc;
 
75
 
 
76
        DB( g_print ("\n[hub-scheduled] row double-clicked\n") );
 
77
 
 
78
        //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(treeview, GTK_TYPE_WINDOW)), "inst_data");
 
79
 
 
80
        arc = ui_hub_scheduled_get_selected_item(treeview);
 
81
        ui_mainwindow_defarchive(arc);
 
82
}
 
83
 
 
84
 
 
85
static void ui_hub_scheduled_do_post(Archive *arc, gboolean doedit, gpointer user_data)
 
86
{
 
87
struct hbfile_data *data = user_data;
 
88
GtkWidget *window;
 
89
gint result;
 
90
Transaction *txn;
 
91
 
 
92
        DB( g_print("\n[hub-scheduled] do post\n") );
 
93
 
 
94
        
 
95
        window =  create_deftransaction_window(GTK_WINDOW(data->window), TRANSACTION_EDIT_ADD, TRUE, 0);
 
96
 
 
97
        /* fill in the transaction */
 
98
        txn = da_transaction_malloc();
 
99
        da_transaction_init_from_template(txn, arc);
 
100
        txn->date = scheduled_get_postdate(arc, arc->nextdate);
 
101
 
 
102
        deftransaction_set_transaction(window, txn);
 
103
 
 
104
        result = gtk_dialog_run (GTK_DIALOG (window));
 
105
 
 
106
        DB( g_print(" - dialog result is %d\n", result) );
 
107
 
 
108
        if(result == HB_RESPONSE_ADD || result == GTK_RESPONSE_ACCEPT)
 
109
        {
 
110
                deftransaction_get(window, NULL);
 
111
                transaction_add(GTK_WINDOW(GLOBALS->mainwindow), txn);
 
112
                GLOBALS->changes_count++;
 
113
 
 
114
                scheduled_date_advance(arc);
 
115
 
 
116
                DB( g_print(" - added 1 transaction to %d\n", txn->kacc) );
 
117
        }
 
118
 
 
119
        da_transaction_free(txn);
 
120
 
 
121
        deftransaction_dispose(window, NULL);
 
122
        gtk_widget_destroy (window);
 
123
 
 
124
}
 
125
 
 
126
 
 
127
static void ui_hub_scheduled_editpost_cb(GtkWidget *widget, gpointer user_data)
 
128
{
 
129
struct hbfile_data *data = user_data;
 
130
 
 
131
        DB( g_print("\n[hub-scheduled] editpost\n") );
 
132
        
 
133
        Archive *arc = ui_hub_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
 
134
 
 
135
        if( (arc != NULL) )
 
136
        {
 
137
                ui_hub_scheduled_do_post(arc, TRUE, data);
 
138
                ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE|UF_REFRESHALL));
 
139
        }
 
140
}
 
141
 
 
142
 
 
143
static void ui_hub_scheduled_post_cb(GtkWidget *widget, gpointer user_data)
 
144
{
 
145
struct hbfile_data *data = user_data;
 
146
 
 
147
        DB( g_print("\n[hub-scheduled] post\n") );
 
148
 
 
149
        Archive *arc = ui_hub_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
 
150
 
 
151
        if( (arc != NULL) )
 
152
        {
 
153
                if( scheduled_is_postable(arc) )
 
154
                {
 
155
                Transaction *txn = da_transaction_malloc ();
 
156
 
 
157
                        da_transaction_init_from_template(txn, arc);
 
158
                        txn->date = scheduled_get_postdate(arc, arc->nextdate);
 
159
                        transaction_add(GTK_WINDOW(GLOBALS->mainwindow), txn);
 
160
 
 
161
                        GLOBALS->changes_count++;
 
162
                        scheduled_date_advance(arc);
 
163
 
 
164
                        da_transaction_free (txn);
 
165
                }
 
166
                else
 
167
                {
 
168
                        ui_hub_scheduled_do_post(arc, FALSE, data);
 
169
                }
 
170
 
 
171
                ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE|UF_REFRESHALL));
 
172
        }
 
173
}
 
174
 
 
175
 
 
176
static void ui_hub_scheduled_skip_cb(GtkWidget *widget, gpointer user_data)
 
177
{
 
178
struct hbfile_data *data = user_data;
 
179
 
 
180
        DB( g_print("\n[hub-scheduled] skip\n") );
 
181
        
 
182
        Archive *arc = ui_hub_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
 
183
        if( (arc != NULL) && (arc->flags & OF_AUTO) )
 
184
        {
 
185
                GLOBALS->changes_count++;
 
186
                scheduled_date_advance(arc);
 
187
 
 
188
                ui_hub_scheduled_populate(GLOBALS->mainwindow, NULL);
 
189
                ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
 
190
        }
 
191
}
 
192
 
 
193
 
 
194
 
 
195
static void ui_hub_scheduled_update(GtkWidget *widget, gpointer user_data)
 
196
{
 
197
struct hbfile_data *data;
 
198
//gint filter;
 
199
 
 
200
        DB( g_print("\n[hub-scheduled] update\n") );
 
201
 
 
202
        data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
 
203
 
 
204
        //filter = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_sched_filter));
 
205
 
 
206
        Archive *arc = ui_hub_scheduled_get_selected_item(GTK_TREE_VIEW(data->LV_upc));
 
207
 
 
208
        if(arc)
 
209
        {
 
210
                DB( g_print("archive is %s\n", arc->memo) );
 
211
                
 
212
                gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_skip), TRUE);
 
213
                gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_post), TRUE);
 
214
                gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_editpost), TRUE);
 
215
        }
 
216
        else
 
217
        {
 
218
                gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_skip), FALSE);
 
219
                gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_post), FALSE);
 
220
                gtk_widget_set_sensitive(GTK_WIDGET(data->BT_sched_editpost), FALSE);
 
221
        }
 
222
 
 
223
}
 
224
 
 
225
 
 
226
 
 
227
static void ui_hub_scheduled_selection_cb(GtkTreeSelection *treeselection, gpointer user_data)
 
228
{
 
229
        ui_hub_scheduled_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), GINT_TO_POINTER(UF_SENSITIVE));
 
230
}
 
231
 
 
232
 
 
233
 
 
234
/*
 
235
** called after load, importamiga, on demand
 
236
*/
 
237
void ui_hub_scheduled_postall(GtkWidget *widget, gpointer user_data)
 
238
{
 
239
//struct hbfile_data *data;
 
240
gint count;
 
241
gint usermode = GPOINTER_TO_INT(user_data);
 
242
 
 
243
        DB( g_print("\n[hub-scheduled] post all\n") );
 
244
 
 
245
        //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
 
246
 
 
247
        count = scheduled_post_all_pending();
 
248
 
 
249
        //inform the user
 
250
        if(usermode == TRUE)
 
251
        {
 
252
        gchar *txt;
 
253
 
 
254
                //#125534
 
255
                if( count > 0 )
 
256
                {
 
257
                        ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_REFRESHALL));
 
258
                }
 
259
                
 
260
                if(count == 0)
 
261
                        txt = _("No transaction to add");
 
262
                else
 
263
                        txt = _("transaction added: %d");
 
264
 
 
265
                ui_dialog_msg_infoerror(GTK_WINDOW(GLOBALS->mainwindow), GTK_MESSAGE_INFO,
 
266
                        _("Check scheduled transactions result"),
 
267
                        txt,
 
268
                        count);
 
269
        }
 
270
 
 
271
}
 
272
 
 
273
 
 
274
void ui_hub_scheduled_populate(GtkWidget *widget, gpointer user_data)
 
275
{
 
276
struct hbfile_data *data;
 
277
GtkTreeModel *model;
 
278
GtkTreeIter  iter;
 
279
GList *list;
 
280
gdouble totexp = 0;
 
281
gdouble totinc = 0;
 
282
gint count = 0;
 
283
gchar buffer[256];
 
284
guint32 maxpostdate;
 
285
GDate *date;
 
286
//Account *acc;
 
287
 
 
288
        DB( g_print("\n[hub-scheduled] populate\n") );
 
289
 
 
290
        data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
 
291
 
 
292
        model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_upc));
 
293
        gtk_list_store_clear (GTK_LIST_STORE(model));
 
294
 
 
295
        homebank_app_date_get_julian();
 
296
 
 
297
        maxpostdate = scheduled_date_get_post_max();
 
298
 
 
299
        date = g_date_new_julian (maxpostdate);
 
300
        g_date_strftime (buffer, 256-1, PREFS->date_format, date);
 
301
        g_date_free(date);
 
302
 
 
303
        gtk_label_set_text(GTK_LABEL(data->LB_maxpostdate), buffer);
 
304
 
 
305
        
 
306
        list = g_list_first(GLOBALS->arc_list);
 
307
        while (list != NULL)
 
308
        {
 
309
        Archive *arc = list->data;
 
310
        Account *acc;
 
311
        gdouble inc, exp;
 
312
        guint nbdays, nblate;
 
313
 
 
314
                if((arc->flags & OF_AUTO) ) //&& arc->kacc > 0)
 
315
                {
 
316
                        count++;
 
317
                        nbdays = arc->nextdate - maxpostdate;
 
318
                        nblate = scheduled_get_latepost_count(arc, GLOBALS->today);
 
319
                        
 
320
                        DB( g_print(" - append '%s' : %d\n", arc->memo, nbdays) );
 
321
 
 
322
                        if(arc->flags & OF_INCOME)
 
323
                        {
 
324
                                inc = arc->amount;
 
325
                                exp = 0.0;
 
326
                        }
 
327
                        else
 
328
                        {
 
329
                                exp = arc->amount;
 
330
                                inc = 0.0;
 
331
                        }
 
332
 
 
333
                        /* insert normal txn */
 
334
                        acc = da_acc_get(arc->kacc);
 
335
                        if( acc)
 
336
                        {
 
337
                                totinc += hb_amount_base(inc, acc->kcur);
 
338
                                totexp += hb_amount_base(exp, acc->kcur);
 
339
                        }
 
340
                        gtk_list_store_append (GTK_LIST_STORE(model), &iter);
 
341
                        gtk_list_store_set (GTK_LIST_STORE(model), &iter,
 
342
                                  LST_DSPUPC_DATAS, arc,
 
343
                              LST_DSPUPC_NEXT, nbdays,
 
344
                                  LST_DSPUPC_ACCOUNT, acc,
 
345
                              LST_DSPUPC_MEMO, arc->memo,
 
346
                              LST_DSPUPC_EXPENSE, exp,
 
347
                              LST_DSPUPC_INCOME, inc,
 
348
                              LST_DSPUPC_NB_LATE, nblate,
 
349
                                  -1);
 
350
 
 
351
                        /* insert internal xfer txn : 1378836 */
 
352
                        if(arc->paymode == PAYMODE_INTXFER)
 
353
                        {
 
354
                                acc = da_acc_get(arc->kxferacc);
 
355
                                if( acc)
 
356
                                {
 
357
                                        totinc += hb_amount_base(-inc, acc->kcur);
 
358
                                        totexp += hb_amount_base(-exp, acc->kcur);
 
359
                                }
 
360
                                gtk_list_store_append (GTK_LIST_STORE(model), &iter);
 
361
                                gtk_list_store_set (GTK_LIST_STORE(model), &iter,
 
362
                                          LST_DSPUPC_DATAS, arc,
 
363
                                      LST_DSPUPC_NEXT, nbdays,
 
364
                                          LST_DSPUPC_ACCOUNT, acc,
 
365
                                          LST_DSPUPC_MEMO, arc->memo,
 
366
                                          LST_DSPUPC_EXPENSE, -inc,
 
367
                                          LST_DSPUPC_INCOME, -exp,
 
368
                                          LST_DSPUPC_NB_LATE, nblate,
 
369
                                          -1);
 
370
                        }
 
371
 
 
372
                }
 
373
                list = g_list_next(list);
 
374
        }
 
375
 
 
376
        // insert total
 
377
        if(count > 0 )
 
378
        {
 
379
                gtk_list_store_append (GTK_LIST_STORE(model), &iter);
 
380
                gtk_list_store_set (GTK_LIST_STORE(model), &iter,
 
381
                          LST_DSPUPC_DATAS, NULL,
 
382
                          LST_DSPUPC_ACCOUNT, NULL,
 
383
                          LST_DSPUPC_MEMO, _("Total"),
 
384
                          LST_DSPUPC_EXPENSE, totexp,
 
385
                      LST_DSPUPC_INCOME, totinc,
 
386
                  -1);
 
387
        }
 
388
 
 
389
        ui_hub_scheduled_update(widget, NULL);
 
390
        
 
391
}
 
392
 
 
393
 
 
394
GtkWidget *ui_hub_scheduled_create(struct hbfile_data *data)
 
395
{
 
396
GtkWidget *hub, *hbox, *vbox, *bbox, *sw, *tbar;
 
397
GtkWidget *label, *widget;
 
398
GtkToolItem *toolitem;
 
399
 
 
400
        DB( g_print("\n[hub-scheduled] create\n") );
 
401
        
 
402
        hub = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
 
403
        gtk_container_set_border_width(GTK_CONTAINER(hub), SPACING_SMALL);
 
404
        //data->GR_upc = hub;
 
405
 
 
406
        vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
 
407
        //gtk_widget_set_margin_top(GTK_WIDGET(vbox), 0);
 
408
        //gtk_widget_set_margin_bottom(GTK_WIDGET(vbox), SPACING_SMALL);
 
409
        //gtk_widget_set_margin_start(GTK_WIDGET(vbox), 2*SPACING_SMALL);
 
410
        //gtk_widget_set_margin_end(GTK_WIDGET(vbox), SPACING_SMALL);
 
411
        gtk_box_pack_start (GTK_BOX (hub), vbox, TRUE, TRUE, 0);
 
412
 
 
413
        sw = gtk_scrolled_window_new (NULL, NULL);
 
414
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
 
415
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
416
        gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
 
417
        
 
418
        widget = (GtkWidget *)create_list_upcoming();
 
419
        data->LV_upc = widget;
 
420
        gtk_container_add (GTK_CONTAINER (sw), widget);
 
421
 
 
422
        tbar = gtk_toolbar_new();
 
423
        gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar), GTK_ICON_SIZE_MENU);
 
424
        gtk_toolbar_set_style(GTK_TOOLBAR(tbar), GTK_TOOLBAR_ICONS);
 
425
        gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
 
426
        gtk_box_pack_start (GTK_BOX (vbox), tbar, FALSE, FALSE, 0);
 
427
 
 
428
        label = make_label_group(_("Scheduled transactions"));
 
429
        toolitem = gtk_tool_item_new();
 
430
        gtk_container_add (GTK_CONTAINER(toolitem), label);
 
431
        gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
 
432
 
 
433
        toolitem = gtk_separator_tool_item_new ();
 
434
        gtk_tool_item_set_expand (toolitem, FALSE);
 
435
        gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
 
436
        gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
 
437
 
 
438
 
 
439
        bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
 
440
        toolitem = gtk_tool_item_new();
 
441
        gtk_container_add (GTK_CONTAINER(toolitem), bbox);
 
442
        gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
 
443
 
 
444
                widget = gtk_button_new_with_label(_("Skip"));
 
445
                data->BT_sched_skip = widget;
 
446
                gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
 
447
 
 
448
                widget = gtk_button_new_with_label(_("Edit & Post"));
 
449
                data->BT_sched_editpost = widget;
 
450
                gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
 
451
 
 
452
                //TRANSLATORS: Posting a scheduled transaction is the action to materialize it into its target account.
 
453
                //TRANSLATORS: Before that action the automated transaction occurrence is pending and not yet really existing.
 
454
                widget = gtk_button_new_with_label (_("Post"));
 
455
                data->BT_sched_post = widget;
 
456
                gtk_box_pack_start (GTK_BOX (bbox), widget, FALSE, FALSE, 0);
 
457
 
 
458
        toolitem = gtk_separator_tool_item_new ();
 
459
        gtk_tool_item_set_expand (toolitem, FALSE);
 
460
        gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
 
461
        gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
 
462
 
 
463
        hbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
 
464
        gtk_widget_set_valign (hbox, GTK_ALIGN_CENTER);
 
465
        toolitem = gtk_tool_item_new();
 
466
        gtk_container_add (GTK_CONTAINER(toolitem), hbox);
 
467
        gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
 
468
 
 
469
                label = make_label(_("maximum post date"), 0.0, 0.7);
 
470
                gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
 
471
                gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
 
472
                gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
 
473
 
 
474
                label = make_label(NULL, 0.0, 0.7);
 
475
                data->LB_maxpostdate = label;
 
476
                gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
 
477
                gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
 
478
                gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
 
479
 
 
480
 
 
481
        g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_upc)), "changed", G_CALLBACK (ui_hub_scheduled_selection_cb), NULL);
 
482
        g_signal_connect (GTK_TREE_VIEW(data->LV_upc), "row-activated", G_CALLBACK (ui_hub_scheduled_onRowActivated), NULL);
 
483
        g_signal_connect (G_OBJECT (data->BT_sched_skip), "clicked", G_CALLBACK (ui_hub_scheduled_skip_cb), data);
 
484
        g_signal_connect (G_OBJECT (data->BT_sched_editpost), "clicked", G_CALLBACK (ui_hub_scheduled_editpost_cb), data);
 
485
        g_signal_connect (G_OBJECT (data->BT_sched_post), "clicked", G_CALLBACK (ui_hub_scheduled_post_cb), data);
 
486
 
 
487
 
 
488
        
 
489
        return hub;
 
490
}