541 lines
18 KiB
C++
541 lines
18 KiB
C++
#include "CompareControl.h"
|
|
|
|
#include <QDesktopServices>
|
|
#include <QDir>
|
|
#include <QFile>
|
|
#include <QListWidget>
|
|
#include <QMessageBox>
|
|
#include <QXmlStreamReader>
|
|
#include <QXmlStreamWriter>
|
|
|
|
#include "Form/Loading.h"
|
|
#include "GuiUtil/Public.h"
|
|
#include "ui_CompareControl.h"
|
|
|
|
Compare::Compare(QWidget* parent) : QWidget(parent), ui(new Ui::Compare)
|
|
{
|
|
ui->setupUi(this);
|
|
InitControl();
|
|
InitMenu();
|
|
}
|
|
|
|
Compare::~Compare()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void Compare::InitMenu()
|
|
{
|
|
menu_ = new QMenu(ui->tableWidget);
|
|
menu_->addAction(tr("尝试访问本地路径"), this, [this]() {
|
|
auto selected = ui->tableWidget->selectedItems();
|
|
if (selected.size() != 3) {
|
|
return;
|
|
}
|
|
auto item = selected[1];
|
|
auto path = item->text();
|
|
emit sigTryVisit(true, path);
|
|
});
|
|
menu_->addAction(tr("尝试访问远程路径"), this, [this]() {
|
|
auto selected = ui->tableWidget->selectedItems();
|
|
if (selected.size() != 3) {
|
|
return;
|
|
}
|
|
auto item = selected[2];
|
|
auto path = item->text();
|
|
emit sigTryVisit(false, path);
|
|
});
|
|
menu_->addAction(tr("添加新行"), this, [this]() {
|
|
int cnt = ui->tableWidget->rowCount();
|
|
ui->tableWidget->insertRow(cnt);
|
|
auto item1 = new QTableWidgetItem("");
|
|
auto item2 = new QTableWidgetItem("");
|
|
auto item3 = new QTableWidgetItem("");
|
|
ui->tableWidget->setItem(cnt, 0, item1);
|
|
ui->tableWidget->setItem(cnt, 1, item2);
|
|
ui->tableWidget->setItem(cnt, 2, item3);
|
|
});
|
|
menu_->addAction(tr("删除"), this, [this]() { deleteSelectedRows(); });
|
|
menu_->addAction(tr("尝试打开本地路径"), this, [this]() {
|
|
auto selected = ui->tableWidget->selectedItems();
|
|
if (selected.size() != 3) {
|
|
return;
|
|
}
|
|
auto item = selected[1];
|
|
auto path = item->text();
|
|
QDir dir(path);
|
|
if (!dir.exists()) {
|
|
FTCommon::msg(this, tr("本地路径不存在。"));
|
|
return;
|
|
}
|
|
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
|
});
|
|
menu_->addAction(tr("上传"), this, [this]() { TransToRight(false); });
|
|
menu_->addAction(tr("下载"), this, [this]() { TransToLeft(false); });
|
|
menu_->addSeparator();
|
|
connect(ui->tableWidget, &QTableWidget::customContextMenuRequested, this,
|
|
[this](const QPoint& pos) { menu_->exec(QCursor::pos()); });
|
|
}
|
|
|
|
void Compare::InitControl()
|
|
{
|
|
InitTabWidget();
|
|
|
|
connect(ui->btnSave, &QPushButton::clicked, this, &Compare::Save);
|
|
connect(ui->btnLoad, &QPushButton::clicked, this, &Compare::Load);
|
|
// connect(ui->btnLeft, &QPushButton::clicked, this, &Compare::TransToLeft);
|
|
// connect(ui->btnRight, &QPushButton::clicked, this, &Compare::TransToRight);
|
|
connect(ui->btnTypeDown, &QPushButton::clicked, this, [this]() { FilterFiles(false); });
|
|
connect(ui->btnTypeUpload, &QPushButton::clicked, this, [this]() { FilterFiles(true); });
|
|
connect(ui->btnSearch, &QPushButton::clicked, this, &Compare::Search);
|
|
connect(ui->btnReset, &QPushButton::clicked, this, &Compare::Reset);
|
|
|
|
// 测试代码
|
|
connect(ui->btnReplace, &QPushButton::clicked, this, [this]() {
|
|
// auto* loading = new LoadingDialog(this);
|
|
// loading->exec();
|
|
});
|
|
|
|
LoadTitles();
|
|
|
|
isResource_ = true;
|
|
ui->tableWidget->setIsResource(isResource_);
|
|
}
|
|
|
|
void Compare::InitTabWidget()
|
|
{
|
|
QStringList headers;
|
|
headers << tr("文件") << tr("本地目录") << tr("远端目录");
|
|
ui->tableWidget->setColumnCount(headers.size());
|
|
ui->tableWidget->setHorizontalHeaderLabels(headers);
|
|
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
|
|
ui->comboBox->setEditable(true);
|
|
// ui->tableWidget->setColumnWidth(0, 50);
|
|
ui->tableWidget->setColumnWidth(0, 400);
|
|
/// ui->tableWidget->setColumnWidth(1, 300);
|
|
ui->tableWidget->setColumnWidth(2, 300);
|
|
|
|
ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
// ui->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
|
// ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
|
|
ui->tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
|
|
ui->tableWidget->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
|
|
ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
ui->tableWidget->setDragEnabled(false);
|
|
ui->tableWidget->viewport()->setAcceptDrops(true);
|
|
ui->tableWidget->setDropIndicatorShown(true);
|
|
ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
ui->tableWidget->setDragDropMode(QAbstractItemView::DropOnly);
|
|
|
|
ui->comboBox->setFixedWidth(100);
|
|
}
|
|
|
|
void Compare::Save()
|
|
{
|
|
auto titleKey = ui->comboBox->currentText().trimmed();
|
|
if (titleKey.isEmpty()) {
|
|
FTCommon::msg(this, tr("请输入标题"));
|
|
return;
|
|
}
|
|
|
|
if (!isResource_) {
|
|
QMessageBox::information(this, tr("提示"), tr("请先重置搜索结果后操作。"));
|
|
return;
|
|
}
|
|
|
|
QFile file("CompareData.xml");
|
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
|
FTCommon::msg(this, tr("打开数据文件失败。"));
|
|
return;
|
|
}
|
|
|
|
QString existingContent;
|
|
QMap<QString, QStringList> dataMap;
|
|
if (file.size() > 0) {
|
|
existingContent = file.readAll();
|
|
file.seek(0);
|
|
QXmlStreamReader reader(existingContent);
|
|
while (!reader.atEnd()) {
|
|
if (reader.isStartElement() && reader.name() == "Entry") {
|
|
QString key = reader.attributes().value("title").toString();
|
|
QStringList paths;
|
|
while (!(reader.isEndElement() && reader.name() == "Entry")) {
|
|
reader.readNext();
|
|
if (reader.isStartElement() && reader.name() == "FileName") {
|
|
paths << reader.readElementText();
|
|
}
|
|
if (reader.isStartElement() && reader.name() == "LocalDir") {
|
|
paths << reader.readElementText();
|
|
}
|
|
if (reader.isStartElement() && reader.name() == "RemoteDir") {
|
|
paths << reader.readElementText();
|
|
}
|
|
}
|
|
dataMap.insert(key, paths);
|
|
}
|
|
reader.readNext();
|
|
}
|
|
}
|
|
|
|
QStringList paths;
|
|
items_.clear();
|
|
|
|
for (int row = 0; row < ui->tableWidget->rowCount(); ++row) {
|
|
QTableWidgetItem* fileName = ui->tableWidget->item(row, 0);
|
|
QTableWidgetItem* localItem = ui->tableWidget->item(row, 1);
|
|
QTableWidgetItem* remoteItem = ui->tableWidget->item(row, 2);
|
|
|
|
auto baseName = (fileName ? fileName->text() : "");
|
|
auto localDir = (localItem ? localItem->text() : "");
|
|
auto remoteDir = (remoteItem ? remoteItem->text() : "");
|
|
|
|
CompareItem item;
|
|
item.baseName = baseName;
|
|
item.localDir = localDir;
|
|
item.remoteDir = remoteDir;
|
|
items_.push_back(item);
|
|
|
|
paths << baseName;
|
|
paths << localDir;
|
|
paths << remoteDir;
|
|
}
|
|
|
|
dataMap[titleKey] = paths;
|
|
|
|
file.resize(0);
|
|
QXmlStreamWriter writer(&file);
|
|
writer.setAutoFormatting(true);
|
|
writer.writeStartDocument();
|
|
writer.writeStartElement("CompareData");
|
|
|
|
for (auto it = dataMap.begin(); it != dataMap.end(); ++it) {
|
|
writer.writeStartElement("Entry");
|
|
writer.writeAttribute("title", it.key());
|
|
|
|
const QStringList& pathList = it.value();
|
|
for (int i = 0; i < pathList.size(); i += 3) {
|
|
writer.writeTextElement("FileName", pathList[i]);
|
|
writer.writeTextElement("LocalDir", pathList[i + 1]);
|
|
writer.writeTextElement("RemoteDir", pathList[i + 2]);
|
|
}
|
|
|
|
writer.writeEndElement();
|
|
}
|
|
|
|
writer.writeEndElement();
|
|
writer.writeEndDocument();
|
|
file.close();
|
|
|
|
if (ui->comboBox->findText(titleKey) == -1) {
|
|
ui->comboBox->addItem(titleKey);
|
|
}
|
|
|
|
FTCommon::msg(this, tr("数据保存成功。"));
|
|
}
|
|
|
|
void Compare::Load()
|
|
{
|
|
auto titleKey = ui->comboBox->currentText().trimmed();
|
|
if (titleKey.isEmpty()) {
|
|
FTCommon::msg(this, tr("请选择或输入标题。"));
|
|
return;
|
|
}
|
|
|
|
QFile file("CompareData.xml");
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
FTCommon::msg(this, tr("打开数据文件失败。"));
|
|
return;
|
|
}
|
|
|
|
items_.clear();
|
|
isResource_ = true;
|
|
ui->tableWidget->setIsResource(isResource_);
|
|
QXmlStreamReader reader(&file);
|
|
bool found = false;
|
|
|
|
ui->tableWidget->setRowCount(0);
|
|
while (!reader.atEnd() && !found) {
|
|
if (reader.isStartElement() && reader.name() == "Entry") {
|
|
if (reader.attributes().value("title").toString() == titleKey) {
|
|
found = true;
|
|
QStringList paths;
|
|
|
|
while (!(reader.isEndElement() && reader.name() == "Entry")) {
|
|
reader.readNext();
|
|
if (reader.isStartElement() && reader.name() == "FileName") {
|
|
paths << reader.readElementText();
|
|
}
|
|
if (reader.isStartElement() && reader.name() == "LocalDir") {
|
|
paths << reader.readElementText();
|
|
}
|
|
if (reader.isStartElement() && reader.name() == "RemoteDir") {
|
|
paths << reader.readElementText();
|
|
}
|
|
}
|
|
for (int i = 0; i < paths.size(); i += 3) {
|
|
int row = ui->tableWidget->rowCount();
|
|
ui->tableWidget->insertRow(row);
|
|
|
|
CompareItem item;
|
|
item.baseName = paths[i];
|
|
item.localDir = paths[i + 1];
|
|
item.remoteDir = paths[i + 2];
|
|
items_.push_back(item);
|
|
|
|
QTableWidgetItem* fileName = new QTableWidgetItem(paths[i]);
|
|
QTableWidgetItem* localItem = new QTableWidgetItem(paths[i + 1]);
|
|
QTableWidgetItem* remoteItem = new QTableWidgetItem(paths[i + 2]);
|
|
|
|
ui->tableWidget->setItem(row, 0, fileName);
|
|
ui->tableWidget->setItem(row, 1, localItem);
|
|
ui->tableWidget->setItem(row, 2, remoteItem);
|
|
}
|
|
}
|
|
}
|
|
reader.readNext();
|
|
}
|
|
|
|
file.close();
|
|
if (!found) {
|
|
FTCommon::msg(this, tr("没有找到标题对应的数据。"));
|
|
} else {
|
|
// FTCommon::msg(this, tr("Data loaded successfully."));
|
|
}
|
|
}
|
|
|
|
void Compare::LoadTitles()
|
|
{
|
|
QFile file("CompareData.xml");
|
|
if (!file.exists()) {
|
|
return;
|
|
}
|
|
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
FTCommon::msg(this, tr("Failed to open data file."));
|
|
return;
|
|
}
|
|
|
|
QString currentText = ui->comboBox->currentText();
|
|
ui->comboBox->clear();
|
|
ui->comboBox->setEditText(currentText);
|
|
|
|
QXmlStreamReader reader(&file);
|
|
while (!reader.atEnd()) {
|
|
if (reader.isStartElement() && reader.name() == "Entry") {
|
|
QString title = reader.attributes().value("title").toString();
|
|
if (!title.isEmpty() && ui->comboBox->findText(title) == -1) {
|
|
ui->comboBox->addItem(title);
|
|
}
|
|
}
|
|
reader.readNext();
|
|
}
|
|
|
|
file.close();
|
|
|
|
if (ui->comboBox->count() > 0) {
|
|
ui->comboBox->setCurrentIndex(0);
|
|
}
|
|
}
|
|
|
|
void Compare::Search()
|
|
{
|
|
auto key = ui->edSearch->text().trimmed();
|
|
if (key.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
key = key.toUpper();
|
|
QVector<CompareItem> result;
|
|
for (const auto& item : items_) {
|
|
auto baseNameU = item.baseName.toUpper();
|
|
auto localDirU = item.localDir.toUpper();
|
|
auto remoteDirU = item.remoteDir.toUpper();
|
|
|
|
if (baseNameU.contains(key) || localDirU.contains(key) || remoteDirU.contains(key)) {
|
|
result.push_back(item);
|
|
}
|
|
}
|
|
SetResult(result);
|
|
isResource_ = false;
|
|
ui->tableWidget->setIsResource(isResource_);
|
|
}
|
|
|
|
void Compare::Reset()
|
|
{
|
|
SetResult(items_);
|
|
isResource_ = true;
|
|
ui->tableWidget->setIsResource(isResource_);
|
|
}
|
|
|
|
void Compare::SetResult(const QVector<CompareItem>& items)
|
|
{
|
|
ui->tableWidget->setRowCount(0);
|
|
for (const auto& item : items) {
|
|
int row = ui->tableWidget->rowCount();
|
|
ui->tableWidget->insertRow(row);
|
|
ui->tableWidget->setItem(row, 0, new QTableWidgetItem(item.baseName));
|
|
ui->tableWidget->setItem(row, 1, new QTableWidgetItem(item.localDir));
|
|
ui->tableWidget->setItem(row, 2, new QTableWidgetItem(item.remoteDir));
|
|
}
|
|
}
|
|
|
|
void Compare::FilterFiles(bool isUpload)
|
|
{
|
|
QDialog dialog(this);
|
|
QString title = QString("筛选文件类型(%1)").arg(isUpload ? tr("上传") : tr("下载"));
|
|
dialog.setWindowTitle(title);
|
|
dialog.resize(400, 300);
|
|
QListWidget listWidget(&dialog);
|
|
|
|
listWidget.setSelectionMode(QAbstractItemView::NoSelection);
|
|
QListWidgetItem* allItem = new QListWidgetItem("*(ALL)");
|
|
allItem->setData(Qt::UserRole, "*");
|
|
allItem->setCheckState(curSelectTypes_.contains("*") ? Qt::Checked : Qt::Unchecked);
|
|
listWidget.addItem(allItem);
|
|
|
|
int rows = ui->tableWidget->rowCount();
|
|
for (int i = 0; i < rows; ++i) {
|
|
QString ext = ui->tableWidget->item(i, 0)->text().split(".").last().toUpper();
|
|
QListWidgetItem* item = new QListWidgetItem(ext);
|
|
item->setData(Qt::UserRole, ext);
|
|
item->setCheckState(curSelectTypes_.contains(ext) ? Qt::Checked : Qt::Unchecked);
|
|
listWidget.addItem(item);
|
|
}
|
|
|
|
QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dialog);
|
|
connect(&buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
|
|
connect(&buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
|
|
|
QVBoxLayout layout(&dialog);
|
|
layout.addWidget(&listWidget);
|
|
layout.addWidget(&buttons);
|
|
dialog.setLayout(&layout);
|
|
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
QVector<QString> selectedTypes;
|
|
for (int i = 0; i < listWidget.count(); ++i) {
|
|
QListWidgetItem* item = listWidget.item(i);
|
|
if (item->checkState() == Qt::Checked) {
|
|
selectedTypes << item->data(Qt::UserRole).toString();
|
|
}
|
|
}
|
|
curSelectTypes_.clear();
|
|
for (int i = 0; i < selectedTypes.count(); ++i) {
|
|
curSelectTypes_.insert(selectedTypes[i]);
|
|
}
|
|
if (isUpload) {
|
|
TransToRight(true);
|
|
} else {
|
|
TransToLeft(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Compare::TransToLeft(bool useSelectTypes)
|
|
{
|
|
QVector<TransTask> tasks;
|
|
|
|
auto pushTask = [&](const QString& localPath, const QString& remotePath) {
|
|
TransTask task;
|
|
task.taskUUID = Util::UUID();
|
|
task.isUpload = false;
|
|
task.localId = GlobalData::Ins()->GetLocalID();
|
|
task.localPath = localPath;
|
|
task.remoteId = GlobalData::Ins()->GetRemoteID();
|
|
task.remotePath = remotePath;
|
|
tasks.push_back(task);
|
|
};
|
|
|
|
if (useSelectTypes) {
|
|
for (int i = 0; i < ui->tableWidget->rowCount(); ++i) {
|
|
QString ext = ui->tableWidget->item(i, 0)->text().split(".").last().toUpper();
|
|
if (curSelectTypes_.contains(ext)) {
|
|
const QTableWidgetItem* itemF = ui->tableWidget->item(i, 1);
|
|
const QTableWidgetItem* itemT = ui->tableWidget->item(i, 2);
|
|
pushTask(itemT->text(), Util::Join(itemF->text(), ui->tableWidget->item(i, 0)->text()));
|
|
}
|
|
}
|
|
if (tasks.size() > 0) {
|
|
emit sigTasks(tasks);
|
|
}
|
|
} else {
|
|
QModelIndexList indexList = ui->tableWidget->selectionModel()->selectedRows();
|
|
if (indexList.size() < 1) {
|
|
QMessageBox::information(this, tr("提示"), tr("请选择要下载的文件。"));
|
|
return;
|
|
}
|
|
for (int i = 0; i < indexList.size(); ++i) {
|
|
const QTableWidgetItem* itemF = ui->tableWidget->item(indexList[i].row(), 2);
|
|
const QTableWidgetItem* itemT = ui->tableWidget->item(indexList[i].row(), 1);
|
|
pushTask(itemT->text(), Util::Join(itemF->text(), ui->tableWidget->item(indexList[i].row(), 0)->text()));
|
|
}
|
|
if (tasks.size() > 0) {
|
|
emit sigTasks(tasks);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Compare::TransToRight(bool useSelectTypes)
|
|
{
|
|
QVector<TransTask> tasks;
|
|
|
|
auto pushTask = [&](const QString& localPath, const QString& remotePath) {
|
|
TransTask task;
|
|
task.taskUUID = Util::UUID();
|
|
task.isUpload = true;
|
|
task.localId = GlobalData::Ins()->GetLocalID();
|
|
task.localPath = localPath;
|
|
task.remoteId = GlobalData::Ins()->GetRemoteID();
|
|
task.remotePath = remotePath;
|
|
tasks.push_back(task);
|
|
};
|
|
|
|
if (useSelectTypes) {
|
|
for (int i = 0; i < ui->tableWidget->rowCount(); ++i) {
|
|
QString ext = ui->tableWidget->item(i, 0)->text().split(".").last().toUpper();
|
|
if (curSelectTypes_.contains(ext)) {
|
|
const QTableWidgetItem* itemF = ui->tableWidget->item(i, 1);
|
|
const QTableWidgetItem* itemT = ui->tableWidget->item(i, 2);
|
|
pushTask(Util::Join(itemF->text(), ui->tableWidget->item(i, 0)->text()), itemT->text());
|
|
}
|
|
}
|
|
if (tasks.size() > 0) {
|
|
emit sigTasks(tasks);
|
|
}
|
|
} else {
|
|
QModelIndexList indexList = ui->tableWidget->selectionModel()->selectedRows();
|
|
if (indexList.size() < 1) {
|
|
QMessageBox::information(this, tr("提示"), tr("请选择要上传的文件。"));
|
|
return;
|
|
}
|
|
for (int i = 0; i < indexList.size(); ++i) {
|
|
const QTableWidgetItem* itemF = ui->tableWidget->item(indexList[i].row(), 1);
|
|
const QTableWidgetItem* itemT = ui->tableWidget->item(indexList[i].row(), 2);
|
|
pushTask(Util::Join(itemF->text(), ui->tableWidget->item(indexList[i].row(), 0)->text()), itemT->text());
|
|
}
|
|
if (tasks.size() > 0) {
|
|
emit sigTasks(tasks);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Compare::deleteSelectedRows()
|
|
{
|
|
auto r = FTCommon::affirm(this, tr("确认"), tr("删除选中的行?"));
|
|
if (!r) {
|
|
return;
|
|
}
|
|
QList<int> rowsToDelete;
|
|
for (QTableWidgetItem* item : ui->tableWidget->selectedItems()) {
|
|
int row = item->row();
|
|
if (!rowsToDelete.contains(row)) {
|
|
rowsToDelete.append(row);
|
|
}
|
|
}
|
|
std::sort(rowsToDelete.begin(), rowsToDelete.end(), std::greater<int>());
|
|
for (int row : rowsToDelete) {
|
|
ui->tableWidget->removeRow(row);
|
|
}
|
|
} |