feat(qt): UI refresh (3/n, update "Masternode" tab layout, status icons, description dialogs, filtering options)#7116
feat(qt): UI refresh (3/n, update "Masternode" tab layout, status icons, description dialogs, filtering options)#7116kwvg wants to merge 12 commits intodashpay:developfrom
Conversation
|
|
This pull request has conflicts, please rebase. |
…ernance" and "Masternode" tabs, split out proposal model, additional bounds checking, better QTextEdit styling) f9f7c6e refactor: repurpose `transactiondescdialog` as a generic desc. container (Kittywhiskers Van Gogh) 5f4a6c0 refactor: track "Masternodes" tab show/hide in `OptionsModel` (Kittywhiskers Van Gogh) 1994f8c qt: use show/hide for "Masternodes" tab to avoid client restart (Kittywhiskers Van Gogh) 6a7e6b0 refactor: track "Governance" tab show/hide in `OptionsModel` (Kittywhiskers Van Gogh) 64a2db6 qt: use show/hide for "Governance" tab to avoid client restart (Kittywhiskers Van Gogh) 762e5d3 qt: add styling support for QTextEdit `<b>` and `<h{1-3}>` elements (Kittywhiskers Van Gogh) 7a2f09d refactor: drop `QObject` inheritance, precalculate hash string (Kittywhiskers Van Gogh) fdd3193 fix: use `unique_ptr` and more bounds checking in `qt/proposalmodel` (Kittywhiskers Van Gogh) c9e0d94 move-only: split proposal model out to `src/qt/proposalmodel.{cpp,h}` (Kittywhiskers Van Gogh) 42f2345 refactor: add `pruneStaleEntities` helper to deduplicate pruning (Kittywhiskers Van Gogh) 72c4099 refactor: add `getScaledFont` helper, keep `getFont` internal (Kittywhiskers Van Gogh) 6d9b90b chore: enforce alphabetical sorting in `src/Makefile.qt.include` (Kittywhiskers Van Gogh) 83b9271 move-only: move `subFeeFromAmount` into `verticalLayout_2` (Kittywhiskers Van Gogh) bcfc0e3 refactor: improve CoinJoin tab nullptr checks, bail-out condition (Kittywhiskers Van Gogh) 7648792 refactor: drop `emitCoinJoinEnabledChanged()`, use `setOption()` instead (Kittywhiskers Van Gogh) Pull request description: ## Additional Information * Dependency for #7110 * Dependency for #7116 | `develop` (cc50446) | This PR (18d6ce6) | | ----------------------- | ------------------- | |  |  | |  |  | |  |  | ## Breaking Changes None expected. ## Checklist - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)** - [x] I have made corresponding changes to the documentation **(note: N/A)** - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: utACK f9f7c6e Tree-SHA512: 6c219c8bc5b90c52bb030a6f05bcf9168ec51be0d72c23b38b5aba852666419949ebe4ee07c2c8ba70241655a542de24e2e31b6b0241517e183b7bf289373a37
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
WalkthroughRefactors the masternode list UI from a QTableWidget to a Qt Model-View design. Adds MasternodeModel and MasternodeEntry to represent masternode data, a MasternodeListSortFilterProxyModel to handle type/owned/hidden-banned/text filtering, and updates MasternodeList to populate and reconcile the model on timer-driven updates. UI changes include switching to QTableView, adding a type combo box, owned and hide-banned checkboxes, and filter-by-address actions. New MOC/public header entries and CSS color rules are included. Sequence DiagramsequenceDiagram
participant Timer as Timer
participant List as MasternodeList
participant Client as Client Interface
participant Model as MasternodeModel
participant Proxy as MasternodeListSortFilterProxyModel
participant UI as QTableView
Timer->>List: triggerUpdate()
List->>Client: request masternode list (MnList)
Client-->>List: return MnList
List->>List: build MasternodeEntryList (compute next payments)
List->>Model: reconcile(entries)
Model->>Model: diff / update / append / remove entries
Model->>Proxy: emit dataChanged / layoutChanged
Proxy->>Proxy: apply filters (Type, Owned, HideBanned, Text)
Proxy->>UI: update visible rows
UI->>UI: repaint / refresh display
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/qt/masternodelist.cpp (1)
1-6:⚠️ Potential issue | 🟡 MinorCI failure: clang-format differences detected — must be resolved before merge.
The pipeline reports formatting violations in this file. Run
./contrib/devtools/clang-format-diff.py -p1to auto-fix.src/qt/masternodelist.h (1)
1-1:⚠️ Potential issue | 🟡 MinorFix clang-format differences flagged by CI.
The pipeline reports clang-format violations in this file. Run
./contrib/devtools/clang-format-diff.py -p1to resolve them before merging.
🧹 Nitpick comments (7)
src/qt/forms/masternodelist.ui (1)
42-61: Combo box item order is implicitly coupled to theTypeFilterenum.The items (All=0, Regular=1, Evo=2) are cast directly to the enum in
on_comboBoxType_currentIndexChanged. This works because the handler validates the range, but adding or reordering items here without updating the enum would silently break filtering. A brief comment in the.uior the handler noting the coupling would help maintainability.src/qt/masternodemodel.cpp (3)
41-112: Constructor performs JSON round-trip for fields not exposed by theMnEntryinterface.The constructor extracts some fields directly from
MnEntry(lines 42–55) and others by parsing the JSON representation (lines 82–111). This works but means every entry construction callstoJson()+write(2)followed by multiplefind_valuelookups.For ~500+ masternodes this runs on every reconciliation cycle. If the
MnEntryinterface could exposecollateralHash,consecutivePayments,PoSeBanHeight, etc., the JSON serialization/parsing overhead could be eliminated. Worth considering in a follow-up if profiling shows this is a bottleneck.
348-405: Reconcile algorithm is correct — the offset-adjustment logic fordataChangedis subtle but verified.I traced multiple scenarios (interleaved changes/removals) and the index adjustment is correct: the
removedvector holds original pre-removal indices, and subtracting the count of removed indices below each changed index gives the correct post-removal position.One subtlety worth noting: in-place data updates (
m_data[idx] = std::move(entry)on line 363) occur beforebeginRemoveRows/endRemoveRowsfor other rows, and beforedataChangedis emitted (line 392). This is safe because all operations are synchronous on the GUI thread, but a future refactor introducing background processing would break this assumption. A brief inline comment on the signal ordering would help future maintainers.
212-228: Tooltip shows "0 day(s)" for nodes banned/active less than one full day.Integer division
(m_current_height - height) / blocks_per_daytruncates, so anything under ~576 blocks shows "0 day(s)". Consider using a "less than 1 day" message or showing hours for the sub-day case if UX precision matters.src/qt/masternodemodel.h (1)
82-85:toTie()subset is well-chosen for mutable fields — consider a brief comment.The tie includes only fields that change over time (
m_banned, heights, penalty, service, reward). Immutable fields (addresses, hashes) are correctly excluded. A one-line comment explaining this would help reviewers understand the intent.src/qt/masternodelist.cpp (2)
122-125: ExplicitupdateFilteredCount()calls are redundant given the signal connections.
updateFilteredCountis connected torowsInserted,rowsRemoved,modelReset, andlayoutChangedon the proxy.setFilterRegularExpression(line 291) internally callsinvalidateFilter(), which emitslayoutChanged, already triggering the connected slot. The explicit calls inon_filterText_textChanged(line 293),on_comboBoxType_currentIndexChanged(line 305),on_checkBoxOwned_stateChanged(line 319),on_checkBoxHideBanned_stateChanged(line 328), andupdateDIP3List(line 254) are harmless but redundant.Not a bug — just extra
setTextcalls that will be superseded by the signal-driven ones.Also applies to: 284-287, 289-293
308-320: Consider guarding against re-fetching the masternode list when the "Owned" checkbox is re-checked without changes.Each time the checkbox is checked,
clientModel->getMasternodeList()is called and the owned hashes are recomputed. If the user toggles rapidly, this causes repeated (potentially expensive) list fetches. This is bounded by the GUI thread serializing calls, but a dirty flag or timestamp guard could avoid redundant work.
Additional Information
Breaking Changes
None expected.
Checklist