Skip to content

Prototype package scaffold and split window - #9

Merged
GeoffRiley merged 11 commits into
mainfrom
issue-6-package-split-window
Sep 27, 2026
Merged

GeoffRiley merged 11 commits into
mainfrom
issue-6-package-split-window

Conversation

@GeoffRiley

@GeoffRiley GeoffRiley commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

User-visible change

Begins checkpoint 1 by adding the installable TextBeside package and a minimal resizable split window. The left pane is an editable plain-text editor; the right pane displays a manually selected source image. File → Open pair… selects the two files without importing or converting them, and both selected filenames remain visible.

This also resolves the existing Python-version mismatch by making pyproject.toml match the documented Python 3.11 or later policy.

Closes #6 when the remaining fresh-checkout development-command check is completed.

How I checked it

  • pytest -vv -s tests/test_app.py passed on Linux with Python 3.14.4 / PySide6 6.11.2: 2 passed.
  • ruff check . — all checks passed.
  • ruff format --check . — 11 files already formatted.
  • Manual Linux workflow:
    1. Launched textbeside.
    2. Opened the committed field-notes sample pairs with File → Open pair….
    3. Resized the splitter successfully with no visible image breakup.
    4. Edited text and confirmed undo works.
    5. Confirmed opening another pair or closing prompts before discarding unsaved edits.
  • Errors are loaded before the visible pair is replaced, and unsaved edits are not silently discarded.
  • Windows manual workflow: tested the same prototype stage and confirmed behavior matches Linux.
  • Fresh-checkout install/launch using the README commands still needs an explicit clean-environment check.

During testing, a timed QStatusBar.showMessage(..., 5000) after opening a pair caused a reproducible SIGSEGV on both Wayland and XCB. The smoke tests and standalone QPixmap loading passed. Removing the non-essential timed status message resolved the crash.

Compatibility and rights

  • Python support is now consistently >=3.11 rather than the accidental >=3.14 package requirement.
  • Adds PySide6 as the runtime dependency and pytest/Ruff as development dependencies, as already specified by the README.
  • No file-format changes, source-file conversion, network access, or new third-party assets.

Summary by Sourcery

Establish the initial installable TextBeside prototype with a resizable split editor, image viewer, and safe manual pair loading workflow.

New Features:

  • Add an installable TextBeside package with a launchable command and minimal Qt split-view editor.
  • Support manually opening an image and Markdown or text transcription pair while displaying both selected filenames and protecting unsaved edits.

Bug Fixes:

  • Align the package's Python requirement with the documented Python 3.11-or-later support policy.

Enhancements:

  • Add the initial application smoke tests and development tooling configuration.
  • Document development setup, launch commands, and current prototype limitations.

Build:

  • Add setuptools packaging metadata, runtime PySide6 dependency, development dependencies, and the textbeside console entry point.

Documentation:

  • Document Python 3.11-or-later setup, prototype usage, and automated checks.

Tests:

  • Add offscreen Qt smoke tests covering the split window and loading an example file pair.

@sourcery-ai

sourcery-ai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

This PR establishes an installable Python 3.11+ TextBeside prototype, packaging it with PySide6 and a console command, implementing a safe resizable text-and-image split view with manual pair selection and unsaved-edit protection, and adding documentation plus Qt smoke tests.

Sequence diagram for opening a TextBeside file pair

sequenceDiagram
    actor User
    participant MainWindow
    participant QFileDialog
    participant FileSystem
    participant Editor
    participant ImageView

    User->>MainWindow: open_pair_dialog()
    MainWindow->>MainWindow: _confirm_discard_if_modified()
    MainWindow->>QFileDialog: getOpenFileName()
    QFileDialog-->>MainWindow: image_name
    MainWindow->>QFileDialog: getOpenFileName()
    QFileDialog-->>MainWindow: text_name
    MainWindow->>FileSystem: read_text_file(text_path)
    FileSystem-->>MainWindow: text
    MainWindow->>FileSystem: load_image(image_path)
    FileSystem-->>MainWindow: pixmap
    MainWindow->>Editor: setPlainText(text)
    MainWindow->>ImageView: setPixmap(pixmap)
    MainWindow->>MainWindow: setText(path.name)
Loading

Flow diagram for safe pair replacement

flowchart TD
    Start[Open pair] --> Check{Unsaved edits?}
    Check -->|Yes| Confirm["_confirm_discard_if_modified()"]
    Confirm -->|Cancel| Keep[Keep current pair]
    Confirm -->|Discard| Select[Select image and text files]
    Check -->|No| Select
    Select --> LoadText["read_text_file()"]
    LoadText --> LoadImage["load_image()"]
    LoadImage --> Replace[Replace editor and image view]
    LoadText -->|Error| Error[Show open error]
    LoadImage -->|Error| Error
    Error --> Keep
Loading

File-Level Changes

