Skip to content

FEAT(ui): Channel/User description dock#6779

Open
jvbsl wants to merge 3 commits intomumble-voip:masterfrom
jvbsl:feature/comment-view
Open

FEAT(ui): Channel/User description dock#6779
jvbsl wants to merge 3 commits intomumble-voip:masterfrom
jvbsl:feature/comment-view

Conversation

@jvbsl
Copy link
Contributor

@jvbsl jvbsl commented Apr 12, 2025

  • Added a ImageWidget for showing a resizable image which keeps its aspect ratio
  • Changed user comment to be observable using signals
  • Added user/channel description dock

Implements #3386

This is just a work in progress and solves some things in ways I personally don't think of as too nice. Perhaps someone can skim over it and give some tips.

Also the commit is not yet cleaned up of changes done by QT editor.

Additionally would be greatly appreciated if someone could try it out and give feedback whether it matches the things that were expected.
(Does layout saving work? Because for me it does not, but it also does not work from the master branch)

Edit: just noticed it doesn't even build the server, ups :D

Checks

Summary by CodeRabbit

  • New Features

    • Added a dockable Comment panel showing user/channel descriptions, avatars, OS/version, and live updates on user changes and channel renames.
  • Improvements

    • More reliable avatar/texture handling and automatic overlay updates.
    • UI integrates the Comment panel across layouts with better refresh behavior.
  • Localization

    • Expanded translations for the new Comment panel, tray actions, and related UI in many languages.
  • Chores

    • Updated ignore rules for IDE files.
    • Translation update tooling now scans additional source directories.

@jvbsl jvbsl force-pushed the feature/comment-view branch 4 times, most recently from 779f447 to 4a96c8f Compare April 15, 2025 17:19
@RafGamer
Copy link

This looks really good. Thanks for working on it!

One thing I noticed is that when resizing the dock, the avatar becomes too large, causing the content of the dock to overlap with the rest of the UI.

Also, I think there should be a maximum size for the resizable image.

@jvbsl
Copy link
Contributor Author

jvbsl commented Apr 25, 2025

Thanks for the feedback I get what you mean with a maximum size but could you please add a screenshot how it looks like when it overlaps, because I did not have that on my side, it just got big and the other content moved somewhere else(and could be scrolled at one point then).

@RafGamer
Copy link

Thanks for the feedback I get what you mean with a maximum size but could you please add a screenshot how it looks like when it overlaps, because I did not have that on my side, it just got big and the other content moved somewhere else(and could be scrolled at one point then).

2025-04-26T06:23:58,962283257+02:00

@jvbsl jvbsl force-pushed the feature/comment-view branch from 2d89293 to 9c09b7d Compare May 18, 2025 13:14
@jvbsl
Copy link
Contributor Author

jvbsl commented May 18, 2025

@RafGamer for me the window gets resized so that no actual overlap happens. But even that I think is not really nice. So I for now just set the maximum size of the avatar to 256x256, I think it is a reasonable size.
If you think this is good enough I will try to get the PR into a reviewable state soon.
And thanks for testing

@RafGamer
Copy link

@RafGamer for me the window gets resized so that no actual overlap happens. But even that I think is not really nice. So I for now just set the maximum size of the avatar to 256x256, I think it is a reasonable size. If you think this is good enough I will try to get the PR into a reviewable state soon. And thanks for testing

This looks good.

But I noticed that the avatar is only shown when the image is a png. It doesn't work when its a jpg and throws this warning: QPixmap::scaled: Pixmap is a null pixmap.

@jvbsl
Copy link
Contributor Author

jvbsl commented May 26, 2025

yes you are right, I completely forgot that I hardcoded that part:

// pretty sure this is not hardcoded

Need to look what a nice way would be because currently the actual conversion is in a completely different component

@RafGamer
Copy link

yes you are right, I completely forgot that I hardcoded that part:

// pretty sure this is not hardcoded

Need to look what a nice way would be because currently the actual conversion is in a completely different component

Yeah, I saw that line but didn't know whether this was a bug or the intended behavior.

Doesn't the texture contain a header? The Qt docs say that it can automatically guess the file format.

@jvbsl
Copy link
Contributor Author

jvbsl commented May 31, 2025

Well yes but there seems to be some legacy image data format which gets converted in the overlay. So that's also what I'm using here to make sure that it was converted and in turn the image format is also set:
676ce28

@Krzmbrzl https://github.com/mumble-voip/mumble/blob/master/src/mumble/Overlay.cpp#L357 does it make sense to have this texture verification and conversion from this compressed raw format in the Overlay which is actually optional in the client? Shouldn't this happen even without this feature enabled?

@Krzmbrzl
Copy link
Member

Yeah, I think doing the de-compression in code that may be excluded could likely cause issues. So it's probably better to just do the de-compression as soon as the texture is received 👀

@jvbsl jvbsl force-pushed the feature/comment-view branch 2 times, most recently from 88cbeaa to b0be4ab Compare June 28, 2025 13:24
@jvbsl
Copy link
Contributor Author

jvbsl commented Jun 28, 2025

I didn't want to directly add it to the database and wanted to keep the change to be not to big to the previous code, but I now extracted the texture decoding into another class with the (bad) name of TextureManager. For now in a separate commit.
If someone decides it is good enough for review, I will make it into a normal PR, and I can squash the commits later on

@jvbsl jvbsl force-pushed the feature/comment-view branch from b0be4ab to 97c2334 Compare June 28, 2025 13:30
@Hartmnt Hartmnt added client feature-request This issue or PR deals with a new feature labels Aug 2, 2025
@jvbsl jvbsl force-pushed the feature/comment-view branch 7 times, most recently from 6e31c07 to c394a6b Compare August 23, 2025 19:42
@jvbsl
Copy link
Contributor Author

jvbsl commented Aug 24, 2025

I guess I'm gonna make it ready for review, so that I can get some feedback on the code. Please be strict, because I only did it kind of iteratively so probably not the nicest code. And do tell if I should strip out the REFAC commit to another PR instead.

Edit: damn forgot that I still had WIP in the commit message^

