qt/LedOK/program/progeditorwin.cpp

777 lines
32 KiB
C++
Raw Normal View History

2022-08-25 18:37:24 +08:00
#include "progeditorwin.h"
#include "ebase.h"
#include "pagelistitem.h"
#include "player/playwin.h"
#include "tools.h"
2024-08-07 18:18:37 +08:00
#include "main.h"
2023-09-19 11:49:20 +08:00
#include "gutil/qwaitingdlg.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/egif.h"
#include "program/edclock.h"
#include "program/eaclock.h"
#include "program/eenviron.h"
#include "program/eweb.h"
#include "program/etimer.h"
2024-08-07 18:18:37 +08:00
#include "program/etimer2.h"
2023-04-18 14:14:46 +08:00
#include "program/emultiwin.h"
#include "program/gentmpthread.h"
#include "program/sendprogramdialog.h"
2022-08-25 18:37:24 +08:00
#include <QCloseEvent>
#include <QGraphicsDropShadowEffect>
#include <QInputDialog>
#include <QMessageBox>
#include <QSettings>
#include <QToolBar>
#include <QUdpSocket>
2023-05-08 09:59:15 +08:00
#include <QMovie>
2022-08-25 18:37:24 +08:00
2022-10-27 15:07:45 +08:00
ProgItem *gProgItem{0};
2022-08-25 18:37:24 +08:00
2023-04-28 16:02:14 +08:00
ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(parent), mProgItem(progItem) {
2022-10-27 15:07:45 +08:00
gProgItem = progItem;
2023-04-28 16:02:14 +08:00
setWindowFlag(Qt::Window);
2023-05-11 11:47:00 +08:00
setWindowTitle(progItem->mName);
2023-05-09 15:08:39 +08:00
setAttribute(Qt::WA_DeleteOnClose);
2023-05-11 11:47:00 +08:00
setAttribute(Qt::WA_AlwaysShowToolTips);
auto parentWin = parentWidget()->window();
if(! parentWin->isMaximized()) resize(parentWin->size());
2023-05-09 15:08:39 +08:00
else resize(1280, 720);
#ifdef Q_OS_WIN
2023-04-28 16:02:14 +08:00
setWindowModality(Qt::WindowModal);
#else
2023-05-11 11:47:00 +08:00
parentWin->hide();
2023-04-28 16:02:14 +08:00
#endif
2022-08-25 18:37:24 +08:00
2023-04-24 15:02:08 +08:00
auto vBox = new QVBoxLayout(this);
2022-08-25 18:37:24 +08:00
vBox->setContentsMargins(0, 0, 0, 0);
vBox->setSpacing(0);
auto toolBar = new QToolBar();
toolBar->setFloatable(false);
toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
toolBar->setIconSize(QSize(46, 40));
2023-04-18 14:14:46 +08:00
auto action = new QAction(QIcon(":/res/program/Save.png"), tr("Save"));
2022-08-25 18:37:24 +08:00
connect(action, &QAction::triggered, this, &ProgEditorWin::onSave);
toolBar->addAction(action);
2023-05-11 11:47:00 +08:00
// action = new QAction(QIcon(":/res/program/SaveAs.png"), tr("Save as"));
// connect(action, &QAction::triggered, this, [this] {
// auto saveThread = QThread::create([this](){
// save();
// });
// connect(saveThread, SIGNAL(finished()), saveThread, SLOT(deleteLater()));
// connect(saveThread, &QThread::finished, this, [this] {
// mProgItem->onSetProgram();
// });
// saveThread->start();
// bool isOK;
// QString progName = QInputDialog::getText(this, tr("Save as"), tr("Save as"), QLineEdit::Normal, QString(), &isOK, Qt::Dialog | Qt::WindowCloseButtonHint);
// if(! isOK || progName.isEmpty()) return;
// mProgItem->mProgDir = mProgItem->mProgsDir + "/" + progName;
// LoEmptyDialog *dlgTip = new LoEmptyDialog(this);
// saveThread = QThread::create([this](){
// save();
// });
// dlgTip->lock(tr("Saving..."),tr("Success"),tr("Save failed"));
// connect(saveThread, SIGNAL(finished()), dlgTip, SLOT(unlock()));//显示正在保存提示对话框
// connect(saveThread, SIGNAL(finished()), saveThread, SLOT(deleteLater()));
// connect(saveThread, &QThread::finished, this, [this] {
// mProgItem->onSetProgram();
// });
// saveThread->start();
// dlgTip->exec();
// close();
// setWindowTitle(progName);
// mProgItem->mProgPanel->onCreateNewProgramOnOpenEditProgramWidget(progName, QSize(mProgItem->mWidth, mProgItem->mHeight), mProgItem->mRemark, mProgItem->mSplitWidths, mProgItem->mMaxWidth);
2024-02-21 18:08:50 +08:00
// void ProgPanel::onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize res, QString remarks, QList<int> &partLengths, int max)
// {
// if(checkIfNameRepeated(name)) return;
// auto item = new ProgItem(mProgsDir, name, res.width(), res.height(), remarks, partLengths, max, mProgTree);
// item->save();//保存pro.json
// if(mProgTree->fdCheckAll->checkState()==Qt::Checked) {
// mProgTree->fdCheckAll->blockSignals(true);
// mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked);
// mProgTree->fdCheckAll->blockSignals(false);
// }
// auto editor = new ProgEditorWin(item, this);
// editor->show();
// }
2023-05-11 11:47:00 +08:00
// });
// toolBar->addAction(action);
2023-04-18 14:14:46 +08:00
action = new QAction(QIcon(":/res/program/Setting.png"), tr("Setting"));
2023-05-17 17:36:18 +08:00
connect(action, &QAction::triggered, this, [this] {
2023-04-18 14:14:46 +08:00
QString widthsStr;
2024-02-21 18:08:50 +08:00
for(auto &width : mProgItem->partLens) {
2023-04-18 14:14:46 +08:00
if(! widthsStr.isEmpty()) widthsStr.append(" ");
widthsStr.append(QString::number(width));
}
2024-02-21 18:08:50 +08:00
ProgCreateDlg dlg(mProgItem->mName, mProgItem->mWidth, mProgItem->mHeight, mProgItem->mRemark, widthsStr, mProgItem->isVer, this);
2024-08-19 16:10:49 +08:00
dlg.edIsInsert->setChecked(mProgItem->isInsert);
2022-09-30 18:08:39 +08:00
if(dlg.exec() != QDialog::Accepted) return;
2022-10-27 15:07:45 +08:00
mProgItem->mWidth = dlg.fdWidth->value();
mProgItem->mHeight = dlg.fdHeight->value();
2023-04-18 14:14:46 +08:00
mProgItem->mRemark = dlg.fdRemark->toPlainText();
2024-08-19 16:10:49 +08:00
mProgItem->isInsert = dlg.edIsInsert->isChecked();
2024-02-21 18:08:50 +08:00
mProgItem->partLens.clear();
mProgItem->maxLen = 0;
mProgItem->isVer = dlg.fdVer->isChecked();
auto len = mProgItem->isVer ? mProgItem->mHeight : mProgItem->mWidth;
2023-10-23 11:44:22 +08:00
if(dlg.fdIsUltraLong->isChecked()) {
2024-02-21 18:08:50 +08:00
auto partLengths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts);
2023-10-23 11:44:22 +08:00
int ttl = 0;
2024-02-21 18:08:50 +08:00
for(auto &partLength : partLengths) {
int val = partLength.toInt();
2023-10-23 11:44:22 +08:00
if(val==0) continue;
2024-02-21 18:08:50 +08:00
if(mProgItem->maxLen < val) mProgItem->maxLen = val;
2023-10-23 11:44:22 +08:00
ttl += val;
2024-02-21 18:08:50 +08:00
mProgItem->partLens.emplace_back(val);
if(ttl>=len) break;
2023-10-23 11:44:22 +08:00
}
2024-02-21 18:08:50 +08:00
if(mProgItem->maxLen) {
while(ttl < len) {
mProgItem->partLens.push_back(mProgItem->maxLen);
ttl += mProgItem->maxLen;
2023-10-23 11:44:22 +08:00
}
2024-02-21 18:08:50 +08:00
if(ttl > len) mProgItem->partLens.back() -= ttl - len;
2023-04-18 14:14:46 +08:00
}
}
mProgItem->onSetProgram();
2023-10-23 11:44:22 +08:00
for(int i=0; i<listPage->count(); i++) {
2023-06-20 08:49:01 +08:00
auto page = (PageListItem*) listPage->item(i);
2022-10-27 15:07:45 +08:00
page->mScene->setSceneRect(0, 0, mProgItem->mWidth, mProgItem->mHeight);
2022-09-30 18:08:39 +08:00
page->mGraView->resetTransform();
qreal scale = qMin(page->mGraView->width() / page->mScene->width(), page->mGraView->height() / page->mScene->height());
page->mGraView->scale(scale, scale);
2022-08-25 18:37:24 +08:00
2022-09-30 18:08:39 +08:00
auto items = page->mScene->items();
2023-10-23 11:44:22 +08:00
for(auto item : items) {
auto element = (EBase*) item;
2023-04-18 14:14:46 +08:00
if(element->mMultiWin == 0) element->fitProgSize();
2022-08-25 18:37:24 +08:00
}
2022-09-30 18:08:39 +08:00
page->mScene->update();
}
2023-04-18 14:14:46 +08:00
onSave();
2022-08-25 18:37:24 +08:00
});
toolBar->addAction(action);
toolBar->addSeparator();
2024-02-21 18:08:50 +08:00
if(progItem->partLens.empty()) {
2023-04-18 14:14:46 +08:00
action = new QAction(QIcon(":/res/program/Window.png"), tr("MuliContentWindow"));
2022-10-27 15:07:45 +08:00
action->setToolTip(tr("In this window, a plurality of different program materials can be added and played according to the order of joining the list;"));
action->setData(EBase::Window);
toolBar->addAction(action);
toolBar->addSeparator();
}
2023-04-18 14:14:46 +08:00
action = new QAction(QIcon(":/res/program/Text.png"), tr("Text"));
action->setData(EBase::Text);
toolBar->addAction(action);
action = new QAction(QIcon(":/res/program/Photo.png"), tr("Photo"));
2024-02-21 18:08:50 +08:00
action->setData(EBase::Image);
2022-08-25 18:37:24 +08:00
toolBar->addAction(action);
2023-04-18 14:14:46 +08:00
action = new QAction(QIcon(":/res/program/Movie.png"), tr("Video"));
2022-08-25 18:37:24 +08:00
action->setData(EBase::Video);
toolBar->addAction(action);
2024-02-21 18:08:50 +08:00
action = new QAction(QIcon(":/res/program/Gif.png"), tr("Gif"));
action->setData(EBase::Gif);
toolBar->addAction(action);
action = new QAction(QIcon(":/res/program/DClock.png"), tr("Clock"));
action->setData(EBase::DClock);
toolBar->addAction(action);
action = new QAction(QIcon(":/res/program/AClock.png"), tr("Analog Clock"));
action->setData(EBase::AClock);
toolBar->addAction(action);
action = new QAction(QIcon(":/res/program/Temp.png"), tr("Environment"));
action->setData(EBase::Environ);
toolBar->addAction(action);
action = new QAction(QIcon(":/res/program/Web.png"), tr("Web"));
action->setData(EBase::Web);
toolBar->addAction(action);
action = new QAction(QIcon(":/res/program/Timer.png"), tr("Timer"));
action->setData(EBase::Timer);
toolBar->addAction(action);
2024-08-07 18:18:37 +08:00
action = new QAction(QIcon(":/res/program/Timer.png"), tr("Timer")+"2");
action->setData(EBase::Timer2);
toolBar->addAction(action);
2023-10-23 11:44:22 +08:00
action = new QAction(QIcon(":/res/program/demo-video.png"), tr("Demos"));
2023-05-17 17:36:18 +08:00
connect(action, &QAction::triggered, this, [this] {
2024-08-13 19:47:06 +08:00
auto file = QFileDialog::getOpenFileName(this, tr("Open Demo"), QApplication::applicationDirPath()+"/Demos");
2023-10-23 11:44:22 +08:00
if(file.isEmpty()) return;
2023-05-17 17:36:18 +08:00
auto scene = mPageEditor->graphicsView->scene();
if(scene==0) return;
2023-10-23 11:44:22 +08:00
if(file.endsWith("png", Qt::CaseInsensitive)) {
auto ePhoto = EPhoto::create(file, mPageItem);
if(ePhoto==0) return;
auto rect = Tools::centerRect(ePhoto->img.width(), ePhoto->img.height(), mProgItem->mWidth, mProgItem->mHeight);
ePhoto->setPos(rect.topLeft());
ePhoto->setSize(rect.width(), rect.height());
ePhoto->setZValue(mPageEditor->sortedEles().count());
scene->addItem(ePhoto);
auto sels = scene->selectedItems();
if(sels.count() == 1) sels.at(0)->setSelected(false);
ePhoto->setSelected(true);
} else {
auto eVideo = EVideo::create(file, mPageItem);
if(eVideo==0) return;
auto rect = Tools::centerRect(eVideo->mCoverImg.width(), eVideo->mCoverImg.height(), mProgItem->mWidth, mProgItem->mHeight);
eVideo->setPos(rect.topLeft());
eVideo->setSize(rect.width(), rect.height());
eVideo->setZValue(mPageEditor->sortedEles().count());
scene->addItem(eVideo);
auto sels = scene->selectedItems();
if(sels.count() == 1) sels.at(0)->setSelected(false);
eVideo->setSelected(true);
}
2023-05-17 17:36:18 +08:00
});
toolBar->addAction(action);
2022-10-27 15:07:45 +08:00
2022-08-25 18:37:24 +08:00
toolBar->addSeparator();
2023-04-18 14:14:46 +08:00
action = new QAction(QIcon(":/res/program/preview.png"), tr("Play")+"/"+tr("Stop"));
2022-08-25 18:37:24 +08:00
connect(action, &QAction::triggered, this, [this] {
2023-08-01 11:42:41 +08:00
if(PlayWin::self) PlayWin::self->close();
2022-08-25 18:37:24 +08:00
else {
if(isProgChanged()) onSave();
2023-04-18 14:14:46 +08:00
auto waitingDlg = new WaitingDlg(this, tr("Generate preview data")+" ...");
2023-05-11 11:47:00 +08:00
auto gen = new GenTmpThread(mProgItem, mProgItem->mName, "", "");
connect(gen, &GenTmpThread::onErr, this, [=](QString err) {
QMessageBox::warning(this, "GenTmpThread Error", err);
});
connect(gen, &QThread::finished, waitingDlg, &WaitingDlg::close);
gen->start();
2023-04-18 14:14:46 +08:00
waitingDlg->exec();
2022-10-27 15:07:45 +08:00
QFile file(mProgItem->mProgDir+"_tmp/program");
2022-08-25 18:37:24 +08:00
if(! file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
2023-10-23 11:44:22 +08:00
auto value = file.readAll();
2022-08-25 18:37:24 +08:00
file.close();
2023-10-23 11:44:22 +08:00
QString jsErr;
auto prog = JFrom(value, &jsErr);
if(! jsErr.isEmpty()) return;
2022-10-27 15:07:45 +08:00
int www = mProgItem->mWidth, hhh = mProgItem->mHeight;
2024-02-21 18:08:50 +08:00
if(mProgItem->maxLen) {
if(mProgItem->isVer) {
hhh = mProgItem->maxLen;
www *= mProgItem->partLens.size();
} else {
www = mProgItem->maxLen;
hhh *= mProgItem->partLens.size();
}
2022-10-27 15:07:45 +08:00
}
PlayWin::self = PlayWin::newIns(www, hhh, mProgItem->mProgDir+"_tmp", prog);
2022-08-25 18:37:24 +08:00
}
});
toolBar->addAction(action);
2023-04-18 14:14:46 +08:00
action = new QAction(QIcon(":/res/program/Send.png"), tr("Publish"));
2022-08-25 18:37:24 +08:00
connect(action, &QAction::triggered, this, [this]{
onSave();
2023-04-18 14:14:46 +08:00
auto waitingDlg = new WaitingDlg(this, tr("Convertering")+" ...");
2023-05-11 11:47:00 +08:00
auto gen = new GenTmpThread(mProgItem, mProgItem->mName, "", "");
connect(gen, &GenTmpThread::onErr, this, [=](QString err) {
QMessageBox::warning(this, "GenTmpThread Error", err);
});
connect(gen, &QThread::finished, waitingDlg, &WaitingDlg::close);
gen->start();
2022-10-27 15:07:45 +08:00
waitingDlg->exec();
2023-04-18 14:14:46 +08:00
SendProgramDialog dlg(mProgItem->mName, this);
dlg.exec();
2022-08-25 18:37:24 +08:00
});
toolBar->addAction(action);
connect(toolBar, &QToolBar::actionTriggered, this, [this](QAction *act) {
auto data = act->data();
if(data.type()!=QVariant::Int) return;
2023-05-09 15:08:39 +08:00
auto scene = mPageEditor->graphicsView->scene();
if(scene==0) return;
int order = mPageEditor->sortedEles().count();
EBase *element = 0;
2022-10-27 15:07:45 +08:00
int iNewWidth = mProgItem->mWidth;
int iNewHeight = mProgItem->mHeight;
2022-08-25 18:37:24 +08:00
if(iNewWidth>128) iNewWidth = iNewWidth * 2 / 3;
if(iNewHeight>128) iNewHeight = iNewHeight * 2 / 3;
2022-10-27 15:07:45 +08:00
if(mNewEleX+iNewWidth>mProgItem->mWidth) mNewEleX=0;
if(mNewEleY+iNewHeight>mProgItem->mHeight) mNewEleY=0;
2022-08-25 18:37:24 +08:00
auto type = data.toInt();
2024-02-21 18:08:50 +08:00
if(type==EBase::Image) {
2022-09-13 23:16:36 +08:00
auto files = QFileDialog::getOpenFileNames(this, tr("Select File"), gFileHome, EPhoto::filters());
2022-08-25 18:37:24 +08:00
for(int i=0; i<files.count(); i++) {
auto ePhoto = EPhoto::create(files[i], mPageItem);
2023-04-25 16:30:58 +08:00
if(ePhoto==0) continue;
2022-10-27 15:07:45 +08:00
auto rect = Tools::centerRect(ePhoto->img.width(), ePhoto->img.height(), mProgItem->mWidth, mProgItem->mHeight);
2022-08-25 18:37:24 +08:00
ePhoto->setPos(rect.topLeft());
ePhoto->setSize(rect.width(), rect.height());
ePhoto->setZValue(order++);
scene->addItem(ePhoto);
if(i==files.count()-1) {
2023-05-09 15:08:39 +08:00
auto sels = scene->selectedItems();
if(sels.count() == 1) sels.at(0)->setSelected(false);
2022-08-25 18:37:24 +08:00
ePhoto->setSelected(true);
2022-09-13 23:16:36 +08:00
gFileHome = ePhoto->mDir;
2022-08-25 18:37:24 +08:00
}
}
} else if(type==EBase::Gif) {
2022-09-13 23:16:36 +08:00
auto files = QFileDialog::getOpenFileNames(this, tr("Select File"), gFileHome, EGif::filters());
2022-08-25 18:37:24 +08:00
for(int i=0; i<files.count(); i++) {
auto eGif = EGif::create(files[i], mPageItem);
2023-05-09 15:08:39 +08:00
if(eGif==0) continue;
2022-08-25 18:37:24 +08:00
auto img = eGif->mMovie->currentPixmap();
2022-10-27 15:07:45 +08:00
auto rect = Tools::centerRect(img.width(), img.height(), mProgItem->mWidth, mProgItem->mHeight);
2022-08-25 18:37:24 +08:00
eGif->setPos(rect.topLeft());
eGif->setSize(rect.width(), rect.height());
eGif->setZValue(order++);
scene->addItem(eGif);
2023-05-09 15:08:39 +08:00
if(i == files.count()-1) {
auto sels = scene->selectedItems();
if(sels.count() == 1) sels.at(0)->setSelected(false);
2022-08-25 18:37:24 +08:00
eGif->setSelected(true);
2022-09-13 23:16:36 +08:00
gFileHome = eGif->mDir;
2022-08-25 18:37:24 +08:00
}
}
} else if(type==EBase::Video) {
2022-09-13 23:16:36 +08:00
auto file = QFileDialog::getOpenFileName(this, tr("Select File"), gFileHome, EVideo::filters());
2022-08-25 18:37:24 +08:00
if(file.isEmpty()) return;
auto eVideo = EVideo::create(file, mPageItem);
if(eVideo==nullptr) return;
2022-10-27 15:07:45 +08:00
auto rect = Tools::centerRect(eVideo->mCoverImg.width(), eVideo->mCoverImg.height(), mProgItem->mWidth, mProgItem->mHeight);
2022-08-25 18:37:24 +08:00
eVideo->setPos(rect.topLeft());
eVideo->setSize(rect.width(), rect.height());
2022-09-13 23:16:36 +08:00
gFileHome = eVideo->mRawDir;
2022-08-25 18:37:24 +08:00
element = eVideo;
2023-05-11 11:47:00 +08:00
} else if(type==EBase::Text) {
2022-10-27 15:07:45 +08:00
if(iNewHeight > 80 && (mProgItem->mWidth >= mProgItem->mHeight)) iNewHeight = 80;
2024-08-07 18:18:37 +08:00
element = new EText;
2023-05-11 11:47:00 +08:00
} else if(type==EBase::DClock) {
2022-10-27 15:07:45 +08:00
if(iNewHeight>80 && (mProgItem->mWidth>=mProgItem->mHeight)) iNewHeight=80;
2024-08-07 18:18:37 +08:00
element = new EDClock;
2023-05-11 11:47:00 +08:00
} else if(type==EBase::AClock) {
2022-08-25 18:37:24 +08:00
if(iNewWidth > 120) iNewWidth = 120;
if(iNewHeight > 120) iNewHeight = 120;
2024-08-07 18:18:37 +08:00
element = new EAClock;
} else if(type==EBase::Environ) element = new EEnviron;
2022-08-25 18:37:24 +08:00
else if(type==EBase::Web) {
2024-08-07 18:18:37 +08:00
element = new EWeb;
2022-10-27 15:07:45 +08:00
element->setSize(mProgItem->mWidth, mProgItem->mHeight);
2024-08-07 18:18:37 +08:00
} else if(type==EBase::Timer) element = new ETimer;
else if(type==EBase::Timer2) element = new ETimer2;
2022-08-25 18:37:24 +08:00
else if(type==EBase::Window) element = new EMultiWin(mPageItem);
2023-04-18 14:14:46 +08:00
if(element) {
2022-08-25 18:37:24 +08:00
if(element->mWidth==0) {
element->setPos(mNewEleX, mNewEleY);
element->setSize(iNewWidth, iNewHeight);
}
element->setZValue(order);
scene->addItem(element);
2023-05-09 15:08:39 +08:00
mNewEleX += 8;
mNewEleY += 8;
auto sels = scene->selectedItems();
if(sels.count() == 1) sels.at(0)->setSelected(false);
2022-08-25 18:37:24 +08:00
element->setSelected(true);
}
});
vBox->addWidget(toolBar);
2023-04-24 15:02:08 +08:00
auto line = new QFrame();
2022-08-25 18:37:24 +08:00
line->setFrameStyle(QFrame::Sunken);
line->setFrameShape(QFrame::HLine);
vBox->addWidget(line);
//主区域横向布局(幻灯片页列表,编辑窗,属性窗)
2023-04-24 15:02:08 +08:00
auto hBox = new QHBoxLayout();
2022-08-25 18:37:24 +08:00
hBox->setContentsMargins(0, 0, 0, 0);
hBox->setSpacing(0);
auto vBoxPage = new QVBoxLayout();
vBoxPage->setContentsMargins(0, 0, 0, 0);
vBoxPage->setSpacing(0);
auto lbName = new QLabel(tr("program"));
2023-04-24 16:35:58 +08:00
lbName->setStyleSheet("QLabel{background-color: #bbb;}");
2022-08-25 18:37:24 +08:00
lbName->setAlignment(Qt::AlignCenter);
vBoxPage->addWidget(lbName);
toolBar = new QToolBar();
toolBar->setIconSize(QSize(22,16));
toolBar->setStyleSheet("QToolBar{spacing: 8px;}");
2023-05-09 15:08:39 +08:00
auto actAdd = new QAction(QIcon(":/res/program/Add.png"), tr("Add page"));
2022-08-25 18:37:24 +08:00
connect(actAdd, &QAction::triggered, this, &ProgEditorWin::onAddPage);
toolBar->addAction(actAdd);
2023-05-09 15:08:39 +08:00
auto actCopy = new QAction(QIcon(":/res/program/Copy.png"), tr("Copy page"));
2022-08-25 18:37:24 +08:00
connect(actCopy, &QAction::triggered, this, [this] {
if(listPage->count() > 0) {
2023-06-20 08:49:01 +08:00
auto cur = (PageListItem*) listPage->currentItem();
2022-08-25 18:37:24 +08:00
cur->updateJson();
2023-09-19 11:49:20 +08:00
JObj attr;
for(auto &pair : cur->mAttr) attr.insert(pair.first, pair.second);
auto item = new PageListItem(attr, cur->mPageDir);
2022-08-25 18:37:24 +08:00
item->mAttr["name"] = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
listPage->addItem(item);
listPage->setItemWidget(item, item->itemWgt());
listPage->setCurrentItem(item);
2023-06-20 08:49:01 +08:00
if(listPage->count()==5) for(int i=0; i<4; i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
2022-08-25 18:37:24 +08:00
}
});
toolBar->addAction(actCopy);
2023-05-09 15:08:39 +08:00
auto actDel = new QAction(QIcon(":/res/program/Delete.png"), tr("Delete page"));
2022-08-25 18:37:24 +08:00
connect(actDel, &QAction::triggered, this, [this] {
2023-05-09 15:08:39 +08:00
if(listPage->count() == 1) mPageEditor->onClean();
2022-08-25 18:37:24 +08:00
else if(listPage->count() > 1) {
2023-06-20 08:49:01 +08:00
auto item = (PageListItem*) listPage->currentItem();
2022-08-25 18:37:24 +08:00
auto res = QMessageBox::information(this, tr("Tip Info"), tr("Are you sure you want to delete this program page?"), QMessageBox::Ok, QMessageBox::Cancel);
if(res == QMessageBox::Ok) {
delete item;
if(listPage->count() > 0) listPage->setCurrentRow(0);
2023-09-19 11:49:20 +08:00
for(int i=0; i<listPage->count(); i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
2022-08-25 18:37:24 +08:00
}
}
});
toolBar->addAction(actDel);
2023-05-09 15:08:39 +08:00
auto actMoveUp = new QAction(QIcon(":/res/program/GoUp.png"), tr("Move up"));
2022-08-25 18:37:24 +08:00
connect(actMoveUp, &QAction::triggered, this, [this] {
if(listPage->count() > 1) {
int index = listPage->currentRow();
if(index > 0) {
auto item = static_cast<PageListItem*>(listPage->takeItem(index));
listPage->insertItem(index-1, item);
listPage->setItemWidget(item, item->itemWgt());
listPage->setCurrentRow(index-1);
}
2023-09-19 11:49:20 +08:00
for(int i=0; i<listPage->count(); i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
2022-08-25 18:37:24 +08:00
}
});
toolBar->addAction(actMoveUp);
2023-05-09 15:08:39 +08:00
auto actMoveDown = new QAction(QIcon(":/res/program/GoDown.png"), tr("Move down"));
2022-08-25 18:37:24 +08:00
connect(actMoveDown, &QAction::triggered, this, [this] {
if(listPage->count() > 1) {
int index = listPage->currentRow();
if(index < listPage->count()-1) {
auto item = static_cast<PageListItem*>(listPage->takeItem(index));
listPage->insertItem(index+1, item);
listPage->setItemWidget(item, item->itemWgt());
listPage->setCurrentRow(index+1);
}
2023-09-19 11:49:20 +08:00
for(int i=0; i<listPage->count(); i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
2022-08-25 18:37:24 +08:00
}
});
toolBar->addAction(actMoveDown);
vBoxPage->addWidget(toolBar);
2023-08-01 11:42:41 +08:00
listPage = new QListWidget;
2022-08-25 18:37:24 +08:00
listPage->setMaximumWidth(190);
2023-05-09 15:08:39 +08:00
connect(listPage, &QListWidget::currentItemChanged, this, [=](QListWidgetItem *current, QListWidgetItem *previous) {
2022-08-25 18:37:24 +08:00
auto curItem = static_cast<PageListItem*>(current);
auto preItem = static_cast<PageListItem*>(previous);
2023-05-09 15:08:39 +08:00
if(preItem) preItem->mScene->clearSelection();
2022-08-25 18:37:24 +08:00
mPageItem = curItem;
2023-05-09 15:08:39 +08:00
auto scene = mPageEditor->graphicsView->scene();
if(scene) disconnect(scene, 0, 0, 0);
if(mPageEditor->curScale != 100) {
mPageEditor->curScale = 100;
mPageEditor->fdScale->setText("100");
mPageEditor->graphicsView->resetTransform();
2022-08-25 18:37:24 +08:00
}
2023-05-09 15:08:39 +08:00
if(curItem == 0) mPageEditor->graphicsView->setScene(0);
2022-08-25 18:37:24 +08:00
else {
2023-05-09 15:08:39 +08:00
mPageEditor->graphicsView->setScene(scene = curItem->mScene);
connect(scene, &QGraphicsScene::selectionChanged, this, [=] {
2022-08-25 18:37:24 +08:00
auto sels = scene->selectedItems();
auto scroll = static_cast<QScrollArea*>(mTabsAttr->widget(0));
if(sels.size() != 1) {
mTabsAttr->setCurrentIndex(1);
auto wgt = scroll->takeWidget();
2023-05-09 15:08:39 +08:00
if(wgt) delete wgt;
2022-08-25 18:37:24 +08:00
} else {
mTabsAttr->setCurrentIndex(0);
scroll->setWidget(static_cast<EBase*>(sels[0])->attrWgt());
scroll->updateGeometry();
}
});
}
auto scroll = static_cast<QScrollArea*>(mTabsAttr->widget(1));
scroll->takeWidget();
2023-05-09 15:08:39 +08:00
if(curItem) {
2022-08-25 18:37:24 +08:00
scroll->setWidget(curItem->attrWgt());
scroll->updateGeometry();
}
mTabsAttr->setCurrentIndex(1);
});
vBoxPage->addWidget(listPage);
hBox->addLayout(vBoxPage);
2023-05-09 15:08:39 +08:00
hBox->addWidget(mPageEditor = new PageEditor, 1);
2022-08-25 18:37:24 +08:00
mTabsAttr = new QTabWidget();
mTabsAttr->setMinimumWidth(360);
mTabsAttr->setStyleSheet("QTabWidget::pane{border:none;}");
QPalette backTrans;
backTrans.setColor(QPalette::Window, Qt::transparent);
auto scroll = new QScrollArea();
scroll->setFrameShape(QFrame::NoFrame);
scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scroll->setWidgetResizable(true);
scroll->setPalette(backTrans);
mTabsAttr->addTab(scroll, tr("widget properties"));
scroll = new QScrollArea();
scroll->setFrameShape(QFrame::NoFrame);
scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scroll->setWidgetResizable(true);
scroll->setPalette(backTrans);
mTabsAttr->addTab(scroll, tr("Page properties"));
mTabsAttr->setCurrentIndex(0);
hBox->addWidget(mTabsAttr);
vBox->addLayout(hBox);
2022-10-27 15:07:45 +08:00
QDir progQDir(mProgItem->mProgDir);
2022-08-25 18:37:24 +08:00
if(progQDir.exists()) {
2023-09-19 11:49:20 +08:00
auto pageNames = progQDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
for(QString &pageName : pageNames) {
2022-08-25 18:37:24 +08:00
if(pageName.endsWith(PAGEDEL_SUFFIX)) {
2022-10-27 15:07:45 +08:00
QDir(mProgItem->mProgDir + "/" + pageName).removeRecursively();
2022-08-25 18:37:24 +08:00
continue;
}
2022-10-27 15:07:45 +08:00
QFile pageFile(mProgItem->mProgDir + "/" + pageName + "/page.json");
2022-08-25 18:37:24 +08:00
if(pageFile.exists()) {
pageFile.open(QIODevice::ReadOnly);
2023-09-19 11:49:20 +08:00
mPageJsons.emplace_back(JFrom(pageFile.readAll()).toObj());
2022-08-25 18:37:24 +08:00
pageFile.close();
2022-10-27 15:07:45 +08:00
} else QDir(mProgItem->mProgDir + "/" + pageName).removeRecursively();
2022-08-25 18:37:24 +08:00
}
2023-09-19 11:49:20 +08:00
std::sort(mPageJsons.begin(), mPageJsons.end(), [](const JObj &a, const JObj &b) {
2022-08-25 18:37:24 +08:00
return a["order"].toInt() < b["order"].toInt();
});
2023-09-19 11:49:20 +08:00
}
if(mPageJsons.empty()) onAddPage();
else for(JObj &pageJson : mPageJsons) {
auto pageDir = mProgItem->mProgDir+"/"+pageJson["name"].toString();
QDir dir(pageDir);
if(! dir.exists() && ! dir.mkdir(pageDir)) continue;
JObj attr;
for(auto &pair : pageJson) attr.insert(pair.first, pair.second);
auto item = new PageListItem(attr, pageDir);
listPage->addItem(item);
listPage->setItemWidget(item, item->itemWgt());
auto cnt = listPage->count();
if(cnt==5) for(int i=0; i<4; i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
2022-08-25 18:37:24 +08:00
}
listPage->setCurrentRow(0);
}
bool ProgEditorWin::isProgChanged() {
if(mPageJsons.size() != listPage->count()) return true;
2023-09-19 11:49:20 +08:00
for(int i=0; i<(int)mPageJsons.size(); i++) {
auto page = (PageListItem*) listPage->item(i);
2022-08-25 18:37:24 +08:00
if(page->mAttrWgt==0) continue;
page->updateJson();
2023-10-23 11:44:22 +08:00
if(page->mAttr != mPageJsons[i]) return true;
2022-08-25 18:37:24 +08:00
}
return false;
}
void ProgEditorWin::closeEvent(QCloseEvent *event) {
2022-10-27 15:07:45 +08:00
mProgItem->onSetProgram();
2023-04-28 16:02:14 +08:00
if(isProgChanged()) {
auto res = QMessageBox::question(this, tr("Tip Info"), tr("Do you want to save the modifications?"), QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel);
if(res == QMessageBox::Yes) onSave();
else if(res == QMessageBox::Cancel) event->ignore();
}
2023-05-09 15:08:39 +08:00
#ifdef Q_OS_MAC
2023-05-11 11:47:00 +08:00
if(event->isAccepted()) parentWidget()->window()->show();
2023-05-09 15:08:39 +08:00
#endif
2022-08-25 18:37:24 +08:00
}
//停止每个页面元素的播放,将节目目录下的每个页面的文件夹另命名
2023-05-15 16:06:10 +08:00
bool ProgEditorWin::save() {
auto rtn = true;
2022-08-25 18:37:24 +08:00
//停止每个幻灯片的元素
int cnt = listPage->count();
for(int i=0; i<cnt; i++) {
auto items = static_cast<PageListItem*>(listPage->item(i))->mScene->items();
foreach(auto item, items) static_cast<EBase*>(item)->freeFiles();
}
2022-10-27 15:07:45 +08:00
QDir progDir(mProgItem->mProgDir);
2023-05-15 16:06:10 +08:00
if(! progDir.exists() && ! progDir.mkdir(mProgItem->mProgDir)) {
QMessageBox::critical(this, tr("Error"), tr("Create Dir failed")+": "+mProgItem->mProgDir);
return 0;
}
2023-09-19 11:49:20 +08:00
auto pageNames = progDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
for(QString &pageName : pageNames) if(! progDir.rename(pageName, pageName + PAGEDEL_SUFFIX)) {
rtn = 0;
QMessageBox::critical(this, tr("Error"), tr("Rename fail when saving")+" "+pageName);
2022-08-25 18:37:24 +08:00
}
//保存每个页面的元素和页面属性到page.json文档
mPageJsons.clear();
for(int i=0; i<cnt; i++) {
2023-09-19 11:49:20 +08:00
auto page = (PageListItem*) listPage->item(i);
page->mAttr["order"] = i;
if(page->saveFiles()) {
JObj json;
for(auto &pair : page->mAttr) json.insert(pair.first, pair.second);
mPageJsons.emplace_back(json);
}
2022-08-25 18:37:24 +08:00
}
pageNames = progDir.entryList(QStringList("*" PAGEDEL_SUFFIX));
foreach(QString pageName, pageNames) {
2023-05-15 16:06:10 +08:00
if(! QDir(mProgItem->mProgDir + "/" + pageName).removeRecursively()) {
rtn = 0;
QMessageBox::critical(this, tr("Error"), tr("Remove Recursively fail when saving")+" "+pageName);
}
2022-08-25 18:37:24 +08:00
}
for(int i=0; i<cnt; i++) {
auto items = static_cast<PageListItem*>(listPage->item(i))->mScene->items();
foreach(auto item, items) static_cast<EBase*>(item)->loadFiles();
}
2023-05-15 16:06:10 +08:00
return rtn;
2022-08-25 18:37:24 +08:00
}
void ProgEditorWin::onSave() {
2022-10-27 15:07:45 +08:00
auto waitingDlg = new WaitingDlg(this, tr("Saving..."), tr("Success"));
2023-08-01 11:42:41 +08:00
waitingDlg->setWindowFlag(Qt::WindowCloseButtonHint, 0);
2022-10-27 15:07:45 +08:00
waitingDlg->show();
2023-05-15 16:06:10 +08:00
if(save()) waitingDlg->success();
else waitingDlg->close();
2022-10-27 15:07:45 +08:00
waitingDlg->exec();
2023-08-01 11:42:41 +08:00
mProgItem->onSetProgram();
2022-08-25 18:37:24 +08:00
}
void ProgEditorWin::onAddPage() {
QDateTime now = QDateTime::currentDateTime();
auto name = now.toString("yyyyMMddhhmmsszzz");
2022-10-27 15:07:45 +08:00
auto pageDir = mProgItem->mProgDir+"/"+name;
2022-08-25 18:37:24 +08:00
QDir dir(pageDir);
2023-04-28 16:02:14 +08:00
if(! dir.exists() && ! dir.mkpath(pageDir)) return;
2023-09-19 11:49:20 +08:00
JObj attr;
2022-08-25 18:37:24 +08:00
attr["name"] = name;
attr["repeat"] = 1;
2023-09-19 11:49:20 +08:00
attr["validDate"] = JObj{
2022-08-25 18:37:24 +08:00
{"isValid", false},
{"start", now.date().toString("yyyy-MM-dd")},
{"end", now.addSecs(2678400).date().toString("yyyy-MM-dd")}
};
auto item = new PageListItem(attr, pageDir);
listPage->addItem(item);
listPage->setItemWidget(item, item->itemWgt());
listPage->setCurrentItem(item);
2023-06-20 08:49:01 +08:00
if(listPage->count()==5) for(int i=0; i<4; i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1);
2022-08-25 18:37:24 +08:00
}
2023-09-19 11:49:20 +08:00
2024-02-21 18:08:50 +08:00
ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remarks, QString widths, bool isVer, QWidget *parent) : QDialog(parent) {
2023-09-19 11:49:20 +08:00
#ifdef Q_OS_WIN
setWindowFlag(Qt::WindowContextHelpButtonHint, 0);
#endif
setWindowTitle(tr("Solution Information"));
auto vBox = new VBox(this);
2023-10-23 11:44:22 +08:00
vBox->setContentsMargins(6,0,6,6);
2023-09-19 11:49:20 +08:00
auto hBox = new HBox(vBox);
auto label = new QLabel(tr("Solution Name"));
label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label);
fdName = new QLineEdit;
if(name.isEmpty()) name = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
else fdName->setDisabled(true);
fdName->setText(name);
hBox->addWidget(fdName);
hBox = new HBox(vBox);
hBox->setSpacing(12);
label = new QLabel(tr("Resolution"));
label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label);
hBox->addSpacing(6);
auto label_4 = new QLabel(tr("Width"));
hBox->addWidget(label_4);
fdWidth = new QSpinBox;
fdWidth->setMaximum(99999);
fdWidth->setValue(width);
hBox->addWidget(fdWidth);
auto label_5 = new QLabel(tr("Height"));
hBox->addWidget(label_5);
fdHeight = new QSpinBox;
fdHeight->setMaximum(99999);
fdHeight->setValue(height);
hBox->addWidget(fdHeight);
hBox->addStretch();
hBox = new HBox(vBox);
label = new QLabel(tr("Remarks"));
label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label);
fdRemark = new QTextEdit(remarks);
2024-02-21 18:08:50 +08:00
fdRemark->setFixedHeight(80);
2023-09-19 11:49:20 +08:00
hBox->addWidget(fdRemark);
2024-08-19 16:10:49 +08:00
hBox = new HBox(vBox);
hBox->addSpacing(72);
edIsInsert = new QCheckBox(tr("Is Insert"));
hBox->addWidget(edIsInsert);
2023-10-23 11:44:22 +08:00
vBox->addSpacing(6);
2023-09-19 11:49:20 +08:00
hBox = new HBox(vBox);
2023-10-23 11:44:22 +08:00
hBox->addSpacing(72);
2023-09-19 11:49:20 +08:00
2023-10-23 11:44:22 +08:00
fdIsUltraLong = new QCheckBox(tr("Ultra-Long Screen Split"));
hBox->addWidget(fdIsUltraLong);
2024-02-21 18:08:50 +08:00
fdHor = new QRadioButton(tr("Horizontal"));
hBox->addWidget(fdHor);
fdVer = new QRadioButton(tr("Vertical"));
hBox->addWidget(fdVer);
hBox->addStretch();
if(isVer) fdVer->setChecked(true);
else fdHor->setChecked(true);
2023-10-23 11:44:22 +08:00
hBox = new HBox(vBox);
2024-02-21 18:08:50 +08:00
auto lbSplitWidth = new QLabel(tr("Lengths of Parts"));
2023-10-23 11:44:22 +08:00
lbSplitWidth->setMinimumWidth(90);
lbSplitWidth->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
2023-09-19 11:49:20 +08:00
hBox->addWidget(lbSplitWidth);
2023-10-23 11:44:22 +08:00
fdSplitWidths = new QLineEdit(widths.isEmpty() ? "1920" : widths);
fdSplitWidths->setPlaceholderText("1920");
2023-09-19 11:49:20 +08:00
hBox->addWidget(fdSplitWidths);
2024-02-21 18:08:50 +08:00
connect(fdIsUltraLong, &QCheckBox::toggled, this, [=](bool checked) {
fdHor->setVisible(checked);
fdVer->setVisible(checked);
lbSplitWidth->setVisible(checked);
fdSplitWidths->setVisible(checked);
});
if(widths.isEmpty()) fdIsUltraLong->toggled(false);
else fdIsUltraLong->setChecked(true);
2023-09-19 11:49:20 +08:00
if(! gWidthSplit) {
2023-10-23 11:44:22 +08:00
fdIsUltraLong->setVisible(false);
2023-09-19 11:49:20 +08:00
lbSplitWidth->setVisible(false);
fdSplitWidths->setVisible(false);
}
vBox->addSpacing(6);
auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(btnBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
connect(btnBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
vBox->addWidget(btnBox);
}