2022-08-25 18:37:24 +08:00
|
|
|
|
#include "pagelistitem.h"
|
|
|
|
|
#include "cfg.h"
|
|
|
|
|
#include "tools.h"
|
2023-04-18 14:14:46 +08:00
|
|
|
|
#include "base/ffutil.h"
|
|
|
|
|
#include "program/wplanlist.h"
|
2022-08-25 18:37:24 +08:00
|
|
|
|
#include "base/lodateselector.h"
|
2023-04-18 14:14:46 +08:00
|
|
|
|
#include "program/ebase.h"
|
|
|
|
|
#include "program/etext.h"
|
|
|
|
|
#include "program/ephoto.h"
|
|
|
|
|
#include "program/evideo.h"
|
|
|
|
|
#include "program/eaudio.h"
|
|
|
|
|
#include "program/egif.h"
|
|
|
|
|
#include "program/edclock.h"
|
|
|
|
|
#include "program/eaclock.h"
|
|
|
|
|
#include "program/eenviron.h"
|
|
|
|
|
#include "program/eweb.h"
|
|
|
|
|
#include "program/etimer.h"
|
|
|
|
|
#include "program/emultiwin.h"
|
2022-08-25 18:37:24 +08:00
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
#include <QJsonArray>
|
|
|
|
|
#include <QDir>
|
|
|
|
|
#include <QBoxLayout>
|
2023-04-18 14:14:46 +08:00
|
|
|
|
#include <QSpinBox>
|
2022-08-25 18:37:24 +08:00
|
|
|
|
#include <QLineEdit>
|
|
|
|
|
#include <QDateEdit>
|
|
|
|
|
|
|
|
|
|
class PageScene : public QGraphicsScene {
|
|
|
|
|
public:
|
|
|
|
|
PageScene(qreal x, qreal y, qreal width, qreal height, QObject *parent = nullptr) : QGraphicsScene(x, y, width, height, parent) {};
|
|
|
|
|
void drawBackground(QPainter *painter, const QRectF &rect) {
|
|
|
|
|
QGraphicsScene::drawBackground(painter, rect);
|
|
|
|
|
painter->fillRect(sceneRect(), Qt::black);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PageListItem::PageListItem(const QJsonObject &attr, const QString &pageDir) : mAttr(attr), mPageDir(pageDir) {
|
|
|
|
|
setSizeHint(QSize(0,80));
|
2022-10-27 15:07:45 +08:00
|
|
|
|
mScene = new PageScene(0, 0, gProgItem->mWidth, gProgItem->mHeight, this);
|
2022-08-25 18:37:24 +08:00
|
|
|
|
auto elements = mAttr["elements"].toArray();
|
|
|
|
|
foreach(auto ele, elements) {
|
|
|
|
|
QString type = ele["elementType"].toString();
|
2023-04-18 14:14:46 +08:00
|
|
|
|
EBase *element = 0;
|
2022-08-25 18:37:24 +08:00
|
|
|
|
if(type=="Text") element = new EText(ele.toObject());
|
|
|
|
|
else if(type=="Photo") element = EPhoto::create(ele.toObject(), this);
|
|
|
|
|
else if(type=="Gif") element = EGif::create(ele.toObject(), this);
|
|
|
|
|
else if(type=="Movie") element = EVideo::create(ele.toObject(), this);
|
|
|
|
|
else if(type=="Audio") element = EAudio::create(ele.toObject(), this);
|
2023-04-18 14:14:46 +08:00
|
|
|
|
else if(type=="DClock") element = new EDClock(ele.toObject());
|
|
|
|
|
else if(type=="AClock") element = new EAClock(ele.toObject());
|
2022-08-25 18:37:24 +08:00
|
|
|
|
else if(type=="Temp") element = new EEnviron(ele.toObject());
|
|
|
|
|
else if(type=="Web") element = new EWeb(ele.toObject());
|
|
|
|
|
else if(type=="Timer") element = new ETimer(ele.toObject());
|
|
|
|
|
else if(type=="Window") element = new EMultiWin(ele.toObject(), this);
|
2023-04-18 14:14:46 +08:00
|
|
|
|
if(element) mScene->addItem(element);
|
2022-08-25 18:37:24 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新页属性参数到page.json
|
|
|
|
|
void PageListItem::updateJson() {
|
|
|
|
|
if(mAttrWgt==0) return; //没有点开该页面进行编辑
|
|
|
|
|
QJsonArray elements;
|
|
|
|
|
auto items = mScene->items();
|
|
|
|
|
foreach(auto item, items) {
|
|
|
|
|
auto element = static_cast<EBase*>(item);
|
|
|
|
|
if(element->mMultiWin == nullptr) elements.append(element->attrJson());
|
|
|
|
|
}
|
|
|
|
|
mAttr.insert("elements", elements);
|
|
|
|
|
|
|
|
|
|
QJsonArray audios;
|
|
|
|
|
auto cnt = mAudiosList->count();
|
|
|
|
|
for(int i=0; i<cnt; i++) {
|
|
|
|
|
auto info = mAudiosList->item(i)->data(Qt::UserRole).value<AudioInfo>();
|
|
|
|
|
audios.append(QJsonObject{
|
|
|
|
|
{"dir", info.dir},
|
|
|
|
|
{"name", info.name},
|
|
|
|
|
{"dur", info.dur},
|
|
|
|
|
{"vol", info.vol}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
mAttr.insert("audios", audios);
|
|
|
|
|
}
|
|
|
|
|
bool PageListItem::saveFiles() {
|
2022-10-27 15:07:45 +08:00
|
|
|
|
mPageDir = gProgItem->mProgDir + "/" + mAttr["name"].toString();
|
2022-08-25 18:37:24 +08:00
|
|
|
|
QDir pageQDir(mPageDir);
|
|
|
|
|
if(! pageQDir.exists() && ! pageQDir.mkpath(".")) return false;
|
|
|
|
|
|
|
|
|
|
QJsonArray elements;
|
|
|
|
|
auto items = mScene->items();
|
|
|
|
|
foreach(auto item, items) {
|
|
|
|
|
auto element = static_cast<EBase*>(item);
|
|
|
|
|
if(element->mMultiWin == nullptr && element->save(mPageDir)) elements.append(element->attrJson());
|
|
|
|
|
}
|
|
|
|
|
mAttr.insert("elements", elements);
|
|
|
|
|
if(mAttrWgt!=0) {
|
|
|
|
|
QJsonArray audios;
|
|
|
|
|
auto cnt = mAudiosList->count();
|
|
|
|
|
for(int i=0; i<cnt; i++) {
|
|
|
|
|
auto info = mAudiosList->item(i)->data(Qt::UserRole).value<AudioInfo>();
|
|
|
|
|
QString oldFile = info.dir + PAGEDEL_SUFFIX + "/" + info.name;
|
|
|
|
|
if(QFileInfo::exists(oldFile)) ;
|
|
|
|
|
else if(QFileInfo::exists(oldFile = info.dir + "/" + info.name)) ;
|
|
|
|
|
else continue;
|
|
|
|
|
QFile::copy(oldFile, mPageDir + "/" + info.name);
|
|
|
|
|
info.dir = mPageDir;
|
|
|
|
|
audios.append(QJsonObject{
|
|
|
|
|
{"dir", info.dir},
|
|
|
|
|
{"name", info.name},
|
|
|
|
|
{"dur", info.dur},
|
|
|
|
|
{"vol", info.vol}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
mAttr.insert("audios", audios);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QFile file(mPageDir + "/page.json");
|
|
|
|
|
if(! file.open(QIODevice::WriteOnly)) {
|
|
|
|
|
QMessageBox::critical(gMainWin, "Write Error", mPageDir + "/page.json "+file.errorString());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
file.write(QJsonDocument(mAttr).toJson());
|
|
|
|
|
file.close();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *PageListItem::itemWgt() {
|
|
|
|
|
auto wgtPage = new QWidget();
|
|
|
|
|
auto hBox = new QHBoxLayout(wgtPage);
|
|
|
|
|
mGraView = new QGraphicsView();
|
|
|
|
|
mGraView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
|
mGraView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
|
|
|
mGraView->setEnabled(false);
|
|
|
|
|
mGraView->setFrameShape(QFrame::NoFrame);
|
|
|
|
|
mGraView->setFixedSize(120, 60);
|
|
|
|
|
mGraView->setStyleSheet("QGraphicsView{background-color:transparent;}");
|
|
|
|
|
mGraView->setScene(mScene);
|
|
|
|
|
qreal scale = qMin(mGraView->width() / mScene->width(), mGraView->height() / mScene->height());
|
|
|
|
|
mGraView->scale(scale, scale);
|
|
|
|
|
hBox->addWidget(mGraView);
|
|
|
|
|
|
|
|
|
|
fdPlayTimes = new QLabel(QString::number(mAttr["repeat"].toInt()));
|
|
|
|
|
hBox->addWidget(fdPlayTimes);
|
|
|
|
|
|
|
|
|
|
hBox->addWidget(new QLabel(tr("times")));
|
|
|
|
|
hBox->addStretch();
|
|
|
|
|
return wgtPage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget *PageListItem::attrWgt() {
|
|
|
|
|
if(mAttrWgt!=0) return mAttrWgt;
|
|
|
|
|
mAttrWgt = new QWidget();
|
|
|
|
|
mAttrWgt->setStyleSheet(R"rrr(
|
|
|
|
|
QPushButton {
|
|
|
|
|
padding-left: 4px;
|
|
|
|
|
padding-right: 4px;
|
|
|
|
|
padding-top: 2px;
|
|
|
|
|
padding-bottom: 2px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
QPushButton:hover {
|
|
|
|
|
background-color: #dddddd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QPushButton#bnAddPlan {
|
2023-04-18 14:14:46 +08:00
|
|
|
|
image: url(:/res/program/AddPlan.png);
|
2022-08-25 18:37:24 +08:00
|
|
|
|
width: 24;
|
|
|
|
|
height: 24;
|
|
|
|
|
}
|
|
|
|
|
QPushButton#bnClearPlan {
|
2023-04-18 14:14:46 +08:00
|
|
|
|
image: url(:/res/program/Clean.png);
|
2022-08-25 18:37:24 +08:00
|
|
|
|
width: 24;
|
|
|
|
|
height: 24;
|
|
|
|
|
}
|
|
|
|
|
QPushButton#bnDel {
|
2023-04-18 14:14:46 +08:00
|
|
|
|
image: url(:/res/program/Delete.png);
|
2022-08-25 18:37:24 +08:00
|
|
|
|
width: 18;
|
|
|
|
|
height: 18;
|
|
|
|
|
}
|
|
|
|
|
QPushButton#bnAddPlan:pressed,
|
|
|
|
|
QPushButton#bnClearPlan:pressed,
|
|
|
|
|
QPushButton#bnDel:pressed {
|
|
|
|
|
margin-top: 1px;
|
|
|
|
|
margin-left: 1px;
|
|
|
|
|
margin-bottom: -1px;
|
|
|
|
|
margin-right: -1px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QPushButton[ssName="weeklySelector"] {
|
|
|
|
|
border: 1px solid #6A838F;
|
|
|
|
|
width: 24;
|
|
|
|
|
height: 24;
|
|
|
|
|
}
|
|
|
|
|
QPushButton[ssName="weeklySelector"]:checked {
|
|
|
|
|
background-color: #0099cc;
|
|
|
|
|
}
|
|
|
|
|
)rrr");
|
|
|
|
|
auto vBox = new QVBoxLayout(mAttrWgt);
|
|
|
|
|
vBox->setContentsMargins(6, 0, 6, 0);
|
|
|
|
|
vBox->setSpacing(4);
|
|
|
|
|
|
|
|
|
|
auto hBox = new QHBoxLayout();
|
|
|
|
|
auto lb1 = new QLabel(tr("Page name"));
|
|
|
|
|
lb1->setMinimumWidth(80);
|
|
|
|
|
hBox->addWidget(lb1);
|
|
|
|
|
|
|
|
|
|
auto fdPageName = new QLineEdit(mAttr["name"].toString());
|
|
|
|
|
connect(fdPageName, &QLineEdit::textEdited, this, [this, fdPageName](const QString &text) {
|
|
|
|
|
bool isDupli = false;
|
|
|
|
|
auto listWgt = listWidget();
|
|
|
|
|
if(nullptr != listWgt) {
|
|
|
|
|
int n = listWgt->count();
|
|
|
|
|
for(int i=0; i<n; i++) {
|
|
|
|
|
auto item = static_cast<PageListItem*>(listWgt->item(i));
|
|
|
|
|
if(text == item->mAttr["name"].toString()) {
|
|
|
|
|
isDupli = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(isDupli) {
|
|
|
|
|
QString newName = tr("New") + QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
|
|
|
|
|
mAttr["name"] = newName;
|
|
|
|
|
fdPageName->setText(newName);
|
|
|
|
|
} else mAttr["name"] = text;
|
|
|
|
|
});
|
|
|
|
|
hBox->addWidget(fdPageName);
|
|
|
|
|
|
|
|
|
|
vBox->addLayout(hBox);
|
|
|
|
|
|
|
|
|
|
hBox = new QHBoxLayout();
|
|
|
|
|
lb1 = new QLabel(tr("Play times"));
|
|
|
|
|
lb1->setMinimumWidth(80);
|
|
|
|
|
hBox->addWidget(lb1);
|
|
|
|
|
|
|
|
|
|
auto fdPlayTimes = new QSpinBox();
|
|
|
|
|
fdPlayTimes->setRange(1, 9999);
|
|
|
|
|
fdPlayTimes->setValue(mAttr["repeat"].toInt());
|
|
|
|
|
connect(fdPlayTimes, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
|
|
|
|
|
mAttr["repeat"] = value;
|
|
|
|
|
this->fdPlayTimes->setText(QString::number(value));
|
|
|
|
|
});
|
|
|
|
|
hBox->addWidget(fdPlayTimes);
|
2023-04-18 14:14:46 +08:00
|
|
|
|
hBox->addSpacing(20);
|
|
|
|
|
|
|
|
|
|
auto fdLoop = new QCheckBox(tr("Sources Repeat"));
|
|
|
|
|
fdLoop->setChecked(mAttr["loop"].toBool());
|
|
|
|
|
connect(fdLoop, &QCheckBox::toggled, this, [this](bool checked) {
|
|
|
|
|
mAttr["loop"] = checked;
|
|
|
|
|
});
|
|
|
|
|
hBox->addWidget(fdLoop);
|
|
|
|
|
|
2022-08-25 18:37:24 +08:00
|
|
|
|
hBox->addStretch();
|
|
|
|
|
|
|
|
|
|
vBox->addLayout(hBox);
|
|
|
|
|
|
|
|
|
|
auto line = new QFrame();
|
|
|
|
|
line->setFrameShape(QFrame::HLine);
|
|
|
|
|
line->setFrameShadow(QFrame::Sunken);
|
|
|
|
|
vBox->addWidget(line);
|
|
|
|
|
|
|
|
|
|
hBox = new QHBoxLayout();
|
|
|
|
|
auto lb = new QLabel();
|
2023-04-18 14:14:46 +08:00
|
|
|
|
lb->setPixmap(QPixmap(":/res/program/Audio.png").scaledToHeight(24, Qt::SmoothTransformation));
|
2022-08-25 18:37:24 +08:00
|
|
|
|
hBox->addWidget(lb);
|
|
|
|
|
hBox->addWidget(new QLabel(tr("Audios")));
|
|
|
|
|
hBox->addStretch();
|
|
|
|
|
|
|
|
|
|
hBox->addWidget(new QLabel(tr("Total Dur")));
|
|
|
|
|
auto fdTtlDur = new QLabel("0");
|
|
|
|
|
hBox->addWidget(fdTtlDur);
|
|
|
|
|
hBox->addWidget(new QLabel(tr("s")));
|
|
|
|
|
hBox->addStretch();
|
|
|
|
|
|
|
|
|
|
auto btnAdd = new QPushButton();
|
2023-04-18 14:14:46 +08:00
|
|
|
|
btnAdd->setIcon(QIcon(":/res/program/Add.png"));
|
2022-08-25 18:37:24 +08:00
|
|
|
|
btnAdd->setProperty("style","multiTool");
|
|
|
|
|
|
|
|
|
|
mAudiosList = new QListWidget();
|
|
|
|
|
connect(btnAdd, &QPushButton::clicked, this, [this, fdTtlDur] {
|
2022-09-13 23:16:36 +08:00
|
|
|
|
auto files = QFileDialog::getOpenFileNames(gMainWin, tr("Select File"), gFileHome, EAudio::filters());
|
2022-08-25 18:37:24 +08:00
|
|
|
|
int durs = fdTtlDur->text().toInt();
|
|
|
|
|
for(int i=0; i<files.count(); i++) {
|
|
|
|
|
int64_t dur;
|
2023-04-18 14:14:46 +08:00
|
|
|
|
QString err = audioInfo(files[i].toUtf8(), &dur);
|
2022-08-25 18:37:24 +08:00
|
|
|
|
if(! err.isEmpty()) {
|
|
|
|
|
QMessageBox::critical(gMainWin, "Audio Error", err+"\n"+files[i]);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
QFileInfo fInfo(files[i]);
|
|
|
|
|
AudioInfo info{fInfo.absolutePath(), fInfo.fileName(), (int)(dur/1000000)};
|
2023-04-18 14:14:46 +08:00
|
|
|
|
auto item = new QListWidgetItem(QIcon(":/res/program/Audio.png"), info.name);
|
2022-08-25 18:37:24 +08:00
|
|
|
|
item->setData(Qt::UserRole, QVariant::fromValue(info));
|
|
|
|
|
mAudiosList->addItem(item);
|
|
|
|
|
if(i == files.count()-1) {
|
|
|
|
|
mAudiosList->setCurrentItem(item);
|
2022-09-13 23:16:36 +08:00
|
|
|
|
gFileHome = fInfo.absolutePath();
|
2022-08-25 18:37:24 +08:00
|
|
|
|
}
|
|
|
|
|
durs += info.dur;
|
|
|
|
|
mAudiosList->addItem(item);
|
|
|
|
|
}
|
|
|
|
|
fdTtlDur->setText(QString::number(durs));
|
|
|
|
|
});
|
|
|
|
|
hBox->addWidget(btnAdd);
|
|
|
|
|
|
|
|
|
|
auto btnDel = new QPushButton();
|
2023-04-18 14:14:46 +08:00
|
|
|
|
btnDel->setIcon(QIcon(":/res/program/Delete.png"));
|
2022-08-25 18:37:24 +08:00
|
|
|
|
btnDel->setProperty("style","multiTool");
|
|
|
|
|
connect(btnDel, &QPushButton::clicked, this, [this, fdTtlDur] {
|
|
|
|
|
auto row = mAudiosList->currentRow();
|
|
|
|
|
if(row < 0) return;
|
|
|
|
|
int durs = fdTtlDur->text().toInt();
|
|
|
|
|
auto item = mAudiosList->takeItem(row);
|
|
|
|
|
auto info = static_cast<AudioInfo>(item->data(Qt::UserRole).value<AudioInfo>());
|
|
|
|
|
durs -= info.dur;
|
|
|
|
|
delete item;
|
|
|
|
|
fdTtlDur->setText(QString::number(durs));
|
|
|
|
|
});
|
|
|
|
|
hBox->addWidget(btnDel);
|
|
|
|
|
|
|
|
|
|
auto btnGoUp = new QPushButton();
|
2023-04-18 14:14:46 +08:00
|
|
|
|
btnGoUp->setIcon(QIcon(":/res/program/GoUp.png"));
|
2022-08-25 18:37:24 +08:00
|
|
|
|
btnGoUp->setProperty("style","multiTool");
|
|
|
|
|
connect(btnGoUp, &QPushButton::clicked, this, [this] {
|
|
|
|
|
int row = mAudiosList->currentRow();
|
|
|
|
|
if(row < 1) return;
|
|
|
|
|
mAudiosList->insertItem(row-1, mAudiosList->takeItem(row));
|
|
|
|
|
mAudiosList->setCurrentRow(row-1);
|
|
|
|
|
});
|
|
|
|
|
hBox->addWidget(btnGoUp);
|
|
|
|
|
|
|
|
|
|
auto btnGoDown = new QPushButton();
|
2023-04-18 14:14:46 +08:00
|
|
|
|
btnGoDown->setIcon(QIcon(":/res/program/GoDown.png"));
|
2022-08-25 18:37:24 +08:00
|
|
|
|
btnGoDown->setProperty("style","multiTool");
|
|
|
|
|
connect(btnGoDown, &QPushButton::clicked, this, [this] {
|
|
|
|
|
int row = mAudiosList->currentRow();
|
|
|
|
|
if(row < 0 || row > mAudiosList->count() - 2) return;
|
|
|
|
|
mAudiosList->insertItem(row+1, mAudiosList->takeItem(row));
|
|
|
|
|
mAudiosList->setCurrentRow(row+1);
|
|
|
|
|
});
|
|
|
|
|
hBox->addWidget(btnGoDown);
|
|
|
|
|
|
|
|
|
|
vBox->addLayout(hBox);
|
|
|
|
|
|
|
|
|
|
mAudiosList->setMinimumHeight(120);
|
|
|
|
|
mAudiosList->setIconSize(QSize(20, 20));
|
|
|
|
|
vBox->addWidget(mAudiosList, 1);
|
|
|
|
|
|
|
|
|
|
auto audios = mAttr["audios"].toArray();
|
|
|
|
|
int durs = 0;
|
|
|
|
|
foreach(auto audio, audios) {
|
|
|
|
|
AudioInfo info{audio["dir"].toString(), audio["name"].toString(), audio["dur"].toInt(), audio["vol"].toInt()};
|
|
|
|
|
if(info.dir.isEmpty() || info.name.isEmpty() || info.dur==0) continue;
|
2023-04-18 14:14:46 +08:00
|
|
|
|
auto item = new QListWidgetItem(QIcon(":/res/program/Audio.png"), info.name);
|
2022-08-25 18:37:24 +08:00
|
|
|
|
item->setData(Qt::UserRole, QVariant::fromValue(info));
|
|
|
|
|
durs += info.dur;
|
|
|
|
|
mAudiosList->addItem(item);
|
|
|
|
|
}
|
|
|
|
|
fdTtlDur->setText(QString::number(durs));
|
|
|
|
|
|
|
|
|
|
auto wgtAudioInfo = new QWidget();
|
|
|
|
|
wgtAudioInfo->hide();
|
|
|
|
|
hBox = new QHBoxLayout(wgtAudioInfo);
|
|
|
|
|
hBox->setContentsMargins(0,0,0,0);
|
|
|
|
|
hBox->setSpacing(2);
|
|
|
|
|
|
|
|
|
|
hBox->addWidget(new QLabel(tr("Duration")));
|
|
|
|
|
hBox->addSpacing(4);
|
|
|
|
|
|
|
|
|
|
auto fdAudioDur = new QLabel("0");
|
|
|
|
|
hBox->addWidget(fdAudioDur);
|
|
|
|
|
hBox->addWidget(new QLabel(tr("s")));
|
|
|
|
|
|
|
|
|
|
hBox->addStretch();
|
|
|
|
|
hBox->addWidget(new QLabel(tr("Vol")));
|
|
|
|
|
|
|
|
|
|
auto fdVol = new QSlider(Qt::Horizontal);
|
|
|
|
|
fdVol->setMaximum(100);
|
|
|
|
|
fdVol->setMinimumWidth(120);
|
|
|
|
|
hBox->addWidget(fdVol);
|
|
|
|
|
|
|
|
|
|
auto fdAudioVol = new QLabel("0");
|
|
|
|
|
fdAudioVol->setAlignment(Qt::AlignRight);
|
|
|
|
|
fdAudioVol->setFixedWidth(38);
|
|
|
|
|
hBox->addWidget(fdAudioVol);
|
|
|
|
|
|
|
|
|
|
vBox->addWidget(wgtAudioInfo);
|
|
|
|
|
|
|
|
|
|
connect(fdVol, &QSlider::valueChanged, this, [this, fdAudioVol](int value) {
|
|
|
|
|
fdAudioVol->setText(QString::number(value)+"%");
|
|
|
|
|
auto item = mAudiosList->currentItem();
|
|
|
|
|
if(item==nullptr) return;
|
|
|
|
|
auto info = static_cast<AudioInfo>(item->data(Qt::UserRole).value<AudioInfo>());
|
|
|
|
|
info.vol = value;
|
|
|
|
|
item->setData(Qt::UserRole, QVariant::fromValue(info));
|
|
|
|
|
});
|
|
|
|
|
connect(mAudiosList, &QListWidget::currentItemChanged, this, [fdAudioDur, wgtAudioInfo, fdVol, fdAudioVol](QListWidgetItem *current, QListWidgetItem *) {
|
|
|
|
|
if(current==nullptr) {
|
|
|
|
|
wgtAudioInfo->hide();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
wgtAudioInfo->show();
|
|
|
|
|
auto info = static_cast<AudioInfo>(current->data(Qt::UserRole).value<AudioInfo>());
|
|
|
|
|
fdAudioDur->setText(QString::number(info.dur));
|
|
|
|
|
fdVol->setValue(info.vol);
|
|
|
|
|
fdAudioVol->setText(QString::number(info.vol)+"%");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
line = new QFrame();
|
|
|
|
|
line->setFrameShape(QFrame::HLine);
|
|
|
|
|
line->setFrameShadow(QFrame::Sunken);
|
|
|
|
|
vBox->addWidget(line);
|
|
|
|
|
|
|
|
|
|
QJsonValue validDate = mAttr["validDate"];
|
|
|
|
|
|
|
|
|
|
auto wValidDate = new QCheckBox(tr("Valid Date"));
|
|
|
|
|
bool isDateValid = validDate["isValid"].toBool();
|
|
|
|
|
wValidDate->setChecked(isDateValid);
|
|
|
|
|
vBox->addWidget(wValidDate);
|
|
|
|
|
|
|
|
|
|
hBox = new QHBoxLayout();
|
|
|
|
|
|
|
|
|
|
auto fdStart = new QDateEdit();
|
|
|
|
|
fdStart->setDisplayFormat("yyyy-MM-dd");
|
|
|
|
|
fdStart->setEnabled(isDateValid);
|
|
|
|
|
fdStart->setDate(QDate::fromString(validDate["start"].toString(), "yyyy-MM-dd"));
|
|
|
|
|
hBox->addWidget(fdStart);
|
|
|
|
|
|
|
|
|
|
auto bnDateStart = new LoDateSelector();
|
|
|
|
|
bnDateStart->setEnabled(isDateValid);
|
|
|
|
|
connect(bnDateStart, &LoDateSelector::sDateSelected, fdStart, &QDateEdit::setDate);
|
|
|
|
|
hBox->addWidget(bnDateStart);
|
|
|
|
|
|
|
|
|
|
hBox->addWidget(new QLabel("~"));
|
|
|
|
|
|
|
|
|
|
auto fdEnd = new QDateEdit();
|
|
|
|
|
fdEnd->setDisplayFormat("yyyy-MM-dd");
|
|
|
|
|
fdEnd->setEnabled(isDateValid);
|
|
|
|
|
fdEnd->setDate(QDate::fromString(validDate["end"].toString(), "yyyy-MM-dd"));
|
|
|
|
|
connect(fdStart, &QDateEdit::dateChanged, this, [this, wValidDate, fdStart, fdEnd](const QDate &date) {
|
|
|
|
|
auto end = fdEnd->date();
|
|
|
|
|
if(! date.isValid() || date > end) {
|
|
|
|
|
QMessageBox::warning(gMainWin, tr("Warning"), tr("Start Time can't be later than End Time"));
|
|
|
|
|
fdStart->setDate(end);
|
|
|
|
|
}
|
|
|
|
|
mAttr["validDate"] = QJsonObject{
|
|
|
|
|
{"isValid", wValidDate->isChecked()},
|
|
|
|
|
{"start", fdStart->date().toString("yyyy-MM-dd")},
|
|
|
|
|
{"end", end.toString("yyyy-MM-dd")}
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
connect(fdEnd, &QDateEdit::dateChanged, this, [this, wValidDate, fdStart, fdEnd](const QDate &date) {
|
|
|
|
|
QDate start = fdStart->date();
|
|
|
|
|
if(! date.isValid() || start > date) {
|
|
|
|
|
QMessageBox::warning(gMainWin, tr("Warning"), tr("End Time can't be earlier than Start Time"));
|
|
|
|
|
fdEnd->setDate(start);
|
|
|
|
|
}
|
|
|
|
|
mAttr["validDate"] = QJsonObject{
|
|
|
|
|
{"isValid", wValidDate->isChecked()},
|
|
|
|
|
{"start", start.toString("yyyy-MM-dd")},
|
|
|
|
|
{"end", fdEnd->date().toString("yyyy-MM-dd")}
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
hBox->addWidget(fdEnd);
|
|
|
|
|
|
|
|
|
|
auto bnDateEnd = new LoDateSelector();
|
|
|
|
|
bnDateEnd->setEnabled(isDateValid);
|
|
|
|
|
connect(bnDateEnd, &LoDateSelector::sDateSelected, fdEnd, &QDateEdit::setDate);
|
|
|
|
|
hBox->addWidget(bnDateEnd);
|
|
|
|
|
|
|
|
|
|
hBox->addStretch();
|
|
|
|
|
|
|
|
|
|
connect(wValidDate, &QCheckBox::toggled, this, [this, fdStart, fdEnd, bnDateStart, bnDateEnd](bool checked) {
|
|
|
|
|
fdStart->setEnabled(checked);
|
|
|
|
|
fdEnd->setEnabled(checked);
|
|
|
|
|
bnDateStart->setEnabled(checked);
|
|
|
|
|
bnDateEnd->setEnabled(checked);
|
|
|
|
|
mAttr["validDate"] = QJsonObject{
|
|
|
|
|
{"isValid", checked},
|
|
|
|
|
{"start", fdStart->date().toString("yyyy-MM-dd")},
|
|
|
|
|
{"end", fdEnd->date().toString("yyyy-MM-dd")}
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
vBox->addLayout(hBox);
|
|
|
|
|
|
|
|
|
|
line = new QFrame();
|
|
|
|
|
line->setFrameShape(QFrame::HLine);
|
|
|
|
|
line->setFrameShadow(QFrame::Sunken);
|
|
|
|
|
vBox->addWidget(line);
|
|
|
|
|
|
|
|
|
|
hBox = new QHBoxLayout();
|
|
|
|
|
hBox->setSpacing(12);
|
|
|
|
|
hBox->addWidget(new QLabel(tr("Plan")));
|
|
|
|
|
|
|
|
|
|
hBox->addStretch();
|
|
|
|
|
|
|
|
|
|
auto bnAddPlan = new QPushButton();
|
|
|
|
|
bnAddPlan->setObjectName("bnAddPlan");
|
|
|
|
|
hBox->addWidget(bnAddPlan);
|
|
|
|
|
|
|
|
|
|
auto bnClearPlan = new QPushButton();
|
|
|
|
|
bnClearPlan->setObjectName("bnClearPlan");
|
|
|
|
|
hBox->addWidget(bnClearPlan);
|
|
|
|
|
|
|
|
|
|
vBox->addLayout(hBox);
|
|
|
|
|
|
|
|
|
|
auto wPlans = new wPlanList();
|
|
|
|
|
wPlans->setStyleSheet(R"rrr(
|
|
|
|
|
QListWidget::item {
|
|
|
|
|
height: 100;
|
|
|
|
|
border-top: 1px solid #6A838F;
|
|
|
|
|
margin-right: 9px;
|
|
|
|
|
})rrr");
|
|
|
|
|
|
|
|
|
|
wPlans->onRestorePlan(mAttr["plans"].toArray());
|
|
|
|
|
connect(bnAddPlan, &QPushButton::clicked, wPlans, &wPlanList::onAddPlan);
|
|
|
|
|
connect(bnClearPlan, &QPushButton::clicked, wPlans, &wPlanList::clear);
|
|
|
|
|
connect(wPlans, &QListWidget::itemChanged, this, [this, wPlans] {
|
|
|
|
|
mAttr["plans"] = wPlans->plansJson();
|
|
|
|
|
});
|
|
|
|
|
vBox->addWidget(wPlans, 2);
|
|
|
|
|
return mAttrWgt;
|
|
|
|
|
}
|