640 lines
28 KiB
C++
640 lines
28 KiB
C++
#include "progeditorwin.h"
|
||
#include "LoUIClass/customprogressindicator.h"
|
||
#include "LoUIClass/loemptydialog.h"
|
||
#include "base/loqtitlebar.h"
|
||
#include "cfg.h"
|
||
#include "ebase.h"
|
||
#include "pagelistitem.h"
|
||
#include "player/playwin.h"
|
||
#include "tools.h"
|
||
#include "wProgramManager/ebase.h"
|
||
#include "wProgramManager/etext.h"
|
||
#include "wProgramManager/ephoto.h"
|
||
#include "wProgramManager/evideo.h"
|
||
#include "wProgramManager/eaudio.h"
|
||
#include "wProgramManager/egif.h"
|
||
#include "wProgramManager/edclock.h"
|
||
#include "wProgramManager/eaclock.h"
|
||
#include "wProgramManager/eenviron.h"
|
||
#include "wProgramManager/eweb.h"
|
||
#include "wProgramManager/etimer.h"
|
||
#include "wProgramManager/emultiwin.h"
|
||
#include "wProgramManager/mconverter.h"
|
||
#include "wProgramManager/sendprogramdialog.h"
|
||
#include "wnewprogram.h"
|
||
#include <QBoxLayout>
|
||
#include <QCloseEvent>
|
||
#include <QGraphicsDropShadowEffect>
|
||
#include <QInputDialog>
|
||
#include <QJsonArray>
|
||
#include <QMessageBox>
|
||
#include <QSettings>
|
||
#include <QToolBar>
|
||
#include <QUdpSocket>
|
||
|
||
QString gProgDir;
|
||
int gProgWidth = 0;
|
||
int gProgHeight = 0;
|
||
|
||
ProgEditorWin::ProgEditorWin(QString &name, int &w, int &h, QString &remarks, const QString &progDir, const QString progsDir, QWidget *parent) : BaseWin(parent), mProgsDir(progsDir), m_name(name), m_remarks(remarks) {
|
||
gProgDir = progDir;
|
||
gProgWidth = w;
|
||
gProgHeight = h;
|
||
setWindowModality(Qt::WindowModal);
|
||
if(parent!=nullptr && ! parent->isMaximized()) resize(parent->size());
|
||
else resize(1280, 720);
|
||
setWindowFlag(Qt::Window);
|
||
setAttribute(Qt::WA_DeleteOnClose);
|
||
auto plt = palette();
|
||
plt.setBrush(QPalette::Window, QColor(0xdddddd));
|
||
setPalette(plt);
|
||
setWindowTitle(name);
|
||
icon = QPixmap(":/res/Logo.ico").scaledToHeight(16);
|
||
|
||
auto vBox = new QVBoxLayout(center);
|
||
vBox->setContentsMargins(0, 0, 0, 0);
|
||
vBox->setSpacing(0);
|
||
|
||
auto titleBar = new LoQTitleBar(this);
|
||
titleBar->bn_Minimize->setVisible(false);
|
||
auto hBox = new QHBoxLayout(titleBar);
|
||
hBox->setContentsMargins(0, 0, 0, 0);
|
||
hBox->setSpacing(0);
|
||
hBox->addStretch();
|
||
hBox->addWidget(titleBar->bn_Minimize);
|
||
hBox->addWidget(titleBar->bn_Maximize);
|
||
hBox->addWidget(titleBar->bn_Close);
|
||
|
||
vBox->addWidget(titleBar);
|
||
auto line = new QFrame();
|
||
line->setFrameShape(QFrame::HLine);
|
||
line->setFrameShadow(QFrame::Sunken);
|
||
vBox->addWidget(line);
|
||
|
||
auto toolBar = new QToolBar();
|
||
toolBar->setFloatable(false);
|
||
toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||
toolBar->setIconSize(QSize(46, 40));
|
||
|
||
auto action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Save.png"), tr("Save"));
|
||
connect(action, &QAction::triggered, this, &ProgEditorWin::onSave);
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/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, SIGNAL(finished()), this, SIGNAL(sProgramChanged()));//连接结束信号到节目列表项
|
||
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;
|
||
gProgDir = 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, SIGNAL(finished()), this, SIGNAL(sProgramChanged()));//连接结束信号到节目列表项
|
||
saveThread->start();
|
||
dlgTip->exec();
|
||
close();
|
||
setWindowTitle(progName);
|
||
emit sProgramSaveAs(progName, QSize(gProgWidth, gProgHeight), m_remarks);
|
||
});
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Setting.png"), tr("Setting"));
|
||
connect(action, &QAction::triggered, this, [this](){
|
||
wNewProgram *dlg = new wNewProgram(m_name, QSize(gProgWidth, gProgHeight), m_remarks, this, true);
|
||
connect(dlg, &wNewProgram::sigAcceptData, this, [this](QString , QSize size, QString remarks){
|
||
gProgWidth = size.width();
|
||
gProgHeight = size.height();
|
||
m_remarks = remarks;
|
||
emit sProgramChanged();
|
||
int n = listPage->count();
|
||
for(int i=0; i<n; i++) {
|
||
auto page = static_cast<PageListItem*>(listPage->item(i));
|
||
page->mScene->setSceneRect(0, 0, gProgWidth, gProgHeight);
|
||
page->mGraView->resetTransform();
|
||
qreal scale = qMin(page->mGraView->width() / page->mScene->width(), page->mGraView->height() / page->mScene->height());
|
||
page->mGraView->scale(scale, scale);
|
||
|
||
auto items = page->mScene->items();
|
||
foreach(auto item, items) {
|
||
auto element = static_cast<EBase*>(item);
|
||
if(element->mMultiWin == nullptr) element->fitProgSize();
|
||
}
|
||
page->mScene->update();
|
||
}
|
||
});
|
||
dlg->exec();
|
||
});
|
||
toolBar->addAction(action);
|
||
toolBar->addSeparator();
|
||
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Window.png"), tr("MuliContentWindow"));
|
||
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();
|
||
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Text.png"), tr("Text"));
|
||
action->setData(EBase::Text);
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Photo.png"), tr("Photo"));
|
||
action->setData(EBase::Photo);
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Movie.png"), tr("Video"));
|
||
action->setData(EBase::Video);
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Gif.png"), tr("Gif"));
|
||
action->setData(EBase::Gif);
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/DClock.png"), tr("Clock"));
|
||
action->setData(EBase::DClock);
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/AClock.png"), tr("Analog Clock"));
|
||
action->setData(EBase::AClock);
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Temp.png"), tr("Environment"));
|
||
action->setData(EBase::Environ);
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Web.png"), tr("Web"));
|
||
action->setData(EBase::Web);
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Timer.png"), tr("Timer"));
|
||
action->setData(EBase::Timer);
|
||
toolBar->addAction(action);
|
||
// action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Audio.png"), tr("Audio"));
|
||
// action->setData(EBase::Audio);
|
||
// toolBar->addAction(action);
|
||
toolBar->addSeparator();
|
||
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/preview.png"), tr("Play")+"/"+tr("Stop"));
|
||
connect(action, &QAction::triggered, this, [this] {
|
||
if(PlayWin::self!=nullptr) PlayWin::self->close();
|
||
else {
|
||
if(isProgChanged()) onSave();
|
||
LoEmptyDialog * msgbox = new LoEmptyDialog(this);
|
||
//转换节目
|
||
auto converter = new mConverter(m_name, "", "" ,this);
|
||
//转换结束,发送信号触发converter释放内存
|
||
connect(converter, SIGNAL(finished()), converter, SLOT(deleteLater()));
|
||
connect(converter, SIGNAL(finished()), msgbox, SLOT(unlock()));
|
||
//链接转换进度信号到进度条槽函数
|
||
connect(converter, SIGNAL(sProgress(QString,int,bool)), msgbox->mIndicator, SLOT(onProgress(QString,int,bool)));
|
||
//链接进度对话框启动信号到转换开始槽函数
|
||
connect(msgbox, SIGNAL(startUp()), converter, SLOT(start()));
|
||
msgbox->lock(tr("Generate preview data")+"...",tr("Ready"),tr("Generate TimeOut"));
|
||
msgbox->exec();
|
||
|
||
QFile file(gProgDir+"_tmp/program");
|
||
if(! file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
|
||
QString value = file.readAll();
|
||
file.close();
|
||
QJsonParseError jsErr;
|
||
QJsonObject prog = QJsonDocument::fromJson(value.toUtf8(), &jsErr).object();
|
||
if(jsErr.error) return;
|
||
PlayWin::self = PlayWin::newIns(gProgWidth, gProgHeight, gProgDir+"_tmp", prog);
|
||
}
|
||
});
|
||
toolBar->addAction(action);
|
||
action = new QAction(QIcon(":/res/ProgramManager/EditProgram/Send.png"), tr("Publish"));
|
||
connect(action, &QAction::triggered, this, [this]{
|
||
onSave();
|
||
LoEmptyDialog * msgbox = new LoEmptyDialog(this);
|
||
//转换节目
|
||
auto converter = new mConverter(m_name, "", "", this);
|
||
//转换结束,发送信号触发converter释放内存
|
||
connect(converter, SIGNAL(finished()), converter, SLOT(deleteLater()));
|
||
connect(converter, SIGNAL(finished()), msgbox, SLOT(unlock()));
|
||
//链接转换进度信号到进度条槽函数
|
||
connect(converter, SIGNAL(sProgress(QString,int,bool)), msgbox->mIndicator, SLOT(onProgress(QString,int,bool)));
|
||
//链接进度对话框启动信号到转换开始槽函数
|
||
connect(msgbox, SIGNAL(startUp()), converter, SLOT(start()));
|
||
msgbox->lock(tr("Convertering")+"...",tr("Converter Successed"),tr("Converter TimeOut"));
|
||
msgbox->exec();
|
||
|
||
auto dlg = new SendProgramDialog(this, m_name, programsDir());
|
||
dlg->show();
|
||
});
|
||
toolBar->addAction(action);
|
||
|
||
connect(toolBar, &QToolBar::actionTriggered, this, [this](QAction *act) {
|
||
auto data = act->data();
|
||
if(data.type()!=QVariant::Int) return;
|
||
auto scene = progEditorMid->graphicsView->scene();
|
||
if(nullptr == scene) return;
|
||
int order = progEditorMid->sortedEles().count();
|
||
EBase *element = nullptr;
|
||
int iNewWidth = gProgWidth;
|
||
int iNewHeight = gProgHeight;
|
||
if(iNewWidth>128) iNewWidth = iNewWidth * 2 / 3;
|
||
if(iNewHeight>128) iNewHeight = iNewHeight * 2 / 3;
|
||
if(mNewEleX+iNewWidth>gProgWidth) mNewEleX=0;
|
||
if(mNewEleY+iNewHeight>gProgHeight) mNewEleY=0;
|
||
auto type = data.toInt();
|
||
if(type==EBase::Photo) {
|
||
auto files = QFileDialog::getOpenFileNames(this, tr("Select File"), gFileHome, EPhoto::filters());
|
||
for(int i=0; i<files.count(); i++) {
|
||
auto ePhoto = EPhoto::create(files[i], mPageItem);
|
||
if(ePhoto==nullptr) continue;
|
||
auto rect = Tools::centerRect(ePhoto->img.width(), ePhoto->img.height(), gProgWidth, gProgHeight);
|
||
ePhoto->setPos(rect.topLeft());
|
||
ePhoto->setSize(rect.width(), rect.height());
|
||
ePhoto->setZValue(order++);
|
||
scene->addItem(ePhoto);
|
||
if(i==files.count()-1) {
|
||
auto scene = progEditorMid->graphicsView->scene();
|
||
if(nullptr != scene) {
|
||
auto list = scene->selectedItems();
|
||
if(list.count() == 1) static_cast<EBase*>(list.at(0))->setSelected(false);
|
||
}
|
||
ePhoto->setSelected(true);
|
||
gFileHome = ePhoto->mDir;
|
||
}
|
||
}
|
||
} else if(type==EBase::Gif) {
|
||
auto files = QFileDialog::getOpenFileNames(this, tr("Select File"), gFileHome, EGif::filters());
|
||
for(int i=0; i<files.count(); i++) {
|
||
auto eGif = EGif::create(files[i], mPageItem);
|
||
if(eGif==nullptr) continue;
|
||
auto img = eGif->mMovie->currentPixmap();
|
||
auto rect = Tools::centerRect(img.width(), img.height(), gProgWidth, gProgHeight);
|
||
eGif->setPos(rect.topLeft());
|
||
eGif->setSize(rect.width(), rect.height());
|
||
eGif->setZValue(order++);
|
||
scene->addItem(eGif);
|
||
if(i == files.count()-1){
|
||
auto scene = progEditorMid->graphicsView->scene();
|
||
if(nullptr != scene) {
|
||
auto list = scene->selectedItems();
|
||
if(list.count() == 1) static_cast<EBase*>(list.at(0))->setSelected(false);
|
||
}
|
||
eGif->setSelected(true);
|
||
gFileHome = eGif->mDir;
|
||
}
|
||
}
|
||
} else if(type==EBase::Video) {
|
||
auto file = QFileDialog::getOpenFileName(this, tr("Select File"), gFileHome, EVideo::filters());
|
||
if(file.isEmpty()) return;
|
||
auto eVideo = EVideo::create(file, mPageItem);
|
||
if(eVideo==nullptr) return;
|
||
auto rect = Tools::centerRect(eVideo->mCoverImg.width(), eVideo->mCoverImg.height(), gProgWidth, gProgHeight);
|
||
eVideo->setPos(rect.topLeft());
|
||
eVideo->setSize(rect.width(), rect.height());
|
||
gFileHome = eVideo->mRawDir;
|
||
element = eVideo;
|
||
} else if(type== EBase::Audio) {
|
||
auto file = QFileDialog::getOpenFileName(this, tr("Select File"), gFileHome, EAudio::filters());
|
||
if(file.isEmpty()) return;
|
||
auto eAudio = EAudio::create(file, mPageItem);
|
||
if(eAudio==nullptr) return;
|
||
int i=0;
|
||
for(; i<gProgWidth; i+=50) if(nullptr==scene->itemAt(i+20, gProgHeight+20, QTransform())) break;
|
||
eAudio->setPos(i, gProgHeight);
|
||
eAudio->setSize(50, 50);
|
||
gFileHome = eAudio->mDir;
|
||
element = eAudio;
|
||
}
|
||
else if(type==EBase::Text) {
|
||
if(iNewHeight > 80 && (gProgWidth >= gProgHeight)) iNewHeight = 80;
|
||
element = new EText();
|
||
}
|
||
else if(type==EBase::DClock) {
|
||
if(iNewHeight>80 && (gProgWidth>=gProgHeight)) iNewHeight=80;
|
||
element = new eDClock();
|
||
}
|
||
else if(type==EBase::AClock) {
|
||
if(iNewWidth > 120) iNewWidth = 120;
|
||
if(iNewHeight > 120) iNewHeight = 120;
|
||
element = new eAClock();
|
||
}
|
||
else if(type==EBase::Environ) element = new EEnviron();
|
||
else if(type==EBase::Web) {
|
||
element = new EWeb();
|
||
element->setSize(gProgWidth, gProgHeight);
|
||
}
|
||
else if(type==EBase::Timer) element = new ETimer();
|
||
else if(type==EBase::Audio) ;
|
||
else if(type==EBase::Window) element = new EMultiWin(mPageItem);
|
||
if(nullptr != element) {
|
||
if(element->mWidth==0) {
|
||
element->setPos(mNewEleX, mNewEleY);
|
||
element->setSize(iNewWidth, iNewHeight);
|
||
}
|
||
element->setZValue(order);
|
||
scene->addItem(element);
|
||
mNewEleX+=8;
|
||
mNewEleY+=8;
|
||
QGraphicsScene *scene = progEditorMid->graphicsView->scene();
|
||
if(nullptr != scene){
|
||
QList<QGraphicsItem *> list = scene->selectedItems();
|
||
if(list.count() == 1) static_cast<EBase*>(list.at(0))->setSelected(false);
|
||
}
|
||
element->setSelected(true);
|
||
}
|
||
});
|
||
vBox->addWidget(toolBar);
|
||
|
||
line = new QFrame();
|
||
line->setFrameStyle(QFrame::Sunken);
|
||
line->setFrameShape(QFrame::HLine);
|
||
vBox->addWidget(line);
|
||
|
||
//主区域横向布局(幻灯片页列表,编辑窗,属性窗)
|
||
hBox = new QHBoxLayout();
|
||
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"));
|
||
lbName->setStyleSheet("QLabel{background-color: #bbbbbb;}");
|
||
lbName->setAlignment(Qt::AlignCenter);
|
||
vBoxPage->addWidget(lbName);
|
||
|
||
toolBar = new QToolBar();
|
||
toolBar->setIconSize(QSize(22,16));
|
||
toolBar->setStyleSheet("QToolBar{spacing: 8px;}");
|
||
|
||
QAction *actAdd = new QAction(QIcon(":/res/ProgramManager/EditProgram/Add.png"), tr("Add page"));
|
||
connect(actAdd, &QAction::triggered, this, &ProgEditorWin::onAddPage);
|
||
toolBar->addAction(actAdd);
|
||
|
||
QAction *actCopy = new QAction(QIcon(":/res/ProgramManager/EditProgram/Copy.png"), tr("Copy page"));
|
||
connect(actCopy, &QAction::triggered, this, [this] {
|
||
if(listPage->count() > 0) {
|
||
auto cur = static_cast<PageListItem*>(listPage->currentItem());
|
||
cur->updateJson();
|
||
auto item = new PageListItem(cur->mAttr, cur->mPageDir);
|
||
item->mAttr["name"] = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
|
||
item->mAttr["order"] = listPage->count();
|
||
listPage->addItem(item);
|
||
listPage->setItemWidget(item, item->itemWgt());
|
||
listPage->setCurrentItem(item);
|
||
}
|
||
});
|
||
toolBar->addAction(actCopy);
|
||
|
||
QAction *actDel = new QAction(QIcon(":/res/ProgramManager/EditProgram/Delete.png"), tr("Delete page"));
|
||
connect(actDel, &QAction::triggered, this, [this] {
|
||
if(listPage->count() == 1) progEditorMid->onClean();
|
||
else if(listPage->count() > 1) {
|
||
auto item = static_cast<PageListItem*>(listPage->currentItem());
|
||
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);
|
||
int n = listPage->count();
|
||
for(int i=0; i<n; i++) static_cast<PageListItem*>(listPage->item(i))->mAttr["order"] = QJsonValue(i);
|
||
}
|
||
}
|
||
});
|
||
toolBar->addAction(actDel);
|
||
|
||
QAction *actMoveUp = new QAction(QIcon(":/res/ProgramManager/EditProgram/GoUp.png"), tr("Move up"));
|
||
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);
|
||
}
|
||
int n = listPage->count();
|
||
for(int i=0; i<n; i++) static_cast<PageListItem*>(listPage->item(i))->mAttr["order"] = QJsonValue(i);
|
||
}
|
||
});
|
||
toolBar->addAction(actMoveUp);
|
||
|
||
QAction *actMoveDown = new QAction(QIcon(":/res/ProgramManager/EditProgram/GoDown.png"), tr("Move down"));
|
||
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);
|
||
}
|
||
int n = listPage->count();
|
||
for(int i=0; i<n; i++) static_cast<PageListItem*>(listPage->item(i))->mAttr["order"] = QJsonValue(i);
|
||
}
|
||
});
|
||
toolBar->addAction(actMoveDown);
|
||
|
||
vBoxPage->addWidget(toolBar);
|
||
|
||
listPage = new QListWidget();
|
||
listPage->setMaximumWidth(190);
|
||
connect(listPage, &QListWidget::currentItemChanged, this, [this](QListWidgetItem *current, QListWidgetItem *previous) {
|
||
auto curItem = static_cast<PageListItem*>(current);
|
||
auto preItem = static_cast<PageListItem*>(previous);
|
||
if(nullptr != preItem) preItem->mScene->clearSelection();
|
||
mPageItem = curItem;
|
||
auto scene = progEditorMid->graphicsView->scene();
|
||
if(scene != nullptr) disconnect(scene, &QGraphicsScene::selectionChanged, this, 0);
|
||
if(progEditorMid->curScale != 100) {
|
||
progEditorMid->curScale = 100;
|
||
progEditorMid->fdScale->setText("100");
|
||
progEditorMid->graphicsView->resetTransform();
|
||
}
|
||
if(curItem == nullptr) progEditorMid->graphicsView->setScene(nullptr);
|
||
else {
|
||
progEditorMid->graphicsView->setScene(scene = curItem->mScene);
|
||
connect(scene, &QGraphicsScene::selectionChanged, this, [this] {
|
||
auto scene = progEditorMid->graphicsView->scene();
|
||
if(scene==nullptr) return;
|
||
auto sels = scene->selectedItems();
|
||
auto scroll = static_cast<QScrollArea*>(mTabsAttr->widget(0));
|
||
if(sels.size() != 1) {
|
||
mTabsAttr->setCurrentIndex(1);
|
||
auto wgt = scroll->takeWidget();
|
||
if(wgt!=nullptr) delete wgt;
|
||
} else {
|
||
mTabsAttr->setCurrentIndex(0);
|
||
scroll->setWidget(static_cast<EBase*>(sels[0])->attrWgt());
|
||
scroll->updateGeometry();
|
||
}
|
||
});
|
||
}
|
||
auto scroll = static_cast<QScrollArea*>(mTabsAttr->widget(1));
|
||
scroll->takeWidget();
|
||
if(curItem != nullptr) {
|
||
scroll->setWidget(curItem->attrWgt());
|
||
scroll->updateGeometry();
|
||
}
|
||
mTabsAttr->setCurrentIndex(1);
|
||
});
|
||
vBoxPage->addWidget(listPage);
|
||
hBox->addLayout(vBoxPage);
|
||
|
||
hBox->addWidget(progEditorMid = new PageEditor(this), 1);
|
||
|
||
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);
|
||
|
||
QGraphicsDropShadowEffect *shadow_effect = new QGraphicsDropShadowEffect(progEditorMid);
|
||
shadow_effect->setOffset(0, 0);
|
||
shadow_effect->setColor(QColor(38, 78, 119, 127));//阴影颜色
|
||
shadow_effect->setBlurRadius(8);//阴影半径
|
||
progEditorMid->setGraphicsEffect(shadow_effect);
|
||
|
||
QDir progQDir(gProgDir);
|
||
if(progQDir.exists()) {
|
||
QStringList pageNames = progQDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
|
||
foreach(QString pageName, pageNames) {
|
||
if(pageName.endsWith(PAGEDEL_SUFFIX)) {
|
||
QDir(gProgDir + "/" + pageName).removeRecursively();
|
||
continue;
|
||
}
|
||
QFile pageFile(gProgDir + "/" + pageName + "/page.json");
|
||
if(pageFile.exists()) {
|
||
pageFile.open(QIODevice::ReadOnly);
|
||
mPageJsons.push_back(QJsonDocument::fromJson(pageFile.readAll()).object());
|
||
pageFile.close();
|
||
} else QDir(gProgDir + "/" + pageName).removeRecursively();
|
||
}
|
||
}
|
||
if(mPageJsons.isEmpty()) onAddPage();
|
||
else {
|
||
std::sort(mPageJsons.begin(), mPageJsons.end(), [](const QJsonObject &a, const QJsonObject &b) {
|
||
return a["order"].toInt() < b["order"].toInt();
|
||
});
|
||
foreach(QJsonObject pageJson, mPageJsons) {
|
||
auto pageDir = gProgDir+"/"+pageJson["name"].toString();
|
||
QDir dir(pageDir);
|
||
if(! dir.exists() && ! dir.mkdir(".")) continue;
|
||
auto item = new PageListItem(pageJson, pageDir);
|
||
listPage->addItem(item);
|
||
listPage->setItemWidget(item, item->itemWgt());
|
||
}
|
||
}
|
||
listPage->setCurrentRow(0);
|
||
}
|
||
bool ProgEditorWin::isProgChanged() {
|
||
if(mPageJsons.size() != listPage->count()) return true;
|
||
for(int i=0; i<mPageJsons.count(); i++) {
|
||
auto page = static_cast<PageListItem*>(listPage->item(i));
|
||
if(page->mAttrWgt==0) continue;
|
||
page->updateJson();
|
||
if(page->mAttr != mPageJsons[i]) return true;
|
||
}
|
||
return false;
|
||
}
|
||
void ProgEditorWin::closeEvent(QCloseEvent *event) {
|
||
emit sProgramChanged();
|
||
if(! isProgChanged()) return;
|
||
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();
|
||
}
|
||
//停止每个页面元素的播放,将节目目录下的每个页面的文件夹另命名
|
||
void ProgEditorWin::save() {
|
||
//停止每个幻灯片的元素
|
||
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();
|
||
}
|
||
QDir progDir(gProgDir);
|
||
if(! progDir.exists() && ! progDir.mkdir(".")) return;
|
||
QStringList pageNames = progDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
|
||
foreach(QString pageName, pageNames) {
|
||
if(! progDir.rename(pageName, pageName + PAGEDEL_SUFFIX)) QMessageBox::critical(this, tr("Error"), tr("Rename fail when saving")+" "+pageName);
|
||
}
|
||
//保存每个页面的元素和页面属性到page.json文档
|
||
mPageJsons.clear();
|
||
for(int i=0; i<cnt; i++) {
|
||
auto page = static_cast<PageListItem*>(listPage->item(i));
|
||
if(page->saveFiles()) mPageJsons.append(page->mAttr);
|
||
}
|
||
pageNames = progDir.entryList(QStringList("*" PAGEDEL_SUFFIX));
|
||
foreach(QString pageName, pageNames) {
|
||
if(! QDir(gProgDir + "/" + pageName).removeRecursively()) QMessageBox::critical(this, tr("Error"), tr("Remove Recursively fail when saving")+" "+pageName);
|
||
}
|
||
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();
|
||
}
|
||
}
|
||
|
||
void ProgEditorWin::onSave() {
|
||
auto dlg = new LoEmptyDialog(this);
|
||
dlg->lock(tr("Saving..."),tr("Success"),tr("Save failed"));
|
||
dlg->show();
|
||
save();
|
||
dlg->unlock();
|
||
dlg->exec();
|
||
emit sProgramChanged();//连接结束信号到节目列表项
|
||
}
|
||
|
||
void ProgEditorWin::UdpSendJson(QJsonObject json) {
|
||
QUdpSocket *tempUdpSocket= new QUdpSocket(this);
|
||
if(!tempUdpSocket->bind(QHostAddress("127.0.0.1"))) {
|
||
QMessageBox::critical(this, tr("Warning"), "udp bind failed");
|
||
return;
|
||
}
|
||
QJsonDocument resultJson;
|
||
resultJson.setObject(json);
|
||
QByteArray byteArray=resultJson.toJson();
|
||
QHostAddress localAddress("127.0.0.1");
|
||
int iSendLength=tempUdpSocket->writeDatagram(byteArray.data(),byteArray.size(),localAddress,2000);
|
||
if(iSendLength != byteArray.size()) {
|
||
char *aa=byteArray.data();
|
||
tempUdpSocket->writeDatagram(&aa[iSendLength],byteArray.size()-iSendLength,localAddress,2000);
|
||
}
|
||
delete tempUdpSocket;
|
||
}
|
||
|
||
void ProgEditorWin::onAddPage() {
|
||
QDateTime now = QDateTime::currentDateTime();
|
||
auto name = now.toString("yyyyMMddhhmmsszzz");
|
||
auto pageDir = gProgDir+"/"+name;
|
||
QDir dir(pageDir);
|
||
if(! dir.exists() && ! dir.mkpath(".")) return;
|
||
QJsonObject attr;
|
||
attr["name"] = name;
|
||
attr["order"] = listPage->count();
|
||
attr["repeat"] = 1;
|
||
attr["validDate"] = QJsonObject{
|
||
{"isValid", false},
|
||
{"start", now.date().toString("yyyy-MM-dd")},
|
||
{"end", now.addSecs(2678400).date().toString("yyyy-MM-dd")}
|
||
};
|
||
attr["plans"] = QJsonArray();
|
||
auto item = new PageListItem(attr, pageDir);
|
||
listPage->addItem(item);
|
||
listPage->setItemWidget(item, item->itemWgt());
|
||
listPage->setCurrentItem(item);
|
||
}
|