feat(gui): port CGenericClientListCtrl to wxDataViewCtrl (#180, #801) - #850
Merged
Conversation
…, amule-org#801) Last remaining piece of amule-org#801's wxListCtrl -> wxDataViewCtrl migration: the shared base feeding CSourceListCtrl (download sources) and CSharedFilePeersListCtrl (shared-file peers). Unlike every prior port, ClientCtrlItem_Struct survives rather than being deleted: it's not a cache-avoidance wrapper, it's structurally required, since one client (ECID) can be a source/peer of more than one file at once, so row identity has to be the (client, owner, type) tuple. Its dwUpdated/status fields (a 10s-TTL cached wxBitmap*) are dropped, matching the no-cache precedent from the Shared Files and Downloads ports -- DrawStatusBar's ColumnUserAvailable path already shipped fully uncached. Two bar columns, two renderers: - ColumnUserProgress (Sources only): CSourceBarRenderer draws the 5-state chunk bar via the base CMuleBarRenderer, except for A4AF rows, which get a bordered "A4AF: <filename>" text badge instead of a bar entirely -- a real per-row renderer branch, not an overlay. - ColumnUserAvailable (Peers only): the plain base renderer is enough (2-state, no per-row branching). It has no Compare() case, matching pre-port behaviour where it was never sortable, so it's registered without wxDATAVIEW_COL_SORTABLE rather than showing a caret that does nothing. The User Name column is a composite icon-cluster (status/software/ credits/ext-protocol/identified/badguy/encryption badges) plus an optional country flag plus text -- no single-icon AddIconTextColumn() cell can carry that. CClientNameRenderer reuses CMuleBarRenderer's identity-carrying CBarFillSpec/GetItemBarFill() extension point to reach the row's ClientCtrlItem_Struct and replay the whole cluster, the same mechanism CDownloadBarRenderer uses for its CPartFile* overlay -- registered via AddBarColumn() since it isn't a literal bar. GetItemColumnText() still answers the plain username for this column, so type-ahead and the accessible row label (the actual point of amule-org#180) work off real text rather than the pre-port GetTTSText()'s hardcoded "". CompareItemData() replicates the original SortProc's type-precedence pre-check (A4AF sources always sort last, direction-independent, not just per selected column) before dispatching to the per-column comparison. Also: CMuleVirtualDataViewCtrl gains a GetModelRow() helper (wraps the wxDataViewIndexListModel::GetRow() cast); CDownloadListCtrl's two hand-rolled instances of the same cast now use it. muuli_wdr.cpp's two construction sites for these lists drop the legacy wxLC_REPORT|wxSUNKEN_BORDER flags (wxLC_REPORT aliases wxDV_VARIABLE_LINE_HEIGHT), matching every other ported list. Verified: amule and amulegui build clean from a fresh CMake configure (wx 3.3.3); pinned clang-format v18 clean; Tier-1/Tier-2 clang-tidy clean via the local CI replica (wx 3.2.4) -- the only Tier-1 hits are 13 pre-existing, unrelated warnings in unittests/tests/. Grepped for every orphaned pre-port symbol (DrawClientItem, DrawSourceStatusBar, DrawStatusBar, SortProc, dwUpdated/status) and confirmed every external caller (TransferWnd.cpp, SharedFilesWnd.cpp, GuiEvents.cpp, amuleDlg.cpp) still compiles unchanged against the same public API (AddSource/RemoveSource/ShowSources/UpdateItem/SetShowing/ RemoveKnownFile). No translatable strings were added or changed, so po/ catalogs are not regenerated.
LSalami
force-pushed
the
downloads-dataview-port
branch
from
August 7, 2026 21:16
b6b6b4c to
6899edf
Compare
The CGenericClientListCtrl port moved the "A4AF" badge string from GenericClientListCtrl.cpp into SourceListCtrl.cpp (CSourceBarRenderer's A4AF branch), shifting its extraction position in po/amule.pot and every po/*.po. Verified symmetric: each locale loses the msgid at its old #: comment and regains it, translation intact, at the new one -- same pattern as the prior DownloadListCtrl.cpp catalog regeneration. Regenerated via scripts/update-po.sh.
CI's Tier-2 clang-tidy (changed-lines gate) caught two modernize-use-nullptr hits that the local ci-local replica's diff base missed (it was run against a stale fork origin/master before the upstream rebase). Grepped the whole file for the same pattern per this repo's convention and fixed all six real NULL pointer literals/comparisons in GenericClientListCtrl.h/.cpp, not just the two CI pointed at -- left the "NULL" mentions inside string literals and comments alone. Verified: amule builds clean; clang-format v18 clean.
Merged
5 tasks
got3nks
pushed a commit
that referenced
this pull request
Aug 8, 2026
…endored wxGenericListCtrl (#855) Follow-up to #801/#180: with the client-list port done in #850, CCommentDialogLst was the only remaining instantiator of CMuleListCtrl and CMuleVirtualListCtrl had no derivers left. CCommentDialogLst drops to a plain wxListCtrl -- a small read-only modal list that does not warrant the CMuleDataViewCtrl treatment -- with click-to-sort reimplemented by hand. amuleDlg's exit-time SaveListControlSettings() widget walk goes too: it existed because CMuleListCtrl only saved lazily from its destructor, which the tray-Exit path could skip, whereas CMuleDataViewCtrl writes column widths and sort orders eagerly on every resize, sort and show/hide, and SaveGUIPrefs() still flushes on every close path. That leaves CMuleVirtualListCtrl, CMuleListCtrl and the vendored wxGenericListCtrl with no consumers, so all four files are deleted. IsListBackgroundDark() moves to MuleColour.h. CListColumnStore's legacy config-migration path is untouched -- it still reads pre-dataview TableWidths* entries. One known simplification: the comments dialog loses its header sort-arrow glyph, which plain wxListCtrl does not draw. A follow-up restores it via ShowSortIndicator().
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Last remaining piece of #801's
wxListCtrl→wxDataViewCtrlmigration: the shared base feedingCSourceListCtrl(download sources) andCSharedFilePeersListCtrl(shared-file peers).Design notes
Unlike every prior port,
ClientCtrlItem_Structsurvives rather than being deleted: it's not a cache-avoidance wrapper, it's structurally required — one client (ECID) can be a source/peer of more than one file at once, so row identity has to be the(client, owner, type)tuple. ItsdwUpdated/statusfields (a 10s-TTL cachedwxBitmap*) are dropped, matching the no-cache precedent from the Shared Files and Downloads ports —DrawStatusBar'sColumnUserAvailablepath already shipped fully uncached.Two bar columns, two renderers:
ColumnUserProgress(Sources only):CSourceBarRendererdraws the 5-state chunk bar via the baseCMuleBarRenderer, except for A4AF rows, which get a bordered "A4AF: <filename>" text badge instead of a bar entirely — a real per-row renderer branch, not an overlay.ColumnUserAvailable(Peers only): the plain base renderer is enough (2-state, no per-row branching). It has noCompare()case, matching pre-port behaviour where it was never sortable, so it's registered withoutwxDATAVIEW_COL_SORTABLErather than showing a caret that does nothing.The User Name column is a composite icon-cluster (status/software/credits/ext-protocol/identified/badguy/encryption badges) plus an optional country flag plus text — no single-icon
AddIconTextColumn()cell can carry that.CClientNameRendererreusesCMuleBarRenderer's identity-carryingCBarFillSpec/GetItemBarFill()extension point to reach the row'sClientCtrlItem_Structand replay the whole cluster, the same mechanismCDownloadBarRendereruses for itsCPartFile*overlay — registered viaAddBarColumn()since it isn't a literal bar.GetItemColumnText()still answers the plain username for this column, so type-ahead and the accessible row label (the actual point of #180) work off real text rather than the pre-portGetTTSText()'s hardcoded"".CompareItemData()replicates the originalSortProc's type-precedence pre-check (A4AF sources always sort last, direction-independent, not just per selected column) before dispatching to the per-column comparison.Also:
CMuleVirtualDataViewCtrlgains aGetModelRow()helper (wraps thewxDataViewIndexListModel::GetRow()cast);CDownloadListCtrl's two hand-rolled instances of the same cast now use it.muuli_wdr.cpp's two construction sites for these lists drop the legacywxLC_REPORT|wxSUNKEN_BORDERflags (wxLC_REPORTaliaseswxDV_VARIABLE_LINE_HEIGHT), matching every other ported list.Verification
amuleandamuleguibuild clean from a fresh CMake configure (wx 3.3.3)unittests/tests/DrawClientItem,DrawSourceStatusBar,DrawStatusBar,SortProc,dwUpdated/status) and confirmed every external caller (TransferWnd.cpp,SharedFilesWnd.cpp,GuiEvents.cpp,amuleDlg.cpp) still compiles unchanged against the same public API (AddSource/RemoveSource/ShowSources/UpdateItem/SetShowing/RemoveKnownFile)No translatable strings were added or changed, so po/ catalogs are not regenerated.