Files
leocad/qt/lc_qutils.h
T
Leonardo Zide 688859b120 Localize numeric displays and HTML export labels
Format UI measurements, snap angles, ladder increments, edge-color values, Preferences labels, counts, and step/page labels using the widget locale without grouping. Preserve numeric table sorting with stored count values and trim localized zero digits correctly. Give float/double formatting and float parsing explicit helper names.

Mark HTML export titles, navigation, alternate text, and credits for translation, escape translated text, and declare UTF-8 output. Keep numbers in HTML, piece-list images, and print/PDF output in ASCII. Include the pending command-status translation drafts in all eight language catalogs, preserving their unfinished review status.

Validation: macOS Qt debug build, display and count-sorting checks across ten locales, all three HTML layouts with test translations under an Arabic numeric locale, and ASCII print/image checks. All eight catalogs pass XML, changed-placeholder, and lrelease validation.
2026-10-23 14:17:52 -07:00

210 lines
4.6 KiB
C++

#pragma once
#include <QObject>
class QLocale;
class lcPartSelectionWidget;
class lcPartSelectionListView;
struct lcTrainTrackConnectionType;
constexpr int LC_MAX_IMAGE_DIMENSION = 32768;
constexpr int LC_MAX_GRID_LINE_SPACING = 10000;
constexpr int LC_MAX_AREA_LIGHT_GRID = 64;
QString lcFormatValue(float Value, int Precision);
QString lcFormatFloatLocalized(float Value, QLocale Locale);
QString lcFormatDoubleLocalized(double Value, QLocale Locale, char Format, int Precision);
QString lcFormatIntegerLocalized(qlonglong Value, QLocale Locale);
std::optional<float> lcParseFloatLocalized(const QString& Value, QLocale Locale);
void lcSetupDialogHelp(QDialog* Dialog, QDialogButtonBox* ButtonBox);
void lcSetupWidgetHelp(QWidget* Root, QDialogButtonBox* ButtonBox);
#ifdef Q_OS_WIN
#include <windows.h>
int lcTerminateChildProcess(QWidget* Parent, const qint64 Pid, const qint64 Ppid);
bool lcRunElevatedProcess(const LPCWSTR ExeName, const LPCWSTR Arguments, const LPCWSTR WorkingFolder);
#endif
class lcTreeWidgetColumnStretcher : public QObject
{
Q_OBJECT
public:
lcTreeWidgetColumnStretcher(QTreeWidget* TreeWidget, int ColumnToStretch);
bool eventFilter(QObject* Object, QEvent* Event) override;
private slots:
void SectionResized(int LogicalIndex, int OldSize, int NewSize);
private:
const int mColumnToStretch;
bool mInteractiveResize;
int mStretchWidth;
};
class lcSmallLineEdit : public QLineEdit
{
Q_OBJECT
public:
QSize sizeHint() const override
{
QFontMetrics FontMetrics(font());
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
const int Width = FontMetrics.horizontalAdvance(QLatin1Char('x')) * 10;
#else
const int Width = FontMetrics.width(QLatin1Char('x')) * 10;
#endif
return QLineEdit::sizeHint() - QSize(Width, 0);
}
};
class lcTransformLineEdit : public lcSmallLineEdit
{
Q_OBJECT
protected:
bool event(QEvent* Event) override
{
if (Event->type() == QEvent::ShortcutOverride)
{
const QKeyEvent* KeyEvent = (QKeyEvent*)Event;
const int Key = KeyEvent->key();
if (KeyEvent->modifiers() == Qt::NoModifier && Key >= Qt::Key_A && Key <= Qt::Key_Z)
Event->accept();
switch (Key)
{
case Qt::Key_Down:
case Qt::Key_Up:
case Qt::Key_Left:
case Qt::Key_Right:
case Qt::Key_Home:
case Qt::Key_End:
case Qt::Key_PageUp:
case Qt::Key_PageDown:
case Qt::Key_Plus:
case Qt::Key_Minus:
case Qt::Key_Enter:
Event->accept();
break;
}
}
return QLineEdit::event(Event);
}
};
class lcStepValidator : public QIntValidator
{
Q_OBJECT
public:
lcStepValidator(lcStep Min, lcStep Max, bool AllowEmpty, QObject* Parent)
: QIntValidator(1, INT_MAX, Parent), mMin(Min), mMax(Max), mAllowEmpty(AllowEmpty)
{
}
QValidator::State validate(QString& Input, int& Pos) const override
{
if (mAllowEmpty && Input.isEmpty())
return Acceptable;
bool Ok;
lcStep Step = locale().toUInt(Input, &Ok);
if (Ok)
return (Step >= mMin && Step <= mMax) ? Acceptable : Invalid;
return QIntValidator::validate(Input, Pos);
}
protected:
lcStep mMin;
lcStep mMax;
bool mAllowEmpty;
};
class lcElidableToolButton : public QToolButton
{
Q_OBJECT
public:
lcElidableToolButton(QWidget* Parent)
: QToolButton(Parent)
{
}
QSize sizeHint() const override
{
QSize Size = QToolButton::sizeHint();
Size.setWidth(0);
return Size;
}
protected:
void paintEvent(QPaintEvent*) override
{
QStylePainter Painter(this);
QStyleOptionToolButton Option;
initStyleOption(&Option);
QRect Button = style()->subControlRect(QStyle::CC_ToolButton, &Option, QStyle::SC_ToolButton, this);
int Frame = style()->proxy()->pixelMetric(QStyle::PixelMetric::PM_DefaultFrameWidth, &Option, this);
Button = Button.adjusted(Frame, Frame, -Frame, -Frame);
QFontMetrics Metrics(font());
QString ElidedText = Metrics.elidedText(text(), Qt::ElideMiddle, Button.width());
Option.text = ElidedText;
Painter.drawComplexControl(QStyle::CC_ToolButton, Option);
}
};
class lcPieceIdStringModel : public QAbstractListModel
{
Q_OBJECT
public:
lcPieceIdStringModel(lcModel* Model, QObject* Parent);
QModelIndex Index(lcPieceData* PieceData) const;
std::vector<bool> GetFilteredRows(const QString& FilterText) const;
int rowCount(const QModelIndex& Parent = QModelIndex()) const override;
QVariant data(const QModelIndex& Index, int Role = Qt::DisplayRole) const override;
protected:
std::vector<lcPieceData*> mSortedPieces;
};
class lcColorDialogPopup : public QWidget
{
Q_OBJECT
public:
lcColorDialogPopup(const QColor& InitialColor, QWidget* Parent);
signals:
void ColorSelected(QColor Color);
protected slots:
void Accept();
void Reject();
protected:
void Close();
QColorDialog* mColorDialog = nullptr;
};