Commit Graph

281 Commits

Author SHA1 Message Date
Simon Chopin
ac14df7bec thread: add a splitter between thread and header panels 2024-07-04 16:13:25 +02:00
Simon Chopin
9147fbc4fc thread: flatten the tree if it doesn't branch
If the thread never branches out, simply flatten the tree to avoid the
extra indentation levels.
2024-07-04 16:13:25 +02:00
Simon Chopin
e431c343ee thread: don't show the email address but highlight subject changes
IMHO, having the full name of the sender is more important than the
email in the message list. However, we can use the new free screen
realestate to display the new subject line if it has changed
2024-07-04 16:13:25 +02:00
Simon Chopin
05b8b84b74 Use a tree view for the thread listing
Besides the obvious tree-like thing, this has for consequences that the
ordering of messages is slightly different, as they are now
topologically sorted rather than through purely chronological order.
2024-07-04 16:13:25 +02:00
Simon Chopin
cd3fd02ded thread: call super().refresh() before doing our own
It avoids parallel refreshes, which can happen if the refresh triggers a
secondary data update, e.g. via automatic mark as read on thread
opening.

It means we trigger our own has_refreshed signal, but that's OK, the
effects should only be a top-level view refresh.
2024-06-24 11:43:21 +02:00
Simon Chopin
b75da6aa54 thread: move completely away from int indices
This is a good old breaking change. Now, `current_message` will actually
yield the current message object rather than its index, while said index
is available at `current_index`. All the model APIs are changed to
consume and emit QModelIndex, and said indices are attached the message
they represent at creation, making it easier.

The goal long-term is to be able to move away from the ListView to use a
TreeView instead.
2024-06-24 11:42:52 +02:00
Simon Chopin
1e661e718d thread: do away with show_message
show_message has a weird API that deals in integer indices, and is also
used to refresh the UI. The indices are annoying because they're an
implementation detail, and the refresh part is a bit surprising when you
come across it in the code.

Removing it leaves only `current_message` as the remaining "integer" API
from ThreadPanel.
2024-06-24 11:42:48 +02:00
Simon Chopin
4dc8562779 thread: move the next unread logic to the model 2024-06-24 11:36:44 +02:00
Simon Chopin
52c38ab0aa thread: move tag handing within the model
It makes sense to have the model deal with the external notmuch calls,
while the Panel just connects the dots.
2024-06-24 11:36:44 +02:00
Simon Chopin
09bdd4e770 thread: move the UI update as a reaction to data update
Rather than explicitly refreshing the data *then* the UI, let's just use
the default model signals to trigger the UI refreshes

This actually saves us a full refresh when first opening a thread.
2024-06-24 11:36:44 +02:00
Simon Chopin
7174f2bb04 panel: add a signal post-refresh, used to update the tab title
This will pay off later on when reducing the number of refreshes, and to
develop more dynamic features, e.g. refining a thread query in-place
2024-06-24 11:32:02 +02:00
Simon Chopin
9f836ec01a thread: gray out the irrelevant messages
Irrelevant in the sense that they didn't match the origin search query.
Not all themes have been tested, the values were determined by looking
for the recommended value for code comments on the various colorscheme
homepages.
2024-06-20 18:54:15 +02:00
Simon Chopin
9204231ec0 thread: new keybinding to jump to next relevant unread
Mightily useful when reading huge ML threads.
2024-06-20 18:54:15 +02:00
Simon Chopin
e9b18ae7bf thread: jump to the first message matching the search query
Any thread opening is normally done from a search query. That search
query might have nothing to do with the unread status, and could only
match a handful of messages in the thread. So, rather than jumping to
the first unread message, we keep the search query as context when
opening the thread and use it to jump to the first message matching it.
2024-06-20 18:54:09 +02:00
Simon Chopin
4aa276050e Add refresh at the message granularity
When tagging a single message in a thread, only refresh that message
rather than the entire thread.