@jvbsl jvbsl marked this pull request as ready for review August 24, 2025 09:39
@jvbsl jvbsl changed the title FEAT(ui): [WIP] Channel/User description dock FEAT(ui): Channel/User description dock Aug 24, 2025
jvbsl added 3 commits August 24, 2025 11:40
* Added a ImageWidget for showing a resizable image which keeps its aspect ratio
* Changed user comment to be observable using signals
* Added user/channel description dock
* Add widgets to be translatable
Previously this was done in the overlay, which would mean the decoding of the textures
in the legacy format could fail if the overlay is not configured to be compiled in.
@jvbsl jvbsl force-pushed the feature/comment-view branch from c394a6b to 6be11aa Compare August 24, 2025 09:41
@coderabbitai
Copy link

coderabbitai bot commented Aug 24, 2025

Walkthrough

Encapsulates user comments behind getters/setters across client and server. Introduces TextureManager with global instance and refactors texture handling and overlay updates. Adds CommentViewWidget (UI, logic, and image widget) and wires it into MainWindow and message handling. Expands translations and updates build and scripts to include new widgets for lupdate.

Changes

Cohort / File(s) Summary
Ignore rule
.gitignore
Add .idea to ignore list.
Translation tooling
scripts/updatetranslations.py
Include ./src/mumble/widgets in lupdate sources.
User comment encapsulation (client API)
src/User.h, src/User.cpp, src/mumble/ClientUser.h, src/mumble/Accessibility.cpp, src/mumble/API_v_1_x_x.cpp
Replace public qsComment member with qsComment(), setComment(), clearComment(). Update usages and add ClientUser::commentChanged signal; propagate through API_v_1_x_x and Accessibility.
Comment UI integration
src/mumble/MainWindow.h, src/mumble/MainWindow.cpp, src/mumble/MainWindow.ui, src/mumble/widgets/CommentViewWidget.h, src/mumble/widgets/CommentViewWidget.cpp, src/mumble/widgets/CommentViewWidget.ui
Add CommentViewWidget dock, update layout/visibility, refresh hook updateCommentView(), handle channel rename, and wire stats/comment updates into the new widget.
Image widget
src/mumble/widgets/ImageWidget.h, src/mumble/widgets/ImageWidget.cpp
New QLabel-based widget for scaled avatar display.
Build updates
src/mumble/CMakeLists.txt
Add TextureManager and new widgets (CommentViewWidget, ImageWidget) to sources/headers.
Texture pipeline refactor
src/mumble/TextureManager.h, src/mumble/TextureManager.cpp, src/mumble/Global.h, src/mumble/Global.cpp, src/mumble/Messages.cpp, src/mumble/UserModel.cpp, src/mumble/Overlay.cpp, src/mumble/Overlay.h
Add TextureManager (convertTexture), initialize global unique_ptr, route texture handling through it, adjust overlay update flow, and move verifyTexture to private.
MainWindow interactions
src/mumble/MainWindow.cpp, src/mumble/MainWindow.h
Connect UserModel::channelRenamed, add on_channelRenamed(int) and updateCommentView(). Use comment accessors in actions/dialogs.
Server-side comment encapsulation
src/murmur/Server.cpp, src/murmur/Server.h, src/murmur/RPC.cpp, src/murmur/Messages.cpp, src/murmur/MumbleServerIce.cpp, src/murmur/DBWrapper.cpp
Introduce Server::hashAssign(QByteArray&, const QString&). Replace direct comment field usage with getters/setters in ServerUser/ServerUserInfo and related flows (auth, RPC, ICE, DB).
UserView instrumentation
src/mumble/UserView.cpp
Log event type; minor refactor using local variable.
Translations
src/mumble/mumble_*.ts
Add contexts/strings for AccessibleQGroupBox, CommentViewWidget, TrayIcon, ResponsiveImageDialog, and “Comment” additions in various contexts; some duplicate blocks.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as User
  participant MW as MainWindow
  participant CVW as CommentViewWidget
  participant UM as UserModel
  participant DB as Database
  participant OL as Overlay

  User->>MW: Select user/channel / UI event
  MW->>CVW: updateCommentView(p, c)
  alt User selected
    CVW->>UM: request UserStats(session)
    CVW->>DB: load comment/texture if missing
    DB-->>CVW: comment/texture (optional)
    CVW->>OL: updateOverlay() (if texture present)
    CVW->>CVW: updateCommentContent(user, null)
    Note over CVW: Connect to<br/>localNicknameChanged,<br/>commentChanged
  else Channel view
    CVW->>DB: load channel description if missing
    DB-->>CVW: description (optional)
    CVW->>CVW: updateCommentContent(null, channel)
    Note over CVW: Subscribe to channel<br/>entered/exited to refresh
  end
Loading
sequenceDiagram
  autonumber
  participant Net as Network
  participant MSG as Messages/UserModel
  participant TM as TextureManager
  participant G as Global.textureManager
  participant OL as Overlay

  Net-->>MSG: UserState with texture or hash
  MSG->>G: get TextureManager
  MSG->>TM: convertTexture(blob, out format)
  TM-->>MSG: converted blob or empty
  alt converted non-empty
    MSG->>MSG: set qbaTexture/qbaTextureHash
    MSG->>OL: updateOverlay()
  else empty
    MSG->>Net: RequestBlob (texture)
  end
Loading
sequenceDiagram
  autonumber
  participant RPC as RPC::setUserState
  participant SU as ServerUser
  participant S as Server

  RPC->>SU: compare comment vs qsComment()
  alt changed
    RPC->>S: hashAssign(SU.qbaCommentHash, newComment)
    S-->>RPC: returns newComment (ref)
    RPC->>SU: setComment(returned QString)
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

A whisk of code, a texture’s sheen,
I hop through widgets, neat and clean.
Comments now with proper gates,
A dock that swaps and syncs with states.
Avatars glow, translations sing—
Carrots compiled, I spring-spring-spring! 🥕✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.38.6)
src/mumble/mumble_ar.ts
src/mumble/mumble_bg.ts
src/mumble/mumble_br.ts
  • 21 others

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 147

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (21)
src/mumble/mumble_fi.ts (5)

1643-1658: Complete listener-attenuation option strings

These appear in a user-facing selector. Unfinished entries will fall back to English and break consistency.

