qt/LedOK/program/edclock.cpp
2023-04-23 10:04:49 +08:00

488 lines
16 KiB
C++

#include "edclock.h"
#include "base/locolorselector.h"
#include "globaldefine.h"
#include "tools.h"
#include <QBoxLayout>
#include <QCheckBox>
#include <QFontComboBox>
#include <QLabel>
#include <QSpinBox>
#include <QToolButton>
EDClock::EDClock(EBase *multiWin) : EBase(multiWin) {
mType = EBase::DClock;
m_attr.timeZoneId = QTimeZone::systemTimeZoneId();
m_attr.font = QFont("Arial", 9);
m_attr.year = true;
m_attr.month = true;
m_attr.day = true;
m_attr.hour = true;
m_attr.min = true;
m_attr.sec = true;
m_attr.weekly = true;
m_attr.fullYear = true;
m_attr.hour12 = true;
m_attr.AmPm = true;
m_attr.dateStyle = 0;
m_attr.timeStyle = 0;
m_attr.multiline = true;
m_attr.textColor = Qt::red;
init();
}
EDClock::EDClock(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) {
mType = EBase::DClock;
setBaseAttr(json);
auto widget = json["widget"];
auto font = widget["font"];
m_attr.font = QFont(font["family"].toString(), font["size"].toInt());
m_attr.font.setBold(font["bold"].toBool());
m_attr.font.setItalic(font["italics"].toBool());
m_attr.font.setUnderline(font["underline"].toBool());
m_attr.textColor = Tools::int2Color(font["color"].toInt());
m_attr.timeZoneId = widget["timeZone"].toString().toUtf8();
m_attr.year = widget["year"].toBool();
m_attr.month = widget["month"].toBool();
m_attr.day = widget["day"].toBool();
m_attr.hour = widget["hour"].toBool();
m_attr.min = widget["min"].toBool();
m_attr.sec = widget["sec"].toBool();
m_attr.weekly = widget["weekly"].toBool();
m_attr.fullYear = widget["fullYear"].toBool();
m_attr.hour12 = widget["12Hour"].toBool();
m_attr.AmPm = widget["AmPm"].toBool();
m_attr.dateStyle = widget["dateStyle"].toInt();
m_attr.timeStyle = widget["timeStyle"].toInt();
m_attr.multiline = widget["multiline"].toBool();
m_attr.playDuration = json["play"]["duration"].toInt();
isSingleMD = m_attr.dateStyle==1||m_attr.dateStyle==2||m_attr.dateStyle==4||m_attr.dateStyle==6||m_attr.dateStyle==8||m_attr.dateStyle==10||m_attr.dateStyle==12;
init();
}
void EDClock::init() {
connect(Tools::getInstance(), &Tools::sTick, this, [this]() {
datetime = QDateTime::currentDateTime().toTimeZone(QTimeZone(m_attr.timeZoneId));
update();
});
}
void EDClock::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
QString text;
QDate date = datetime.date();
QTime time = datetime.time();
QString spacer = m_attr.multiline ? "\n" : " ";
QString yearFmt = m_attr.fullYear ? "yyyy" : "yy";
QString monthFmt = isSingleMD ? "M" : "MM";
QString dateFmt = isSingleMD ? "d" : "dd";
QString sep;
if(m_attr.dateStyle > 7) sep = "-";
else if(m_attr.dateStyle > 1) sep = "/";
switch(m_attr.dateStyle) {
case 0: case 1:
if(m_attr.year) text += date.toString(yearFmt) + "";
if(m_attr.month) text += date.toString(monthFmt) + "";
if(m_attr.day) text += date.toString(dateFmt) + "";
break;
case 2: case 3: case 8: case 9:
if(m_attr.month) text += date.toString(monthFmt) + sep;
if(m_attr.day) text += date.toString(dateFmt) + sep;
if(m_attr.year) text += date.toString(yearFmt);
if(text.endsWith(sep)) text.chop(1);
break;
case 4: case 5: case 10: case 11:
if(m_attr.day) text += date.toString(dateFmt) + sep;
if(m_attr.month) text += date.toString(monthFmt) + sep;
if(m_attr.year) text += date.toString(yearFmt);
if(text.endsWith(sep)) text.chop(1);
break;
case 6: case 7: case 12: case 13:
if(m_attr.year) text += date.toString(yearFmt) + sep;
if(m_attr.month) text += date.toString(monthFmt) + sep;
if(m_attr.day) text += date.toString(dateFmt);
if(text.endsWith(sep)) text.chop(1);
break;
default:
break;
}
if(! text.isEmpty()) text += spacer;
if(m_attr.weekly) {
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;
if(m_attr.hour12 && m_attr.AmPm) timeFmt += (time.hour()<12 ? tr("AM") : tr("PM")) + " ";
if(m_attr.hour) timeFmt += (m_attr.timeStyle!=1 ? "hh:" : "h:");
if(m_attr.min) timeFmt += "mm:";
if(m_attr.sec) timeFmt += "ss";
if(timeFmt.endsWith(":")) timeFmt.chop(1);
if(! timeFmt.isEmpty()) text += time.toString(timeFmt);
text = text.trimmed();
painter->save();
painter->setPen(m_attr.textColor);
m_attr.font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias);
painter->setFont(m_attr.font);
painter->drawText(innerRect(), text, QTextOption(Qt::AlignCenter));
painter->restore();
EBase::paint(painter, option, widget);
}
QWidget* EDClock::attrWgt() {
auto wgtAttr = new QWidget();
auto vBox = new QVBoxLayout(wgtAttr);
vBox->setContentsMargins(6, 0, 6, 0);
if(mMultiWin!=nullptr) vBox->setSpacing(3);
addBaseAttrWgt(vBox);
auto hBox = new QHBoxLayout();
hBox->addWidget(new QLabel(tr("Basic Properties")));
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")));
auto wTimeZone = new QComboBox();
auto zoneIds = QTimeZone::availableTimeZoneIds();
foreach(QByteArray zoneId, zoneIds) wTimeZone->addItem(QString::fromUtf8(zoneId));
wTimeZone->setCurrentText(QString::fromUtf8(m_attr.timeZoneId));
connect(wTimeZone, &QComboBox::currentTextChanged, this, [this](const QString &text) {
m_attr.timeZoneId = text.toUtf8();
update();
});
hBox->addWidget(wTimeZone);
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"));
fdYear->setChecked(m_attr.year);
connect(fdYear, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.year = checked;
update();
});
hBox->addWidget(fdYear);
auto fdMonth = new QCheckBox(tr("Month"));
fdMonth->setChecked(m_attr.month);
connect(fdMonth, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.month = checked;
update();
});
hBox->addWidget(fdMonth);
auto fdDay = new QCheckBox(tr("Day"));
fdDay->setChecked(m_attr.day);
connect(fdDay, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.day = checked;
update();
});
hBox->addWidget(fdDay);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
auto fdHour = new QCheckBox(tr("Hour"));
fdHour->setChecked(m_attr.hour);
connect(fdHour, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.hour = checked;
update();
});
hBox->addWidget(fdHour);
auto fdMin = new QCheckBox(tr("Min."));
fdMin->setChecked(m_attr.min);
connect(fdMin, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.min = checked;
update();
});
hBox->addWidget(fdMin);
auto fdSec = new QCheckBox(tr("Sec."));
fdSec->setChecked(m_attr.sec);
connect(fdSec, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.sec = checked;
update();
});
hBox->addWidget(fdSec);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
auto fdHasWeek = new QCheckBox(tr("Weekly"));
fdHasWeek->setChecked(m_attr.weekly);
connect(fdHasWeek, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.weekly = checked;
update();
});
hBox->addWidget(fdHasWeek);
auto fdFullYear = new QCheckBox(tr("Full Year"));
fdFullYear->setChecked(m_attr.fullYear);
connect(fdFullYear, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.fullYear = checked;
update();
});
hBox->addWidget(fdFullYear);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
auto fdIs12Hour = new QCheckBox(tr("12-Hour"));
fdIs12Hour->setChecked(m_attr.hour12);
hBox->addWidget(fdIs12Hour);
auto fdAmPm = new QCheckBox(tr("AM")+"/"+tr("PM"));
fdAmPm->setChecked(m_attr.AmPm);
connect(fdIs12Hour, &QCheckBox::toggled, this, [this, fdAmPm](bool checked) {
m_attr.hour12 = checked;
fdAmPm->setVisible(checked);
if(! checked) fdAmPm->setChecked(false);
update();
});
connect(fdAmPm, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.AmPm = checked;
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")));
auto fdDateFmt = new QComboBox();
fdDateFmt->addItem("1955年02月04日");
fdDateFmt->addItem("1955年2月4日");
fdDateFmt->addItem("2/24/1955");
fdDateFmt->addItem("02/24/1955");
fdDateFmt->addItem("24/2/1955");
fdDateFmt->addItem("24/02/1955");
fdDateFmt->addItem("1955/2/24");
fdDateFmt->addItem("1955/02/24");
fdDateFmt->addItem("2-24-1955");
fdDateFmt->addItem("02-24-1955");
fdDateFmt->addItem("24-2-1955");
fdDateFmt->addItem("24-02-1955");
fdDateFmt->addItem("1955-2-24");
fdDateFmt->addItem("1955-02-24");
fdDateFmt->setCurrentIndex(m_attr.dateStyle);
connect(fdDateFmt, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int index) {
m_attr.dateStyle = index;
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")));
auto fdTimeFmt = new QComboBox();
fdTimeFmt->addItem("HH:MM:SS");
fdTimeFmt->addItem("H:MM:SS");
fdTimeFmt->setCurrentIndex(m_attr.timeStyle);
connect(fdTimeFmt, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int index) {
m_attr.timeStyle = index;
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"));
fdIsMultiline->setChecked(m_attr.multiline);
connect(fdIsMultiline, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.multiline = checked;
update();
});
hBox->addWidget(fdIsMultiline);
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 fdFontFamily = new QFontComboBox();
fdFontFamily->setEditable(false);
fdFontFamily->setCurrentText(m_attr.font.family());
connect(fdFontFamily, &QFontComboBox::currentFontChanged, this, [this](const QFont &f) {
QFont font(f.family());
font.setPixelSize(m_attr.font.pixelSize());
font.setBold(m_attr.font.bold());
font.setItalic(m_attr.font.italic());
font.setUnderline(m_attr.font.underline());
m_attr.font = font;
update();
});
hBox->addWidget(fdFontFamily);
auto fdFontSize = new QSpinBox();
fdFontSize->setRange(4, 9999);
fdFontSize->setValue(m_attr.font.pixelSize());
connect(fdFontSize, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
m_attr.font.setPixelSize(value);
update();
});
hBox->addWidget(fdFontSize);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
auto fdBold = new QPushButton("B");
fdBold->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-weight: bold;} QPushButton:checked{background: #29c; color: #fff;}");
fdBold->setFixedSize(30, 30);
fdBold->setCheckable(true);
fdBold->setChecked(m_attr.font.bold());
connect(fdBold, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.font.setBold(checked);
update();
});
hBox->addWidget(fdBold);
auto fdItalic = new QPushButton("I");
fdItalic->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-style: italic;} QPushButton:checked{background: #29c; color: #fff;}");
fdItalic->setFixedSize(30, 30);
fdItalic->setCheckable(true);
fdItalic->setChecked(m_attr.font.italic());
connect(fdItalic, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.font.setItalic(checked);
update();
});
hBox->addWidget(fdItalic);
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);
fdFontUnderline->setChecked(m_attr.font.underline());
connect(fdFontUnderline, &QCheckBox::toggled, this, [this](bool checked) {
m_attr.font.setUnderline(checked);
update();
});
hBox->addWidget(fdFontUnderline);
auto fdColor = new LoColorSelector("T", m_attr.textColor);
fdColor->setFixedWidth(30);
connect(fdColor, &LoColorSelector::sColorChanged, this, [this](const QColor &color) {
m_attr.textColor = color;
update();
});
hBox->addWidget(fdColor);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addWidget(new QLabel(tr("Play Properties")));
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("Play Duration")));
auto fdDuration = new QSpinBox();
fdDuration->setRange(1, 99999);
fdDuration->setValue(m_attr.playDuration);
connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
m_attr.playDuration = value;
});
hBox->addWidget(fdDuration);
hBox->addWidget(new QLabel(tr("s")));
hBox->addStretch();
vBox->addLayout(hBox);
vBox->addStretch();
return wgtAttr;
}
QJsonObject EDClock::attrJson() const{
QJsonObject oWidget;
oWidget["timeZone"] = QString::fromUtf8(m_attr.timeZoneId);
oWidget["year"] = m_attr.year;
oWidget["month"] = m_attr.month;
oWidget["day"] = m_attr.day;
oWidget["hour"] = m_attr.hour;
oWidget["min"] = m_attr.min;
oWidget["sec"] = m_attr.sec;
oWidget["weekly"] = m_attr.weekly;
oWidget["fullYear"] = m_attr.fullYear;
oWidget["12Hour"] = m_attr.hour12;
oWidget["AmPm"] = m_attr.AmPm;
oWidget["dateStyle"] = m_attr.dateStyle;
oWidget["timeStyle"] = m_attr.timeStyle;
oWidget["multiline"] = m_attr.multiline;
oWidget["font"] = QJsonObject{
{"family", m_attr.font.family()},
{"size", m_attr.font.pixelSize()},
{"bold", m_attr.font.bold()},
{"italics", m_attr.font.italic()},
{"underline", m_attr.font.underline()},
{"color", Tools::color2Int(m_attr.textColor)}
};
QJsonObject oRoot;
addBaseAttr(oRoot);
oRoot["elementType"] = "DClock";
oRoot["widget"] = oWidget;
oRoot["play"] = QJsonObject{{"duration", m_attr.playDuration}};
return oRoot;
}