Merge pull request #12 from SamiAhmed7777/hd-on-master

HD wallet: outline HD status letters in TRI brand red (#f26522)
This commit is contained in:
SamiAhmed7777
2026-07-03 01:02:07 -07:00
committed by GitHub
7 changed files with 209 additions and 22 deletions
+46 -16
View File
@@ -26,12 +26,20 @@ jobs:
- name: Check format on changed lines
run: |
BASE_SHA=$(git merge-base origin/${{ github.base_ref }} HEAD)
echo "Comparing against merge-base: $BASE_SHA"
# Diff-only on PRs (have a base_ref). On workflow_dispatch, base_ref is
# empty — in that case run clang-format on the whole tree so a manual
# trigger still produces a useful signal instead of erroring out.
if [ -n "${{ github.base_ref }}" ]; then
BASE_SHA=$(git merge-base "origin/${{ github.base_ref }}" HEAD)
echo "Comparing against merge-base: $BASE_SHA"
# git-clang-format prints a diff if any changed line violates style.
# --diff exits non-zero when reformatting would change something.
OUTPUT=$(git clang-format --diff "$BASE_SHA" -- '*.cpp' '*.h' '*.hpp' '*.cc' || true)
# git-clang-format prints a diff if any changed line violates style.
# --diff exits non-zero when reformatting would change something.
OUTPUT=$(git clang-format --diff "$BASE_SHA" -- '*.cpp' '*.h' '*.hpp' '*.cc' || true)
else
echo "No base_ref (workflow_dispatch) — running clang-format on whole tree"
OUTPUT=$(git clang-format --diff $(git rev-list --max-parents=0 HEAD | head -1) -- '*.cpp' '*.h' '*.hpp' '*.cc' || true)
fi
if [ -z "$OUTPUT" ] || [ "$OUTPUT" = "no modified files to format" ] || [ "$OUTPUT" = "clang-format did not modify any files" ]; then
echo "clang-format: clean"
@@ -83,9 +91,6 @@ jobs:
- name: Run clang-tidy on changed lines
run: |
BASE_SHA=$(git merge-base origin/${{ github.base_ref }} HEAD)
echo "Comparing against merge-base: $BASE_SHA"
# clang-tidy-diff.py ships with clang-tidy; runs tidy only on changed lines.
DIFF_SCRIPT=$(dpkg -L clang-tidy-15 | grep clang-tidy-diff.py | head -1)
if [ -z "$DIFF_SCRIPT" ]; then
@@ -93,17 +98,42 @@ jobs:
fi
echo "Using: $DIFF_SCRIPT"
if [ -n "${{ github.base_ref }}" ]; then
BASE_SHA=$(git merge-base "origin/${{ github.base_ref }}" HEAD)
echo "Comparing against merge-base: $BASE_SHA"
git diff -U0 "$BASE_SHA" -- 'src/*.cpp' 'src/*.h' \
':(exclude)src/json/nlohmann_json.hpp' \
':(exclude)src/leveldb/*' \
':(exclude)src/lz4/*' \
':(exclude)src/tor/tor-src/*' > /tmp/changes.diff
else
echo "No base_ref (workflow_dispatch) — running clang-tidy on whole tree"
git diff -U0 -- $(git rev-list --max-parents=0 HEAD | head -1)..HEAD -- 'src/*.cpp' 'src/*.h' \
':(exclude)src/json/nlohmann_json.hpp' \
':(exclude)src/leveldb/*' \
':(exclude)src/lz4/*' \
':(exclude)src/tor/tor-src/*' > /tmp/changes.diff || true
# If the initial commit was so old that the diff is empty, fall back to HEAD vs HEAD~100
if [ ! -s /tmp/changes.diff ]; then
git diff -U0 HEAD~100..HEAD -- 'src/*.cpp' 'src/*.h' \
':(exclude)src/json/nlohmann_json.hpp' \
':(exclude)src/leveldb/*' \
':(exclude)src/lz4/*' \
':(exclude)src/tor/tor-src/*' > /tmp/changes.diff || true
fi
fi
if [ ! -s /tmp/changes.diff ]; then
echo "No changes to lint in dispatch context — skipping"
exit 0
fi
# -p1 strips the leading "a/"/"b/" from git diff paths.
# -path=build points clang-tidy at compile_commands.json.
# -iregex restricts to project sources (not vendored).
git diff -U0 "$BASE_SHA" -- 'src/*.cpp' 'src/*.h' \
':(exclude)src/json/nlohmann_json.hpp' \
':(exclude)src/leveldb/*' \
':(exclude)src/lz4/*' \
':(exclude)src/tor/tor-src/*' \
| python3 "$DIFF_SCRIPT" -p1 -path build \
-iregex '.*\.(cpp|cc|h|hpp)$' \
-j$(nproc) || EXIT=$?
cat /tmp/changes.diff | python3 "$DIFF_SCRIPT" -p1 -path build \
-iregex '.*\.(cpp|cc|h|hpp)$' \
-j$(nproc) || EXIT=$?
# Warn-only initially. Flip this to `exit ${EXIT:-0}` once we're clean.
exit 0
+1
View File
@@ -450,6 +450,7 @@ if(BUILD_QT)
qt/qvaluecombobox.cpp
qt/askpassphrasedialog.cpp
qt/hdseeddialog.cpp
qt/outlinedlabel.cpp
qt/notificator.cpp
qt/qtipcserver.cpp
qt/rpcconsole.cpp
+18 -1
View File
@@ -1664,7 +1664,7 @@ QProgressBar::chunk {
</widget>
</item>
<item>
<widget class="QLabel" name="label_hd">
<widget class="OutlinedLabel" name="label_hd">
<property name="font">
<font>
<pointsize>9</pointsize>
@@ -1672,6 +1672,16 @@ QProgressBar::chunk {
<bold>true</bold>
</font>
</property>
<property name="outlineColor">
<color>
<red>242</red>
<green>101</green>
<blue>34</blue>
</color>
</property>
<property name="outlineWidth">
<number>3</number>
</property>
<property name="toolTip">
<string>HD (BIP39) wallet seed status</string>
</property>
@@ -1759,6 +1769,13 @@ QProgressBar::chunk {
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>OutlinedLabel</class>
<extends>QLabel</extends>
<header>qt/outlinedlabel.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../triangles.qrc"/>
</resources>
+93
View File
@@ -0,0 +1,93 @@
#include "outlinedlabel.h"
#include <QPainter>
#include <QPainterPath>
#include <QPaintEvent>
#include <QStyleOption>
#include <QTextDocument>
#include <QString>
OutlinedLabel::OutlinedLabel(QWidget* parent)
: QLabel(parent)
, m_outlineColor(QColor("#f26522"))
, m_outlineWidth(3)
{
// OutlinedLabel is always styled; do not let QSS override our paint.
setAttribute(Qt::WA_OpaquePaintEvent, false);
}
void OutlinedLabel::setOutlineColor(const QColor& c)
{
if (m_outlineColor == c) return;
m_outlineColor = c;
update();
}
void OutlinedLabel::setOutlineWidth(int w)
{
if (m_outlineWidth == w) return;
m_outlineWidth = w;
update();
}
void OutlinedLabel::paintEvent(QPaintEvent* e)
{
Q_UNUSED(e);
// Honor any background styling the parent may have given us, but
// do our own text rendering below. We deliberately skip QLabel's
// built-in drawContents/drawText path because it cannot paint a
// per-character outline.
QStyleOption opt;
opt.initFrom(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, nullptr, this);
if (text().isEmpty()) return;
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setRenderHint(QPainter::TextAntialiasing, true);
const QFontMetricsF fm(font());
const QString t = text();
// Bounding rect for the text, honoring alignment. Add half the
// outline width on each side so strokes don't clip against the
// widget edge.
const qreal pad = m_outlineWidth / 2.0;
QRectF r = rect().adjusted(pad, pad, -pad, -pad);
// Center vertically based on font metrics
const qreal yOffset = (r.height() - fm.height()) / 2.0;
QPointF baseline(r.left(), r.top() + yOffset + fm.ascent());
// Align: use only the horizontal part of the alignment flag.
const int align = int(alignment() & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter | Qt::AlignJustify));
const qreal textWidth = fm.horizontalAdvance(t);
qreal x = r.left();
if (align & Qt::AlignHCenter) {
x = r.left() + (r.width() - textWidth) / 2.0;
} else if (align & Qt::AlignRight) {
x = r.right() - textWidth;
}
baseline.setX(x);
QPainterPath path;
path.addText(baseline, font(), t);
// Stroke (outline) — drawn first, in the brand red so each letter
// has a clear 3px red border matching the triangle icons.
QPen outlinePen(m_outlineColor);
outlinePen.setWidth(m_outlineWidth);
outlinePen.setJoinStyle(Qt::RoundJoin);
outlinePen.setCapStyle(Qt::RoundCap);
painter.setPen(outlinePen);
painter.setBrush(Qt::NoBrush);
painter.drawPath(path);
// Fill the interior with the widget background color so the
// letters read as hollow red outlines against the dark wallet
// background, like the triangle icons beside them.
painter.setPen(Qt::NoPen);
painter.setBrush(QBrush(palette().color(backgroundRole())));
painter.drawPath(path);
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef TRIANGLES_QT_OUTLINEDLABEL_H
#define TRIANGLES_QT_OUTLINEDLABEL_H
#include <QLabel>
/**
* QLabel that renders its text with an outline (stroke) in the
* outline color, and a fill in the fill color. Used for the
* "HD" badge in the status bar of the Triangles Qt wallet so
* that each letter is outlined in the same red (#f26522) as
* the triangle icons.
*
* Outline is drawn first (wide red pen), then the fill is drawn
* on top (narrower pen, slightly inset). Both pens use the
* same font/alignment as the parent label.
*/
class OutlinedLabel : public QLabel
{
Q_OBJECT
Q_PROPERTY(QColor outlineColor READ outlineColor WRITE setOutlineColor)
Q_PROPERTY(int outlineWidth READ outlineWidth WRITE setOutlineWidth)
public:
explicit OutlinedLabel(QWidget* parent = nullptr);
QColor outlineColor() const { return m_outlineColor; }
void setOutlineColor(const QColor& c);
int outlineWidth() const { return m_outlineWidth; }
void setOutlineWidth(int w);
protected:
void paintEvent(QPaintEvent* e) override;
private:
QColor m_outlineColor;
int m_outlineWidth;
};
#endif // TRIANGLES_QT_OUTLINEDLABEL_H
+8 -4
View File
@@ -32,6 +32,7 @@
#include "guiconstants.h"
#include "askpassphrasedialog.h"
#include "hdseeddialog.h"
#include "outlinedlabel.h"
#include "notificator.h"
#include "guiutil.h"
#include "rpcconsole.h"
@@ -349,7 +350,6 @@ TrianglesGUI::TrianglesGUI(bool fIsTestnet, QWidget *parent):
labelOnionAddress->setCursor(Qt::PointingHandCursor);
labelOnionAddress->installEventFilter(this);
// I2P address, stacked directly above the .onion address (click to copy)
labelI2PAddress = ui->label_i2p;
labelI2PAddress->setVisible(false);
labelI2PAddress->setCursor(Qt::PointingHandCursor);
@@ -1896,17 +1896,21 @@ void TrianglesGUI::updateHDStatus()
}
if (fHD) {
labelHdIcon->setStyleSheet("color: #f26522; font-weight: bold;");
// Both letters outlined in the brand red, 3px stroke (matches the
// triangles beside it).
labelHdIcon->setOutlineColor(QColor("#f26522"));
labelHdIcon->setOutlineWidth(3);
labelHdIcon->setToolTip(tr("HD wallet: BIP39 seed active. Backup your seed phrase — individual keys alone will not restore this wallet."));
} else {
labelHdIcon->setStyleSheet("color: #555555; font-weight: bold;");
// Greyed-out (dim) badge until the user runs hdnew.
labelHdIcon->setOutlineColor(QColor("#555555"));
labelHdIcon->setOutlineWidth(3);
labelHdIcon->setToolTip(tr("Non-HD wallet: backup each address key separately. Use hdnew to upgrade to an HD seed."));
}
labelHdIcon->setText(QStringLiteral("HD"));
labelHdIcon->setVisible(true);
}
void TrianglesGUI::on_bHelp_clicked()
{
ensureRPCConsole();
+3 -1
View File
@@ -6,6 +6,8 @@
#include <QMap>
#include <QBitmap>
class OutlinedLabel;
class TransactionTableModel;
class ClientModel;
class WalletModel;
@@ -114,7 +116,7 @@ private:
QLabel *labelV3Icon;
QLabel *labelI2PIcon;
QLabel *labelTorIcon;
QLabel *labelHdIcon;
OutlinedLabel *labelHdIcon;
QLabel *progressBarLabel;
QProgressBar *progressBar;