Apply this diff:

-        <source>at</source>
-        <translation type="unfinished"></translation>
+        <source>at</source>
+        <translation>tasolla</translation>
@@
-        <source>while someone in your channel talks</source>
-        <translation type="unfinished"></translation>
+        <source>while someone in your channel talks</source>
+        <translation>kun joku kanavallasi puhuu</translation>
@@
-        <source>always</source>
-        <translation type="unfinished"></translation>
+        <source>always</source>
+        <translation>aina</translation>
@@
-        <source>Attenuate listeners by...</source>
-        <translation type="unfinished"></translation>
+        <source>Attenuate listeners by...</source>
+        <translation>Vaimenna kuuntelijoita...</translation>

5063-5093: Finish TalkingUI background controls translations

Complete these to keep the Look & Feel page fully localized.

Apply this diff:

-        <source>Clears the TalkingUI background setting.</source>
-        <translation type="unfinished"></translation>
+        <source>Clears the TalkingUI background setting.</source>
+        <translation>Tyhjentää Puhujalistan tausta-asetuksen.</translation>
@@
-        <source>Clear Background Color</source>
-        <translation type="unfinished"></translation>
+        <source>Clear Background Color</source>
+        <translation>Tyhjennä taustaväri</translation>
@@
-        <source>Clear</source>
-        <translation type="unfinished">Tyhjennä</translation>
+        <source>Clear</source>
+        <translation>Tyhjennä</translation>
@@
-        <source>Color that gets used for the background of the talkingUI.</source>
-        <translation type="unfinished"></translation>
+        <source>Color that gets used for the background of the talkingUI.</source>
+        <translation>Puhujalistan taustana käytettävä väri.</translation>
@@
-        <source>Choose</source>
-        <translation type="unfinished"></translation>
+        <source>Choose</source>
+        <translation>Valitse</translation>
@@
-        <source>Background color that, if set, overrides the theme background color.</source>
-        <translation type="unfinished"></translation>
+        <source>Background color that, if set, overrides the theme background color.</source>
+        <translation>Taustaväri, joka asetettuna ohittaa teeman taustavärin.</translation>
@@
-        <source>Background Color</source>
-        <translation type="unfinished"></translation>
+        <source>Background Color</source>
+        <translation>Taustaväri</translation>
@@
-        <source>Choose a Color</source>
-        <translation type="unfinished"></translation>
+        <source>Choose a Color</source>
+        <translation>Valitse väri</translation>

5095-5150: Finish Dark/Light theme configuration translations

New theme-related strings are all unfinished. Provide concise Finnish equivalents.

Apply this diff:

-        <source>Dark theme to use to style the user interface</source>
-        <translation type="unfinished"></translation>
+        <source>Dark theme to use to style the user interface</source>
+        <translation>Tumma teema käyttöliittymän tyylitykseen</translation>
@@
-        <source>&lt;b&gt;Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme&lt;/b&gt;&lt;br /&gt;Mumble will pick up themes from certain directories and display them in this list. The one you select will be used to customize the visual appearance of Mumble. This includes colors, icons and more.</source>
-        <translation type="unfinished"></translation>
+        <source>&lt;b&gt;Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme&lt;/b&gt;&lt;br /&gt;Mumble will pick up themes from certain directories and display them in this list. The one you select will be used to customize the visual appearance of Mumble. This includes colors, icons and more.</source>
+        <translation>&lt;b&gt;Määrittää millä teemalla Mumblen käyttöliittymä tyylitellään tummassa tilassa&lt;/b&gt;&lt;br /&gt;Mumble hakee teemoja tietyistä hakemistoista ja näyttää ne tässä luettelossa. Valittua teemaa käytetään ulkoasun (värit, kuvakkeet jne.) mukauttamiseen.</translation>
@@
-        <source>Light theme to use to style the user interface</source>
-        <translation type="unfinished"></translation>
+        <source>Light theme to use to style the user interface</source>
+        <translation>Vaalea teema käyttöliittymän tyylitykseen</translation>
@@
-        <source>Dark Theme</source>
-        <translation type="unfinished"></translation>
+        <source>Dark Theme</source>
+        <translation>Tumma teema</translation>
@@
-        <source>Sets the theme automatically based on the system theme.</source>
-        <translation type="unfinished"></translation>
+        <source>Sets the theme automatically based on the system theme.</source>
+        <translation>Asettaa teeman automaattisesti järjestelmän teeman perusteella.</translation>
@@
-        <source>Automatic theme based on system theme</source>
-        <translation type="unfinished"></translation>
+        <source>Automatic theme based on system theme</source>
+        <translation>Automaattinen teema järjestelmän teeman mukaan</translation>
@@
-        <source>Auto</source>
-        <translation type="unfinished"></translation>
+        <source>Auto</source>
+        <translation>Automaattinen</translation>
@@
-        <source>Sets the theme to the configured dark theme setting</source>
-        <translation type="unfinished"></translation>
+        <source>Sets the theme to the configured dark theme setting</source>
+        <translation>Ottaa käyttöön määritetyn tumman teeman</translation>
@@
-        <source>Dark</source>
-        <translation type="unfinished"></translation>
+        <source>Dark</source>
+        <translation>Tumma</translation>
@@
-        <source>Sets the theme to the configured light theme setting</source>
-        <translation type="unfinished"></translation>
+        <source>Sets the theme to the configured light theme setting</source>
+        <translation>Ottaa käyttöön määritetyn vaalean teeman</translation>
@@
-        <source>Light Theme</source>
-        <translation type="unfinished"></translation>
+        <source>Light Theme</source>
+        <translation>Vaalea teema</translation>
@@
-        <source>Light</source>
-        <translation type="unfinished"></translation>
+        <source>Light</source>
+        <translation>Vaalea</translation>
@@
-        <source>Open the themes directory in the systems file manager</source>
-        <translation type="unfinished"></translation>
+        <source>Open the themes directory in the systems file manager</source>
+        <translation>Avaa teemakansio tiedostonhallinnassa</translation>
@@
-        <source>Open Themes Directory</source>
-        <translation type="unfinished"></translation>
+        <source>Open Themes Directory</source>
+        <translation>Avaa teemakansio</translation>

