diff options
| -rw-r--r-- | CHANGELOG.md | 37 | ||||
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | README.md | 24 |
3 files changed, 62 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index fd71c70..c0ec610 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,43 @@ point at which they are stable. Nothing yet. +## [0.4.0] - 2026-08-03 + +Attachments become reachable. They were parsed all along and there was simply +no way to get at one, and no way to tell a message had any without opening it. + +### Added + +- A paperclip column marks threads carrying an attachment, so it is visible + without opening the thread. Driven by the `attachment` tag notmuch already + applies, so it costs no extra query. +- The message pane lists attachments behind one **Attachments (N)** button: + a dialog with the message number, filename and size, a **Save** for each, + and **Save all** when there is more than one. +- **Save all** writes into a new subfolder named `<date> <subject>` inside a + folder you pick, so a thread with sixteen files does not scatter them among + whatever is already there. The folder is named in the picker before you + choose, and an existing folder of that name is never merged into. + +### Fixed + +- **Attachments were unreachable.** The attachment bar had been created and + added to the layout since it was written, and nothing ever populated it. +- **Saving several attachments could destroy files.** Messages in one thread + commonly attach the same filename, and each save overwrote the previous one + while still reporting success: sixteen attachments produced ten files. Batch + saves now add a numeric suffix instead, and keep a compound extension like + `.tar.gz` whole. +- **A `Date:` header carrying a timezone comment lost its date.** `+0200 + (CEST)` is legal and common, but Qt rejects the whole header rather than the + comment, so those messages got no date prefix on their folder. + +### Changed + +- Thread-list column widths reset once on first launch after upgrading. The + saved layout is from before the paperclip column existed, and applying it + would have shifted every width onto the wrong column. + ## [0.3.0] - 2026-08-03 The app remembers how you left it. Window, splitter and column sizes survive diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a08928..827b806 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.21) -project(qtmaildir VERSION 0.3.0 LANGUAGES CXX) +project(qtmaildir VERSION 0.4.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -158,6 +158,30 @@ Note that a `/` in an INI key is a group separator to QSettings, so as `shopping\amazon`. It is read back correctly; the escaping is QSettings' own. +## Attachments + +A paperclip in the leftmost column of the thread list marks threads that carry +an attachment, so it is visible without opening the thread. It comes from the +`attachment` tag notmuch applies while indexing, not from parsing the message, +and costs no extra query. + +Under the message pane, one **Attachments (N)** button opens a list of the +thread's attachments: which message each came from, its filename and its size, +with a **Save** for each. With more than one, **Save all** writes them into a +new subfolder named `<date> <subject>` inside a folder you choose. The subfolder +is named in the picker before you commit to a location, and an existing folder +of that name is never merged into. + +Filenames in a message are untrusted, so what is displayed and written is +always a sanitised basename: an attachment named `../../etc/passwd` is written +inside the folder you chose and nowhere else. Where several messages in a thread +attach the same filename, later ones get a numeric suffix rather than +overwriting the earlier file. + +Opening an attachment in its default application is deliberately not offered. +Handing a file from a stranger to `xdg-open` is a different security decision +from writing it where you asked, and is not one this program makes for you. + ## Keybindings Defaults, all rebindable through `[keys]`: |
