#include "progpanel.h" #include "globaldefine.h" #include "gutil/qgui.h" #include "cfg.h" #include "player/playwin.h" #include "program/progeditorwin.h" #include "program/copydirthread.h" #include #include #include #include #include #include ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_DeleteOnClose); setAutoFillBackground(true); QPalette pal; pal.setBrush(QPalette::Window, QColor(0xeeeeee)); setPalette(pal); auto vBox = new QVBoxLayout(this); vBox->setContentsMargins(0, 0, 0, 0); vBox->setSpacing(0); auto hBox = new QHBoxLayout(); hBox->setContentsMargins(6,6,6,6); hBox->setSpacing(6); vBox->addLayout(hBox); bnNew = new QPushButton(tr("New")); bnNew->setFixedSize(88, 38); bnNew->setProperty("ssType", "progManageTool"); hBox->addWidget(bnNew); connect(bnNew, &QPushButton::clicked, this, [this] { ProgCreateDlg dlg("", 512, 256, "", "", this); if(dlg.exec() != QDialog::Accepted) return; if(checkIfNameRepeated(dlg.fdName->text())) return; QList widths; int max = 0; auto width = dlg.fdWidth->value(); if(dlg.fdIsUltraLong->isChecked()) { auto splitWidths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts); int ttl = 0; for(auto &splitWidth : splitWidths) { int val = splitWidth.toInt(); if(val==0) continue; if(max < val) max = val; widths.append(val); ttl += val; if(ttl>=width) break; } if(max) { while(ttl < width) { widths.append(max); ttl += max; } if(ttl > width) widths.last() -= ttl - width; } } auto item = new ProgItem(mProgsDir, dlg.fdName->text(), width, dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, 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(); }); bnEdit = new QPushButton(tr("Edit")); bnEdit->setFixedSize(QSize(88, 38)); bnEdit->setProperty("ssType", "progManageTool"); bnEdit->setEnabled(false); hBox->addWidget(bnEdit); connect(bnEdit, SIGNAL(clicked(bool)), this, SLOT(onEditClicked(bool))); bnDelete = new QPushButton(tr("Delete")); bnDelete->setFixedSize(QSize(88, 38)); bnDelete->setProperty("ssType", "progManageTool"); bnDelete->setEnabled(false); hBox->addWidget(bnDelete); connect(bnDelete, SIGNAL(clicked(bool)), this, SLOT(onDeleteClicked(bool))); bnImport = new QPushButton(tr("Import")); bnImport->setFixedSize(88, 38); bnImport->setProperty("ssType", "progManageTool"); hBox->addWidget(bnImport); connect(bnImport, &QPushButton::clicked, this, [this] { auto dir = QFileDialog::getExistingDirectory(this, tr("Choose Directory"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if(dir.isEmpty()) return; QString progsDir = programsDir(); if(dir.contains(progsDir, Qt::CaseInsensitive)) { QMessageBox::warning(this, tr("Tip"), tr("The imported directory is already in the working directory, so there is no need to import it again!")); return; } QStringList progDirs; if(QFileInfo::exists(dir + "/pro.json")) progDirs.append(dir); else { QStringList subdirNames = QDir(dir).entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); foreach(QString subdirName, subdirNames) { auto subdir = dir + "/" + subdirName; if(! QFileInfo::exists(subdir + "/pro.json")) continue; if(QFileInfo::exists(progsDir + "/" + subdirName)) { auto res = QMessageBox::information(this, tr("Tip Info"), subdirName + tr(":solution(s) already exist.are you sure you want to overwrite the existing solution(s)?"), QMessageBox::Yes, QMessageBox::No); if(res == QMessageBox::No) continue; } progDirs.append(subdir); } if(progDirs.isEmpty()) return; } ProgPortDlg dlg(this, tr("Import")); dlg.table->setRowCount(progDirs.count()); for(int i=0; isetItem(i, 0, new QTableWidgetItem(QFileInfo(progDirs[i]).fileName())); dlg.table->setCellWidget(i, 1, new QProgressBar); } connect(dlg.bnOK, &QPushButton::clicked, this, [=, &dlg] { for(int i=0; icellWidget(i, 1))->setMaximum(dirFileSize(progDirs[i])); auto thread = new CopyDirThread(); thread->dirSrcs = progDirs; thread->dirDst = progsDir; connect(thread, &CopyDirThread::sigProgress, &dlg, [&dlg](int i, int value) { ((QProgressBar*)dlg.table->cellWidget(i, 1))->setValue(value); }); thread->start(); }); dlg.exec(); mProgTree->clear(); QStringList progNames = QDir(mProgsDir).entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); foreach(QString pro_name, progNames) { QFile jFile(mProgsDir + "/" + pro_name + "/pro.json"); if(! jFile.exists()) continue; if(! jFile.open(QIODevice::ReadOnly)) continue; auto data = jFile.readAll(); jFile.close(); m_pwPorgramItemList.append(new ProgItem(mProgsDir, QJsonDocument::fromJson(data).object(), mProgTree)); } }); bnExport = new QPushButton(tr("Export")); bnExport->setFixedSize(QSize(88, 38)); bnExport->setEnabled(false); bnExport->setProperty("ssType", "progManageTool"); hBox->addWidget(bnExport); connect(bnExport, &QPushButton::clicked, this, [=] { int cnt = mProgTree->topLevelItemCount(); QStringList progNames; for(int i=0; iitem(i)->checkState("check") == Qt::Checked) progNames.append(((ProgItem*) mProgTree->topLevelItem(i))->mName); if(progNames.isEmpty()) return; ProgPortDlg dlg(this, tr("Export")); dlg.table->setRowCount(progNames.count()); for(int i=0; isetItem(i, 0, new QTableWidgetItem(progNames[i])); dlg.table->setCellWidget(i, 1, new QProgressBar); } connect(dlg.bnOK, &QPushButton::clicked, this, [=, &dlg] { QString dirDst = QFileDialog::getExistingDirectory(this, tr("Choose Directory"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if(dirDst.isEmpty()) return; auto progsDir = programsDir(); auto thread = new CopyDirThread(); for(int i=0; icellWidget(i, 1))->setMaximum(dirFileSize(dir)); thread->dirSrcs.append(dir); } thread->dirDst = dirDst; connect(thread, &CopyDirThread::sigProgress, &dlg, [&dlg](int i, int value) { ((QProgressBar*)dlg.table->cellWidget(i, 1))->setValue(value); }); thread->start(); }); dlg.exec(); }); bnSend = new QPushButton(tr("Send")); bnSend->setFixedSize(QSize(88, 38)); bnSend->setProperty("ssType", "progManageTool"); bnSend->setEnabled(false); bnSend->hide(); hBox->addWidget(bnSend); btnPlay = new QPushButton(tr("Play")+"/"+tr("Stop")); btnPlay->setFixedSize(QSize(88, 38)); btnPlay->setProperty("ssType", "progManageTool"); hBox->addWidget(btnPlay); connect(btnPlay, &QPushButton::clicked, this, [this] { if(PlayWin::self) PlayWin::self->close(); else { int cnt = mProgTree->topLevelItemCount(); for(int i=0; iitem(i)->checkState("check") == Qt::Checked) { auto item = (ProgItem*) mProgTree->topLevelItem(i); auto dir = mProgsDir+"/"+item->mName+"_tmp"; QFile file(dir+"/program"); if(! file.open(QIODevice::ReadOnly | QIODevice::Text)) return; auto value = file.readAll(); file.close(); QString jsErr; auto prog = JFrom(value, &jsErr); if(! jsErr.isEmpty()) return; if(item->mSplitWidths.isEmpty()) PlayWin::self = PlayWin::newIns(item->mWidth, item->mHeight, dir, prog); else PlayWin::self = PlayWin::newIns(item->mMaxWidth, item->mHeight * item->mSplitWidths.size(), dir, prog); break; } } }); hBox->addStretch(); auto fdSearch = new QLineEdit; fdSearch->setFixedWidth(200); auto search = new QAction; search->setIcon(QIcon(":/res/program/bnSearch.png")); fdSearch->addAction(search, QLineEdit::LeadingPosition); fdSearch->setClearButtonEnabled(true); fdSearch->setStyleSheet("border: 2px solid #aaa;"); connect(fdSearch, &QLineEdit::textChanged, this, [this](const QString &text) { auto cnt = mProgTree->topLevelItemCount(); for(int i=0; iitem(i); item->setHidden(! (text.isEmpty() || item->text("name").contains(text) || item->text("resolution").contains(text))); } }); hBox->addWidget(fdSearch); auto table = new LoQTreeWidget; table->addCol("#", "", 20); table->addCol("check", "", 36).margin(6); table->addCol("name", "", 300, QHeaderView::Stretch); table->addCol("resolution", "", 150, QHeaderView::Stretch); table->addCol("size", "", 100, QHeaderView::Stretch); table->addCol("lasttime", "", 180); table->addCol("usb", "", 80); table->addCol("send", "", 80); table->setDefs()->setHeaderAlignC(); table->addFd(); table->minRowHeight = 36; table->setSelectionMode(QAbstractItemView::NoSelection); table->setSortingEnabled(true); connect(table, &LoQTreeWidget::selChanged, this, [=] { auto en = table->fdCheckAll->checkState()!=Qt::Unchecked; bnEdit->setEnabled(en); bnDelete->setEnabled(en); bnExport->setEnabled(en); bnSend->setEnabled(en); }); vBox->addWidget(mProgTree = table); QString doc_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); if(!doc_path.isEmpty()) { QString app_path = doc_path + "/" + QApplication::applicationName(); mProgsDir = app_path + "/NPrograms"; if(!QFileInfo::exists(mProgsDir)) QDir(app_path).mkdir("NPrograms"); } //查找根路径下的项目文件夹,查找文件夹下的节目pro.json信息,包括节目名称,大小,像素,备注等信息 if(!mProgsDir.isEmpty()) { QDir root_dir(mProgsDir); QStringList pro_list = root_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); foreach(QString pro_name, pro_list) { QDir pro_dir(mProgsDir + "/" + pro_name); if(pro_dir.exists("pro.json")) { QFile fPro(pro_dir.path() + "/pro.json"); fPro.open(QIODevice::ReadOnly); QJsonDocument pro = QJsonDocument::fromJson(fPro.readAll()); fPro.close(); m_pwPorgramItemList.append(new ProgItem(mProgsDir, pro.object(), mProgTree)); } } } QSettings settings; if(settings.value("ProgramListSortOrder").toInt()==0) mProgTree->sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::AscendingOrder); else mProgTree->sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::DescendingOrder); transUi(); } void ProgPanel::changeEvent(QEvent *event) { QWidget::changeEvent(event); if(event->type() == QEvent::LanguageChange) transUi(); } void ProgPanel::transUi() { mProgTree->headerItem()->setText("name"**mProgTree, tr("Name")); mProgTree->headerItem()->setText("resolution"**mProgTree, tr("Resolution")); mProgTree->headerItem()->setText("size"**mProgTree, tr("File Size")); mProgTree->headerItem()->setText("lasttime"**mProgTree, tr("Last Modify")); mProgTree->headerItem()->setText("usb"**mProgTree, tr("USB Update")); mProgTree->headerItem()->setText("send"**mProgTree, tr("Publish")); bnNew->setText(tr("New")); bnEdit->setText(tr("Edit")); bnDelete->setText(tr("Delete")); bnImport->setText(tr("Import")); bnExport->setText(tr("Export")); bnSend->setText(tr("Send")); btnPlay->setText(tr("Play")+"/"+tr("Stop")); } void ProgPanel::onEditClicked(bool){ int cnt = mProgTree->topLevelItemCount(); for(int i=0; iitem(i)->checkState("check") == Qt::Checked) { auto item = static_cast(mProgTree->topLevelItem(i)); auto editor = new ProgEditorWin(item, this); editor->show(); break; } } } bool ProgPanel::checkIfNameRepeated(const QString &name, QTreeWidgetItem *skip){ int cnt = mProgTree->topLevelItemCount(); for(int i=0; i(mProgTree->topLevelItem(i)); if(item == skip) continue; if(name == item->mName) { QMessageBox::warning(this, tr("Warning"), tr("Program name conflicted")); return true; } } return false; } void ProgPanel::onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize res, QString remarks, QList &splitWidths, int max) { if(checkIfNameRepeated(name)) return; auto item = new ProgItem(mProgsDir, name, res.width(), res.height(), remarks, splitWidths, 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(); } void ProgPanel::onDeleteClicked(bool){ auto res = QMessageBox::information(this, tr("Tip Info"), tr("You will delete the selected solution(s),are you sure?"), QMessageBox::Ok, QMessageBox::Cancel); if(res == QMessageBox::Ok) { for(int i=0; itopLevelItemCount(); i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) { auto item = (ProgItem*) mProgTree->topLevelItem(i--); item->del(); delete item; } mProgTree->fdCheckAll->blockSignals(true); mProgTree->fdCheckAll->setCheckState(Qt::Unchecked); mProgTree->fdCheckAll->blockSignals(false); emit mProgTree->selChanged(); } } ProgPortDlg::ProgPortDlg(QWidget *parent, QString title) : QDialog(parent) { #ifdef Q_OS_WIN setWindowFlag(Qt::WindowContextHelpButtonHint, 0); #endif resize(600, 400); setWindowTitle(title); auto vBox = new VBox(this); vBox->setContentsMargins(0, 0, 0, 6); table = new QTableWidget(0, 2); table->setSelectionMode(QTableWidget::NoSelection); table->setEditTriggers(QAbstractItemView::NoEditTriggers); table->setAlternatingRowColors(true); table->horizontalHeader()->setBackgroundRole(QPalette::Window); table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); table->horizontalHeader()->resizeSection(1, 200); table->setHorizontalHeaderLabels({tr("Solution Name"), tr("Progress")}); vBox->addWidget(table); auto hBox = new HBox(vBox); hBox->addStretch(); bnOK = new QPushButton(title); hBox->addWidget(bnOK); auto bnDone = new QPushButton(tr("Done")); connect(bnDone, &QPushButton::clicked, this, &QDialog::accept); hBox->addWidget(bnDone); }