9619-9654: Complete UserInformation statistics strings

These appear in the connection stats. Provide final translations and remove unfinished flags.

Apply this diff:

-        <source>to client rolling average</source>
-        <translation type="unfinished"></translation>
+        <source>to client rolling average</source>
+        <translation>Ohjelmalle liukuva keskiarvo</translation>
@@
-        <source>Last X minutes:</source>
-        <translation type="unfinished"></translation>
+        <source>Last X minutes:</source>
+        <translation>Viimeiset X minuuttia:</translation>
@@
-        <source>% lost</source>
-        <translation type="unfinished"></translation>
+        <source>% lost</source>
+        <translation>% hävikkiä</translation>
@@
-        <source>from client rolling average</source>
-        <translation type="unfinished"></translation>
+        <source>from client rolling average</source>
+        <translation>Ohjelmalta liukuva keskiarvo</translation>
@@
-        <source>% late</source>
-        <translation type="unfinished"></translation>
+        <source>% late</source>
+        <translation>% myöhässä</translation>
@@
-        <source>Total:</source>
-        <translation type="unfinished"></translation>
+        <source>Total:</source>
+        <translation>Yhteensä:</translation>
@@
-        <source>Last %1 %2:</source>
-        <translation type="unfinished"></translation>
+        <source>Last %1 %2:</source>
+        <translation>Viimeiset %1 %2:</translation>
@@
-        <source>seconds</source>
-        <translation type="unfinished">sekuntia</translation>
+        <source>seconds</source>
+        <translation>sekuntia</translation>
@@
-        <source>minutes</source>
-        <translation type="unfinished"></translation>
+        <source>minutes</source>
+        <translation>minuuttia</translation>

10124-10131: Localize new Voice Recorder output modes (JACK)

Finish these labels to match existing recorder terminology.

Apply this diff:

-        <source>Multichannel + Transport (JACK)</source>
-        <translation type="unfinished"></translation>
+        <source>Multichannel + Transport (JACK)</source>
+        <translation>Monikanava + kuljetus (JACK)</translation>
@@
-        <source>Transport (JACK, standalone)</source>
-        <translation type="unfinished"></translation>
+        <source>Transport (JACK, standalone)</source>
+        <translation>Kuljetus (JACK, erillinen)</translation>
scripts/updatetranslations.py (1)

86-88: Bug: bytes/str concatenation in error path crashes on lupdate failure.

logging.debug('stdout: ' + res.stdout) will raise a TypeError (str + bytes). This masks the real lupdate error and can break CI diagnostics.

Apply this diff:

@@
-    if debuglupdate:
-        logging.debug(res.stdout)
+    if debuglupdate:
+        logging.debug('lupdate stdout:\n%s', res.stdout.decode('utf-8', errors='replace'))
+        logging.debug('lupdate stderr:\n%s', res.stderr.decode('utf-8', errors='replace'))
     if res.returncode != 0:
         logging.error('lupdate failed with error code %d', res.returncode)
-        logging.debug('stdout: ' + res.stdout)
-        exit(1)
+        logging.debug('lupdate stdout:\n%s', res.stdout.decode('utf-8', errors='replace'))
+        logging.debug('lupdate stderr:\n%s', res.stderr.decode('utf-8', errors='replace'))
+        sys.exit(1)
src/mumble/mumble_tr.ts (2)

7291-7301: Provide translations for image dialog strings

These user-facing strings are currently unfinished.

Apply this diff:

-        <source>Open Image</source>
-        <translation type="unfinished"></translation>
+        <source>Open Image</source>
+        <translation>Görsel Aç</translation>
@@
-        <source>Error</source>
-        <translation type="unfinished"></translation>
+        <source>Error</source>
+        <translation>Hata</translation>
@@
-        <source>Failed to decode image.</source>
-        <translation type="unfinished"></translation>
+        <source>Failed to decode image.</source>
+        <translation>Görsel çözümlenemedi.</translation>

1-10175: Unfinished translations found — please complete before release

Quick summary: src/mumble/mumble_tr.ts contains translation nodes still marked type="unfinished" in several newly introduced contexts. These must be translated or the unfinished attribute removed before release.

Files/contexts and source strings requiring attention:

  • src/mumble/mumble_tr.ts — AccessibleQGroupBox
    • "empty"
  • src/mumble/mumble_tr.ts — CommentViewWidget
    • "Title"
    • "Users"
    • "Properties"
    • "OS"
    • "Version"
    • "Description:"
    • "This is a test text"
    • "Comment"
    • "Description"
    • "%1 (%2)"
  • src/mumble/mumble_tr.ts — MainWindow
    • long usage/help block starting "Usage: mumble [options] [...]" (entire block is unfinished)
    • "Adaptive Push"
    • "When using the push-to-talk transmission mode, this will act as the push-to-talk action. Otherwise, it will act as a push-to-mute action."
    • "Open Image"
    • "Error"
    • "Failed to decode image."
    • "Comment"
  • src/mumble/mumble_tr.ts — ResponsiveImageDialog
    • "Image Preview"
  • src/mumble/mumble_tr.ts — TrayIcon
    • "Show"
    • "Hide"

Action required:

  • Provide Turkish translations for the empty entries and/or finish the existing translations.
  • Remove type="unfinished" from translation nodes that are complete.
  • Re-run a check (e.g. rg -n 'type="unfinished"' src/mumble/mumble_tr.ts) and ensure no unfinished entries remain in these contexts.
src/mumble/mumble_te.ts (3)

71-79: Correct “Password” translation and remove stray line breaks

Current translation “సాంకేతిక పదం” is incorrect for “Password” and includes extra newlines that degrade readability.

     <message>
         <source>Password</source>
-        <translation>సాంకేతిక పదం
-
-
-
-
-
-</translation>
+        <translation>పాస్‌వర్డ్</translation>
     </message>

27-29: Fix obvious mistranslations and typos in early ACLEditor strings

These are user-facing staples and currently misleading or machine-transliterated.