Change Details Files
Add the installable Qt application scaffold and development tooling for Python 3.11+.
  • Add setuptools build metadata, package discovery, console entry point, and version metadata.
  • Declare PySide6 runtime and pytest/Ruff development dependencies.
  • Align the package requirement and Ruff target with the documented Python 3.11+ policy.
pyproject.toml
src/textbeside/__init__.py
Implement a minimal split transcription-and-image workspace with safe pair loading and edit protection.
  • Create a horizontal resizable splitter with an editable plain-text pane and scrollable image pane.
  • Open image and Markdown/text files through File → Open pair… while retaining selected filenames.
  • Validate and load both files before replacing the current pair, and prompt before discarding modified text on reopen or close.
  • Provide standard open and quit actions plus application launch behavior.
src/textbeside/app.py
Document prototype setup, launch commands, checks, and current scope limitations.
  • Add Linux and Windows virtual-environment installation instructions.
  • Document console/module launch commands, automated checks, and unsupported checkpoint features.
README.md
Add offscreen Qt smoke coverage for the split layout and sample-pair loading.
  • Configure pytest to use the offscreen Qt platform by default.
  • Verify splitter orientation, pane count, editor mutability, filenames, text contents, image loading, and clean modified state.
tests/conftest.py
tests/test_app.py

Assessment against linked issues

Issue Objective Addressed Explanation
#6 Create a minimal installable Python package with documented development setup and commands for launching it from a fresh checkout. ✅
#6 Provide a single main window with a resizable horizontal splitter containing an editable plain-text pane on the left and an image pane on the right, with selected filenames visible. ✅
#6 Support manually opening an image together with a .md or .txt file without conversion or directory scanning, and provide smoke-test coverage for startup and sample-pair loading. ✅

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Owner Author

Linux manual testing on Python 3.14.4 / PySide6 6.11.2 found a reproducible SIGSEGV immediately after opening both sample files. The existing pytest smoke tests passed and standalone QPixmap loading succeeded. Instrumentation isolated the crash to the timed QStatusBar.showMessage(..., 5000) call after the pair had otherwise loaded successfully; both Wayland and XCB showed the same behavior. Removing that non-essential transient status message prevents the crash in the reported test run. The status-bar notification is not required by issue #6, so this PR now avoids the timed call rather than broadening scope into Qt runtime investigation.

@GeoffRiley
GeoffRiley marked this pull request as ready for review September 27, 2026 00:26
Copilot AI lite review requested due to automatic review settings September 27, 2026 00:26
@GeoffRiley
GeoffRiley merged commit 11f1b7c into main Sep 27, 2026
2 checks passed

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/textbeside/app.py" line_range="147" />
<code_context>
+
+        self.current_text_path = text_path
+        self.current_image_path = image_path
+        self.text_path_label.setText(f"Text: {text_path.name}")
+        self.text_path_label.setToolTip(str(text_path))
+        self.image_path_label.setText(f"Image: {image_path.name}")
</code_context>
<issue_to_address>
**nitpick (bug_risk):** Long selected filenames are placed in fixed-width, non-wrapping `QLabel`s without elision or a scrollable header, so the filename is clipped rather than remaining visible in the pane.

**Triggers:** When either selected filename is longer than the available pane width.

**Suggested fix:** Use a horizontally scrollable label, enable wrapping, or display an elided filename with the complete name in an accessible tooltip.

```suggestion
        self.text_path_label.setText(f"Text: {text_path.name}")
        self.text_path_label.setWordWrap(True)
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread src/textbeside/app.py

self.current_text_path = text_path
self.current_image_path = image_path
self.text_path_label.setText(f"Text: {text_path.name}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (bug_risk): Long selected filenames are placed in fixed-width, non-wrapping QLabels without elision or a scrollable header, so the filename is clipped rather than remaining visible in the pane.

Triggers: When either selected filename is longer than the available pane width.

Suggested fix: Use a horizontally scrollable label, enable wrapping, or display an elided filename with the complete name in an accessible tooltip.

Suggested change
self.text_path_label.setText(f"Text: {text_path.name}")
self.text_path_label.setText(f"Text: {text_path.name}")
self.text_path_label.setWordWrap(True)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

Only a minor README PowerShell activation-path nit remains; no blocking issues were identified.

Review effort: Lite
Findings: None

What changed in this PR

Adds the initial installable TextBeside Qt prototype with a split editor/image view and safe manual pair loading.

Changes:

  • Adds the PySide6 application and console entry point.
  • Implements text/image pair loading with unsaved-edit protection.
  • Adds packaging metadata, smoke tests, and setup documentation.
  • Notes a minor PowerShell activation-path documentation nit.
File Description
tests/​test_app.py Adds Qt application smoke tests.
tests/​conftest.py Configures offscreen Qt testing.
src/​textbeside/​app.py Implements the split window and safe pair loading.
src/​textbeside/​__init__.py Defines package metadata.
README.md Documents setup, usage, and prototype scope.
pyproject.toml Configures packaging and dependencies.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prototype: package scaffold and split window

2 participants