Fix history pane, some small cleanups
This commit is contained in:
parent
f023224074
commit
ab1af80d10
12 changed files with 47 additions and 114 deletions
|
|
@ -1,3 +1,8 @@
|
||||||
|
# 0.2.1.1
|
||||||
|
|
||||||
|
* Fix history preview pane to be in markdown
|
||||||
|
* Some other code cleanups
|
||||||
|
|
||||||
# 0.2.1
|
# 0.2.1
|
||||||
|
|
||||||
* Introduce tabs!
|
* Introduce tabs!
|
||||||
|
|
|
||||||
|
|
@ -427,29 +427,6 @@ class DBManager:
|
||||||
cur.execute("SELECT sqlcipher_export('backup')")
|
cur.execute("SELECT sqlcipher_export('backup')")
|
||||||
cur.execute("DETACH DATABASE backup")
|
cur.execute("DETACH DATABASE backup")
|
||||||
|
|
||||||
def export_by_extension(self, file_path: str) -> None:
|
|
||||||
"""
|
|
||||||
Fallback catch-all that runs one of the above functions based on
|
|
||||||
the extension of the file name that was chosen by the user.
|
|
||||||
"""
|
|
||||||
entries = self.get_all_entries()
|
|
||||||
ext = os.path.splitext(file_path)[1].lower()
|
|
||||||
|
|
||||||
if ext == ".json":
|
|
||||||
self.export_json(entries, file_path)
|
|
||||||
elif ext == ".csv":
|
|
||||||
self.export_csv(entries, file_path)
|
|
||||||
elif ext == ".txt":
|
|
||||||
self.export_txt(entries, file_path)
|
|
||||||
elif ext in {".html", ".htm"}:
|
|
||||||
self.export_html(entries, file_path)
|
|
||||||
elif ext in {".sql", ".sqlite"}:
|
|
||||||
self.export_sql(file_path)
|
|
||||||
elif ext == ".md":
|
|
||||||
self.export_markdown(entries, file_path)
|
|
||||||
else:
|
|
||||||
raise ValueError(f"Unsupported extension: {ext}")
|
|
||||||
|
|
||||||
def compact(self) -> None:
|
def compact(self) -> None:
|
||||||
"""
|
"""
|
||||||
Runs VACUUM on the db.
|
Runs VACUUM on the db.
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,8 @@ from PySide6.QtWidgets import (
|
||||||
class FindBar(QWidget):
|
class FindBar(QWidget):
|
||||||
"""Widget for finding text in the Editor"""
|
"""Widget for finding text in the Editor"""
|
||||||
|
|
||||||
closed = (
|
# emitted when the bar is hidden (Esc/✕), so caller can refocus editor
|
||||||
Signal()
|
closed = Signal()
|
||||||
) # emitted when the bar is hidden (Esc/✕), so caller can refocus editor
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
|
@ -45,7 +44,7 @@ class FindBar(QWidget):
|
||||||
layout.addWidget(QLabel("Find:"))
|
layout.addWidget(QLabel("Find:"))
|
||||||
|
|
||||||
self.edit = QLineEdit(self)
|
self.edit = QLineEdit(self)
|
||||||
self.edit.setPlaceholderText("Type to search…")
|
self.edit.setPlaceholderText("Type to search")
|
||||||
layout.addWidget(self.edit)
|
layout.addWidget(self.edit)
|
||||||
|
|
||||||
self.case = QCheckBox("Match case", self)
|
self.case = QCheckBox("Match case", self)
|
||||||
|
|
@ -79,7 +78,7 @@ class FindBar(QWidget):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def editor(self) -> QTextEdit | None:
|
def editor(self) -> QTextEdit | None:
|
||||||
"""Get the current editor (no side effects)."""
|
"""Get the current editor"""
|
||||||
return self._editor_getter()
|
return self._editor_getter()
|
||||||
|
|
||||||
# ----- Public API -----
|
# ----- Public API -----
|
||||||
|
|
|
||||||
|
|
@ -118,9 +118,9 @@ class HistoryDialog(QDialog):
|
||||||
return local.strftime("%Y-%m-%d %H:%M:%S %Z")
|
return local.strftime("%Y-%m-%d %H:%M:%S %Z")
|
||||||
|
|
||||||
def _load_versions(self):
|
def _load_versions(self):
|
||||||
self._versions = self._db.list_versions(
|
# [{id,version_no,created_at,note,is_current}]
|
||||||
self._date
|
self._versions = self._db.list_versions(self._date)
|
||||||
) # [{id,version_no,created_at,note,is_current}]
|
|
||||||
self._current_id = next(
|
self._current_id = next(
|
||||||
(v["id"] for v in self._versions if v["is_current"]), None
|
(v["id"] for v in self._versions if v["is_current"]), None
|
||||||
)
|
)
|
||||||
|
|
@ -152,13 +152,8 @@ class HistoryDialog(QDialog):
|
||||||
self.btn_revert.setEnabled(False)
|
self.btn_revert.setEnabled(False)
|
||||||
return
|
return
|
||||||
sel_id = item.data(Qt.UserRole)
|
sel_id = item.data(Qt.UserRole)
|
||||||
# Preview selected as plain text (markdown)
|
|
||||||
sel = self._db.get_version(version_id=sel_id)
|
sel = self._db.get_version(version_id=sel_id)
|
||||||
# Show markdown as plain text with monospace font for better readability
|
self.preview.setMarkdown(sel["content"])
|
||||||
self.preview.setPlainText(sel["content"])
|
|
||||||
self.preview.setStyleSheet(
|
|
||||||
"font-family: Consolas, Menlo, Monaco, monospace; font-size: 13px;"
|
|
||||||
)
|
|
||||||
# Diff vs current (textual diff)
|
# Diff vs current (textual diff)
|
||||||
cur = self._db.get_version(version_id=self._current_id)
|
cur = self._db.get_version(version_id=self._current_id)
|
||||||
self.diff.setHtml(_colored_unified_diff_html(cur["content"], sel["content"]))
|
self.diff.setHtml(_colored_unified_diff_html(cur["content"], sel["content"]))
|
||||||
|
|
|
||||||
|
|
@ -808,7 +808,7 @@ class MainWindow(QMainWindow):
|
||||||
def _adjust_today(self):
|
def _adjust_today(self):
|
||||||
"""Jump to today."""
|
"""Jump to today."""
|
||||||
today = QDate.currentDate()
|
today = QDate.currentDate()
|
||||||
self.calendar.setSelectedDate(today)
|
self._create_new_tab(today)
|
||||||
|
|
||||||
def _load_yesterday_todos(self):
|
def _load_yesterday_todos(self):
|
||||||
try:
|
try:
|
||||||
|
|
@ -1090,7 +1090,7 @@ If you want an encrypted backup, choose Backup instead of Export.
|
||||||
elif selected_filter.startswith("SQL"):
|
elif selected_filter.startswith("SQL"):
|
||||||
self.db.export_sql(filename)
|
self.db.export_sql(filename)
|
||||||
else:
|
else:
|
||||||
self.db.export_by_extension(filename)
|
raise ValueError("Unrecognised extension!")
|
||||||
|
|
||||||
QMessageBox.information(self, "Export complete", f"Saved to:\n{filename}")
|
QMessageBox.information(self, "Export complete", f"Saved to:\n{filename}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ class MarkdownHighlighter(QSyntaxHighlighter):
|
||||||
self.setCurrentBlockState(1 if in_code_block else 0)
|
self.setCurrentBlockState(1 if in_code_block else 0)
|
||||||
# Format the fence markers - but keep them somewhat visible for editing
|
# Format the fence markers - but keep them somewhat visible for editing
|
||||||
# Use code format instead of syntax format so cursor is visible
|
# Use code format instead of syntax format so cursor is visible
|
||||||
self.setFormat(0, len(text), self.code_block_format)
|
self.setFormat(0, len(text), self.code_format)
|
||||||
return
|
return
|
||||||
|
|
||||||
if in_code_block:
|
if in_code_block:
|
||||||
|
|
@ -258,13 +258,13 @@ class MarkdownEditor(QTextEdit):
|
||||||
|
|
||||||
# Transform only this line:
|
# Transform only this line:
|
||||||
# - "TODO " at start (with optional indent) -> "- ☐ "
|
# - "TODO " at start (with optional indent) -> "- ☐ "
|
||||||
# - "- [ ] " -> "- ☐ " and "- [x] " -> "- ☑ "
|
# - "- [ ] " -> " ☐ " and "- [x] " -> " ☑ "
|
||||||
def transform_line(s: str) -> str:
|
def transform_line(s: str) -> str:
|
||||||
s = s.replace("- [x] ", f"- {self._CHECK_CHECKED_DISPLAY} ")
|
s = s.replace("- [x] ", f"{self._CHECK_CHECKED_DISPLAY} ")
|
||||||
s = s.replace("- [ ] ", f"- {self._CHECK_UNCHECKED_DISPLAY} ")
|
s = s.replace("- [ ] ", f"{self._CHECK_UNCHECKED_DISPLAY} ")
|
||||||
s = re.sub(
|
s = re.sub(
|
||||||
r"^([ \t]*)TODO\b[:\-]?\s+",
|
r"^([ \t]*)TODO\b[:\-]?\s+",
|
||||||
lambda m: f"{m.group(1)}- {self._CHECK_UNCHECKED_DISPLAY} ",
|
lambda m: f"{m.group(1)}\n{self._CHECK_UNCHECKED_DISPLAY} ",
|
||||||
s,
|
s,
|
||||||
)
|
)
|
||||||
return s
|
return s
|
||||||
|
|
@ -293,8 +293,8 @@ class MarkdownEditor(QTextEdit):
|
||||||
text = self._extract_images_to_markdown()
|
text = self._extract_images_to_markdown()
|
||||||
|
|
||||||
# Convert Unicode checkboxes back to markdown syntax
|
# Convert Unicode checkboxes back to markdown syntax
|
||||||
text = text.replace(f"- {self._CHECK_CHECKED_DISPLAY} ", "- [x] ")
|
text = text.replace(f"{self._CHECK_CHECKED_DISPLAY} ", "- [x] ")
|
||||||
text = text.replace(f"- {self._CHECK_UNCHECKED_DISPLAY} ", "- [ ] ")
|
text = text.replace(f"{self._CHECK_UNCHECKED_DISPLAY} ", "- [ ] ")
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
@ -336,15 +336,15 @@ class MarkdownEditor(QTextEdit):
|
||||||
"""Load markdown text into the editor (convert markdown checkboxes to Unicode)."""
|
"""Load markdown text into the editor (convert markdown checkboxes to Unicode)."""
|
||||||
# Convert markdown checkboxes to Unicode for display
|
# Convert markdown checkboxes to Unicode for display
|
||||||
display_text = markdown_text.replace(
|
display_text = markdown_text.replace(
|
||||||
"- [x] ", f"- {self._CHECK_CHECKED_DISPLAY} "
|
"- [x] ", f"{self._CHECK_CHECKED_DISPLAY} "
|
||||||
)
|
)
|
||||||
display_text = display_text.replace(
|
display_text = display_text.replace(
|
||||||
"- [ ] ", f"- {self._CHECK_UNCHECKED_DISPLAY} "
|
"- [ ] ", f"{self._CHECK_UNCHECKED_DISPLAY} "
|
||||||
)
|
)
|
||||||
# Also convert any plain 'TODO ' at the start of a line to an unchecked checkbox
|
# Also convert any plain 'TODO ' at the start of a line to an unchecked checkbox
|
||||||
display_text = re.sub(
|
display_text = re.sub(
|
||||||
r"(?m)^([ \t]*)TODO\s",
|
r"(?m)^([ \t]*)TODO\s",
|
||||||
lambda m: f"{m.group(1)}- {self._CHECK_UNCHECKED_DISPLAY} ",
|
lambda m: f"{m.group(1)}\n{self._CHECK_UNCHECKED_DISPLAY} ",
|
||||||
display_text,
|
display_text,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -425,10 +425,10 @@ class MarkdownEditor(QTextEdit):
|
||||||
line = line.lstrip()
|
line = line.lstrip()
|
||||||
|
|
||||||
# Checkbox list (Unicode display format)
|
# Checkbox list (Unicode display format)
|
||||||
if line.startswith(f"- {self._CHECK_UNCHECKED_DISPLAY} ") or line.startswith(
|
if line.startswith(f"{self._CHECK_UNCHECKED_DISPLAY} ") or line.startswith(
|
||||||
f"- {self._CHECK_CHECKED_DISPLAY} "
|
f"{self._CHECK_CHECKED_DISPLAY} "
|
||||||
):
|
):
|
||||||
return ("checkbox", f"- {self._CHECK_UNCHECKED_DISPLAY} ")
|
return ("checkbox", f"{self._CHECK_UNCHECKED_DISPLAY} ")
|
||||||
|
|
||||||
# Bullet list
|
# Bullet list
|
||||||
if re.match(r"^[-*+]\s", line):
|
if re.match(r"^[-*+]\s", line):
|
||||||
|
|
@ -533,19 +533,19 @@ class MarkdownEditor(QTextEdit):
|
||||||
|
|
||||||
# Check if clicking on a checkbox line
|
# Check if clicking on a checkbox line
|
||||||
if (
|
if (
|
||||||
f"- {self._CHECK_UNCHECKED_DISPLAY} " in line
|
f"{self._CHECK_UNCHECKED_DISPLAY} " in line
|
||||||
or f"- {self._CHECK_CHECKED_DISPLAY} " in line
|
or f"{self._CHECK_CHECKED_DISPLAY} " in line
|
||||||
):
|
):
|
||||||
# Toggle the checkbox
|
# Toggle the checkbox
|
||||||
if f"- {self._CHECK_UNCHECKED_DISPLAY} " in line:
|
if f"{self._CHECK_UNCHECKED_DISPLAY} " in line:
|
||||||
new_line = line.replace(
|
new_line = line.replace(
|
||||||
f"- {self._CHECK_UNCHECKED_DISPLAY} ",
|
f"{self._CHECK_UNCHECKED_DISPLAY} ",
|
||||||
f"- {self._CHECK_CHECKED_DISPLAY} ",
|
f"{self._CHECK_CHECKED_DISPLAY} ",
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
new_line = line.replace(
|
new_line = line.replace(
|
||||||
f"- {self._CHECK_CHECKED_DISPLAY} ",
|
f"{self._CHECK_CHECKED_DISPLAY} ",
|
||||||
f"- {self._CHECK_UNCHECKED_DISPLAY} ",
|
f"{self._CHECK_UNCHECKED_DISPLAY} ",
|
||||||
)
|
)
|
||||||
|
|
||||||
cursor.insertText(new_line)
|
cursor.insertText(new_line)
|
||||||
|
|
@ -745,18 +745,18 @@ class MarkdownEditor(QTextEdit):
|
||||||
|
|
||||||
# Check if already has checkbox (Unicode display format)
|
# Check if already has checkbox (Unicode display format)
|
||||||
if (
|
if (
|
||||||
f"- {self._CHECK_UNCHECKED_DISPLAY} " in line
|
f"{self._CHECK_UNCHECKED_DISPLAY} " in line
|
||||||
or f"- {self._CHECK_CHECKED_DISPLAY} " in line
|
or f"{self._CHECK_CHECKED_DISPLAY} " in line
|
||||||
):
|
):
|
||||||
# Remove checkbox - use raw string to avoid escape sequence warning
|
# Remove checkbox - use raw string to avoid escape sequence warning
|
||||||
new_line = re.sub(
|
new_line = re.sub(
|
||||||
rf"^\s*-\s*[{self._CHECK_UNCHECKED_DISPLAY}{self._CHECK_CHECKED_DISPLAY}]\s+",
|
rf"^\s*[{self._CHECK_UNCHECKED_DISPLAY}{self._CHECK_CHECKED_DISPLAY}]\s+",
|
||||||
"",
|
"",
|
||||||
line,
|
line,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Add checkbox (Unicode display format)
|
# Add checkbox (Unicode display format)
|
||||||
new_line = f"- {self._CHECK_UNCHECKED_DISPLAY} " + line.lstrip()
|
new_line = f"{self._CHECK_UNCHECKED_DISPLAY} " + line.lstrip()
|
||||||
|
|
||||||
cursor.insertText(new_line)
|
cursor.insertText(new_line)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "bouquin"
|
name = "bouquin"
|
||||||
version = "0.2.1"
|
version = "0.2.1.1"
|
||||||
description = "Bouquin is a simple, opinionated notebook application written in Python, PyQt and SQLCipher."
|
description = "Bouquin is a simple, opinionated notebook application written in Python, PyQt and SQLCipher."
|
||||||
authors = ["Miguel Jacq <mig@mig5.net>"]
|
authors = ["Miguel Jacq <mig@mig5.net>"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
import pytest
|
||||||
import json, csv
|
import json, csv
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
|
|
||||||
|
from bouquin.db import DBManager
|
||||||
|
|
||||||
def _today():
|
def _today():
|
||||||
return dt.date.today().isoformat()
|
return dt.date.today().isoformat()
|
||||||
|
|
@ -57,7 +59,7 @@ def test_dates_with_content_and_search(fresh_db):
|
||||||
assert any(d == _tomorrow() for d, _ in hits)
|
assert any(d == _tomorrow() for d, _ in hits)
|
||||||
|
|
||||||
|
|
||||||
def test_get_all_entries_and_export_by_extension(fresh_db, tmp_path):
|
def test_get_all_entries_and_export(fresh_db, tmp_path):
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
d = (dt.date.today() - dt.timedelta(days=i)).isoformat()
|
d = (dt.date.today() - dt.timedelta(days=i)).isoformat()
|
||||||
fresh_db.save_new_version(d, _entry(f"note {i}"), f"note {i}")
|
fresh_db.save_new_version(d, _entry(f"note {i}"), f"note {i}")
|
||||||
|
|
@ -93,18 +95,12 @@ def test_get_all_entries_and_export_by_extension(fresh_db, tmp_path):
|
||||||
fresh_db.export_sqlcipher(str(sqlc_path))
|
fresh_db.export_sqlcipher(str(sqlc_path))
|
||||||
assert sqlc_path.exists() and sqlc_path.read_bytes()
|
assert sqlc_path.exists() and sqlc_path.read_bytes()
|
||||||
|
|
||||||
for path in [json_path, csv_path, txt_path, md_path, html_path, sql_path]:
|
|
||||||
path.unlink(missing_ok=True)
|
|
||||||
fresh_db.export_by_extension(str(path))
|
|
||||||
assert path.exists()
|
|
||||||
|
|
||||||
|
|
||||||
def test_rekey_and_reopen(fresh_db, tmp_db_cfg):
|
def test_rekey_and_reopen(fresh_db, tmp_db_cfg):
|
||||||
fresh_db.save_new_version(_today(), _entry("secure"), "before rekey")
|
fresh_db.save_new_version(_today(), _entry("secure"), "before rekey")
|
||||||
fresh_db.rekey("new-key-123")
|
fresh_db.rekey("new-key-123")
|
||||||
fresh_db.close()
|
fresh_db.close()
|
||||||
|
|
||||||
from bouquin.db import DBManager
|
|
||||||
|
|
||||||
tmp_db_cfg.key = "new-key-123"
|
tmp_db_cfg.key = "new-key-123"
|
||||||
db2 = DBManager(tmp_db_cfg)
|
db2 = DBManager(tmp_db_cfg)
|
||||||
|
|
@ -116,12 +112,3 @@ def test_rekey_and_reopen(fresh_db, tmp_db_cfg):
|
||||||
def test_compact_and_close_dont_crash(fresh_db):
|
def test_compact_and_close_dont_crash(fresh_db):
|
||||||
fresh_db.compact()
|
fresh_db.compact()
|
||||||
fresh_db.close()
|
fresh_db.close()
|
||||||
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
def test_export_by_extension_unsupported(fresh_db, tmp_path):
|
|
||||||
p = tmp_path / "export.xyz"
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
fresh_db.export_by_extension(str(p))
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import pytest
|
||||||
from PySide6.QtGui import QTextCursor
|
from PySide6.QtGui import QTextCursor
|
||||||
from bouquin.markdown_editor import MarkdownEditor
|
from bouquin.markdown_editor import MarkdownEditor
|
||||||
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
||||||
|
from bouquin.find_bar import FindBar
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def editor(app, qtbot):
|
def editor(app, qtbot):
|
||||||
|
|
@ -14,9 +14,6 @@ def editor(app, qtbot):
|
||||||
return ed
|
return ed
|
||||||
|
|
||||||
|
|
||||||
from bouquin.find_bar import FindBar
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
def test_findbar_basic_navigation(qtbot, editor):
|
def test_findbar_basic_navigation(qtbot, editor):
|
||||||
editor.from_markdown("alpha\nbeta\nalpha\nGamma\n")
|
editor.from_markdown("alpha\nbeta\nalpha\nGamma\n")
|
||||||
|
|
@ -42,7 +39,6 @@ def test_findbar_basic_navigation(qtbot, editor):
|
||||||
|
|
||||||
|
|
||||||
def test_show_bar_seeds_selection(qtbot, editor):
|
def test_show_bar_seeds_selection(qtbot, editor):
|
||||||
from PySide6.QtGui import QTextCursor
|
|
||||||
|
|
||||||
editor.from_markdown("alpha beta")
|
editor.from_markdown("alpha beta")
|
||||||
c = editor.textCursor()
|
c = editor.textCursor()
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ from bouquin.key_prompt import KeyPrompt
|
||||||
from PySide6.QtCore import QTimer
|
from PySide6.QtCore import QTimer
|
||||||
from PySide6.QtWidgets import QApplication
|
from PySide6.QtWidgets import QApplication
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
def test_main_window_loads_and_saves(qtbot, app, tmp_db_cfg, fresh_db):
|
def test_main_window_loads_and_saves(qtbot, app, tmp_db_cfg, fresh_db):
|
||||||
s = get_settings()
|
s = get_settings()
|
||||||
|
|
@ -52,10 +51,6 @@ def test_main_window_loads_and_saves(qtbot, app, tmp_db_cfg, fresh_db):
|
||||||
|
|
||||||
|
|
||||||
def test_load_yesterday_todos_moves_items(qtbot, app, tmp_db_cfg, fresh_db):
|
def test_load_yesterday_todos_moves_items(qtbot, app, tmp_db_cfg, fresh_db):
|
||||||
from PySide6.QtCore import QDate
|
|
||||||
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
|
||||||
from bouquin.settings import get_settings
|
|
||||||
|
|
||||||
s = get_settings()
|
s = get_settings()
|
||||||
s.setValue("db/path", str(tmp_db_cfg.path))
|
s.setValue("db/path", str(tmp_db_cfg.path))
|
||||||
s.setValue("db/key", tmp_db_cfg.key)
|
s.setValue("db/key", tmp_db_cfg.key)
|
||||||
|
|
@ -66,7 +61,6 @@ def test_load_yesterday_todos_moves_items(qtbot, app, tmp_db_cfg, fresh_db):
|
||||||
fresh_db.save_new_version(y, "- [ ] carry me\n- [x] done", "seed")
|
fresh_db.save_new_version(y, "- [ ] carry me\n- [x] done", "seed")
|
||||||
|
|
||||||
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
|
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
|
||||||
from bouquin.main_window import MainWindow
|
|
||||||
|
|
||||||
w = MainWindow(themes=themes)
|
w = MainWindow(themes=themes)
|
||||||
qtbot.addWidget(w)
|
qtbot.addWidget(w)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
from bouquin.db import DBManager, DBConfig
|
||||||
|
from bouquin.key_prompt import KeyPrompt
|
||||||
from bouquin.settings_dialog import SettingsDialog
|
from bouquin.settings_dialog import SettingsDialog
|
||||||
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
||||||
from PySide6.QtCore import QTimer
|
from PySide6.QtCore import QTimer
|
||||||
from PySide6.QtWidgets import QApplication, QMessageBox, QWidget
|
from PySide6.QtWidgets import QApplication, QMessageBox, QWidget
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
def test_settings_dialog_config_roundtrip(qtbot, tmp_db_cfg, fresh_db, tmp_path):
|
def test_settings_dialog_config_roundtrip(qtbot, tmp_db_cfg, fresh_db, tmp_path):
|
||||||
# Provide a parent that exposes a real ThemeManager (dialog calls parent().themes.set(...))
|
# Provide a parent that exposes a real ThemeManager (dialog calls parent().themes.set(...))
|
||||||
|
|
@ -38,12 +39,6 @@ def test_settings_dialog_config_roundtrip(qtbot, tmp_db_cfg, fresh_db, tmp_path)
|
||||||
|
|
||||||
|
|
||||||
def test_save_key_toggle_roundtrip(qtbot, tmp_db_cfg, fresh_db, app):
|
def test_save_key_toggle_roundtrip(qtbot, tmp_db_cfg, fresh_db, app):
|
||||||
from PySide6.QtCore import QTimer
|
|
||||||
from PySide6.QtWidgets import QApplication, QMessageBox
|
|
||||||
from bouquin.key_prompt import KeyPrompt
|
|
||||||
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
|
||||||
from PySide6.QtWidgets import QWidget
|
|
||||||
|
|
||||||
parent = QWidget()
|
parent = QWidget()
|
||||||
parent.themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
|
parent.themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
|
||||||
|
|
||||||
|
|
@ -81,12 +76,6 @@ def test_save_key_toggle_roundtrip(qtbot, tmp_db_cfg, fresh_db, app):
|
||||||
|
|
||||||
|
|
||||||
def test_change_key_mismatch_shows_error(qtbot, tmp_db_cfg, tmp_path, app):
|
def test_change_key_mismatch_shows_error(qtbot, tmp_db_cfg, tmp_path, app):
|
||||||
from PySide6.QtCore import QTimer
|
|
||||||
from PySide6.QtWidgets import QApplication, QMessageBox, QWidget
|
|
||||||
from bouquin.key_prompt import KeyPrompt
|
|
||||||
from bouquin.db import DBManager, DBConfig
|
|
||||||
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
|
||||||
|
|
||||||
cfg = DBConfig(
|
cfg = DBConfig(
|
||||||
path=tmp_path / "iso.db",
|
path=tmp_path / "iso.db",
|
||||||
key="oldkey",
|
key="oldkey",
|
||||||
|
|
@ -129,12 +118,6 @@ def test_change_key_mismatch_shows_error(qtbot, tmp_db_cfg, tmp_path, app):
|
||||||
|
|
||||||
|
|
||||||
def test_change_key_success(qtbot, tmp_path, app):
|
def test_change_key_success(qtbot, tmp_path, app):
|
||||||
from PySide6.QtCore import QTimer
|
|
||||||
from PySide6.QtWidgets import QApplication, QWidget, QMessageBox
|
|
||||||
from bouquin.key_prompt import KeyPrompt
|
|
||||||
from bouquin.db import DBManager, DBConfig
|
|
||||||
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
|
||||||
|
|
||||||
cfg = DBConfig(
|
cfg = DBConfig(
|
||||||
path=tmp_path / "iso2.db",
|
path=tmp_path / "iso2.db",
|
||||||
key="oldkey",
|
key="oldkey",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import pytest
|
||||||
from PySide6.QtWidgets import QWidget
|
from PySide6.QtWidgets import QWidget
|
||||||
from bouquin.markdown_editor import MarkdownEditor
|
from bouquin.markdown_editor import MarkdownEditor
|
||||||
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
||||||
|
from bouquin.toolbar import ToolBar
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
@ -12,10 +13,6 @@ def editor(app, qtbot):
|
||||||
ed.show()
|
ed.show()
|
||||||
return ed
|
return ed
|
||||||
|
|
||||||
|
|
||||||
from bouquin.toolbar import ToolBar
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
def test_toolbar_signals_and_styling(qtbot, editor):
|
def test_toolbar_signals_and_styling(qtbot, editor):
|
||||||
host = QWidget()
|
host = QWidget()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue