/* * * Copyright (C) 2023, KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * */ #include "search.h" #include #include #include static const QByteArray UKUI_SEARCH_SCHEMAS = QByteArrayLiteral("org.ukui.search.settings"); static const QString SEARCH_METHOD_KEY = QStringLiteral("fileIndexEnable"); static const QString WEB_ENGINE_KEY = QStringLiteral("webEngine"); static const QString CONTENT_FUZZY_SEARCH_KEY = QStringLiteral("contentFuzzySearch"); static const QString CONTENT_INDEX_ENABLE_KEY = QStringLiteral("contentIndexEnable"); static const QString CONTENT_INDEX_ENABLE_OCR_KEY = QStringLiteral("contentIndexEnableOcr"); Search::Search() { QTranslator* translator = new QTranslator(this); if(!translator->load("/usr/share/ukui-search/search-ukcc-plugin/translations/" + QLocale::system().name())) { qWarning() << "/usr/share/ukui-search/search-ukcc-plugin/translations/" + QLocale::system().name() << "load failed"; } QApplication::installTranslator(translator); m_plugin_name = tr("Search"); m_plugin_type = SEARCH_F; m_interface = new QDBusInterface("com.ukui.search.fileindex.service", "/org/ukui/search/privateDirWatcher", "org.ukui.search.fileindex", QDBusConnection::sessionBus(), this); if (m_interface->isValid()) { connect(m_interface, SIGNAL(indexDirsChanged()), this, SLOT(refreshSearchDirsUi())); } m_setSearchDirInterface = new QDBusInterface("com.ukui.search.fileindex.service", "/org/ukui/search/fileindex", "org.ukui.search.fileindex", QDBusConnection::sessionBus(), this); const QByteArray id(UKUI_SEARCH_SCHEMAS); if (QGSettings::isSchemaInstalled(id)) { m_gsettings = new QGSettings(id, QByteArray(), this); } else { qCritical() << UKUI_SEARCH_SCHEMAS << " not installed!\n"; } m_lastBlockDialogDir = QDir::homePath(); m_lastSearchDialogDir = QDir::homePath(); } QString Search::plugini18nName() { return m_plugin_name; } int Search::pluginTypes() { return m_plugin_type; } QWidget *Search::pluginUi() { initUi(); initSearchDirs(); initBlockDirsList(); connect(m_addSearchDirBtn, &QPushButton::clicked, this, &Search::onAddSearchDirBtnClicked); connect(m_addBlockDirWidget, &QPushButton::clicked, this, &Search::onBtnAddBlockFolderClicked); if (m_gsettings) { //按钮状态初始化 if (m_gsettings->keys().contains(SEARCH_METHOD_KEY)) { bool fileIndexOn = m_gsettings->get(SEARCH_METHOD_KEY).toBool(); m_fileIndexBtn->setChecked(fileIndexOn); } else { m_fileIndexBtn->setEnabled(false); } if (m_gsettings->keys().contains(CONTENT_INDEX_ENABLE_KEY)) { //当前是否开启内容索引 bool isContentIndexOn= m_gsettings->get(CONTENT_INDEX_ENABLE_KEY).toBool(); m_contentIndexBtn->setChecked(isContentIndexOn); if (isContentIndexOn) { m_indexSetFrame->show(); } } else { m_contentIndexBtn->setEnabled(false); } if (m_gsettings->keys().contains(CONTENT_INDEX_ENABLE_OCR_KEY)) { m_ocrSwitchBtn->setChecked(m_gsettings->get(CONTENT_INDEX_ENABLE_OCR_KEY).toBool()); } else { m_ocrSwitchBtn->setEnabled(false); } if (m_gsettings->keys().contains(WEB_ENGINE_KEY)) { //当前网页搜索的搜索引擎 QString engine = m_gsettings->get(WEB_ENGINE_KEY).toString(); m_webEngineFrame->mCombox->setCurrentIndex(m_webEngineFrame->mCombox->findData(engine)); } else { m_webEngineFrame->mCombox->setEnabled(false); } if (m_gsettings->keys().contains(CONTENT_FUZZY_SEARCH_KEY)) { //是否为模糊搜索 bool isFuzzy = m_gsettings->get(CONTENT_FUZZY_SEARCH_KEY).toBool(); if (isFuzzy) { m_fuzzyBtn->setChecked(true); } else { m_preciseBtn->setChecked(true); } } else { m_fuzzyBtn->setEnabled(false); m_preciseBtn->setEnabled(false); } //监听gsettings值改变,更新控制面板UI connect(m_gsettings, &QGSettings::changed, this, [ = ](const QString &key) { if (key == SEARCH_METHOD_KEY) { bool isFileIndexOn = m_gsettings->get(SEARCH_METHOD_KEY).toBool(); m_fileIndexBtn->blockSignals(true); m_fileIndexBtn->setChecked(isFileIndexOn); m_fileIndexBtn->blockSignals(false); } else if (key == CONTENT_INDEX_ENABLE_KEY) { bool isContentIndexOn = m_gsettings->get(CONTENT_INDEX_ENABLE_KEY).toBool(); m_contentIndexBtn->blockSignals(true); m_contentIndexBtn->setChecked(isContentIndexOn); m_contentIndexBtn->blockSignals(false); if (isContentIndexOn) { m_indexSetFrame->show(); } else { m_indexSetFrame->hide(); if (m_gsettings->keys().contains(CONTENT_INDEX_ENABLE_OCR_KEY)) { m_gsettings->set(CONTENT_INDEX_ENABLE_OCR_KEY, false); } } } else if (key == CONTENT_INDEX_ENABLE_OCR_KEY) { m_ocrSwitchBtn->blockSignals(true); m_ocrSwitchBtn->setChecked(m_gsettings->get(CONTENT_INDEX_ENABLE_OCR_KEY).toBool()); m_ocrSwitchBtn->blockSignals(false); } else if (key == WEB_ENGINE_KEY) { QString engine = m_gsettings->get(WEB_ENGINE_KEY).toString(); m_webEngineFrame->mCombox->blockSignals(true); m_webEngineFrame->mCombox->setCurrentIndex(m_webEngineFrame->mCombox->findData(engine)); m_webEngineFrame->mCombox->blockSignals(false); } else if (key == CONTENT_FUZZY_SEARCH_KEY) { bool isFuzzy = m_gsettings->get(CONTENT_FUZZY_SEARCH_KEY).toBool(); if (isFuzzy) { m_fuzzyBtn->setChecked(true); } else { m_preciseBtn->setChecked(true); } } }); connect(m_fileIndexBtn, &kdk::KSwitchButton::stateChanged, this, [ = ](bool checked) { if (m_gsettings && m_gsettings->keys().contains(SEARCH_METHOD_KEY)) { m_gsettings->set(SEARCH_METHOD_KEY, checked); } }); connect(m_contentIndexBtn, &kdk::KSwitchButton::pressed, this, [ & ] { if (!m_contentIndexBtn->isChecked()) { QMessageBox msgBox; msgBox.setModal(true); msgBox.setIcon(QMessageBox::Warning); msgBox.setText(tr("Create file content index will increase the usage of memory and CPU, do you still want to open it?")); auto button = msgBox.addButton(tr("OK"),QMessageBox::AcceptRole); msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole); msgBox.exec(); if (msgBox.clickedButton() == button) { m_contentIndexBtn->setChecked(true); } } }); connect(m_contentIndexBtn, &kdk::KSwitchButton::stateChanged, this, [ = ](bool checked) { if (m_gsettings && m_gsettings->keys().contains(CONTENT_INDEX_ENABLE_KEY)) { m_gsettings->set(CONTENT_INDEX_ENABLE_KEY, checked); } }); connect(m_ocrSwitchBtn, &kdk::KSwitchButton::stateChanged, this, [ = ](bool checked) { if (m_gsettings && m_gsettings->keys().contains(CONTENT_INDEX_ENABLE_OCR_KEY)) { m_gsettings->set(CONTENT_INDEX_ENABLE_OCR_KEY, checked); } }); connect(m_indexMethodBtnGroup, QOverload::of(&QButtonGroup::buttonToggled),[ = ](int id, bool checked) { if (id == -3) {//fuzzyBtn's id if (m_gsettings && m_gsettings->keys().contains(CONTENT_FUZZY_SEARCH_KEY)) { m_gsettings->set(CONTENT_FUZZY_SEARCH_KEY, checked); } } }); connect(m_webEngineFrame->mCombox, QOverload::of(&QComboBox::currentIndexChanged), this, [=] { if (m_gsettings && m_gsettings->keys().contains(WEB_ENGINE_KEY)) { m_gsettings->set(WEB_ENGINE_KEY, m_webEngineFrame->mCombox->currentData().toString()); } }); } else { qCritical() << "Gsettings of the search plugin for ukcc is not initialized!"; m_contentIndexBtn->setEnabled(false); m_webEngineFrame->mCombox->setEnabled(false); } return m_pluginWidget; } const QString Search::name() const { return QStringLiteral("Search"); } QString Search::translationPath() const { return QStringLiteral("/usr/share/ukui-search/search-ukcc-plugin/translations/%1.ts"); } bool Search::isShowOnHomePage() const { return true; } QIcon Search::icon() const { return QIcon::fromTheme("search-symbolic"); } bool Search::isEnable() const { return true; } /** * @brief Search::initUi 初始化此插件UI */ void Search::initUi() { m_pluginWidget = new QWidget; m_pluginWidget->setAttribute(Qt::WA_DeleteOnClose); m_mainLyt = new QVBoxLayout(m_pluginWidget); m_pluginWidget->setLayout(m_mainLyt); m_titleLabel = new TitleLabel(m_pluginWidget); //~ contents_path /Search/Search m_titleLabel->setText(tr("Search")); m_mainLyt->addWidget(m_titleLabel); //设置网页搜索引擎部分的ui //~ contents_path /Search/Default web searching engine m_webEngineFrame = new ComboxFrame(tr("Default web searching engine"), m_pluginWidget); m_webEngineFrame->setContentsMargins(8, 0, 8, 0);// ComboxFrame右侧自带8的边距,左右边距各是16所以分别设为8 m_webEngineFrame->setFixedHeight(56); m_webEngineFrame->setMinimumWidth(550); m_webEngineFrame->mCombox->insertItem(0, QIcon("/usr/share/ukui-search/search-ukcc-plugin/image/baidu.svg"), tr("baidu"), "baidu"); m_webEngineFrame->mCombox->insertItem(1, QIcon("/usr/share/ukui-search/search-ukcc-plugin/image/sougou.svg"), tr("sougou"), "sougou"); m_webEngineFrame->mCombox->insertItem(2, QIcon("/usr/share/ukui-search/search-ukcc-plugin/image/360.svg"), tr("360"), "360"); m_mainLyt->addWidget(m_webEngineFrame); //设置索引开关 m_indexTitleLabel = new TitleLabel(m_pluginWidget); //~ contents_path /Search/Create index m_indexTitleLabel->setText(tr("Create index")); m_mainLyt->addSpacing(32); m_mainLyt->addWidget(m_indexTitleLabel); m_fileIndexFrame = new QFrame(m_pluginWidget); m_fileIndexFrame->setFrameShape(QFrame::Shape::Box); m_fileIndexFrame->setFixedHeight(64); m_fileIndexLyt = new QHBoxLayout(m_fileIndexFrame); m_fileIndexLyt->setContentsMargins(16, 20, 16, 20); m_fileIndexFrame->setLayout(m_fileIndexLyt); m_fileIndexLabel = new QLabel(m_fileIndexFrame); //~ contents_path /Search/Create file index m_fileIndexLabel->setText(tr("Create file index")); m_fileIndexLabel->setContentsMargins(0, 0, 0, 0); m_fileIndexBtn = new kdk::KSwitchButton(m_fileIndexFrame); m_fileIndexLyt->addWidget(m_fileIndexLabel); m_fileIndexLyt->addStretch(); m_fileIndexLyt->addWidget(m_fileIndexBtn); m_mainLyt->addWidget(m_fileIndexFrame); //设置内容索引部分的ui m_setFrame = new QFrame(m_pluginWidget); m_setFrame->setFrameShape(QFrame::Shape::Box); m_setFrameLyt = new QVBoxLayout(m_setFrame); m_setFrameLyt->setContentsMargins(0, 0, 0, 0); m_setFrameLyt->setSpacing(0); //索引开关UI m_contentIndexFrame = new QFrame(m_setFrame); m_contentIndexFrame->setMinimumWidth(550); m_contentIndexFrame->setFixedHeight(64); m_contentIndexLyt = new QHBoxLayout(m_contentIndexFrame); m_contentIndexLyt->setContentsMargins(16, 20, 16, 20); m_contentIndexFrame->setLayout(m_contentIndexLyt); m_contentIndexLabel = new QLabel(m_contentIndexFrame); //~ contents_path /Search/Create file content index m_contentIndexLabel->setText(tr("Create file content index")); m_contentIndexLabel->setContentsMargins(0, 0, 0, 0); m_contentIndexBtn = new kdk::KSwitchButton(m_contentIndexFrame); m_contentIndexLyt->addWidget(m_contentIndexLabel); m_contentIndexLyt->addStretch(); m_contentIndexLyt->addWidget(m_contentIndexBtn); m_indexSetFrame = new QFrame(m_setFrame); m_indexSetFrame->setFixedHeight(228); m_indexSetLyt = new QVBoxLayout(m_indexSetFrame); m_indexSetLyt->setContentsMargins(0, 0, 0, 0); m_indexSetLyt->setSpacing(0); //分隔线 QFrame *line = new QFrame(m_indexSetFrame); line->setFixedHeight(1); line->setContentsMargins(0, 0, 0, 0); line->setLineWidth(0); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); //设置索引模式的ui m_indexMethodFrame = new QFrame(m_indexSetFrame); m_indexMethodFrame->setFixedHeight(103); m_indexMethodLyt = new QVBoxLayout(m_indexMethodFrame); m_indexMethodLyt->setContentsMargins(8, 0, 0, 0);// radiobutton本身左边有8间距 m_indexMethodFrame->setLayout(m_indexMethodLyt); m_preciseBtnFrame = new QFrame(m_indexMethodFrame); m_preciseBtnFrame->setFixedHeight(50); m_preciseBtnLyt = new QHBoxLayout(m_preciseBtnFrame); m_preciseBtnFrame->setLayout(m_preciseBtnLyt); m_preciseBtn = new QRadioButton(tr("Precise Search"), m_indexMethodFrame); m_preciseDescLabel = new QLabel(m_indexMethodFrame); m_preciseDescLabel->setContentsMargins(0, 0, 0, 0); m_preciseDescLabel->setText(tr("show the results that exactly match the keyword")); m_preciseDescLabel->setEnabled(false); m_preciseBtnLyt->addWidget(m_preciseBtn); m_preciseBtnLyt->addWidget(m_preciseDescLabel); m_preciseBtnLyt->addStretch(); m_fuzzyBtnFrame = new QFrame(m_indexMethodFrame); m_fuzzyBtnFrame->setFixedHeight(53); m_fuzzyBtnLyt = new QHBoxLayout(m_fuzzyBtnFrame); m_fuzzyBtnFrame->setLayout(m_fuzzyBtnLyt); m_fuzzyBtn = new QRadioButton(tr("Fuzzy Search"), m_indexMethodFrame); m_fuzzyDescLabel = new QLabel(m_indexMethodFrame); m_fuzzyDescLabel->setContentsMargins(0, 0, 0, 0); m_fuzzyDescLabel->setText(tr("show more results that match the keyword")); m_fuzzyDescLabel->setEnabled(false); m_fuzzyBtnLyt->addWidget(m_fuzzyBtn); m_fuzzyBtnLyt->addWidget(m_fuzzyDescLabel); m_fuzzyBtnLyt->addStretch(); m_indexMethodBtnGroup = new QButtonGroup(m_indexSetFrame); m_indexMethodBtnGroup->addButton(m_preciseBtn); m_indexMethodBtnGroup->addButton(m_fuzzyBtn); m_indexMethodBtnGroup->setExclusive(true); m_indexMethodLyt->addWidget(m_preciseBtnFrame); m_indexMethodLyt->addWidget(m_fuzzyBtnFrame); m_indexMethodLyt->addSpacing(24); //第二条分隔线 QFrame *ocrLine = new QFrame(m_indexSetFrame); ocrLine->setFixedHeight(1); ocrLine->setContentsMargins(0, 0, 0, 0); ocrLine->setLineWidth(0); ocrLine->setFrameShape(QFrame::HLine); ocrLine->setFrameShadow(QFrame::Sunken); //OCR开关 m_ocrSwitchFrame = new QFrame(m_indexSetFrame); m_ocrSwitchFrame->setMinimumWidth(550); m_ocrSwitchFrame->setFixedHeight(60); m_ocrSwitchLyt = new QHBoxLayout(m_contentIndexFrame); m_ocrSwitchLyt->setContentsMargins(16, 15, 16, 21); m_ocrSwitchFrame->setLayout(m_ocrSwitchLyt); m_ocrSwitchLabel = new QLabel(m_ocrSwitchFrame); //~ contents_path /Search/Use OCR to index the text in pictures m_ocrSwitchLabel->setText(tr("Index the text in pictures")); m_ocrSwitchLabel->setContentsMargins(0, 0, 0, 0); m_ocrSwitchBtn = new kdk::KSwitchButton(m_ocrSwitchFrame); m_ocrSwitchLyt->addWidget(m_ocrSwitchLabel); m_ocrSwitchLyt->addStretch(); m_ocrSwitchLyt->addWidget(m_ocrSwitchBtn); m_indexSetLyt->addWidget(line); m_indexSetLyt->addWidget(m_indexMethodFrame); m_indexSetLyt->addWidget(ocrLine); m_indexSetLyt->addWidget(m_ocrSwitchFrame); m_setFrameLyt->addWidget(m_contentIndexFrame); m_setFrameLyt->addWidget(m_indexSetFrame); m_indexSetFrame->hide();//默认隐藏,根据是否开索引来初始化 m_mainLyt->addWidget(m_setFrame); //添加搜索目录部分ui m_searchDirTitleLabel = new TitleLabel(m_pluginWidget); //~ contents_path /Search/Search Folders m_searchDirTitleLabel->setText(tr("Search Folders")); m_searchDirDescLabel = new QLabel(m_pluginWidget); m_searchDirDescLabel->setContentsMargins(16, 0, 0, 0); //TitleLabel自带16边距,QLabel需要自己设 m_searchDirDescLabel->setEnabled(false); m_searchDirDescLabel->setWordWrap(true); m_searchDirDescLabel->setText(tr("Following folders will be searched. You can set it by adding and removing folders.")); m_searchDirsFrame = new QFrame(m_pluginWidget); m_searchDirsFrame->setFrameShape(QFrame::Shape::Box); m_searchDirLyt = new QVBoxLayout(m_searchDirsFrame); m_searchDirsFrame->setLayout(m_searchDirLyt); m_searchDirLyt->setContentsMargins(0, 0, 0, 0); m_searchDirLyt->setSpacing(2); m_searchDirLyt->setDirection(QBoxLayout::BottomToTop); m_addSearchDirFrame = new QFrame(m_searchDirsFrame); m_addSearchDirFrame->setFrameShape(QFrame::Shape::NoFrame); m_addSearchDirFrame->setFixedHeight(60); m_addSearchDirBtn = new AddBtn(m_addSearchDirFrame); m_searchDirLyt->addWidget(m_addSearchDirBtn); m_mainLyt->addSpacing(32); m_mainLyt->addWidget(m_searchDirTitleLabel); m_mainLyt->addWidget(m_searchDirDescLabel); m_mainLyt->addWidget(m_searchDirsFrame); //设置黑名单文件夹部分的ui m_blockDirTitleLabel = new TitleLabel(m_pluginWidget); //~ contents_path /Search/Block Folders m_blockDirTitleLabel->setText(tr("Block Folders")); m_blockDirDescLabel = new QLabel(m_pluginWidget); m_blockDirDescLabel->setContentsMargins(16, 0, 0, 0); //TitleLabel自带16边距,QLabel需要自己设 m_blockDirDescLabel->setEnabled(false); m_blockDirDescLabel->setWordWrap(true); m_blockDirDescLabel->setText(tr("Following folders will not be searched. You can set it by adding and removing folders.")); m_blockDirsFrame = new QFrame(m_pluginWidget); m_blockDirsFrame->setFrameShape(QFrame::Shape::Box); m_blockDirsLyt = new QVBoxLayout(m_blockDirsFrame); m_blockDirsLyt->setDirection(QBoxLayout::BottomToTop); m_blockDirsFrame->setLayout(m_blockDirsLyt); m_blockDirsLyt->setContentsMargins(0, 0, 0, 0); m_blockDirsLyt->setSpacing(2); QFrame * m_addBlockDirFrame = new QFrame(m_blockDirsFrame); m_addBlockDirFrame->setFrameShape(QFrame::Shape::NoFrame); m_addBlockDirFrame->setFixedHeight(60); m_addBlockDirWidget = new AddBtn(m_addBlockDirFrame); m_blockDirsLyt->addWidget(m_addBlockDirWidget); m_mainLyt->addSpacing(32); m_mainLyt->addWidget(m_blockDirTitleLabel); m_mainLyt->addWidget(m_blockDirDescLabel); m_mainLyt->addWidget(m_blockDirsFrame); m_mainLyt->addStretch(); m_mainLyt->setContentsMargins(0, 0, 0, 0); } void Search::refreshSearchDirsUi() { qWarning() << "==========refreshUi!!!!"; while (m_searchDirLyt->count() - 1) { QWidget *widget = m_searchDirLyt->itemAt(m_searchDirLyt->count() - 1)->widget(); m_searchDirLyt->removeWidget(widget); widget->deleteLater(); } initSearchDirs(); } /** * @brief Search::getBlockDirs 从配置文件获取黑名单并将黑名单列表传入 */ void Search::getBlockDirs() { if (m_interface->isValid()) { QDBusReply reply = m_interface->call("blockDirsForUser"); if (reply.isValid()) { m_blockDirs = reply.value(); } } } /** * @brief Search::setBlockDir 尝试写入新的黑名单文件夹 * @param dirPath 待添加到黑名单的文件夹路径 * @param is_add 是否是在添加黑名单 * @return 0成功 !0添加失败的错误代码 */ int Search::setBlockDir(const QString &dirPath, const bool &is_add) { if (!QFile::exists(dirPath)) { removeBlockDirFromList(dirPath); return ReturnCode::NotExists; } QStringList pathSections = dirPath.split("/"); for (const QString §ion : pathSections) { if (section.startsWith(".")) { return ReturnCode::Hidden; } } if (!m_interface->isValid()) { return ReturnCode::DirWatcherError; } if (!is_add) { //删除黑名单目录 m_interface->call("removeBlockDirOfUser", dirPath); removeBlockDirFromList(dirPath); return ReturnCode::Successful; } QStringList oldBlockList = m_blockDirs; getBlockDirs(); for (const QString& oldBlockDir : oldBlockList) { if (!m_blockDirs.contains(oldBlockDir)) { removeBlockDirFromList(oldBlockDir); } } for (QString dir : m_blockDirs) { if (dirPath == dir) { return ReturnCode::HasBeenBlocked; } if (dirPath.startsWith(dir + "/") || dir == "/") { return ReturnCode::Duplicated; } //有它的子文件夹已被添加,删除这些子文件夹 if (dir.startsWith(dirPath + "/") || dirPath == "/") { removeBlockDirFromList(dir); } } m_interface->call("addBlockDirOfUser", dirPath); appendBlockDirToList(dirPath); return ReturnCode::Successful; } /** * @brief Search::initBlockDirsList 初始化黑名单列表 */ void Search::initBlockDirsList() { getBlockDirs(); for (QString path: m_blockDirs) { if (QFileInfo(path).isDir() /*&& path.startsWith("home")*/) { appendBlockDirToList(path); } } } void Search::initSearchDirs() { if (m_interface->isValid()) { QDBusReply reply = m_interface->call("currentIndexableDir"); if (reply.isValid()) { for (const QString &path : reply.value()) { appendSearchDirToList(path); } } else { qCritical() << "Fail to call currentIndexableDir."; } } else { qCritical() << "fileindex dbus error:" << m_interface->lastError(); } } int Search::setSearchDir(const QString &dirPath, const bool isAdd) { QFileInfo info(dirPath); if (!(info.isExecutable() && info.isReadable())) { //路径不存在时从ui上删除 if (!isAdd) { this->removeSearchDirFromList(dirPath); } return ReturnCode::PermissionDenied; } if (!m_setSearchDirInterface->isValid()) { return ReturnCode::DirWatcherError; } QStringList pathSections = dirPath.split("/"); for (const QString §ion : pathSections) { if (section.startsWith(".")) { return ReturnCode::Hidden; } } if (isAdd) { QDBusReply indexDirsRpl = m_interface->call("currentSearchDirs"); QStringList indexDirs; if (indexDirsRpl.isValid()) { indexDirs = indexDirsRpl.value(); } QDBusReply appendIndexRpl = m_setSearchDirInterface->call("appendSearchDir", dirPath); if (appendIndexRpl.isValid()) { if (appendIndexRpl.value() == 0) { this->appendSearchDirToList(dirPath); if (!indexDirs.isEmpty()) { indexDirsRpl = m_interface->call("currentSearchDirs"); if (indexDirsRpl.isValid() && (indexDirsRpl.value().size() < indexDirs.size() + 1)) { QStringList dirsAfterAppend = indexDirsRpl.value(); for (const QString& dir : indexDirs) { if (!dirsAfterAppend.contains(dir)) { this->removeSearchDirFromList(dir); } } } } } return appendIndexRpl.value(); } } else { this->removeSearchDirFromList(dirPath); m_setSearchDirInterface->call("removeSearchDir", dirPath); } return ReturnCode::Successful; } void Search::appendSearchDirToList(const QString &path) { HoverWidget * dirWidget = new HoverWidget(path, m_searchDirsFrame); dirWidget->setObjectName(path); dirWidget->setMinimumWidth(550); QHBoxLayout * dirWidgetLyt = new QHBoxLayout(dirWidget); dirWidgetLyt->setSpacing(8); dirWidgetLyt->setContentsMargins(0, 0, 0, 0); dirWidget->setLayout(dirWidgetLyt); QFrame * dirFrame = new QFrame(dirWidget); dirFrame->setFrameShape(QFrame::Shape::Box); dirFrame->setFixedHeight(50); QHBoxLayout * dirFrameLayout = new QHBoxLayout(dirFrame); dirFrameLayout->setSpacing(16); dirFrameLayout->setContentsMargins(16, 0, 16, 0); QLabel * iconLabel = new QLabel(dirFrame); QLabel * pathLabel = new QLabel(dirFrame); dirFrameLayout->addWidget(iconLabel); iconLabel->setPixmap(QIcon::fromTheme("inode-directory").pixmap(QSize(24, 24))); pathLabel->setText(path); dirFrameLayout->addWidget(pathLabel); dirFrameLayout->addStretch(); QPushButton * delBtn = new QPushButton(dirFrame); delBtn->setIcon(QIcon::fromTheme("edit-delete-symbolic")); delBtn->setProperty("useButtonPalette", true); delBtn->setFixedSize(30, 30); delBtn->setToolTip(tr("delete")); delBtn->setFlat(true); delBtn->hide(); dirFrameLayout->addWidget(delBtn); dirWidgetLyt->addWidget(dirFrame); QFrame *line = new QFrame(dirWidget); line->setObjectName(path); line->setFixedHeight(1); line->setLineWidth(0); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); m_searchDirLyt->addWidget(line); m_searchDirLyt->addWidget(dirWidget); connect(delBtn, &QPushButton::clicked, this, [ = ]() { setSearchDir(path, false); }); connect(dirWidget, &HoverWidget::enterWidget, this, [ = ]() { delBtn->show(); }); connect(dirWidget, &HoverWidget::leaveWidget, this, [ = ]() { delBtn->hide(); }); } void Search::removeSearchDirFromList(const QString &path) { HoverWidget *delDirWidget = m_searchDirsFrame->findChild(path); if (delDirWidget) { m_searchDirLyt->removeWidget(delDirWidget); delDirWidget->deleteLater(); qDebug() << "Delete folder of search succeed! path = " << path; } QFrame *line = m_searchDirsFrame->findChild(path); if (line) { m_searchDirLyt->removeWidget(line); line->deleteLater(); qDebug()<< "Delete line of search folder:" << path; } } void Search::appendBlockDirToList(const QString &path) { HoverWidget * dirWidget = new HoverWidget(path, m_blockDirsFrame); dirWidget->setObjectName(path); dirWidget->setMinimumWidth(550); QHBoxLayout * dirWidgetLyt = new QHBoxLayout(dirWidget); dirWidgetLyt->setSpacing(8); dirWidgetLyt->setContentsMargins(0, 0, 0, 0); dirWidget->setLayout(dirWidgetLyt); QFrame * dirFrame = new QFrame(dirWidget); dirFrame->setFrameShape(QFrame::Shape::Box); dirFrame->setFixedHeight(50); QHBoxLayout * dirFrameLayout = new QHBoxLayout(dirFrame); dirFrameLayout->setSpacing(16); dirFrameLayout->setContentsMargins(16, 0, 16, 0); QLabel * iconLabel = new QLabel(dirFrame); QLabel * pathLabel = new QLabel(dirFrame); dirFrameLayout->addWidget(iconLabel); iconLabel->setPixmap(QIcon::fromTheme("inode-directory").pixmap(QSize(24, 24))); pathLabel->setText(path); dirFrameLayout->addWidget(pathLabel); dirFrameLayout->addStretch(); QPushButton * delBtn = new QPushButton(dirFrame); delBtn->setIcon(QIcon::fromTheme("edit-delete-symbolic")); delBtn->setProperty("useButtonPalette", true); delBtn->setFixedSize(30, 30); delBtn->setToolTip(tr("delete")); delBtn->setFlat(true); delBtn->hide(); dirFrameLayout->addWidget(delBtn); dirWidgetLyt->addWidget(dirFrame); // dirWidgetLyt->addWidget(delBtn); QFrame *line = new QFrame(m_blockDirsFrame); line->setObjectName(path); line->setFixedHeight(1); line->setLineWidth(0); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); // m_setFrameLyt->addWidget(line); m_blockDirsLyt->addWidget(line); m_blockDirsLyt->addWidget(dirWidget); connect(delBtn, &QPushButton::clicked, this, [ = ]() { setBlockDir(path, false); getBlockDirs(); }); connect(dirWidget, &HoverWidget::enterWidget, this, [ = ]() { delBtn->show(); }); connect(dirWidget, &HoverWidget::leaveWidget, this, [ = ]() { delBtn->hide(); }); } void Search::removeBlockDirFromList(const QString &path) { HoverWidget * delDirWidget = m_blockDirsFrame->findChild(path); if (delDirWidget) { qDebug() << "Delete blocked folder succeed! path = " << path; m_blockDirsLyt->removeWidget(delDirWidget); delDirWidget->deleteLater(); } QFrame *line = m_blockDirsFrame->findChild(path); if (line) { m_blockDirsLyt->removeWidget(line); line->deleteLater(); qDebug() << "Delete line of blocked folder:" << path; } } void Search::setupConnection() { connect(m_addBlockDirWidget, &QPushButton::clicked, this, &Search::onBtnAddBlockFolderClicked); } void Search::onBtnAddBlockFolderClicked() { auto blockDirDialog = new QFileDialog; blockDirDialog->setFileMode(QFileDialog::DirectoryOnly); //只允许查看文件夹 // fileDialog->setViewMode(QFileDialog::Detail); blockDirDialog->setDirectory(m_lastBlockDialogDir); blockDirDialog->setNameFilter(tr("Directories")); blockDirDialog->setWindowTitle(tr("select blocked folder")); blockDirDialog->setLabelText(QFileDialog::Accept, tr("Select")); blockDirDialog->setLabelText(QFileDialog::LookIn, tr("Position: ")); blockDirDialog->setLabelText(QFileDialog::FileName, tr("FileName: ")); blockDirDialog->setLabelText(QFileDialog::FileType, tr("FileType: ")); blockDirDialog->setLabelText(QFileDialog::Reject, tr("Cancel")); connect(blockDirDialog, &QFileDialog::finished, [ = ] (int result) { if (result == QDialog::Accepted) { QString selectedDir = blockDirDialog->selectedFiles().first(); m_lastBlockDialogDir = selectedDir.left(selectedDir.lastIndexOf("/") + 1); qWarning() << "======history of block dialog changed into " << m_lastBlockDialogDir; qDebug() << "Selected a folder in onBtnAddClicked(): " << selectedDir; int returnCode = setBlockDir(selectedDir, true); switch (returnCode) { case ReturnCode::Successful : qDebug() << "Add blocked folder succeed! path = " << selectedDir; getBlockDirs(); break; case ReturnCode::Duplicated : qWarning() << "Add blocked folder failed, its parent dir is exist! path = " << selectedDir; QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add blocked folder failed, its parent dir has been added!")); break; case ReturnCode::NotExists : qWarning() << "Add blocked folder failed, it's not exist! path = " << selectedDir; QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add blocked folder failed, choosen path is not exist!")); break; case ReturnCode::HasBeenBlocked : qWarning() << "Add blocked folder failed, it has been already blocked! path = " << selectedDir; QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add blocked folder failed, it has already been blocked!")); break; case ReturnCode::Hidden : qWarning() << "Add blocked folder failed, it has been hidden! path = " << selectedDir; QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add search folder failed, hidden path is not supported!")); break; default: break; } } }); blockDirDialog->exec(); if (blockDirDialog) { delete blockDirDialog; blockDirDialog = nullptr; } } void Search::onAddSearchDirBtnClicked() { //添加搜索目录对话框 auto searchDirDialog = new QFileDialog; searchDirDialog->setFileMode(QFileDialog::DirectoryOnly); //只允许查看文件夹 searchDirDialog->setDirectory(m_lastSearchDialogDir); searchDirDialog->setNameFilter(tr("Directories")); searchDirDialog->setWindowTitle(tr("select search folder")); searchDirDialog->setLabelText(QFileDialog::Accept, tr("Select")); searchDirDialog->setLabelText(QFileDialog::LookIn, tr("Position: ")); searchDirDialog->setLabelText(QFileDialog::FileName, tr("FileName: ")); searchDirDialog->setLabelText(QFileDialog::FileType, tr("FileType: ")); searchDirDialog->setLabelText(QFileDialog::Reject, tr("Cancel")); connect(searchDirDialog, &QFileDialog::finished, this, [ = ] (int result) { if (result == QDialog::Accepted) { QString selectedDir = searchDirDialog->selectedFiles().first(); m_lastSearchDialogDir = selectedDir.left(selectedDir.lastIndexOf("/") + 1); qDebug() << "======history of search dialog changed into " << m_lastSearchDialogDir; qDebug() << "Selected a folder in onAddSearchDirBtnClicked(): " << selectedDir; int returnCode = setSearchDir(selectedDir, true); switch (returnCode) { case ReturnCode::Successful: qDebug() << "Add search folder succeed! path = " << selectedDir; break; case ReturnCode::Duplicated: QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add search folder failed, choosen path or its parent dir has been added!")); break; case ReturnCode::UnderBlackList: QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add search folder failed, choosen path is not supported currently!")); break; case ReturnCode::RepeatMount1: QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add search folder failed, choosen path is in repeat mounted devices and another path which is in the same device has been added!")); break; case ReturnCode::RepeatMount2: QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add search folder failed, another path which is in the same device has been added!")); break; case ReturnCode::NotExists: QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add search folder failed, choosen path is not exists!")); break; case ReturnCode::Hidden : QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add search folder failed, hidden path is not supported!")); break; case ReturnCode::PermissionDenied: QMessageBox::warning(m_pluginWidget, tr("Warning"), tr("Add search folder failed, permission denied!")); break; default: break; } } }); //open()会导致cpu占用拉满 // searchDirDialog->open(); searchDirDialog->exec(); if (searchDirDialog) { delete searchDirDialog; searchDirDialog = nullptr; } }