@@
-        <translation>సడలించు సర్వర్ విలువ</translation>
+        <translation>డిఫాల్ట్ సర్వర్ విలువ</translation>
@@
-        <translation> కధనం</translation>
+        <translation>వివరణ</translation>
@@
-        <translation>అనిత్యమైన</translation>
+        <translation>తాత్కాలికం</translation>
@@
-        <translation>తల్లితండ్రి నుంచి వారసత్వ జాబితసంక్య</translation>
+        <translation>మాతృ ఛానల్ నుండి గ్రూప్ సభ్యులను వారసత్వంగా పొందు</translation>
@@
-        <translation>గ్రూప్ వజ్ ఇణెరిటెడ్ బై పెరెంట్ పెరెంట్</translation>
+        <translation>సమూహం మాతృ ఛానల్ నుండి వారసత్వంగా పొందబడింది</translation>

Rationale: fixes wrong meaning, spelling, and transliterations, improving clarity and consistency.

Also applies to: 67-69, 89-91, 124-126, 140-142


43-45: Fix placeholder formatting in Telugu translations

The translation strings at the following locations include spaces between the % and the placeholder index, which will break runtime formatting and trigger lrelease warnings. Please update them to use %1 and %2 exactly (no intervening spaces), and adjust the Telugu wording as needed:

• File: src/mumble/mumble_te.ts, lines 43–45

-        <translation>ఇది% 1 హక్కును మంజూరు చేస్తుంది. ఒక విశేషణం అనుమతి మరియు తిరస్కరించబడినట్లయితే, అది ఖండించబడింది. &lt;br /&gt;% 2</translation>
+        <translation>ఇది %1 హక్కును మంజూరు చేస్తుంది. ఒక అధికారం అనుమతించి కూడా తిరస్కరించబడితే, అది తిరస్కరించబడినట్లే ఉంటుంది. &lt;br /&gt;%2</translation>

• File: src/mumble/mumble_te.ts, lines 51–53

-        <translation type="unfinished"></translation>
+        <translation>ఇది %1 హక్కును రద్దు చేస్తుంది. ఒక అధికారం అనుమతించి కూడా తిరస్కరించబడితే, అది తిరస్కరించబడినట్లే ఉంటుంది. &lt;br /&gt;%2</translation>

After applying these changes, please run lrelease to verify there are no remaining placeholder mismatches.

src/mumble/mumble_uk.ts (1)

5096-5151: Provide translations for new Theme selection controls (Dark/Light/Auto).

Missing translations leave parts of the new theming UI in English. Suggestions below keep terminology consistent with the rest of the settings pages.

-        <source>Dark theme to use to style the user interface</source>
-        <translation type="unfinished"></translation>
+        <source>Dark theme to use to style the user interface</source>
+        <translation>Темна тема для оформлення інтерфейсу користувача</translation>
@@
-        <source>&lt;b&gt;Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme&lt;/b&gt;&lt;br /&gt;Mumble will pick up themes from certain directories and display them in this list. The one you select will be used to customize the visual appearance of Mumble. This includes colors, icons and more.</source>
-        <translation type="unfinished"></translation>
+        <source>&lt;b&gt;Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme&lt;/b&gt;&lt;br /&gt;Mumble will pick up themes from certain directories and display them in this list. The one you select will be used to customize the visual appearance of Mumble. This includes colors, icons and more.</source>
+        <translation>&lt;b&gt;Визначає, якою темною темою оформлювати інтерфейс Mumble&lt;/b&gt;&lt;br /&gt;Mumble знаходить теми у певних каталогах і показує їх у цьому списку. Обрана тема застосовується до зовнішнього вигляду програми (кольори, піктограми тощо).</translation>
@@
-        <source>Light theme to use to style the user interface</source>
-        <translation type="unfinished"></translation>
+        <source>Light theme to use to style the user interface</source>
+        <translation>Світла тема для оформлення інтерфейсу користувача</translation>
@@
-        <source>Dark Theme</source>
-        <translation type="unfinished"></translation>
+        <source>Dark Theme</source>
+        <translation>Темна тема</translation>
@@
-        <source>Sets the theme automatically based on the system theme.</source>
-        <translation type="unfinished"></translation>
+        <source>Sets the theme automatically based on the system theme.</source>
+        <translation>Автоматично встановлює тему на основі системної теми.</translation>
@@
-        <source>Automatic theme based on system theme</source>
-        <translation type="unfinished"></translation>
+        <source>Automatic theme based on system theme</source>
+        <translation>Автоматичне визначення теми за системною</translation>
@@
-        <source>Auto</source>
-        <translation type="unfinished"></translation>
+        <source>Auto</source>
+        <translation>Авто</translation>
@@
-        <source>Sets the theme to the configured dark theme setting</source>
-        <translation type="unfinished"></translation>
+        <source>Sets the theme to the configured dark theme setting</source>
+        <translation>Перемикає на налаштовану темну тему</translation>
@@
-        <source>Dark</source>
-        <translation type="unfinished"></translation>
+        <source>Dark</source>
+        <translation>Темна</translation>
@@
-        <source>Sets the theme to the configured light theme setting</source>
-        <translation type="unfinished"></translation>
+        <source>Sets the theme to the configured light theme setting</source>
+        <translation>Перемикає на налаштовану світлу тему</translation>
@@
-        <source>Light Theme</source>
-        <translation type="unfinished"></translation>
+        <source>Light Theme</source>
+        <translation>Світла тема</translation>
@@
-        <source>Light</source>
-        <translation type="unfinished"></translation>
+        <source>Light</source>
+        <translation>Світла</translation>
@@
-        <source>Open the themes directory in the systems file manager</source>
-        <translation type="unfinished"></translation>
+        <source>Open the themes directory in the systems file manager</source>
+        <translation>Відкрити каталог тем у файловому менеджері системи</translation>
@@
-        <source>Open Themes Directory</source>
-        <translation type="unfinished"></translation>
+        <source>Open Themes Directory</source>
+        <translation>Відкрити каталог тем</translation>
src/mumble/mumble_ca.ts (7)

1639-1658: Translate new attenuation strings (AudioOutput: listener attenuation controls)

Untranslated labels impact UX. Proposed translations:

  • “at” → “a”
  • “while someone in your channel talks” → “mentre algú del vostre canal parla”
  • “always” → “sempre”
  • “Attenuate listeners by...” → “Atenua els oients en...”
