editor module
Overview
The editor module provides the standalone WYSIWYG newsletter editor used by sendMail. It contains the Qt bridge, the editor window, the configuration dialogs, and the helper functions that support HTML editing, file selection, and editor startup.
Module API
WYSIWYG HTML editor for composing sendMail newsletters.
- Usage:
python src/editor.py # blank editor python src/editor.py data/template.md # open existing markdown file python src/editor.py data/newsletter.html # open existing HTML file
- The editor saves output as .html, ready for sendMail:
python src/sendMail.py –profile cambristi data/newsletter.html
- editor.pyqtSignal(*args, **kwargs)
Fake pyqtSignal instance with connect/disconnect/emit.
- editor.pyqtSlot(*args, **kwargs)
Fake @pyqtSlot that behaves as a no-op decorator.
- class editor.EditorBridge(parent: _FakeQObject | None = None)[source]
Bases:
_FakeQObjectQWebChannel bridge for communication with Quill.js editor.
Registered with QWebChannel as “bridge”. Provides slots callable from JavaScript for image insertion, file operations, and content changes.
- Signals:
dirty_changed: Emitted when content modification state changes css_changed: Emitted when user selects custom CSS stylesheet
- dirty_changed = <MagicMock id='123166021544464'>
- css_changed = <MagicMock id='123166000604944'>
- on_content_changed = '<function EditorBridge.on_content_changed>'
- request_image_insert() str[source]
Opens a file dialog and returns a base64 data URI for the chosen image. Returns “” if the user cancels.
- request_link_insert(selected_text: str) str[source]
Opens a link dialog pre-filled with selected_text. Returns a JSON string {“url”: “…”, “text”: “…”} on confirm, or “” on cancel.
- request_table_insert() str[source]
Opens a dialog asking for table dimensions. Returns JSON string {“rows”: n, “cols”: m} on confirm, or “” on cancel.
- log_js_error = '<function EditorBridge.log_js_error>'
- reset(html: str = '') None[source]
Clears the dirty flag and updates cached HTML (called after save).
- property is_dirty: bool
- class editor.EditorWindow(file_path: str | None = None)[source]
Bases:
_FakeQMainWindowMain WYSIWYG newsletter editor window.
Desktop application for composing and editing HTML newsletters. Uses Quill.js for rich text editing in QWebEngineView. Supports inline images, attachments, CSS customization, and sendMail output.
- Parameters:
file_path – Optional markdown or HTML file to open on startup
Classes
- class editor._LinkDialog(parent: <MagicMock name = 'mock.QWidget.__or__()' id='123165999223184'> = None, selected_text: str = '')[source]
Bases:
_FakeQDialogSmall dialog asking for a URL and optional display text.
- class editor._AnchorDialog(parent: <MagicMock name = 'mock.QWidget.__or__()' id='123165999223184'> = None)[source]
Bases:
_FakeQDialogSmall dialog asking for a named anchor / bookmark identifier.
- class editor._TableDialog(parent: <MagicMock name = 'mock.QWidget.__or__()' id='123165999223184'> = None)[source]
Bases:
_FakeQDialogDialog asking for table dimensions (rows × columns).
- class editor._SendDialog(parent: <MagicMock name = 'mock.QWidget.__or__()' id='123165999223184'> = None, *, attachment_path: str, config_path: str, config_data: dict[str, dict[str, str | int]] | None=None, initial_profile: str = 'default')[source]
Bases:
_FakeQDialogDialog for selecting sendMail options before sending the edited file.
- __init__(parent: <MagicMock name = 'mock.QWidget.__or__()' id='123165999223184'> = None, *, attachment_path: str, config_path: str, config_data: dict[str, dict[str, str | int]] | None=None, initial_profile: str = 'default') None[source]
- load_current_filter(profile: str) None[source]
Load filter from profile config and display in filter field.
- load_database_records() tuple[list[list[str]], list[str]][source]
Load database records from CSV or Google Sheets (T026).
- class editor._LineFieldSpec(key: 'str', label: 'str', tooltip: 'str' = '', placeholder: 'str' = '', password: 'bool' = False, browse_caption: 'str | None' = None, browse_filter: 'str' = 'All Files (*)')[source]
Bases:
object- key: str
- label: str
- tooltip: str = ''
- placeholder: str = ''
- password: bool = False
- browse_caption: str | None = None
- browse_filter: str = 'All Files (*)'
- __init__(key: str, label: str, tooltip: str = '', placeholder: str = '', password: bool = False, browse_caption: str | None = None, browse_filter: str = 'All Files (*)') None
- class editor._ConfigDialog(parent: <MagicMock name = 'mock.QWidget.__or__()' id='123165999223184'> = None, *, config_path: str, config_data: dict[str, dict[str, str | int | list[str] | dict[str, str]]] | None=None, initial_profile: str = 'default')[source]
Bases:
_FakeQDialogDialog for editing sendMail YAML configuration by profile.
Provides tabbed interface for editing: - Identity (sender, credentials) - Delivery (SMTP/IMAP settings) - Sources (subscriber database location) - Templates (message templates, rate limits) - Filters (filter_test and filter rules with validation)
- class editor.EditorBridge(parent: _FakeQObject | None = None)[source]
Bases:
_FakeQObjectQWebChannel bridge for communication with Quill.js editor.
Registered with QWebChannel as “bridge”. Provides slots callable from JavaScript for image insertion, file operations, and content changes.
- Signals:
dirty_changed: Emitted when content modification state changes css_changed: Emitted when user selects custom CSS stylesheet
- dirty_changed = <MagicMock id='123166021544464'>
- css_changed = <MagicMock id='123166000604944'>
- on_content_changed = '<function EditorBridge.on_content_changed>'
- request_image_insert() str[source]
Opens a file dialog and returns a base64 data URI for the chosen image. Returns “” if the user cancels.
- request_link_insert(selected_text: str) str[source]
Opens a link dialog pre-filled with selected_text. Returns a JSON string {“url”: “…”, “text”: “…”} on confirm, or “” on cancel.
- request_table_insert() str[source]
Opens a dialog asking for table dimensions. Returns JSON string {“rows”: n, “cols”: m} on confirm, or “” on cancel.
- log_js_error = '<function EditorBridge.log_js_error>'
- reset(html: str = '') None[source]
Clears the dirty flag and updates cached HTML (called after save).
- property is_dirty: bool
- class editor.EditorWindow(file_path: str | None = None)[source]
Bases:
_FakeQMainWindowMain WYSIWYG newsletter editor window.
Desktop application for composing and editing HTML newsletters. Uses Quill.js for rich text editing in QWebEngineView. Supports inline images, attachments, CSS customization, and sendMail output.
- Parameters:
file_path – Optional markdown or HTML file to open on startup