This is again due to some threads being *very* big, which when combined
with crypto signatures make the UI feel sluggish when changing the state
of a message, e.g. when reading it for the first time.

The computing time now doesn't scale with the size of the thread. It's
at similar levels from before on small threads, and is an order of
magnitude better on the recent tmpfs thread on debian-devel.

Note that right now we go through the entire list to get the index of a
given message. This could easily be optimized later on.
2024-06-20 18:52:08 +02:00
Simon Chopin
647af204b7 thread: Don't refresh the data on display_message
This has a really noticeable cost when reading monster threads, e.g. if
you're reading Debian mailing lists. It gets even worse when there's
crypto involved! OTOH, it's fairly unlikely that the data changes
underneath our feet if we're using Dodo to drive the "notmuch new"
calls, as it would trigger a refresh when done (or mark the panel as
dirty).
2024-06-18 10:32:23 +02:00
Aleks Kissinger
f28a71c06f
Merge pull request #54 from laarmen/refreshes
Allow for thread-level refreshes
2024-06-10 09:51:47 -07:00
Aleks Kissinger
70fd5ad73c
Merge pull request #55 from laarmen/logs
Add some minimal logging support
2024-06-10 09:51:27 -07:00
Aleks Kissinger
c2bdacf446
Merge pull request #53 from hbog/filename
unfold filename from content-disposition header
2024-06-10 09:50:35 -07:00
Aleks Kissinger
2768c2d5b6
Merge pull request #51 from hbog/encryption
Fix signing mail with non-ascii  headers and add encryption
2024-06-10 09:49:40 -07:00
Aleks Kissinger
add030278c
Merge pull request #47 from laarmen/multiline-header
compose: directly load the draft into the final EmailMessage object
2024-06-10 09:47:39 -07:00
Simon Chopin
b5cb39bf2b search: defer thread-specific refreshes until the next focus
This allows collating multiple events on the same threads, e.g. reading
a long unread thread in a Thread panel. The previous approach would
trigger a full refresh if reading more than one message.
2024-06-04 10:41:22 +02:00
Simon Chopin
f209e0cc05 Add some minimal logging support
This has been useful in some of my recent investigations.
2024-06-04 10:31:45 +02:00
Simon Chopin
f816267a9c Move the 'refresh-on-focus' logic from mainwindow.py into panel.py
This will allow customizing this behavior in specialized panels
afterward.
2024-06-04 10:30:06 +02:00
Simon Chopin
673a07c2b0 thread: don't explicitly refresh on unread
It's already taken care of in `tag_message()`.
2024-06-04 10:30:06 +02:00
Simon Chopin
a43ee74812 Allow for thread-level refreshes
Updating the entire search panel when touching any piece of data is
really costly, which is presumably why we only do it on the currently
active one and will only refresh the other ones when we focus them.

This patch allows for a more granular approach to refreshes, with an API
that specifies which thread has been updated. Each panel can then either
update their own data model (if known to be relevant, e.g. the thread is
already in the search results, and it is cheap enough to do it right
away), mark itself as dirty to fall back on the previous global
behaviour, or ignore the update entirely (relevant for Thread panels).
2024-06-04 10:30:06 +02:00
Herwig Bogaert
d801b03401
fix startup error when gnupg is not present 2024-05-31 19:24:45 +02:00
Herwig Bogaert
fa5be01768
unfold filename from content-disposition header
When line wrapping in a folded content-disposition header occurs within
its filename parameter value, then the get_filename() method of the
(legacy) email.message.Message object returns a string containing a
newline character at the position where the filename parameter value
wraps. An attachment filename containing a newline character may result
in undefined behaviour with file management tools or scripts and may
have security implication. It also prevents forwarding mail in dodo by
throwing the exception 'Header values may not contain linefeed or
carriage return characters', because the filename is copied in the A:
pseudo-header.

This bug is not present in the email.message.EmailMessage class, which is
used when specifying the policy email.policy.default.

