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.
Files changed (31) hide show
  1. {bouquin-0.4.1 → bouquin-0.4.2}/PKG-INFO +1 -1
  2. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/bug_report_dialog.py +1 -8
  3. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/db.py +7 -11
  4. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/key_prompt.py +3 -2
  5. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/locales/en.json +21 -19
  6. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/locales/fr.json +0 -12
  7. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/locales/it.json +1 -13
  8. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/main_window.py +67 -16
  9. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/markdown_editor.py +3 -3
  10. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/save_dialog.py +13 -1
  11. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/settings.py +9 -0
  12. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/settings_dialog.py +128 -61
  13. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/statistics_dialog.py +2 -1
  14. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/toolbar.py +19 -3
  15. {bouquin-0.4.1 → bouquin-0.4.2}/pyproject.toml +1 -1
  16. {bouquin-0.4.1 → bouquin-0.4.2}/LICENSE +0 -0
  17. {bouquin-0.4.1 → bouquin-0.4.2}/README.md +0 -0
  18. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/__init__.py +0 -0
  19. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/__main__.py +0 -0
  20. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/find_bar.py +0 -0
  21. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/flow_layout.py +0 -0
  22. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/history_dialog.py +0 -0
  23. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/lock_overlay.py +0 -0
  24. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/main.py +0 -0
  25. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/markdown_highlighter.py +0 -0
  26. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/search.py +0 -0
  27. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/strings.py +0 -0
  28. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/tag_browser.py +0 -0
  29. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/tags_widget.py +0 -0
  30. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/theme.py +0 -0
  31. {bouquin-0.4.1 → bouquin-0.4.2}/bouquin/time_log.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: bouquin
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: Bouquin is a simple, opinionated notebook application written in Python, PyQt and SQLCipher.
5
5
  Home-page: https://git.mig5.net/mig5/bouquin
6
6
  License: GPL-3.0-or-later
@@ -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
- try:
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
- try:
738
- d = _dt.date.fromisoformat(date_iso)
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
- try:
753
- d = _dt.date.fromisoformat(date_iso)
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
- return Path(text)
106
- return self._db_path
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": "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.'nSet to 0 (never) to never lock.",
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
- "add_project_label": "Add a project",
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
- "database_path": "Percorso del database",
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, TimeReportDialog
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
- font = QFont()
45
- font.setPointSize(10)
46
- self.setFont(font)
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
- self.note.setText(strings._("new_version_i_saved_at") + f" {now}")
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
- form = QFormLayout()
43
- form.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
44
- self.setMinimumWidth(560)
43
+ self.current_settings = load_db_config()
44
+
45
+ self.setMinimumWidth(480)
45
46
  self.setSizeGripEnabled(True)
46
47
 
47
- self.current_settings = load_db_config()
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
- # Add theme selection
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
- form.addRow(theme_group)
71
-
72
- # Locale settings
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
- locale_row = QHBoxLayout()
92
- locale_row.setContentsMargins(24, 0, 0, 0)
93
- locale_row.addWidget(self.locale_label)
94
- locale_layout.addLayout(locale_row)
95
- form.addRow(locale_group)
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
- # Add Behaviour
98
- behaviour_group = QGroupBox(strings._("behaviour"))
99
- behaviour_layout = QVBoxLayout(behaviour_group)
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
- behaviour_layout.addWidget(self.move_todos)
108
- form.addRow(behaviour_group)
179
+ layout.addWidget(features_group)
180
+ layout.addStretch()
181
+ return page
109
182
 
110
- # Encryption settings
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) # indent to line up under the checkbox
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
- form.addRow(enc_group)
222
+ layout.addWidget(enc_group)
151
223
 
152
- # Privacy settings
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._("Never"))
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
- # Explanation for idle option (autolock)
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) # indent to line up under the spinbox
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
- form.addRow(priv_group)
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
- form.addRow(maint_group)
209
-
210
- # Buttons
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
- # Root layout (adjust margins/spacing a bit)
216
- v = QVBoxLayout(self)
217
- v.setContentsMargins(12, 12, 12, 12)
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(300, sz.width()), sz.height())
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("N", self)
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+N")
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, "N")
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, "•")
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "bouquin"
3
- version = "0.4.1"
3
+ version = "0.4.2"
4
4
  description = "Bouquin is a simple, opinionated notebook application written in Python, PyQt and SQLCipher."
5
5
  authors = ["Miguel Jacq <mig@mig5.net>"]
6
6
  readme = "README.md"
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