From 834cbd88f87111be8a3e93c4932d508db49fd695 Mon Sep 17 00:00:00 2001 From: Skykey Date: Tue, 30 Jun 2020 02:54:08 +0800 Subject: [PATCH] First Build --- PKGBUILD_ASSISTANT.pro | 9 + PKGBUILD_ASSISTANT.pro.user | 2 +- dialogfilechmod.cpp | 86 ++++ dialogfilechmod.h | 38 ++ dialogfilecopy.cpp | 118 ++++++ dialogfilecopy.h | 37 ++ dialogfiledelete.cpp | 77 ++++ dialogfiledelete.h | 32 ++ ico.png | Bin 0 -> 21156 bytes pkgbuildassistant.cpp | 818 ++++++++++++++++++++++++++++++++++-- pkgbuildassistant.h | 21 +- res.qrc | 5 + 12 files changed, 1206 insertions(+), 37 deletions(-) create mode 100644 dialogfilechmod.cpp create mode 100644 dialogfilechmod.h create mode 100644 dialogfilecopy.cpp create mode 100644 dialogfilecopy.h create mode 100644 dialogfiledelete.cpp create mode 100644 dialogfiledelete.h create mode 100644 ico.png create mode 100644 res.qrc diff --git a/PKGBUILD_ASSISTANT.pro b/PKGBUILD_ASSISTANT.pro index 39a25b7..0e1b989 100644 --- a/PKGBUILD_ASSISTANT.pro +++ b/PKGBUILD_ASSISTANT.pro @@ -16,10 +16,16 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + dialogfilechmod.cpp \ + dialogfilecopy.cpp \ + dialogfiledelete.cpp \ main.cpp \ pkgbuildassistant.cpp HEADERS += \ + dialogfilechmod.h \ + dialogfilecopy.h \ + dialogfiledelete.h \ pkgbuildassistant.h FORMS += \ @@ -29,3 +35,6 @@ FORMS += \ qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target + +RESOURCES += \ + res.qrc diff --git a/PKGBUILD_ASSISTANT.pro.user b/PKGBUILD_ASSISTANT.pro.user index 68b44f0..b599daf 100644 --- a/PKGBUILD_ASSISTANT.pro.user +++ b/PKGBUILD_ASSISTANT.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/dialogfilechmod.cpp b/dialogfilechmod.cpp new file mode 100644 index 0000000..dc814b7 --- /dev/null +++ b/dialogfilechmod.cpp @@ -0,0 +1,86 @@ +#include "dialogfilechmod.h" + +DialogFileChmod::DialogFileChmod(QWidget *parent, int mode) : QDialog(parent), _mode(mode) +{ + setWindowIcon(QIcon(":/ico.png")); + + setFixedSize(QSize(600,150)); + + mainLay = new QVBoxLayout(this); + le_fileName = new QLineEdit; + le_mod = new QLineEdit; + combox = new QComboBox; + + QHBoxLayout *lay_edit = new QHBoxLayout; + QHBoxLayout *lay_mod = new QHBoxLayout; + QHBoxLayout *lay_btns = new QHBoxLayout; + + mainLay->addLayout(lay_edit); + mainLay->addLayout(lay_mod); + mainLay->addLayout(lay_btns); + + lay_edit->addWidget(new QLabel("目标路径:")); + lay_edit->addWidget(combox); + lay_edit->addWidget(le_fileName); + + lay_mod->addWidget(new QLabel("目标权限:")); + lay_mod->addWidget(le_mod); + lay_mod->addStretch(3); + + combox->addItem("${srcdir}"); + combox->addItem("${pkgdir}"); + combox->setCurrentIndex(1); + + QPushButton *btn_cancel = new QPushButton("取消"); + QPushButton *btn_apply = new QPushButton("确定"); + + lay_btns->addStretch(); + lay_btns->addWidget(btn_cancel); + lay_btns->addStretch(); + lay_btns->addWidget(btn_apply); + lay_btns->addStretch(); + + le_fileName->setText("/"); + + //file + if(_mode == 0) + { + setWindowTitle("更改文件权限"); + } + + //dir + if(_mode == 1) + { + setWindowTitle("更改文件夹权限"); + } + + connect(btn_cancel, &QPushButton::clicked, [=](){ + int ret = QMessageBox::question(this, "确认退出", "确认退出文件权限更改吗?"); + + if(ret == QMessageBox::Yes) + { + close(); + } + }); + + connect(btn_apply, &QPushButton::clicked, [=](){ + if(le_fileName->text()=="/" || le_mod->text().isEmpty()) + { + QMessageBox::critical(this, "错误!", "请填写目标路径及对应权限!"); + + return; + } + + if(_mode == 0) + { + emit signalAddOperation(tr("chmod 0%1 %2").arg(le_mod->text()).arg(combox->currentText()+le_fileName->text())); + } + + if(_mode == 1) + { + emit signalAddOperation(tr("chmod -R 0%1 %2").arg(le_mod->text()).arg(combox->currentText()+le_fileName->text())); + } + }); + + +} diff --git a/dialogfilechmod.h b/dialogfilechmod.h new file mode 100644 index 0000000..c261653 --- /dev/null +++ b/dialogfilechmod.h @@ -0,0 +1,38 @@ +#ifndef DIALOGFILECHMOD_H +#define DIALOGFILECHMOD_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class DialogFileChmod : public QDialog +{ + Q_OBJECT +public: + explicit DialogFileChmod(QWidget *parent = nullptr, int mode =0); + + QVBoxLayout *mainLay; + + QComboBox *combox; + + QLineEdit *le_fileName; + + QLineEdit *le_mod; + + +private: + int _mode; + +signals: + + void signalAddOperation(QString operation); + +}; + +#endif // DIALOGFILECHMOD_H diff --git a/dialogfilecopy.cpp b/dialogfilecopy.cpp new file mode 100644 index 0000000..1425c71 --- /dev/null +++ b/dialogfilecopy.cpp @@ -0,0 +1,118 @@ +#include "dialogfilecopy.h" + +DialogFileCopy::DialogFileCopy(QWidget *parent, int mode) : QDialog(parent), _mode(mode) +{ + setWindowIcon(QIcon(":/ico.png")); + + setFixedSize(QSize(600,200)); + + mainLay = new QVBoxLayout(this); + + QHBoxLayout *hlay_source = new QHBoxLayout; + QHBoxLayout *hlay_destination = new QHBoxLayout; + QHBoxLayout *hlay_btns = new QHBoxLayout; + + check_binary = new QCheckBox("可执行文件"); + + mainLay->addWidget(check_binary); + mainLay->addLayout(hlay_source); + mainLay->addLayout(hlay_destination); + mainLay->addLayout(hlay_btns); + + combox_source = new QComboBox; + combox_destination = new QComboBox; + le_source = new QLineEdit; + le_destination = new QLineEdit; + + QPushButton *btn_cancel = new QPushButton("取消"); + QPushButton *btn_apply = new QPushButton("确定"); + + hlay_source->addWidget(new QLabel("源路径:")); + hlay_source->addWidget(combox_source); + hlay_source->addWidget(le_source); + + + hlay_destination->addWidget(new QLabel("目标路径:")); + hlay_destination->addWidget(combox_destination); + hlay_destination->addWidget(le_destination); + + + hlay_btns->addStretch(); + hlay_btns->addWidget(btn_cancel); + hlay_btns->addStretch(); + hlay_btns->addWidget(btn_apply); + hlay_btns->addStretch(); + + combox_source->addItem("${srcdir}"); + combox_source->addItem("${pkgdir}"); + combox_source->setCurrentIndex(0); + + combox_destination->addItem("${srcdir}"); + combox_destination->addItem("${pkgdir}"); + combox_destination->setCurrentIndex(1); + + le_source->setText("/"); + le_destination->setText("/"); + + check_binary->setChecked(false); + + if(_mode==0) //文件 + { + setWindowTitle("复制文件"); + + check_binary->setCheckable(true); + + } + + if(_mode==1) //文件夹 + { + setWindowTitle("复制文件夹"); + + check_binary->setCheckable(false); + } + + + connect(btn_cancel, &QPushButton::clicked, [=](){ + int ret = QMessageBox::question(this, "确认退出", "确认退出文件拷贝吗?"); + + if(ret == QMessageBox::Yes) + { + close(); + } + }); + + connect(btn_apply, &QPushButton::clicked, [=](){ + if(le_source->text()=="/" || le_destination->text()=="/") + { + QMessageBox::critical(this, "错误!", "请填写源路径和目标路径!"); + + return; + } + + if(_mode == 0) + { + + if(check_binary->isChecked()) + { + emit signalAddOperation(tr("install -Dm755 %1 %2").arg(combox_source->currentText()+le_source->text()).arg(combox_destination->currentText()+le_destination->text())); + } + else + { + emit signalAddOperation(tr("install -Dm644 %1 %2").arg(combox_source->currentText()+le_source->text()).arg(combox_destination->currentText()+le_destination->text())); + } + } + + if(_mode == 1) + { + + if(le_source->text().at(le_source->text().length()-1)!='/') + { + le_source->setText(le_source->text()+"/"); + } + + emit signalAddOperation(tr("install -Dm644 %1* %2").arg(combox_source->currentText()+le_source->text()).arg(combox_destination->currentText()+le_destination->text())); + } + }); + +} + diff --git a/dialogfilecopy.h b/dialogfilecopy.h new file mode 100644 index 0000000..2d7b54f --- /dev/null +++ b/dialogfilecopy.h @@ -0,0 +1,37 @@ +#ifndef DIALOGFILECOPY_H +#define DIALOGFILECOPY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class DialogFileCopy : public QDialog +{ + Q_OBJECT +public: + explicit DialogFileCopy(QWidget *parent = nullptr, int mode = 0); + + QVBoxLayout *mainLay; + + QComboBox *combox_source; + QComboBox *combox_destination; + QCheckBox *check_binary; + + QLineEdit *le_source; + QLineEdit *le_destination; + +private: + int _mode; +signals: + void signalAddOperation(QString operation); + +}; + +#endif // DIALOGFILECOPY_H diff --git a/dialogfiledelete.cpp b/dialogfiledelete.cpp new file mode 100644 index 0000000..2fe88a8 --- /dev/null +++ b/dialogfiledelete.cpp @@ -0,0 +1,77 @@ +#include "dialogfiledelete.h" + +DialogFileDelete::DialogFileDelete(QWidget *parent, int mode) : QDialog(parent), _mode(mode) +{ + setWindowIcon(QIcon(":/ico.png")); + + setFixedSize(QSize(600,100)); + + mainLay = new QVBoxLayout(this); + le_fileName = new QLineEdit; + combox = new QComboBox; + + QHBoxLayout *lay_edit = new QHBoxLayout; + QHBoxLayout *lay_btns = new QHBoxLayout; + + mainLay->addLayout(lay_edit); + mainLay->addLayout(lay_btns); + + lay_edit->addWidget(new QLabel("目标路径:")); + lay_edit->addWidget(combox); + lay_edit->addWidget(le_fileName); + + combox->addItem("${srcdir}"); + combox->addItem("${pkgdir}"); + combox->setCurrentIndex(1); + + QPushButton *btn_cancel = new QPushButton("取消"); + QPushButton *btn_apply = new QPushButton("确定"); + + lay_btns->addStretch(); + lay_btns->addWidget(btn_cancel); + lay_btns->addStretch(); + lay_btns->addWidget(btn_apply); + lay_btns->addStretch(); + + le_fileName->setText("/"); + + //file + if(_mode == 0) + { + setWindowTitle("删除文件"); + } + + //dir + if(_mode == 1) + { + setWindowTitle("删除文件夹"); + } + + connect(btn_cancel, &QPushButton::clicked, [=](){ + int ret = QMessageBox::question(this, "确认退出", "确认退出文件删除吗?"); + + if(ret == QMessageBox::Yes) + { + close(); + } + }); + + connect(btn_apply, &QPushButton::clicked, [=](){ + if(le_fileName->text()=="/") + { + QMessageBox::critical(this, "错误!", "请填写目标路径!"); + + return; + } + + if(_mode == 0) + { + emit signalAddOperation(tr("rm -f %1").arg(combox->currentText()+le_fileName->text())); + } + + if(_mode == 1) + { + emit signalAddOperation(tr("rm -rf %1").arg(combox->currentText()+le_fileName->text())); + } + }); +} diff --git a/dialogfiledelete.h b/dialogfiledelete.h new file mode 100644 index 0000000..c6bf4d4 --- /dev/null +++ b/dialogfiledelete.h @@ -0,0 +1,32 @@ +#ifndef DIALOGFILEDELETE_H +#define DIALOGFILEDELETE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class DialogFileDelete : public QDialog +{ + Q_OBJECT +public: + explicit DialogFileDelete(QWidget *parent = nullptr, int mode = 0); + + QVBoxLayout *mainLay; + + QComboBox *combox; + + QLineEdit *le_fileName; + +private: + int _mode; +signals: + void signalAddOperation(QString operation); +}; + +#endif // DIALOGFILEDELETE_H diff --git a/ico.png b/ico.png new file mode 100644 index 0000000000000000000000000000000000000000..406cd0c09d315af9635399ef8fc21bc33f6d6954 GIT binary patch literal 21156 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 B@+$xU literal 0 HcmV?d00001 diff --git a/pkgbuildassistant.cpp b/pkgbuildassistant.cpp index 5e89512..853feb1 100644 --- a/pkgbuildassistant.cpp +++ b/pkgbuildassistant.cpp @@ -7,6 +7,8 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) { ui->setupUi(this); + setWindowIcon(QIcon(":/ico.png")); + ui->tabWidget->setCurrentIndex(0); /* BaseInfo Tab */ @@ -72,14 +74,23 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) /* Relations Tab */ // Init layout_relationsTab = new QGridLayout(ui->tab_relations); + le_maintainerName = new QLineEdit; + le_maintainerEmail = new QLineEdit; le_provides = new QLineEdit; le_conflicts = new QLineEdit; - layout_relationsTab->addWidget(new QLabel("提供功能:"),0,0); - layout_relationsTab->addWidget(le_provides,0,1); + layout_relationsTab->addWidget(new QLabel("打包者姓名:"),0,0); + layout_relationsTab->addWidget(le_maintainerName,0,1); + + layout_relationsTab->addWidget(new QLabel("打包者邮箱:"),1,0); + layout_relationsTab->addWidget(le_maintainerEmail,1,1); + + layout_relationsTab->addWidget(new QLabel("提供功能:"),2,0); + layout_relationsTab->addWidget(le_provides,2,1); + + layout_relationsTab->addWidget(new QLabel("冲突:"),3,0); + layout_relationsTab->addWidget(le_conflicts,3,1); - layout_relationsTab->addWidget(new QLabel("冲突:"),1,0); - layout_relationsTab->addWidget(le_conflicts,1,1); /* Depends Tab */ @@ -124,13 +135,30 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) { le_dependsDir->setText(dir); dependsDir = new QDir(dir); + + scanSoFiles(); + } }); connect(btn_scanDepends, &QPushButton::clicked, [=](){ if(!le_dependsDir->text().isEmpty()) { - scanSoFiles(); + int ret = QMessageBox::question(this,"请求确认","即将开始查询lib文件包名,程序可能会卡死较长时间,请耐心等待!"); + + // Query the package name + if(ret == QMessageBox::Yes) + {for(int i=0; isetText(pkgname); + + table_depends->setItem(i,1,itemPackage); + } + } } else { @@ -148,9 +176,9 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) group_trees = new QGroupBox("文件树"); group_preview = new QGroupBox("命令预览"); le_fakeDirPath = new QLineEdit; - le_debPath = new QLineEdit; - tree_source = new QTreeWidget; - tree_pkg = new QTreeWidget; + le_archPath = new QLineEdit; + tree_source = new QTextBrowser; + tree_pkg = new QTextBrowser; le_preview = new QTextEdit; layout_functionTab->addWidget(group_setFakeDir); @@ -164,9 +192,9 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) vlay_setFakeDir->addLayout(hlay_fakeDir); QHBoxLayout *hlay_debPath = new QHBoxLayout; - QPushButton *btn_debPath = new QPushButton("选择Deb包"); - hlay_debPath->addWidget(new QLabel("Deb包目录:")); - hlay_debPath->addWidget(le_debPath); + QPushButton *btn_debPath = new QPushButton("选择压缩包"); + hlay_debPath->addWidget(new QLabel("压缩包目录:")); + hlay_debPath->addWidget(le_archPath); hlay_debPath->addWidget(btn_debPath); vlay_setFakeDir->addLayout(hlay_fakeDir); @@ -179,6 +207,8 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) QPushButton *btn_installDir = new QPushButton("拷贝文件夹"); QPushButton *btn_removeFile = new QPushButton("删除文件"); QPushButton *btn_removeDir = new QPushButton("删除文件夹"); + QPushButton *btn_chmodFile = new QPushButton("更改文件权限"); + QPushButton *btn_chmodDir = new QPushButton("更改文件夹权限"); hlay_operation->addStretch(); hlay_operation->addWidget(btn_installFile); @@ -189,6 +219,12 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) hlay_operation->addStretch(); hlay_operation->addWidget(btn_removeDir); hlay_operation->addStretch(); + hlay_operation->addWidget(btn_chmodFile); + hlay_operation->addStretch(); + hlay_operation->addWidget(btn_chmodDir); + hlay_operation->addStretch(); + + layout_functionTab->addWidget(group_trees); QHBoxLayout *hlay_trees = new QHBoxLayout(group_trees); @@ -201,6 +237,11 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) vlay_preview->addWidget(le_preview); + layout_functionTab->setStretchFactor(group_setFakeDir,1); + layout_functionTab->setStretchFactor(group_operation,1); + layout_functionTab->setStretchFactor(group_trees,2); + layout_functionTab->setStretchFactor(group_preview,1); + connect(btn_fakedir, &QPushButton::clicked, [=](){ QString dir = QFileDialog::getExistingDirectory(this,"选择模拟文件夹"); if(dir.isEmpty()) @@ -210,6 +251,7 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) else { le_fakeDirPath->setText(dir); + updateTree(); } }); @@ -220,18 +262,121 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) } else { - QString fileName = QFileDialog::getOpenFileName(this,"选择Deb安装包","","Deb File (*.deb)"); + QString fileName = QFileDialog::getOpenFileName(this,"选择压缩包","","deb archive(*.deb);;tar archive(*.tar.gz)"); if(fileName.isEmpty()) { - QMessageBox::critical(this,"错误","请选择deb安装包"); + QMessageBox::critical(this,"错误","请选择压缩包"); } else { - le_debPath->setText(fileName); + le_archPath->setText(fileName); + + decompress(fileName); + } } }); + connect(btn_installFile, &QPushButton::clicked, [=](){ + if(!le_fakeDirPath->text().isEmpty()) + { + DialogFileCopy *dlg = new DialogFileCopy(this,0); + + void (DialogFileCopy::*pSignalAddOperation)(QString) = &DialogFileCopy::signalAddOperation; + void (PKGBUILDASSISTANT::*pSlotAddOperation)(QString) = &PKGBUILDASSISTANT::slotAddOperation; + connect(dlg, pSignalAddOperation, this, pSlotAddOperation); + + dlg->exec(); + } + else + { + QMessageBox::critical(this, "错误", "请先填写模拟目录"); + } + + + }); + + connect(btn_installDir, &QPushButton::clicked,[=](){ + if(!le_fakeDirPath->text().isEmpty()) + { + DialogFileCopy *dlg = new DialogFileCopy(this,1); + + void (DialogFileCopy::*pSignalAddOperation)(QString) = &DialogFileCopy::signalAddOperation; + void (PKGBUILDASSISTANT::*pSlotAddOperation)(QString) = &PKGBUILDASSISTANT::slotAddOperation; + connect(dlg, pSignalAddOperation, this, pSlotAddOperation); + + dlg->exec(); + } + else + { + QMessageBox::critical(this, "错误", "请先填写模拟目录"); + } + + }); + + connect(btn_removeFile, &QPushButton::clicked, [=](){ + if(!le_fakeDirPath->text().isEmpty()) + { + DialogFileDelete *dlg = new DialogFileDelete(this, 0); + void (DialogFileDelete::*pSignalAddOperation)(QString) = &DialogFileDelete::signalAddOperation; + void (PKGBUILDASSISTANT::*pSlotAddOperation)(QString) = &PKGBUILDASSISTANT::slotAddOperation; + connect(dlg, pSignalAddOperation, this, pSlotAddOperation); + + dlg->exec(); + } + else + { + QMessageBox::critical(this, "错误", "请先填写模拟目录"); + } + }); + + connect(btn_removeDir, &QPushButton::clicked,[=](){ + if(!le_fakeDirPath->text().isEmpty()) + { + DialogFileDelete *dlg = new DialogFileDelete(this,1); + void (DialogFileDelete::*pSignalAddOperation)(QString) = &DialogFileDelete::signalAddOperation; + void (PKGBUILDASSISTANT::*pSlotAddOperation)(QString) = &PKGBUILDASSISTANT::slotAddOperation; + connect(dlg, pSignalAddOperation, this, pSlotAddOperation); + dlg->exec(); + } + else + { + QMessageBox::critical(this, "错误", "请先填写模拟目录"); + } + }); + + connect(btn_chmodFile, &QPushButton::clicked, [=](){ + if(!le_fakeDirPath->text().isEmpty()) + { + DialogFileChmod *dlg = new DialogFileChmod(this,0); + void (DialogFileChmod::*pSignalAddOperation)(QString) = &DialogFileChmod::signalAddOperation; + void (PKGBUILDASSISTANT::*pSlotAddOperation)(QString) = &PKGBUILDASSISTANT::slotAddOperation; + connect(dlg, pSignalAddOperation, this, pSlotAddOperation); + + dlg->exec(); + } + else + { + QMessageBox::critical(this, "错误", "请先填写模拟目录"); + } + }); + + connect(btn_chmodDir, &QPushButton::clicked, [=](){ + if(!le_fakeDirPath->text().isEmpty()) + { + DialogFileChmod *dlg = new DialogFileChmod(this, 1); + void (DialogFileChmod::*pSignalAddOperation)(QString) = &DialogFileChmod::signalAddOperation; + void (PKGBUILDASSISTANT::*pSlotAddOperation)(QString) = &PKGBUILDASSISTANT::slotAddOperation; + connect(dlg, pSignalAddOperation, this, pSlotAddOperation); + + dlg->exec(); + } + else + { + QMessageBox::critical(this, "错误", "请先填写模拟目录"); + } + }); + /* Create Tab */ layout_createTab = new QVBoxLayout(ui->tab_create); @@ -250,10 +395,10 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) QVBoxLayout *vlay_savePrew = new QVBoxLayout(group_savePreview); QHBoxLayout *hlay_savePreviewBtn = new QHBoxLayout; - QPushButton *btn_openPKG = new QPushButton("打开PKGBUILD"); + QPushButton *btn_prevPKG = new QPushButton("生成PKGBUILD"); QPushButton *btn_savePKG = new QPushButton("保存PKGBUILD"); hlay_savePreviewBtn->addStretch(); - hlay_savePreviewBtn->addWidget(btn_openPKG); + hlay_savePreviewBtn->addWidget(btn_prevPKG); hlay_savePreviewBtn->addStretch(); hlay_savePreviewBtn->addWidget(btn_savePKG); hlay_savePreviewBtn->addStretch(); @@ -265,7 +410,7 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) vlay_savePrew->addLayout(hlay_savePreviewEdit); connect(btn_saveFile, &QPushButton::clicked, [=](){ - QString fileName = QFileDialog::getSaveFileName(this,"选择PKGBUILD保存位置"); + QString fileName = QFileDialog::getSaveFileName(this,"选择PKGBUILD保存位置","","PKGBUILD(PKGBUILD)"); if(fileName.isEmpty()) { QMessageBox::critical(this,"错误!","请选择PKGBUILD文件保存位置!"); @@ -276,6 +421,27 @@ PKGBUILDASSISTANT::PKGBUILDASSISTANT(QWidget *parent) } }); + connect(btn_prevPKG, &QPushButton::clicked, this, &PKGBUILDASSISTANT::createFile); + + connect(btn_savePKG, &QPushButton::clicked, [=](){ + if(le_savePath->text().isEmpty()) + { + QMessageBox::critical(this, "保存失败", "保存失败,请先选择PKGBUILD文件保存路径!"); + + return; + } + + QFile file(le_savePath->text()); + file.open(QFile::ReadWrite); + + file.write(le_savePreview->toPlainText().toUtf8()); + + file.close(); + + ui->statusbar->showMessage("PKGBUILD文件已保存",2000); + }); + + } PKGBUILDASSISTANT::~PKGBUILDASSISTANT() @@ -308,37 +474,627 @@ void PKGBUILDASSISTANT::scanSoFiles() table_depends->setItem(table_depends->rowCount()-1,0,itemName); } + ui->statusbar->showMessage(tr("目录便利完毕,共找到了%1个lib文件").arg(list_so.size()),2000); - // Query the package name - for(int i=0; itext()); + + if(!dir.exists("src")) + dir.mkdir("src"); + + if(!dir.exists("pkg")) + dir.mkdir("pkg"); + + if(info.suffix()=="gz") { - QString pkgname = scanPackageNames(list_so.at(i)); - qDebug()<setText(pkgname); + // decompress tar.gz file + process.start(tr("tar -zxvf %1 -C %2/src").arg(le_archPath->text()).arg(le_fakeDirPath->text())); - table_depends->setItem(i,1,itemPackage); + process.waitForFinished(); + + qDebug()<<"Decompress finished"; + + updateTree(); //update file trees + + return; } + if(info.suffix()=="deb") + { + qDebug()<<"deb"; + + QProcess process; + // first decompress .deb file + process.start(tr("ar -vx %1 --output=%2/src").arg(le_archPath->text()).arg(le_fakeDirPath->text())); + process.waitForStarted(); + + qDebug()<<"deb decomprocessed"; + + QProcess process1; + + // then decompress data.tar.xz + process1.start(tr("tar -xvJf %1/src/data.tar.xz -C %2/pkg").arg(le_fakeDirPath->text()).arg(le_fakeDirPath->text())); + + process1.waitForFinished(); + + qDebug()<<"data.tar.xz decomprocessed"; + + updateTree(); //update file trees + + return; + + } } -QString PKGBUILDASSISTANT::scanPackageNames(QString filename) +void PKGBUILDASSISTANT::updateTree() { - QProcess process; + QDir dir_src(le_fakeDirPath->text()+"/src"); + QDir dir_pkg(le_fakeDirPath->text()+"/pkg"); - process.start(tr("pacman -Fx %1").arg(filename)); + //qDebug()<text()+"/src")); - QString ret(buf); + process_src.waitForFinished(); + + buf = process_src.readAllStandardOutput(); + + tree_source->setText(buf); + + process_pkg.start(tr("tree %1").arg(le_fakeDirPath->text()+"/pkg")); + + process_pkg.waitForFinished(); + + buf = process_pkg.readAllStandardOutput(); + + tree_pkg->setText(buf); +} + +void PKGBUILDASSISTANT::slotAddOperation(QString operation) +{ + QString opeShell = operation.section(' ',0,0); + qDebug()<<"opeShell = " <text()+"/src"; + QString realPkgDir = le_fakeDirPath->text()+"/pkg"; + + + + qDebug()<<"realSrcDir: "<insertPlainText(newOperation.replace("${srcdir}","\"${srcdir}\"").replace("${pkgdir}","\"${pkgdir}\"")+"\n"); + + QString srcStr = operation.section(" ",2,2); + QString destStr = operation.section(" ",3,3); + + // Firstly build the fake dir + QProcess mkdir; + + if(destStr.mid(0,9)=="${srcdir}") + mkdir.start(tr("mkdir -p %1").arg(realSrcDir+destStr.mid(9,destStr.lastIndexOf("/")-9+1))); + else + mkdir.start(tr("mkdir -p %1").arg(realPkgDir+destStr.mid(9,destStr.lastIndexOf("/")-9+1))); + + mkdir.waitForFinished(); + + // Copy the file to fake dir + QProcess cp; + + if(srcStr.mid(0,9)=="${srcdir}") // Source:${srcdir} + { + if(destStr.mid(0,9)=="${srcdir}") + cp.start(tr("cp %1 %2").arg(realSrcDir+srcStr.mid(9,srcStr.length()-9)).arg(realSrcDir+destStr.mid(9,destStr.length()-9))); + if(destStr.mid(0,9)=="${pkgdir}") + cp.start(tr("cp %1 %2").arg(realSrcDir+srcStr.mid(9,srcStr.length()-9)).arg(realPkgDir+destStr.mid(9,destStr.length()-9))); + + cp.waitForFinished(); + qDebug()<<"copy file: "<text()); + QString srcStr = operation.section(" ",2,2); + QString destStr = operation.section(" ",3,3); + + if(destStr.mid(0,9)=="${srcdir}") // Destination: ${srcdir} + { + // if dir exists + if(tmpDir.exists("src"+destStr.mid(9,destStr.length()-9))) + { + le_preview->insertPlainText(operation.replace("${srcdir}","\"${srcdir}\"").replace("${pkgdir}","\"${pkgdir}\"")+"\n"); + + // copy dir + if(srcStr.mid(0,9)=="${srcdir}") // Source: ${srcdir} + { + qDebug()<insertPlainText(tr("mkdir -p %1\n").arg("\"${srcdir}\""+destStr.mid(9,destStr.length()-9))); + QString newOperation = operation; + le_preview->insertPlainText(newOperation.replace("${srcdir}","\"${srcdir}\"").replace("${pkgdir}","\"${pkgdir}\"")+"\n"); + + // copy the dir + if(srcStr.mid(0,9)=="${srcdir}") // Source: ${srcdir} + { + + qDebug()<insertPlainText(newOperation.replace("${srcdir}","\"${srcdir}\"").replace("${pkgdir}","\"${pkgdir}\"")+"\n"); + + // copy the dir + if(srcStr.mid(0,9)=="${srcdir}") // Source: ${srcdir} + { + qDebug()<insertPlainText(tr("mkdir -p %1\n").arg("\"${pkgdir}\""+destStr.mid(9,destStr.length()-9))); + QString newOperation = operation; + le_preview->insertPlainText(newOperation.replace("${srcdir}","\"${srcdir}\"").replace("${pkgdir}","\"${pkgdir}\"")+"\n"); + + // copy the dir + if(srcStr.mid(0,9)=="${srcdir}") // Source: ${srcdir} + { + + qDebug()<insertPlainText(newOperation.replace("${srcdir}","\"${srcdir}\"").replace("${pkgdir}","\"${pkgdir}\"")+"\n"); + + + if(dirStr.mid(0,9)=="${srcdir}") // delete file from ${srcdir} + { + QDir tmpDir(realSrcDir); + + qDebug()<insertPlainText(newOperation.replace("${srcdir}","\"${srcdir}\"").replace("${pkgdir}","\"${pkgdir}\"")+"\n"); + + + if(dirStr.mid(0,9)=="${srcdir}") // delete dir from ${srcdir} + { + QDir tmpDir(realSrcDir); + + qDebug()<insertPlainText(newOperation.replace("${srcdir}","\"${srcdir}\"").replace("${pkgdir}","\"${pkgdir}\"")+"\n"); + + if(operation.section(" ",1,1) != "-R") // chmod file + { + // chmod 0755 ${pkgdir}/usr/name + + qDebug()<<"chmod file"; + QString mod = operation.section(" ",1,1); + QString dirStr = operation.section(" ",2,2); + + QProcess chmod; + + if(dirStr.mid(0,9)=="${srcdir}") // chmod file from ${srcdir} + { + chmod.start(tr("chmod %1 %2").arg(mod).arg(realSrcDir+"/"+dirStr.mid(10, dirStr.length()-10))); + + chmod.waitForFinished(); + } + + if(dirStr.mid(0,9)=="${pkgdir}") // chmod file from ${pkgdir} + { + chmod.start(tr("chmod %1 %2").arg(mod).arg(realPkgDir+"/"+dirStr.mid(10, dirStr.length()-10))); + + chmod.waitForFinished(); + } + } + else //chmod dir + { + // chmod -R 0755 ${pkgdir}/usr/name + QString mod = operation.section(" ",2,2); + QString dirStr = operation.section(" ",3,3); + + QProcess chmod; + + if(dirStr.mid(0,9)=="${srcdir}") // chmod file from ${srcdir} + { + chmod.start(tr("chmod -R %1 %2").arg(mod).arg(realSrcDir+"/"+dirStr.mid(10, dirStr.length()-10))); + + chmod.waitForFinished(); + } + + if(dirStr.mid(0,9)=="${pkgdir}") // chmod file from ${pkgdir} + { + chmod.start(tr("chmod -R %1 %2").arg(mod).arg(realPkgDir+"/"+dirStr.mid(10, dirStr.length()-10))); + + chmod.waitForFinished(); + } + } + + + updateTree(); + + return; + } + + +} + +bool PKGBUILDASSISTANT::copyDirectoryFiles(const QString &fromDir, const QString &toDir) +{ + QDir sourceDir(fromDir); + QDir targetDir(toDir); + if(!targetDir.exists()) + { /**< 如果目标目录不存在,则进行创建 */ + if(!targetDir.mkdir(targetDir.absolutePath())) + return false; + } + + QFileInfoList fileInfoList = sourceDir.entryInfoList(); + foreach(QFileInfo fileInfo, fileInfoList) + { + if(fileInfo.fileName() == "." || fileInfo.fileName() == "..") + continue; + + if(fileInfo.isDir()) + { /**< 当为目录时,递归的进行copy */ + if(!copyDirectoryFiles(fileInfo.filePath(),targetDir.filePath(fileInfo.fileName()))) + return false; + } + else + { /**< 当允许覆盖操作时,将旧文件进行删除操作 */ + if(targetDir.exists(fileInfo.fileName())) + { + targetDir.remove(fileInfo.fileName()); + } + + /// 进行文件copy + if(!QFile::copy(fileInfo.filePath(), + targetDir.filePath(fileInfo.fileName()))){ + return false; + } + } + } + return true; + +} + +bool PKGBUILDASSISTANT::DeleteDirectory(const QString &path) +{ + if (path.isEmpty()) + { + return false; + } + + QDir dir(path); + if(!dir.exists()) + { + return true; + } + + dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot); + QFileInfoList fileList = dir.entryInfoList(); + foreach (QFileInfo fi, fileList) + { + if (fi.isFile()) + { + fi.dir().remove(fi.fileName()); + } + else + { + DeleteDirectory(fi.absoluteFilePath()); + } + } + return dir.rmpath(dir.absolutePath()); +} + +void PKGBUILDASSISTANT::createFile() +{ + if(le_pkgname->text().isEmpty() || le_pkgver->text().isEmpty() || le_pkgrel->text().isEmpty() + || le_pkgdesc->toPlainText().isEmpty() || le_arch->text().isEmpty() || le_url->text().isEmpty() + || le_source->toPlainText().isEmpty() || le_sum->toPlainText().isEmpty() || le_maintainerName->text().isEmpty() + || le_maintainerEmail->text().isEmpty() || le_provides->text().isEmpty()) + { + QMessageBox::critical(this, "生成失败", "生成失败,一项或多项关键信息未填写!"); + return; + } + + pkgBuf.clear(); + + // Maintainer Info + pkgBuf.append(tr("#Maintainer: %1 <%2>\n\n").arg(le_maintainerName->text()).arg(le_maintainerEmail->text())); + + // Pkgname + pkgBuf.append(tr("pkgname=(\'%1\')\n").arg(le_pkgname->text())); + + // Pkgver + pkgBuf.append(tr("pkgver=%1\n").arg(le_pkgver->text())); + + // Pkgrel + pkgBuf.append(tr("pkgrel=%1\n").arg(le_pkgrel->text())); + + // Pkgdec + pkgBuf.append(tr("pkgdesc=\"%1\"\n").arg(le_pkgdesc->toPlainText())); + + // Provides + pkgBuf.append(tr("provides=(\"%1\")\n").arg(le_provides->text())); + + // Conflicts + pkgBuf.append(tr("conflicts=(\"%1\")\n").arg(le_conflicts->text())); + + // Url + pkgBuf.append(tr("url=\'%1\'\n").arg(le_url->text())); + + // Arch + pkgBuf.append(tr("arch=(\'%1\')\n").arg(le_arch->text())); + + // Depends + int count = 0; + QString str = le_depends->toPlainText(); + qDebug()<toPlainText(); + QString optdependsStr; + + count = str.count("\n")+1; + for(int i=0; itoPlainText(); + QString sourceStr; + + count = str.count("\n")+1; + for(int i=0; itoPlainText(); + QString sumStr; + + count = str.count("\n")+1; + for(int i = 0; iisChecked()) + sumType = "md5sums"; + if(radio_sha1sums->isChecked()) + sumType = "sha1sums"; + if(radio_sha256sums->isChecked()) + sumType = "sha256sums"; + if(radio_sha512sums->isChecked()) + sumType = "sha512sums"; + + pkgBuf.append(tr("%1=(%2)\n\n").arg(sumType).arg(sumStr)); + + // Package() + //head + pkgBuf.append("package(){\n"); + + if(!le_archPath->text().isEmpty()) // deb archive + if(le_archPath->text().mid(le_archPath->text().lastIndexOf("."),-1) == ".deb") + { + pkgBuf.append("\t cd ${srcdir}\n"); + pkgBuf.append("\t tar -xJvf data.tar.xz -C \"${pkgdir}\"\n\n"); + } + + // body + count = 0; + QString packageStr = le_preview->toPlainText(); + + count = packageStr.count("\n")+1; + for(int i=0; isetText(pkgBuf.data()); - return buf; } diff --git a/pkgbuildassistant.h b/pkgbuildassistant.h index 1d20cdc..788fb59 100644 --- a/pkgbuildassistant.h +++ b/pkgbuildassistant.h @@ -18,11 +18,13 @@ #include #include #include -#include -#include +#include #include #include +#include "dialogfilecopy.h" +#include "dialogfiledelete.h" +#include "dialogfilechmod.h" QT_BEGIN_NAMESPACE @@ -59,6 +61,8 @@ class PKGBUILDASSISTANT : public QMainWindow QGridLayout* layout_relationsTab; QLineEdit *le_provides; QLineEdit *le_conflicts; + QLineEdit *le_maintainerName; + QLineEdit *le_maintainerEmail; QGridLayout *layout_dependsTab; @@ -76,10 +80,10 @@ class PKGBUILDASSISTANT : public QMainWindow QGroupBox *group_trees; QGroupBox *group_preview; QLineEdit *le_fakeDirPath; - QLineEdit *le_debPath; + QLineEdit *le_archPath; QTextEdit *le_preview; - QTreeWidget *tree_source; - QTreeWidget *tree_pkg; + QTextBrowser *tree_source; + QTextBrowser *tree_pkg; QVBoxLayout *layout_createTab; @@ -87,11 +91,18 @@ class PKGBUILDASSISTANT : public QMainWindow QTextEdit *le_savePreview; QGroupBox *group_savePreview; + QByteArray pkgBuf; + void scanSoFiles(); QString scanPackageNames(QString filename); + void decompress(QString fileName); + void updateTree(); + bool copyDirectoryFiles(const QString &fromDir, const QString &toDir); + bool DeleteDirectory(const QString &path); void createFile(); public slots: + void slotAddOperation(QString operation); private: Ui::PKGBUILDASSISTANT *ui; diff --git a/res.qrc b/res.qrc new file mode 100644 index 0000000..6fbca47 --- /dev/null +++ b/res.qrc @@ -0,0 +1,5 @@ + + + ico.png + +