00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030 #include "config.h"
00031
00032 #include <string.h>
00033
00034 #include <glib.h>
00035
00036 #include "action.h"
00037 #include "duifield.h"
00038 #include "duifield-gobj.h"
00039 #include "duifield-hash.h"
00040 #include "duifield-qof.h"
00041 #include "duifieldmap.h"
00042 #include "duifilter.h"
00043 #include "duiresolver.h"
00044 #include "duitxnquery.h"
00045 #include "perr.h"
00046 #include "report.h"
00047
00048 typedef struct DuiCheck_s DuiCheck;
00049 typedef struct DuiRefresh_s DuiRefresh;
00050
00051 struct DuiAction_s
00052 {
00053 gchar * name;
00056 DuiTxnQuery *query;
00057 gchar * database_name;
00059
00060 GList *non_table_targets;
00061
00062
00063 gchar * report_name;
00064 DuiReport * report;
00065
00069 GList *check_list;
00070
00072 GList *refresh_list;
00073
00077 DuiResolver *resolver;
00078 DuiInterface *interface;
00079 gboolean is_finalized;
00080 };
00081
00082 struct DuiRefresh_s
00083 {
00084 gchar * reportname;
00085 DuiReport *report;
00086 };
00087
00088 struct DuiCheck_s
00089 {
00090 gchar * actionname;
00091 DuiAction *action;
00092 };
00093
00094
00095
00096 DuiAction *
00097 dui_action_new (const gchar * name)
00098 {
00099 DuiAction *act;
00100
00101 act = g_new0 (DuiAction, 1);
00102 act->name = g_strdup (name);
00103
00104 act->query = NULL;
00105 act->database_name = NULL;
00106 act->non_table_targets = NULL;
00107
00108 act->report_name = NULL;
00109 act->report = NULL;
00110 act->check_list = NULL;
00111 act->refresh_list = NULL;
00112
00113 act->resolver = dui_resolver_new();
00114 act->interface = NULL;
00115 act->is_finalized = FALSE;
00116
00117 return act;
00118 }
00119
00120
00121
00122 void
00123 dui_action_destroy (DuiAction * act)
00124 {
00125 GList *node;
00126 if (!act) return;
00127
00128 act->interface = NULL;
00129 if (act->name) g_free (act->name);
00130 act->name = NULL;
00131 if (act->database_name) g_free (act->database_name);
00132 act->database_name = NULL;
00133
00134 dui_txnquery_destroy (act->query);
00135
00136
00137 for (node=act->non_table_targets; node; node=node->next)
00138 {
00139 DuiFieldMap *fm = node->data;
00140 dui_field_map_destroy (fm);
00141 }
00142 g_list_free (act->non_table_targets);
00143 act->non_table_targets = NULL;
00144
00145 g_free(act->report_name);
00146 act->report_name = NULL;
00147 act->report = NULL;
00148
00149 for (node=act->check_list; node; node=node->next)
00150 {
00151 DuiCheck *chk = node->data;
00152 g_free (chk->actionname);
00153 g_free (chk);
00154 }
00155 for (node=act->refresh_list; node; node=node->next)
00156 {
00157 DuiRefresh *rsh = node->data;
00158 g_free (rsh->reportname);
00159 g_free (rsh);
00160 }
00161 g_list_free (act->refresh_list);
00162
00163 dui_resolver_destroy (act->resolver);
00164 act->interface = NULL;
00165 g_free (act);
00166 }
00167
00168
00169
00170 const gchar *
00171 dui_action_get_name (DuiAction *act)
00172 {
00173 g_return_val_if_fail (act, NULL);
00174 if (act->name) return (act->name);
00175 return NULL;
00176 }
00177
00178
00179
00180 void
00181 dui_action_set_report (DuiAction * act, const gchar * rptname)
00182 {
00183 g_return_if_fail (act);
00184 if (act->report_name) g_free (act->report_name);
00185 act->report_name = g_strdup (rptname);
00186 }
00187
00188 const gchar *
00189 dui_action_get_report (DuiAction * act)
00190 {
00191 g_return_val_if_fail (act, NULL);
00192 return act->report_name;
00193 }
00194
00195
00196
00197 void
00198 dui_action_add_chain (DuiAction *act, const gchar * actname)
00199 {
00200 DuiCheck *chk;
00201 if (!act) return;
00202
00203 chk = g_new (DuiCheck, 1);
00204 chk->actionname = g_strdup (actname);
00205 chk->action = NULL;
00206
00207 act->check_list = g_list_prepend (act->check_list, chk);
00208 }
00209
00210
00211
00212 void
00213 dui_action_add_refresh (DuiAction *act, const gchar * name)
00214 {
00215 DuiRefresh *rsh;
00216 if (!act) return;
00217
00218 rsh = g_new (DuiRefresh, 1);
00219 rsh->reportname = g_strdup (name);
00220 rsh->report = NULL;
00221
00222 act->refresh_list = g_list_prepend (act->refresh_list, rsh);
00223 }
00224
00225
00226
00227 void
00228 dui_action_set_database_name (DuiAction * act, const gchar *dbname)
00229 {
00230 if (!act || !dbname) return;
00231 if (act->database_name) g_free (act->database_name);
00232 act->database_name = g_strdup (dbname);
00233 }
00234
00235
00236
00237 void
00238 dui_action_add_row (DuiAction * act, DuiTxnQuery *qry)
00239 {
00240 if (!act || !qry) return;
00241
00242 dui_txnquery_set_resolver (qry, act->resolver);
00243
00244
00245 if (act->query)
00246 {
00247 PERR ("There already is a query in this action");
00248 }
00249 act->query = qry;
00250 }
00251
00252 DuiTxnQuery *
00253 dui_action_get_query (DuiAction * act)
00254 {
00255 if (!act) return NULL;
00256 return act->query;
00257 }
00258
00259 void
00260 dui_action_add_term (DuiAction * act, DuiFieldMap *fm)
00261 {
00262 if (!act || !fm) return;
00263
00264 if (DUI_FIELD_IS_TYPE(&fm->target, DUI_FIELD_SQL) ||
00265 DUI_FIELD_IS_TYPE(&fm->target, DUI_FIELD_WHERE) ||
00266 DUI_FIELD_IS_TYPE(&fm->target, DUI_FIELD_CONST))
00267 {
00268 if (NULL == act->query)
00269 {
00270 DuiTxnQuery *qry = dui_txnquery_new();
00271 dui_action_add_row (act, qry);
00272 act->query = qry;
00273 }
00274 dui_txnquery_add_term (act->query, fm);
00275 }
00276 else
00277 {
00278 dui_resolver_add_field (act->resolver, &fm->source);
00279 dui_resolver_add_field (act->resolver, &fm->target);
00280 act->non_table_targets = g_list_append (act->non_table_targets, fm);
00281 }
00282 }
00283
00284
00285
00286
00287
00288
00289 static void
00290 resolve_widget_again (DuiAction *act)
00291 {
00292 GList *node;
00293 for (node=act->non_table_targets; node; node=node->next)
00294 {
00295 DuiFieldMap *fm = node->data;
00296 dui_field_map_resolve (fm);
00297 }
00298 dui_resolver_resolve (act->resolver);
00299 }
00300
00301 static void
00302 final_setup (DuiAction *act)
00303 {
00304 GList *node;
00305 DuiInterface *iface;
00306 DuiDatabase *db;
00307
00308 if (act->is_finalized) return;
00309 act->is_finalized = TRUE;
00310 ENTER ("(act=%p)", act);
00311
00312
00313 iface = act->interface;
00314 act->report = dui_interface_find_report_by_name (iface, act->report_name);
00315 if (act->report_name && !act->report)
00316 {
00317 const gchar * tmp = dui_action_get_name(act);
00318 SYNTAX ("In form \'%s\', can't find the report \'%s\'",
00319 tmp, act->report_name);
00320 }
00321
00322
00323 for (node=act->check_list; node; node=node->next)
00324 {
00325 DuiCheck *chk = node->data;
00326 chk->action = dui_interface_find_action_by_name (iface, chk->actionname);
00327
00328 if (chk->actionname && !chk->action)
00329 {
00330 const gchar * tmp = dui_action_get_name(act);
00331 SYNTAX ("In form \'%s\', can't find the chain form \'%s\'",
00332 tmp, chk->actionname);
00333 }
00334 }
00335
00336
00337 for (node=act->refresh_list; node; node=node->next)
00338 {
00339 DuiRefresh *rsh = node->data;
00340 rsh->report = dui_interface_find_report_by_name (iface, rsh->reportname);
00341
00342 if (rsh->reportname && !rsh->report)
00343 {
00344 const gchar * tmp = dui_action_get_name(act);
00345 SYNTAX ("In form \'%s\', can't find the refresh report \'%s\'",
00346 tmp, rsh->reportname);
00347 }
00348 }
00349
00350 for (node=act->non_table_targets; node; node=node->next)
00351 {
00352 DuiFieldMap *fm = node->data;
00353 dui_field_map_resolve (fm);
00354 }
00355 dui_report_do_realize (act->report);
00356
00357
00358 dui_resolver_resolve_gobj (act->resolver, act->interface);
00359 dui_resolver_resolve_hash (act->resolver, act->interface);
00360 dui_resolver_resolve (act->resolver);
00361
00362
00363 db = dui_interface_find_database_by_name (act->interface, act->database_name);
00364 if (db)
00365 {
00366 dui_txnquery_set_database (act->query, db);
00367 }
00368 dui_txnquery_do_realize (act->query);
00369
00370 LEAVE ("(act=%p)", act);
00371 }
00372
00373
00374
00375 void
00376 dui_action_set_interface (DuiAction *act, DuiInterface *iface)
00377 {
00378 if (!act) return;
00379 act->interface = iface;
00380 }
00381
00382 void
00383 dui_action_add_resolver (DuiAction *act, DuiResolverFieldFunc fn, gpointer ud)
00384 {
00385 if (!act) return;
00386 dui_resolver_add_resolver (act->resolver, fn, ud);
00387 }
00388
00389 void
00390 dui_action_add_realizer (DuiAction *act, DuiResolverRealizeFunc fn, gpointer ud)
00391 {
00392 if (!act) return;
00393 dui_resolver_add_realizer (act->resolver, fn, ud);
00394 }
00395
00396 void
00397 dui_action_do_realize (DuiAction *act)
00398 {
00399 if (!act) return;
00400
00401 ENTER ("(act=%p)", act);
00402 final_setup (act);
00403 dui_resolver_realize (act->resolver);
00404 LEAVE ("(act=%p)", act);
00405 }
00406
00407
00408
00409 void
00410 dui_action_db_connect (DuiAction *act)
00411 {
00412 if (!act) return;
00413 dui_txnquery_connect (act->query);
00414 }
00415
00416
00417
00418 gint
00419 dui_action_run (DuiAction *act)
00420 {
00421 DuiDBRecordSet *recs = NULL;
00422 GList *node;
00423 gint rc = 0;
00424
00425 if (!act) return 0;
00426 ENTER ("(act=%p \'%s\')", act, dui_action_get_name (act));
00427 final_setup (act);
00428
00429
00430
00431
00432
00433 resolve_widget_again (act);
00434
00435
00436 for (node=act->check_list; node; node=node->next)
00437 {
00438 DuiCheck *chk = node->data;
00439 rc = dui_action_run (chk->action);
00440 if (rc) return rc;
00441 }
00442
00443
00444
00445 for (node = act->non_table_targets; node; node=node->next)
00446 {
00447 DuiFieldMap *fm = node->data;
00448 dui_field_map_transfer_data (fm);
00449 }
00450
00451 recs = dui_txnquery_run (act->query);
00452
00453
00454 dui_report_set_last_action (act->report, act);
00455 rc = dui_report_show_data (act->report, recs);
00456
00457
00458 dui_recordset_free (recs);
00459
00460
00461 for (node=act->refresh_list; node; node=node->next)
00462 {
00463 DuiRefresh *rsh = node->data;
00464 dui_report_refresh (rsh->report);
00465 }
00466 LEAVE ("(act=%p \'%s\') rc=%d", act, dui_action_get_name (act), rc);
00467 return rc;
00468 }
00469
00470
00471
00472 void
00473 dui_action_rerun_last_query (DuiAction *act)
00474 {
00475 DuiDBRecordSet *recs = NULL;
00476
00477 if (!act) return;
00478
00479 ENTER ("(act=%p \'%s\')", act, dui_action_get_name (act));
00480
00481
00482 recs = dui_txnquery_rerun_last_query (act->query);
00483 dui_report_show_data (act->report, recs);
00484 dui_recordset_free (recs);
00485
00486 LEAVE ("(act=%p \'%s\')", act, dui_action_get_name (act));
00487 }
00488
00489