-        <source>at</source>
-        <translation type="unfinished"></translation>
+        <source>at</source>
+        <translation>a</translation>

-        <source>while someone in your channel talks</source>
-        <translation type="unfinished"></translation>
+        <source>while someone in your channel talks</source>
+        <translation>mentre algú del vostre canal parla</translation>

-        <source>always</source>
-        <translation type="unfinished"></translation>
+        <source>always</source>
+        <translation>sempre</translation>

-        <source>Attenuate listeners by...</source>
-        <translation type="unfinished"></translation>
+        <source>Attenuate listeners by...</source>
+        <translation>Atenua els oients en...</translation>

5063-5093: Complete LookConfig color/theme translations

These are visible UI controls; finish them and keep terminology consistent with earlier “Talking UI” = “Interfície de la parla”.

-        <source>Clears the TalkingUI background setting.</source>
-        <translation type="unfinished"></translation>
+        <source>Clears the TalkingUI background setting.</source>
+        <translation>Esborra la configuració del fons de la Interfície de la parla.</translation>

-        <source>Clear Background Color</source>
-        <translation type="unfinished"></translation>
+        <source>Clear Background Color</source>
+        <translation>Esborra el color de fons</translation>

-        <source>Clear</source>
-        <translation type="unfinished"></translation>
+        <source>Clear</source>
+        <translation>Neteja</translation>

-        <source>Color that gets used for the background of the talkingUI.</source>
-        <translation type="unfinished"></translation>
+        <source>Color that gets used for the background of the talkingUI.</source>
+        <translation>Color utilitzat per al fons de la Interfície de la parla.</translation>

-        <source>Choose</source>
-        <translation type="unfinished"></translation>
+        <source>Choose</source>
+        <translation>Tria</translation>

-        <source>Background color that, if set, overrides the theme background color.</source>
-        <translation type="unfinished"></translation>
+        <source>Background color that, if set, overrides the theme background color.</source>
+        <translation>Color de fons que, si s’estableix, sobreescriu el color de fons del tema.</translation>

-        <source>Background Color</source>
-        <translation type="unfinished"></translation>
+        <source>Background Color</source>
+        <translation>Color de fons</translation>

-        <source>Choose a Color</source>
-        <translation type="unfinished"></translation>
+        <source>Choose a Color</source>
+        <translation>Trieu un color</translation>

-        <source>Dark theme to use to style the user interface</source>
-        <translation type="unfinished"></translation>
+        <source>Dark theme to use to style the user interface</source>
+        <translation>Tema fosc per estilitzar la interfície d’usuari</translation>

-        <source>&lt;b&gt;Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme&lt;/b&gt;...
-        <translation type="unfinished"></translation>
+        <source>&lt;b&gt;Configures which theme the Mumble user interface should be styled with when it’s in the Dark theme&lt;/b&gt;...
+        <translation>&lt;b&gt;Configura amb quin tema s’ha d’estilitzar la interfície d’usuari del Mumble quan s’utilitza el tema fosc&lt;/b&gt;...</translation>

-        <source>Light theme to use to style the user interface</source>
-        <translation type="unfinished"></translation>
+        <source>Light theme to use to style the user interface</source>
+        <translation>Tema clar per estilitzar la interfície d’usuari</translation>

-        <source>Dark Theme</source>
-        <translation type="unfinished"></translation>
+        <source>Dark Theme</source>
+        <translation>Tema fosc</translation>

-        <source>Sets the theme automatically based on the system theme.</source>
-        <translation type="unfinished"></translation>
+        <source>Sets the theme automatically based on the system theme.</source>
+        <translation>Estableix el tema automàticament segons el tema del sistema.</translation>

-        <source>Automatic theme based on system theme</source>
-        <translation type="unfinished"></translation>
+        <source>Automatic theme based on system theme</source>
+        <translation>Tema automàtic segons el tema del sistema</translation>

-        <source>Auto</source>
-        <translation type="unfinished"></translation>
+        <source>Auto</source>
+        <translation>Automàtic</translation>

-        <source>Sets the theme to the configured dark theme setting</source>
-        <translation type="unfinished"></translation>
+        <source>Sets the theme to the configured dark theme setting</source>
+        <translation>Estableix el tema al tema fosc configurat</translation>

-        <source>Dark</source>
-        <translation type="unfinished"></translation>
+        <source>Dark</source>
+        <translation>Fosc</translation>

-        <source>Sets the theme to the configured light theme setting</source>
-        <translation type="unfinished"></translation>
+        <source>Sets the theme to the configured light theme setting</source>
+        <translation>Estableix el tema al tema clar configurat</translation>

-        <source>Light Theme</source>
-        <translation type="unfinished"></translation>
+        <source>Light Theme</source>
+        <translation>Tema clar</translation>

-        <source>Light</source>
-        <translation type="unfinished"></translation>
+        <source>Light</source>
+        <translation>Clar</translation>

-        <source>Open the themes directory in the systems file manager</source>
-        <translation type="unfinished"></translation>
+        <source>Open the themes directory in the systems file manager</source>
+        <translation>Obre la carpeta de temes al gestor de fitxers del sistema</translation>

-        <source>Open Themes Directory</source>
-        <translation type="unfinished"></translation>
+        <source>Open Themes Directory</source>
+        <translation>Obre la carpeta de temes</translation>

7166-7185: Translate “Move back” action and keep accelerator

Add Catalan with an accelerator. Proposal uses “&Torna enrere”.

-        <source>M&amp;ove back</source>
-        <translation type="unfinished"></translation>
+        <source>M&amp;ove back</source>
+        <translation>&amp;Torna enrere</translation>

-        <source>Moves you back to the previous channel</source>
-        <translation type="unfinished"></translation>
+        <source>Moves you back to the previous channel</source>
+        <translation>Us torna al canal anterior</translation>

-        <source>Move back</source>
-        <comment>Global shortcut</comment>
-        <translation type="unfinished"></translation>
+        <source>Move back</source>
+        <comment>Global shortcut</comment>
+        <translation>Torna enrere</translation>