Additionally, the legacy method get_payload() is replaced by
get_content().
2024-05-26 10:06:03 +02:00
Herwig Bogaert
a000f0df3b
Automatically decrypt encrypted messages
Before, messages were only decrypted if a session key was already
present due to the default behaviour of notmuch-show. (--decrypt=auto)
2024-05-16 11:48:18 +02:00
Herwig Bogaert
9e2cef65dc
fix codestyle 2024-05-16 11:18:06 +02:00
Herwig bogaert
4f263ccffd
show decription status 2024-05-16 11:18:06 +02:00
Herwig bogaert
3fa57ee364
fix problem with non-ascii characters in headers
Signing and encryption is done on a copy of the original message. When
this original message contained non-ASCII characters, the copy process
introduced encoded words with the unknown-8bit charset.
2024-05-16 11:18:06 +02:00
Herwig bogaert
b71ddc87ed
always add encryption for from address 2024-05-16 11:18:06 +02:00
Herwig bogaert
492c44bbf4
add PGP Encryption information to Readme. 2024-05-16 11:18:06 +02:00
Herwig bogaert
aafb8d6dd9
refactor: move pgphandling to pgp_util.py 2024-05-16 11:18:06 +02:00
Herwig bogaert
7fa69262d9
add PGP encryption and decryption 2024-05-16 11:18:05 +02:00
Simon Chopin
61f8a1d286 compose: directly load the draft into the final EmailMessage object
This simplifies the code as we don't have to copy the data over from the
temporary Message object. The header copying in particular was failing
when using multiline headers as allowed by RFC 822.

I'm guessing we *could* get into trouble with encoding though? Since I'm
using UTF-8 everywhere it works fine for me.
2024-04-09 15:16:56 +02:00
Aleks Kissinger
e3fbfd04ee
Merge pull request #18 from leromarinvit/fix-remote-request-blocking
Use QWebEngineUrlRequestInterceptor to block remote requests
2024-04-09 13:51:46 +01:00
Aleks Kissinger
cd8a07b61a
Merge pull request #41 from hashhsah/html_charset
Html charset
2024-04-09 13:43:39 +01:00
Aleks Kissinger
5313ab6f29
Merge pull request #39 from hbog/hooks
add configuration option for running notmuch hooks on send
2024-04-09 13:41:39 +01:00
Aleks Kissinger
3460163a5b
Merge pull request #45 from laarmen/py3.12
colorize_text: use raw strings for regex
2024-04-09 13:40:35 +01:00
Aleks Kissinger
212225e074
Merge branch 'master' into py3.12 2024-04-09 13:40:11 +01:00
Aleks Kissinger
3ee641e558
Merge pull request #44 from laarmen/case-content-type
Do a case-insensitive content-type comparison
2024-04-09 13:33:51 +01:00
Aleks Kissinger
2d5fe85c8f
Merge pull request #46 from laarmen/reply-to-header
Implement support for the Reply-To field
2024-04-09 13:26:59 +01:00
Aleks Kissinger
6aa1962718
Merge pull request #40 from hashhsah/master
fix: produce 7-bit clean messages.
2024-04-09 13:25:41 +01:00
Aleks Kissinger
6a0beccc09
Merge pull request #48 from laarmen/geometry
Save the search panel tree geometry
2024-04-09 13:24:33 +01:00
Aleks Kissinger
f123797d07
Merge pull request #43 from laarmen/quote-text-prefix
compose: add a "On $date, $sender wrote:" header to quoted text
2024-04-09 13:22:25 +01:00
Simon Chopin
5d8632aafe Save the search panel tree geometry
This allows the user to set up the column width to their convenience.
2024-04-05 13:17:49 +02:00
Simon Chopin
a3a4d967a2 Implement support for the Reply-To field
Very useful to reply to Gitlab notifications and similar.
2024-03-15 15:11:56 +01:00
Simon Chopin
93244ad996 compose: use raw strings for regexes 2024-03-15 15:11:04 +01:00