470 lines
20 KiB
C++
470 lines
20 KiB
C++
#include "progpanel.h"
|
|
#include "program/progitem.h"
|
|
#include "main.h"
|
|
#include "gutil/qgui.h"
|
|
#include "player/playwin.h"
|
|
#include "program/progeditorwin.h"
|
|
#include "program/copydirthread.h"
|
|
#include <QApplication>
|
|
#include <QMessageBox>
|
|
#include <QStandardPaths>
|
|
#include <QProgressBar>
|
|
#include <QFileDialog>
|
|
#include <QLineEdit>
|
|
#include <QProcess>
|
|
#include <QInputDialog>
|
|
|
|
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->setMinimumSize(75, 30);
|
|
bnNew->setProperty("ssType", "progManageTool");
|
|
hBox->addWidget(bnNew);
|
|
connect(bnNew, &QPushButton::clicked, this, [this] {
|
|
ProgCreateDlg dlg("", gProgWidth, gProgHeight, "", "", false, this);
|
|
if(dlg.exec() != QDialog::Accepted) return;
|
|
if(checkIfNameRepeated(dlg.fdName->text())) return;
|
|
std::vector<int> widths;
|
|
int max = 0;
|
|
auto width = dlg.fdVer->isChecked() ? dlg.fdHeight->value() : dlg.fdWidth->value();
|
|
if(dlg.fdIsUltraLong->isChecked()) {
|
|
auto partLengths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts);
|
|
int ttl = 0;
|
|
for(auto &partLength : partLengths) {
|
|
int val = partLength.toInt();
|
|
if(val==0) continue;
|
|
if(max < val) max = val;
|
|
ttl += val;
|
|
widths.emplace_back(val);
|
|
if(ttl>=width) break;
|
|
}
|
|
if(max) {
|
|
while(ttl < width) {
|
|
ttl += max;
|
|
widths.emplace_back(max);
|
|
}
|
|
if(ttl > width) widths.back() -= ttl - width;
|
|
}
|
|
}
|
|
auto item = new ProgItem(mProgsDir, dlg.fdName->text(), gProgWidth = dlg.fdWidth->value(), gProgHeight = dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, dlg.fdVer->isChecked(), mProgTree);
|
|
item->isInsert = dlg.edIsInsert->isChecked();
|
|
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->setMinimumSize(75, 30);
|
|
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->setMinimumSize(75, 30);
|
|
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->setMinimumSize(75, 30);
|
|
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;
|
|
auto progsDir = programsDir();
|
|
if(dir.contains(progsDir, Qt::CaseInsensitive)) {
|
|
QMessageBox::warning(this, translate("","Tip"), tr("The imported directory is already in the working directory, so there is no need to import it again!"));
|
|
return;
|
|
}
|
|
PathPairList pathPairs;
|
|
if(QFileInfo::exists(dir + "/pro.json")) pathPairs.append({dir, progsDir+"/"+QFileInfo(dir).fileName()});
|
|
else {
|
|
QStringList subdirNames = QDir(dir).entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
|
|
for(QString &subdirName : subdirNames) {
|
|
auto subdir = dir + "/" + subdirName;
|
|
if(! QFileInfo::exists(subdir + "/pro.json")) continue;
|
|
if(QFileInfo::exists(progsDir + "/" + subdirName)) {
|
|
auto res = QMessageBox::information(this, translate("","Tip"), 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;
|
|
}
|
|
pathPairs.append({subdir, progsDir+"/"+subdirName});
|
|
}
|
|
if(pathPairs.isEmpty()) return;
|
|
}
|
|
ProgPortDlg dlg(this, tr("Import"));
|
|
dlg.table->setRowCount(pathPairs.count());
|
|
for(int i=0; i<pathPairs.count(); i++) {
|
|
dlg.table->setItem(i, 0, new QTableWidgetItem(QFileInfo(pathPairs[i].first).fileName()));
|
|
dlg.table->setCellWidget(i, 1, new QProgressBar);
|
|
}
|
|
connect(dlg.bnOK, &QPushButton::clicked, this, [=, &dlg] {
|
|
for(int i=0; i<pathPairs.count(); i++) ((QProgressBar*)dlg.table->cellWidget(i, 1))->setMaximum(dirFileSize(pathPairs[i].first));
|
|
auto thread = new CopyDirThread;
|
|
thread->paths = pathPairs;
|
|
connect(thread, &CopyDirThread::sigProgress, &dlg, [&dlg](int i, int value) {
|
|
((QProgressBar*)dlg.table->cellWidget(i, 1))->setValue(value);
|
|
});
|
|
thread->start();
|
|
});
|
|
dlg.exec();
|
|
addProFiles();
|
|
});
|
|
|
|
bnExport = new QPushButton(tr("Export"));
|
|
bnExport->setMinimumSize(75, 30);
|
|
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; i<cnt; i++) if(mProgTree->item(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; i<progNames.count(); i++) {
|
|
dlg.table->setItem(i, 0, new QTableWidgetItem(progNames[i]));
|
|
dlg.table->setCellWidget(i, 1, new QProgressBar);
|
|
}
|
|
connect(dlg.bnOK, &QPushButton::clicked, this, [=, &dlg] {
|
|
auto 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; i<progNames.count(); i++) {
|
|
auto dir = progsDir+"/"+progNames[i];
|
|
((QProgressBar*)dlg.table->cellWidget(i, 1))->setMaximum(dirFileSize(dir));
|
|
thread->paths.append({dir, dirDst+"/"});
|
|
}
|
|
connect(thread, &CopyDirThread::sigProgress, &dlg, [&dlg](int i, int value) {
|
|
((QProgressBar*)dlg.table->cellWidget(i, 1))->setValue(value);
|
|
});
|
|
thread->start();
|
|
});
|
|
dlg.exec();
|
|
});
|
|
|
|
bnRename = new QPushButton(tr("Rename"));
|
|
bnRename->setMinimumSize(60, 30);
|
|
bnRename->setProperty("ssType", "progManageTool");
|
|
hBox->addWidget(bnRename);
|
|
connect(bnRename, &QPushButton::clicked, this, [=] {
|
|
int cnt = mProgTree->topLevelItemCount();
|
|
QString progName;
|
|
for(int i=0; i<cnt; i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
|
|
progName = ((ProgItem*) mProgTree->topLevelItem(i))->mName;
|
|
break;
|
|
}
|
|
if(progName.isEmpty()) return;
|
|
bool ok = false;
|
|
auto newName = QInputDialog::getText(this, "Rename '"+progName+"'", "New Name", QLineEdit::Normal, "", &ok);
|
|
if(! ok) return;
|
|
if(newName.isEmpty()) {
|
|
QMessageBox::warning(this, "Warning", "New Name is Empty");
|
|
return;
|
|
}
|
|
auto progsDir = programsDir();
|
|
auto res = QDir(progsDir).rename(progName, newName);
|
|
if(res) addProFiles();
|
|
else QMessageBox::warning(this, "Error", "Rename Failed");
|
|
});
|
|
// bnCopy = new QPushButton(tr("Copy"));
|
|
// bnCopy->setMinimumSize(60, 30);
|
|
// bnCopy->setProperty("ssType", "progManageTool");
|
|
// hBox->addWidget(bnCopy);
|
|
// connect(bnCopy, &QPushButton::clicked, this, [=] {
|
|
// int cnt = mProgTree->topLevelItemCount();
|
|
// QString progName;
|
|
// for(int i=0; i<cnt; i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
|
|
// progName = ((ProgItem*) mProgTree->topLevelItem(i))->mName;
|
|
// break;
|
|
// }
|
|
// if(progName.isEmpty()) return;
|
|
// bool ok = false;
|
|
// auto newName = QInputDialog::getText(this, "Copy '"+progName+"'", "New Name", QLineEdit::Normal, "", &ok);
|
|
// if(! ok) return;
|
|
// if(newName.isEmpty()) {
|
|
// QMessageBox::warning(this, "Warning", "New Name is Empty");
|
|
// return;
|
|
// }
|
|
// auto progsDir = programsDir();
|
|
// auto dir = progsDir+"/"+progName;
|
|
// QDialog dlg(this);
|
|
// auto vBox = new VBox(&dlg);
|
|
// auto edProgress = new QProgressBar;
|
|
// edProgress->setMaximum(dirFileSize(dir));
|
|
// vBox->addWidget(edProgress);
|
|
// auto thread = new CopyDirThread;
|
|
// thread->paths.append({dir, progsDir+"/"+newName});
|
|
// connect(thread, &CopyDirThread::sigProgress, edProgress, [=](int value) {
|
|
// edProgress->setValue(value);
|
|
// if(value>=edProgress->maximum()) addProFiles();
|
|
// });
|
|
// progress->show();
|
|
// thread->start();
|
|
// });
|
|
|
|
bnSend = new QPushButton(translate("","Send"));
|
|
bnSend->setMinimumSize(75, 30);
|
|
bnSend->setProperty("ssType", "progManageTool");
|
|
bnSend->setEnabled(false);
|
|
bnSend->hide();
|
|
hBox->addWidget(bnSend);
|
|
|
|
btnPlay = new QPushButton(tr("Play")+"/"+tr("Stop"));
|
|
btnPlay->setMinimumSize(75, 30);
|
|
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; i<cnt; i++) if(mProgTree->item(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->partLens.empty()) PlayWin::self = PlayWin::newIns(item->mWidth, item->mHeight, dir, prog);
|
|
else PlayWin::self = item->isVer ? PlayWin::newIns(item->mWidth * item->partLens.size(), item->maxLen, dir, prog) : PlayWin::newIns(item->maxLen, item->mHeight * item->partLens.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; i<cnt; i++) {
|
|
auto item = mProgTree->item(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);
|
|
});
|
|
connect(table, &LoQTreeWidget::itemPressed, this, [=](QTreeWidgetItem *item, int) {
|
|
if(((QApplication*)QApplication::instance())->mouseButtons()==Qt::RightButton) {
|
|
auto menu = new QMenu(table);
|
|
auto act = new QAction("Open folder");
|
|
menu->addAction(act);
|
|
connect(act, &QAction::triggered, this, [=] {
|
|
#ifdef Q_OS_WINDOWS
|
|
auto str = ((ProgItem*)item)->mProgDir;
|
|
QProcess::execute("explorer", {str.replace('/','\\')});
|
|
#endif
|
|
#ifdef Q_OS_MAC
|
|
QProcess::execute("open", {"-R", ((ProgItem*)item)->mProgDir});
|
|
#endif
|
|
});
|
|
menu->exec(QCursor::pos()+QPoint{2,2});
|
|
}
|
|
});
|
|
vBox->addWidget(mProgTree = table);
|
|
|
|
auto dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
|
if(! dataDir.isEmpty()) {
|
|
mProgsDir = dataDir + "/programs";
|
|
if(! QFileInfo::exists(mProgsDir)) {
|
|
qDebug()<<"mkdir programs"<<QDir(dataDir).mkdir("programs");
|
|
auto oldProgsDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)+"/"+QApplication::applicationName()+"/NPrograms";
|
|
QDir oldProgsQDir(oldProgsDir);
|
|
if(oldProgsQDir.exists()) {
|
|
CopyDirThread thread;
|
|
auto names = oldProgsQDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
|
|
for(auto &name : names) if(! name.endsWith("_tmp")) thread.paths.append({oldProgsDir+"/"+name, mProgsDir+"/"+name});
|
|
if(! thread.paths.isEmpty()) thread.move();
|
|
oldProgsQDir.removeRecursively();
|
|
}
|
|
}
|
|
}
|
|
addProFiles();
|
|
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"));
|
|
bnRename->setText(tr("Rename"));
|
|
bnSend->setText(translate("","Send"));
|
|
btnPlay->setText(tr("Play")+"/"+tr("Stop"));
|
|
}
|
|
|
|
void ProgPanel::addProFiles() {
|
|
if(mProgsDir.isEmpty()) return;
|
|
auto progNames = QDir(mProgsDir).entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
|
|
mProgTree->clear();
|
|
for(auto &progName : progNames) {
|
|
auto file = mProgsDir + "/" + progName + "/pro.json";
|
|
QFile qFile(file);
|
|
if(! qFile.exists()) continue;
|
|
if(! qFile.open(QIODevice::ReadOnly)) continue;
|
|
auto data = qFile.readAll();
|
|
qFile.close();
|
|
QString error;
|
|
auto json = JFrom(data, &error);
|
|
if(! error.isEmpty()) continue;
|
|
auto item = new ProgItem(mProgTree);
|
|
item->mProgsDir = mProgsDir;
|
|
item->mName = progName;
|
|
item->mWidth = json["resolution"]["w"].toInt();
|
|
item->mHeight = json["resolution"]["h"].toInt();
|
|
item->mRemark = json["remarks"].toString();
|
|
item->isInsert = json["isInsert"].toBool();
|
|
item->isVer = json["isVer"].toBool();
|
|
auto partLengths = json["splitWidths"].toArray();
|
|
for(auto &partLength : partLengths) {
|
|
auto len = partLength.toInt();
|
|
if(item->maxLen < len) item->maxLen = len;
|
|
item->partLens.emplace_back(len);
|
|
}
|
|
item->m_fsize = json["file_size"].toDouble();
|
|
item->mProgDir = item->mProgsDir + "/" + item->mName;
|
|
item->m_orgName = item->mName;
|
|
item->setText("lasttime", QFileInfo(file).lastModified().toString("yyyy-MM-dd hh:mm:ss"));
|
|
item->init();
|
|
}
|
|
}
|
|
|
|
void ProgPanel::onEditClicked(bool){
|
|
int cnt = mProgTree->topLevelItemCount();
|
|
for(int i=0; i<cnt; i++) {
|
|
if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
|
|
auto item = static_cast<ProgItem*>(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<cnt; i++) {
|
|
auto item = static_cast<ProgItem*>(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::onDeleteClicked(bool){
|
|
auto res = QMessageBox::information(this, translate("","Tip"), tr("You will delete the selected solution(s),are you sure?"), QMessageBox::Ok, QMessageBox::Cancel);
|
|
if(res == QMessageBox::Ok) {
|
|
for(int i=0; i<mProgTree->topLevelItemCount(); 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);
|
|
}
|