-        <source>This will move you back into your previous channel</source>
-        <translation type="unfinished"></translation>
+        <source>This will move you back into your previous channel</source>
+        <translation>Això us retornarà al vostre canal anterior</translation>

-        <source>The channel you have been in previously no longer exists on this server.</source>
-        <translation type="unfinished"></translation>
+        <source>The channel you have been in previously no longer exists on this server.</source>
+        <translation>El canal en què éreu anteriorment ja no existeix en aquest servidor.</translation>

7187-7212: Translate listener attenuation hotkeys

Add concise, consistent phrases.

-        <source>Cycle listener attenuation mode</source>
-        <comment>Global shortcut</comment>
-        <translation type="unfinished"></translation>
+        <source>Cycle listener attenuation mode</source>
+        <comment>Global shortcut</comment>
+        <translation>Canvia el mode d’atenuació dels oients</translation>

-        <source>This will cycle through the different attenuation modes for channel listeners</source>
-        <translation type="unfinished"></translation>
+        <source>This will cycle through the different attenuation modes for channel listeners</source>
+        <translation>Això recorrerà els diferents modes d’atenuació per als oients del canal</translation>

-        <source>Listener attenuation up (+10%)</source>
-        <comment>Global shortcut</comment>
-        <translation type="unfinished"></translation>
+        <source>Listener attenuation up (+10%)</source>
+        <comment>Global shortcut</comment>
+        <translation>Atenuació dels oients amunt (+10%)</translation>

-        <source>This increases the attenuation of channel listeners by 10 percents points</source>
-        <translation type="unfinished"></translation>
+        <source>This increases the attenuation of channel listeners by 10 percents points</source>
+        <translation>Això augmenta l’atenuació dels oients del canal en 10 punts percentuals</translation>

-        <source>Listener attenuation down (-10%)</source>
-        <comment>Global shortcut</comment>
-        <translation type="unfinished"></translation>
+        <source>Listener attenuation down (-10%)</source>
+        <comment>Global shortcut</comment>
+        <translation>Atenuació dels oients avall (-10%)</translation>

-        <source>This decreases the attenuation of channel listeners by 10 percents points</source>
-        <translation type="unfinished"></translation>
+        <source>This decreases the attenuation of channel listeners by 10 percents points</source>
+        <translation>Això redueix l’atenuació dels oients del canal en 10 punts percentuals</translation>

7282-7290: Translate “Adaptive Push” shortcut

-        <source>Adaptive Push</source>
-        <comment>Global Shortcut</comment>
-        <translation type="unfinished"></translation>
+        <source>Adaptive Push</source>
+        <comment>Global Shortcut</comment>
+        <translation>Pulsació adaptativa</translation>

-        <source>When using the push-to-talk transmission mode, this will act as the push-to-talk action. Otherwise, it will act as a push-to-mute action.</source>
-        <comment>Global Shortcut</comment>
-        <translation type="unfinished"></translation>
+        <source>When using the push-to-talk transmission mode, this will act as the push-to-talk action. Otherwise, it will act as a push-to-mute action.</source>
+        <comment>Global Shortcut</comment>
+        <translation>Quan utilitzeu el mode Prémer per parlar, actuarà com a acció de Prémer per parlar. En cas contrari, actuarà com a acció de Prémer per silenciar.</translation>

7292-7302: Translate image error messages

-        <source>Open Image</source>
-        <translation type="unfinished"></translation>
+        <source>Open Image</source>
+        <translation>Obre la imatge</translation>

-        <source>Error</source>
-        <translation type="unfinished"></translation>
+        <source>Error</source>
+        <translation>Error</translation>

-        <source>Failed to decode image.</source>
-        <translation type="unfinished"></translation>
+        <source>Failed to decode image.</source>
+        <translation>No s’ha pogut descodificar la imatge.</translation>

9619-9654: Translate UserInformation rolling-average stats

-        <source>to client rolling average</source>
-        <translation type="unfinished"></translation>
+        <source>to client rolling average</source>
+        <translation>mitjana mòbil cap al client</translation>

-        <source>Last X minutes:</source>
-        <translation type="unfinished"></translation>
+        <source>Last X minutes:</source>
+        <translation>Darrers X minuts:</translation>

-        <source>% lost</source>
-        <translation type="unfinished"></translation>
+        <source>% lost</source>
+        <translation>% perdut</translation>

-        <source>from client rolling average</source>
-        <translation type="unfinished"></translation>
+        <source>from client rolling average</source>
+        <translation>mitjana mòbil des del client</translation>

-        <source>% late</source>
-        <translation type="unfinished"></translation>
+        <source>% late</source>
+        <translation>% tard</translation>

-        <source>Total:</source>
-        <translation type="unfinished"></translation>
+        <source>Total:</source>
+        <translation>Total:</translation>

-        <source>Last %1 %2:</source>
-        <translation type="unfinished"></translation>
+        <source>Last %1 %2:</source>
+        <translation>Darrers %1 %2:</translation>

-        <source>minutes</source>
-        <translation type="unfinished"></translation>
+        <source>minutes</source>
+        <translation>minuts</translation>
src/murmur/Server.cpp (1)

2818-2839: In-memory user comment is not updated; also remove ineffective std::move on const

setComment updates qbaCommentHash and persists to DB but never updates the ServerUser’s in-memory comment, causing stale state until a reload. Also, std::move(comment) on a const QString is a no-op and obscures intent.

