diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/administration.cpp | 3 | ||||
| -rw-r--r-- | src/administration_writer.cpp | 348 | ||||
| -rw-r--r-- | src/main.cpp | 3 | ||||
| -rw-r--r-- | src/ui/ui_contacts.cpp | 30 | ||||
| -rw-r--r-- | src/ui/ui_projects.cpp | 19 | ||||
| -rw-r--r-- | src/ui/ui_settings.cpp | 14 |
6 files changed, 284 insertions, 133 deletions
diff --git a/src/administration.cpp b/src/administration.cpp index b3e30fa..21b70f3 100644 --- a/src/administration.cpp +++ b/src/administration.cpp @@ -388,13 +388,14 @@ void administration_create() list_init(&g_administration.tax_brackets); list_init(&g_administration.cost_centers); strops_copy(g_administration.path, "", sizeof(g_administration.path)); + strops_copy(g_administration.program_version, PROGRAM_VERSION, sizeof(g_administration.program_version)); administration_create_default_tax_brackets(); administration_create_default_cost_centers(); administration_create_debug_data(); - administration_writer_save_all(); + administration_writer_save_all_async(); } static void administration_destroy_list(list_t *list) diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp index 86b3ee2..00543af 100644 --- a/src/administration_writer.cpp +++ b/src/administration_writer.cpp @@ -8,24 +8,55 @@ #include "ui.hpp" #include "administration_writer.hpp" -static bool administration_writer_write_to_zip(char* entry_to_replace, char* orig_content, int final_length) +mtx_t _save_file_mutex; + +bool administration_writer_create() { - bool result = true; - bool entry_exists = false; + return mtx_init(&_save_file_mutex, mtx_plain) == thrd_success; +} + +void administration_writer_destroy() +{ + mtx_destroy(&_save_file_mutex); +} - // Check if entry exists already. +static bool administration_writer_entry_exists(char* entry) +{ + bool entry_exists = false; struct zip_t *zip_read = zip_open(administration_file_path_get(), 0, 'r'); int i, n = (int)zip_entries_total(zip_read); for (i = 0; i < n; ++i) { zip_entry_openbyindex(zip_read, i); const char *entry_name = zip_entry_name(zip_read); - if (strcmp(entry_name, entry_to_replace) == 0) { + if (strcmp(entry_name, entry) == 0) { entry_exists = true; break; } zip_entry_close(zip_read); } zip_close(zip_read); + return entry_exists; +} + +bool administration_writer_delete_entry(char* id) +{ + bool result = 1; + struct zip_t *zip_write = zip_open(administration_file_path_get(), 0, 'a'); + if (!zip_write) zip_write = zip_open(administration_file_path_get(), 0, 'w'); + + char final_path[50]; + snprintf(final_path, 50, "%s.xml", id); + + char* indices[1] = {final_path}; + if (zip_entries_delete(zip_write, indices, 1) < 0) result = 0; + zip_close(zip_write); + return result; +} + +static bool administration_writer_write_to_zip(char* entry_to_replace, char* orig_content, int final_length) +{ + bool result = 1; + bool entry_exists = administration_writer_entry_exists(entry_to_replace); struct zip_t *zip_write = zip_open(administration_file_path_get(), 0, 'a'); if (!zip_write) zip_write = zip_open(administration_file_path_get(), 0, 'w'); @@ -34,13 +65,13 @@ static bool administration_writer_write_to_zip(char* entry_to_replace, char* ori { char* indices[1] = {entry_to_replace}; zip_entries_delete(zip_write, indices, 1); - zip_close(zip_write); // Need to close to flush removed entry. + zip_close(zip_write); zip_write = zip_open(administration_file_path_get(), 0, 'a'); } zip_entry_open(zip_write, entry_to_replace); - if (zip_entry_write(zip_write, orig_content, final_length) < 0) result = false; + if (zip_entry_write(zip_write, orig_content, final_length) < 0) result = 0; zip_entry_close(zip_write); zip_close(zip_write); @@ -48,55 +79,133 @@ static bool administration_writer_write_to_zip(char* entry_to_replace, char* ori return result; } -bool administration_writer_save_all_cost_centers() +///////////////////////////// +//// Projects +///////////////////////////// +bool administration_writer_save_project_blocking(project project) { - //// Get all data. - u32 num_costcenters = administration_cost_center_count(); - u32 buffer_size = sizeof(cost_center) * num_costcenters; - cost_center* costcenter_buffer = (cost_center*)malloc(buffer_size); - num_costcenters = administration_cost_center_get_all(costcenter_buffer); - - int buf_length = num_costcenters * 500; // Ballpark file content size. - char* settings_content = (char*)malloc(buf_length); - memset(settings_content, 0, buf_length); + bool result = 1; + int buf_length = 1000; // Ballpark file content size. + char* file_content = (char*)malloc(buf_length); + memset(file_content, 0, buf_length); - char* orig_content = settings_content; + char* orig_content = file_content; - //// Cost centers. - settings_content += sprintf(settings_content, "<cost_centers>\n"); + file_content += sprintf(file_content, "<project>\n"); + file_content += sprintf(file_content, "\t<id>%s</id>\n", project.id); + file_content += sprintf(file_content, "\t<description>%s</description>\n", project.description); + file_content += sprintf(file_content, "\t<state>%d</state>\n", project.state); + file_content += sprintf(file_content, "\t<start_date>%lld</start_date>\n", (long long)project.start_date); + file_content += sprintf(file_content, "\t<end_date>%lld</end_date>\n", (long long)project.end_date); + file_content += sprintf(file_content, "</project>\n"); - for (u32 i = 0; i < num_costcenters; i++) { - cost_center c = costcenter_buffer[i]; - - settings_content += sprintf(settings_content, "\t<cost_center>\n"); + //// Write to Disk. + char final_path[50]; + snprintf(final_path, 50, "%s.xml", project.id); + + int final_length = (int)strlen(orig_content); + if (!xml_parse_document((uint8_t*)orig_content, final_length)) result = 0; + else if (!administration_writer_write_to_zip(final_path, orig_content, final_length)) result = 0; - settings_content += sprintf(settings_content, "\t\t<id>%s</id>\n", c.id); - settings_content += sprintf(settings_content, "\t\t<code>%s</code>\n", c.code); - settings_content += sprintf(settings_content, "\t\t<description>%s</description>\n", c.description); + free(orig_content); + return result; +} - settings_content += sprintf(settings_content, "\t</cost_center>\n"); +static bool administration_writer_save_all_projects_blocking() +{ + bool result = 1; + u32 num_projects = administration_project_count(); + u32 buffer_size = sizeof(project) * num_projects; + project* project_buffer = (project*)malloc(buffer_size); + num_projects = administration_project_get_all(project_buffer); + + for (u32 i = 0; i < num_projects; i++) { + project c = project_buffer[i]; + if (!administration_writer_save_project_blocking(c)) result = 0; } + + free(project_buffer); + return result; +} - settings_content += sprintf(settings_content, "</cost_centers>"); +///////////////////////////// +//// Cost centers +///////////////////////////// +bool administration_writer_save_cost_center_blocking(cost_center cost) +{ + bool result = 1; + int buf_length = 1000; // Ballpark file content size. + char* file_content = (char*)malloc(buf_length); + memset(file_content, 0, buf_length); + + char* orig_content = file_content; + + file_content += sprintf(file_content, "<cost_center>\n"); + file_content += sprintf(file_content, "\t<id>%s</id>\n", cost.id); + file_content += sprintf(file_content, "\t<code>%s</code>\n", cost.code); + file_content += sprintf(file_content, "\t<description>%s</description>\n", cost.description); + file_content += sprintf(file_content, "</cost_center>\n"); //// Write to Disk. + char final_path[50]; + snprintf(final_path, 50, "%s.xml", cost.id); + int final_length = (int)strlen(orig_content); - bool result = true; + if (!xml_parse_document((uint8_t*)orig_content, final_length)) result = 0; + else if (!administration_writer_write_to_zip(final_path, orig_content, final_length)) result = 0; - if (!xml_parse_document((uint8_t*)orig_content, final_length)) { - result = false; - } - else { - administration_writer_write_to_zip(ADMIN_FILE_COSTCENTERS, orig_content, final_length); - } + free(orig_content); + return result; +} +static bool administration_writer_save_all_cost_centers_blocking() +{ + bool result = 1; + u32 num_costcenters = administration_cost_center_count(); + u32 buffer_size = sizeof(cost_center) * num_costcenters; + cost_center* costcenter_buffer = (cost_center*)malloc(buffer_size); + num_costcenters = administration_cost_center_get_all(costcenter_buffer); + + for (u32 i = 0; i < num_costcenters; i++) { + cost_center c = costcenter_buffer[i]; + if (!administration_writer_save_cost_center_blocking(c)) result = 0; + } + free(costcenter_buffer); - free(orig_content); + return result; +} + +///////////////////////////// +//// Tax brackets +///////////////////////////// +bool administration_writer_save_tax_bracket_blocking(country_tax_bracket bracket) +{ + bool result = 1; + int buf_length = 1000; // Ballpark file content size. + char* file_content = (char*)malloc(buf_length); + memset(file_content, 0, buf_length); + char* orig_content = file_content; + + file_content += sprintf(file_content, "<country_tax_bracket>\n"); + file_content += sprintf(file_content, "\t<id>%s</id>\n", bracket.id); + file_content += sprintf(file_content, "\t<country_code>%s</country_code>\n", bracket.country_code); + file_content += sprintf(file_content, "\t<rate>%.2f</rate>\n", bracket.rate); + file_content += sprintf(file_content, "\t<description>%s</description>\n", bracket.description); + file_content += sprintf(file_content, "</country_tax_bracket>\n"); + + //// Write to Disk. + char final_path[50]; + snprintf(final_path, 50, "%s.xml", bracket.id); + + int final_length = (int)strlen(orig_content); + if (!xml_parse_document((uint8_t*)orig_content, final_length)) result = 0; + else if (!administration_writer_write_to_zip(final_path, orig_content, final_length)) result = 0; + free(orig_content); return result; } -bool administration_writer_save_all_tax_brackets() +static bool administration_writer_save_all_tax_brackets_blocking() { //// Get all data. u32 num_brackets = administration_tax_bracket_count(); @@ -104,96 +213,60 @@ bool administration_writer_save_all_tax_brackets() country_tax_bracket* bracket_buffer = (country_tax_bracket*)malloc(buffer_size); num_brackets = administration_tax_bracket_get_all(bracket_buffer); - int buf_length = num_brackets * 500; // Ballpark file content size. - char* settings_content = (char*)malloc(buf_length); - memset(settings_content, 0, buf_length); - - char* orig_content = settings_content; - - //// Tax brackets. - settings_content += sprintf(settings_content, "<country_tax_brackets>\n"); + bool result = 1; for (u32 i = 0; i < num_brackets; i++) { country_tax_bracket c = bracket_buffer[i]; - - settings_content += sprintf(settings_content, "\t<country_tax_bracket>\n"); - - settings_content += sprintf(settings_content, "\t\t<id>%s</id>\n", c.id); - settings_content += sprintf(settings_content, "\t\t<country_code>%s</country_code>\n", c.country_code); - settings_content += sprintf(settings_content, "\t\t<rate>%.2f</rate>\n", c.rate); - settings_content += sprintf(settings_content, "\t\t<description>%s</description>\n", c.description); - - settings_content += sprintf(settings_content, "\t</country_tax_bracket>\n"); - } - - settings_content += sprintf(settings_content, "</country_tax_brackets>"); - - //// Write to Disk. - int final_length = (int)strlen(orig_content); - bool result = true; - - if (!xml_parse_document((uint8_t*)orig_content, final_length)) { - result = false; - } - else { - administration_writer_write_to_zip(ADMIN_FILE_BRACKETS, orig_content, final_length); + if (!administration_writer_save_tax_bracket_blocking(c)) result = 0; } free(bracket_buffer); - free(orig_content); - return result; } -bool administration_writer_save_contact(contact c, char* content_buffer = NULL) +///////////////////////////// +//// Contacts +///////////////////////////// +bool administration_writer_save_contact_blocking(contact c) { - bool result = true; - bool do_free = false; - if (!content_buffer) { - int buf_length = 2000; // Ballpark contact content size. - content_buffer = (char*)malloc(buf_length); - memset(content_buffer, 0, buf_length); - do_free = true; - } + bool result = 1; + int buf_length = 2000; // Ballpark contact content size. + char* file_content = (char*)malloc(buf_length); + memset(file_content, 0, buf_length); - char* orig_content = content_buffer; + char* orig_content = file_content; - content_buffer += sprintf(content_buffer, "<contact>\n"); + file_content += sprintf(file_content, "<contact>\n"); - content_buffer += sprintf(content_buffer, "\t<id>%s</id>\n", c.id); - content_buffer += sprintf(content_buffer, "\t<name>%s</name>\n", c.name); - content_buffer += sprintf(content_buffer, "\t<type>%d</type>\n", c.type); - content_buffer += sprintf(content_buffer, "\t<taxid>%s</taxid>\n", c.taxid); - content_buffer += sprintf(content_buffer, "\t<businessid>%s</businessid>\n", c.businessid); - content_buffer += sprintf(content_buffer, "\t<email>%s</email>\n", c.email); - content_buffer += sprintf(content_buffer, "\t<phone_number>%s</phone_number>\n", c.phone_number); - content_buffer += sprintf(content_buffer, "\t<bank_account>%s</bank_account>\n", c.bank_account); + file_content += sprintf(file_content, "\t<id>%s</id>\n", c.id); + file_content += sprintf(file_content, "\t<name>%s</name>\n", c.name); + file_content += sprintf(file_content, "\t<type>%d</type>\n", c.type); + file_content += sprintf(file_content, "\t<taxid>%s</taxid>\n", c.taxid); + file_content += sprintf(file_content, "\t<businessid>%s</businessid>\n", c.businessid); + file_content += sprintf(file_content, "\t<email>%s</email>\n", c.email); + file_content += sprintf(file_content, "\t<phone_number>%s</phone_number>\n", c.phone_number); + file_content += sprintf(file_content, "\t<bank_account>%s</bank_account>\n", c.bank_account); - content_buffer += sprintf(content_buffer, "\t<address>\n"); - content_buffer += sprintf(content_buffer, "\t\t<address1>%s</address1>\n", c.address.address1); - content_buffer += sprintf(content_buffer, "\t\t<address2>%s</address2>\n", c.address.address2); - content_buffer += sprintf(content_buffer, "\t\t<country_code>%s</country_code>\n", c.address.country_code); - content_buffer += sprintf(content_buffer, "\t</address>\n"); + file_content += sprintf(file_content, "\t<address>\n"); + file_content += sprintf(file_content, "\t\t<address1>%s</address1>\n", c.address.address1); + file_content += sprintf(file_content, "\t\t<address2>%s</address2>\n", c.address.address2); + file_content += sprintf(file_content, "\t\t<country_code>%s</country_code>\n", c.address.country_code); + file_content += sprintf(file_content, "\t</address>\n"); - content_buffer += sprintf(content_buffer, "</contact>\n"); + file_content += sprintf(file_content, "</contact>\n"); char final_path[50]; snprintf(final_path, 50, "%s.xml", c.id); int final_length = (int)strlen(orig_content); - if (!xml_parse_document((uint8_t*)orig_content, final_length)) { - result = false; - } - else { - administration_writer_write_to_zip(final_path, orig_content, final_length); - } + if (!xml_parse_document((uint8_t*)orig_content, final_length)) result = 0; + else if (!administration_writer_write_to_zip(final_path, orig_content, final_length)) result = 0; - if (do_free) free(content_buffer); + free(orig_content); return result; } - -bool administration_writer_save_all_contacts() +static bool administration_writer_save_all_contacts_blocking() { //// Get all data. u32 num_contacts = administration_contact_count(); @@ -201,42 +274,71 @@ bool administration_writer_save_all_contacts() contact* contact_buffer = (contact*)malloc(buffer_size); num_contacts = administration_contact_get_all(contact_buffer); + bool result = 1; - int buf_length = 2000; // Ballpark contact content size. - char* content_buffer = (char*)malloc(buf_length); - memset(content_buffer, 0, buf_length); - char* orig_content = content_buffer; - bool result = true; - - if (!administration_writer_save_contact(administration_company_info_get(), content_buffer)) result = false; + // Save company info. + if (!administration_writer_save_contact_blocking(administration_company_info_get())) result = 0; - // Contacts. + // Save contacts. for (u32 i = 0; i < num_contacts; i++) { - contact c = contact_buffer[i]; - - if (!administration_writer_save_contact(c, content_buffer)) result = false; - - content_buffer = orig_content; - memset(content_buffer, 0, buf_length); + contact c = ((contact*)contact_buffer)[i]; + if (!administration_writer_save_contact_blocking(c)) result = 0; } free(contact_buffer); + return result; +} + +///////////////////////////// +//// Administration info +///////////////////////////// +bool administration_writer_save_all_administration_info_blocking() +{ + bool result = 1; + int buf_length = 1000; // Ballpark file content size. + char* file_content = (char*)malloc(buf_length); + memset(file_content, 0, buf_length); + char* orig_content = file_content; + + //// Cost centers. + file_content += sprintf(file_content, "<administration>\n"); + file_content += sprintf(file_content, "\t<next_id>%d</next_id>\n", administation_get()->next_id); + file_content += sprintf(file_content, "\t<next_sequence_number>%d</next_sequence_number>\n", administation_get()->next_sequence_number); + file_content += sprintf(file_content, "\t<program_version>%s</program_version>\n", administation_get()->program_version); + file_content += sprintf(file_content, "</administration>"); + + //// Write to Disk. + int final_length = (int)strlen(orig_content); + if (!xml_parse_document((uint8_t*)orig_content, final_length)) result = 0; + else if (!administration_writer_write_to_zip(ADMIN_FILE_INFO, orig_content, final_length)) result = 0; + free(orig_content); return result; } +///////////////////////////// +//// Other +///////////////////////////// static int administration_writer_write_all_t(void *arg) { + (void)arg; int result = 1; - if (!administration_writer_save_all_tax_brackets()) result = 0; - if (!administration_writer_save_all_cost_centers()) result = 0; - if (!administration_writer_save_all_contacts()) result = 0; + + mtx_lock(&_save_file_mutex); + + if (!administration_writer_save_all_projects_blocking()) result = 0; + if (!administration_writer_save_all_administration_info_blocking()) result = 0; + if (!administration_writer_save_all_tax_brackets_blocking()) result = 0; + if (!administration_writer_save_all_cost_centers_blocking()) result = 0; + if (!administration_writer_save_all_contacts_blocking()) result = 0; + + mtx_unlock(&_save_file_mutex); ui_set_status_loading(false); - return result; // thread exit code + return result; } -bool administration_writer_save_all() +bool administration_writer_save_all_async() { ui_set_status_loading(true); diff --git a/src/main.cpp b/src/main.cpp index c1eb694..fc50c25 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,7 @@ #include "ui.hpp" #include "administration.hpp" +#include "administration_writer.hpp" // Data static ID3D11Device* g_pd3dDevice = nullptr; @@ -87,6 +88,7 @@ int main() ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + administration_writer_create(); administration_create(); // Main loop @@ -144,6 +146,7 @@ int main() } administration_destroy(); + administration_writer_destroy(); // Cleanup ImGui_ImplDX11_Shutdown(); diff --git a/src/ui/ui_contacts.cpp b/src/ui/ui_contacts.cpp index dbe6625..d680ae8 100644 --- a/src/ui/ui_contacts.cpp +++ b/src/ui/ui_contacts.cpp @@ -5,6 +5,7 @@ #include "ui.hpp" #include "imgui.h" #include "administration.hpp" +#include "administration_writer.hpp" #include "locales.hpp" static view_state current_view_state = view_state::LIST; @@ -259,7 +260,14 @@ static void draw_contact_list() ImGui::Separator(); if (ImGui::Button(localize("form.yes"), ImVec2(120, 0))) { - administration_contact_remove(selected_for_removal); + if (administration_contact_remove(selected_for_removal)) { + if (administration_writer_delete_entry(selected_for_removal.id)) { + ui_set_status(localize("status.saved")); + } + else { + ui_set_status_error(localize("status.saveFailed")); + } + } ImGui::CloseCurrentPopup(); } ImGui::SameLine(); @@ -286,7 +294,15 @@ static void ui_draw_contacts_create() // Save button ImGui::Spacing(); if (ImGui::Button(localize("form.save"))) { - administration_contact_add(active_contact); + if (administration_contact_add(active_contact)) { + if (administration_writer_save_contact_blocking(active_contact)) { + ui_set_status(localize("status.saved")); + } + else { + ui_set_status_error(localize("status.saveFailed")); + } + } + current_view_state = view_state::LIST; } if (!can_save) ImGui::EndDisabled(); @@ -305,7 +321,15 @@ static void ui_draw_contacts_update() // Save button ImGui::Spacing(); if (ImGui::Button(localize("form.save"))) { - administration_contact_update(active_contact); + if (administration_contact_update(active_contact)) { + if (administration_writer_save_contact_blocking(active_contact)) { + ui_set_status(localize("status.saved")); + } + else { + ui_set_status_error(localize("status.saveFailed")); + } + } + current_view_state = view_state::LIST; } if (!can_save) ImGui::EndDisabled(); diff --git a/src/ui/ui_projects.cpp b/src/ui/ui_projects.cpp index 8753a94..ca9b845 100644 --- a/src/ui/ui_projects.cpp +++ b/src/ui/ui_projects.cpp @@ -3,6 +3,7 @@ #include "ui.hpp" #include "imgui.h" #include "administration.hpp" +#include "administration_writer.hpp" #include "locales.hpp" static view_state current_view_state = view_state::LIST; @@ -51,11 +52,25 @@ static void draw_project_form() // Save button ImGui::Spacing(); if (ImGui::Button(localize("form.save"))) { - if (current_view_state == view_state::CREATE) + if (current_view_state == view_state::CREATE) { administration_project_add(active_project); + if (administration_writer_save_project_blocking(active_project)) { + ui_set_status(localize("status.saved")); + } + else { + ui_set_status_error(localize("status.saveFailed")); + } + } - else if (current_view_state == view_state::EDIT) + else if (current_view_state == view_state::EDIT) { administration_project_update(active_project); + if (administration_writer_save_project_blocking(active_project)) { + ui_set_status(localize("status.saved")); + } + else { + ui_set_status_error(localize("status.saveFailed")); + } + } current_view_state = view_state::LIST; selected_country = 0; diff --git a/src/ui/ui_settings.cpp b/src/ui/ui_settings.cpp index 75c4918..1d6a5f4 100644 --- a/src/ui/ui_settings.cpp +++ b/src/ui/ui_settings.cpp @@ -125,7 +125,7 @@ static void ui_draw_vat_rates() is_adding_item = false; administration_tax_bracket_update(new_tax_bracket); - if (administration_writer_save_all_tax_brackets()) { + if (administration_writer_save_tax_bracket_blocking(new_tax_bracket)) { ui_set_status(localize("status.saved")); } else { @@ -177,7 +177,7 @@ static void ui_draw_vat_rates() is_adding_item = false; administration_tax_bracket_add(new_tax_bracket); - if (administration_writer_save_all_tax_brackets()) { + if (administration_writer_save_tax_bracket_blocking(new_tax_bracket)) { ui_set_status(localize("status.saved")); } else { @@ -239,7 +239,7 @@ static void ui_draw_cost_centers() is_adding_item = false; administration_cost_center_update(new_cost_center); - if (administration_writer_save_all_cost_centers()) { + if (administration_writer_save_cost_center_blocking(new_cost_center)) { ui_set_status(localize("status.saved")); } else { @@ -300,7 +300,7 @@ static void ui_draw_cost_centers() is_adding_item = false; is_editing_item = false; administration_cost_center_add(new_cost_center); - if (administration_writer_save_all_cost_centers()) { + if (administration_writer_save_cost_center_blocking(new_cost_center)) { ui_set_status(localize("status.saved")); } else { @@ -346,6 +346,12 @@ void ui_draw_settings() ImGui::Spacing(); if (ImGui::Button(localize("form.save"))) { administration_company_info_set(company_info); + if (administration_writer_save_contact_blocking(company_info)) { + ui_set_status(localize("status.saved")); + } + else { + ui_set_status_error(localize("status.saveFailed")); + } } if (!can_save) ImGui::EndDisabled(); |
