2026年5月23日暂存
This commit is contained in:
+17
-3
@@ -87,7 +87,16 @@ BarcodeEditor::~BarcodeEditor()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void BarcodeEditor::bindViewModel(const BarcodeViewModel& vm)
|
||||
void BarcodeEditor::bindSysPara(SysPara *sysPara)
|
||||
{
|
||||
if (!sysPara) {
|
||||
qWarning() << "BarcodeEditor::bindSysPara: null pointer passed, ignored";
|
||||
return;
|
||||
}
|
||||
m_sysPara = sysPara;
|
||||
}
|
||||
|
||||
void BarcodeEditor::bindViewModel(const BarcodeViewModel &vm)
|
||||
{
|
||||
m_vm = vm;
|
||||
|
||||
@@ -221,7 +230,7 @@ BarcodeViewModel BarcodeEditor::viewModel()
|
||||
|
||||
void BarcodeEditor::restoreViewModel()
|
||||
{
|
||||
m_vm.generalSettingsVM = ItemGeneralSettingsVM();
|
||||
m_vm.generalSettingsVM = TextItemModel();
|
||||
m_vm.contentPattern = "";
|
||||
m_vm.counterViewModel = CounterViewModel();
|
||||
m_vm.dateViewModel = DateItemModel::createDefaultReplaceModel();
|
||||
@@ -238,7 +247,12 @@ void BarcodeEditor::applyCounterConfigToSysPara()
|
||||
{
|
||||
if(!m_vm.contentPattern.contains("{c}"))
|
||||
return;
|
||||
|
||||
|
||||
if (!m_sysPara) {
|
||||
qWarning() << "BarcodeEditor::applyCounterConfigToSysPara: m_sysPara is null, skipping";
|
||||
return;
|
||||
}
|
||||
|
||||
CounterEditorVM cnt = m_counterEditor->viewModel();
|
||||
if(cnt.counterType == COUNTER_TYPE_1) {
|
||||
m_sysPara->para.cnt1StartValue = cnt.counter1.startValue;
|
||||
|
||||
@@ -26,7 +26,7 @@ enum BarcodeType {
|
||||
* 仅当 contentPattern 含有相应变量时,counterViewModel / dateViewModel 字段才有意义。
|
||||
*/
|
||||
struct BarcodeViewModel {
|
||||
ItemGeneralSettingsVM generalSettingsVM; // 通用设置视图模型
|
||||
TextItemModel generalSettingsVM; // 通用设置视图模型
|
||||
QString contentPattern; // 条形码内容模版,例如 "ABC{t}{c1}"
|
||||
CounterViewModel counterViewModel; // 计数器视图模型
|
||||
DateItemModel dateViewModel; // 日期视图模型
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
*
|
||||
* @param sysPara
|
||||
*/
|
||||
void bindSysPara(SysPara* sysPara) { m_sysPara = sysPara; }
|
||||
void bindSysPara(SysPara* sysPara);
|
||||
|
||||
/**
|
||||
* @brief 注入条形码视图模型(纯结构体,按值拷贝)
|
||||
|
||||
+16
-16
@@ -126,7 +126,7 @@ QSpinBox::down-arrow {
|
||||
<widget class="QSpinBox" name="BarCodeScale">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>300</x>
|
||||
<x>280</x>
|
||||
<y>150</y>
|
||||
<width>60</width>
|
||||
<height>31</height>
|
||||
@@ -173,9 +173,9 @@ QSpinBox::down-arrow {
|
||||
<widget class="QComboBox" name="BarCodeDot">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>190</x>
|
||||
<y>150</y>
|
||||
<width>71</width>
|
||||
<x>70</x>
|
||||
<y>230</y>
|
||||
<width>111</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -213,10 +213,10 @@ QSpinBox::down-arrow {
|
||||
<widget class="QCheckBox" name="checkBoxAddText">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>240</y>
|
||||
<width>83</width>
|
||||
<height>16</height>
|
||||
<x>280</x>
|
||||
<y>230</y>
|
||||
<width>150</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -240,7 +240,7 @@ QSpinBox::down-arrow {
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>150</y>
|
||||
<width>71</width>
|
||||
<width>111</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -248,9 +248,9 @@ QSpinBox::down-arrow {
|
||||
<widget class="QComboBox" name="comboBoxInkColor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>300</x>
|
||||
<x>280</x>
|
||||
<y>70</y>
|
||||
<width>81</width>
|
||||
<width>111</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -271,8 +271,8 @@ QSpinBox::down-arrow {
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>190</x>
|
||||
<y>120</y>
|
||||
<x>70</x>
|
||||
<y>200</y>
|
||||
<width>76</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
@@ -299,7 +299,7 @@ QSpinBox::down-arrow {
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>70</y>
|
||||
<width>140</width>
|
||||
<width>161</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -319,7 +319,7 @@ QSpinBox::down-arrow {
|
||||
<widget class="QLabel" name="lab123">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>300</x>
|
||||
<x>280</x>
|
||||
<y>40</y>
|
||||
<width>76</width>
|
||||
<height>23</height>
|
||||
@@ -335,7 +335,7 @@ QSpinBox::down-arrow {
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>300</x>
|
||||
<x>280</x>
|
||||
<y>120</y>
|
||||
<width>129</width>
|
||||
<height>23</height>
|
||||
|
||||
+39
-9
@@ -6,6 +6,7 @@
|
||||
#include "BarCode/barcode.h"
|
||||
#include <QPainter>
|
||||
#include <cstring>
|
||||
#include <QDebug>
|
||||
|
||||
/**
|
||||
* @brief 将libqrencode的QRcode结构渲染成QImage
|
||||
@@ -308,10 +309,15 @@ static QImage generateBarCodeImage(const QString &content, int barCodeType)
|
||||
return generateBarCodeImage(content, vm);
|
||||
}
|
||||
|
||||
QString generateTxtFromDateItemModel(const DateItemModel &model, const QDateTime &time)
|
||||
QString ItemUtils::generateTxtFromDateItemModel(const DateItemModel &model, const QDateTime &time)
|
||||
{
|
||||
QString result = model.datetimePattern;
|
||||
|
||||
|
||||
if (!time.isValid()) {
|
||||
qWarning() << "generateTxtFromDateItemModel: invalid QDateTime passed";
|
||||
return result;
|
||||
}
|
||||
|
||||
// 应用偏移量
|
||||
QDateTime applyDateTime = time;
|
||||
if(model.monthsOffset != 0) {
|
||||
@@ -341,19 +347,37 @@ QString generateTxtFromDateItemModel(const DateItemModel &model, const QDateTime
|
||||
// 匹配两位数月份 MM
|
||||
i = result.indexOf("MM");
|
||||
if(i != -1) {
|
||||
result.replace(i, 2, model.monthsMap[applyDateTime.date().month() - 1]);
|
||||
int monthIdx = applyDateTime.date().month() - 1;
|
||||
if (monthIdx >= 0 && monthIdx < model.monthsMap.size()) {
|
||||
result.replace(i, 2, model.monthsMap[monthIdx]);
|
||||
} else {
|
||||
qWarning() << "generateTxtFromDateItemModel: monthsMap index out of range:" << monthIdx;
|
||||
result.replace(i, 2, QString::number(applyDateTime.date().month()).rightJustified(2, '0'));
|
||||
}
|
||||
}
|
||||
|
||||
// 匹配两位数日期 dd
|
||||
i = result.indexOf("dd");
|
||||
if(i != -1) {
|
||||
result.replace(i, 2, model.daysMap[applyDateTime.date().day() - 1]);
|
||||
int dayIdx = applyDateTime.date().day() - 1;
|
||||
if (dayIdx >= 0 && dayIdx < model.daysMap.size()) {
|
||||
result.replace(i, 2, model.daysMap[dayIdx]);
|
||||
} else {
|
||||
qWarning() << "generateTxtFromDateItemModel: daysMap index out of range:" << dayIdx;
|
||||
result.replace(i, 2, QString::number(applyDateTime.date().day()).rightJustified(2, '0'));
|
||||
}
|
||||
}
|
||||
|
||||
// 匹配两位数小时 HH
|
||||
i = result.indexOf("HH");
|
||||
if(i != -1) {
|
||||
result.replace(i, 2, model.hoursMap[applyDateTime.time().hour()]);
|
||||
int hourIdx = applyDateTime.time().hour();
|
||||
if (hourIdx >= 0 && hourIdx < model.hoursMap.size()) {
|
||||
result.replace(i, 2, model.hoursMap[hourIdx]);
|
||||
} else {
|
||||
qWarning() << "generateTxtFromDateItemModel: hoursMap index out of range:" << hourIdx;
|
||||
result.replace(i, 2, QString::number(applyDateTime.time().hour()).rightJustified(2, '0'));
|
||||
}
|
||||
}
|
||||
|
||||
// 匹配两位数分钟 mm
|
||||
@@ -373,7 +397,13 @@ QString generateTxtFromDateItemModel(const DateItemModel &model, const QDateTime
|
||||
// 格式化周几 w
|
||||
i = result.indexOf("w");
|
||||
if (i != -1) {
|
||||
result.replace(i, 1, model.weeksMap[applyDateTime.date().dayOfWeek() - 1]);
|
||||
int weekIdx = applyDateTime.date().dayOfWeek() - 1;
|
||||
if (weekIdx >= 0 && weekIdx < model.weeksMap.size()) {
|
||||
result.replace(i, 1, model.weeksMap[weekIdx]);
|
||||
} else {
|
||||
qWarning() << "generateTxtFromDateItemModel: weeksMap index out of range:" << weekIdx;
|
||||
result.replace(i, 1, QString::number(applyDateTime.date().dayOfWeek()));
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化年中周数 c
|
||||
@@ -386,7 +416,7 @@ QString generateTxtFromDateItemModel(const DateItemModel &model, const QDateTime
|
||||
}
|
||||
|
||||
|
||||
QString generateTxtFromBarcodeViewModel(const BarcodeViewModel &vm, const std::array<int, 2> counterValues, const QDateTime &time)
|
||||
QString ItemUtils::generateTxtFromBarcodeViewModel(const BarcodeViewModel &vm, const std::array<int, 2> counterValues, const QDateTime &time)
|
||||
{
|
||||
QString txt = vm.contentPattern;
|
||||
auto pos = vm.contentPattern.indexOf("{t}");
|
||||
@@ -424,7 +454,7 @@ QString generateTxtFromBarcodeViewModel(const BarcodeViewModel &vm, const std::a
|
||||
* - BARCODE_TYPE_BARCODE: DlgBarcodeFormatVM(完整配置)或 int(条形码类型索引,使用默认值)
|
||||
* @return QImage 生成的图像;失败返回空QImage
|
||||
*/
|
||||
QImage generateBarcodeImage(const QString &content, BarcodeType type, const QVariant &format)
|
||||
QImage ItemUtils::generateBarcodeImage(const QString &content, BarcodeType type, const QVariant &format)
|
||||
{
|
||||
if (content.isEmpty()) {
|
||||
return QImage();
|
||||
@@ -516,7 +546,7 @@ end:
|
||||
return img.copy(clipRect);
|
||||
}
|
||||
|
||||
QImage txtToImage(const QString &txt, const QFont &font, const QColor &fgColor, const QColor &bgColor)
|
||||
QImage ItemUtils::txtToImage(const QString &txt, const QFont &font, const QColor &fgColor, const QColor &bgColor)
|
||||
{
|
||||
if (txt.isEmpty()) {
|
||||
return QImage();
|
||||
|
||||
+63
-60
@@ -9,68 +9,71 @@
|
||||
#include <array>
|
||||
#include <QImage>
|
||||
|
||||
/**
|
||||
* @brief 根据日期视图模型和时间生成字符串
|
||||
* @param model 包含日期格式模版和相关配置的视图模型
|
||||
* @param time 用于生成字符串的时间
|
||||
* @return QString 生成的字符串
|
||||
* @remark
|
||||
* 该函数根据 model.datetimePattern 中的格式模版生成字符串,支持以下格式:
|
||||
* - yyyy: 四位数年份,支持替换为自定义字符串(通过 model.yearsMap)
|
||||
* - YY: 两位数年份
|
||||
* - MM: 两位数月份,支持替换为自定义字符串(通过 model.monthsMap)
|
||||
* - dd: 两位数日期,支持替换为自定义字符串(通过 model.daysMap)
|
||||
* - HH: 两位数小时,支持替换为自定义字符串(通过 model.hoursMap)
|
||||
* - mm: 两位数分钟
|
||||
* - ss: 两位数秒钟
|
||||
* - w: 星期几,支持替换为自定义字符串(通过 model.weeksMap)
|
||||
* - c: 年中周数
|
||||
*/
|
||||
QString generateTxtFromDateItemModel(const DateItemModel& model, const QDateTime& time);
|
||||
|
||||
/**
|
||||
* @brief 根据条形码视图模型的内容模版生成字符串,
|
||||
* 生成的字符串可用于创建条形码或二维码
|
||||
*
|
||||
* @example
|
||||
* input: "ABC_{c}_{t}"
|
||||
* output: "ABC_1230_2026/04/30"
|
||||
*
|
||||
* @remark
|
||||
* 函数根据vm中的 contentPattern 是否存在变量模版,如果存在计数器变量,则使用 counterViewModel 格式化,同理也处理时间变量。
|
||||
*
|
||||
* @param vm 包含格式化所需的内容模版及相关配置
|
||||
* @param counterValues 所有计数器的当前值,counterValues[0] 为计数器1的当前值,counterValues[1]为计数器2的当前值......
|
||||
* @param time 要用于格式化的时间,通常是当前时间
|
||||
* @return QString 格式化后的字符串
|
||||
*
|
||||
*/
|
||||
QString generateTxtFromBarcodeViewModel(const BarcodeViewModel& vm, const std::array<int, 2> counterValues, const QDateTime& time);
|
||||
namespace ItemUtils
|
||||
{
|
||||
/**
|
||||
* @brief 根据日期视图模型和时间生成字符串
|
||||
* @param model 包含日期格式模版和相关配置的视图模型
|
||||
* @param time 用于生成字符串的时间
|
||||
* @return QString 生成的字符串
|
||||
* @remark
|
||||
* 该函数根据 model.datetimePattern 中的格式模版生成字符串,支持以下格式:
|
||||
* - yyyy: 四位数年份,支持替换为自定义字符串(通过 model.yearsMap)
|
||||
* - YY: 两位数年份
|
||||
* - MM: 两位数月份,支持替换为自定义字符串(通过 model.monthsMap)
|
||||
* - dd: 两位数日期,支持替换为自定义字符串(通过 model.daysMap)
|
||||
* - HH: 两位数小时,支持替换为自定义字符串(通过 model.hoursMap)
|
||||
* - mm: 两位数分钟
|
||||
* - ss: 两位数秒钟
|
||||
* - w: 星期几,支持替换为自定义字符串(通过 model.weeksMap)
|
||||
* - c: 年中周数
|
||||
*/
|
||||
QString generateTxtFromDateItemModel(const DateItemModel& model, const QDateTime& time);
|
||||
|
||||
/**
|
||||
* @brief 根据条形码类型和内容生成条形码或二维码图像
|
||||
* @param content 已格式化的文本内容
|
||||
* @param type 条码类型
|
||||
* @param format 配置参数
|
||||
* @return QImage 生成的图像;如果失败返回空图像
|
||||
* @note
|
||||
* format 参数类型:
|
||||
* - BARCODE_TYPE_QRCODE: DlgQrcodeFormatVM 或 int
|
||||
* - BARCODE_TYPE_BARCODE: DlgBarcodeFormatVM 或 int
|
||||
* 如果 format 是 int 类型, 对于 QR Code,0 表示 Data Matrix,1 表示 QR Code;对于条形码,int 值对应 DlgBarcodeFormatVM 中 type 的索引。
|
||||
* 如果 format 是 int 类型,则使用默认配置并根据 int 值选择二维码或条形码的子类型;如果 format 是对应的 VM 类型,则使用其中的详细配置。
|
||||
*/
|
||||
QImage generateBarcodeImage(const QString& content, BarcodeType type, const QVariant& format);
|
||||
/**
|
||||
* @brief 根据条形码视图模型的内容模版生成字符串,
|
||||
* 生成的字符串可用于创建条形码或二维码
|
||||
*
|
||||
* @example
|
||||
* input: "ABC_{c}_{t}"
|
||||
* output: "ABC_1230_2026/04/30"
|
||||
*
|
||||
* @remark
|
||||
* 函数根据vm中的 contentPattern 是否存在变量模版,如果存在计数器变量,则使用 counterViewModel 格式化,同理也处理时间变量。
|
||||
*
|
||||
* @param vm 包含格式化所需的内容模版及相关配置
|
||||
* @param counterValues 所有计数器的当前值,counterValues[0] 为计数器1的当前值,counterValues[1]为计数器2的当前值......
|
||||
* @param time 要用于格式化的时间,通常是当前时间
|
||||
* @return QString 格式化后的字符串
|
||||
*
|
||||
*/
|
||||
QString generateTxtFromBarcodeViewModel(const BarcodeViewModel& vm, const std::array<int, 2> counterValues, const QDateTime& time);
|
||||
|
||||
/**
|
||||
* @brief 将文本转换为图像
|
||||
* @param txt 要转换的文本
|
||||
* @param font 文本使用的字体
|
||||
* @param fgColor 文本颜色,默认为黑色
|
||||
* @param bgColor 背景颜色,默认为白色
|
||||
* @return QImage 转换后的图像
|
||||
* @note 返回的字符串图像会裁剪至最小边界以节省空间。例如字符串"aaa"的高度会比"bbbjjj"小,因为前者没有上下行部分。
|
||||
*/
|
||||
QImage txtToImage(const QString& txt, const QFont& font, const QColor& fgColor = Qt::black, const QColor& bgColor = Qt::white);
|
||||
/**
|
||||
* @brief 根据条形码类型和内容生成条形码或二维码图像
|
||||
* @param content 已格式化的文本内容
|
||||
* @param type 条码类型
|
||||
* @param format 配置参数
|
||||
* @return QImage 生成的图像;如果失败返回空图像
|
||||
* @note
|
||||
* format 参数类型:
|
||||
* - BARCODE_TYPE_QRCODE: DlgQrcodeFormatVM 或 int
|
||||
* - BARCODE_TYPE_BARCODE: DlgBarcodeFormatVM 或 int
|
||||
* 如果 format 是 int 类型, 对于 QR Code,0 表示 Data Matrix,1 表示 QR Code;对于条形码,int 值对应 DlgBarcodeFormatVM 中 type 的索引。
|
||||
* 如果 format 是 int 类型,则使用默认配置并根据 int 值选择二维码或条形码的子类型;如果 format 是对应的 VM 类型,则使用其中的详细配置。
|
||||
*/
|
||||
QImage generateBarcodeImage(const QString& content, BarcodeType type, const QVariant& format);
|
||||
|
||||
/**
|
||||
* @brief 将文本转换为图像
|
||||
* @param txt 要转换的文本
|
||||
* @param font 文本使用的字体
|
||||
* @param fgColor 文本颜色,默认为黑色
|
||||
* @param bgColor 背景颜色,默认为白色
|
||||
* @return QImage 转换后的图像
|
||||
* @note 返回的字符串图像会裁剪至最小边界以节省空间。例如字符串"aaa"的高度会比"bbbjjj"小,因为前者没有上下行部分。
|
||||
*/
|
||||
QImage txtToImage(const QString& txt, const QFont& font, const QColor& fgColor = Qt::black, const QColor& bgColor = Qt::white);
|
||||
}
|
||||
#endif // _ITEM_COMMON_H_
|
||||
|
||||
@@ -38,7 +38,7 @@ void ItemGeneralSettings::edit(PicTextItem *item)
|
||||
m_currItem = item;
|
||||
|
||||
// 从item快照创建ViewModel(如果item为空,使用默认值)
|
||||
setViewModel(ItemGeneralSettingsVM::fromItem(item));
|
||||
setViewModel(TextItemModel::fromItem(item));
|
||||
}
|
||||
|
||||
void ItemGeneralSettings::initUI()
|
||||
@@ -53,7 +53,7 @@ void ItemGeneralSettings::initUI()
|
||||
ui->counterIDSpinBox->setValue(0);
|
||||
}
|
||||
|
||||
void ItemGeneralSettings::setViewModel(const ItemGeneralSettingsVM &vm)
|
||||
void ItemGeneralSettings::setViewModel(const TextItemModel &vm)
|
||||
{
|
||||
m_vmSnapshot = vm;
|
||||
m_vm = vm;
|
||||
|
||||
@@ -11,46 +11,6 @@ namespace Ui {
|
||||
class ItemGeneralSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 图元通用属性的ViewModel
|
||||
*
|
||||
* 目的:解耦UI编辑器与PicTextItem,支持灵活的数据绑定和批量操作。
|
||||
* UI修改属性时先更新VM,再决定何时应用到item(实时或延迟)。
|
||||
*/
|
||||
struct ItemGeneralSettingsVM {
|
||||
// 图元类型,用于判断是否显示字间距
|
||||
SourceType sourceType = SourceType::UNKNOWN;
|
||||
|
||||
ItemDirectionType direction = NORMAL;
|
||||
int boldMultiple = 1;
|
||||
int letterSpace = 0;
|
||||
bool colorReversal = false;
|
||||
|
||||
std::function<QImage()> imageGenerator; // 图片生成函数
|
||||
|
||||
// 便利方法:从PicTextItem快照创建VM
|
||||
static ItemGeneralSettingsVM fromItem(PicTextItem *item) {
|
||||
ItemGeneralSettingsVM vm;
|
||||
if (item) {
|
||||
vm.sourceType = item->sourceType();
|
||||
vm.direction = item->direction();
|
||||
vm.boldMultiple = item->boldMultiple();
|
||||
vm.letterSpace = item->letterSpace();
|
||||
vm.colorReversal = item->colorReversal();
|
||||
}
|
||||
return vm;
|
||||
}
|
||||
|
||||
// 检查是否有改动
|
||||
bool hasDifference(const ItemGeneralSettingsVM &other) const {
|
||||
return sourceType != other.sourceType ||
|
||||
direction != other.direction ||
|
||||
boldMultiple != other.boldMultiple ||
|
||||
letterSpace != other.letterSpace ||
|
||||
colorReversal != other.colorReversal;
|
||||
}
|
||||
};
|
||||
|
||||
class ItemGeneralSettings : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -72,14 +32,14 @@ public:
|
||||
*
|
||||
* @param vm
|
||||
*/
|
||||
void setViewModel(const ItemGeneralSettingsVM& vm);
|
||||
void setViewModel(const TextItemModel& vm);
|
||||
|
||||
/**
|
||||
* @brief 获取当前ViewModel
|
||||
*
|
||||
* 调用者可以检查是否有改动,并决定是否应用
|
||||
*/
|
||||
ItemGeneralSettingsVM viewModel() const { return m_vm; }
|
||||
TextItemModel viewModel() const { return m_vm; }
|
||||
|
||||
/**
|
||||
* @brief 将ViewModel的属性应用到指定的PicTextItem
|
||||
@@ -117,10 +77,10 @@ private:
|
||||
PicTextItem* m_currItem = nullptr;
|
||||
|
||||
// UI编辑的状态,独立于m_currItem
|
||||
ItemGeneralSettingsVM m_vm;
|
||||
TextItemModel m_vm;
|
||||
|
||||
// 初始加载时的VM状态,用于检测改动
|
||||
ItemGeneralSettingsVM m_vmSnapshot;
|
||||
TextItemModel m_vmSnapshot;
|
||||
|
||||
QPainter m_painter;
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ void PicDateItem::setSource(QVariant var)
|
||||
if(m_model.datetimePattern.isEmpty())
|
||||
return;
|
||||
|
||||
m_currDateTimeStr = generateTxtFromDateItemModel(m_model, QDateTime::currentDateTime());
|
||||
m_currDateTimeStr = ItemUtils::generateTxtFromDateItemModel(m_model, QDateTime::currentDateTime());
|
||||
applyModify();
|
||||
}
|
||||
|
||||
@@ -47,13 +47,13 @@ bool PicDateItem::updateDatetimeStr()
|
||||
return false;
|
||||
|
||||
if(m_currDateTimeStr.isEmpty()) {
|
||||
m_currDateTimeStr = generateTxtFromDateItemModel(m_model, QDateTime::currentDateTime());
|
||||
m_currDateTimeStr = ItemUtils::generateTxtFromDateItemModel(m_model, QDateTime::currentDateTime());
|
||||
applyModify();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto now = QDateTime::currentDateTime();
|
||||
auto str = generateTxtFromDateItemModel(m_model, now);
|
||||
auto str = ItemUtils::generateTxtFromDateItemModel(m_model, now);
|
||||
if(str == m_currDateTimeStr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -52,22 +52,20 @@ ScheduleShiftsEditor::~ScheduleShiftsEditor()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ScheduleShiftsEditor::edit(PicScheduleShiftItem* item)
|
||||
void ScheduleShiftsEditor::setItemModel(QVector<ScheduleModel> schedulesModel, TextItemModel txtModel)
|
||||
{
|
||||
m_backup.clear();
|
||||
m_generalSettings->edit(item);
|
||||
if(item) {
|
||||
item->saveAttrs(m_backup);
|
||||
m_dataModel = item->schedules();
|
||||
}
|
||||
else {
|
||||
m_dataModel.clear();
|
||||
}
|
||||
m_generalSettings->setViewModel(txtModel);
|
||||
m_dataModel = schedulesModel;
|
||||
|
||||
applyDataModel();
|
||||
}
|
||||
|
||||
const QVector<ScheduleModel>& ScheduleShiftsEditor::dataModel() const
|
||||
TextItemModel ScheduleShiftsEditor::textItemModel()
|
||||
{
|
||||
return m_generalSettings->viewModel();
|
||||
}
|
||||
|
||||
const QVector<ScheduleModel>& ScheduleShiftsEditor::scheduleModel() const
|
||||
{
|
||||
return m_dataModel;
|
||||
}
|
||||
@@ -79,10 +77,6 @@ PicScheduleShiftItem *ScheduleShiftsEditor::currEditItem()
|
||||
|
||||
void ScheduleShiftsEditor::onBtnCloseClicked()
|
||||
{
|
||||
if(currEditItem()) {
|
||||
currEditItem()->setAttrs(m_backup);
|
||||
}
|
||||
|
||||
emit rejected();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,11 @@ public:
|
||||
|
||||
void edit(PicScheduleShiftItem* item);
|
||||
|
||||
const QVector<ScheduleModel>& dataModel() const;
|
||||
void setItemModel(QVector<ScheduleModel> schedulesModel, TextItemModel txtModel);
|
||||
|
||||
TextItemModel textItemModel();
|
||||
|
||||
const QVector<ScheduleModel>& scheduleModel() const;
|
||||
|
||||
PicScheduleShiftItem* currEditItem();
|
||||
|
||||
@@ -59,8 +63,6 @@ private:
|
||||
Ui::ScheduleShiftsEditor *ui;
|
||||
QVector<ScheduleModel> m_dataModel;
|
||||
ItemGeneralSettings* m_generalSettings = nullptr;
|
||||
|
||||
QXmlStreamAttributes m_backup;
|
||||
};
|
||||
|
||||
#endif // SCHEDULESHIFTSEDITOR_H
|
||||
|
||||
+13
-2
@@ -37,17 +37,23 @@ void PicCodeItem::setBarcodeViewModel(const BarcodeViewModel &vm)
|
||||
{
|
||||
m_vm = vm;
|
||||
m_currCodeTxt = "";
|
||||
setTextItemModel(m_vm.generalSettingsVM);
|
||||
updateVariants();
|
||||
qInfo() << "Barcode model: \r\n" << qPrintable(BarcodeViewModel::toString(vm));
|
||||
}
|
||||
|
||||
BarcodeViewModel PicCodeItem::barcodeViewModel()
|
||||
{
|
||||
m_vm.generalSettingsVM = textItemModel();
|
||||
return m_vm;
|
||||
}
|
||||
|
||||
bool PicCodeItem::updateVariants(const QVector<int> counters)
|
||||
{
|
||||
if (counters.size() < 2) {
|
||||
qWarning() << "PicCodeItem::updateVariants: counters size insufficient:" << counters.size() << ", expected >= 2";
|
||||
return false;
|
||||
}
|
||||
m_currCounterValues = counters;
|
||||
return updateVariants();
|
||||
}
|
||||
@@ -70,10 +76,15 @@ void PicCodeItem::saveCustomAttrs(QXmlStreamAttributes &attrs)
|
||||
|
||||
bool PicCodeItem::updateVariants()
|
||||
{
|
||||
auto txt = generateTxtFromBarcodeViewModel(m_vm, {m_currCounterValues[0], m_currCounterValues[1]}, QDateTime::currentDateTime());
|
||||
if (m_currCounterValues.size() < 2) {
|
||||
qWarning() << "PicCodeItem::updateVariants: m_currCounterValues size < 2, cannot generate barcode text";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto txt = ItemUtils::generateTxtFromBarcodeViewModel(m_vm, {m_currCounterValues[0], m_currCounterValues[1]}, QDateTime::currentDateTime());
|
||||
if(txt != m_currCodeTxt || m_currCodeTxt.isEmpty()) {
|
||||
m_currCodeTxt = txt;
|
||||
m_codeImage = generateBarcodeImage(txt, m_vm.type, m_vm.format);
|
||||
m_codeImage = ItemUtils::generateBarcodeImage(txt, m_vm.type, m_vm.format);
|
||||
applyModify();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -300,6 +300,19 @@ QImage PicTextItem::preview()
|
||||
{
|
||||
return m_itemImage;
|
||||
}
|
||||
void PicTextItem::setTextItemModel(const TextItemModel &model)
|
||||
{
|
||||
setLetterSpace(model.letterSpace);
|
||||
setBoldMultiple(model.boldMultiple);
|
||||
setDirection(model.direction);
|
||||
setColorReversal(model.colorReversal);
|
||||
}
|
||||
|
||||
TextItemModel PicTextItem::textItemModel()
|
||||
{
|
||||
return TextItemModel::fromItem(this);
|
||||
}
|
||||
|
||||
//! [1]
|
||||
QVariant PicTextItem::itemChange(GraphicsItemChange change,
|
||||
const QVariant &value)
|
||||
@@ -441,3 +454,16 @@ QPointF PicTextItem::clampItemPos(const QPointF &p)
|
||||
return QPointF (std::min(qreal(scene()->width() - boundingRect().width()), std::max(0.0, p.x())),
|
||||
std::min(qreal(scene()->height() - boundingRect().height()), std::max(0.0, p.y())));
|
||||
}
|
||||
|
||||
TextItemModel TextItemModel::fromItem(PicTextItem *item)
|
||||
{
|
||||
TextItemModel vm;
|
||||
if (item) {
|
||||
vm.sourceType = item->sourceType();
|
||||
vm.direction = item->direction();
|
||||
vm.boldMultiple = item->boldMultiple();
|
||||
vm.letterSpace = item->letterSpace();
|
||||
vm.colorReversal = item->colorReversal();
|
||||
}
|
||||
return vm;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,39 @@ enum SourceType{
|
||||
COUNTER,
|
||||
};
|
||||
|
||||
class PicTextItem;
|
||||
|
||||
/**
|
||||
* @brief 图元通用属性的ViewModel
|
||||
*
|
||||
* 目的:解耦UI编辑器与PicTextItem,支持灵活的数据绑定和批量操作。
|
||||
* UI修改属性时先更新VM,再决定何时应用到item(实时或延迟)。
|
||||
*/
|
||||
struct TextItemModel {
|
||||
// 图元类型,用于判断是否显示字间距
|
||||
SourceType sourceType = SourceType::UNKNOWN;
|
||||
|
||||
ItemDirectionType direction = NORMAL;
|
||||
int boldMultiple = 1;
|
||||
int letterSpace = 0;
|
||||
bool colorReversal = false;
|
||||
|
||||
std::function<QImage()> imageGenerator; // 图片生成函数
|
||||
|
||||
// 便利方法:从PicTextItem快照创建VM
|
||||
static TextItemModel fromItem(PicTextItem *item);
|
||||
|
||||
// 检查是否有改动
|
||||
bool hasDifference(const TextItemModel &other) const {
|
||||
return sourceType != other.sourceType ||
|
||||
direction != other.direction ||
|
||||
boldMultiple != other.boldMultiple ||
|
||||
letterSpace != other.letterSpace ||
|
||||
colorReversal != other.colorReversal;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PicTextItem : public QGraphicsTextItem
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -121,6 +154,10 @@ public:
|
||||
*/
|
||||
QImage preview();
|
||||
|
||||
void setTextItemModel(const TextItemModel& model);
|
||||
|
||||
TextItemModel textItemModel();
|
||||
|
||||
signals:
|
||||
void lostFocus(PicTextItem *item);
|
||||
void selectedChange(QGraphicsItem *item);
|
||||
|
||||
Reference in New Issue
Block a user