205 lines
6.2 KiB
C++
Executable File
205 lines
6.2 KiB
C++
Executable File
#include "backuplistwidget.h"
|
||
#include <QHBoxLayout>
|
||
#include <QVBoxLayout>
|
||
#include <QPushButton>
|
||
#include <QMimeData>
|
||
#include <QFileInfo>
|
||
#include "mylabel.h"
|
||
#include "../messageboxutils.h"
|
||
|
||
MyItemWidget::MyItemWidget(QWidget* parent) :
|
||
QWidget(parent)
|
||
{}
|
||
|
||
MyItemWidget::~MyItemWidget()
|
||
{}
|
||
|
||
BackupListWidget::BackupListWidget(QWidget *parent /*= nullptr*/) :
|
||
QListWidget(parent)
|
||
{
|
||
setSortingEnabled(false);
|
||
setAcceptDrops(true);
|
||
setAlternatingRowColors(true);
|
||
// 设置为无边框,默认时为StyledPanel
|
||
// setFrameShape(QListWidget::NoFrame);
|
||
|
||
// 列表为空时,展示一个“+”号图标和拖拽文件提示
|
||
m_plusLogo = new QLabel;
|
||
m_plusLogo->setFixedHeight(36);
|
||
QIcon icon = QIcon::fromTheme("list-add-symbolic", QIcon(":/symbos/list-add-symbolic.png"));
|
||
m_plusLogo->setPixmap(icon.pixmap(icon.actualSize(QSize(24, 24))));
|
||
m_plusLogo->setEnabled(false);
|
||
// 文件拖放区域
|
||
m_plusText = new QLabel;
|
||
m_plusText->setText(tr("File drag and drop area"));
|
||
m_plusText->setEnabled(false);
|
||
|
||
QHBoxLayout *hlayout = new QHBoxLayout;
|
||
hlayout->addStretch();
|
||
hlayout->addWidget(m_plusLogo);
|
||
hlayout->addWidget(m_plusText);
|
||
hlayout->addStretch();
|
||
|
||
QVBoxLayout *vlayout = new QVBoxLayout;
|
||
vlayout->addStretch();
|
||
vlayout->addLayout(hlayout);
|
||
vlayout->addStretch();
|
||
setLayout(vlayout);
|
||
|
||
connect(this, &BackupListWidget::currentItemChanged, this, [=](QListWidgetItem *current, QListWidgetItem *previous) {
|
||
if (current) {
|
||
MyItemWidget *widget = qobject_cast<MyItemWidget *>(this->itemWidget(current));
|
||
if (widget)
|
||
emit widget->selected(true);
|
||
}
|
||
|
||
if (previous) {
|
||
MyItemWidget *widget = qobject_cast<MyItemWidget *>(this->itemWidget(previous));
|
||
if (widget)
|
||
emit widget->selected(false);
|
||
}
|
||
|
||
// repaint();
|
||
});
|
||
}
|
||
|
||
BackupListWidget::~BackupListWidget()
|
||
{}
|
||
|
||
bool BackupListWidget::contains(const QString& text)
|
||
{
|
||
// 1、针对使用addItem等的正规使用场景(展示内容在原生item上)
|
||
if (findItems(text, Qt::MatchCaseSensitive).size() > 0)
|
||
return true;
|
||
|
||
// 2、针对使用setItemWidget添加项(展示内容在widget上)的特殊使用场景
|
||
return m_List.contains(text);
|
||
}
|
||
|
||
bool BackupListWidget::appendItem(const QString &text)
|
||
{
|
||
if (!checkPathLimit(text))
|
||
return false;
|
||
|
||
int count = this->count();
|
||
if (count > 0)
|
||
++count;
|
||
|
||
int width = this->width();
|
||
|
||
QListWidgetItem *item = new QListWidgetItem(this, m_type);
|
||
item->setSizeHint(QSize(width - 10, 36));
|
||
MyItemWidget *widget = new MyItemWidget;
|
||
QHBoxLayout *hlayout = new QHBoxLayout;
|
||
hlayout->setContentsMargins(0,5,0,5);
|
||
|
||
MyLabel *label = new MyLabel;
|
||
label->setDeplayText(text);
|
||
label->setToolTip(text);
|
||
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||
// label->setMinimumWidth(width - 60);
|
||
label->setMaximumWidth(width - 10);
|
||
label->setIsOriginal(true);
|
||
hlayout->addWidget(label);
|
||
hlayout->addStretch();
|
||
m_List << text;
|
||
|
||
QPushButton *buttonDelete = new QPushButton;
|
||
// buttonDelete->setProperty("isWindowButton", 0x2);
|
||
// buttonDelete->setProperty("useIconHighlightEffect", 0x8);
|
||
buttonDelete->setFlat(true);
|
||
buttonDelete->setFixedSize(20, 20);
|
||
buttonDelete->setIcon(QIcon::fromTheme("window-close-symbolic"));
|
||
buttonDelete->setVisible(false);
|
||
hlayout->addWidget(buttonDelete);
|
||
|
||
widget->setLayout(hlayout);
|
||
|
||
this->setItemWidget(item, widget);
|
||
// this->setCurrentItem(item);
|
||
|
||
connect(widget, &MyItemWidget::selected, buttonDelete, [=](bool checked) {
|
||
if (checked)
|
||
buttonDelete->setVisible(true);
|
||
else
|
||
buttonDelete->setVisible(false);
|
||
});
|
||
|
||
connect(buttonDelete, &QPushButton::clicked, this, [=]() {
|
||
this->m_List.removeOne(label->text());
|
||
this->removeItemWidget(item);
|
||
this->takeItem(this->row(item));
|
||
delete item;
|
||
if (this->count() == 0) {
|
||
this->m_plusLogo->setVisible(true);
|
||
this->m_plusText->setVisible(true);
|
||
emit this->deleteEmpty();
|
||
}
|
||
});
|
||
|
||
m_plusLogo->setVisible(false);
|
||
m_plusText->setVisible(false);
|
||
emit this->addedItem();
|
||
return true;
|
||
}
|
||
|
||
void BackupListWidget::dropEvent(QDropEvent *event)
|
||
{
|
||
if (event->mimeData()->hasUrls()) {
|
||
for (QUrl url : event->mimeData()->urls()) {
|
||
QString file = url.toString();
|
||
if (file.startsWith("file://")) {
|
||
file.replace("file://", "");
|
||
appendItem(file);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
bool BackupListWidget::checkPathLimit(const QString &path)
|
||
{
|
||
// 1、列表中是否已经存在
|
||
if (contains(path)) {
|
||
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
|
||
QObject::tr("Path already exists : ") + path,
|
||
QObject::tr("Ok"));
|
||
return false;
|
||
}
|
||
|
||
// 2、路径是否存在
|
||
QFileInfo fileInfo(path);
|
||
if (!fileInfo.exists()) {
|
||
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
|
||
QObject::tr("The file or directory does not exist : ") + path,
|
||
QObject::tr("Ok"));
|
||
return false;
|
||
}
|
||
|
||
// 3、是否是限定路径及其子路径
|
||
bool blimit = false;
|
||
QString dirCanBeSelected;
|
||
for (const QString &item : m_pathLimit) {
|
||
if (path.startsWith(item)) {
|
||
blimit = true;
|
||
break;
|
||
}
|
||
|
||
if (dirCanBeSelected.isEmpty())
|
||
dirCanBeSelected = item;
|
||
else {
|
||
dirCanBeSelected += ",";
|
||
dirCanBeSelected += item;
|
||
}
|
||
}
|
||
if (m_pathLimit.size() > 0 && !blimit) {
|
||
MessageBoxUtils::QMESSAGE_BOX_WARNING(this, QObject::tr("Warning"),
|
||
QObject::tr("Only data that exists in the follow directorys can be selected: %1.\n Path:%2 is not in them.").arg(dirCanBeSelected).arg(path),
|
||
QObject::tr("Ok"));
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|