43 #ifdef GNC_PLATFORM_WINDOWS 45 #define __STDC_FORMAT_MACROS = 1 50 #include "qofevent-p.h" 52 #include "qofbook-p.h" 55 #include "qofbookslots.h" 56 #include "kvp-frame.hpp" 61 #include "qofbook.hpp" 63 static QofLogModule log_module = QOF_MOD_ENGINE;
70 PROP_OPT_TRADING_ACCOUNTS,
71 PROP_OPT_AUTO_READONLY_DAYS,
72 PROP_OPT_NUM_FIELD_SOURCE,
73 PROP_OPT_DEFAULT_BUDGET,
78 qof_book_option_num_field_source_changed_cb (GObject *gobject,
82 qof_book_option_num_autoreadonly_changed_cb (GObject *gobject,
87 #define PARAM_NAME_NUM_FIELD_SOURCE "split-action-num-field" 88 #define PARAM_NAME_NUM_AUTOREAD_ONLY "autoreadonly-days" 90 G_DEFINE_TYPE(QofBook, qof_book, QOF_TYPE_INSTANCE)
91 QOF_GOBJECT_DISPOSE(qof_book);
92 QOF_GOBJECT_FINALIZE(qof_book);
94 #undef G_PARAM_READWRITE 95 #define G_PARAM_READWRITE static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_WRITABLE) 99 static void coll_destroy(gpointer col)
105 qof_book_init (QofBook *book)
109 book->hash_of_collections = g_hash_table_new_full(
110 g_str_hash, g_str_equal,
116 book->data_tables = g_hash_table_new_full (g_str_hash, g_str_equal,
118 book->data_table_finalizers = g_hash_table_new (g_str_hash, g_str_equal);
120 book->book_open =
'y';
121 book->read_only = FALSE;
122 book->session_dirty = FALSE;
124 book->cached_num_field_source_isvalid = FALSE;
125 book->cached_num_days_autoreadonly_isvalid = FALSE;
130 g_signal_connect (G_OBJECT(book),
131 "notify::" PARAM_NAME_NUM_FIELD_SOURCE,
132 G_CALLBACK (qof_book_option_num_field_source_changed_cb),
138 g_signal_connect (G_OBJECT(book),
139 "notify::" PARAM_NAME_NUM_AUTOREAD_ONLY,
140 G_CALLBACK (qof_book_option_num_autoreadonly_changed_cb),
144 static const std::string str_KVP_OPTION_PATH(KVP_OPTION_PATH);
145 static const std::string str_OPTION_SECTION_ACCOUNTS(OPTION_SECTION_ACCOUNTS);
146 static const std::string str_OPTION_SECTION_BUDGETING(OPTION_SECTION_BUDGETING);
147 static const std::string str_OPTION_NAME_DEFAULT_BUDGET(OPTION_NAME_DEFAULT_BUDGET);
148 static const std::string str_OPTION_NAME_TRADING_ACCOUNTS(OPTION_NAME_TRADING_ACCOUNTS);
149 static const std::string str_OPTION_NAME_AUTO_READONLY_DAYS(OPTION_NAME_AUTO_READONLY_DAYS);
150 static const std::string str_OPTION_NAME_NUM_FIELD_SOURCE(OPTION_NAME_NUM_FIELD_SOURCE);
153 qof_book_get_property (GObject*
object,
160 g_return_if_fail (QOF_IS_BOOK (
object));
161 book = QOF_BOOK (
object);
164 case PROP_OPT_TRADING_ACCOUNTS:
165 qof_instance_get_path_kvp (QOF_INSTANCE (book), value, {str_KVP_OPTION_PATH,
166 str_OPTION_SECTION_ACCOUNTS, str_OPTION_NAME_TRADING_ACCOUNTS});
168 case PROP_OPT_AUTO_READONLY_DAYS:
169 qof_instance_get_path_kvp (QOF_INSTANCE (book), value, {str_KVP_OPTION_PATH,
170 str_OPTION_SECTION_ACCOUNTS, str_OPTION_NAME_AUTO_READONLY_DAYS});
172 case PROP_OPT_NUM_FIELD_SOURCE:
173 qof_instance_get_path_kvp (QOF_INSTANCE (book), value, {str_KVP_OPTION_PATH,
174 str_OPTION_SECTION_ACCOUNTS, str_OPTION_NAME_NUM_FIELD_SOURCE});
176 case PROP_OPT_DEFAULT_BUDGET:
177 qof_instance_get_path_kvp (QOF_INSTANCE (book), value, {str_KVP_OPTION_PATH,
178 str_OPTION_SECTION_BUDGETING, str_OPTION_NAME_DEFAULT_BUDGET});
180 case PROP_OPT_FY_END:
181 qof_instance_get_path_kvp (QOF_INSTANCE (book), value, {
"fy_end"});
184 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
190 qof_book_set_property (GObject *
object,
197 g_return_if_fail (QOF_IS_BOOK (
object));
198 book = QOF_BOOK (
object);
199 g_assert (qof_instance_get_editlevel(book));
203 case PROP_OPT_TRADING_ACCOUNTS:
204 qof_instance_set_path_kvp (QOF_INSTANCE (book), value, {str_KVP_OPTION_PATH,
205 str_OPTION_SECTION_ACCOUNTS, str_OPTION_NAME_TRADING_ACCOUNTS});
207 case PROP_OPT_AUTO_READONLY_DAYS:
208 qof_instance_set_path_kvp (QOF_INSTANCE (book), value, {str_KVP_OPTION_PATH,
209 str_OPTION_SECTION_ACCOUNTS, str_OPTION_NAME_AUTO_READONLY_DAYS});
211 case PROP_OPT_NUM_FIELD_SOURCE:
212 qof_instance_set_path_kvp (QOF_INSTANCE (book), value, {str_KVP_OPTION_PATH,
213 str_OPTION_SECTION_ACCOUNTS, str_OPTION_NAME_NUM_FIELD_SOURCE});
215 case PROP_OPT_DEFAULT_BUDGET:
216 qof_instance_set_path_kvp (QOF_INSTANCE (book), value, {str_KVP_OPTION_PATH,
217 str_OPTION_SECTION_BUDGETING, OPTION_NAME_DEFAULT_BUDGET});
219 case PROP_OPT_FY_END:
220 qof_instance_set_path_kvp (QOF_INSTANCE (book), value, {
"fy_end"});
223 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
229 qof_book_class_init (QofBookClass *klass)
231 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
232 gobject_class->dispose = qof_book_dispose;
233 gobject_class->finalize = qof_book_finalize;
234 gobject_class->get_property = qof_book_get_property;
235 gobject_class->set_property = qof_book_set_property;
237 g_object_class_install_property
239 PROP_OPT_TRADING_ACCOUNTS,
240 g_param_spec_string(
"trading-accts",
241 "Use Trading Accounts",
242 "Scheme true ('t') or nullptr. If 't', then the book " 243 "uses trading accounts for managing multiple-currency " 248 g_object_class_install_property
250 PROP_OPT_NUM_FIELD_SOURCE,
251 g_param_spec_string(PARAM_NAME_NUM_FIELD_SOURCE,
252 "Use Split-Action in the Num Field",
253 "Scheme true ('t') or nullptr. If 't', then the book " 254 "will put the split action value in the Num field.",
258 g_object_class_install_property
260 PROP_OPT_AUTO_READONLY_DAYS,
261 g_param_spec_double(
"autoreadonly-days",
262 "Transaction Auto-read-only Days",
263 "Prevent editing of transactions posted more than " 264 "this many days ago.",
270 g_object_class_install_property
272 PROP_OPT_DEFAULT_BUDGET,
273 g_param_spec_boxed(
"default-budget",
274 "Book Default Budget",
275 "The default Budget for this book.",
278 g_object_class_install_property
281 g_param_spec_boxed(
"fy-end",
282 "Book Fiscal Year End",
283 "A GDate with a bogus year having the last Month and " 284 "Day of the Fiscal year for the book.",
295 book =
static_cast<QofBook*
>(g_object_new(QOF_TYPE_BOOK,
nullptr));
299 LEAVE (
"book=%p", book);
304 book_final (gpointer key, gpointer value, gpointer booq)
306 QofBookFinalCB cb =
reinterpret_cast<QofBookFinalCB
>(value);
307 QofBook *book =
static_cast<QofBook*
>(booq);
309 gpointer user_data = g_hash_table_lookup (book->data_tables, key);
310 (*cb) (book, key, user_data);
314 qof_book_dispose_real (G_GNUC_UNUSED GObject *bookp)
319 qof_book_finalize_real (G_GNUC_UNUSED GObject *bookp)
324 destroy_lot(
QofInstance *inst, [[maybe_unused]]
void* data)
326 auto lot{GNC_LOT(inst)};
327 gnc_lot_destroy(lot);
336 ENTER (
"book=%p", book);
338 book->shutting_down = TRUE;
339 qof_event_force (&book->inst, QOF_EVENT_DESTROY,
nullptr);
344 g_hash_table_foreach (book->data_table_finalizers, book_final, book);
350 qof_collection_foreach(lots, destroy_lot,
nullptr);
351 qof_object_book_end (book);
353 g_hash_table_destroy (book->data_table_finalizers);
354 book->data_table_finalizers =
nullptr;
355 g_hash_table_destroy (book->data_tables);
356 book->data_tables =
nullptr;
365 cols = book->hash_of_collections;
366 g_object_unref (book);
367 g_hash_table_destroy (cols);
369 LEAVE (
"book=%p", book);
377 if (!book)
return FALSE;
387 book->dirty_time = 0;
388 if (book->session_dirty)
391 book->session_dirty = FALSE;
393 book->dirty_cb(book, FALSE, book->dirty_data);
400 if (!book->session_dirty)
403 book->session_dirty = TRUE;
404 book->dirty_time =
gnc_time (
nullptr);
406 book->dirty_cb(book, TRUE, book->dirty_data);
414 PINFO(
"book is dirty.");
415 qof_book_foreach_collection
422 return book->dirty_time;
428 g_return_if_fail(book);
430 PWARN(
"Already existing callback %p, will be overwritten by %p\n",
432 book->dirty_data = user_data;
442 if (!book)
return nullptr;
443 return book->backend;
449 if (!book)
return FALSE;
450 return book->shutting_down;
457 qof_book_set_backend (QofBook *book,
QofBackend *be)
460 ENTER (
"book=%p be=%p", book, be);
470 if (!book || !key)
return;
472 g_hash_table_insert (book->data_tables, (gpointer)CACHE_INSERT(key), data);
474 g_hash_table_remove(book->data_tables, key);
480 if (!book || !key)
return;
481 g_hash_table_insert (book->data_tables, (gpointer)key, data);
484 g_hash_table_insert (book->data_table_finalizers, (gpointer)key,
485 reinterpret_cast<void*>(cb));
491 if (!book || !key)
return nullptr;
492 return g_hash_table_lookup (book->data_tables, (gpointer)key);
499 g_return_val_if_fail( book !=
nullptr, TRUE );
500 return book->read_only;
506 g_return_if_fail( book !=
nullptr );
507 book->read_only = TRUE;
513 if (!book)
return TRUE;
525 if (!book || !entity_type)
return nullptr;
527 col =
static_cast<QofCollection*
>(g_hash_table_lookup (book->hash_of_collections, entity_type));
532 book->hash_of_collections,
545 foreach_cb (G_GNUC_UNUSED gpointer key, gpointer item, gpointer arg)
548 QofCollection *col =
static_cast<QofCollection*
>(item);
550 iter->fn (col, iter->data);
554 qof_book_foreach_collection (
const QofBook *book,
559 g_return_if_fail (book);
560 g_return_if_fail (cb);
563 iter.data = user_data;
565 g_hash_table_foreach (book->hash_of_collections, foreach_cb, &iter);
576 book->book_open =
'n';
587 PWARN (
"No book!!!");
591 if (!counter_name || *counter_name ==
'\0')
593 PWARN (
"Invalid counter name.");
598 kvp = qof_instance_get_slots (QOF_INSTANCE (book));
602 PWARN (
"Book has no KVP_Frame");
606 value = kvp->get_slot({
"counters", counter_name});
609 auto int_value{value->get<int64_t>()};
614 int_value =
static_cast<int64_t
>(value->get<
double>());
635 PWARN (
"No book!!!");
639 if (!counter_name || *counter_name ==
'\0')
641 PWARN (
"Invalid counter name.");
656 kvp = qof_instance_get_slots (QOF_INSTANCE (book));
660 PWARN (
"Book has no KVP_Frame");
665 qof_book_begin_edit(book);
666 value =
new KvpValue(counter);
667 delete kvp->set_path({
"counters", counter_name}, value);
668 qof_instance_set_dirty (QOF_INSTANCE (book));
669 qof_book_commit_edit(book);
675 PWARN(
"Cannot get format for counter");
680 result = g_strdup_printf(format, counter);
689 const char *user_format =
nullptr;
690 gchar *norm_format =
nullptr;
692 gchar *error =
nullptr;
696 PWARN (
"No book!!!");
700 if (!counter_name || *counter_name ==
'\0')
702 PWARN (
"Invalid counter name.");
707 kvp = qof_instance_get_slots (QOF_INSTANCE (book));
711 PWARN (
"Book has no KVP_Frame");
716 value = kvp->get_slot({
"counter_formats", counter_name});
719 user_format = value->get<
const char*>();
723 PWARN(
"Invalid counter format string. Format string: '%s' Counter: '%s' Error: '%s')", user_format, counter_name, error);
725 user_format =
nullptr;
735 norm_format = g_strdup (
"%.6" PRIi64);
743 const gchar *valid_formats [] = {
752 gchar *normalized_spec =
nullptr;
754 while (valid_formats[i])
757 if (err_msg && *err_msg)
765 return normalized_spec;
774 const gchar *gint64_format, gchar **err_msg)
776 const gchar *conv_start, *base, *tmp =
nullptr;
777 gchar *normalized_str =
nullptr, *aux_str =
nullptr;
790 if (p[0] ==
'%' && p[1] ==
'%')
806 *err_msg = g_strdup(
"Format string ended without any conversion specification");
818 tmp = strstr(p, gint64_format);
823 *err_msg = g_strdup_printf(
"Format string doesn't contain requested format specifier: %s", gint64_format);
828 while (*p && (tmp != p) && strchr(
"#0- +'I", *p))
831 tmp = strstr(p, gint64_format);
836 while (*p && (tmp != p) && strchr(
"0123456789.", *p))
839 tmp = strstr(p, gint64_format);
845 *err_msg = g_strdup_printf(
"Format string ended during the conversion specification. Conversion seen so far: %s", conv_start);
851 tmp = strstr(p, gint64_format);
855 *err_msg = g_strdup_printf(
"Invalid length modifier and/or conversion specifier ('%.4s'), it should be: %s", p, gint64_format);
861 *err_msg = g_strdup_printf(
"Garbage before length modifier and/or conversion specifier: '%*s'", (
int)(tmp - p), p);
866 aux_str = g_strndup (base, p - base);
867 normalized_str = g_strconcat (aux_str, PRIi64,
nullptr);
871 p += strlen(gint64_format);
879 if (p[0] ==
'%' && p[1] ==
'%')
889 *err_msg = g_strdup_printf(
"Format string contains unescaped %% signs (or multiple conversion specifications) at '%s'", p);
890 g_free (normalized_str);
898 aux_str = normalized_str;
899 normalized_str = g_strconcat (aux_str, tmp,
nullptr);
904 return normalized_str;
913 auto retval = (opt && opt[0] ==
't' && opt[1] == 0);
923 g_return_val_if_fail (book, FALSE);
924 if (!book->cached_num_field_source_isvalid)
930 PARAM_NAME_NUM_FIELD_SOURCE, &opt,
933 if (opt && opt[0] ==
't' && opt[1] == 0)
942 const_cast<QofBook*
>(book)->cached_num_field_source = result;
943 const_cast<QofBook*
>(book)->cached_num_field_source_isvalid = TRUE;
946 return book->cached_num_field_source;
953 qof_book_option_num_field_source_changed_cb (GObject *gobject,
957 QofBook *book =
reinterpret_cast<QofBook*
>(user_data);
958 g_return_if_fail(QOF_IS_BOOK(book));
959 book->cached_num_field_source_isvalid = FALSE;
972 if (!book->cached_num_days_autoreadonly_isvalid)
978 PARAM_NAME_NUM_AUTOREAD_ONLY, &tmp,
981 const_cast<QofBook*
>(book)->cached_num_days_autoreadonly = tmp;
982 const_cast<QofBook*
>(book)->cached_num_days_autoreadonly_isvalid = TRUE;
985 return (gint) book->cached_num_days_autoreadonly;
991 GDate* result =
nullptr;
998 g_date_subtract_days(result, num_days);
1007 qof_book_option_num_autoreadonly_changed_cb (GObject *gobject,
1011 QofBook *book =
reinterpret_cast<QofBook*
>(user_data);
1012 g_return_if_fail(QOF_IS_BOOK(book));
1013 book->cached_num_days_autoreadonly_isvalid = FALSE;
1017 get_option_default_invoice_report_value (QofBook *book)
1019 KvpFrame *root = qof_instance_get_slots (QOF_INSTANCE(book));
1020 return root->get_slot ({KVP_OPTION_PATH,
1021 OPTION_SECTION_BUSINESS,
1022 OPTION_NAME_DEFAULT_INVOICE_REPORT});
1029 const gchar *existing_guid_name =
nullptr;
1030 gchar *new_guid_name;
1034 PWARN (
"No book!!!");
1040 PWARN (
"No guid!!!");
1046 PWARN (
"No name!!!");
1050 KvpValue *value = get_option_default_invoice_report_value (book);
1053 existing_guid_name = {value->get<
const char*>()};
1055 new_guid_name = g_strconcat (guid,
"/", name,
nullptr);
1057 if (g_strcmp0 (existing_guid_name, new_guid_name) != 0)
1059 auto value =
new KvpValue {g_strdup(new_guid_name)};
1060 KvpFrame *root = qof_instance_get_slots (QOF_INSTANCE(book));
1061 qof_book_begin_edit (book);
1062 delete root->set_path ({KVP_OPTION_PATH,
1063 OPTION_SECTION_BUSINESS,
1064 OPTION_NAME_DEFAULT_INVOICE_REPORT}, value);
1065 qof_instance_set_dirty (QOF_INSTANCE(book));
1066 qof_book_commit_edit (book);
1068 g_free (new_guid_name);
1074 gchar *report_guid =
nullptr;
1078 PWARN (
"No book!!!");
1082 KvpValue *value = get_option_default_invoice_report_value (const_cast<QofBook*>(book));
1086 auto str {value->get<
const char*>()};
1087 auto ptr = strchr (str,
'/');
1103 gchar *report_name =
nullptr;
1107 PWARN (
"No book!!!");
1111 KvpValue *value = get_option_default_invoice_report_value (const_cast<QofBook*>(book));
1115 auto str {value->get<
const char*>()};
1116 auto ptr = strchr (str,
'/');
1124 report_name = g_strdup (
"");
1138 PWARN (
"No book!!!");
1142 KvpFrame *root = qof_instance_get_slots (QOF_INSTANCE(book));
1143 KvpValue *value = root->get_slot ({KVP_OPTION_PATH,
1144 OPTION_SECTION_BUSINESS,
1145 OPTION_NAME_DEFAULT_INVOICE_REPORT_TIMEOUT});
1148 ret = {value->get<
double>()};
1155 static Path opt_name_to_path (
const char* opt_name)
1158 g_return_val_if_fail (opt_name, result);
1159 auto opt_name_list = g_strsplit(opt_name,
"/", -1);
1160 for (
int i=0; opt_name_list[i]; i++)
1161 result.push_back (opt_name_list[i]);
1162 g_strfreev (opt_name_list);
1167 qof_book_get_string_option(
const QofBook* book,
const char* opt_name)
1169 auto slot = qof_instance_get_slots(QOF_INSTANCE (book))->get_slot(opt_name_to_path(opt_name));
1170 if (slot ==
nullptr)
1172 return slot->get<
const char*>();
1176 qof_book_set_string_option(QofBook* book,
const char* opt_name,
const char* opt_val)
1178 qof_book_begin_edit(book);
1179 auto frame = qof_instance_get_slots(QOF_INSTANCE(book));
1180 auto opt_path = opt_name_to_path(opt_name);
1181 if (opt_val && (*opt_val !=
'\0'))
1182 delete frame->set_path(opt_path,
new KvpValue(g_strdup(opt_val)));
1184 delete frame->set_path(opt_path,
nullptr);
1185 qof_instance_set_dirty (QOF_INSTANCE (book));
1186 qof_book_commit_edit(book);
1190 qof_book_get_guid_option(QofBook* book, GSList* path)
1192 g_return_val_if_fail(book !=
nullptr,
nullptr);
1193 g_return_val_if_fail(path !=
nullptr,
nullptr);
1198 return table_value->get<
GncGUID*>();
1202 qof_book_option_frame_delete (QofBook *book,
const char* opt_name)
1204 if (opt_name && (*opt_name !=
'\0'))
1206 qof_book_begin_edit(book);
1207 auto frame = qof_instance_get_slots(QOF_INSTANCE(book));
1208 auto opt_path = opt_name_to_path(opt_name);
1209 delete frame->set_path(opt_path,
nullptr);
1210 qof_instance_set_dirty (QOF_INSTANCE (book));
1211 qof_book_commit_edit(book);
1216 qof_book_begin_edit (QofBook *book)
1223 PERR (
"Failed to commit: %d", errcode);
1227 #define GNC_FEATURES "features" 1229 add_feature_to_hash (
const gchar *key, KvpValue *value, GHashTable * user_data)
1231 gchar *descr = g_strdup(value->get<
const char*>());
1232 g_hash_table_insert (user_data, (gchar*)key, descr);
1238 KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
1239 GHashTable *features = g_hash_table_new_full (g_str_hash, g_str_equal,
1242 PWARN (
"qof_book_get_features is now deprecated.");
1244 auto slot = frame->get_slot({GNC_FEATURES});
1245 if (slot !=
nullptr)
1247 frame = slot->get<KvpFrame*>();
1248 frame->for_each_slot_temp(&add_feature_to_hash, features);
1254 qof_book_set_feature (QofBook *book,
const gchar *key,
const gchar *descr)
1256 KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
1257 KvpValue* feature =
nullptr;
1258 auto feature_slot = frame->get_slot({GNC_FEATURES});
1261 auto feature_frame = feature_slot->get<KvpFrame*>();
1262 feature = feature_frame->get_slot({key});
1264 if (feature ==
nullptr || g_strcmp0 (feature->get<
const char*>(), descr))
1266 qof_book_begin_edit (book);
1267 delete frame->set_path({GNC_FEATURES, key},
new KvpValue(g_strdup (descr)));
1268 qof_instance_set_dirty (QOF_INSTANCE (book));
1269 qof_book_commit_edit (book);
1274 qof_book_get_unknown_features (QofBook *book,
const FeaturesTable& features)
1277 auto test_feature = [&](
const KvpFrameImpl::map_type::value_type& feature)
1279 if (features.find (feature.first) == features.end ())
1280 rv.emplace_back (feature.first, feature.second->get<
const char*>());
1282 auto frame = qof_instance_get_slots (QOF_INSTANCE (book));
1283 auto slot = frame->get_slot({GNC_FEATURES});
1284 if (slot !=
nullptr)
1286 frame = slot->get<KvpFrame*>();
1287 std::for_each (frame->begin (), frame->end (), test_feature);
1293 qof_book_test_feature (QofBook *book,
const char *feature)
1295 auto frame = qof_instance_get_slots (QOF_INSTANCE (book));
1296 return (frame->get_slot({GNC_FEATURES, feature}) !=
nullptr);
1300 qof_book_unset_feature (QofBook *book,
const gchar *key)
1302 KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (book));
1303 auto feature_slot = frame->get_slot({GNC_FEATURES, key});
1306 PWARN (
"no feature %s. bail out.", key);
1309 qof_book_begin_edit (book);
1310 delete frame->set_path({GNC_FEATURES, key},
nullptr);
1311 qof_instance_set_dirty (QOF_INSTANCE (book));
1312 qof_book_commit_edit (book);
1318 load_cb (odb, book);
1329 qof_book_begin_edit (book);
1330 save_cb (odb, book, clear);
1331 qof_book_commit_edit (book);
1337 qof_book_commit_edit(QofBook *book)
1345 static Path gslist_to_option_path (GSList *gspath)
1348 if (!gspath)
return tmp_path;
1350 Path path_v {str_KVP_OPTION_PATH};
1351 for (
auto item = gspath; item !=
nullptr; item = g_slist_next(item))
1352 tmp_path.push_back(static_cast<const char*>(item->data));
1353 if ((tmp_path.front() ==
"counters") || (tmp_path.front() ==
"counter_formats"))
1356 path_v.insert(path_v.end(), tmp_path.begin(), tmp_path.end());
1363 KvpFrame *root = qof_instance_get_slots (QOF_INSTANCE (book));
1364 qof_book_begin_edit (book);
1365 delete root->set_path(gslist_to_option_path(path), value);
1366 qof_instance_set_dirty (QOF_INSTANCE (book));
1367 qof_book_commit_edit (book);
1370 book->cached_num_field_source_isvalid = FALSE;
1376 KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book));
1377 return root->get_slot(gslist_to_option_path(path));
1383 KvpFrame *root = qof_instance_get_slots(QOF_INSTANCE (book));
1384 if (path !=
nullptr)
1386 Path path_v {str_KVP_OPTION_PATH};
1388 for (
auto item = path; item !=
nullptr; item = g_slist_next(item))
1389 tmp_path.push_back(static_cast<const char*>(item->data));
1390 delete root->set_path(gslist_to_option_path(path),
nullptr);
1393 delete root->set_path({str_KVP_OPTION_PATH},
nullptr);
1399 static QofParam params[] =
Holds all of the options for a book, report, or stylesheet, organized by GncOptionSections.
This is the private header for the account structure.
API for data storage Backend.
void qof_book_load_options(QofBook *book, GncOptionLoad load_cb, GncOptionDB *odb)
Load a GncOptionsDB from KVP data.
void qof_instance_get(const QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_get.
void qof_book_set_dirty_cb(QofBook *book, QofBookDirtyCB cb, gpointer user_data)
Set the function to call when a book transitions from clean to dirty, or vice versa.
KvpValue * qof_book_get_option(QofBook *book, GSList *path)
Read a single option value.
void(* QofCollectionForeachCB)(QofCollection *, gpointer user_data)
Invoke the indicated callback on each collection in the book.
gboolean qof_book_register(void)
Register the book object with the QOF object system.
#define PINFO(format, args...)
Print an informational note.
void qof_object_book_begin(QofBook *book)
To be called from within the book.
QofBackendError
The errors that can be reported to the GUI & other front-end users.
time64 qof_book_get_session_dirty_time(const QofBook *book)
Retrieve the earliest modification time on the book.
gdouble qof_book_get_default_invoice_report_timeout(const QofBook *book)
Get the length of time available to change the used Invoice Report when printing Invoices.
gchar * qof_book_increment_and_format_counter(QofBook *book, const char *counter_name)
This will increment the named counter for this book and format it.
gint qof_book_get_num_days_autoreadonly(const QofBook *book)
Returns the number of days for auto-read-only transactions.
gboolean qof_book_use_split_action_for_num_field(const QofBook *book)
Returns TRUE if this book uses split action field as the 'Num' field, FALSE if it uses transaction nu...
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
This function registers a new object class with the Qof subsystem.
QofBook * qof_book_new(void)
Allocate, initialise and return a new QofBook.
void qof_book_mark_closed(QofBook *book)
Close a book to editing.
char * qof_book_get_counter_format(const QofBook *book, const char *counter_name)
Get the format string to use for the named counter.
void qof_book_mark_readonly(QofBook *book)
Mark the book as read only.
gboolean qof_commit_edit(QofInstance *inst)
commit_edit helpers
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
GHashTable * qof_book_get_features(QofBook *book)
Access functions for reading and setting the used-features on this book.
const char * qof_string_cache_insert(const char *key)
You can use this function with g_hash_table_insert(), for the key (or value), as long as you use the ...
the Core Object Registration/Lookup Private Interface
#define PWARN(format, args...)
Log a warning.
gint64 qof_book_get_counter(QofBook *book, const char *counter_name)
This will get the named counter for this book.
gboolean qof_book_empty(const QofBook *book)
Check if the book has had anything loaded into it.
const gchar * QofIdType
QofIdType declaration.
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
gboolean qof_begin_edit(QofInstance *inst)
begin_edit
void qof_book_save_options(QofBook *book, GncOptionSave save_cb, GncOptionDB *odb, gboolean clear)
Save a GncOptionsDB back to the book's KVP.
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
Returns the GDate that is the threshold for auto-read-only.
void qof_book_mark_session_saved(QofBook *book)
The qof_book_mark_saved() routine marks the book as having been saved (to a file, to a database)...
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
void qof_book_set_data_fin(QofBook *book, const gchar *key, gpointer data, QofBookFinalCB)
Same as qof_book_set_data(), except that the callback will be called when the book is destroyed...
void qof_book_set_data(QofBook *book, const gchar *key, gpointer data)
The qof_book_set_data() allows arbitrary pointers to structs to be stored in QofBook.
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
part2 – deal with the backend
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
gchar * qof_book_normalize_counter_format(const gchar *p, gchar **err_msg)
Validate a counter format string.
gchar * qof_book_normalize_counter_format_internal(const gchar *p, const gchar *gint64_format, gchar **err_msg)
Validate a counter format string with a given format specifier.
gboolean qof_book_session_not_saved(const QofBook *book)
qof_book_not_saved() returns the value of the session_dirty flag, set when changes to any object in t...
const GncGUID * qof_entity_get_guid(gconstpointer ent)
#define QOF_PARAM_KVP
"Known" Object Parameters – some objects might support these
void qof_collection_destroy(QofCollection *col)
destroy the collection
void qof_book_mark_session_dirty(QofBook *book)
The qof_book_mark_dirty() routine marks the book as having been modified.
void qof_book_set_default_invoice_report(QofBook *book, const gchar *guid, const gchar *name)
Save the Invoice Report name / guid to be used as the default for printing Invoices.
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
gchar * qof_book_get_default_invoice_report_name(const QofBook *book)
Get the name of the Invoice Report to be used as the default for printing Invoices.
void qof_book_print_dirty(const QofBook *book)
This debugging function can be used to traverse the book structure and all subsidiary structures...
#define LEAVE(format, args...)
Print a function exit debugging message.
QOF String cache functions.
time64 gnc_time(time64 *tbuf)
get the current time
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
gpointer qof_collection_get_data(const QofCollection *col)
Store and retrieve arbitrary object-defined data.
void qof_book_set_option(QofBook *book, KvpValue *value, GSList *path)
Save a single option value.
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Returns TRUE if the auto-read-only feature should be used, otherwise FALSE.
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
gboolean qof_book_shutting_down(const QofBook *book)
Is the book shutting down?
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
void qof_book_options_delete(QofBook *book, GSList *path)
Delete the options.
gchar * qof_book_get_default_invoice_report_guid(const QofBook *book)
Get the guid of the Invoice Report to be used as the default for printing Invoices.
The type used to store guids in C.
gpointer qof_book_get_data(const QofBook *book, const gchar *key)
Retrieves arbitrary pointers to structs stored by qof_book_set_data.
gboolean qof_book_use_trading_accounts(const QofBook *book)
Returns flag indicating whether this book uses trading accounts.
void qof_string_cache_remove(const char *key)
You can use this function as a destroy notifier for a GHashTable that uses common strings as keys (or...
void qof_book_destroy(QofBook *book)
End any editing sessions associated with book, and free all memory associated with it...
QofCollection * qof_collection_new(QofIdType type)
create a new collection of entities of type
GDate * gnc_g_date_new_today()
Returns a newly allocated date of the current clock time, taken from time(2).