| Age | Commit message (Collapse) | Author | Files | Lines |
|
Nothing loaded a translation before this: no QTranslator, no .ts file and
no build rule, so every string was English whatever the locale said. The
language now comes from the environment, LANG=it_IT.UTF-8, and any other
locale runs in English as before.
The audit found that the tr() discipline was largely holding, and found
eight strings that could never be translated into any language. kFields[]
in tagrulesdialog.cpp declared the rule-builder field labels with
QT_TR_NOOP inside an anonymous namespace, where lupdate reports "tr()
cannot be called without context" and extracts nothing, while the use site
calls TagRulesDialog::tr() on them at runtime. From, To, Cc, Subject, Tag,
Folder, Attachment and Date: the whole vocabulary of the rule builder,
absent from every translation file that could ever exist. The source
compiles and reads correctly; only lupdate reveals it.
Q_DECLARE_TR_FUNCTIONS is not the fix for that case, though it is the fix
for a free function calling tr(). Measured against lupdate: a class
carrying the macro beside the array still extracts 0 strings, because the
context must be attached to the literal itself. QT_TRANSLATE_NOOP names it
explicitly and matches the tr() that already reads them, so the use site
needed no change.
Twenty configuration and keybinding warnings were not translatable either.
They are user-facing, reaching the status label and the "Configuration
problems" dialog. Config already had the tr() macro; KeyMap needed it.
Translating the filter labels then broke startup_query, found in hand
testing: a filter's name is a translated label, so `startup_query = Inbox`
matched nothing where the filter shows as "In arrivo". The application
opened a different view and reported the user's own working config as
invalid. Resolution matches the generator as well now, which is stored in
queries.json and identical in every locale; the translated name still
works. The regression test installs a real QTranslator rather than a stub,
since the bug lives in the gap between the stored string and the displayed
one, and it writes a queries.json because the warning it asserts on is
guarded by a non-empty saved-query list: without one the branch never runs
and the test passes against a broken check.
main.cpp's --help and --version stay bare printf, as they run before
QApplication exists and no translator could serve them.
Verified per the backlog's own standard, that lupdate output is the
evidence rather than reading: 355 strings extracted with zero context
warnings, where before there were 327 with eight; lrelease reporting 355
finished and 0 unfinished; the built .qm loaded in a standalone probe
printing "From -> Da" and both Italian plural forms; and the install rule
placing it where main.cpp looks. test_translations guards it and was
mutation checked, failing on an emptied translation and naming the defect
when QT_TRANSLATE_NOOP is reverted.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
next_thread and prev_thread now walk with indexBelow/indexAbove, skipping
message rows, so they keep meaning thread-to-thread whatever is expanded.
Stepping message-to-message needs no code: QTreeView's own Up/Down walk VISIBLE
rows and already enter an expanded thread, and being the view's key handling
rather than a shortcut they stay inert when the message pane, a menu or an entry
bar has focus.
Item 60 turns out to have been fixed already, in 5487d58 on this branch, by
threadRowOf() walking up to the containing thread before doing the arithmetic.
The backlog entry was written against master, where that helper does not exist,
so it described a defect this branch had resolved a commit earlier. Verified by
writing both failing tests first and watching them pass: from the last reply of
an expanded thread, and from a thread root with its replies showing. They are
kept, because the property they assert is the one this change must not lose.
What the rewrite buys is that nothing is keyed on a row number any more, which
is the rule a deeper tree would break next.
Alt+Up/Down added alongside Ctrl+J/K. That required KeyMap::sequencesFor and a
move from setShortcut to setShortcuts, because the singular setter keeps only
the last binding and the second one was silently unreachable. Alt because
Shift+arrows is the built-in extend-selection that multi-row tagging depends on,
and because a bare arrow cannot be a window shortcut without breaking every text
field in the window, as Return already demonstrated. sequencesFor puts
sequenceFor's own choice first so the menus advertise an unchanged binding, and
sorts the tail, since QHash order is unspecified.
|
|
Typing a capital emits Shift+<key>, but QKeySequence::fromString() folds
the case of a bare letter away: "N" parsed to plain Key_N, a combination
no keystroke produces. The N, F and G defaults (toggle_unread, flag and
sync) therefore never fired, and neither would any hand-written capital
in [keys].
normalizeSequence() rewrites a bare capital to Shift+<letter> and is
shared by the defaults and the override pass. As a side effect "y" and
"Y" become distinct keys rather than a collision that dropped one.
Defaults move to modifier shortcuts throughout. A single letter cannot
be a QAction shortcut without stealing that letter from every text field
in the window, and the menus in the next commit need real accelerators.
defaultBindings() is now the one source of truth for them.
|
|
Confirmed with the maintainer as v2-only rather than v2-or-later. LICENSE is
the official text from gnu.org. Every file under src/ and tests/ carries the
matching notice.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Maps key sequences to action name strings, with hardcoded vim-style
defaults and QSettings-based [keys] overrides. Unknown actions and
unparseable sequences are collected as warnings rather than treated
as fatal, so a typo in the config cannot silently misbind or crash.
Note: QKeySequence::fromString() on Qt 6.11 does not return an empty
sequence for unparseable input (e.g. "NotAKey++") -- it returns a
non-empty sequence whose toString() is empty. Detection uses that
instead of isEmpty().
|