qt/LedOK/program/edclock.cpp

463 lines
15 KiB
C++
Raw Normal View History

2022-08-25 18:37:24 +08:00
#include "edclock.h"
#include "base/locolorselector.h"
2024-08-07 18:18:37 +08:00
#include "main.h"
2023-04-27 15:06:24 +08:00
#include "gutil/qgui.h"
2025-05-06 18:28:05 +08:00
#include "tools.h"
2022-08-25 18:37:24 +08:00
#include <QCheckBox>
#include <QFontComboBox>
#include <QSpinBox>
2023-04-18 14:14:46 +08:00
#include <QToolButton>
2023-05-15 16:06:10 +08:00
#include <QLabel>
2022-08-25 18:37:24 +08:00
2023-04-18 14:14:46 +08:00
EDClock::EDClock(EBase *multiWin) : EBase(multiWin) {
2022-08-25 18:37:24 +08:00
mType = EBase::DClock;
2025-05-06 18:28:05 +08:00
timeZone = QTimeZone::systemTimeZone();
2022-08-25 18:37:24 +08:00
init();
}
2023-10-23 14:58:29 +08:00
EDClock::EDClock(const JObj &json, EBase *multiWin) : EBase(multiWin) {
2022-08-25 18:37:24 +08:00
mType = EBase::DClock;
setBaseAttr(json);
auto widget = json["widget"];
2025-05-06 18:28:05 +08:00
if(widget.isNull()) {
widget = json;
font = qfont(json["font"].toString(), json["fontSize"].toInt(), json["fontBold"].toBool(), json["fontItalic"].toBool());
font.setUnderline(json["fontUnderline"].toBool());
color = json["color"].toStr("#ffff0000");
hasYear = widget["hasYear"].toBool();
hasMonth = widget["hasMonth"].toBool();
hasDay = widget["hasDay"].toBool();
hasHour = widget["hasHour"].toBool();
hasMin = widget["hasMin"].toBool();
hasSec = widget["hasSec"].toBool();
hasWeek = widget["hasWeek"].toBool();
hasAmPm = widget["hasAmPm"].toBool();
is12Hour = widget["is12Hour"].toBool();
isFullYear = widget["isFullYear"].toBool();
isMultiline = json["isMultiline"].toBool();
} else {
auto font = widget["font"];
this->font = qfont(font["family"].toString(), font["size"].toInt(), font["bold"].toBool(), font["italics"].toBool());
this->font.setUnderline(font["underline"].toBool());
color = Tools::int2Color(font["color"].toInt());
hasYear = widget["year"].toBool();
hasMonth = widget["month"].toBool();
hasDay = widget["day"].toBool();
hasHour = widget["hour"].toBool();
hasMin = widget["min"].toBool();
hasSec = widget["sec"].toBool();
hasWeek = widget["weekly"].toBool();
hasAmPm = widget["AmPm"].toBool();
is12Hour = widget["12Hour"].toBool();
isFullYear = widget["fullYear"].toBool();
isMultiline = widget["multiline"].toBool();
}
timeZone = QTimeZone(widget["timeZone"].toString().toUtf8());
dateStyle = widget["dateStyle"].toInt();
isSingleHour = widget["timeStyle"].toInt();
isSingleMD = dateStyle==1||dateStyle==2||dateStyle==4||dateStyle==6||dateStyle==8||dateStyle==10||dateStyle==12;
2022-08-25 18:37:24 +08:00
init();
}
2023-04-18 14:14:46 +08:00
void EDClock::init() {
2024-08-07 18:18:37 +08:00
connect(gTick, &Tick::secChanged, this, [this](const QDateTime &cur) {
2025-05-06 18:28:05 +08:00
datetime = cur.toTimeZone(timeZone);
2022-08-25 18:37:24 +08:00
update();
});
}
2023-04-18 14:14:46 +08:00
void EDClock::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
2022-08-25 18:37:24 +08:00
QString text;
QDate date = datetime.date();
QTime time = datetime.time();
2025-05-06 18:28:05 +08:00
QString spacer = isMultiline ? "\n" : " ";
QString yearFmt = isFullYear ? "yyyy" : "yy";
2022-08-25 18:37:24 +08:00
QString monthFmt = isSingleMD ? "M" : "MM";
QString dateFmt = isSingleMD ? "d" : "dd";
QString sep;
2025-05-06 18:28:05 +08:00
if(dateStyle > 7) sep = "-";
else if(dateStyle > 1) sep = "/";
switch(dateStyle) {
2022-08-25 18:37:24 +08:00
case 0: case 1:
2025-05-06 18:28:05 +08:00
if(hasYear) text += date.toString(yearFmt) + "";
if(hasMonth) text += date.toString(monthFmt) + "";
if(hasDay) text += date.toString(dateFmt) + "";
2022-08-25 18:37:24 +08:00
break;
case 2: case 3: case 8: case 9:
2025-05-06 18:28:05 +08:00
if(hasMonth) text += date.toString(monthFmt) + sep;
if(hasDay) text += date.toString(dateFmt) + sep;
if(hasYear) text += date.toString(yearFmt);
2022-08-25 18:37:24 +08:00
if(text.endsWith(sep)) text.chop(1);
break;
case 4: case 5: case 10: case 11:
2025-05-06 18:28:05 +08:00
if(hasDay) text += date.toString(dateFmt) + sep;
if(hasMonth) text += date.toString(monthFmt) + sep;
if(hasYear) text += date.toString(yearFmt);
2022-08-25 18:37:24 +08:00
if(text.endsWith(sep)) text.chop(1);
break;
case 6: case 7: case 12: case 13:
2025-05-06 18:28:05 +08:00
if(hasYear) text += date.toString(yearFmt) + sep;
if(hasMonth) text += date.toString(monthFmt) + sep;
if(hasDay) text += date.toString(dateFmt);
2022-08-25 18:37:24 +08:00
if(text.endsWith(sep)) text.chop(1);
break;
default:
break;
}
if(! text.isEmpty()) text += spacer;
2025-05-06 18:28:05 +08:00
if(hasWeek) {
2022-08-25 18:37:24 +08:00
auto dayOfWeek = date.dayOfWeek();
if(dayOfWeek==1) text += tr("MON");
else if(dayOfWeek==2) text += tr("TUE");
else if(dayOfWeek==3) text += tr("WED");
else if(dayOfWeek==4) text += tr("THU");
else if(dayOfWeek==5) text += tr("FRI");
else if(dayOfWeek==6) text += tr("SAT");
else if(dayOfWeek==7) text += tr("SUN");
text += spacer;
}
QString timeFmt;
2025-05-06 18:28:05 +08:00
if(is12Hour && hasAmPm) timeFmt += (time.hour()<12 ? tr("AM") : tr("PM")) + " ";
if(hasHour) timeFmt += (isSingleHour ? "h:" : "hh:");
if(hasMin) timeFmt += "mm:";
if(hasSec) timeFmt += "ss";
2022-08-25 18:37:24 +08:00
if(timeFmt.endsWith(":")) timeFmt.chop(1);
if(! timeFmt.isEmpty()) text += time.toString(timeFmt);
text = text.trimmed();
2025-05-06 18:28:05 +08:00
auto lines = text.split("\n");
auto rect = innerRect();
if(lines.size() > 1) rect.setHeight(lineHeight = rect.height() / lines.size());
2022-08-25 18:37:24 +08:00
painter->save();
2025-05-06 18:28:05 +08:00
painter->setPen(color);
font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias);
painter->setFont(font);
for(auto &line : lines) {
painter->drawText(rect, line, QTextOption(Qt::AlignCenter));
rect.translate(0, rect.height());
}
2022-08-25 18:37:24 +08:00
painter->restore();
EBase::paint(painter, option, widget);
}
2023-04-18 14:14:46 +08:00
QWidget* EDClock::attrWgt() {
2022-08-25 18:37:24 +08:00
auto wgtAttr = new QWidget();
auto vBox = new QVBoxLayout(wgtAttr);
vBox->setContentsMargins(6, 0, 6, 0);
2025-05-06 18:28:05 +08:00
if(mMultiWin) vBox->setSpacing(3);
2022-08-25 18:37:24 +08:00
addBaseAttrWgt(vBox);
auto hBox = new QHBoxLayout();
2025-05-06 18:28:05 +08:00
hBox->addWidget(new QLabel(translate("","Basic Properties")));
2022-08-25 18:37:24 +08:00
auto line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Time Zone")));
2024-06-25 09:37:41 +08:00
auto edTimeZone = new QComboBox;
2022-08-25 18:37:24 +08:00
auto zoneIds = QTimeZone::availableTimeZoneIds();
2024-06-25 09:37:41 +08:00
for(auto &zoneId : zoneIds) edTimeZone->addItem(zoneId);
2025-05-06 18:28:05 +08:00
edTimeZone->setCurrentText(timeZone.id());
2024-06-25 09:37:41 +08:00
connect(edTimeZone, &QComboBox::currentTextChanged, this, [this](const QString &text) {
2025-05-06 18:28:05 +08:00
timeZone = QTimeZone(text.toUtf8());
2022-08-25 18:37:24 +08:00
update();
});
2024-06-25 09:37:41 +08:00
hBox->addWidget(edTimeZone);
2022-08-25 18:37:24 +08:00
hBox->addStretch();
vBox->addLayout(hBox);
line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
vBox->addWidget(line);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
auto fdYear = new QCheckBox(tr("Year"));
2025-05-06 18:28:05 +08:00
fdYear->setChecked(hasYear);
2022-08-25 18:37:24 +08:00
connect(fdYear, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
hasYear = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdYear);
auto fdMonth = new QCheckBox(tr("Month"));
2025-05-06 18:28:05 +08:00
fdMonth->setChecked(hasMonth);
2022-08-25 18:37:24 +08:00
connect(fdMonth, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
hasMonth = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdMonth);
auto fdDay = new QCheckBox(tr("Day"));
2025-05-06 18:28:05 +08:00
fdDay->setChecked(hasDay);
2022-08-25 18:37:24 +08:00
connect(fdDay, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
hasDay = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdDay);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
auto fdHour = new QCheckBox(tr("Hour"));
2025-05-06 18:28:05 +08:00
fdHour->setChecked(hasHour);
2022-08-25 18:37:24 +08:00
connect(fdHour, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
hasHour = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdHour);
auto fdMin = new QCheckBox(tr("Min."));
2025-05-06 18:28:05 +08:00
fdMin->setChecked(hasMin);
2022-08-25 18:37:24 +08:00
connect(fdMin, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
hasMin = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdMin);
auto fdSec = new QCheckBox(tr("Sec."));
2025-05-06 18:28:05 +08:00
fdSec->setChecked(hasSec);
2022-08-25 18:37:24 +08:00
connect(fdSec, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
hasSec = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdSec);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
auto fdHasWeek = new QCheckBox(tr("Weekly"));
2025-05-06 18:28:05 +08:00
fdHasWeek->setChecked(hasWeek);
2022-08-25 18:37:24 +08:00
connect(fdHasWeek, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
hasWeek = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdHasWeek);
auto fdFullYear = new QCheckBox(tr("Full Year"));
2025-05-06 18:28:05 +08:00
fdFullYear->setChecked(isFullYear);
2022-08-25 18:37:24 +08:00
connect(fdFullYear, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
isFullYear = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdFullYear);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
auto fdIs12Hour = new QCheckBox(tr("12-Hour"));
2025-05-06 18:28:05 +08:00
fdIs12Hour->setChecked(is12Hour);
2022-08-25 18:37:24 +08:00
hBox->addWidget(fdIs12Hour);
auto fdAmPm = new QCheckBox(tr("AM")+"/"+tr("PM"));
2025-05-06 18:28:05 +08:00
fdAmPm->setChecked(hasAmPm);
2022-08-25 18:37:24 +08:00
connect(fdIs12Hour, &QCheckBox::toggled, this, [this, fdAmPm](bool checked) {
2025-05-06 18:28:05 +08:00
is12Hour = checked;
2022-08-25 18:37:24 +08:00
fdAmPm->setVisible(checked);
if(! checked) fdAmPm->setChecked(false);
update();
});
connect(fdAmPm, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
hasAmPm = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdAmPm);
vBox->addLayout(hBox);
line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
vBox->addWidget(line);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Date Style")));
2025-05-06 18:28:05 +08:00
auto fdDateFmt = new QComboBox;
fdDateFmt->addItem("1970-02-24", 13);
fdDateFmt->addItem("1970-2-24", 12);
fdDateFmt->addItem("1970年02月04日", 0);
fdDateFmt->addItem("1970年2月4日", 1);
fdDateFmt->addItem("1970/02/24", 7);
fdDateFmt->addItem("1970/2/24", 6);
fdDateFmt->addItem("02-24-1970", 9);
fdDateFmt->addItem("2-24-1970", 8);
fdDateFmt->addItem("02/24/1970", 3);
fdDateFmt->addItem("2/24/1970", 2);
fdDateFmt->addItem("24-02-1970", 11);
fdDateFmt->addItem("24-2-1970", 10);
fdDateFmt->addItem("24/02/1970", 5);
fdDateFmt->addItem("24/2/1970", 4);
SetCurData(fdDateFmt, dateStyle);
connect(fdDateFmt, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=](int index) {
dateStyle = fdDateFmt->itemData(index).toInt();
2022-08-25 18:37:24 +08:00
isSingleMD = index==1||index==2||index==4||index==6||index==8||index==10||index==12;
update();
});
hBox->addWidget(fdDateFmt);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Time Style")));
2025-05-06 18:28:05 +08:00
auto fdTimeFmt = new QComboBox;
2022-08-25 18:37:24 +08:00
fdTimeFmt->addItem("HH:MM:SS");
fdTimeFmt->addItem("H:MM:SS");
2025-05-06 18:28:05 +08:00
fdTimeFmt->setCurrentIndex(isSingleHour);
2022-08-25 18:37:24 +08:00
connect(fdTimeFmt, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int index) {
2025-05-06 18:28:05 +08:00
isSingleHour = index;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdTimeFmt);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Display Style")));
auto fdIsMultiline = new QCheckBox(tr("Multiline"));
2025-05-06 18:28:05 +08:00
fdIsMultiline->setChecked(isMultiline);
2022-08-25 18:37:24 +08:00
connect(fdIsMultiline, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
isMultiline = checked;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdIsMultiline);
hBox->addStretch();
vBox->addLayout(hBox);
2025-05-06 18:28:05 +08:00
line = new QFrame;
2022-08-25 18:37:24 +08:00
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
vBox->addWidget(line);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
auto fdFontFamily = new QFontComboBox();
fdFontFamily->setEditable(false);
2025-05-06 18:28:05 +08:00
fdFontFamily->setCurrentText(font.family());
2022-08-25 18:37:24 +08:00
connect(fdFontFamily, &QFontComboBox::currentFontChanged, this, [this](const QFont &f) {
2025-05-06 18:28:05 +08:00
QFont ft(f.family());
ft.setPixelSize(font.pixelSize());
ft.setBold(font.bold());
ft.setItalic(font.italic());
ft.setUnderline(font.underline());
font = ft;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdFontFamily);
auto fdFontSize = new QSpinBox();
fdFontSize->setRange(4, 9999);
2025-05-06 18:28:05 +08:00
fdFontSize->setValue(font.pixelSize());
2022-08-25 18:37:24 +08:00
connect(fdFontSize, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
2025-05-06 18:28:05 +08:00
font.setPixelSize(value);
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdFontSize);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
2023-04-18 14:14:46 +08:00
auto fdBold = new QPushButton("B");
fdBold->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-weight: bold;} QPushButton:checked{background: #29c; color: #fff;}");
2022-08-25 18:37:24 +08:00
fdBold->setFixedSize(30, 30);
fdBold->setCheckable(true);
2025-05-06 18:28:05 +08:00
fdBold->setChecked(font.bold());
2022-08-25 18:37:24 +08:00
connect(fdBold, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
font.setBold(checked);
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdBold);
2023-04-18 14:14:46 +08:00
auto fdItalic = new QPushButton("I");
fdItalic->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-style: italic;} QPushButton:checked{background: #29c; color: #fff;}");
2022-08-25 18:37:24 +08:00
fdItalic->setFixedSize(30, 30);
fdItalic->setCheckable(true);
2025-05-06 18:28:05 +08:00
fdItalic->setChecked(font.italic());
2022-08-25 18:37:24 +08:00
connect(fdItalic, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
font.setItalic(checked);
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdItalic);
2023-04-18 14:14:46 +08:00
auto fdFontUnderline = new QPushButton("U");
fdFontUnderline->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; text-decoration: underline;} QPushButton:checked{background: #29c; color: #fff;}");
fdFontUnderline->setFixedSize(30, 30);
fdFontUnderline->setCheckable(true);
2025-05-06 18:28:05 +08:00
fdFontUnderline->setChecked(font.underline());
2023-04-18 14:14:46 +08:00
connect(fdFontUnderline, &QCheckBox::toggled, this, [this](bool checked) {
2025-05-06 18:28:05 +08:00
font.setUnderline(checked);
2022-08-25 18:37:24 +08:00
update();
});
2023-04-18 14:14:46 +08:00
hBox->addWidget(fdFontUnderline);
2022-08-25 18:37:24 +08:00
2025-05-06 18:28:05 +08:00
auto fdColor = new LoColorSelector("T", color);
2022-08-25 18:37:24 +08:00
fdColor->setFixedWidth(30);
connect(fdColor, &LoColorSelector::sColorChanged, this, [this](const QColor &color) {
2025-05-06 18:28:05 +08:00
this->color = color;
2022-08-25 18:37:24 +08:00
update();
});
hBox->addWidget(fdColor);
hBox->addStretch();
vBox->addLayout(hBox);
vBox->addStretch();
return wgtAttr;
}
2025-05-06 18:28:05 +08:00
JObj EDClock::attrJson() const {
JObj json;
addBaseAttr(json);
json["elementType"] = "DClock";
json["timeZone"] = QString::fromUtf8(timeZone.id());
json["hasYear"] = hasYear;
json["hasMonth"] = hasMonth;
json["hasDay"] = hasDay;
json["hasHour"] = hasHour;
json["hasMin"] = hasMin;
json["hasSec"] = hasSec;
json["hasWeek"] = hasWeek;
json["isFullYear"] = isFullYear;
json["is12Hour"] = is12Hour;
json["hasAmPm"] = hasAmPm;
json["dateStyle"] = dateStyle;
json["timeStyle"] = isSingleHour;
json["isMultiline"] = isMultiline;
json["color"] = color.name(QColor::HexArgb);
json["font"] = font.family();
json["fontSize"] = font.pixelSize();
json["fontBold"] = font.bold();
json["fontItalic"] = font.italic();
json["fontUnderline"] = font.underline();
json["lineHeight"] = lineHeight;
return json;
2022-08-25 18:37:24 +08:00
}