bouquin 0.4.1__tar.gz → 0.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bouquin-0.4.1 → bouquin-0.4.2}/PKG-INFO +1 -1
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/bug_report_dialog.py +1 -8
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/db.py +7 -11
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/key_prompt.py +3 -2
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/locales/en.json +21 -19
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/locales/fr.json +0 -12
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/locales/it.json +1 -13
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/main_window.py +67 -16
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/markdown_editor.py +3 -3
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/save_dialog.py +13 -1
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/settings.py +9 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/settings_dialog.py +128 -61
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/statistics_dialog.py +2 -1
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/toolbar.py +19 -3
- {bouquin-0.4.1 → bouquin-0.4.2}/pyproject.toml +1 -1
- {bouquin-0.4.1 → bouquin-0.4.2}/LICENSE +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/README.md +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/__init__.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/__main__.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/find_bar.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/flow_layout.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/history_dialog.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/lock_overlay.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/main.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/markdown_highlighter.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/search.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/strings.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/tag_browser.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/tags_widget.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/theme.py +0 -0
- {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/time_log.py +0 -0
|
@@ -70,10 +70,6 @@ class BugReportDialog(QDialog):
|
|
|
70
70
|
self.text_edit.setPlainText(text[: self.MAX_CHARS])
|
|
71
71
|
self.text_edit.blockSignals(False)
|
|
72
72
|
|
|
73
|
-
# Clamp cursor position to end of text
|
|
74
|
-
if pos > self.MAX_CHARS:
|
|
75
|
-
pos = self.MAX_CHARS
|
|
76
|
-
|
|
77
73
|
cursor.setPosition(pos)
|
|
78
74
|
self.text_edit.setTextCursor(cursor)
|
|
79
75
|
|
|
@@ -88,10 +84,7 @@ class BugReportDialog(QDialog):
|
|
|
88
84
|
return
|
|
89
85
|
|
|
90
86
|
# Get current app version
|
|
91
|
-
|
|
92
|
-
version = importlib.metadata.version("bouquin")
|
|
93
|
-
except importlib.metadata.PackageNotFoundError:
|
|
94
|
-
version = "unknown"
|
|
87
|
+
version = importlib.metadata.version("bouquin")
|
|
95
88
|
|
|
96
89
|
payload: dict[str, str] = {
|
|
97
90
|
"message": text,
|
|
@@ -61,7 +61,10 @@ class DBConfig:
|
|
|
61
61
|
idle_minutes: int = 15 # 0 = never lock
|
|
62
62
|
theme: str = "system"
|
|
63
63
|
move_todos: bool = False
|
|
64
|
+
tags: bool = True
|
|
65
|
+
time_log: bool = True
|
|
64
66
|
locale: str = "en"
|
|
67
|
+
font_size: int = 11
|
|
65
68
|
|
|
66
69
|
|
|
67
70
|
class DBManager:
|
|
@@ -734,12 +737,8 @@ class DBManager:
|
|
|
734
737
|
page_most_revisions_count = c
|
|
735
738
|
page_most_revisions = date_iso
|
|
736
739
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
revisions_by_date[d] = c
|
|
740
|
-
except ValueError:
|
|
741
|
-
# Ignore malformed dates
|
|
742
|
-
pass
|
|
740
|
+
d = _dt.date.fromisoformat(date_iso)
|
|
741
|
+
revisions_by_date[d] = c
|
|
743
742
|
|
|
744
743
|
# 4) total words + per-date words (current version only)
|
|
745
744
|
entries = self.get_all_entries()
|
|
@@ -749,11 +748,8 @@ class DBManager:
|
|
|
749
748
|
for date_iso, content in entries:
|
|
750
749
|
wc = self._count_words(content or "")
|
|
751
750
|
total_words += wc
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
words_by_date[d] = wc
|
|
755
|
-
except ValueError:
|
|
756
|
-
pass
|
|
751
|
+
d = _dt.date.fromisoformat(date_iso)
|
|
752
|
+
words_by_date[d] = wc
|
|
757
753
|
|
|
758
754
|
# tags + page with most tags
|
|
759
755
|
|
|
@@ -99,8 +99,9 @@ class KeyPrompt(QDialog):
|
|
|
99
99
|
|
|
100
100
|
def db_path(self) -> Path | None:
|
|
101
101
|
"""Return the chosen DB path (or None if unchanged/not shown)."""
|
|
102
|
+
p = self._db_path
|
|
102
103
|
if self.path_edit is not None:
|
|
103
104
|
text = self.path_edit.text().strip()
|
|
104
105
|
if text:
|
|
105
|
-
|
|
106
|
-
return
|
|
106
|
+
p = Path(text)
|
|
107
|
+
return p
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
"db_version_id_does_not_belong_to_the_given_date": "version_id does not belong to the given date",
|
|
6
6
|
"db_key_incorrect": "The key is probably incorrect",
|
|
7
7
|
"db_database_error": "Database error",
|
|
8
|
-
"database_path": "Database path",
|
|
9
8
|
"database_maintenance": "Database maintenance",
|
|
10
9
|
"database_compact": "Compact the database",
|
|
11
10
|
"database_compact_explanation": "Compacting runs VACUUM on the database. This can help reduce its size.",
|
|
@@ -26,16 +25,14 @@
|
|
|
26
25
|
"close": "Close",
|
|
27
26
|
"find": "Find",
|
|
28
27
|
"file": "File",
|
|
29
|
-
"locale": "
|
|
28
|
+
"locale": "Language",
|
|
30
29
|
"locale_restart": "Please restart the application to load the new language.",
|
|
31
30
|
"settings": "Settings",
|
|
32
31
|
"theme": "Theme",
|
|
33
32
|
"system": "System",
|
|
34
33
|
"light": "Light",
|
|
35
34
|
"dark": "Dark",
|
|
36
|
-
"behaviour": "Behaviour",
|
|
37
35
|
"never": "Never",
|
|
38
|
-
"browse": "Browse",
|
|
39
36
|
"close_tab": "Close tab",
|
|
40
37
|
"previous": "Previous",
|
|
41
38
|
"previous_day": "Previous day",
|
|
@@ -45,7 +42,6 @@
|
|
|
45
42
|
"show": "Show",
|
|
46
43
|
"history": "History",
|
|
47
44
|
"view_history": "View History",
|
|
48
|
-
"export": "Export",
|
|
49
45
|
"export_accessible_flag": "&Export",
|
|
50
46
|
"export_entries": "Export entries",
|
|
51
47
|
"export_complete": "Export complete",
|
|
@@ -98,15 +94,23 @@
|
|
|
98
94
|
"backup_encrypted_notebook": "Backup encrypted notebook",
|
|
99
95
|
"enter_a_name_for_this_version": "Enter a name for this version",
|
|
100
96
|
"new_version_i_saved_at": "New version I saved at",
|
|
97
|
+
"appearance": "Appearance",
|
|
98
|
+
"security": "Security",
|
|
99
|
+
"features": "Features",
|
|
100
|
+
"database": "Database",
|
|
101
101
|
"save_key_warning": "If you don't want to be prompted for your encryption key, check this to remember it.\nWARNING: the key is saved to disk and could be recoverable if your disk is compromised.",
|
|
102
102
|
"lock_screen_when_idle": "Lock screen when idle",
|
|
103
|
-
"autolock_explanation": "Bouquin will automatically lock the notepad after this length of time, after which you'll need to re-enter the key to unlock it
|
|
103
|
+
"autolock_explanation": "Bouquin will automatically lock the notepad after this length of time, after which you'll need to re-enter the key to unlock it.\nSet to 0 (never) to never lock.",
|
|
104
|
+
"font_size": "Font size",
|
|
105
|
+
"font_size_explanation": "Changing this value will change the size of all paragraph text in all tabs. It does not affect heading or code block size",
|
|
104
106
|
"search_for_notes_here": "Search for notes here",
|
|
105
107
|
"toolbar_format": "Format",
|
|
106
108
|
"toolbar_bold": "Bold",
|
|
107
109
|
"toolbar_italic": "Italic",
|
|
108
110
|
"toolbar_strikethrough": "Strikethrough",
|
|
109
111
|
"toolbar_normal_paragraph_text": "Normal paragraph text",
|
|
112
|
+
"toolbar_font_smaller": "Smaller text",
|
|
113
|
+
"toolbar_font_larger": "Larger text",
|
|
110
114
|
"toolbar_bulleted_list": "Bulleted list",
|
|
111
115
|
"toolbar_numbered_list": "Numbered list",
|
|
112
116
|
"toolbar_code_block": "Code block",
|
|
@@ -115,20 +119,11 @@
|
|
|
115
119
|
"tags": "Tags",
|
|
116
120
|
"tag": "Tag",
|
|
117
121
|
"manage_tags": "Manage tags",
|
|
118
|
-
"main_window_manage_tags_accessible_flag": "Manage &Tags",
|
|
119
122
|
"add_tag_placeholder": "Add a tag and press Enter",
|
|
120
123
|
"tag_browser_title": "Tag Browser",
|
|
121
124
|
"tag_browser_instructions": "Click a tag to expand and see all pages with that tag. Click a date to open it. Select a tag to edit its name, change its color, or delete it globally.",
|
|
122
|
-
"tag_name": "Tag name",
|
|
123
|
-
"tag_color_hex": "Hex colour",
|
|
124
125
|
"color_hex": "Colour",
|
|
125
126
|
"date": "Date",
|
|
126
|
-
"pick_color": "Pick colour",
|
|
127
|
-
"invalid_color_title": "Invalid colour",
|
|
128
|
-
"invalid_color_message": "Please enter a valid hex colour like #RRGGBB.",
|
|
129
|
-
"add": "Add",
|
|
130
|
-
"remove": "Remove",
|
|
131
|
-
"ok": "OK",
|
|
132
127
|
"add_a_tag": "Add a tag",
|
|
133
128
|
"edit_tag_name": "Edit tag name",
|
|
134
129
|
"new_tag_name": "New tag name:",
|
|
@@ -156,6 +151,7 @@
|
|
|
156
151
|
"bug_report_send_failed": "Could not send bug report.",
|
|
157
152
|
"bug_report_sent_ok": "Bug report sent. Thank you!",
|
|
158
153
|
"send": "Send",
|
|
154
|
+
"reminder": "Reminder",
|
|
159
155
|
"set_reminder": "Set reminder prompt",
|
|
160
156
|
"set_reminder_prompt": "Enter a time",
|
|
161
157
|
"reminder_no_text_fallback": "You scheduled a reminder to alert you now!",
|
|
@@ -193,7 +189,6 @@
|
|
|
193
189
|
"invalid_activity_title": "Invalid activity",
|
|
194
190
|
"invalid_project_message": "The project is invalid",
|
|
195
191
|
"invalid_project_title": "Invalid project",
|
|
196
|
-
"label_key": "Label",
|
|
197
192
|
"manage_activities": "Manage activities",
|
|
198
193
|
"manage_projects": "Manage projects",
|
|
199
194
|
"manage_projects_activities": "Manage project activities",
|
|
@@ -209,8 +204,14 @@
|
|
|
209
204
|
"rename_activity": "Rename activity",
|
|
210
205
|
"rename_project": "Rename project",
|
|
211
206
|
"run_report": "Run report",
|
|
212
|
-
"
|
|
207
|
+
"add_activity_title": "Add activity",
|
|
213
208
|
"add_activity_label": "Add an activity",
|
|
209
|
+
"rename_activity_label": "Rename activity",
|
|
210
|
+
"add_project_title": "Add project",
|
|
211
|
+
"add_project_label": "Add a project",
|
|
212
|
+
"rename_activity_title": "Rename this activity",
|
|
213
|
+
"rename_project_label": "Rename project",
|
|
214
|
+
"rename_project_title": "Rename this project",
|
|
214
215
|
"select_activity_message": "Select an activity",
|
|
215
216
|
"select_activity_title": "Select activity",
|
|
216
217
|
"select_project_message": "Select a project",
|
|
@@ -227,7 +228,6 @@
|
|
|
227
228
|
"time_log_total_hours": "Total time spent",
|
|
228
229
|
"time_log_with_total": "Time log ({hours:.2f}h)",
|
|
229
230
|
"time_log_total_hours": "Total for day: {hours:.2f}h",
|
|
230
|
-
"title_key": "title",
|
|
231
231
|
"update_time_entry": "Update time entry",
|
|
232
232
|
"time_report_total": "Total: {hours:.2f} hours",
|
|
233
233
|
"no_report_title": "No report",
|
|
@@ -238,5 +238,7 @@
|
|
|
238
238
|
"export_csv_error_message": "Could not write CSV file:\n{error}",
|
|
239
239
|
"export_pdf": "Export PDF",
|
|
240
240
|
"export_pdf_error_title": "PDF export failed",
|
|
241
|
-
"export_pdf_error_message": "Could not write PDF file:\n{error}"
|
|
241
|
+
"export_pdf_error_message": "Could not write PDF file:\n{error}",
|
|
242
|
+
"enable_tags_feature": "Enable Tags",
|
|
243
|
+
"enable_time_log_feature": "Enable Time Logging"
|
|
242
244
|
}
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
"db_version_id_does_not_belong_to_the_given_date": "version_id ne correspond pas à la date indiquée",
|
|
6
6
|
"db_key_incorrect": "La clé est peut-être incorrecte",
|
|
7
7
|
"db_database_error": "Erreur de base de données",
|
|
8
|
-
"database_path": "Chemin de la base de données",
|
|
9
8
|
"database_maintenance": "Maintenance de la base de données",
|
|
10
9
|
"database_compact": "Compacter la base de données",
|
|
11
10
|
"database_compact_explanation": "La compaction exécute VACUUM sur la base de données. Cela peut aider à réduire sa taille.",
|
|
@@ -33,9 +32,7 @@
|
|
|
33
32
|
"system": "Système",
|
|
34
33
|
"light": "Clair",
|
|
35
34
|
"dark": "Sombre",
|
|
36
|
-
"behaviour": "Comportement",
|
|
37
35
|
"never": "Jamais",
|
|
38
|
-
"browse": "Parcourir",
|
|
39
36
|
"previous": "Précédent",
|
|
40
37
|
"previous_day": "Jour précédent",
|
|
41
38
|
"next": "Suivant",
|
|
@@ -44,7 +41,6 @@
|
|
|
44
41
|
"show": "Afficher",
|
|
45
42
|
"history": "Historique",
|
|
46
43
|
"view_history": "Afficher l'historique",
|
|
47
|
-
"export": "Exporter",
|
|
48
44
|
"export_accessible_flag": "E&xporter",
|
|
49
45
|
"export_entries": "Exporter les entrées",
|
|
50
46
|
"export_complete": "Exportation terminée",
|
|
@@ -117,16 +113,8 @@
|
|
|
117
113
|
"add_tag_placeholder": "Ajouter une étiquette et appuyez sur Entrée",
|
|
118
114
|
"tag_browser_title": "Navigateur de étiquettes",
|
|
119
115
|
"tag_browser_instructions": "Cliquez sur une étiquette pour l'étendre et voir toutes les pages avec cette étiquette. Cliquez sur une date pour l'ouvrir. Sélectionnez une étiquette pour modifier son nom, changer sa couleur ou la supprimer globalement.",
|
|
120
|
-
"tag_name": "Nom de l'étiquette",
|
|
121
|
-
"tag_color_hex": "Couleur hexadécimale",
|
|
122
116
|
"color_hex": "Couleur",
|
|
123
117
|
"date": "Date",
|
|
124
|
-
"pick_color": "Choisir la couleur",
|
|
125
|
-
"invalid_color_title": "Couleur invalide",
|
|
126
|
-
"invalid_color_message": "Veuillez entrer une couleur hexadécimale valide comme #RRGGBB.",
|
|
127
|
-
"add": "Ajouter",
|
|
128
|
-
"remove": "Supprimer",
|
|
129
|
-
"ok": "OK",
|
|
130
118
|
"add_a_tag": "Ajouter une étiquette",
|
|
131
119
|
"edit_tag_name": "Modifier le nom de l'étiquette",
|
|
132
120
|
"new_tag_name": "Nouveau nom de l'étiquette :",
|
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
"db_issues_reported": "problema/i segnalato/i",
|
|
4
4
|
"db_reopen_failed_after_rekey": "Riapertura fallita dopo il cambio chiave",
|
|
5
5
|
"db_version_id_does_not_belong_to_the_given_date": "version_id non appartiene alla data indicata",
|
|
6
|
-
"db_key_incorrect": "La chiave è probabilmente errata",
|
|
7
6
|
"db_database_error": "Errore del database",
|
|
8
|
-
"
|
|
7
|
+
"db_key_incorrect": "La chiave è probabilmente errata",
|
|
9
8
|
"database_maintenance": "Manutenzione del database",
|
|
10
9
|
"database_compact": "Compatta il database",
|
|
11
10
|
"database_compact_explanation": "La compattazione esegue VACUUM sul database. Può aiutare a ridurne le dimensioni.",
|
|
@@ -33,9 +32,7 @@
|
|
|
33
32
|
"system": "Sistema",
|
|
34
33
|
"light": "Chiaro",
|
|
35
34
|
"dark": "Scuro",
|
|
36
|
-
"behaviour": "Comportamento",
|
|
37
35
|
"never": "Mai",
|
|
38
|
-
"browse": "Sfoglia",
|
|
39
36
|
"previous": "Precedente",
|
|
40
37
|
"previous_day": "Giorno precedente",
|
|
41
38
|
"next": "Successivo",
|
|
@@ -44,7 +41,6 @@
|
|
|
44
41
|
"show": "Mostra",
|
|
45
42
|
"history": "Cronologia",
|
|
46
43
|
"view_history": "Visualizza cronologia",
|
|
47
|
-
"export": "Esporta",
|
|
48
44
|
"export_accessible_flag": "&Esporta",
|
|
49
45
|
"export_entries": "Esporta voci",
|
|
50
46
|
"export_complete": "Esportazione completata",
|
|
@@ -116,16 +112,8 @@
|
|
|
116
112
|
"add_tag_placeholder": "Aggiungi un tag e premi Invio",
|
|
117
113
|
"tag_browser_title": "Browser dei tag",
|
|
118
114
|
"tag_browser_instructions": "Fai clic su un tag per espandere e vedere tutte le pagine con quel tag. Fai clic su una data per aprirla. Seleziona un tag per modificarne il nome, cambiarne il colore o eliminarlo globalmente.",
|
|
119
|
-
"tag_name": "Nome del tag",
|
|
120
|
-
"tag_color_hex": "Colore esadecimale",
|
|
121
115
|
"color_hex": "Colore",
|
|
122
116
|
"date": "Data",
|
|
123
|
-
"pick_color": "Scegli colore",
|
|
124
|
-
"invalid_color_title": "Colore non valido",
|
|
125
|
-
"invalid_color_message": "Inserisci un colore esadecimale valido come #RRGGBB.",
|
|
126
|
-
"add": "Aggiungi",
|
|
127
|
-
"remove": "Rimuovi",
|
|
128
|
-
"ok": "OK",
|
|
129
117
|
"add_a_tag": "Aggiungi un tag",
|
|
130
118
|
"edit_tag_name": "Modifica nome tag",
|
|
131
119
|
"new_tag_name": "Nuovo nome tag:",
|
|
@@ -66,7 +66,7 @@ from .statistics_dialog import StatisticsDialog
|
|
|
66
66
|
from . import strings
|
|
67
67
|
from .tags_widget import PageTagsWidget
|
|
68
68
|
from .theme import ThemeManager
|
|
69
|
-
from .time_log import TimeLogWidget
|
|
69
|
+
from .time_log import TimeLogWidget
|
|
70
70
|
from .toolbar import ToolBar
|
|
71
71
|
|
|
72
72
|
|
|
@@ -92,6 +92,8 @@ class MainWindow(QMainWindow):
|
|
|
92
92
|
else:
|
|
93
93
|
self._try_connect()
|
|
94
94
|
|
|
95
|
+
self.settings = QSettings(APP_ORG, APP_NAME)
|
|
96
|
+
|
|
95
97
|
# ---- UI: Left fixed panel (calendar) + right editor -----------------
|
|
96
98
|
self.calendar = QCalendarWidget()
|
|
97
99
|
self.calendar.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
|
@@ -219,18 +221,10 @@ class MainWindow(QMainWindow):
|
|
|
219
221
|
act_backup.setShortcut("Ctrl+Shift+B")
|
|
220
222
|
act_backup.triggered.connect(self._backup)
|
|
221
223
|
file_menu.addAction(act_backup)
|
|
222
|
-
act_tags = QAction(strings._("main_window_manage_tags_accessible_flag"), self)
|
|
223
|
-
act_tags.setShortcut("Ctrl+T")
|
|
224
|
-
act_tags.triggered.connect(self.tags._open_manager)
|
|
225
|
-
file_menu.addAction(act_tags)
|
|
226
224
|
act_stats = QAction(strings._("main_window_statistics_accessible_flag"), self)
|
|
227
225
|
act_stats.setShortcut("Shift+Ctrl+S")
|
|
228
226
|
act_stats.triggered.connect(self._open_statistics)
|
|
229
227
|
file_menu.addAction(act_stats)
|
|
230
|
-
act_time_report = QAction(strings._("time_log_report"), self)
|
|
231
|
-
act_time_report.setShortcut("Ctrl+Shift+L")
|
|
232
|
-
act_time_report.triggered.connect(self._open_time_report)
|
|
233
|
-
file_menu.addAction(act_time_report)
|
|
234
228
|
file_menu.addSeparator()
|
|
235
229
|
act_quit = QAction("&" + strings._("quit"), self)
|
|
236
230
|
act_quit.setShortcut("Ctrl+Q")
|
|
@@ -320,8 +314,13 @@ class MainWindow(QMainWindow):
|
|
|
320
314
|
self._load_selected_date()
|
|
321
315
|
self._refresh_calendar_marks()
|
|
322
316
|
|
|
317
|
+
# Hide tags and time log widgets if not enabled
|
|
318
|
+
if not self.cfg.tags:
|
|
319
|
+
self.tags.hide()
|
|
320
|
+
if not self.cfg.time_log:
|
|
321
|
+
self.time_log.hide()
|
|
322
|
+
|
|
323
323
|
# Restore window position from settings
|
|
324
|
-
self.settings = QSettings(APP_ORG, APP_NAME)
|
|
325
324
|
self._restore_window_position()
|
|
326
325
|
|
|
327
326
|
# re-apply all runtime color tweaks when theme changes
|
|
@@ -487,6 +486,9 @@ class MainWindow(QMainWindow):
|
|
|
487
486
|
|
|
488
487
|
editor = MarkdownEditor(self.themes)
|
|
489
488
|
|
|
489
|
+
# Apply user’s preferred font size
|
|
490
|
+
self._apply_font_size(editor)
|
|
491
|
+
|
|
490
492
|
# Set up the editor's event connections
|
|
491
493
|
editor.currentCharFormatChanged.connect(lambda _f: self._sync_toolbar())
|
|
492
494
|
editor.cursorPositionChanged.connect(self._sync_toolbar)
|
|
@@ -914,6 +916,17 @@ class MainWindow(QMainWindow):
|
|
|
914
916
|
pass
|
|
915
917
|
|
|
916
918
|
# ----------------- Some theme helpers -------------------#
|
|
919
|
+
def _apply_font_size(self, editor: MarkdownEditor) -> None:
|
|
920
|
+
"""Apply the saved font size to a newly created editor."""
|
|
921
|
+
size = self.cfg.font_size
|
|
922
|
+
editor.qfont.setPointSize(size)
|
|
923
|
+
editor.setFont(editor.qfont)
|
|
924
|
+
self.cfg.font_size = size
|
|
925
|
+
# save size to settings
|
|
926
|
+
cfg = load_db_config()
|
|
927
|
+
cfg.font_size = self.cfg.font_size
|
|
928
|
+
save_db_config(cfg)
|
|
929
|
+
|
|
917
930
|
def _retheme_overrides(self):
|
|
918
931
|
self._apply_calendar_text_colors()
|
|
919
932
|
self._apply_search_highlights(getattr(self, "_search_highlighted_dates", set()))
|
|
@@ -997,6 +1010,8 @@ class MainWindow(QMainWindow):
|
|
|
997
1010
|
self._tb_numbers = lambda: self._call_editor("toggle_numbers")
|
|
998
1011
|
self._tb_checkboxes = lambda: self._call_editor("toggle_checkboxes")
|
|
999
1012
|
self._tb_alarm = self._on_alarm_requested
|
|
1013
|
+
self._tb_font_larger = self._on_font_larger_requested
|
|
1014
|
+
self._tb_font_smaller = self._on_font_smaller_requested
|
|
1000
1015
|
|
|
1001
1016
|
tb.boldRequested.connect(self._tb_bold)
|
|
1002
1017
|
tb.italicRequested.connect(self._tb_italic)
|
|
@@ -1009,6 +1024,8 @@ class MainWindow(QMainWindow):
|
|
|
1009
1024
|
tb.alarmRequested.connect(self._tb_alarm)
|
|
1010
1025
|
tb.insertImageRequested.connect(self._on_insert_image)
|
|
1011
1026
|
tb.historyRequested.connect(self._open_history)
|
|
1027
|
+
tb.fontSizeLargerRequested.connect(self._tb_font_larger)
|
|
1028
|
+
tb.fontSizeSmallerRequested.connect(self._tb_font_smaller)
|
|
1012
1029
|
|
|
1013
1030
|
self._toolbar_bound = True
|
|
1014
1031
|
|
|
@@ -1054,6 +1071,34 @@ class MainWindow(QMainWindow):
|
|
|
1054
1071
|
self.toolBar.actBullets.setChecked(bool(bullets_on))
|
|
1055
1072
|
self.toolBar.actNumbers.setChecked(bool(numbers_on))
|
|
1056
1073
|
|
|
1074
|
+
def _change_font_size(self, delta: int) -> None:
|
|
1075
|
+
"""Change font size for all editor tabs and save the setting."""
|
|
1076
|
+
old_size = self.cfg.font_size
|
|
1077
|
+
new_size = old_size + delta
|
|
1078
|
+
|
|
1079
|
+
self.cfg.font_size = new_size
|
|
1080
|
+
# save size to settings
|
|
1081
|
+
cfg = load_db_config()
|
|
1082
|
+
cfg.font_size = self.cfg.font_size
|
|
1083
|
+
save_db_config(cfg)
|
|
1084
|
+
|
|
1085
|
+
# Apply font size change to all open editors
|
|
1086
|
+
self._apply_font_size_to_all_tabs(new_size)
|
|
1087
|
+
|
|
1088
|
+
def _apply_font_size_to_all_tabs(self, size: int) -> None:
|
|
1089
|
+
for i in range(self.tab_widget.count()):
|
|
1090
|
+
ed = self.tab_widget.widget(i)
|
|
1091
|
+
if not isinstance(ed, MarkdownEditor):
|
|
1092
|
+
continue
|
|
1093
|
+
ed.qfont.setPointSize(size)
|
|
1094
|
+
ed.setFont(ed.qfont)
|
|
1095
|
+
|
|
1096
|
+
def _on_font_larger_requested(self) -> None:
|
|
1097
|
+
self._change_font_size(+1)
|
|
1098
|
+
|
|
1099
|
+
def _on_font_smaller_requested(self) -> None:
|
|
1100
|
+
self._change_font_size(-1)
|
|
1101
|
+
|
|
1057
1102
|
# ----------- Alarms handler ------------#
|
|
1058
1103
|
def _on_alarm_requested(self):
|
|
1059
1104
|
"""Create a one-shot reminder based on the current line in the editor."""
|
|
@@ -1320,13 +1365,17 @@ class MainWindow(QMainWindow):
|
|
|
1320
1365
|
self.cfg.idle_minutes = getattr(new_cfg, "idle_minutes", self.cfg.idle_minutes)
|
|
1321
1366
|
self.cfg.theme = getattr(new_cfg, "theme", self.cfg.theme)
|
|
1322
1367
|
self.cfg.move_todos = getattr(new_cfg, "move_todos", self.cfg.move_todos)
|
|
1368
|
+
self.cfg.tags = getattr(new_cfg, "tags", self.cfg.tags)
|
|
1369
|
+
self.cfg.time_log = getattr(new_cfg, "time_log", self.cfg.time_log)
|
|
1323
1370
|
self.cfg.locale = getattr(new_cfg, "locale", self.cfg.locale)
|
|
1371
|
+
self.cfg.font_size = getattr(new_cfg, "font_size", self.cfg.font_size)
|
|
1324
1372
|
|
|
1325
1373
|
# Persist once
|
|
1326
1374
|
save_db_config(self.cfg)
|
|
1327
|
-
|
|
1328
1375
|
# Apply idle setting immediately (restart the timer with new interval if it changed)
|
|
1329
1376
|
self._apply_idle_minutes(self.cfg.idle_minutes)
|
|
1377
|
+
# Apply font size to all tabs
|
|
1378
|
+
self._apply_font_size_to_all_tabs(self.cfg.font_size)
|
|
1330
1379
|
|
|
1331
1380
|
# If the DB path changed, reconnect
|
|
1332
1381
|
if self.cfg.path != old_path:
|
|
@@ -1341,6 +1390,13 @@ class MainWindow(QMainWindow):
|
|
|
1341
1390
|
self._load_selected_date()
|
|
1342
1391
|
self._refresh_calendar_marks()
|
|
1343
1392
|
|
|
1393
|
+
# Show or hide the tags and time_log features depending on what the settings are now.
|
|
1394
|
+
self.tags.hide() if not self.cfg.tags else self.tags.show()
|
|
1395
|
+
if not self.cfg.time_log:
|
|
1396
|
+
self.time_log.hide()
|
|
1397
|
+
else:
|
|
1398
|
+
self.time_log.show()
|
|
1399
|
+
|
|
1344
1400
|
# ------------ Statistics handler --------------- #
|
|
1345
1401
|
|
|
1346
1402
|
def _open_statistics(self):
|
|
@@ -1358,11 +1414,6 @@ class MainWindow(QMainWindow):
|
|
|
1358
1414
|
dlg._heatmap.date_clicked.connect(on_date_clicked)
|
|
1359
1415
|
dlg.exec()
|
|
1360
1416
|
|
|
1361
|
-
# ------------ Timesheet report handler --------------- #
|
|
1362
|
-
def _open_time_report(self):
|
|
1363
|
-
dlg = TimeReportDialog(self.db, self)
|
|
1364
|
-
dlg.exec()
|
|
1365
|
-
|
|
1366
1417
|
# ------------ Window positioning --------------- #
|
|
1367
1418
|
def _restore_window_position(self):
|
|
1368
1419
|
geom = self.settings.value("main/geometry", None)
|
|
@@ -41,9 +41,9 @@ class MarkdownEditor(QTextEdit):
|
|
|
41
41
|
self.setAcceptRichText(False)
|
|
42
42
|
|
|
43
43
|
# Normal text
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
self.setFont(
|
|
44
|
+
self.qfont = QFont()
|
|
45
|
+
self.qfont.setPointSize(11)
|
|
46
|
+
self.setFont(self.qfont)
|
|
47
47
|
|
|
48
48
|
self._apply_line_spacing() # 1.25× initial spacing
|
|
49
49
|
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import datetime
|
|
4
4
|
|
|
5
|
+
from PySide6.QtGui import QFontMetrics
|
|
5
6
|
from PySide6.QtWidgets import (
|
|
6
7
|
QDialog,
|
|
7
8
|
QVBoxLayout,
|
|
@@ -22,13 +23,24 @@ class SaveDialog(QDialog):
|
|
|
22
23
|
Used for explicitly saving a new version of a page.
|
|
23
24
|
"""
|
|
24
25
|
super().__init__(parent)
|
|
26
|
+
|
|
25
27
|
self.setWindowTitle(strings._("enter_a_name_for_this_version"))
|
|
28
|
+
|
|
26
29
|
v = QVBoxLayout(self)
|
|
27
30
|
v.addWidget(QLabel(strings._("enter_a_name_for_this_version")))
|
|
31
|
+
|
|
28
32
|
self.note = QLineEdit()
|
|
29
33
|
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
30
|
-
|
|
34
|
+
text = strings._("new_version_i_saved_at") + f" {now}"
|
|
35
|
+
self.note.setText(text)
|
|
31
36
|
v.addWidget(self.note)
|
|
37
|
+
|
|
38
|
+
# make dialog wide enough for the line edit text
|
|
39
|
+
fm = QFontMetrics(self.note.font())
|
|
40
|
+
text_width = fm.horizontalAdvance(text) + 20
|
|
41
|
+
self.note.setMinimumWidth(text_width)
|
|
42
|
+
self.adjustSize()
|
|
43
|
+
|
|
32
44
|
bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
|
33
45
|
bb.accepted.connect(self.accept)
|
|
34
46
|
bb.rejected.connect(self.reject)
|
|
@@ -41,14 +41,20 @@ def load_db_config() -> DBConfig:
|
|
|
41
41
|
idle = s.value("ui/idle_minutes", 15, type=int)
|
|
42
42
|
theme = s.value("ui/theme", "system", type=str)
|
|
43
43
|
move_todos = s.value("ui/move_todos", False, type=bool)
|
|
44
|
+
tags = s.value("ui/tags", True, type=bool)
|
|
45
|
+
time_log = s.value("ui/time_log", True, type=bool)
|
|
44
46
|
locale = s.value("ui/locale", "en", type=str)
|
|
47
|
+
font_size = s.value("ui/font_size", 11, type=int)
|
|
45
48
|
return DBConfig(
|
|
46
49
|
path=path,
|
|
47
50
|
key=key,
|
|
48
51
|
idle_minutes=idle,
|
|
49
52
|
theme=theme,
|
|
50
53
|
move_todos=move_todos,
|
|
54
|
+
tags=tags,
|
|
55
|
+
time_log=time_log,
|
|
51
56
|
locale=locale,
|
|
57
|
+
font_size=font_size,
|
|
52
58
|
)
|
|
53
59
|
|
|
54
60
|
|
|
@@ -59,4 +65,7 @@ def save_db_config(cfg: DBConfig) -> None:
|
|
|
59
65
|
s.setValue("ui/idle_minutes", str(cfg.idle_minutes))
|
|
60
66
|
s.setValue("ui/theme", str(cfg.theme))
|
|
61
67
|
s.setValue("ui/move_todos", str(cfg.move_todos))
|
|
68
|
+
s.setValue("ui/tags", str(cfg.tags))
|
|
69
|
+
s.setValue("ui/time_log", str(cfg.time_log))
|
|
62
70
|
s.setValue("ui/locale", str(cfg.locale))
|
|
71
|
+
s.setValue("ui/font_size", str(cfg.font_size))
|
|
@@ -6,7 +6,6 @@ from PySide6.QtWidgets import (
|
|
|
6
6
|
QCheckBox,
|
|
7
7
|
QComboBox,
|
|
8
8
|
QDialog,
|
|
9
|
-
QFormLayout,
|
|
10
9
|
QFrame,
|
|
11
10
|
QGroupBox,
|
|
12
11
|
QLabel,
|
|
@@ -18,6 +17,8 @@ from PySide6.QtWidgets import (
|
|
|
18
17
|
QSizePolicy,
|
|
19
18
|
QSpinBox,
|
|
20
19
|
QMessageBox,
|
|
20
|
+
QWidget,
|
|
21
|
+
QTabWidget,
|
|
21
22
|
)
|
|
22
23
|
from PySide6.QtCore import Qt, Slot
|
|
23
24
|
from PySide6.QtGui import QPalette
|
|
@@ -39,14 +40,45 @@ class SettingsDialog(QDialog):
|
|
|
39
40
|
self._db = db
|
|
40
41
|
self.key = ""
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
self.setMinimumWidth(
|
|
43
|
+
self.current_settings = load_db_config()
|
|
44
|
+
|
|
45
|
+
self.setMinimumWidth(480)
|
|
45
46
|
self.setSizeGripEnabled(True)
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
# --- Tabs ----------------------------------------------------------
|
|
49
|
+
tabs = QTabWidget()
|
|
50
|
+
tabs.setTabPosition(QTabWidget.North)
|
|
51
|
+
tabs.setDocumentMode(True)
|
|
52
|
+
tabs.setMovable(False)
|
|
53
|
+
|
|
54
|
+
tabs.addTab(self._create_appearance_page(cfg), strings._("appearance"))
|
|
55
|
+
tabs.addTab(self._create_features_page(), strings._("features"))
|
|
56
|
+
tabs.addTab(self._create_security_page(cfg), strings._("security"))
|
|
57
|
+
tabs.addTab(self._create_database_page(), strings._("database"))
|
|
48
58
|
|
|
49
|
-
#
|
|
59
|
+
# --- Buttons -------------------------------------------------------
|
|
60
|
+
bb = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel)
|
|
61
|
+
bb.accepted.connect(self._save)
|
|
62
|
+
bb.rejected.connect(self.reject)
|
|
63
|
+
|
|
64
|
+
# Root layout
|
|
65
|
+
root = QVBoxLayout(self)
|
|
66
|
+
root.setContentsMargins(12, 12, 12, 12)
|
|
67
|
+
root.setSpacing(8)
|
|
68
|
+
root.addWidget(tabs)
|
|
69
|
+
root.addWidget(bb, 0, Qt.AlignRight)
|
|
70
|
+
|
|
71
|
+
# ------------------------------------------------------------------ #
|
|
72
|
+
# Pages
|
|
73
|
+
# ------------------------------------------------------------------ #
|
|
74
|
+
|
|
75
|
+
def _create_appearance_page(self, cfg: DBConfig) -> QWidget:
|
|
76
|
+
page = QWidget()
|
|
77
|
+
layout = QVBoxLayout(page)
|
|
78
|
+
layout.setContentsMargins(12, 12, 12, 12)
|
|
79
|
+
layout.setSpacing(12)
|
|
80
|
+
|
|
81
|
+
# --- Theme group --------------------------------------------------
|
|
50
82
|
theme_group = QGroupBox(strings._("theme"))
|
|
51
83
|
theme_layout = QVBoxLayout(theme_group)
|
|
52
84
|
|
|
@@ -54,7 +86,6 @@ class SettingsDialog(QDialog):
|
|
|
54
86
|
self.theme_light = QRadioButton(strings._("light"))
|
|
55
87
|
self.theme_dark = QRadioButton(strings._("dark"))
|
|
56
88
|
|
|
57
|
-
# Load current theme from settings
|
|
58
89
|
current_theme = self.current_settings.theme
|
|
59
90
|
if current_theme == Theme.DARK.value:
|
|
60
91
|
self.theme_dark.setChecked(True)
|
|
@@ -67,53 +98,98 @@ class SettingsDialog(QDialog):
|
|
|
67
98
|
theme_layout.addWidget(self.theme_light)
|
|
68
99
|
theme_layout.addWidget(self.theme_dark)
|
|
69
100
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
101
|
+
# font size row
|
|
102
|
+
font_row = QHBoxLayout()
|
|
103
|
+
self.font_heading = QLabel(strings._("font_size"))
|
|
104
|
+
self.font_size = QSpinBox()
|
|
105
|
+
self.font_size.setRange(1, 24)
|
|
106
|
+
self.font_size.setSingleStep(1)
|
|
107
|
+
self.font_size.setAccelerated(True)
|
|
108
|
+
self.font_size.setValue(getattr(cfg, "font_size", 11))
|
|
109
|
+
font_row.addWidget(self.font_heading)
|
|
110
|
+
font_row.addWidget(self.font_size)
|
|
111
|
+
font_row.addStretch()
|
|
112
|
+
theme_layout.addLayout(font_row)
|
|
113
|
+
|
|
114
|
+
# explanation
|
|
115
|
+
self.font_size_label = QLabel(strings._("font_size_explanation"))
|
|
116
|
+
self.font_size_label.setWordWrap(True)
|
|
117
|
+
self.font_size_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
118
|
+
pal = self.font_size_label.palette()
|
|
119
|
+
self.font_size_label.setForegroundRole(QPalette.PlaceholderText)
|
|
120
|
+
self.font_size_label.setPalette(pal)
|
|
121
|
+
|
|
122
|
+
font_exp_row = QHBoxLayout()
|
|
123
|
+
font_exp_row.setContentsMargins(24, 0, 0, 0)
|
|
124
|
+
font_exp_row.addWidget(self.font_size_label)
|
|
125
|
+
theme_layout.addLayout(font_exp_row)
|
|
126
|
+
|
|
127
|
+
layout.addWidget(theme_group)
|
|
128
|
+
|
|
129
|
+
# --- Locale group -------------------------------------------------
|
|
73
130
|
locale_group = QGroupBox(strings._("locale"))
|
|
74
131
|
locale_layout = QVBoxLayout(locale_group)
|
|
75
|
-
locale_layout.setContentsMargins(12, 8, 12, 12)
|
|
76
|
-
locale_layout.setSpacing(6)
|
|
77
132
|
|
|
78
133
|
self.locale_combobox = QComboBox()
|
|
79
134
|
self.locale_combobox.addItems(strings._AVAILABLE)
|
|
80
135
|
self.locale_combobox.setCurrentText(self.current_settings.locale)
|
|
81
136
|
locale_layout.addWidget(self.locale_combobox, 0, Qt.AlignLeft)
|
|
82
137
|
|
|
83
|
-
# Explanation for locale
|
|
84
138
|
self.locale_label = QLabel(strings._("locale_restart"))
|
|
85
139
|
self.locale_label.setWordWrap(True)
|
|
86
140
|
self.locale_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
87
|
-
# make it look secondary
|
|
88
141
|
lpal = self.locale_label.palette()
|
|
89
142
|
self.locale_label.setForegroundRole(QPalette.PlaceholderText)
|
|
90
143
|
self.locale_label.setPalette(lpal)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
locale_layout.addLayout(
|
|
95
|
-
|
|
144
|
+
loc_row = QHBoxLayout()
|
|
145
|
+
loc_row.setContentsMargins(24, 0, 0, 0)
|
|
146
|
+
loc_row.addWidget(self.locale_label)
|
|
147
|
+
locale_layout.addLayout(loc_row)
|
|
148
|
+
|
|
149
|
+
layout.addWidget(locale_group)
|
|
150
|
+
layout.addStretch()
|
|
151
|
+
return page
|
|
96
152
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
153
|
+
def _create_features_page(self) -> QWidget:
|
|
154
|
+
page = QWidget()
|
|
155
|
+
layout = QVBoxLayout(page)
|
|
156
|
+
layout.setContentsMargins(12, 12, 12, 12)
|
|
157
|
+
layout.setSpacing(12)
|
|
158
|
+
|
|
159
|
+
features_group = QGroupBox(strings._("features"))
|
|
160
|
+
features_layout = QVBoxLayout(features_group)
|
|
100
161
|
|
|
101
162
|
self.move_todos = QCheckBox(
|
|
102
163
|
strings._("move_yesterdays_unchecked_todos_to_today_on_startup")
|
|
103
164
|
)
|
|
104
165
|
self.move_todos.setChecked(self.current_settings.move_todos)
|
|
105
166
|
self.move_todos.setCursor(Qt.PointingHandCursor)
|
|
167
|
+
features_layout.addWidget(self.move_todos)
|
|
168
|
+
|
|
169
|
+
self.tags = QCheckBox(strings._("enable_tags_feature"))
|
|
170
|
+
self.tags.setChecked(self.current_settings.tags)
|
|
171
|
+
self.tags.setCursor(Qt.PointingHandCursor)
|
|
172
|
+
features_layout.addWidget(self.tags)
|
|
173
|
+
|
|
174
|
+
self.time_log = QCheckBox(strings._("enable_time_log_feature"))
|
|
175
|
+
self.time_log.setChecked(self.current_settings.time_log)
|
|
176
|
+
self.time_log.setCursor(Qt.PointingHandCursor)
|
|
177
|
+
features_layout.addWidget(self.time_log)
|
|
106
178
|
|
|
107
|
-
|
|
108
|
-
|
|
179
|
+
layout.addWidget(features_group)
|
|
180
|
+
layout.addStretch()
|
|
181
|
+
return page
|
|
109
182
|
|
|
110
|
-
|
|
183
|
+
def _create_security_page(self, cfg: DBConfig) -> QWidget:
|
|
184
|
+
page = QWidget()
|
|
185
|
+
layout = QVBoxLayout(page)
|
|
186
|
+
layout.setContentsMargins(12, 12, 12, 12)
|
|
187
|
+
layout.setSpacing(12)
|
|
188
|
+
|
|
189
|
+
# --- Encryption group ---------------------------------------------
|
|
111
190
|
enc_group = QGroupBox(strings._("encryption"))
|
|
112
191
|
enc = QVBoxLayout(enc_group)
|
|
113
|
-
enc.setContentsMargins(12, 8, 12, 12)
|
|
114
|
-
enc.setSpacing(6)
|
|
115
192
|
|
|
116
|
-
# Checkbox to remember key
|
|
117
193
|
self.save_key_btn = QCheckBox(strings._("remember_key"))
|
|
118
194
|
self.key = self.current_settings.key or ""
|
|
119
195
|
self.save_key_btn.setChecked(bool(self.key))
|
|
@@ -121,17 +197,15 @@ class SettingsDialog(QDialog):
|
|
|
121
197
|
self.save_key_btn.toggled.connect(self._save_key_btn_clicked)
|
|
122
198
|
enc.addWidget(self.save_key_btn, 0, Qt.AlignLeft)
|
|
123
199
|
|
|
124
|
-
# Explanation for remembering key
|
|
125
200
|
self.save_key_label = QLabel(strings._("save_key_warning"))
|
|
126
201
|
self.save_key_label.setWordWrap(True)
|
|
127
202
|
self.save_key_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
128
|
-
# make it look secondary
|
|
129
203
|
pal = self.save_key_label.palette()
|
|
130
204
|
self.save_key_label.setForegroundRole(QPalette.PlaceholderText)
|
|
131
205
|
self.save_key_label.setPalette(pal)
|
|
132
206
|
|
|
133
207
|
exp_row = QHBoxLayout()
|
|
134
|
-
exp_row.setContentsMargins(24, 0, 0, 0)
|
|
208
|
+
exp_row.setContentsMargins(24, 0, 0, 0)
|
|
135
209
|
exp_row.addWidget(self.save_key_label)
|
|
136
210
|
enc.addLayout(exp_row)
|
|
137
211
|
|
|
@@ -140,62 +214,59 @@ class SettingsDialog(QDialog):
|
|
|
140
214
|
line.setFrameShadow(QFrame.Sunken)
|
|
141
215
|
enc.addWidget(line)
|
|
142
216
|
|
|
143
|
-
# Change key button
|
|
144
217
|
self.rekey_btn = QPushButton(strings._("change_encryption_key"))
|
|
145
218
|
self.rekey_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
|
146
219
|
self.rekey_btn.clicked.connect(self._change_key)
|
|
147
|
-
|
|
148
220
|
enc.addWidget(self.rekey_btn, 0, Qt.AlignLeft)
|
|
149
221
|
|
|
150
|
-
|
|
222
|
+
layout.addWidget(enc_group)
|
|
151
223
|
|
|
152
|
-
#
|
|
224
|
+
# --- Idle lock group ----------------------------------------------
|
|
153
225
|
priv_group = QGroupBox(strings._("lock_screen_when_idle"))
|
|
154
226
|
priv = QVBoxLayout(priv_group)
|
|
155
|
-
priv.setContentsMargins(12, 8, 12, 12)
|
|
156
|
-
priv.setSpacing(6)
|
|
157
227
|
|
|
158
228
|
self.idle_spin = QSpinBox()
|
|
159
229
|
self.idle_spin.setRange(0, 240)
|
|
160
230
|
self.idle_spin.setSingleStep(1)
|
|
161
231
|
self.idle_spin.setAccelerated(True)
|
|
162
232
|
self.idle_spin.setSuffix(" min")
|
|
163
|
-
self.idle_spin.setSpecialValueText(strings._("
|
|
233
|
+
self.idle_spin.setSpecialValueText(strings._("never"))
|
|
164
234
|
self.idle_spin.setValue(getattr(cfg, "idle_minutes", 15))
|
|
165
235
|
priv.addWidget(self.idle_spin, 0, Qt.AlignLeft)
|
|
166
|
-
|
|
236
|
+
|
|
167
237
|
self.idle_spin_label = QLabel(strings._("autolock_explanation"))
|
|
168
238
|
self.idle_spin_label.setWordWrap(True)
|
|
169
239
|
self.idle_spin_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
170
|
-
# make it look secondary
|
|
171
240
|
spal = self.idle_spin_label.palette()
|
|
172
241
|
self.idle_spin_label.setForegroundRole(QPalette.PlaceholderText)
|
|
173
242
|
self.idle_spin_label.setPalette(spal)
|
|
174
243
|
|
|
175
244
|
spin_row = QHBoxLayout()
|
|
176
|
-
spin_row.setContentsMargins(24, 0, 0, 0)
|
|
245
|
+
spin_row.setContentsMargins(24, 0, 0, 0)
|
|
177
246
|
spin_row.addWidget(self.idle_spin_label)
|
|
178
247
|
priv.addLayout(spin_row)
|
|
179
248
|
|
|
180
|
-
|
|
249
|
+
layout.addWidget(priv_group)
|
|
250
|
+
layout.addStretch()
|
|
251
|
+
return page
|
|
252
|
+
|
|
253
|
+
def _create_database_page(self) -> QWidget:
|
|
254
|
+
page = QWidget()
|
|
255
|
+
layout = QVBoxLayout(page)
|
|
256
|
+
layout.setContentsMargins(12, 12, 12, 12)
|
|
257
|
+
layout.setSpacing(12)
|
|
181
258
|
|
|
182
|
-
# Maintenance settings
|
|
183
259
|
maint_group = QGroupBox(strings._("database_maintenance"))
|
|
184
260
|
maint = QVBoxLayout(maint_group)
|
|
185
|
-
maint.setContentsMargins(12, 8, 12, 12)
|
|
186
|
-
maint.setSpacing(6)
|
|
187
261
|
|
|
188
262
|
self.compact_btn = QPushButton(strings._("database_compact"))
|
|
189
263
|
self.compact_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
|
190
264
|
self.compact_btn.clicked.connect(self._compact_btn_clicked)
|
|
191
|
-
|
|
192
265
|
maint.addWidget(self.compact_btn, 0, Qt.AlignLeft)
|
|
193
266
|
|
|
194
|
-
# Explanation for compacting button
|
|
195
267
|
self.compact_label = QLabel(strings._("database_compact_explanation"))
|
|
196
268
|
self.compact_label.setWordWrap(True)
|
|
197
269
|
self.compact_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
|
|
198
|
-
# make it look secondary
|
|
199
270
|
cpal = self.compact_label.palette()
|
|
200
271
|
self.compact_label.setForegroundRole(QPalette.PlaceholderText)
|
|
201
272
|
self.compact_label.setPalette(cpal)
|
|
@@ -205,22 +276,15 @@ class SettingsDialog(QDialog):
|
|
|
205
276
|
maint_row.addWidget(self.compact_label)
|
|
206
277
|
maint.addLayout(maint_row)
|
|
207
278
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
bb = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel)
|
|
212
|
-
bb.accepted.connect(self._save)
|
|
213
|
-
bb.rejected.connect(self.reject)
|
|
279
|
+
layout.addWidget(maint_group)
|
|
280
|
+
layout.addStretch()
|
|
281
|
+
return page
|
|
214
282
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
v.setSpacing(10)
|
|
219
|
-
v.addLayout(form)
|
|
220
|
-
v.addWidget(bb, 0, Qt.AlignRight)
|
|
283
|
+
# ------------------------------------------------------------------ #
|
|
284
|
+
# Save settings
|
|
285
|
+
# ------------------------------------------------------------------ #
|
|
221
286
|
|
|
222
287
|
def _save(self):
|
|
223
|
-
# Save the selected theme into QSettings
|
|
224
288
|
if self.theme_dark.isChecked():
|
|
225
289
|
selected_theme = Theme.DARK
|
|
226
290
|
elif self.theme_light.isChecked():
|
|
@@ -236,7 +300,10 @@ class SettingsDialog(QDialog):
|
|
|
236
300
|
idle_minutes=self.idle_spin.value(),
|
|
237
301
|
theme=selected_theme.value,
|
|
238
302
|
move_todos=self.move_todos.isChecked(),
|
|
303
|
+
tags=self.tags.isChecked(),
|
|
304
|
+
time_log=self.time_log.isChecked(),
|
|
239
305
|
locale=self.locale_combobox.currentText(),
|
|
306
|
+
font_size=self.font_size.value(),
|
|
240
307
|
)
|
|
241
308
|
|
|
242
309
|
save_db_config(self._cfg)
|
|
@@ -98,7 +98,7 @@ class DateHeatmap(QWidget):
|
|
|
98
98
|
|
|
99
99
|
def minimumSizeHint(self) -> QSize:
|
|
100
100
|
sz = self.sizeHint()
|
|
101
|
-
return QSize(min(
|
|
101
|
+
return QSize(min(350, sz.width()), sz.height())
|
|
102
102
|
|
|
103
103
|
def paintEvent(self, event):
|
|
104
104
|
super().paintEvent(event)
|
|
@@ -249,6 +249,7 @@ class StatisticsDialog(QDialog):
|
|
|
249
249
|
|
|
250
250
|
self.setWindowTitle(strings._("statistics"))
|
|
251
251
|
self.setMinimumWidth(600)
|
|
252
|
+
self.setMinimumHeight(350)
|
|
252
253
|
root = QVBoxLayout(self)
|
|
253
254
|
|
|
254
255
|
(
|
|
@@ -19,6 +19,8 @@ class ToolBar(QToolBar):
|
|
|
19
19
|
historyRequested = Signal()
|
|
20
20
|
insertImageRequested = Signal()
|
|
21
21
|
alarmRequested = Signal()
|
|
22
|
+
fontSizeLargerRequested = Signal()
|
|
23
|
+
fontSizeSmallerRequested = Signal()
|
|
22
24
|
|
|
23
25
|
def __init__(self, parent=None):
|
|
24
26
|
super().__init__(strings._("toolbar_format"), parent)
|
|
@@ -67,12 +69,22 @@ class ToolBar(QToolBar):
|
|
|
67
69
|
self.actH3.setCheckable(True)
|
|
68
70
|
self.actH3.setShortcut("Ctrl+3")
|
|
69
71
|
self.actH3.triggered.connect(lambda: self.headingRequested.emit(14))
|
|
70
|
-
self.actNormal = QAction("
|
|
72
|
+
self.actNormal = QAction("P", self)
|
|
71
73
|
self.actNormal.setToolTip(strings._("toolbar_normal_paragraph_text"))
|
|
72
74
|
self.actNormal.setCheckable(True)
|
|
73
|
-
self.actNormal.setShortcut("Ctrl
|
|
75
|
+
self.actNormal.setShortcut("Ctrl+.")
|
|
74
76
|
self.actNormal.triggered.connect(lambda: self.headingRequested.emit(0))
|
|
75
77
|
|
|
78
|
+
self.actFontSmaller = QAction("P-", self)
|
|
79
|
+
self.actFontSmaller.setToolTip(strings._("toolbar_font_smaller"))
|
|
80
|
+
self.actFontSmaller.setShortcut("Ctrl+Shift+-")
|
|
81
|
+
self.actFontSmaller.triggered.connect(self.fontSizeSmallerRequested)
|
|
82
|
+
|
|
83
|
+
self.actFontLarger = QAction("P+", self)
|
|
84
|
+
self.actFontLarger.setToolTip(strings._("toolbar_font_larger"))
|
|
85
|
+
self.actFontLarger.setShortcut("Ctrl+Shift+=")
|
|
86
|
+
self.actFontLarger.triggered.connect(self.fontSizeLargerRequested)
|
|
87
|
+
|
|
76
88
|
# Lists
|
|
77
89
|
self.actBullets = QAction("•", self)
|
|
78
90
|
self.actBullets.setToolTip(strings._("toolbar_bulleted_list"))
|
|
@@ -132,6 +144,8 @@ class ToolBar(QToolBar):
|
|
|
132
144
|
self.actH2,
|
|
133
145
|
self.actH3,
|
|
134
146
|
self.actNormal,
|
|
147
|
+
self.actFontSmaller,
|
|
148
|
+
self.actFontLarger,
|
|
135
149
|
self.actBullets,
|
|
136
150
|
self.actNumbers,
|
|
137
151
|
self.actCheckboxes,
|
|
@@ -153,7 +167,9 @@ class ToolBar(QToolBar):
|
|
|
153
167
|
self._style_letter_button(self.actH1, "H1")
|
|
154
168
|
self._style_letter_button(self.actH2, "H2")
|
|
155
169
|
self._style_letter_button(self.actH3, "H3")
|
|
156
|
-
self._style_letter_button(self.actNormal, "
|
|
170
|
+
self._style_letter_button(self.actNormal, "P")
|
|
171
|
+
self._style_letter_button(self.actFontSmaller, "P-")
|
|
172
|
+
self._style_letter_button(self.actFontLarger, "P+")
|
|
157
173
|
|
|
158
174
|
# Lists
|
|
159
175
|
self._style_letter_button(self.actBullets, "•")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|