Apply both fixes:

 bool Server::setComment(ServerUser &user, const QString &comment) {
-    hashAssign(user.qbaCommentHash, comment);
+    user.setComment(hashAssign(user.qbaCommentHash, comment));
 
     if (user.iId <= 0) {
         return false;
     }
 
     QMap< int, QString > info;
-    info.insert(static_cast< int >(::mumble::server::db::UserProperty::Comment), std::move(comment));
+    info.insert(static_cast< int >(::mumble::server::db::UserProperty::Comment), comment);

This keeps the in-memory object consistent with what we store/emit.

src/mumble/mumble_es.ts (1)

7293-7307: Localize new image-dialog strings.

These are user-visible errors and actions; translate and drop unfinished flags.

Apply this diff:

-        <source>Open Image</source>
-        <translation type="unfinished"></translation>
+        <source>Open Image</source>
+        <translation>Abrir imagen</translation>

-        <source>Error</source>
-        <translation type="unfinished"></translation>
+        <source>Error</source>
+        <translation>Error</translation>

-        <source>Failed to decode image.</source>
-        <translation type="unfinished"></translation>
+        <source>Failed to decode image.</source>
+        <translation>No se pudo decodificar la imagen.</translation>

-        <source>Comment</source>
-        <translation type="unfinished"></translation>
+        <source>Comment</source>
+        <translation>Comentario</translation>

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review continued from previous batch...

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review continued from previous batch...

Comment on lines +81 to 86
if (!user->qsComment().isEmpty()) {
if (user->qsComment().length() <= 20) {
description += QString("%1,").arg(user->qsComment());
} else {
description += QString("%1,").arg(QObject::tr("has a long comment"));
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Strip HTML from comments before exposing to assistive tech

Comments may contain HTML. Feeding markup into screen readers degrades accessibility. Use the existing removeHTMLTags() helper and avoid repeated accessor calls.

-		if (!user->qsComment().isEmpty()) {
-			if (user->qsComment().length() <= 20) {
-				description += QString("%1,").arg(user->qsComment());
+		const QString comment = removeHTMLTags(user->qsComment());
+		if (!comment.isEmpty()) {
+			if (comment.length() <= 20) {
+				description += QString("%1,").arg(comment);
 			} else {
 				description += QString("%1,").arg(QObject::tr("has a long comment"));
 			}
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!user->qsComment().isEmpty()) {
if (user->qsComment().length() <= 20) {
description += QString("%1,").arg(user->qsComment());
} else {
description += QString("%1,").arg(QObject::tr("has a long comment"));
}
const QString comment = removeHTMLTags(user->qsComment());
if (!comment.isEmpty()) {
if (comment.length() <= 20) {
description += QString("%1,").arg(comment);
} else {
description += QString("%1,").arg(QObject::tr("has a long comment"));
}
}
🤖 Prompt for AI Agents
In src/mumble/Accessibility.cpp around lines 81-86, the code appends
user->qsComment() directly (and calls the accessor multiple times) which may
contain HTML and thus should be sanitized and not re-accessed repeatedly; fetch
user->qsComment() into a local QString, call removeHTMLTags() on it, use the
stripped string for the length check and for appending to description (or fall
back to QObject::tr("has a long comment") when the stripped length > 20), and
ensure you append the sanitized value followed by the comma.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review continued from previous batch...

Comment on lines +15 to +25
void ImageWidget::resizeEvent(QResizeEvent *event) {
const QPixmap scaled = m_pix.scaled(
sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumWidth() : event->size().width(),
sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumHeight() : event->size().width(),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
setPixmap(scaled);

m_sizeHint = scaled.size();

QLabel::resizeEvent(event);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Fix axis mix-up and guard against null pixmaps in resizeEvent (prevents wrong scaling and Qt warnings).

  • Height uses event->size().width() and checks the horizontal policy for both axes. This distorts aspect ratio and ignores actual height.
  • When m_pix is null, QPixmap::scaled warns and does nothing useful.
  • Using only maximumWidth/Height for the target size can create huge pixmaps if those maxima aren’t set (default is very large). Clamp to the current size as well.

Apply:

 void ImageWidget::resizeEvent(QResizeEvent *event) {
-    const QPixmap scaled = m_pix.scaled(
-        sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumWidth() : event->size().width(),
-        sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumHeight() : event->size().width(),
-        Qt::KeepAspectRatio, Qt::SmoothTransformation);
-    setPixmap(scaled);
-
-    m_sizeHint = scaled.size();
+    if (m_pix.isNull()) {
+        QLabel::resizeEvent(event);
+        return;
+    }
+    const int targetW = qMin(event->size().width(),  maximumWidth());
+    const int targetH = qMin(event->size().height(), maximumHeight());
+    const QPixmap scaled =
+        m_pix.scaled(targetW, targetH, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+    setPixmap(scaled);
+    m_sizeHint = scaled.size();
 
     QLabel::resizeEvent(event);
 }

This clamps by the widget’s current size and respects its maxima, avoiding the oversized avatar issue reported in the PR discussion while preserving aspect ratio.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void ImageWidget::resizeEvent(QResizeEvent *event) {
const QPixmap scaled = m_pix.scaled(
sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumWidth() : event->size().width(),
sizePolicy().horizontalPolicy() == QSizePolicy::Preferred ? maximumHeight() : event->size().width(),
Qt::KeepAspectRatio, Qt::SmoothTransformation);
setPixmap(scaled);
m_sizeHint = scaled.size();
QLabel::resizeEvent(event);
}
void ImageWidget::resizeEvent(QResizeEvent *event) {
// If there's no pixmap to scale, just propagate the event.
if (m_pix.isNull()) {
QLabel::resizeEvent(event);
return;
}
// Clamp target dimensions to the widget's current size and its maxima.
const int targetW = qMin(event->size().width(), maximumWidth());
const int targetH = qMin(event->size().height(), maximumHeight());
// Scale the pixmap correctly (respecting aspect ratio, smooth transformation).
const QPixmap scaled =
m_pix.scaled(targetW, targetH, Qt::KeepAspectRatio, Qt::SmoothTransformation);
setPixmap(scaled);
m_sizeHint = scaled.size();
QLabel::resizeEvent(event);
}
🤖 Prompt for AI Agents
In src/mumble/widgets/ImageWidget.cpp around lines 15-25, the resizeEvent mixes
axes, doesn't guard null pixmaps, and can scale to enormous sizes; fix by
returning early if m_pix.isNull(), compute targetWidth as qMin(maximumWidth(),
event->size().width()) and targetHeight as qMin(maximumHeight(),
event->size().height()) (use horizontalPolicy for width and verticalPolicy for
height where needed), call m_pix.scaled(QSize(targetWidth, targetHeight),
Qt::KeepAspectRatio, Qt::SmoothTransformation), set m_sizeHint from the
resulting pixmap, and then call QLabel::resizeEvent(event); ensure you clamp to
the widget's current/event size and maxima to avoid oversized pixmaps.

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

Labels

client feature-request This issue or PR deals with a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments