From d08873ffe3ca2def1132701af54ddfd592036568 Mon Sep 17 00:00:00 2001 From: Frank Faulstich Date: Fri, 8 May 2026 18:22:31 +0200 Subject: [PATCH 1/5] Missing Translation Fixes #395 --- sl/SL_Menu.py | 114 +++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 61 deletions(-) diff --git a/sl/SL_Menu.py b/sl/SL_Menu.py index 487b8e7..c4eaebf 100644 --- a/sl/SL_Menu.py +++ b/sl/SL_Menu.py @@ -122,14 +122,6 @@ def render_header(title, subtitle=None): elif f['type'] == 'error': st.error(f['message']) st.session_state.feedback = None # Clear after showing -def t_label(key): - """Translates the key and removes leading numbering.""" - match = re.match(r'^(\d+\.?\s*)(.*)', key) - if match: - _numbering, text = match.groups() - return _(text) - return _(key) - # --- Views --- def view_main(): @@ -188,7 +180,7 @@ def view_main(): st.info(_("No active work session.")) with col_done: - if st.button("✔", help=_("Done"), disabled=not current_work or is_done): + if st.button("✔", help=_("Done"), disabled=not current_work or is_done, key="main_done_button"): st.session_state.tracker.update_task( current_work['main_project_name'], current_work['task_name'], @@ -196,7 +188,7 @@ def view_main(): recurring=task_details.get('recurring'), frequency=task_details.get('frequency'), userdefined_days=task_details.get('userdefined_days'), - task_id=task_details.get('id') + task_id=task_details.get('id'), ) st.rerun() @@ -207,38 +199,38 @@ def view_main(): st.session_state.context['return_to'] = 'main' navigate_to('edit_task_form') - if st.button(t_label("1. Start work on task"), use_container_width=True): + if st.button(_("Start work on task"), use_container_width=True): navigate_to('start_work') - if st.button(t_label("2. Show current work"), use_container_width=True): + if st.button(_("Show current work"), use_container_width=True): navigate_to('show_current_work') - if st.button(t_label("3. Stop current work"), use_container_width=True): + if st.button(_("Stop current work"), use_container_width=True): if st.session_state.tracker.stop_work(): set_feedback(_("Work session stopped successfully.")) else: set_feedback(_("No active work session to stop."), 'info') st.rerun() - if st.button(_("Task Planning"), use_container_width=True): + if st.button(_("Task Planning"), use_container_width=True, key="main_task_planning"): navigate_to('task_planning') - if st.button(_("Today View"), use_container_width=True): + if st.button(_("Today View"), use_container_width=True, key="main_today_view"): navigate_to('today_view') - if st.button(_("E-Mail Task Assignment"), use_container_width=True): + if st.button(_("E-Mail Task Assignment"), use_container_width=True, key="main_email_assignment"): navigate_to('email_assignment') st.divider() - if st.button(t_label("4. Handle projects and tasks"), use_container_width=True): + if st.button(_("Handle projects and tasks"), use_container_width=True): navigate_to('project_management') - if st.button(t_label("5. Reporting"), use_container_width=True): + if st.button(_("Reporting"), use_container_width=True): navigate_to('reporting') - if st.button(t_label("6. Settings"), use_container_width=True): + if st.button(_("Settings"), use_container_width=True): navigate_to('settings') st.divider() - if st.button(t_label("0. Exit"), use_container_width=True): + if st.button(_("Exit"), use_container_width=True): os._exit(0) def view_task_planning(): @@ -547,14 +539,14 @@ def view_project_management(): """ render_header(_("Project Management")) - if st.button(t_label("1. Project Management"), use_container_width=True): + if st.button(_("Main Project Management"), use_container_width=True): navigate_to('main_project_mgmt') - if st.button(t_label("2. Task Management"), use_container_width=True): + if st.button(_("Task Management"), use_container_width=True): navigate_to('task_mgmt') st.divider() - if st.button(t_label("0. Back to Main Menu"), use_container_width=True): + if st.button(_("Back to Main Menu"), use_container_width=True): navigate_to('main') def view_main_project_mgmt(): @@ -563,19 +555,19 @@ def view_main_project_mgmt(): """ render_header(_("Project Management")) - if st.button(t_label("1. Add Project"), use_container_width=True): navigate_to('add_main_project') - if st.button(t_label("2. List Projects"), use_container_width=True): navigate_to('list_main_projects') - if st.button(t_label("3. Rename Project"), use_container_width=True): navigate_to('rename_main_project') - if st.button(t_label("4. Close Project"), use_container_width=True): navigate_to('close_main_project') - if st.button(t_label("5. Re-open Project"), use_container_width=True): navigate_to('reopen_main_project') - if st.button(t_label("6. Delete Project"), use_container_width=True): navigate_to('delete_main_project') - if st.button(t_label("7. List Inactive Projects"), use_container_width=True): navigate_to('list_inactive_main') - if st.button(t_label("8. Demote Project to Task"), use_container_width=True): navigate_to('demote_main_project') - if st.button(t_label("9. List Completed Projects"), use_container_width=True): navigate_to('list_completed_main') + if st.button(_("Add Project"), use_container_width=True): navigate_to('add_main_project') + if st.button(_("List Projects"), use_container_width=True): navigate_to('list_main_projects') + if st.button(_("Rename Project"), use_container_width=True): navigate_to('rename_main_project') + if st.button(_("Close Project"), use_container_width=True): navigate_to('close_main_project') + if st.button(_("Re-open Project"), use_container_width=True): navigate_to('reopen_main_project') + if st.button(_("Delete Project"), use_container_width=True): navigate_to('delete_main_project') + if st.button(_("List Inactive Projects"), use_container_width=True): navigate_to('list_inactive_main') + if st.button(_("Demote Project to Task"), use_container_width=True): navigate_to('demote_main_project') + if st.button(_("List Completed Projects"), use_container_width=True): navigate_to('list_completed_main') st.divider() - if st.button(t_label("0. Back"), use_container_width=True): + if st.button(_("Back"), use_container_width=True): navigate_to('project_management') def view_task_mgmt(): @@ -584,22 +576,22 @@ def view_task_mgmt(): """ render_header(_("Task Management")) - if st.button(t_label("1. Add Task"), use_container_width=True): navigate_to('add_task') - if st.button(t_label("2. List Tasks"), use_container_width=True): navigate_to('list_tasks') - if st.button(t_label("3. Rename Task"), use_container_width=True): navigate_to('rename_task') - if st.button(t_label("4. Close Task"), use_container_width=True): navigate_to('close_task') - if st.button(t_label("5. Re-open Task"), use_container_width=True): navigate_to('reopen_task') - if st.button(t_label("6. Delete Task"), use_container_width=True): navigate_to('delete_task') - if st.button(t_label("7. Move Task"), use_container_width=True): navigate_to('move_task') - if st.button(t_label("8. List Inactive Tasks"), use_container_width=True): navigate_to('list_inactive_tasks') - if st.button(t_label("9. List All Closed Tasks"), use_container_width=True): navigate_to('list_closed_tasks') - if st.button(_("Edit Task"), use_container_width=True): navigate_to('edit_task') - if st.button(t_label("10. Delete All Closed Tasks"), use_container_width=True): navigate_to('delete_all_closed_tasks') - if st.button(t_label("11. Promote Task to Project"), use_container_width=True): navigate_to('promote_task_to_project') + if st.button(_("Add Task"), use_container_width=True): navigate_to('add_task') + if st.button(_("List Tasks"), use_container_width=True): navigate_to('list_tasks') + if st.button(_("Rename Task"), use_container_width=True): navigate_to('rename_task') + if st.button(_("Close Task"), use_container_width=True): navigate_to('close_task') + if st.button(_("Re-open Task"), use_container_width=True): navigate_to('reopen_task') + if st.button(_("Delete Task"), use_container_width=True): navigate_to('delete_task') + if st.button(_("Move Task"), use_container_width=True): navigate_to('move_task') + if st.button(_("List Inactive Tasks"), use_container_width=True): navigate_to('list_inactive_tasks') + if st.button(_("List All Closed Tasks"), use_container_width=True): navigate_to('list_closed_tasks') + if st.button(_("Edit Task"), use_container_width=True, key="task_mgmt_edit_task"): navigate_to('edit_task') + if st.button(_("Delete All Closed Tasks"), use_container_width=True): navigate_to('delete_all_closed_tasks') + if st.button(_("Promote Task to Project"), use_container_width=True): navigate_to('promote_task_to_project') st.divider() - if st.button(t_label("0. Back"), use_container_width=True): + if st.button(_("Back"), use_container_width=True): navigate_to('project_management') def view_reporting(): @@ -609,20 +601,20 @@ def view_reporting(): render_header(_("Reporting")) tt = st.session_state.tracker - if st.button(t_label("1. Daily Report (Today)"), use_container_width=True): + if st.button(_("Daily Report (Today)"), use_container_width=True): report = tt.generate_daily_report() st.session_state.context['report'] = report navigate_to('view_report') st.rerun() - if st.button(t_label("2. Daily Report (Specific Day)"), use_container_width=True): navigate_to('report_specific_day') - if st.button(t_label("3. Date Range Report"), use_container_width=True): navigate_to('report_date_range') - if st.button(t_label("4. Detailed Task Report"), use_container_width=True): navigate_to('report_detailed_task') - if st.button(t_label("5. Detailed Project Report"), use_container_width=True): navigate_to('report_detailed_main') - if st.button(t_label("6. Detailed Daily Report"), use_container_width=True): navigate_to('report_detailed_daily') + if st.button(_("Daily Report (Specific Day)"), use_container_width=True): navigate_to('report_specific_day') + if st.button(_("Date Range Report"), use_container_width=True): navigate_to('report_date_range') + if st.button(_("Detailed Task Report"), use_container_width=True): navigate_to('report_detailed_task') + if st.button(_("Detailed Project Report"), use_container_width=True): navigate_to('report_detailed_main') + if st.button(_("Detailed Daily Report"), use_container_width=True): navigate_to('report_detailed_daily') st.divider() - if st.button(t_label("0. Back to Main Menu"), use_container_width=True): + if st.button(_("Back to Main Menu"), use_container_width=True): navigate_to('main') def view_settings(): @@ -631,17 +623,17 @@ def view_settings(): """ render_header(_("Settings")) - if st.button(t_label("1. Change Language"), use_container_width=True): navigate_to('settings_language') - if st.button(t_label("2. Restore Previous Version"), use_container_width=True): navigate_to('settings_restore') - if st.button(t_label("3. Change Data Storage Location"), use_container_width=True): navigate_to('settings_storage') - if st.button(t_label("4. Change Streamlit Port"), use_container_width=True): navigate_to('settings_port') - if st.button(_("Email Settings"), use_container_width=True): navigate_to('settings_email') - if st.button(_("Change CSS Style"), use_container_width=True): navigate_to('settings_css') - if st.button(_("Change View Mode"), use_container_width=True): navigate_to('settings_view_mode') + if st.button(_("Change Language"), use_container_width=True): navigate_to('settings_language') + if st.button(_("Restore Previous Version"), use_container_width=True): navigate_to('settings_restore') + if st.button(_("Change Data Storage Location"), use_container_width=True): navigate_to('settings_storage') + if st.button(_("Change Streamlit Port"), use_container_width=True): navigate_to('settings_port') + if st.button(_("Email Settings"), use_container_width=True, key="settings_email"): navigate_to('settings_email') + if st.button(_("Change CSS Style"), use_container_width=True, key="settings_css"): navigate_to('settings_css') + if st.button(_("Change View Mode"), use_container_width=True, key="settings_view_mode"): navigate_to('settings_view_mode') st.divider() - if st.button(t_label("0. Back to Main Menu"), use_container_width=True): + if st.button(_("Back to Main Menu"), use_container_width=True): navigate_to('main') # --- Action Views (Forms) --- From 5602e75230c2c3620784a464ba1e64feaf823d6a Mon Sep 17 00:00:00 2001 From: Frank Faulstich Date: Fri, 8 May 2026 18:26:20 +0200 Subject: [PATCH 2/5] cs --- locale/cs/LC_MESSAGES/timetracker.mo | Bin 26193 -> 26742 bytes locale/cs/LC_MESSAGES/timetracker.po | 24 ++++++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/locale/cs/LC_MESSAGES/timetracker.mo b/locale/cs/LC_MESSAGES/timetracker.mo index 5f0b5af494e2d34fe88233b3b2bf67ece8dcdc1a..91d33f1aad958d7fc435dbe9e10ff7cc09bc2421 100644 GIT binary patch delta 6853 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 BMD+jw delta 6426 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 && n<=4) ? 1 : 2;\n" msgid "Edit current task" -msgstr "" +msgstr "Upravit aktuální úkol" msgid "Warning: Could not read {file}. Error: {error}" msgstr "Varování: Nelze přečíst soubor {file}. Chyba: {error}" @@ -80,7 +80,7 @@ msgid "Task '{name}' moved successfully." msgstr "Úkol '{name}' byl úspěšně přesunut." msgid "No project selected. Please start again." -msgstr "" +msgstr "Nebyl vybrán žádný projekt. Začněte prosím znovu." msgid "A project named '{name}' already exists." msgstr "Projekt s názvem '{name}' již existuje." @@ -114,7 +114,7 @@ msgstr "" "{parent_name}'." msgid "No open projects found." -msgstr "" +msgstr "Nebyly nalezeny žádné otevřené projekty." msgid "# Daily Time Report: {date}\n" msgstr "# Denní zpráva o čase: {date}\n" @@ -776,9 +776,6 @@ msgstr "Rozpis úkolů" msgid "{num_sessions} sessions" msgstr "{num_sessions} relací" -msgid "6. Detailed Daily Report" -msgstr "6. Podrobná denní zpráva" - msgid "\n--- Detailed Daily Report ---" msgstr "\n--- Podrobná denní zpráva ---" @@ -863,6 +860,21 @@ msgstr "Podrobná zpráva o úkolu" msgid "Detailed Project Report" msgstr "Podrobná zpráva o projektu" +msgid "Detailed Daily Report" +msgstr "Podrobná denní zpráva" + +msgid "Main Project Management" +msgstr "Hlavní správa projektů" + +msgid "Start work on task" +msgstr "Začít práci na úkolu" + +msgid "Show current work" +msgstr "Zobrazit aktuální práci" + +msgid "Stop current work" +msgstr "Zastavit aktuální práci" + msgid "Select Project" msgstr "Vybrat projekt" From 8aa89816860b95240047d2e5fa1888f76536a8e3 Mon Sep 17 00:00:00 2001 From: Frank Faulstich Date: Fri, 8 May 2026 18:31:08 +0200 Subject: [PATCH 3/5] de --- locale/de/LC_MESSAGES/timetracker.mo | Bin 30516 -> 30628 bytes locale/de/LC_MESSAGES/timetracker.po | 12 +++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/locale/de/LC_MESSAGES/timetracker.mo b/locale/de/LC_MESSAGES/timetracker.mo index be0087202cb8a7b4a12e80c662445258d4de2505..c2912b3a14d28f20fb3eb05cfa9f5fe82ef5de57 100644 GIT binary patch delta 7327 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 delta 7208 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 Date: Fri, 8 May 2026 19:01:12 +0200 Subject: [PATCH 4/5] es --- locale/es/LC_MESSAGES/timetracker.mo | Bin 39665 -> 39663 bytes locale/es/LC_MESSAGES/timetracker.po | 12 +++--- sl/SL_Menu.py | 60 +++++++++++++-------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/locale/es/LC_MESSAGES/timetracker.mo b/locale/es/LC_MESSAGES/timetracker.mo index 8f24d52de7cf1684f3a466e572009c8f37e2c5ba..c7937211665112acff97d8104732d8dbb2491858 100644 GIT binary patch delta 7072 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 VSKYU2aRc|tx^VB}(0k7Z{ueOmzs3Ln delta 7023 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 diff --git a/locale/es/LC_MESSAGES/timetracker.po b/locale/es/LC_MESSAGES/timetracker.po index f68ccdc..a2654d9 100644 --- a/locale/es/LC_MESSAGES/timetracker.po +++ b/locale/es/LC_MESSAGES/timetracker.po @@ -1428,14 +1428,14 @@ msgstr "Informe Detallado de Proyecto" msgid "Detailed Daily Report" msgstr "Informe Diario Detallado" -msgid "Change Language" -msgstr "Cambiar Idioma" +msgid "Main Project Management" +msgstr "Gestión de Proyectos Principales" -msgid "Restore Previous Version" -msgstr "Restaurar Versión Anterior" +msgid "Start work on task" +msgstr "Iniciar trabajo en tarea" -msgid "Change Data Storage Location" -msgstr "Cambiar Ubicación de Almacenamiento de Datos" +msgid "Handle projects and tasks" +msgstr "Gestionar proyectos y tareas" msgid "Select Action" msgstr "Seleccionar Acción" diff --git a/sl/SL_Menu.py b/sl/SL_Menu.py index c4eaebf..43b976e 100644 --- a/sl/SL_Menu.py +++ b/sl/SL_Menu.py @@ -210,13 +210,13 @@ def view_main(): set_feedback(_("No active work session to stop."), 'info') st.rerun() - if st.button(_("Task Planning"), use_container_width=True, key="main_task_planning"): + if st.button(_("Task Planning"), use_container_width=True, key="main_task_planning_btn"): navigate_to('task_planning') - if st.button(_("Today View"), use_container_width=True, key="main_today_view"): + if st.button(_("Today View"), use_container_width=True, key="main_today_view_btn"): navigate_to('today_view') - if st.button(_("E-Mail Task Assignment"), use_container_width=True, key="main_email_assignment"): + if st.button(_("E-Mail Task Assignment"), use_container_width=True, key="main_email_assignment_btn"): navigate_to('email_assignment') st.divider() @@ -555,19 +555,19 @@ def view_main_project_mgmt(): """ render_header(_("Project Management")) - if st.button(_("Add Project"), use_container_width=True): navigate_to('add_main_project') - if st.button(_("List Projects"), use_container_width=True): navigate_to('list_main_projects') - if st.button(_("Rename Project"), use_container_width=True): navigate_to('rename_main_project') - if st.button(_("Close Project"), use_container_width=True): navigate_to('close_main_project') - if st.button(_("Re-open Project"), use_container_width=True): navigate_to('reopen_main_project') - if st.button(_("Delete Project"), use_container_width=True): navigate_to('delete_main_project') - if st.button(_("List Inactive Projects"), use_container_width=True): navigate_to('list_inactive_main') - if st.button(_("Demote Project to Task"), use_container_width=True): navigate_to('demote_main_project') - if st.button(_("List Completed Projects"), use_container_width=True): navigate_to('list_completed_main') + if st.button(_("Add Project"), use_container_width=True, key="mgmt_add_proj"): navigate_to('add_main_project') + if st.button(_("List Projects"), use_container_width=True, key="mgmt_list_proj"): navigate_to('list_main_projects') + if st.button(_("Rename Project"), use_container_width=True, key="mgmt_rename_proj"): navigate_to('rename_main_project') + if st.button(_("Close Project"), use_container_width=True, key="mgmt_close_proj"): navigate_to('close_main_project') + if st.button(_("Re-open Project"), use_container_width=True, key="mgmt_reopen_proj"): navigate_to('reopen_main_project') + if st.button(_("Delete Project"), use_container_width=True, key="mgmt_del_proj"): navigate_to('delete_main_project') + if st.button(_("List Inactive Projects"), use_container_width=True, key="mgmt_list_inact_proj"): navigate_to('list_inactive_main') + if st.button(_("Demote Project to Task"), use_container_width=True, key="mgmt_demote_proj"): navigate_to('demote_main_project') + if st.button(_("List Completed Projects"), use_container_width=True, key="mgmt_list_comp_proj"): navigate_to('list_completed_main') st.divider() - if st.button(_("Back"), use_container_width=True): + if st.button(_("Back"), use_container_width=True, key="mgmt_back_proj"): navigate_to('project_management') def view_task_mgmt(): @@ -576,22 +576,22 @@ def view_task_mgmt(): """ render_header(_("Task Management")) - if st.button(_("Add Task"), use_container_width=True): navigate_to('add_task') - if st.button(_("List Tasks"), use_container_width=True): navigate_to('list_tasks') - if st.button(_("Rename Task"), use_container_width=True): navigate_to('rename_task') - if st.button(_("Close Task"), use_container_width=True): navigate_to('close_task') - if st.button(_("Re-open Task"), use_container_width=True): navigate_to('reopen_task') - if st.button(_("Delete Task"), use_container_width=True): navigate_to('delete_task') - if st.button(_("Move Task"), use_container_width=True): navigate_to('move_task') - if st.button(_("List Inactive Tasks"), use_container_width=True): navigate_to('list_inactive_tasks') - if st.button(_("List All Closed Tasks"), use_container_width=True): navigate_to('list_closed_tasks') + if st.button(_("Add Task"), use_container_width=True, key="t_mgmt_add"): navigate_to('add_task') + if st.button(_("List Tasks"), use_container_width=True, key="t_mgmt_list"): navigate_to('list_tasks') + if st.button(_("Rename Task"), use_container_width=True, key="t_mgmt_rename"): navigate_to('rename_task') + if st.button(_("Close Task"), use_container_width=True, key="t_mgmt_close"): navigate_to('close_task') + if st.button(_("Re-open Task"), use_container_width=True, key="t_mgmt_reopen"): navigate_to('reopen_task') + if st.button(_("Delete Task"), use_container_width=True, key="t_mgmt_del"): navigate_to('delete_task') + if st.button(_("Move Task"), use_container_width=True, key="t_mgmt_move"): navigate_to('move_task') + if st.button(_("List Inactive Tasks"), use_container_width=True, key="t_mgmt_list_inact"): navigate_to('list_inactive_tasks') + if st.button(_("List All Closed Tasks"), use_container_width=True, key="t_mgmt_list_closed"): navigate_to('list_closed_tasks') if st.button(_("Edit Task"), use_container_width=True, key="task_mgmt_edit_task"): navigate_to('edit_task') - if st.button(_("Delete All Closed Tasks"), use_container_width=True): navigate_to('delete_all_closed_tasks') - if st.button(_("Promote Task to Project"), use_container_width=True): navigate_to('promote_task_to_project') + if st.button(_("Delete All Closed Tasks"), use_container_width=True, key="t_mgmt_del_all"): navigate_to('delete_all_closed_tasks') + if st.button(_("Promote Task to Project"), use_container_width=True, key="t_mgmt_promote"): navigate_to('promote_task_to_project') st.divider() - if st.button(_("Back"), use_container_width=True): + if st.button(_("Back"), use_container_width=True, key="t_mgmt_back"): navigate_to('project_management') def view_reporting(): @@ -623,17 +623,17 @@ def view_settings(): """ render_header(_("Settings")) - if st.button(_("Change Language"), use_container_width=True): navigate_to('settings_language') - if st.button(_("Restore Previous Version"), use_container_width=True): navigate_to('settings_restore') - if st.button(_("Change Data Storage Location"), use_container_width=True): navigate_to('settings_storage') - if st.button(_("Change Streamlit Port"), use_container_width=True): navigate_to('settings_port') + if st.button(_("1. Change Language"), use_container_width=True): navigate_to('settings_language') + if st.button(_("2. Restore Previous Version"), use_container_width=True): navigate_to('settings_restore') + if st.button(_("3. Change Data Storage Location"), use_container_width=True): navigate_to('settings_storage') + if st.button(_("4. Change Streamlit Port"), use_container_width=True): navigate_to('settings_port') if st.button(_("Email Settings"), use_container_width=True, key="settings_email"): navigate_to('settings_email') if st.button(_("Change CSS Style"), use_container_width=True, key="settings_css"): navigate_to('settings_css') if st.button(_("Change View Mode"), use_container_width=True, key="settings_view_mode"): navigate_to('settings_view_mode') st.divider() - if st.button(_("Back to Main Menu"), use_container_width=True): + if st.button(_("0. Back to Main Menu"), use_container_width=True): navigate_to('main') # --- Action Views (Forms) --- From d9f672832128f1b62a44f4174030cdeada8e3f88 Mon Sep 17 00:00:00 2001 From: Frank Faulstich Date: Fri, 8 May 2026 19:21:56 +0200 Subject: [PATCH 5/5] fr --- locale/fr/LC_MESSAGES/timetracker.po | 243 ++++++++++++++++++++++++++- 1 file changed, 236 insertions(+), 7 deletions(-) diff --git a/locale/fr/LC_MESSAGES/timetracker.po b/locale/fr/LC_MESSAGES/timetracker.po index 654e1da..97e912d 100644 --- a/locale/fr/LC_MESSAGES/timetracker.po +++ b/locale/fr/LC_MESSAGES/timetracker.po @@ -220,18 +220,27 @@ msgstr "Port mis à jour vers {port}. Veuillez redémarrer Streamlit pour que le msgid "Work started on '{task_name}' in project '{main_name}'." msgstr "Travail commencé sur '{task_name}' dans le projet '{main_name}'." +msgid "daily" +msgstr "quotidien" + msgid "1. Main Project Management" msgstr "1. Gestion des projets principaux" msgid "2. Task Management" msgstr "2. Gestion des tâches" +msgid "on all business days" +msgstr "tous les jours ouvrables" + msgid "1. Add Main Project" msgstr "1. Ajouter un projet principal" msgid "6. Demote Main-Project to Task" msgstr "6. Rétrograder un projet principal en tâche" +msgid "weekly" +msgstr "hebdomadaire" + #: TimeTracker.py:651 msgid "- {name}: {hours} hour" msgid_plural "- {name}: {hours} hours" @@ -239,6 +248,9 @@ msgstr[0] "- {name} : {hours} heure" msgstr[1] "- {name} : {hours} heures" #: TimeTracker.py:657 +msgid "monthly" +msgstr "mensuel" + msgid "## {name} ({hours} hour)\n" msgid_plural "## {name} ({hours} hours)\n" msgstr[0] "## {name} ({hours} heure)\n" @@ -248,6 +260,9 @@ msgstr[1] "## {name} ({hours} heures)\n" msgid "# Daily Time Report: {date}\n" msgstr "# Rapport de temps journalier : {date}\n" +msgid "userdefined" +msgstr "# Rapport de temps journalier : {date}\n" + #: TimeTracker.py:666 msgid "\n**Total Daily Time: {hours} hour**" msgid_plural "\n**Total Daily Time: {hours} hours**" @@ -258,6 +273,9 @@ msgstr[1] "\n**Temps total journalier : {hours} heures**" msgid "No time tracked for {date}." msgstr "Aucun temps suivi pour le {date}." +msgid "Days" +msgstr "Aucun temps suivi pour le {date}." + #: TimeTracker.py:708 msgid "# Time Report: {start_date} to {end_date}\n" msgstr "# Rapport de temps : du {start_date} au {end_date}\n" @@ -274,48 +292,72 @@ msgstr "" msgid "No time tracked between {start_date} and {end_date}." msgstr "Aucun temps suivi entre le {start_date} et le {end_date}." +msgid "Notes (Markdown)" +msgstr "Aucun temps suivi entre le {start_date} et le {end_date}." + msgid "now" msgstr "maintenant" msgid "# Detailed Daily Report: {date}" msgstr "# Rapport journalier détaillé : {date}" +msgid "No notes provided." +msgstr "Aucune note fournie." + msgid "\nNo time tracked for {date}." msgstr "\nAucun temps suivi pour le {date}." msgid "Active (working on '{task_name}')" msgstr "Actif (travail sur '{task_name}')" +msgid "Add New Project" +msgstr "Ajouter un nouveau projet" + msgid "# Detailed Report for Task: {name}" msgstr "# Rapport détaillé pour la tâche : {name}" msgid "Part of Main Project: {name}" msgstr "Fait partie du projet principal : {name}" +msgid "Name of the new task" +msgstr "Nom de la nouvelle tâche" + msgid "Active (currently running)" msgstr "Actif (en cours)" msgid "Last activity" msgstr "Dernière activité" +msgid "Today" +msgstr "Aujourd'hui" + msgid "Inactive" msgstr "Inactif" msgid "Status" msgstr "Statut" +msgid "Recurring" +msgstr "Récurrent" + msgid "First entry" msgstr "Première entrée" msgid "Total recorded time" msgstr "Temps total enregistré" +msgid "Frequency" +msgstr "Fréquence" + msgid "Total work sessions" msgstr "Nombre total de sessions de travail" msgid "Average session duration" msgstr "Durée moyenne des sessions" +msgid "Edit" +msgstr "Modifier" + msgid "Weekday Distribution" msgstr "Répartition par jour de la semaine" @@ -340,30 +382,45 @@ msgstr "Samedi" msgid "Sunday" msgstr "Dimanche" +msgid "Preview" +msgstr "Aperçu" + msgid "Daily Breakdown" msgstr "Répartition journalière" msgid "Duration" msgstr "Durée" +msgid "Add Task" +msgstr "Ajouter une tâche" + msgid "# Detailed Report for Main Project: {name}" msgstr "# Rapport détaillé pour le projet principal : {name}" msgid "Number of sub-projects" msgstr "Nombre de tâches" +msgid "A task with this name already exists in this project." +msgstr "Une tâche avec ce nom existe déjà dans ce projet." + msgid "Task Breakdown" msgstr "Répartition par tâche" msgid "{num_sessions} sessions" msgstr "{num_sessions} sessions" +msgid "Step 1: Select Project" +msgstr "Étape 1 : Sélectionner le projet" + msgid "6. Detailed Daily Report" msgstr "6. Rapport journalier détaillé" msgid "\n--- Detailed Daily Report ---" msgstr "\n--- Rapport journalier détaillé ---" +msgid "No open projects found." +msgstr "Aucun projet ouvert trouvé." + msgid "Enter the date (YYYY-MM-DD) or press Enter for today: " msgstr "Entrez la date (AAAA-MM-JJ) ou appuyez sur Entrée pour aujourd'hui : " @@ -371,6 +428,9 @@ msgstr "Entrez la date (AAAA-MM-JJ) ou appuyez sur Entrée pour aujourd'hui : " msgid "\n--- Project Management ---" msgstr "\n--- Gestion des projets ---" +msgid "Next" +msgstr "Suivant" + #: TimeTrackerCLI.py:22 msgid "1. Add Project" msgstr "1. Ajouter un projet" @@ -379,6 +439,9 @@ msgstr "1. Ajouter un projet" msgid "2. List Projects" msgstr "2. Lister les projets" +msgid "Step 2: Select Task from" +msgstr "Étape 2 : Sélectionner la tâche de" + #: TimeTrackerCLI.py:24 msgid "3. Rename Project" msgstr "3. Renommer le projet" @@ -391,6 +454,9 @@ msgstr "4. Supprimer le projet" msgid "5. List Inactive Projects" msgstr "5. Lister les projets inactifs" +msgid "No open tasks found." +msgstr "Aucune tâche ouverte trouvée." + #: TimeTrackerCLI.py:27 msgid "6. Demote Project to Task" msgstr "6. Rétrograder un projet en tâche" @@ -403,6 +469,9 @@ msgstr "7. Ajouter une tâche" msgid "8. List Tasks" msgstr "8. Lister les tâches" +msgid "Task not found." +msgstr "Tâche non trouvée." + #: TimeTrackerCLI.py:31 TimeTrackerCLI.py:32 msgid "9. Rename Task" msgstr "9. Renommer la tâche" @@ -422,6 +491,9 @@ msgstr "13. Déplacer la tâche" msgid "14. List Inactive Tasks" msgstr "14. Lister les tâches inactives" +msgid "Done" +msgstr "Terminé" + msgid "15. List All Closed Tasks" msgstr "15. Lister toutes les tâches fermées" @@ -431,6 +503,9 @@ msgstr "16. Supprimer toutes les tâches fermées" msgid "17. Promote Task to Project" msgstr "17. Promouvoir une tâche en projet" +msgid "Save Changes" +msgstr "Enregistrer les modifications" + #: TimeTrackerCLI.py:37 TimeTrackerCLI.py:403 TimeTrackerCLI.py:461 TimeTrackerCLI.py:539 msgid "0. Back to Main Menu" msgstr "0. Retour au menu principal" @@ -443,6 +518,9 @@ msgstr "Choix : " msgid "\n--- Add New Project ---" msgstr "\n--- Ajouter un nouveau projet ---" +msgid "Error: Could not update task." +msgstr "Erreur : Impossible de mettre à jour la tâche." + #: TimeTrackerCLI.py:45 msgid "Name of the project: " msgstr "Nom du projet : " @@ -455,6 +533,9 @@ msgstr "Projet '{name}' ajouté." msgid "\n--- List Projects ---" msgstr "\n--- Lister les projets ---" +msgid "No open projects found. Please add one first." +msgstr "Aucun projet ouvert trouvé. Veuillez d'abord en ajouter un." + #: TimeTrackerCLI.py:55 TimeTrackerCLI.py:166 TimeTrackerCLI.py:288 TimeTrackerCLI.py:411 TimeTrackerCLI.py:434 TimeTrackerCLI.py:479 msgid "No projects found." msgstr "Aucun projet trouvé." @@ -467,6 +548,9 @@ msgstr "\n--- Renommer le projet ---" msgid "No projects to rename." msgstr "Aucun projet à renommer." +msgid "Start Work" +msgstr "Démarrer le travail" + #: TimeTrackerCLI.py:64 msgid "Select a project to rename:" msgstr "Sélectionnez un projet à renommer :" @@ -479,6 +563,9 @@ msgstr "Entrez le numéro du projet : " msgid "Enter the new name for '{name}': " msgstr "Entrez le nouveau nom pour '{name}' : " +msgid "Error starting work." +msgstr "Erreur lors du démarrage du travail." + #: TimeTrackerCLI.py:74 msgid "Project '{old_name}' successfully renamed to '{new_name}'." msgstr "Le projet '{old_name}' a été renommé en '{new_name}' avec succès." @@ -491,6 +578,9 @@ msgstr "Erreur : Impossible de renommer. Le nouveau nom '{new_name}' existe peut msgid "Invalid input. Please enter a valid number." msgstr "Entrée invalide. Veuillez entrer un numéro valide." +msgid "Current Active Work" +msgstr "Travail actif en cours" + #: TimeTrackerCLI.py:81 msgid "\n--- Delete Project ---" msgstr "\n--- Supprimer le projet ---" @@ -503,6 +593,9 @@ msgstr "Aucun projet à supprimer." msgid "Select a project to delete:" msgstr "Sélectionnez un projet à supprimer :" +msgid "Project" +msgstr "Projet" + #: TimeTrackerCLI.py:93 msgid "Project '{name}' deleted." msgstr "Projet '{name}' supprimé." @@ -515,6 +608,9 @@ msgstr "Erreur : Projet '{name}' non trouvé." msgid "\n--- List Inactive Projects ---" msgstr "\n--- Lister les projets inactifs ---" +msgid "Task" +msgstr "Tâche" + #: TimeTrackerCLI.py:103 msgid "Enter the number of weeks without activity (e.g., 8): " msgstr "Entrez le nombre de semaines sans activité (ex: 8) : " @@ -527,6 +623,9 @@ msgstr "Veuillez entrer un nombre positif." msgid "\nInactive Main-Projects (>{weeks} weeks):" msgstr "\nProjets principaux inactifs (>{weeks} semaines) :" +msgid "Started at" +msgstr "Démarré à" + #: TimeTrackerCLI.py:112 msgid " - Main Project: {name}" msgstr " - Projet principal : {name}" @@ -545,6 +644,9 @@ msgstr[1] "Aucun projet principal inactif depuis plus de {weeks} semaines n'a é msgid "Invalid input. Please enter a valid number for weeks." msgstr "Entrée invalide. Veuillez entrer un nombre valide pour les semaines." +msgid "Streamlit Port Settings" +msgstr "Paramètres du port Streamlit" + #: TimeTrackerCLI.py:122 msgid "\n--- Add New Sub-Project ---" msgstr "\n--- Ajouter un nouveau sous-projet ---" @@ -557,6 +659,9 @@ msgstr "Aucun projet principal trouvé. Veuillez d'abord en ajouter un." msgid "Select a main project to add a sub-project to:" msgstr "Sélectionnez un projet principal auquel ajouter un sous-projet :" +msgid "New Port" +msgstr "Nouveau port" + #: TimeTrackerCLI.py:135 msgid "Name of the new sub-project: " msgstr "Nom du nouveau sous-projet : " @@ -569,6 +674,9 @@ msgstr "Sous-projet '{sub_name}' ajouté à '{main_name}'." msgid "\n--- List Sub-Projects ---" msgstr "\n--- Lister les sous-projets ---" +msgid "Save" +msgstr "Enregistrer" + #: TimeTrackerCLI.py:145 msgid "No main projects found. Cannot list sub-projects." msgstr "Aucun projet principal trouvé. Impossible de lister les sous-projets." @@ -581,6 +689,9 @@ msgstr "Sélectionnez le projet principal dont vous voulez lister les sous-proje msgid "Sub-projects for '{name}':" msgstr "Sous-projets pour '{name}' :" +msgid "Port updated to {port}. Please restart Streamlit." +msgstr "Port mis à jour vers {port}. Veuillez redémarrer Streamlit." + #: TimeTrackerCLI.py:159 TimeTrackerCLI.py:262 TimeTrackerCLI.py:489 msgid "No sub-projects found for '{name}'." msgstr "Aucun sous-projet trouvé pour '{name}'." @@ -593,6 +704,9 @@ msgstr "\n--- Renommer le sous-projet ---" msgid "Select the main project:" msgstr "Sélectionnez le projet principal :" +msgid "Change Data Storage Location" +msgstr "Changer l'emplacement de stockage des données" + #: TimeTrackerCLI.py:177 msgid "No sub-projects to rename for '{name}'." msgstr "Aucun sous-projet à renommer pour '{name}'." @@ -605,6 +719,9 @@ msgstr "Sélectionnez un sous-projet de '{name}' à renommer :" msgid "Enter the number of the sub-project: " msgstr "Entrez le numéro du sous-projet : " +msgid "Current data file" +msgstr "Fichier de données actuel" + #: TimeTrackerCLI.py:190 msgid "Sub-project '{old_name}' renamed to '{new_name}'." msgstr "Le sous-projet '{old_name}' a été renommé en '{new_name}'." @@ -615,6 +732,9 @@ msgid "" "was not found." msgstr "Erreur : Impossible de renommer. Le nouveau nom existe peut-être déjà ou le projet n'a pas été trouvé." +msgid "New Path for data file" +msgstr "Nouveau chemin pour le fichier de données" + #: TimeTrackerCLI.py:195 msgid "\n--- Delete Sub-Project ---" msgstr "\n--- Supprimer le sous-projet ---" @@ -627,6 +747,9 @@ msgstr "Aucun sous-projet à supprimer pour '{name}'." msgid "Select a sub-project from '{name}' to delete:" msgstr "Sélectionnez un sous-projet de '{name}' à supprimer :" +msgid "Move existing data to the new location" +msgstr "Déplacer les données existantes vers le nouvel emplacement" + #: TimeTrackerCLI.py:217 msgid "Sub-project '{sub_name}' deleted from '{main_name}'." msgstr "Sous-projet '{sub_name}' supprimé de '{main_name}'." @@ -634,6 +757,13 @@ msgstr "Sous-projet '{sub_name}' supprimé de '{main_name}'." msgid "\n--- List All Closed Sub-Projects ---" msgstr "\n--- Lister tous les sous-projets fermés ---" +msgid "" +"If unchecked, the old data file will remain, and a new empty one might be " +"created at the new location on restart." +msgstr "" +"Si décoché, l'ancien fichier de données restera, et un nouveau fichier vide " +"pourrait être créé au nouvel emplacement au redémarrage." + msgid "No closed sub-projects found." msgstr "Aucun sous-projet fermé trouvé." @@ -643,6 +773,9 @@ msgstr "\n--- Supprimer tous les sous-projets fermés ---" msgid "Are you sure you want to delete ALL closed sub-projects? (y/n): " msgstr "Êtes-vous sûr de vouloir supprimer TOUS les sous-projets fermés ? (o/n) : " +msgid "Error: For security, the data file must be located within the application directory." +msgstr "Erreur : Pour des raisons de sécurité, le fichier de données doit être situé dans le répertoire de l'application." + msgid "{count} closed sub-projects were deleted." msgstr "{count} sous-projets fermés ont été supprimés." @@ -650,6 +783,9 @@ msgid "Operation cancelled." msgstr "Opération annulée." #: TimeTrackerCLI.py:219 TimeTrackerCLI.py:281 +msgid "Error: The directory '{dir}' does not exist." +msgstr "Erreur : Le répertoire '{dir}' n'existe pas." + msgid "Error: Main project or sub-project not found." msgstr "Erreur : Projet principal ou sous-projet non trouvé." @@ -657,6 +793,9 @@ msgstr "Erreur : Projet principal ou sous-projet non trouvé." msgid "\n--- List Inactive Sub-Projects ---" msgstr "\n--- Lister les sous-projets inactifs ---" +msgid "Storage location updated. Please restart the application for the changes to take effect." +msgstr "Emplacement de stockage mis à jour. Veuillez redémarrer l'application pour que les changements prennent effet." + #: TimeTrackerCLI.py:228 msgid "Enter the number of weeks without activity (e.g., 4): " msgstr "Entrez le nombre de semaines sans activité (ex: 4) : " @@ -669,6 +808,9 @@ msgstr "\nSous-projets inactifs (>{weeks} semaines) :" msgid " Sub-Project: {name}" msgstr " Sous-projet : {name}" +msgid "Error moving data: {error}" +msgstr "Erreur lors du déplacement des données : {error}" + #: TimeTrackerCLI.py:241 msgid "No sub-projects found inactive for more than {weeks} week." msgid_plural "No sub-projects found inactive for more than {weeks} weeks." @@ -679,6 +821,9 @@ msgstr[1] "Aucun sous-projet inactif depuis plus de {weeks} semaines n'a été t msgid "\n--- Move Sub-Project ---" msgstr "\n--- Déplacer le sous-projet ---" +msgid "Change CSS Style" +msgstr "Changer le style CSS" + #: TimeTrackerCLI.py:250 msgid "You need at least two main projects to move a sub-project." msgstr "Vous avez besoin d'au moins deux projets principaux pour déplacer un sous-projet." @@ -691,6 +836,9 @@ msgstr "Sélectionnez le projet principal source :" msgid "Enter the number of the source main project: " msgstr "Entrez le numéro du projet principal source : " +msgid "Current CSS file" +msgstr "Fichier CSS actuel" + #: TimeTrackerCLI.py:265 msgid "\nSelect a sub-project from '{name}' to move:" msgstr "\nSélectionnez un sous-projet de '{name}' à déplacer :" @@ -703,6 +851,9 @@ msgstr "\nSélectionnez le projet principal de destination :" msgid "Enter the number of the destination main project: " msgstr "Entrez le numéro du projet principal de destination : " +msgid "Select CSS File" +msgstr "Sélectionner le fichier CSS" + #: TimeTrackerCLI.py:279 msgid "Successfully moved '{sub_name}' from '{source_name}' to '{dest_name}'." msgstr "Déplacement réussi de '{sub_name}' de '{source_name}' vers '{dest_name}'." @@ -710,6 +861,9 @@ msgstr "Déplacement réussi de '{sub_name}' de '{source_name}' vers '{dest_name msgid "Error: {message}" msgstr "Erreur : {message}" +msgid "CSS style updated. Please restart the application for the changes to take effect." +msgstr "Style CSS mis à jour. Veuillez redémarrer l'application pour que les changements prennent effet." + #: TimeTrackerCLI.py:286 msgid "\n--- Promote Sub-Project to Main-Project ---" msgstr "\n--- Promouvoir un sous-projet en projet principal ---" @@ -722,6 +876,9 @@ msgstr "Sélectionnez le projet principal contenant le sous-projet à promouvoir msgid "No sub-projects to promote in '{name}'." msgstr "Aucun sous-projet à promouvoir dans '{name}'." +msgid "Change View Mode" +msgstr "Changer le mode d'affichage" + #: TimeTrackerCLI.py:304 msgid "\nSelect a sub-project from '{name}' to promote:" msgstr "\nSélectionnez un sous-projet de '{name}' à promouvoir :" @@ -734,6 +891,9 @@ msgstr "\n--- Rétrograder un projet principal en sous-projet ---" msgid "You need at least two main projects for this operation." msgstr "Vous avez besoin d'au moins deux projets principaux pour cette opération." +msgid "App Window (Webview)" +msgstr "Fenêtre d'application (Webview)" + msgid "Select the main project to demote:" msgstr "Sélectionnez le projet principal à rétrograder :" @@ -745,6 +905,9 @@ msgstr "Entrez le numéro du projet à rétrograder : " msgid "\nSelect the new parent main project:" msgstr "\nSélectionnez le nouveau projet principal parent :" +msgid "System Browser" +msgstr "Navigateur système" + #: TimeTrackerCLI.py:333 msgid "Enter the number of the new parent project: " msgstr "Entrez le numéro du nouveau projet parent : " @@ -756,6 +919,9 @@ msgstr "Choix invalide. Veuillez entrer un nombre de 0 à 17." msgid "\n--- Reporting ---" msgstr "\n--- Rapports ---" +msgid "Select View Mode" +msgstr "Sélectionner le mode d'affichage" + #: TimeTrackerCLI.py:349 msgid "1. Daily Report (Today)" msgstr "1. Rapport journalier (Aujourd'hui)" @@ -768,6 +934,9 @@ msgstr "2. Rapport journalier (Jour spécifique)" msgid "3. Date Range Report" msgstr "3. Rapport par plage de dates" +msgid "View mode updated. Please restart the application for the changes to take effect." +msgstr "Mode d'affichage mis à jour. Veuillez redémarrer l'application pour que les changements prennent effet." + #: TimeTrackerCLI.py:352 msgid "4. Detailed Task Report" msgstr "4. Rapport détaillé de tâche" @@ -780,6 +949,9 @@ msgstr "5. Rapport détaillé de projet" msgid "\n--- Generate Daily Report (Today) ---" msgstr "\n--- Générer le rapport journalier (Aujourd'hui) ---" +msgid "Restore Previous Version" +msgstr "Restaurer la version précédente" + #: TimeTrackerCLI.py:363 msgid "\n--- Generate Daily Report for a specific Day ---" msgstr "\n--- Générer le rapport journalier pour un jour spécifique ---" @@ -792,6 +964,9 @@ msgstr "Entrez la date (AAAA-MM-JJ) : " msgid "Invalid date format. Please use YYYY-MM-DD." msgstr "Format de date invalide. Veuillez utiliser AAAA-MM-JJ." +msgid "No previous version backup '{filename}' found." +msgstr "Aucune sauvegarde de la version précédente '{filename}' trouvée." + #: TimeTrackerCLI.py:371 TimeTrackerCLI.py:373 msgid "\n--- Generate Report for a Date Range ---" msgstr "\n--- Générer un rapport pour une plage de dates ---" @@ -803,6 +978,9 @@ msgstr "Entrez la date de début (AAAA-MM-JJ) : " msgid "Enter the end date (YYYY-MM-DD): " msgstr "Entrez la date de fin (AAAA-MM-JJ) : " +msgid "This will restore the application to the previously backed-up version. The application will then restart. You may need to manually refresh your browser if it does not reconnect automatically." +msgstr "Ceci restaurera l'application à la version sauvegardée précédemment. L'application redémarrera ensuite. Vous devrez peut-être actualiser manuellement votre navigateur s'il ne se reconnecte pas automatiquement." + #: TimeTrackerCLI.py:377 msgid "Error: The start date cannot be after the end date." msgstr "Erreur : La date de début ne peut pas être postérieure à la date de fin." @@ -815,6 +993,9 @@ msgstr "\n--- Rapport détaillé de tâche ---" msgid "\nSelect the sub-project for the report:" msgstr "\nSélectionnez le sous-projet pour le rapport :" +msgid "Restore and Restart" +msgstr "Restaurer et redémarrer" + #: TimeTrackerCLI.py:405 msgid "\n--- Detailed Project Report ---" msgstr "\n--- Rapport détaillé de projet ---" @@ -827,6 +1008,9 @@ msgstr "Sélectionnez le projet pour le rapport :" msgid "Invalid choice. Please enter a number from 0 to 5." msgstr "Choix invalide. Veuillez entrer un nombre de 0 à 5." +msgid "Restoring and restarting..." +msgstr "Restauration et redémarrage..." + #: TimeTrackerCLI.py:428 TimeTrackerCLI.py:469 msgid "\n--- Settings ---" msgstr "\n--- Paramètres ---" @@ -835,6 +1019,9 @@ msgstr "\n--- Paramètres ---" msgid "1. Change Language" msgstr "1. Changer de langue" +msgid "Change Language" +msgstr "1. Changer de langue" + msgid "3. Change Data Storage Location" msgstr "3. Changer l'emplacement de stockage des données" @@ -842,6 +1029,9 @@ msgstr "3. Changer l'emplacement de stockage des données" msgid "2. Restore Previous Version" msgstr "2. Restaurer la version précédente" +msgid "Select Language" +msgstr "Sélectionner la langue" + msgid "Invalid choice. Please enter a number from 0 to 3." msgstr "Choix invalide. Veuillez entrer un nombre de 0 à 3." @@ -853,6 +1043,9 @@ msgstr "\n--- Paramètres de langue ---" msgid "No additional languages found." msgstr "Aucune langue supplémentaire trouvée." +msgid "Language changed. Please restart the application for the changes to take effect." +msgstr "Langue changée. Veuillez redémarrer l'application pour que les changements prennent effet." + #: TimeTrackerCLI.py:458 TimeTrackerCLI.py:587 msgid "Language changed to '{lang}'. Please restart the application." msgstr "Langue changée en '{lang}'. Veuillez redémarrer l'application." @@ -880,8 +1073,8 @@ msgstr "Laisser vide pour annuler." msgid "New Path: " msgstr "Nouveau chemin : " -msgid "Error: The directory '{dir}' does not exist." -msgstr "Erreur : Le répertoire '{dir}' n'existe pas." +msgid "IMAP Server" +msgstr "Serveur IMAP" msgid "Storage location updated." msgstr "Emplacement de stockage mis à jour." @@ -892,8 +1085,8 @@ msgstr "Voulez-vous déplacer les données existantes vers le nouvel emplacement msgid "Data moved successfully." msgstr "Données déplacées avec succès." -msgid "Error moving data: {error}" -msgstr "Erreur lors du déplacement des données : {error}" +msgid "Port" +msgstr "Port" msgid "Error updating configuration: {error}" msgstr "Erreur lors de la mise à jour de la configuration : {error}" @@ -945,6 +1138,9 @@ msgstr "--- Menu principal ---" msgid "1. Start work on task" msgstr "1. Démarrer le travail sur une tâche" +msgid "Daily Report (Specific Day)" +msgstr "Rapport journalier (Jour spécifique)" + #: TimeTrackerCLI.py:528 msgid "2. Show current work" msgstr "2. Afficher le travail en cours" @@ -957,6 +1153,9 @@ msgstr "3. Arrêter le travail en cours" msgid "4. Handle projects and tasks" msgstr "4. Gérer les projets et les tâches" +msgid "Select Date" +msgstr "Sélectionner la date" + #: TimeTrackerCLI.py:532 msgid "5. Reporting" msgstr "5. Rapports" @@ -969,6 +1168,9 @@ msgstr "6. Paramètres" msgid "0. Exit" msgstr "0. Quitter" +msgid "Generate Report" +msgstr "Générer le rapport" + #: TimeTrackerCLI.py:541 msgid "\n--- Start Work on a Task ---" msgstr "\n--- Démarrer le travail sur une tâche ---" @@ -977,17 +1179,20 @@ msgstr "\n--- Démarrer le travail sur une tâche ---" msgid "Select a task from '{name}':" msgstr "Sélectionnez une tâche de '{name}' :" +msgid "Date Range Report" +msgstr "Rapport par plage de dates" + #: TimeTrackerCLI.py:507 msgid "Work started on '{sub_name}' in project '{main_name}'." msgstr "Travail démarré sur '{sub_name}' dans le projet '{main_name}'." -msgid "Error starting work." -msgstr "Erreur lors du démarrage du travail." - #: TimeTrackerCLI.py:514 msgid "\n--- Current Active Work ---" msgstr "\n--- Travail actif en cours ---" +msgid "Start Date" +msgstr "Date de début" + #: TimeTrackerCLI.py:523 msgid "You are currently working on:" msgstr "Vous travaillez actuellement sur :" @@ -996,6 +1201,9 @@ msgstr "Vous travaillez actuellement sur :" msgid " Project: {name}" msgstr " Projet : {name}" +msgid "End Date" +msgstr "Date de fin" + #: TimeTrackerCLI.py:525 msgid " Task: {name}" msgstr " Tâche : {name}" @@ -1020,6 +1228,9 @@ msgstr "\n--- Arrêter le travail ---" msgid "Work session stopped successfully." msgstr "Session de travail arrêtée avec succès." +msgid "Detailed Task Report" +msgstr "Rapport détaillé de tâche" + #: TimeTrackerCLI.py:536 msgid "No active work session to stop." msgstr "Aucune session de travail active à arrêter." @@ -1032,6 +1243,9 @@ msgstr "\nRecherche de mises à jour..." msgid "Exiting application. Goodbye!" msgstr "Fermeture de l'application. Au revoir !" +msgid "Detailed Project Report" +msgstr "Rapport détaillé de projet" + #: TimeTrackerCLI.py:605 msgid "Invalid choice. Please enter a number from 0 to 6." msgstr "Choix invalide. Veuillez entrer un nombre de 0 à 6." @@ -1045,6 +1259,9 @@ msgstr "" "trouvé dans config.json ou fichier invalide." #: update.py:38 +msgid "Detailed Daily Report" +msgstr "Rapport journalier détaillé" + msgid "A new version ({version}) is available." msgstr "Une nouvelle version ({version}) est disponible." @@ -1062,6 +1279,9 @@ msgstr "" "Une erreur inattendue s'est produite lors de la recherche de mises à jour : " "{error}" +"Une erreur inattendue s'est produite lors de la recherche de mises à jour : " +"{error}" + #: update.py:61 msgid "Downloading update..." msgstr "Téléchargement de la mise à jour..." @@ -1074,6 +1294,9 @@ msgstr "Téléchargement terminé. La mise à jour sera installée au prochain d msgid "Error downloading the update: {error}" msgstr "Erreur lors du téléchargement de la mise à jour : {error}" +msgid "Report Result" +msgstr "Résultat du rapport" + #: update.py:112 msgid "Creating backup of current version before update..." msgstr "Création d'une sauvegarde de la version actuelle avant la mise à jour..." @@ -1086,6 +1309,9 @@ msgstr "Sauvegarde créée avec succès sous le nom {filename}." msgid "Warning: Could not create backup. Error: {error}" msgstr "Avertissement : Impossible de créer la sauvegarde. Erreur : {error}" +msgid "This feature is available in the CLI. GUI implementation coming soon." +msgstr "Cette fonctionnalité est disponible en CLI. L'implémentation GUI arrive bientôt." + #: update.py:125 msgid "Installing update..." msgstr "Installation de la mise à jour..." @@ -1098,6 +1324,9 @@ msgstr "Fichier protégé ignoré : {filename}. Il ne sera pas écrasé." msgid "Update installed successfully." msgstr "Mise à jour installée avec succès." +msgid "Time Control" +msgstr "Contrôle du temps" + #: update.py:154 msgid "Error during update installation: {error}" msgstr "Erreur lors de l'installation de la mise à jour : {error}"