forked from openkylin/ukui-search
Remove useless code.
This commit is contained in:
parent
e59c369221
commit
c69c04207b
|
@ -1,828 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "content-widget.h"
|
||||
#include <QDebug>
|
||||
#include <QLabel>
|
||||
#include <QTimer>
|
||||
#include "config-file.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
ContentWidget::ContentWidget(QWidget * parent): QStackedWidget(parent) {
|
||||
initUI();
|
||||
initListView();
|
||||
//快速入口应用列表
|
||||
// m_quicklyOpenList<<"/usr/share/applications/peony.desktop"<<"/usr/share/applications/ukui-control-center.desktop"<<"/usr/share/applications/ksc-defender.desktop";
|
||||
m_quicklyOpenList << "/usr/share/applications/ksc-defender.desktop"
|
||||
<< "/usr/share/applications/ukui-notebook.desktop"
|
||||
<< "/usr/share/applications/kylin-photo-viewer.desktop"
|
||||
<< "/usr/share/applications/pluma.desktop"
|
||||
<< "/usr/share/applications/claws-mail.desktop" ;
|
||||
if (QString::compare(FileUtils::getAppName(m_quicklyOpenList.at(2)), "Unknown App") == 0) {
|
||||
m_quicklyOpenList.replace(2, "/usr/share/applications/eom.desktop");
|
||||
}
|
||||
if (QString::compare(FileUtils::getAppName(m_quicklyOpenList.at(4)), "Unknown App") == 0) {
|
||||
m_quicklyOpenList.replace(4, "/usr/share/applications/evolution.desktop");
|
||||
}
|
||||
}
|
||||
|
||||
ContentWidget::~ContentWidget() {
|
||||
if(m_homePage) {
|
||||
delete m_homePage;
|
||||
m_homePage = nullptr;
|
||||
}
|
||||
if(m_resultPage) {
|
||||
delete m_resultPage;
|
||||
m_resultPage = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initUI 初始化homepage和resultpage
|
||||
*/
|
||||
void ContentWidget::initUI() {
|
||||
this->setFixedHeight(486);
|
||||
QPalette pal = palette();
|
||||
QPalette scroll_bar_pal = palette();
|
||||
// pal.setColor(QPalette::Base, QColor(0, 0, 0, 0));
|
||||
pal.setColor(QPalette::Window, QColor(0, 0, 0, 0)); //使用此palette的窗口背景将为透明
|
||||
scroll_bar_pal.setColor(QPalette::Base, QColor(0, 0, 0, 0));
|
||||
m_homePage = new QWidget(this);
|
||||
m_homePageLyt = new QVBoxLayout(m_homePage);
|
||||
m_homePageLyt->setSpacing(0);
|
||||
m_homePageLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_homePage->setLayout(m_homePageLyt);
|
||||
|
||||
m_resultPage = new QWidget(this);
|
||||
m_resultPageLyt = new QHBoxLayout(m_resultPage);
|
||||
m_resultPageLyt->setSpacing(0);
|
||||
m_resultPageLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_resultListArea = new QScrollArea(m_resultPage);
|
||||
m_resultListArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_resultListArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
m_resultDetailArea = new QScrollArea(m_resultPage);
|
||||
m_resultDetailArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_resultDetailArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
m_resultListArea->setFixedWidth(280);
|
||||
m_resultPageLyt->addWidget(m_resultListArea);
|
||||
m_resultPageLyt->addWidget(m_resultDetailArea);
|
||||
m_resultPage->setLayout(m_resultPageLyt);
|
||||
|
||||
m_resultList = new QWidget(m_resultListArea);
|
||||
m_resultDetail = new QWidget(m_resultDetailArea);
|
||||
m_listLyt = new QVBoxLayout(m_resultList);
|
||||
m_detailLyt = new QVBoxLayout(m_resultDetail);
|
||||
//需要给滚动条留出16个像素点的宽度
|
||||
m_resultList->setFixedWidth(280 - 16);
|
||||
m_resultList->setFixedHeight(0);
|
||||
m_listLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_listLyt->setSpacing(0);
|
||||
m_resultListArea->setWidget(m_resultList);
|
||||
m_resultListArea->setWidgetResizable(true);
|
||||
m_detailView = new SearchDetailView(m_resultDetailArea);
|
||||
connect(m_detailView, &SearchDetailView::configFileChanged, this, [ = ]() {
|
||||
clearLayout(m_homePageLyt);
|
||||
initHomePage();
|
||||
});
|
||||
connect(m_detailView, &SearchDetailView::actionTriggerd, this, &ContentWidget::effectiveSearch);
|
||||
m_resultDetailArea->setWidget(m_detailView);
|
||||
m_resultDetailArea->setWidgetResizable(true);
|
||||
m_resultListArea->setFrameShape(QFrame::NoFrame);
|
||||
m_resultDetailArea->setFrameShape(QFrame::NoFrame);
|
||||
m_resultListArea->setPalette(pal);
|
||||
m_resultDetailArea->setPalette(pal);
|
||||
m_resultListArea->verticalScrollBar()->setPalette(scroll_bar_pal);
|
||||
m_resultDetailArea->verticalScrollBar()->setPalette(scroll_bar_pal);
|
||||
this->addWidget(m_homePage);
|
||||
this->addWidget(m_resultPage);
|
||||
|
||||
setPage(SearchItem::SearchType::Best);//初始化按“最佳”加载
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::initListView 初始化所有搜索结果列表
|
||||
*/
|
||||
void ContentWidget::initListView() {
|
||||
m_fileListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Files);
|
||||
m_dirListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Dirs);
|
||||
m_contentListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Contents);
|
||||
m_settingListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Settings);
|
||||
m_appListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Apps);
|
||||
m_bestListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Best);
|
||||
m_webListView = new SearchListView(m_resultList, QStringList(), SearchItem::SearchType::Web);
|
||||
|
||||
setupConnect(m_fileListView);
|
||||
setupConnect(m_dirListView);
|
||||
setupConnect(m_contentListView);
|
||||
setupConnect(m_settingListView);
|
||||
setupConnect(m_appListView);
|
||||
setupConnect(m_bestListView);
|
||||
setupConnect(m_webListView);
|
||||
|
||||
m_fileTitleLabel = new TitleLabel(m_resultList);
|
||||
m_fileTitleLabel->setText(getTitleName(SearchItem::SearchType::Files));
|
||||
m_dirTitleLabel = new TitleLabel(m_resultList);
|
||||
m_dirTitleLabel->setText(getTitleName(SearchItem::SearchType::Dirs));
|
||||
m_contentTitleLabel = new TitleLabel(m_resultList);
|
||||
m_contentTitleLabel->setText(getTitleName(SearchItem::SearchType::Contents));
|
||||
m_appTitleLabel = new TitleLabel(m_resultList);
|
||||
m_appTitleLabel->setText(getTitleName(SearchItem::SearchType::Apps));
|
||||
m_settingTitleLabel = new TitleLabel(m_resultList);
|
||||
m_settingTitleLabel->setText(getTitleName(SearchItem::SearchType::Settings));
|
||||
m_bestTitleLabel = new TitleLabel(m_resultList);
|
||||
m_bestTitleLabel->setText(getTitleName(SearchItem::SearchType::Best));
|
||||
m_webTitleLabel = new TitleLabel(m_resultList);
|
||||
m_webTitleLabel->setText(getTitleName(SearchItem::SearchType::Web));
|
||||
|
||||
m_appShowMoreLabel = new ShowMoreLabel(m_resultList);
|
||||
m_settingShowMoreLabel = new ShowMoreLabel(m_resultList);
|
||||
m_dirShowMoreLabel = new ShowMoreLabel(m_resultList);
|
||||
m_fileShowMoreLabel = new ShowMoreLabel(m_resultList);
|
||||
m_contentShowMoreLabel = new ShowMoreLabel(m_resultList);
|
||||
|
||||
m_listLyt->addWidget(m_bestTitleLabel);
|
||||
m_listLyt->addWidget(m_bestListView);
|
||||
m_listLyt->addWidget(m_appTitleLabel);
|
||||
m_listLyt->addWidget(m_appListView);
|
||||
m_listLyt->addWidget(m_appShowMoreLabel);
|
||||
m_listLyt->addWidget(m_settingTitleLabel);
|
||||
m_listLyt->addWidget(m_settingListView);
|
||||
m_listLyt->addWidget(m_settingShowMoreLabel);
|
||||
m_listLyt->addWidget(m_dirTitleLabel);
|
||||
m_listLyt->addWidget(m_dirListView);
|
||||
m_listLyt->addWidget(m_dirShowMoreLabel);
|
||||
m_listLyt->addWidget(m_fileTitleLabel);
|
||||
m_listLyt->addWidget(m_fileListView);
|
||||
m_listLyt->addWidget(m_fileShowMoreLabel);
|
||||
m_listLyt->addWidget(m_contentTitleLabel);
|
||||
m_listLyt->addWidget(m_contentListView);
|
||||
m_listLyt->addWidget(m_contentShowMoreLabel);
|
||||
m_listLyt->addWidget(m_webTitleLabel);
|
||||
m_listLyt->addWidget(m_webListView);
|
||||
|
||||
this->hideListView();
|
||||
m_resultList->setFixedHeight(0);
|
||||
|
||||
m_resultListArea->setFocusProxy(m_bestListView);
|
||||
m_bestListView->setFocus();
|
||||
connect(m_appShowMoreLabel, &ShowMoreLabel::showMoreClicked, this, [ = ]() {
|
||||
m_appListView->setList(m_appList);
|
||||
m_appShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
m_resultListArea->setFocusProxy(m_appListView);
|
||||
m_appListView->setFocus();
|
||||
});
|
||||
connect(m_appShowMoreLabel, &ShowMoreLabel::retractClicked, this, [ = ]() {
|
||||
m_appListView->setList(m_appList.mid(0, 5));
|
||||
m_appShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
});
|
||||
connect(m_settingShowMoreLabel, &ShowMoreLabel::showMoreClicked, this, [ = ]() {
|
||||
m_settingListView->setList(m_settingList);
|
||||
m_settingShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
m_resultListArea->setFocusProxy(m_settingListView);
|
||||
m_settingListView->setFocus();
|
||||
});
|
||||
connect(m_settingShowMoreLabel, &ShowMoreLabel::retractClicked, this, [ = ]() {
|
||||
m_settingListView->setList(m_settingList.mid(0, 5));
|
||||
m_settingShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
});
|
||||
connect(m_dirShowMoreLabel, &ShowMoreLabel::showMoreClicked, this, [ = ]() {
|
||||
m_dirListView->setList(m_dirList);
|
||||
m_dirShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
m_resultListArea->setFocusProxy(m_dirListView);
|
||||
m_dirListView->setFocus();
|
||||
});
|
||||
connect(m_dirShowMoreLabel, &ShowMoreLabel::retractClicked, this, [ = ]() {
|
||||
m_dirListView->setList(m_dirList.mid(0, 5));
|
||||
m_dirShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
});
|
||||
connect(m_fileShowMoreLabel, &ShowMoreLabel::showMoreClicked, this, [ = ]() {
|
||||
m_fileListView->setList(m_fileList);
|
||||
m_fileShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
m_resultListArea->setFocusProxy(m_fileListView);
|
||||
m_fileListView->setFocus();
|
||||
});
|
||||
connect(m_fileShowMoreLabel, &ShowMoreLabel::retractClicked, this, [ = ]() {
|
||||
m_fileListView->setList(m_fileList.mid(0, 5));
|
||||
m_fileShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
});
|
||||
connect(m_contentShowMoreLabel, &ShowMoreLabel::showMoreClicked, this, [ = ]() {
|
||||
m_contentListView->setList(m_contentList);
|
||||
m_contentShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
m_resultListArea->setFocusProxy(m_contentListView);
|
||||
m_contentListView->setFocus();
|
||||
});
|
||||
connect(m_contentShowMoreLabel, &ShowMoreLabel::retractClicked, this, [ = ]() {
|
||||
m_contentListView->setList(m_contentList.mid(0, 5));
|
||||
m_contentShowMoreLabel->stopLoading();
|
||||
this->resetListHeight();
|
||||
});
|
||||
|
||||
connect(qApp, &QApplication::paletteChanged, this, [ = ]() {
|
||||
m_fileListView->refresh();
|
||||
m_dirListView->refresh();
|
||||
m_contentListView->refresh();
|
||||
m_settingListView->refresh();
|
||||
m_appListView->refresh();
|
||||
m_bestListView->refresh();
|
||||
m_webListView->refresh();
|
||||
this->resetListHeight();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::hideListView 隐藏所有列表
|
||||
*/
|
||||
void ContentWidget::hideListView() {
|
||||
m_bestTitleLabel->hide();
|
||||
m_bestListView->hide();
|
||||
m_appTitleLabel->hide();
|
||||
m_appListView->hide();
|
||||
m_appShowMoreLabel->hide();
|
||||
m_settingTitleLabel->hide();
|
||||
m_settingListView->hide();
|
||||
m_settingShowMoreLabel->hide();
|
||||
m_dirTitleLabel->hide();
|
||||
m_dirListView->hide();
|
||||
m_dirShowMoreLabel->hide();
|
||||
m_fileTitleLabel->hide();
|
||||
m_fileListView->hide();
|
||||
m_fileShowMoreLabel->hide();
|
||||
m_contentTitleLabel->hide();
|
||||
m_contentListView->hide();
|
||||
m_contentShowMoreLabel->hide();
|
||||
m_webTitleLabel->hide();
|
||||
m_webListView->hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::setupConnect 初始化各个treeview的信号与槽
|
||||
* @param listview
|
||||
*/
|
||||
void ContentWidget::setupConnect(SearchListView * listview) {
|
||||
connect(this, &ContentWidget::currentItemChanged, listview, [ = ]() {
|
||||
|
||||
if(! listview->is_current_list) {
|
||||
listview->blockSignals(true);
|
||||
listview->clearSelection();
|
||||
listview->blockSignals(false);
|
||||
}
|
||||
});
|
||||
connect(listview, &SearchListView::currentSelectPos, [ = ](QPoint pos) {
|
||||
m_resultListArea->ensureVisible(pos.x(), pos.y());
|
||||
});
|
||||
connect(listview, &SearchListView::mousePressed, this, &ContentWidget::effectiveSearch);
|
||||
connect(listview, &SearchListView::currentRowChanged, this, &ContentWidget::onListViewRowChanged);
|
||||
connect(listview, &SearchListView::onRowDoubleClicked, this, &ContentWidget::onListViewRowDoubleClicked);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::resetHeight 重新计算列表高度
|
||||
*/
|
||||
void ContentWidget::resetListHeight() {
|
||||
int height = 0;
|
||||
if(! m_bestListView->isHidden) {
|
||||
height += m_bestTitleLabel->height();
|
||||
height += m_bestListView->height();
|
||||
}
|
||||
if(! m_appListView->isHidden) {
|
||||
height += m_appTitleLabel->height();
|
||||
height += m_appListView->height();
|
||||
if(m_appShowMoreLabel->isVisible()) {
|
||||
height += m_appShowMoreLabel->height();
|
||||
}
|
||||
}
|
||||
if(! m_settingListView->isHidden) {
|
||||
height += m_settingTitleLabel->height();
|
||||
height += m_settingListView->height();
|
||||
if(m_settingShowMoreLabel->isVisible()) {
|
||||
height += m_settingShowMoreLabel->height();
|
||||
}
|
||||
}
|
||||
if(! m_fileListView->isHidden) {
|
||||
height += m_fileTitleLabel->height();
|
||||
height += m_fileListView->height();
|
||||
if(m_fileShowMoreLabel->isVisible()) {
|
||||
height += m_fileShowMoreLabel->height();
|
||||
}
|
||||
}
|
||||
if(! m_dirListView->isHidden) {
|
||||
height += m_dirTitleLabel->height();
|
||||
height += m_dirListView->height();
|
||||
if(m_dirShowMoreLabel->isVisible()) {
|
||||
height += m_dirShowMoreLabel->height();
|
||||
}
|
||||
}
|
||||
if(! m_contentListView->isHidden) {
|
||||
height += m_contentTitleLabel->height();
|
||||
height += m_contentListView->height();
|
||||
if(m_contentShowMoreLabel->isVisible()) {
|
||||
height += m_contentShowMoreLabel->height();
|
||||
}
|
||||
}
|
||||
if(! m_webListView->isHidden) {
|
||||
height += m_webTitleLabel->height();
|
||||
height += m_webListView->height();
|
||||
}
|
||||
m_resultList->setFixedHeight(height);
|
||||
}
|
||||
|
||||
void ContentWidget::appendBestItem(const int &type, const QString &path) {
|
||||
m_bestList.append(QPair<int, QString>(type, path));
|
||||
m_bestListView->appendBestItem(QPair<int, QString>(type, path));
|
||||
appendSearchItem(SearchItem::SearchType::Best, path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::initHomePage 向homepage填充内容
|
||||
* @param lists 三个列表:常用,最近,快捷
|
||||
*/
|
||||
void ContentWidget::initHomePage() {
|
||||
QVector<QStringList> lists;
|
||||
QMap<QString, QStringList> map = ConfigFile::readConfig();
|
||||
QStringList commonlyList;
|
||||
commonlyList = map.value("Commonly");
|
||||
QStringList recentlyList;
|
||||
recentlyList = map.value("Recently");
|
||||
|
||||
lists.append(m_quicklyOpenList);
|
||||
lists.append(recentlyList);
|
||||
lists.append(commonlyList);
|
||||
|
||||
for(int i = 0; i < lists.count(); i++) {
|
||||
if(lists.at(i).isEmpty())
|
||||
continue;
|
||||
QWidget * listWidget = new QWidget(m_homePage);
|
||||
QVBoxLayout * itemWidgetLyt = new QVBoxLayout(listWidget);
|
||||
QLabel * titleLabel = new QLabel(listWidget);
|
||||
QWidget * itemWidget = new QWidget(listWidget);
|
||||
if(i == 1) {
|
||||
if(lists.at(i).length() <= 2) itemWidget->setFixedHeight(48);
|
||||
else itemWidget->setFixedHeight(104);
|
||||
titleLabel->setText(tr("Recently Opened"));
|
||||
QGridLayout * layout = new QGridLayout(itemWidget);
|
||||
layout->setSpacing(8);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
itemWidget->setLayout(layout);
|
||||
for(int j = 0; j < lists.at(i).count(); j++) {
|
||||
HomePageItem * item = new HomePageItem(itemWidget, i, lists.at(i).at(j));
|
||||
item->setFixedSize(312, 48);
|
||||
layout->addWidget(item, j / 2, j % 2);
|
||||
}
|
||||
if(lists.at(i).length() == 1) {
|
||||
QWidget * emptyItem = new QWidget(itemWidget);
|
||||
emptyItem->setFixedSize(300, 48); //占位用widget,只有一项时在右方补全
|
||||
layout->addWidget(emptyItem, 1, 2);
|
||||
}
|
||||
} else {
|
||||
itemWidget->setFixedHeight(116);
|
||||
QHBoxLayout * layout = new QHBoxLayout(itemWidget);
|
||||
layout->setSpacing(8);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
itemWidget->setLayout(layout);
|
||||
int shownItem = lists.at(i).length();
|
||||
Q_FOREACH(QString path, lists.at(i)) {
|
||||
if(i == 0 && QString::compare(FileUtils::getAppName(path), "Unknown App") == 0) {
|
||||
shownItem --;
|
||||
continue;
|
||||
}
|
||||
HomePageItem * item = new HomePageItem(itemWidget, i, path);
|
||||
item->setFixedSize(116, 116);
|
||||
layout->addWidget(item);
|
||||
}
|
||||
for(int j = 0; j < 5 - shownItem; j++) {
|
||||
QWidget * emptyItem = new QWidget(itemWidget);
|
||||
emptyItem->setFixedSize(116, 116); //占位用widget,少于5项会补全后方占位
|
||||
layout->addWidget(emptyItem);
|
||||
}
|
||||
if(i == 0 && shownItem) titleLabel->setText(tr("Open Quickly"));
|
||||
else titleLabel->setText(tr("Commonly Used"));
|
||||
}
|
||||
itemWidgetLyt->setSpacing(6);
|
||||
titleLabel->setFixedHeight(24);
|
||||
titleLabel->setContentsMargins(6,0,0,0);
|
||||
itemWidgetLyt->addWidget(titleLabel);
|
||||
itemWidgetLyt->addWidget(itemWidget);
|
||||
m_homePageLyt->addWidget(listWidget);
|
||||
}
|
||||
m_homePageLyt->addStretch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setPageType 预留的接口,为指定类别搜索调整界面内容
|
||||
* @param type
|
||||
*/
|
||||
void ContentWidget::setPage(const int& type) {
|
||||
m_currentType = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::currentType 返回当前内容页(home或searchresult)
|
||||
* @return
|
||||
*/
|
||||
int ContentWidget::currentPage() {
|
||||
return m_currentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::resetSearchList 在构建新的搜索结果列表前,先重置所有控件
|
||||
*/
|
||||
void ContentWidget::resetSearchList() {
|
||||
// this->hideListView();
|
||||
if(m_fileListView) {
|
||||
m_fileListView->hide();
|
||||
m_fileTitleLabel->hide();
|
||||
m_fileShowMoreLabel->hide();
|
||||
m_fileListView->isHidden = true;
|
||||
m_fileListView->clear();
|
||||
}
|
||||
if(m_dirListView) {
|
||||
m_dirListView->hide();
|
||||
m_dirTitleLabel->hide();
|
||||
m_dirShowMoreLabel->hide();
|
||||
m_dirListView->isHidden = true;
|
||||
m_dirListView->clear();
|
||||
}
|
||||
if(m_contentListView) {
|
||||
m_contentListView->hide();
|
||||
m_contentTitleLabel->hide();
|
||||
m_contentShowMoreLabel->hide();
|
||||
m_contentListView->isHidden = true;
|
||||
m_contentListView->clear();
|
||||
}
|
||||
if(m_appListView) {
|
||||
m_appListView->hide();
|
||||
m_appTitleLabel->hide();
|
||||
m_appShowMoreLabel->hide();
|
||||
m_appListView->isHidden = true;
|
||||
m_appListView->clear();
|
||||
}
|
||||
if(m_settingListView) {
|
||||
m_settingListView->hide();
|
||||
m_settingTitleLabel->hide();
|
||||
m_settingShowMoreLabel->hide();
|
||||
m_settingListView->isHidden = true;
|
||||
m_settingListView->clear();
|
||||
}
|
||||
if(m_bestListView) {
|
||||
m_bestListView->hide();
|
||||
m_bestTitleLabel->hide();
|
||||
m_bestListView->isHidden = true;
|
||||
m_bestListView->clear();
|
||||
}
|
||||
if(m_webListView) {
|
||||
m_webListView->clear();
|
||||
m_webListView->appendItem(m_keyword);
|
||||
m_webTitleLabel->show();
|
||||
m_webListView->show();
|
||||
m_webListView->isHidden = false;
|
||||
}
|
||||
|
||||
resetListHeight();
|
||||
m_detailView->clearLayout();
|
||||
m_contentDetailList.clear();
|
||||
m_bestContent.clear();
|
||||
|
||||
m_appShowMoreLabel->resetLabel();
|
||||
m_settingShowMoreLabel->resetLabel();
|
||||
m_dirShowMoreLabel->resetLabel();
|
||||
m_fileShowMoreLabel->resetLabel();
|
||||
m_contentShowMoreLabel->resetLabel();
|
||||
|
||||
m_bestList.clear();
|
||||
if(! m_appList.isEmpty())
|
||||
m_appList.clear();
|
||||
if(! m_settingList.isEmpty())
|
||||
m_settingList.clear();
|
||||
if(! m_dirList.isEmpty())
|
||||
m_dirList.clear();
|
||||
if(! m_fileList.isEmpty())
|
||||
m_fileList.clear();
|
||||
if(! m_contentList.isEmpty())
|
||||
m_contentList.clear();
|
||||
if(! m_appPathList.isEmpty())
|
||||
m_appPathList.clear();
|
||||
if(! m_appIconList.isEmpty())
|
||||
m_appIconList.clear();
|
||||
if(!m_appDescList.isEmpty())
|
||||
m_appDescList.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::setSettingList 插入设置项搜索结果列表
|
||||
* @param settingList
|
||||
*/
|
||||
void ContentWidget::setSettingList(const QStringList & settingList) {
|
||||
if(settingList.isEmpty())
|
||||
return;
|
||||
m_settingList = settingList;
|
||||
qDebug() << "Append a best item into list: " << settingList.at(0);
|
||||
this->appendBestItem(SearchItem::SearchType::Settings, settingList.at(0));
|
||||
m_settingListView->show();
|
||||
m_settingTitleLabel->show();
|
||||
m_settingListView->isHidden = false;
|
||||
if(m_settingList.length() <= 5) {
|
||||
m_settingListView->setList(m_settingList);
|
||||
} else {
|
||||
m_settingShowMoreLabel->show();
|
||||
m_settingListView->setList(m_settingList.mid(0, 5));
|
||||
}
|
||||
this->resetListHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::setAppList 插入应用搜索结果
|
||||
* @param appList QVector<namelist,pathlist,iconlist>
|
||||
*/
|
||||
void ContentWidget::setAppList(const QVector<QStringList>& appList) {
|
||||
if(appList.at(0).isEmpty())
|
||||
return;
|
||||
m_appList = appList.at(0);
|
||||
m_appPathList = appList.at(1);
|
||||
m_appIconList = appList.at(2);
|
||||
m_appDescList = appList.at(3);
|
||||
m_appListView->setAppList(m_appPathList, m_appIconList);
|
||||
qDebug() << "Append a best item into list: " << appList.at(0).at(0);
|
||||
SearchItemModel * model = qobject_cast<SearchItemModel *>(m_bestListView->model());
|
||||
if(appList.at(1).at(0).isEmpty() || appList.at(1).at(0) == "") {
|
||||
model->setBestAppIcon(appList.at(2).at(0), false);
|
||||
} else {
|
||||
model->setBestAppIcon(appList.at(2).at(0), true);
|
||||
}
|
||||
this->appendBestItem(SearchItem::SearchType::Apps, appList.at(0).at(0));
|
||||
m_appListView->show();
|
||||
m_appTitleLabel->show();
|
||||
m_appListView->isHidden = false;
|
||||
if(m_appList.length() <= 5) {
|
||||
m_appListView->setList(m_appList);
|
||||
} else {
|
||||
m_appShowMoreLabel->show();
|
||||
m_appListView->setList(m_appList.mid(0, 5));
|
||||
}
|
||||
this->resetListHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::appendSearchItem 向列表添加一项搜索结果
|
||||
* @param type 类型
|
||||
* @param path 路径
|
||||
* @param contents 文件内容
|
||||
*/
|
||||
void ContentWidget::appendSearchItem(const int& type, const QString& path, QStringList contents) {
|
||||
switch(type) {
|
||||
case SearchItem::SearchType::Best: {
|
||||
if(m_bestListView->isHidden) {
|
||||
m_bestListView->show();
|
||||
m_bestTitleLabel->show();
|
||||
m_bestListView->isHidden = false;
|
||||
}
|
||||
m_bestListView->appendItem(path);
|
||||
if(m_detailView->isEmpty()) {
|
||||
m_bestListView->setCurrentIndex(m_bestListView->model()->index(0, 0, QModelIndex()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SearchItem::SearchType::Files: {
|
||||
if(m_fileListView->isHidden) {
|
||||
m_fileListView->show();
|
||||
m_fileTitleLabel->show();
|
||||
m_fileListView->isHidden = false;
|
||||
this->appendBestItem(SearchItem::SearchType::Files, path);
|
||||
}
|
||||
if(m_fileListView->getLength() < 5) { //当已搜索结果列表少于5项,直接将搜索结果添加到列表中
|
||||
m_fileListView->appendItem(path);
|
||||
} else if(m_fileListView->getLength() == 5) { //当已搜索结果等于5项,新增的被折叠,显示“展开”按钮
|
||||
m_fileShowMoreLabel->show();
|
||||
} else { //当搜索列表显示的大于5项,说明列表被展开,可以继续把新增项添加到列表中
|
||||
m_fileListView->appendItem(path);
|
||||
}
|
||||
m_fileList.append(path);
|
||||
break;;
|
||||
}
|
||||
case SearchItem::SearchType::Dirs: {
|
||||
if(m_dirListView->isHidden) {
|
||||
m_dirListView->show();
|
||||
m_dirTitleLabel->show();
|
||||
m_dirListView->isHidden = false;
|
||||
this->appendBestItem(SearchItem::SearchType::Dirs, path);
|
||||
}
|
||||
if(m_dirListView->getLength() < 5) {
|
||||
m_dirListView->appendItem(path);
|
||||
} else if(m_dirListView->getLength() == 5) {
|
||||
m_dirShowMoreLabel->show();
|
||||
} else {
|
||||
m_dirListView->appendItem(path);
|
||||
}
|
||||
m_dirList.append(path);
|
||||
break;
|
||||
}
|
||||
case SearchItem::SearchType::Contents: {
|
||||
if(m_contentListView->isHidden) {
|
||||
m_contentListView->show();
|
||||
m_contentTitleLabel->show();
|
||||
m_contentListView->isHidden = false;
|
||||
for(int i = 0; i < contents.length(); i ++) {
|
||||
m_bestContent.append(contents.at(i));
|
||||
if(i != contents.length() - 1) {
|
||||
m_bestContent.append("\n");
|
||||
}
|
||||
}
|
||||
this->appendBestItem(SearchItem::SearchType::Contents, path);
|
||||
}
|
||||
if(m_contentListView->getLength() < 5) {
|
||||
m_contentListView->appendItem(path);
|
||||
} else if(m_contentListView->getLength() == 5) {
|
||||
m_contentShowMoreLabel->show();
|
||||
} else {
|
||||
m_contentListView->appendItem(path);
|
||||
}
|
||||
m_contentList.append(path);
|
||||
QString temp;
|
||||
for(int i = 0; i < contents.length(); i ++) {
|
||||
temp.append(contents.at(i));
|
||||
if(i != contents.length() - 1) {
|
||||
temp.append("\n");
|
||||
}
|
||||
}
|
||||
m_contentDetailList.append(temp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->resetListHeight();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::getTitleName 获取表头
|
||||
* @param type 搜索类型
|
||||
* @return
|
||||
*/
|
||||
QString ContentWidget::getTitleName(const int& type) {
|
||||
switch(type) {
|
||||
case SearchItem::SearchType::Apps :
|
||||
return tr("Apps");
|
||||
case SearchItem::SearchType::Settings :
|
||||
return tr("Settings");
|
||||
case SearchItem::SearchType::Files :
|
||||
return tr("Files");
|
||||
case SearchItem::SearchType::Dirs :
|
||||
return tr("Dirs");
|
||||
case SearchItem::SearchType::Contents :
|
||||
return tr("File Contents");
|
||||
case SearchItem::SearchType::Best :
|
||||
return tr("Best Matches");
|
||||
case SearchItem::SearchType::Web :
|
||||
return tr("Web Pages");
|
||||
default :
|
||||
return tr("Unknown");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::clearLayout 清空某个布局
|
||||
* @param layout 需要清空的布局
|
||||
*/
|
||||
void ContentWidget::clearLayout(QLayout * layout) {
|
||||
if(! layout) return;
|
||||
QLayoutItem * child;
|
||||
while((child = layout->takeAt(0)) != 0) {
|
||||
if(child->widget()) {
|
||||
child->widget()->setParent(NULL); //防止删除后窗口看上去没有消失
|
||||
}
|
||||
delete child;
|
||||
}
|
||||
child = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::onListViewRowChanged 点击某列表某一行的槽函数
|
||||
* @param type
|
||||
* @param path
|
||||
*/
|
||||
void ContentWidget::onListViewRowChanged(SearchListView * listview, const int &type, const QString &path) {
|
||||
if(type == SearchItem::SearchType::Contents && !m_contentDetailList.isEmpty()) {
|
||||
m_detailView->isContent = true;
|
||||
m_detailView->setContent(m_contentDetailList.at(listview->currentIndex().row()), m_keyword);
|
||||
} else if(type == SearchItem::SearchType::Best && !m_bestContent.isEmpty() && SearchItem::SearchType::Contents == m_bestList.at(listview->currentIndex().row()).first) {
|
||||
m_detailView->setContent(m_bestContent, m_keyword);
|
||||
m_detailView->isContent = true;
|
||||
m_detailView->setupWidget(SearchItem::SearchType::Contents, path);
|
||||
listview->is_current_list = true;
|
||||
Q_EMIT this->currentItemChanged();
|
||||
listview->is_current_list = false;
|
||||
return;
|
||||
} else {
|
||||
m_detailView->isContent = false;
|
||||
}
|
||||
if(type == SearchItem::SearchType::Web) {
|
||||
m_detailView->setWebWidget(this->m_keyword);
|
||||
} else if(type == SearchItem::SearchType::Apps) {
|
||||
int index = listview->currentIndex().row();
|
||||
m_detailView->setAppWidget(m_appList.at(index), m_appPathList.at(index), m_appIconList.at(index), m_appDescList.at(index));
|
||||
} else if(type == SearchItem::SearchType::Best) {
|
||||
if(m_bestList.at(listview->currentIndex().row()).first == SearchItem::SearchType::Apps) {
|
||||
m_detailView->setAppWidget(m_appList.at(0), m_appPathList.at(0), m_appIconList.at(0), m_appDescList.at(0));
|
||||
} else {
|
||||
m_detailView->setupWidget(m_bestList.at(listview->currentIndex().row()).first, m_bestList.at(listview->currentIndex().row()).second);
|
||||
}
|
||||
} else {
|
||||
m_detailView->setupWidget(type, path);
|
||||
}
|
||||
listview->is_current_list = true;
|
||||
Q_EMIT this->currentItemChanged();
|
||||
listview->is_current_list = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::onListViewRowDoubleClicked 双击某列表某一行的槽函数
|
||||
* @param type
|
||||
* @param path
|
||||
*/
|
||||
void ContentWidget::onListViewRowDoubleClicked(SearchListView * listview, const int &type, const QString &path) {
|
||||
qDebug() << "A row has been double clicked.Type = " << type << "; Name = " << path;
|
||||
if(type == SearchItem::SearchType::Best && m_bestList.at(listview->currentIndex().row()).first != SearchItem::SearchType::Apps) {
|
||||
m_detailView->doubleClickAction(m_bestList.at(listview->currentIndex().row()).first, path);
|
||||
} else if(type == SearchItem::SearchType::Best && m_bestList.at(listview->currentIndex().row()).first == SearchItem::SearchType::Apps) {
|
||||
if(m_appPathList.at(0) == "" || m_appPathList.at(0).isEmpty()) {
|
||||
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appList.at(0));
|
||||
} else {
|
||||
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appPathList.at(0));
|
||||
}
|
||||
} else if(type == SearchItem::SearchType::Apps) {
|
||||
int index = listview->currentIndex().row();
|
||||
if(m_appPathList.at(index) == "" || m_appPathList.at(index).isEmpty()) {
|
||||
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appList.at(index));
|
||||
} else {
|
||||
m_detailView->doubleClickAction(SearchListView::ResType::App, m_appPathList.at(index));
|
||||
}
|
||||
} else {
|
||||
m_detailView->doubleClickAction(type, path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::setContentList 文本内容搜索结果列表(包含所有文本段)
|
||||
* @param list
|
||||
*/
|
||||
void ContentWidget::setContentList(const QStringList& list) {
|
||||
m_contentDetailList.clear();
|
||||
m_contentDetailList = list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::setKeyword 设置关键字
|
||||
* @param keyword
|
||||
*/
|
||||
void ContentWidget::setKeyword(QString keyword) {
|
||||
m_keyword = keyword;
|
||||
m_fileListView->setKeyword(keyword);
|
||||
m_dirListView->setKeyword(keyword);
|
||||
m_contentListView->setKeyword(keyword);
|
||||
m_settingListView->setKeyword(keyword);
|
||||
m_appListView->setKeyword(keyword);
|
||||
m_bestListView->setKeyword(keyword);
|
||||
m_webListView->setKeyword(keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::setQuicklyOpenList 设置快速打开列表
|
||||
* @param list
|
||||
*/
|
||||
void ContentWidget::setQuicklyOpenList(const QStringList & list) {
|
||||
m_quicklyOpenList = list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ContentWidget::closeWebView 在主界面失焦消失的时候调用,(若webview未关闭)关闭网页搜索界面
|
||||
*/
|
||||
void ContentWidget::closeWebView() {
|
||||
m_detailView->closeWebWidget();
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef CONTENTWIDGET_H
|
||||
#define CONTENTWIDGET_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStackedWidget>
|
||||
#include <QScrollArea>
|
||||
#include <QGridLayout>
|
||||
#include <QScrollBar>
|
||||
#include "control/search-detail-view.h"
|
||||
#include "home-page-item.h"
|
||||
#include "show-more-label.h"
|
||||
#include "title-label.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class ContentWidget : public QStackedWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ContentWidget(QWidget *);
|
||||
~ContentWidget();
|
||||
|
||||
void setPage(const int&);
|
||||
int currentPage();
|
||||
void resetSearchList();
|
||||
void setSettingList(const QStringList&);
|
||||
void setAppList(const QVector<QStringList>&);
|
||||
void appendSearchItem(const int& type, const QString& path, QStringList contents = QStringList());
|
||||
void initHomePage();
|
||||
void setContentList(const QStringList&);
|
||||
void setKeyword(QString);
|
||||
void setQuicklyOpenList(const QStringList &);
|
||||
void closeWebView();
|
||||
private:
|
||||
void initUI();
|
||||
void initListView();
|
||||
void hideListView();
|
||||
void setupConnect(SearchListView *);
|
||||
void clearHomepage();
|
||||
void resetListHeight();
|
||||
void appendBestItem(const int&, const QString&);
|
||||
QString m_keyword;
|
||||
QStringList m_contentDetailList;
|
||||
QWidget * m_homePage = nullptr;
|
||||
QVBoxLayout * m_homePageLyt = nullptr;
|
||||
QWidget * m_resultPage = nullptr;
|
||||
QHBoxLayout * m_resultPageLyt = nullptr;
|
||||
QScrollArea * m_resultListArea = nullptr;
|
||||
QScrollArea * m_resultDetailArea = nullptr;
|
||||
QWidget * m_resultList = nullptr;
|
||||
QVBoxLayout * m_listLyt = nullptr;
|
||||
QWidget * m_resultDetail = nullptr;
|
||||
QVBoxLayout * m_detailLyt = nullptr;
|
||||
|
||||
SearchDetailView * m_detailView = nullptr;
|
||||
SearchListView * m_fileListView = nullptr;
|
||||
SearchListView * m_dirListView = nullptr;
|
||||
SearchListView * m_contentListView = nullptr;
|
||||
SearchListView * m_settingListView = nullptr;
|
||||
SearchListView * m_appListView = nullptr;
|
||||
SearchListView * m_bestListView = nullptr;
|
||||
SearchListView * m_webListView = nullptr;
|
||||
TitleLabel * m_fileTitleLabel = nullptr;
|
||||
TitleLabel * m_dirTitleLabel = nullptr;
|
||||
TitleLabel * m_contentTitleLabel = nullptr;
|
||||
TitleLabel * m_appTitleLabel = nullptr;
|
||||
TitleLabel * m_settingTitleLabel = nullptr;
|
||||
TitleLabel * m_bestTitleLabel = nullptr;
|
||||
TitleLabel * m_webTitleLabel = nullptr;
|
||||
ShowMoreLabel * m_appShowMoreLabel = nullptr;
|
||||
ShowMoreLabel * m_settingShowMoreLabel = nullptr;
|
||||
ShowMoreLabel * m_dirShowMoreLabel = nullptr;
|
||||
ShowMoreLabel * m_fileShowMoreLabel = nullptr;
|
||||
ShowMoreLabel * m_contentShowMoreLabel = nullptr;
|
||||
|
||||
QStringList m_appList;
|
||||
QStringList m_settingList;
|
||||
QStringList m_dirList;
|
||||
QStringList m_fileList;
|
||||
QStringList m_contentList;
|
||||
QStringList m_quicklyOpenList;
|
||||
QStringList m_appPathList;
|
||||
QStringList m_appIconList;
|
||||
QStringList m_appDescList;
|
||||
QList<QPair<int, QString>> m_bestList;
|
||||
|
||||
QString m_bestContent; //最佳匹配有文件内容搜索结果的时候,以此变量传递
|
||||
|
||||
int m_currentType = 0;
|
||||
|
||||
QString getTitleName(const int&);
|
||||
|
||||
Q_SIGNALS:
|
||||
void currentItemChanged();
|
||||
void effectiveSearch();
|
||||
|
||||
private Q_SLOTS:
|
||||
void clearLayout(QLayout *);
|
||||
void onListViewRowChanged(SearchListView * listview, const int& type, const QString& path);
|
||||
void onListViewRowDoubleClicked(SearchListView * listview, const int& type, const QString& path);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CONTENTWIDGET_H
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: sunfengsheng <sunfengsheng@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "config-file.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
bool ConfigFile::writeCommonly(QString message) {
|
||||
QSettings *m_qSettings = new QSettings(HOMEPAGE_SETTINGS, QSettings::IniFormat);
|
||||
QStringList messagelist = message.split("/");
|
||||
QString appname = messagelist.last();
|
||||
if(!appname.contains("desktop"))
|
||||
return false;
|
||||
m_qSettings->beginGroup("Commonly");
|
||||
QStringList quickly = m_qSettings->allKeys();
|
||||
if(quickly.contains(message.mid(1, message.length() - 1))) {
|
||||
m_qSettings->setValue(message, m_qSettings->value(message).toInt() + 1);
|
||||
} else {
|
||||
m_qSettings->setValue(message, 1);
|
||||
}
|
||||
m_qSettings->endGroup();
|
||||
if(m_qSettings)
|
||||
delete m_qSettings;
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList ConfigFile::readCommonly() {
|
||||
QSettings *m_qSettings = new QSettings(HOMEPAGE_SETTINGS, QSettings::IniFormat);
|
||||
QStringList returnlist;
|
||||
QMap<QString, int> quicklycount;
|
||||
m_qSettings->beginGroup("Commonly");
|
||||
QStringList Commonly = m_qSettings->allKeys();
|
||||
for(int i = 0; i < Commonly.size(); i++) {
|
||||
quicklycount.insert(Commonly.at(i), m_qSettings->value(Commonly.at(i)).toInt());
|
||||
}
|
||||
m_qSettings->endGroup();
|
||||
QMap<QString, int>::iterator iter = quicklycount.begin();
|
||||
QVector<QPair<QString, int>> vec;
|
||||
while(iter != quicklycount.end()) {
|
||||
vec.push_back(qMakePair(iter.key(), iter.value()));
|
||||
iter++;
|
||||
}
|
||||
qSort(vec.begin(), vec.end(), [](const QPair<QString, int> &l, const QPair<QString, int> &r) {
|
||||
return (l.second > r.second);
|
||||
});
|
||||
for(int j = 0; j < vec.size(); j++) {
|
||||
returnlist.append("/" + vec.at(j).first);
|
||||
}
|
||||
if(m_qSettings)
|
||||
delete m_qSettings;
|
||||
return returnlist.mid(0, 5);
|
||||
}
|
||||
|
||||
bool ConfigFile::writeRecently(QString message) {
|
||||
QSettings *m_qSettings = new QSettings(HOMEPAGE_SETTINGS, QSettings::IniFormat);
|
||||
|
||||
m_qSettings->beginGroup("Recently");
|
||||
QStringList recently = m_qSettings->value("Recently").toStringList();
|
||||
m_qSettings->endGroup();
|
||||
if(recently.contains(message)) {
|
||||
recently.removeOne(message);
|
||||
}
|
||||
recently.insert(0, message);
|
||||
|
||||
m_qSettings->beginGroup("Recently");
|
||||
if(m_qSettings->value("Recently").toStringList().length() >= 20) {
|
||||
m_qSettings->setValue("Recently", QStringList(recently.mid(0, 20)));
|
||||
} else {
|
||||
m_qSettings->setValue("Recently", recently);
|
||||
}
|
||||
m_qSettings->endGroup();
|
||||
if(m_qSettings)
|
||||
delete m_qSettings;
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList ConfigFile::readRecently() {
|
||||
QSettings *m_qSettings = new QSettings(HOMEPAGE_SETTINGS, QSettings::IniFormat);
|
||||
|
||||
m_qSettings->beginGroup("Recently");
|
||||
QStringList recently = m_qSettings->value("Recently").toStringList();
|
||||
m_qSettings->endGroup();
|
||||
if(m_qSettings)
|
||||
delete m_qSettings;
|
||||
return recently.mid(0, 4);
|
||||
}
|
||||
|
||||
bool ConfigFile::writeConfig(QString message) {
|
||||
bool isWriteCommonlyDone = writeCommonly(message);
|
||||
bool isWriteRecentlyDone = writeRecently(message);
|
||||
return (isWriteCommonlyDone || isWriteRecentlyDone);
|
||||
}
|
||||
|
||||
QMap<QString, QStringList> ConfigFile::readConfig() {
|
||||
QMap<QString, QStringList> returnresult;
|
||||
returnresult.insert("Commonly", readCommonly());
|
||||
returnresult.insert("Recently", readRecently());
|
||||
return returnresult;
|
||||
}
|
||||
|
||||
void ConfigFile::receiveMessage(QString message) {
|
||||
QFile file(HOMEPAGE_SETTINGS);
|
||||
if(!file.exists()) {
|
||||
file.open(QIODevice::ReadWrite | QIODevice::Text);
|
||||
file.close();
|
||||
}
|
||||
readConfig();//页面调用
|
||||
writeConfig(message);
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: sunfengsheng <sunfengsheng@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef CONFIGFILE_H
|
||||
#define CONFIGFILE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSettings>
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#define HOMEPAGE_SETTINGS QDir::homePath()+"/.config/org.ukui/ukui-search/ukui-search-homepage.conf"
|
||||
namespace Zeeker {
|
||||
class ConfigFile : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static bool writeConfig(QString message);
|
||||
static QMap<QString, QStringList> readConfig();
|
||||
static void receiveMessage(QString message);
|
||||
private:
|
||||
static bool writeCommonly(QString message);
|
||||
static QStringList readCommonly();
|
||||
static bool writeRecently(QString message);
|
||||
static QStringList readRecently();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CONFIGFILE_H
|
|
@ -1,23 +0,0 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/config-file.h \
|
||||
$$PWD/folder-list-item.h \
|
||||
$$PWD/highlight-item-delegate.h \
|
||||
$$PWD/search-list-view.h \
|
||||
$$PWD/search-detail-view.h \
|
||||
$$PWD/option-view.h \
|
||||
$$PWD/home-page-item.h \
|
||||
$$PWD/show-more-label.h \
|
||||
$$PWD/title-label.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/config-file.cpp \
|
||||
$$PWD/folder-list-item.cpp \
|
||||
$$PWD/highlight-item-delegate.cpp \
|
||||
$$PWD/search-list-view.cpp \
|
||||
$$PWD/search-detail-view.cpp \
|
||||
$$PWD/option-view.cpp \
|
||||
$$PWD/home-page-item.cpp \
|
||||
$$PWD/show-more-label.cpp \
|
||||
$$PWD/title-label.cpp
|
|
@ -1,111 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "folder-list-item.h"
|
||||
#include <QIcon>
|
||||
#include <QEvent>
|
||||
|
||||
using namespace Zeeker;
|
||||
FolderListItem::FolderListItem(QWidget *parent, const QString &path) : QWidget(parent) {
|
||||
m_path = path;
|
||||
initUi();
|
||||
}
|
||||
|
||||
FolderListItem::~FolderListItem() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FolderListItem::initUi 构建ui
|
||||
*/
|
||||
void FolderListItem::initUi() {
|
||||
m_layout = new QVBoxLayout(this);
|
||||
m_layout->setSpacing(0);
|
||||
m_layout->setContentsMargins(0, 0, 0, 0);
|
||||
m_widget = new QWidget(this);
|
||||
m_widget->setObjectName("mWidget");
|
||||
this->setFixedHeight(32);
|
||||
m_layout->addWidget(m_widget);
|
||||
m_widgetlayout = new QHBoxLayout(m_widget);
|
||||
m_widgetlayout->setContentsMargins(8, 4, 8, 4);
|
||||
m_widget->setLayout(m_widgetlayout);
|
||||
|
||||
m_iconLabel = new QLabel(m_widget);
|
||||
m_pathLabel = new QLabel(m_widget);
|
||||
m_delLabel = new QLabel(m_widget);
|
||||
m_iconLabel->setPixmap(QIcon::fromTheme("inode-directory").pixmap(QSize(16, 16)));
|
||||
m_pathLabel->setText(m_path);
|
||||
m_delLabel->setText(tr("Delete the folder out of blacklist"));
|
||||
QPalette pal = palette();
|
||||
pal.setColor(QPalette::WindowText, QColor(55, 144, 250, 255));
|
||||
m_delLabel->setPalette(pal);
|
||||
m_delLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
m_delLabel->installEventFilter(this);
|
||||
m_delLabel->hide();
|
||||
m_widgetlayout->addWidget(m_iconLabel);
|
||||
m_widgetlayout->addWidget(m_pathLabel);
|
||||
m_widgetlayout->addStretch();
|
||||
m_widgetlayout->addWidget(m_delLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FolderListItem::getPath 获取当前文件夹路径
|
||||
* @return
|
||||
*/
|
||||
QString FolderListItem::getPath() {
|
||||
return m_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FolderListItem::enterEvent 鼠标移入事件
|
||||
* @param event
|
||||
*/
|
||||
void FolderListItem::enterEvent(QEvent *event) {
|
||||
m_delLabel->show();
|
||||
m_widget->setStyleSheet("QWidget#mWidget{background: rgba(0,0,0,0.1);}");
|
||||
QWidget::enterEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FolderListItem::leaveEvent 鼠标移出事件
|
||||
* @param event
|
||||
*/
|
||||
void FolderListItem::leaveEvent(QEvent *event) {
|
||||
m_delLabel->hide();
|
||||
m_widget->setStyleSheet("QWidget#mWidget{background: transparent;}");
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief FolderListItem::eventFilter 处理删除按钮点击事件
|
||||
* @param watched
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
bool FolderListItem::eventFilter(QObject *watched, QEvent *event) {
|
||||
if(watched == m_delLabel) {
|
||||
if(event->type() == QEvent::MouseButtonPress) {
|
||||
// qDebug()<<"pressed!";
|
||||
Q_EMIT this->onDelBtnClicked(m_path);
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef FOLDERLISTITEM_H
|
||||
#define FOLDERLISTITEM_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
|
||||
namespace Zeeker {
|
||||
class FolderListItem : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FolderListItem(QWidget *parent = nullptr, const QString &path = 0);
|
||||
~FolderListItem();
|
||||
QString getPath();
|
||||
|
||||
protected:
|
||||
virtual void enterEvent(QEvent *);
|
||||
virtual void leaveEvent(QEvent *);
|
||||
bool eventFilter(QObject *, QEvent *);
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
|
||||
QString m_path;
|
||||
|
||||
QVBoxLayout * m_layout = nullptr;
|
||||
QWidget * m_widget = nullptr;
|
||||
QHBoxLayout * m_widgetlayout = nullptr;
|
||||
QLabel * m_iconLabel = nullptr;
|
||||
QLabel * m_pathLabel = nullptr;
|
||||
QLabel * m_delLabel = nullptr;
|
||||
Q_SIGNALS:
|
||||
void onDelBtnClicked(const QString&);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // FOLDERLISTITEM_H
|
|
@ -1,183 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "highlight-item-delegate.h"
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
#include <QDebug>
|
||||
#include <QTextDocument>
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
|
||||
using namespace Zeeker;
|
||||
HighlightItemDelegate::HighlightItemDelegate(QObject *parent) : QStyledItemDelegate(parent) {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief treewidget_styledItemDelegate::paint
|
||||
* \param painter
|
||||
* \param option
|
||||
* \param index
|
||||
*/
|
||||
void HighlightItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
||||
QStyleOptionViewItemV4 optionV4 = option;
|
||||
initStyleOption(&optionV4, index);
|
||||
|
||||
QStyle *style = optionV4.widget ? optionV4.widget->style() : QApplication::style();
|
||||
|
||||
optionV4.text = QString();
|
||||
style->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter); //绘制非文本区域内容
|
||||
if(index.model()->data(index, Qt::DisplayRole).toString().isEmpty()) return;
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setHtml(getHtmlText(painter, option, index)); //提取富文本
|
||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||
|
||||
if(optionV4.state & QStyle::State_Selected)
|
||||
ctx.palette.setColor(QPalette::Text, optionV4.palette.color(QPalette::Active, QPalette::HighlightedText));
|
||||
|
||||
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &optionV4);
|
||||
// textRect.adjust(0, 0, 0, 0);
|
||||
painter->save();
|
||||
painter->translate(textRect.topLeft());
|
||||
painter->setClipRect(textRect.translated(-textRect.topLeft()));
|
||||
doc.documentLayout()->draw(painter, ctx); //绘制文本区域内容
|
||||
painter->restore();
|
||||
|
||||
//以下为drawitemtext方法绘制文字,因加粗字体与原字体不等宽导致像素不对齐,视觉效果较差,已暂时摒弃
|
||||
// QStyleOptionViewItem itemOption = option;
|
||||
// initStyleOption(&itemOption, index);
|
||||
// if (itemOption.state & QStyle::State_HasFocus) {
|
||||
// itemOption.state = itemOption.state ^ QStyle::State_HasFocus;//去掉选中时候的Item的虚线框,也就是焦点
|
||||
// }
|
||||
// QStyledItemDelegate::paint(painter, itemOption, index);
|
||||
// findKeyWord(painter, itemOption, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HighlightItemDelegate::getHtmlText 将文本区域内容转换为标记语言形式(在关键字左右加<b></b>来加粗部分文字)
|
||||
* @param painter
|
||||
* @param itemOption
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
QString HighlightItemDelegate::getHtmlText(QPainter *painter, const QStyleOptionViewItem &itemOption, const QModelIndex &index) const {
|
||||
int indexFindLeft = 0;
|
||||
QString indexString = index.model()->data(index, Qt::DisplayRole).toString();
|
||||
QFont ft(painter->font().family(), GlobalSettings::getInstance()->getValue(FONT_SIZE_KEY).toInt());
|
||||
QFontMetrics fm(ft);
|
||||
QString indexColString = fm.elidedText(indexString, Qt::ElideRight, itemOption.rect.width() - 30); //当字体超过Item的长度时显示为省略号
|
||||
// QFontMetrics m_QFontMetrics = painter->fontMetrics();
|
||||
// QString indexColString = m_QFontMetrics.elidedText(indexString, Qt::ElideRight, itemOption.rect.width() + 10); //当字体超过Item的长度时显示为省略号
|
||||
QString htmlString;
|
||||
if((indexColString.toUpper()).contains((m_regFindKeyWords.toUpper()))) {
|
||||
indexFindLeft = indexColString.toUpper().indexOf(m_regFindKeyWords.toUpper()); //得到查找字体在当前整个Item字体中的位置
|
||||
// paintKeywordHighlight(painter, itemOption, indexColString, indexFindLeft, m_regFindKeyWords.length());
|
||||
htmlString = escapeHtml(indexColString.left(indexFindLeft)) + "<b>" + escapeHtml(indexColString.mid(indexFindLeft, m_regFindKeyWords.length())) + "</b>" + escapeHtml(indexColString.right(indexColString.length() - indexFindLeft - m_regFindKeyWords.length()));
|
||||
} else {
|
||||
bool boldOpenned = false;
|
||||
for(int i = 0; i < indexColString.length(); i++) {
|
||||
if((m_regFindKeyWords.toUpper()).contains(QString(indexColString.at(i)).toUpper())) {
|
||||
// paintKeywordHighlight(painter, itemOption, indexColString, i, 1);
|
||||
if(! boldOpenned) {
|
||||
boldOpenned = true;
|
||||
htmlString.append(QString("<b>"));
|
||||
}
|
||||
htmlString.append(escapeHtml(QString(indexColString.at(i))));
|
||||
} else {
|
||||
if(boldOpenned) {
|
||||
boldOpenned = false;
|
||||
htmlString.append(QString("</b>"));
|
||||
}
|
||||
htmlString.append(escapeHtml(QString(indexColString.at(i))));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// qDebug()<<indexColString<<"---->"<<htmlString;
|
||||
return htmlString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HighlightItemDelegate::escapeHtml 将文件名原本带的尖括号转义,以防被识别为富文本
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
QString HighlightItemDelegate::escapeHtml(const QString & str) const {
|
||||
QString temp = str;
|
||||
temp.replace("<", "<");
|
||||
temp.replace(">", ">");
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HighlightItemDelegate::paintKeywordHighlight drawitemtext方法绘制文字,印加粗字体与原字体不等宽导致像素不对齐,视觉效果较差,已暂时摒弃,保留以做底色高亮等备用
|
||||
* @param painter
|
||||
* @param itemOption
|
||||
* @param indexColString 完整字符串
|
||||
* @param indexFindLeft 关键字位置
|
||||
* @param keywordLength 关键字长度
|
||||
*/
|
||||
void HighlightItemDelegate::paintKeywordHighlight(QPainter *painter, const QStyleOptionViewItem &itemOption, const QString &indexColString, const int &indexFindLeft, const int &keywordLength) const {
|
||||
QPen pen(Qt::black);
|
||||
painter->setPen(pen);
|
||||
QFont font = QApplication::font(itemOption.widget);
|
||||
// QFont boldFont = QApplication::font(itemOption.widget);
|
||||
// boldFont.setBold(true);
|
||||
// boldFont.setStyleStrategy(QFont::PreferAntialias);
|
||||
painter->setFont(font);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QFontMetrics m_leftFontMetrics = painter->fontMetrics();//得到这个item原字体的像素
|
||||
// painter->setFont(boldFont);
|
||||
// QFontMetrics m_QFontMetrics = painter->fontMetrics();//得到这个加粗字体的像素
|
||||
const QWidget * m_QWidget = itemOption.widget;
|
||||
QStyle * m_QStyle = m_QWidget ? m_QWidget->style() : QApplication::style(); //得到当前的style
|
||||
QRect m_QRect = itemOption.rect;//得到Item的自己的Rect
|
||||
QPalette::ColorRole textDisplayRole = QPalette::NoRole; //设置text的role
|
||||
if(itemOption.state & QStyle::State_Selected) {
|
||||
textDisplayRole = QPalette::HighlightedText; //当选中字体的时候字体显示高亮
|
||||
} else {
|
||||
textDisplayRole = QPalette::Text;
|
||||
}
|
||||
|
||||
int findKeyWordWidth = m_leftFontMetrics.width(m_regFindKeyWords); //得到查找字体的像素宽度
|
||||
int preFindKeyWordWidth = m_leftFontMetrics.width(indexColString.mid(0, indexFindLeft)); //得到查找字体前面的字体的像素宽度
|
||||
|
||||
m_QRect = m_QRect.adjusted(preFindKeyWordWidth + 3, 0, findKeyWordWidth, 0);
|
||||
//高亮字段
|
||||
m_QStyle->drawItemText(painter, m_QRect, itemOption.displayAlignment, QApplication::palette(), true, indexColString.mid(indexFindLeft, keywordLength), textDisplayRole);
|
||||
// painter->restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief treewidget_styledItemDelegate::search_keyword 赋值关键字
|
||||
* \param regFindKeyWords
|
||||
*/
|
||||
void HighlightItemDelegate::setSearchKeyword(const QString ®FindKeyWords) {
|
||||
m_regFindKeyWords.clear();
|
||||
m_regFindKeyWords = regFindKeyWords;
|
||||
}
|
||||
|
||||
QSize HighlightItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QSize size = QStyledItemDelegate::sizeHint(option,index);
|
||||
size.setHeight(size.height() + 10);
|
||||
return size;
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef HIGHLIGHTITEMDELEGATE_H
|
||||
#define HIGHLIGHTITEMDELEGATE_H
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
#include "global-settings.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class HighlightItemDelegate : public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HighlightItemDelegate(QObject *parent = nullptr);
|
||||
void setSearchKeyword(const QString &);
|
||||
protected:
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
private:
|
||||
QString m_regFindKeyWords = 0;
|
||||
void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override;
|
||||
QString getHtmlText(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const;
|
||||
QString escapeHtml(const QString&) const;
|
||||
void paintKeywordHighlight(QPainter *, const QStyleOptionViewItem &, const QString &, const int &, const int &) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // HIGHLIGHTITEMDELEGATE_H
|
|
@ -1,195 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "home-page-item.h"
|
||||
#include <QEvent>
|
||||
#include <QProcess>
|
||||
#include <QDebug>
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <QPainter>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
|
||||
using namespace Zeeker;
|
||||
HomePageItem::HomePageItem(QWidget *parent, const int& type, const QString& path) : QWidget(parent) {
|
||||
setupUi(type, path);
|
||||
m_transparency = 0.06;
|
||||
connect(qApp, &QApplication::paletteChanged, this, [ = ]() {
|
||||
if(m_namelabel) {
|
||||
QString name = this->toolTip();
|
||||
if(m_type == ItemType::Recent) {
|
||||
m_namelabel->setText(m_namelabel->fontMetrics().elidedText(name, Qt::ElideRight, 250));
|
||||
} else {
|
||||
m_namelabel->setText(m_namelabel->fontMetrics().elidedText(name, Qt::ElideRight, 108));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
HomePageItem::~HomePageItem() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HomePageItem::setupUi 根据不同的分栏创建item
|
||||
* @param type 所属分栏
|
||||
* @param path 路径
|
||||
*/
|
||||
void HomePageItem::setupUi(const int& type, const QString& path) {
|
||||
m_path = path;
|
||||
m_type = type;
|
||||
m_widget = new QWidget(this);
|
||||
m_widget->setObjectName("MainWidget");
|
||||
m_widget->installEventFilter(this);
|
||||
m_iconlabel = new QLabel(m_widget);
|
||||
m_namelabel = new QLabel(m_widget);
|
||||
if(type == ItemType::Recent) {
|
||||
m_widget->setFixedSize(300, 48);
|
||||
QIcon icon;
|
||||
switch(SearchListView::getResType(path)) { //可能出现文件应用等,需要根据路径判断类型
|
||||
case SearchListView::ResType::App : {
|
||||
icon = FileUtils::getAppIcon(path);
|
||||
m_namelabel->setText(FileUtils::getAppName(path));
|
||||
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
||||
QString name = FileUtils::getAppName(path);
|
||||
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 250));
|
||||
this->setToolTip(name);
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Best :
|
||||
case SearchListView::ResType::Content:
|
||||
case SearchListView::ResType::Dir :
|
||||
case SearchListView::ResType::File : {
|
||||
icon = FileUtils::getFileIcon(QUrl::fromLocalFile(path).toString());
|
||||
// m_namelabel->setText(FileUtils::getFileName(path));
|
||||
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
||||
QString name = FileUtils::getFileName(path);
|
||||
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 250));
|
||||
this->setToolTip(name);
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Setting : {
|
||||
icon = FileUtils::getSettingIcon(path, true);
|
||||
// m_namelabel->setText(FileUtils::getSettingName(path));
|
||||
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
||||
QString name = FileUtils::getSettingName(path);
|
||||
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 250));
|
||||
this->setToolTip(name);
|
||||
break;
|
||||
}
|
||||
default :
|
||||
break;
|
||||
}
|
||||
m_iconlabel->setPixmap(icon.pixmap(icon.actualSize(QSize(24, 24))));
|
||||
m_hlayout = new QHBoxLayout(m_widget);
|
||||
m_iconlabel->setAlignment(Qt::AlignCenter);
|
||||
m_namelabel->setAlignment(Qt::AlignCenter);
|
||||
m_hlayout->addWidget(m_iconlabel);
|
||||
m_hlayout->addWidget(m_namelabel);
|
||||
m_hlayout->addStretch();
|
||||
return;
|
||||
} else if(type == ItemType::Quick) {
|
||||
QIcon icon = FileUtils::getAppIcon(path);
|
||||
m_iconlabel->setPixmap(icon.pixmap(icon.actualSize(QSize(48, 48))));
|
||||
QString name = FileUtils::getAppName(path);
|
||||
m_namelabel->setText(m_namelabel->fontMetrics().elidedText(name, Qt::ElideRight, 108));
|
||||
this->setToolTip(name);
|
||||
} else {
|
||||
QIcon icon = FileUtils::getAppIcon(path);
|
||||
m_iconlabel->setPixmap(icon.pixmap(icon.actualSize(QSize(48, 48))));
|
||||
// m_namelabel->setText(FileUtils::getAppName(path));
|
||||
QFontMetrics fontMetrics = m_namelabel->fontMetrics();
|
||||
QString name = FileUtils::getAppName(path);
|
||||
m_namelabel->setText(fontMetrics.elidedText(name, Qt::ElideRight, 108));
|
||||
this->setToolTip(name);
|
||||
}
|
||||
m_widget->setFixedSize(116, 116);
|
||||
m_vlayout = new QVBoxLayout(m_widget);
|
||||
m_vlayout->setContentsMargins(0, 16, 0, 12);
|
||||
m_iconlabel->setAlignment(Qt::AlignCenter);
|
||||
m_namelabel->setAlignment(Qt::AlignCenter);
|
||||
m_vlayout->addWidget(m_iconlabel);
|
||||
m_vlayout->addWidget(m_namelabel);
|
||||
}
|
||||
|
||||
void HomePageItem::onItemClicked() {
|
||||
switch(SearchListView::getResType(m_path)) {
|
||||
case SearchListView::ResType::App: {
|
||||
GDesktopAppInfo * desktopAppInfo = g_desktop_app_info_new_from_filename(m_path.toLocal8Bit().data());
|
||||
g_app_info_launch(G_APP_INFO(desktopAppInfo), nullptr, nullptr, nullptr);
|
||||
g_object_unref(desktopAppInfo);
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Best:
|
||||
case SearchListView::ResType::Content:
|
||||
case SearchListView::ResType::Dir:
|
||||
case SearchListView::ResType::File: {
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(m_path));
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Setting: {
|
||||
//打开控制面板对应页面
|
||||
QProcess process;
|
||||
process.startDetached(QString("ukui-control-center --%1").arg(m_path.left(m_path.indexOf("/")).toLower()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool HomePageItem::eventFilter(QObject *watched, QEvent *event) {
|
||||
if(watched == m_widget) {
|
||||
if(event->type() == QEvent::MouseButtonPress) {
|
||||
m_transparency = 0.06;
|
||||
this->update();
|
||||
return true;
|
||||
} else if(event->type() == QEvent::MouseButtonRelease) {
|
||||
this->onItemClicked();
|
||||
m_transparency = 0.06;
|
||||
this->update();
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Enter) {
|
||||
m_transparency = 0.15;
|
||||
this->update();
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Leave) {
|
||||
m_transparency = 0.06;
|
||||
this->update();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void HomePageItem::paintEvent(QPaintEvent *event) {
|
||||
Q_UNUSED(event)
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
QRect rect = this->rect();
|
||||
p.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
p.setBrush(opt.palette.color(QPalette::Text));
|
||||
p.setOpacity(m_transparency);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(rect, 4, 4);
|
||||
return QWidget::paintEvent(event);
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef HOMEPAGEITEM_H
|
||||
#define HOMEPAGEITEM_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include "file-utils.h"
|
||||
#include "search-list-view.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class HomePageItem : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HomePageItem(QWidget *, const int&, const QString&);
|
||||
~HomePageItem();
|
||||
|
||||
enum ItemType { //homepage中item的类型,包括常用应用、最近打开、快捷打开
|
||||
Quick,
|
||||
Recent,
|
||||
Common
|
||||
};
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *, QEvent *);
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
private:
|
||||
void setupUi(const int&, const QString&);
|
||||
void onItemClicked();
|
||||
|
||||
QWidget * m_widget = nullptr;
|
||||
QHBoxLayout * m_hlayout = nullptr;
|
||||
QVBoxLayout * m_vlayout = nullptr;
|
||||
QLabel * m_iconlabel = nullptr;
|
||||
QLabel * m_namelabel = nullptr;
|
||||
double m_transparency = 0;
|
||||
QString m_path;
|
||||
int m_type = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // HOMEPAGEITEM_H
|
|
@ -1,332 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "option-view.h"
|
||||
#include <QDebug>
|
||||
#include <QEvent>
|
||||
|
||||
using namespace Zeeker;
|
||||
OptionView::OptionView(QWidget *parent) : QWidget(parent) {
|
||||
m_mainLyt = new QVBoxLayout(this);
|
||||
this->setLayout(m_mainLyt);
|
||||
m_mainLyt->setContentsMargins(0, 8, 0, 0);
|
||||
m_mainLyt->setSpacing(8);
|
||||
initUI();
|
||||
}
|
||||
|
||||
OptionView::~OptionView() {
|
||||
if(m_openLabel) {
|
||||
delete m_openLabel;
|
||||
m_openLabel = NULL;
|
||||
}
|
||||
if(m_shortcutLabel) {
|
||||
delete m_shortcutLabel;
|
||||
m_shortcutLabel = NULL;
|
||||
}
|
||||
if(m_panelLabel) {
|
||||
delete m_panelLabel;
|
||||
m_panelLabel = NULL;
|
||||
}
|
||||
if(m_openPathLabel) {
|
||||
delete m_openPathLabel;
|
||||
m_openPathLabel = NULL;
|
||||
}
|
||||
if(m_copyPathLabel) {
|
||||
delete m_copyPathLabel;
|
||||
m_copyPathLabel = NULL;
|
||||
}
|
||||
if(m_installLabel) {
|
||||
delete m_installLabel;
|
||||
m_installLabel = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OptionView::initComponent 构建可用选项表
|
||||
* @param type 详情页类型
|
||||
* @param is_appInstalled 如果是应用详情页,应用是否已安装
|
||||
*/
|
||||
void OptionView::setupOptions(const int& type, bool is_appInstalled) {
|
||||
this->hideOptions();
|
||||
switch(type) {
|
||||
case SearchListView::ResType::App : {
|
||||
setupAppOptions(is_appInstalled);
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Content:
|
||||
case SearchListView::ResType::Best:
|
||||
case SearchListView::ResType::File : {
|
||||
setupFileOptions();
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Setting : {
|
||||
setupSettingOptions();
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Dir : {
|
||||
setupDirOptions();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OptionView::initUI() {
|
||||
QPalette pal = palette();
|
||||
pal.setColor(QPalette::WindowText, NORMAL_COLOR);
|
||||
pal.setColor(QPalette::Light, HOVER_COLOR);
|
||||
pal.setColor(QPalette::Dark, PRESS_COLOR);
|
||||
m_optionFrame = new QFrame(this);
|
||||
m_optionLyt = new QVBoxLayout(m_optionFrame);
|
||||
m_optionLyt->setContentsMargins(8, 0, 0, 0);
|
||||
|
||||
m_openLabel = new QLabel(m_optionFrame);
|
||||
m_openLabel->setText(tr("Open")); //打开
|
||||
m_openLabel->setPalette(pal);
|
||||
m_openLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
m_openLabel->installEventFilter(this);
|
||||
m_optionLyt->addWidget(m_openLabel);
|
||||
|
||||
m_shortcutLabel = new QLabel(m_optionFrame);
|
||||
m_shortcutLabel->setText(tr("Add Shortcut to Desktop")); //添加到桌面快捷方式
|
||||
m_shortcutLabel->setPalette(pal);
|
||||
m_shortcutLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
m_shortcutLabel->installEventFilter(this);
|
||||
m_optionLyt->addWidget(m_shortcutLabel);
|
||||
|
||||
m_panelLabel = new QLabel(m_optionFrame);
|
||||
m_panelLabel->setText(tr("Add Shortcut to Panel")); //添加到任务栏快捷方式
|
||||
m_panelLabel->setPalette(pal);
|
||||
m_panelLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
m_panelLabel->installEventFilter(this);
|
||||
m_optionLyt->addWidget(m_panelLabel);
|
||||
|
||||
m_openPathLabel = new QLabel(m_optionFrame);
|
||||
m_openPathLabel->setText(tr("Open path")); //打开所在路径
|
||||
m_openPathLabel->setPalette(pal);
|
||||
m_openPathLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
m_openPathLabel->installEventFilter(this);
|
||||
m_optionLyt->addWidget(m_openPathLabel);
|
||||
|
||||
m_copyPathLabel = new QLabel(m_optionFrame);
|
||||
m_copyPathLabel->setText(tr("Copy path")); //复制所在路径
|
||||
m_copyPathLabel->setPalette(pal);
|
||||
m_copyPathLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
m_copyPathLabel->installEventFilter(this);
|
||||
m_optionLyt->addWidget(m_copyPathLabel);
|
||||
|
||||
m_installLabel = new QLabel(m_optionFrame);
|
||||
m_installLabel->setText(tr("Install")); //复制所在路径
|
||||
m_installLabel->setPalette(pal);
|
||||
m_installLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
m_installLabel->installEventFilter(this);
|
||||
m_optionLyt->addWidget(m_installLabel);
|
||||
|
||||
m_optionLyt->addStretch();
|
||||
m_optionFrame->setLayout(m_optionLyt);
|
||||
m_mainLyt->addWidget(m_optionFrame);
|
||||
this->hideOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setupOptionLabel 创建每一个单独的选项
|
||||
* @param opt 选项类型
|
||||
*/
|
||||
void OptionView::setupOptionLabel(const int& opt) {
|
||||
switch(opt) {
|
||||
case Options::Open: {
|
||||
m_openLabel->show();
|
||||
break;
|
||||
}
|
||||
case Options::Shortcut: {
|
||||
m_shortcutLabel->show();
|
||||
break;
|
||||
}
|
||||
case Options::Panel: {
|
||||
m_panelLabel->show();
|
||||
break;
|
||||
}
|
||||
case Options::OpenPath: {
|
||||
m_openPathLabel->show();
|
||||
break;
|
||||
}
|
||||
case Options::CopyPath: {
|
||||
m_copyPathLabel->show();
|
||||
break;
|
||||
}
|
||||
case Options::Install: {
|
||||
m_installLabel->show();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OptionView::hideOptions() {
|
||||
m_openLabel->hide();
|
||||
m_shortcutLabel->hide();
|
||||
m_panelLabel->hide();
|
||||
m_openPathLabel->hide();
|
||||
m_copyPathLabel->hide();
|
||||
m_installLabel->hide();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OptionView::setupAppOptions 为应用类型的详情页构建选项表
|
||||
* @param is_installed 应用是否已安装
|
||||
*/
|
||||
void OptionView::setupAppOptions(bool is_installed) {
|
||||
if(is_installed) {
|
||||
setupOptionLabel(Options::Open);
|
||||
setupOptionLabel(Options::Shortcut);
|
||||
setupOptionLabel(Options::Panel);
|
||||
} else {
|
||||
setupOptionLabel(Options::Install);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OptionView::setupFileOptions 为文件类型的详情页构建选项表
|
||||
*/
|
||||
void OptionView::setupFileOptions() {
|
||||
setupOptionLabel(Options::Open);
|
||||
setupOptionLabel(Options::OpenPath);
|
||||
setupOptionLabel(Options::CopyPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OptionView::setupDirOptions 为文件夹类型的详情页构建选项表
|
||||
*/
|
||||
void OptionView::setupDirOptions() {
|
||||
setupOptionLabel(Options::Open);
|
||||
setupOptionLabel(Options::OpenPath);
|
||||
setupOptionLabel(Options::CopyPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OptionView::setupSettingOptions 为设置类型的详情页构建选项表
|
||||
*/
|
||||
void OptionView::setupSettingOptions() {
|
||||
setupOptionLabel(Options::Open);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OptionView::eventFilter 相应鼠标点击事件并发出信号供detailview处理
|
||||
* @param watched
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
bool OptionView::eventFilter(QObject *watched, QEvent *event) {
|
||||
if(m_openLabel && watched == m_openLabel) {
|
||||
if(event->type() == QEvent::MouseButtonPress) {
|
||||
m_openLabel->setForegroundRole(QPalette::Dark);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::MouseButtonRelease) {
|
||||
m_openLabel->setForegroundRole(QPalette::WindowText);
|
||||
Q_EMIT this->onOptionClicked(Options::Open);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Enter) {
|
||||
m_openLabel->setForegroundRole(QPalette::Light);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Leave) {
|
||||
m_openLabel->setForegroundRole(QPalette::WindowText);
|
||||
return true;
|
||||
}
|
||||
} else if(m_shortcutLabel && watched == m_shortcutLabel) {
|
||||
if(event->type() == QEvent::MouseButtonPress) {
|
||||
m_shortcutLabel->setForegroundRole(QPalette::Dark);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::MouseButtonRelease) {
|
||||
m_shortcutLabel->setForegroundRole(QPalette::WindowText);
|
||||
Q_EMIT this->onOptionClicked(Options::Shortcut);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Enter) {
|
||||
m_shortcutLabel->setForegroundRole(QPalette::Light);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Leave) {
|
||||
m_shortcutLabel->setForegroundRole(QPalette::WindowText);
|
||||
return true;
|
||||
}
|
||||
} else if(m_panelLabel && watched == m_panelLabel) {
|
||||
if(event->type() == QEvent::MouseButtonPress) {
|
||||
m_panelLabel->setForegroundRole(QPalette::Dark);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::MouseButtonRelease) {
|
||||
m_panelLabel->setForegroundRole(QPalette::WindowText);
|
||||
Q_EMIT this->onOptionClicked(Options::Panel);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Enter) {
|
||||
m_panelLabel->setForegroundRole(QPalette::Light);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Leave) {
|
||||
m_panelLabel->setForegroundRole(QPalette::WindowText);
|
||||
return true;
|
||||
}
|
||||
} else if(m_openPathLabel && watched == m_openPathLabel) {
|
||||
if(event->type() == QEvent::MouseButtonPress) {
|
||||
m_openPathLabel->setForegroundRole(QPalette::Dark);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::MouseButtonRelease) {
|
||||
m_openPathLabel->setForegroundRole(QPalette::WindowText);
|
||||
Q_EMIT this->onOptionClicked(Options::OpenPath);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Enter) {
|
||||
m_openPathLabel->setForegroundRole(QPalette::Light);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Leave) {
|
||||
m_openPathLabel->setForegroundRole(QPalette::WindowText);
|
||||
return true;
|
||||
}
|
||||
} else if(m_copyPathLabel && watched == m_copyPathLabel) {
|
||||
if(event->type() == QEvent::MouseButtonPress) {
|
||||
m_copyPathLabel->setForegroundRole(QPalette::Dark);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::MouseButtonRelease) {
|
||||
m_copyPathLabel->setForegroundRole(QPalette::WindowText);
|
||||
Q_EMIT this->onOptionClicked(Options::CopyPath);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Enter) {
|
||||
m_copyPathLabel->setForegroundRole(QPalette::Light);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Leave) {
|
||||
m_copyPathLabel->setForegroundRole(QPalette::WindowText);
|
||||
return true;
|
||||
}
|
||||
} else if(m_installLabel && watched == m_installLabel) {
|
||||
if(event->type() == QEvent::MouseButtonPress) {
|
||||
m_installLabel->setForegroundRole(QPalette::Dark);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::MouseButtonRelease) {
|
||||
m_installLabel->setForegroundRole(QPalette::WindowText);
|
||||
Q_EMIT this->onOptionClicked(Options::Install);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Enter) {
|
||||
m_installLabel->setForegroundRole(QPalette::Light);
|
||||
return true;
|
||||
} else if(event->type() == QEvent::Leave) {
|
||||
m_installLabel->setForegroundRole(QPalette::WindowText);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef OPTIONVIEW_H
|
||||
#define OPTIONVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include "search-list-view.h"
|
||||
|
||||
#define NORMAL_COLOR QColor(55, 144, 250, 255)
|
||||
#define HOVER_COLOR QColor(64, 169, 251, 255)
|
||||
#define PRESS_COLOR QColor(41, 108, 217, 255)
|
||||
|
||||
namespace Zeeker {
|
||||
class OptionView : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OptionView(QWidget *);
|
||||
~OptionView();
|
||||
void setupOptions(const int&, bool is_appInstalled = true);
|
||||
|
||||
enum Options {
|
||||
Open,
|
||||
Shortcut,
|
||||
Panel,
|
||||
OpenPath,
|
||||
CopyPath,
|
||||
Install
|
||||
};
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *, QEvent *);
|
||||
|
||||
private:
|
||||
void initUI();
|
||||
void setupAppOptions(bool);
|
||||
void setupFileOptions();
|
||||
void setupDirOptions();
|
||||
void setupSettingOptions();
|
||||
void setupOptionLabel(const int&);
|
||||
void hideOptions();
|
||||
|
||||
int m_type;
|
||||
|
||||
QFrame * m_optionFrame = nullptr;
|
||||
QVBoxLayout * m_optionLyt = nullptr;
|
||||
QVBoxLayout * m_mainLyt = nullptr;
|
||||
QLabel * m_openLabel = nullptr;
|
||||
QLabel * m_shortcutLabel = nullptr;
|
||||
QLabel * m_panelLabel = nullptr;
|
||||
QLabel * m_openPathLabel = nullptr;
|
||||
QLabel * m_copyPathLabel = nullptr;
|
||||
QLabel * m_installLabel = nullptr;
|
||||
|
||||
Q_SIGNALS:
|
||||
void onOptionClicked(const int&);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // OPTIONVIEW_H
|
|
@ -1,721 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "search-detail-view.h"
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
#include <QDebug>
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusReply>
|
||||
#include <QStandardPaths>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
#include <QClipboard>
|
||||
#include <QFileInfo>
|
||||
#include <QDateTime>
|
||||
#include <QDBusMetaType>
|
||||
//#include <QWebEngineCookieStore>
|
||||
#include "config-file.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
SearchDetailView::SearchDetailView(QWidget *parent) : QWidget(parent) {
|
||||
initUI();
|
||||
connect(qApp, &QApplication::paletteChanged, this, &SearchDetailView::refreshIcon);
|
||||
}
|
||||
|
||||
SearchDetailView::~SearchDetailView() {
|
||||
if(m_layout) {
|
||||
delete m_layout;
|
||||
m_layout = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::clearLayout 清空布局
|
||||
*/
|
||||
void SearchDetailView::clearLayout() {
|
||||
// QLayoutItem * child;
|
||||
// while ((child = m_layout->takeAt(0)) != 0) {
|
||||
// if(child->widget())
|
||||
// {
|
||||
// child->widget()->setParent(NULL); //防止删除后窗口看上去没有消失
|
||||
// }
|
||||
// delete child;
|
||||
// }
|
||||
// child = NULL;
|
||||
m_noNetFrame->hide();
|
||||
m_iconLabel->hide();
|
||||
m_nameFrame->hide();
|
||||
m_nameLabel->hide();
|
||||
m_typeLabel->hide();
|
||||
m_hLine->hide();
|
||||
m_detailFrame->hide();
|
||||
m_contentLabel->hide();
|
||||
m_pathFrame->hide();
|
||||
m_timeFrame->hide();
|
||||
m_pathLabel_1->hide();
|
||||
m_pathLabel_2->hide();
|
||||
m_timeLabel_1->hide();
|
||||
m_timeLabel_2->hide();
|
||||
m_hLine_2->hide();
|
||||
m_optionView->hide();
|
||||
m_isEmpty = true;
|
||||
// closeWebWidget();
|
||||
// if (m_webView) {
|
||||
// m_webView->hide();
|
||||
// }
|
||||
// m_reload = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::setContent 设置文本区域内容(仅内容搜索)
|
||||
* @param text 内容搜索结果组成的文段
|
||||
* @param keyword 搜索关键词
|
||||
*/
|
||||
void SearchDetailView::setContent(const QString& text, const QString& keyword) {
|
||||
m_contentText = text;
|
||||
m_keyword = keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::isEmpty 返回当前详情页是否为空
|
||||
* @return
|
||||
*/
|
||||
bool SearchDetailView::isEmpty() {
|
||||
return m_isEmpty;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::getType 返回当前详情页显示的类型
|
||||
* @return
|
||||
*/
|
||||
int SearchDetailView::getType() {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::setWebWidget 显示为网页
|
||||
* @param keyword 关键词
|
||||
*/
|
||||
void SearchDetailView::setWebWidget(const QString& keyword) {
|
||||
clearLayout();
|
||||
m_isEmpty = false;
|
||||
m_reload = false;
|
||||
// if (m_webView) {
|
||||
// if (QString::compare(keyword, m_currentKeyword) == 0 && m_net_enable) { //关键词没有发生变化,只把原来的网页show出来
|
||||
// m_webView->show();
|
||||
// return;
|
||||
// }
|
||||
// } else {
|
||||
// m_webView = new QWebEngineView(this);
|
||||
// m_engineProfile = m_webView->page()->profile();
|
||||
// m_webView->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
|
||||
// m_webView->setAttribute(Qt::WA_DeleteOnClose);
|
||||
// m_webView->move(0, 0);
|
||||
// m_webView->setFixedSize(378, 522);
|
||||
|
||||
// connect(m_webView,&QWebEngineView::loadFinished, this, [ = ](bool is_successful){
|
||||
// m_reload = true;
|
||||
// if (m_engineProfile){
|
||||
// m_engineProfile->clearHttpCache(); // 清理缓存
|
||||
// m_engineProfile->clearAllVisitedLinks(); // 清理浏览记录
|
||||
// m_engineProfile->cookieStore()->deleteAllCookies(); // 清理cookie
|
||||
// m_engineProfile->cookieStore()->deleteSessionCookies(); // 清理会话cookie
|
||||
// }
|
||||
// if (is_successful) {
|
||||
// m_webView->show();
|
||||
// m_net_enable = true;
|
||||
// } else {
|
||||
// m_noNetFrame->show();
|
||||
// m_net_enable = false;
|
||||
// }
|
||||
// });
|
||||
// connect(m_webView, &QWebEngineView::urlChanged, this, [ = ](const QUrl& url) {
|
||||
// if (m_reload) {
|
||||
// QDesktopServices::openUrl(url);
|
||||
// closeWebWidget();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//如果使用非手机版百度跳转,请使用RequestInterceptor类
|
||||
// RequestInterceptor * interceptor = new RequestInterceptor(m_webView);
|
||||
// QWebEngineProfile * profile = new QWebEngineProfile(m_webView);
|
||||
// profile->setRequestInterceptor(interceptor);
|
||||
// QWebEnginePage * page = new QWebEnginePage(profile, m_webView);
|
||||
// m_webView->setPage(page);
|
||||
|
||||
//新打开网页搜索或关键词发生变化,重新load
|
||||
m_currentKeyword = keyword;//目前网页搜索的关键词,记录此词来判断网页是否需要刷新
|
||||
QString address;
|
||||
QString engine = GlobalSettings::getInstance()->getValue(WEB_ENGINE).toString();
|
||||
if(!engine.isEmpty()) {
|
||||
if(engine == "360") {
|
||||
address = "https://so.com/s?q=" + keyword; //360
|
||||
} else if(engine == "sougou") {
|
||||
address = "https://www.sogou.com/web?query=" + keyword; //搜狗
|
||||
} else {
|
||||
address = "http://baidu.com/s?word=" + keyword; //百度
|
||||
}
|
||||
} else { //默认值
|
||||
address = "http://baidu.com/s?word=" + keyword; //百度
|
||||
}
|
||||
QDesktopServices::openUrl(address);
|
||||
// QString str = "http://m.baidu.com/s?word=" + keyword; //百度
|
||||
// QString str = "https://m.so.com/s?q=" + keyword; //360
|
||||
// QString str = "https://wap.sogou.com/web/searchList.jsp?&keyword=" + keyword; //搜狗
|
||||
|
||||
// m_webView->load(address);
|
||||
// m_webView->show();
|
||||
}
|
||||
|
||||
void SearchDetailView::setAppWidget(const QString &appname, const QString &path, const QString &iconpath, const QString &description) {
|
||||
m_type = SearchListView::ResType::App;
|
||||
m_path = path;
|
||||
m_name = appname.contains("/") ? appname.left(appname.indexOf("/")) : appname;
|
||||
m_pkgname = appname.contains("/") ? appname.mid(appname.indexOf("/") + 1) : appname;
|
||||
m_isEmpty = false;
|
||||
clearLayout();
|
||||
m_iconLabel->show();
|
||||
m_nameFrame->show();
|
||||
m_nameLabel->show();
|
||||
m_typeLabel->show();
|
||||
m_hLine->show();
|
||||
|
||||
if(path.isEmpty() || path == "") {
|
||||
m_optionView->setupOptions(m_type, false);
|
||||
//未安装应用有一个label显示软件描述
|
||||
if(description != "" && !description.isEmpty()) {
|
||||
m_detailFrame->show();
|
||||
m_contentLabel->show();
|
||||
m_contentLabel->setText(QString(tr("Introduction: %1")).arg(description));
|
||||
}
|
||||
setIcon(iconpath, false);
|
||||
} else {
|
||||
m_optionView->setupOptions(m_type, true);
|
||||
setIcon(iconpath, true);
|
||||
}
|
||||
m_optionView->show();
|
||||
|
||||
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
|
||||
QString showname = fontMetrics.elidedText(m_name, Qt::ElideRight, 274); //当字体长度超过215时显示为省略号
|
||||
// m_nameLabel->setText(showname);
|
||||
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(escapeHtml(showname)));
|
||||
if(QString::compare(showname, m_name)) {
|
||||
m_nameLabel->setToolTip(m_name);
|
||||
}
|
||||
m_typeLabel->setText(tr("Application"));
|
||||
}
|
||||
|
||||
void SearchDetailView::closeWebWidget() {
|
||||
// if (m_webView) {
|
||||
// m_webView->close();
|
||||
// m_webView = NULL;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::doubleClickAction 处理搜索结果列表选项双击事件
|
||||
* @param type
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
bool SearchDetailView::doubleClickAction(const int &type, const QString &path) {
|
||||
if(type == SearchListView::ResType::App && !path.contains(".desktop")) {
|
||||
return installAppAction(path.mid(path.indexOf("/") + 1));
|
||||
} else {
|
||||
if(openAction(type, path)) {
|
||||
writeConfigFile(path);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QString SearchDetailView::getHtmlText(const QString & text, const QString & keyword) {
|
||||
QString htmlString;
|
||||
bool boldOpenned = false;
|
||||
for(int i = 0; i < text.length(); i++) {
|
||||
if((keyword.toUpper()).contains(QString(text.at(i)).toUpper())) {
|
||||
if(! boldOpenned) {
|
||||
boldOpenned = true;
|
||||
htmlString.append(QString("<b><font size=\"4\">"));
|
||||
}
|
||||
htmlString.append(escapeHtml(QString(text.at(i))));
|
||||
} else {
|
||||
if(boldOpenned) {
|
||||
boldOpenned = false;
|
||||
htmlString.append(QString("</font></b>"));
|
||||
}
|
||||
htmlString.append(escapeHtml(QString(text.at(i))));
|
||||
}
|
||||
}
|
||||
htmlString.replace("\n", "<br />");//替换换行符
|
||||
return htmlString;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::escapeHtml 将搜索结果内容中的标签括号转义,来防止文件内容中的标记语言被识别为富文本
|
||||
* @param str 需要转义的字段
|
||||
* @return
|
||||
*/
|
||||
QString SearchDetailView::escapeHtml(const QString & str) {
|
||||
QString temp = str;
|
||||
temp.replace("<", "<");
|
||||
temp.replace(">", ">");
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::setupWidget 构建右侧搜索结果详情区域
|
||||
* @param type 搜索类型
|
||||
* @param path 结果路径
|
||||
*/
|
||||
void SearchDetailView::setupWidget(const int& type, const QString& path) {
|
||||
m_type = type;
|
||||
m_path = path;
|
||||
m_isEmpty = false;
|
||||
clearLayout();
|
||||
|
||||
m_iconLabel->show();
|
||||
m_nameFrame->show();
|
||||
m_nameLabel->show();
|
||||
m_typeLabel->show();
|
||||
m_hLine->show();
|
||||
|
||||
//文件和文件夹有一个额外的详情区域
|
||||
if(type == SearchListView::ResType::Dir || type == SearchListView::ResType::File || type == SearchListView::ResType::Content) {
|
||||
m_detailFrame->show();
|
||||
if(isContent) { //文件内容区域
|
||||
m_contentLabel->show();
|
||||
m_contentLabel->setText(QApplication::translate("", getHtmlText(m_contentText, m_keyword).toLocal8Bit(), nullptr));
|
||||
}
|
||||
m_pathFrame->show();
|
||||
m_timeFrame->show();
|
||||
m_pathLabel_1->show();
|
||||
m_pathLabel_2->show();
|
||||
// m_pathLabel_2->setText(path);
|
||||
// QString showPath = path;
|
||||
// QFontMetrics fontMetrics = m_pathLabel_2->fontMetrics();
|
||||
// if(fontMetrics.width(path) > m_pathLabel_2->width() - 10) {
|
||||
// //路径长度超过230,手动添加换行符以实现折叠
|
||||
// int lastIndex = 0;
|
||||
// for(int i = lastIndex; i < path.length(); i++) {
|
||||
// if(fontMetrics.width(path.mid(lastIndex, i - lastIndex)) == m_pathLabel_2->width() - 10) {
|
||||
// lastIndex = i;
|
||||
// showPath.insert(i, '\n');
|
||||
// } else if(fontMetrics.width(path.mid(lastIndex, i - lastIndex)) > m_pathLabel_2->width() - 10) {
|
||||
// lastIndex = i;
|
||||
// showPath.insert(i - 1, '\n');
|
||||
// } else {
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// m_pathLabel_2->setText(showPath);
|
||||
m_pathLabel_2->setText(m_pathLabel_2->fontMetrics().elidedText(path, Qt::ElideRight, m_pathLabel_2->width()));
|
||||
m_pathLabel_2->setToolTip(path);
|
||||
m_timeLabel_1->show();
|
||||
m_timeLabel_2->show();
|
||||
QFileInfo fileInfo(path);
|
||||
m_timeLabel_2->setText(fileInfo.lastModified().toString("yyyy-MM-dd hh:mm:ss"));
|
||||
m_hLine_2->show();
|
||||
}
|
||||
|
||||
m_optionView->setupOptions(m_type);
|
||||
m_optionView->show();
|
||||
|
||||
//根据不同类型的搜索结果切换加载图片和名称的方式
|
||||
switch(type) {
|
||||
case SearchListView::ResType::Content:
|
||||
case SearchListView::ResType::Dir :
|
||||
case SearchListView::ResType::File : {
|
||||
setIcon(path);
|
||||
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
|
||||
QString wholeName = FileUtils::getFileName(path);
|
||||
QString name = fontMetrics.elidedText(wholeName, Qt::ElideRight, 274);
|
||||
// m_nameLabel->setText(name);
|
||||
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(escapeHtml(name)));
|
||||
if(QString::compare(name, wholeName)) {
|
||||
m_nameLabel->setToolTip(wholeName);
|
||||
}
|
||||
m_typeLabel->setText(tr("Document"));
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Setting : {
|
||||
setIcon(path);
|
||||
QString settingType = path.mid(path.indexOf("/") + 1, path.lastIndexOf("/") - path.indexOf("/") - 1); //配置项所属控制面板插件名
|
||||
// m_nameLabel->setText(settingType);
|
||||
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(escapeHtml(settingType)));
|
||||
m_typeLabel->setText(FileUtils::getSettingName(path));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::execActions 根据点击的选项执行指定动作
|
||||
* @param type 选中的类型
|
||||
*/
|
||||
void SearchDetailView::execActions(const int& type, const int& option, const QString& path) {
|
||||
switch(option) {
|
||||
case OptionView::Options::Open: {
|
||||
if(openAction(type, path)) {
|
||||
writeConfigFile(path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OptionView::Options::Shortcut: {
|
||||
addDesktopShortcut(path);
|
||||
break;
|
||||
}
|
||||
case OptionView::Options::Panel: {
|
||||
addPanelShortcut(path);
|
||||
break;
|
||||
}
|
||||
case OptionView::Options::OpenPath: {
|
||||
openPathAction(path);
|
||||
break;
|
||||
}
|
||||
case OptionView::Options::CopyPath: {
|
||||
copyPathAction(path);
|
||||
break;
|
||||
}
|
||||
case OptionView::Options::Install: {
|
||||
installAppAction(m_pkgname); //未安装应用点击此选项,不使用路径作为参数,而是使用软件名
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Q_EMIT this->actionTriggerd();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::openAction 执行“打开”动作
|
||||
* @return
|
||||
*/
|
||||
bool SearchDetailView::openAction(const int& type, const QString& path) {
|
||||
switch(type) {
|
||||
case SearchListView::ResType::App: {
|
||||
GDesktopAppInfo * desktopAppInfo = g_desktop_app_info_new_from_filename(path.toLocal8Bit().data());
|
||||
bool res = static_cast<bool>(g_app_info_launch(G_APP_INFO(desktopAppInfo), nullptr, nullptr, nullptr));
|
||||
g_object_unref(desktopAppInfo);
|
||||
return res;
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Best:
|
||||
case SearchListView::ResType::Content:
|
||||
case SearchListView::ResType::Dir:
|
||||
case SearchListView::ResType::File: {
|
||||
// QProcess process;
|
||||
// process.startDetached(QString("xdg-open %1").arg(path));
|
||||
return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||
break;
|
||||
}
|
||||
case SearchListView::ResType::Setting: {
|
||||
//打开控制面板对应页面
|
||||
QProcess process;
|
||||
if(path.left(path.indexOf("/")).toLower() == "wallpaper")
|
||||
return process.startDetached(QString("ukui-control-center --background"));
|
||||
else return process.startDetached(QString("ukui-control-center --%1").arg(path.left(path.indexOf("/")).toLower()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::writeConfigFile 将打开过的文件或应用或配置项记录下来并发出刷新Homepage的请求
|
||||
* @param path 待写入的文件路径
|
||||
* @return
|
||||
*/
|
||||
bool SearchDetailView::writeConfigFile(const QString& path) {
|
||||
if(ConfigFile::writeConfig(path)) {
|
||||
Q_EMIT this->configFileChanged();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::initUI 初始化ui
|
||||
*/
|
||||
void SearchDetailView::initUI() {
|
||||
m_layout = new QVBoxLayout(this);
|
||||
this->setLayout(m_layout);
|
||||
m_layout->setContentsMargins(16, 60, 16, 24);
|
||||
this->setFixedWidth(368);
|
||||
|
||||
//没有网络的时候的提示信息
|
||||
m_noNetFrame = new QFrame(this);
|
||||
m_noNetFrame->setFixedSize(378, 140);
|
||||
m_noNetLyt = new QVBoxLayout(m_noNetFrame);
|
||||
m_noNetIconLabel = new QLabel(m_noNetFrame);
|
||||
m_noNetIconLabel->setFixedHeight(98);
|
||||
m_noNetIconLabel->setPixmap(QIcon(":/res/icons/net-disconnected.svg").pixmap(QSize(98, 86)));
|
||||
m_noNetIconLabel->setAlignment(Qt::AlignCenter);
|
||||
m_noNetTipsLabel = new QLabel(m_noNetFrame);
|
||||
m_noNetTipsLabel->setText(tr("Preview is not avaliable"));
|
||||
m_noNetTipsLabel->setAlignment(Qt::AlignCenter);
|
||||
m_noNetFrame->setLayout(m_noNetLyt);
|
||||
m_noNetLyt->addWidget(m_noNetIconLabel);
|
||||
m_noNetLyt->addWidget(m_noNetTipsLabel);
|
||||
m_noNetLyt->setSpacing(12);
|
||||
m_noNetFrame->move((this->width() - m_noNetFrame->width()) / 2, 160);
|
||||
|
||||
//图标和名称、分割线区域
|
||||
m_iconLabel = new QLabel(this);
|
||||
m_iconLabel->setAlignment(Qt::AlignCenter);
|
||||
m_iconLabel->setFixedHeight(128);
|
||||
m_nameFrame = new QFrame(this);
|
||||
m_nameLayout = new QHBoxLayout(m_nameFrame);
|
||||
m_nameLabel = new QLabel(m_nameFrame);
|
||||
m_typeLabel = new QLabel(m_nameFrame);
|
||||
m_typeLabel->setEnabled(false);
|
||||
m_nameFrame->setFixedHeight(48);
|
||||
m_nameLabel->setMaximumWidth(280);
|
||||
m_nameLayout->addWidget(m_nameLabel);
|
||||
m_nameLayout->addStretch();
|
||||
m_nameLayout->addWidget(m_typeLabel);
|
||||
m_nameFrame->setLayout(m_nameLayout);
|
||||
m_hLine = new QFrame(this);
|
||||
m_hLine->setLineWidth(0);
|
||||
m_hLine->setFixedHeight(1);
|
||||
m_layout->addWidget(m_iconLabel);
|
||||
m_layout->addWidget(m_nameFrame);
|
||||
m_layout->addWidget(m_hLine);
|
||||
|
||||
//文件和文件夹有一个额外的详情区域
|
||||
m_detailFrame = new QFrame(this);
|
||||
m_detailLyt = new QVBoxLayout(m_detailFrame);
|
||||
m_detailLyt->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
//文件内容区域
|
||||
m_contentLabel = new QLabel(m_detailFrame);
|
||||
m_contentLabel->setWordWrap(true);
|
||||
m_contentLabel->setContentsMargins(9, 0, 9, 0);
|
||||
m_detailLyt->addWidget(m_contentLabel);
|
||||
|
||||
//路径与修改时间区域
|
||||
m_pathFrame = new QFrame(m_detailFrame);
|
||||
m_timeFrame = new QFrame(m_detailFrame);
|
||||
m_pathLyt = new QHBoxLayout(m_pathFrame);
|
||||
m_timeLyt = new QHBoxLayout(m_timeFrame);
|
||||
m_pathLabel_1 = new QLabel(m_pathFrame);
|
||||
m_pathLabel_2 = new QLabel(m_pathFrame);
|
||||
m_pathLabel_1->setText(tr("Path"));
|
||||
m_pathLabel_2->setFixedWidth(240);
|
||||
m_pathLabel_2->setAlignment(Qt::AlignRight);
|
||||
// m_pathLabel_2->setWordWrap(true);
|
||||
m_pathLyt->addWidget(m_pathLabel_1);
|
||||
m_pathLyt->addStretch();
|
||||
m_pathLyt->addWidget(m_pathLabel_2);
|
||||
m_timeLabel_1 = new QLabel(m_timeFrame);
|
||||
m_timeLabel_2 = new QLabel(m_timeFrame);
|
||||
m_timeLabel_2->setAlignment(Qt::AlignRight);
|
||||
m_timeLabel_1->setText(tr("Last time modified"));
|
||||
m_timeLyt->addWidget(m_timeLabel_1);
|
||||
m_timeLyt->addStretch();
|
||||
m_timeLyt->addWidget(m_timeLabel_2);
|
||||
m_detailLyt->addWidget(m_pathFrame);
|
||||
m_detailLyt->addWidget(m_timeFrame);
|
||||
|
||||
m_hLine_2 = new QFrame(this);
|
||||
m_hLine_2->setLineWidth(0);
|
||||
m_hLine_2->setFixedHeight(1);
|
||||
m_layout->addWidget(m_detailFrame);
|
||||
m_layout->addWidget(m_hLine_2);
|
||||
|
||||
//可执行操作区域
|
||||
m_optionView = new OptionView(this);
|
||||
connect(m_optionView, &OptionView::onOptionClicked, this, [ = ](const int& option) {
|
||||
execActions(m_type, option, m_path);
|
||||
});
|
||||
m_layout->addWidget(m_optionView);
|
||||
|
||||
m_layout->addStretch();
|
||||
|
||||
this->clearLayout(); //初始化时隐藏所有控件
|
||||
resetLineColor();
|
||||
connect(qApp, &QApplication::paletteChanged, this, &SearchDetailView::resetLineColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::refreshIcon 图标主题变更时,刷新图标的槽函数
|
||||
*/
|
||||
void SearchDetailView::refreshIcon() {
|
||||
this->setIcon(m_iconPath);
|
||||
}
|
||||
|
||||
void SearchDetailView::resetLineColor()
|
||||
{
|
||||
if (GlobalSettings::getInstance()->getValue(STYLE_NAME_KEY).toString() != "ukui-dark") {
|
||||
m_hLine->setStyleSheet("QFrame{background: rgba(0,0,0,0.06);}");
|
||||
m_hLine_2->setStyleSheet("QFrame{background: rgba(0,0,0,0.06);}");
|
||||
} else {
|
||||
m_hLine->setStyleSheet("QFrame{background: rgba(255,255,255,0.08);}");
|
||||
m_hLine_2->setStyleSheet("QFrame{background: rgba(255,255,255,0.08);}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::setIcon 设置图标区域
|
||||
* @param path 图标路径或图标名
|
||||
* @param installed 如果是应用,是否已安装
|
||||
*/
|
||||
void SearchDetailView::setIcon(const QString &path, const bool &installed)
|
||||
{
|
||||
m_iconPath = path;
|
||||
if (m_type == SearchListView::ResType::App) {
|
||||
QIcon icon;
|
||||
if(!installed) {
|
||||
icon = QIcon(path);
|
||||
} else {
|
||||
if(QIcon::fromTheme(path).isNull()) {
|
||||
icon = QIcon(":/res/icons/desktop.png");
|
||||
} else {
|
||||
icon = QIcon::fromTheme(path);
|
||||
}
|
||||
}
|
||||
m_iconLabel->setPixmap(icon.pixmap(icon.actualSize(QSize(128, 128))));
|
||||
} else if (m_type == SearchListView::ResType::Setting) {
|
||||
QIcon icon = FileUtils::getSettingIcon(path, true);
|
||||
m_iconLabel->setPixmap(icon.pixmap(icon.actualSize(QSize(128, 128))));
|
||||
} else {
|
||||
QIcon icon = FileUtils::getFileIcon(QUrl::fromLocalFile(path).toString());
|
||||
m_iconLabel->setPixmap(icon.pixmap(icon.actualSize(QSize(128, 128))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::addDesktopShortcut 添加到桌面快捷方式
|
||||
* @return
|
||||
*/
|
||||
bool SearchDetailView::addDesktopShortcut(const QString& path) {
|
||||
QString dirpath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||
QFileInfo fileInfo(path);
|
||||
QString desktopfn = fileInfo.fileName();
|
||||
QFile file(path);
|
||||
QString newName = QString(dirpath + "/" + desktopfn);
|
||||
bool ret = file.copy(QString(dirpath + "/" + desktopfn));
|
||||
if(ret) {
|
||||
QProcess process;
|
||||
process.startDetached(QString("chmod a+x %1").arg(newName));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::addPanelShortcut 添加到任务栏
|
||||
* @return
|
||||
*/
|
||||
bool SearchDetailView::addPanelShortcut(const QString& path) {
|
||||
QDBusInterface iface("com.ukui.panel.desktop",
|
||||
"/",
|
||||
"com.ukui.panel.desktop",
|
||||
QDBusConnection::sessionBus());
|
||||
if(iface.isValid()) {
|
||||
QDBusReply<bool> isExist = iface.call("CheckIfExist", path);
|
||||
if(isExist) {
|
||||
qDebug() << "qDebug: Add shortcut to panel failed, because it is already existed!";
|
||||
return false;
|
||||
}
|
||||
QDBusReply<QVariant> ret = iface.call("AddToTaskbar", path);
|
||||
qDebug() << "qDebug: Add shortcut to panel successed!";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::openPathAction 打开文件所在路径
|
||||
* @return
|
||||
*/
|
||||
bool SearchDetailView::openPathAction(const QString& path) {
|
||||
return QDesktopServices::openUrl(QUrl::fromLocalFile(path.left(path.lastIndexOf("/"))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::copyPathAction 复制文件所在路径
|
||||
* @return
|
||||
*/
|
||||
bool SearchDetailView::copyPathAction(const QString& path) {
|
||||
QClipboard * clipboard = QApplication::clipboard(); //获取系统剪贴板指针
|
||||
clipboard->setText(path);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchDetailView::installAppAction 执行打开软件商店操作
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
bool SearchDetailView::installAppAction(const QString & name) {
|
||||
QDBusInterface * interface = new QDBusInterface("com.kylin.softwarecenter",
|
||||
"/com/kylin/softwarecenter",
|
||||
"com.kylin.utiliface",
|
||||
QDBusConnection::sessionBus());
|
||||
|
||||
if(interface->isValid()) {
|
||||
//软件商店已打开,直接跳转
|
||||
interface->call("show_search_result", name);
|
||||
bool reply = QDBusReply<bool>(interface->call(QString("show_search_result"), name));
|
||||
return reply;
|
||||
} else {
|
||||
//软件商店未打开,打开软件商店下载此软件
|
||||
qDebug() << "软件商店未打开,打开软件商店下载此软件" << name;
|
||||
QProcess process;
|
||||
return process.startDetached(QString("kylin-software-center -find %1").arg(name));
|
||||
}
|
||||
}
|
||||
|
||||
void SearchDetailView::paintEvent(QPaintEvent *event) {
|
||||
Q_UNUSED(event)
|
||||
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
|
||||
QRect rect = this->rect();
|
||||
p.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
p.setBrush(opt.palette.color(QPalette::Text));
|
||||
p.setOpacity(0.06);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(rect, 4, 4);
|
||||
return QWidget::paintEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RequestInterceptor::interceptRequest 拦截qwebengineview的Url请求
|
||||
* @param info
|
||||
*/
|
||||
//void RequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info)
|
||||
//{
|
||||
//当使用PC版搜索引擎时,可以使用此方法获取用户点击的链接的url
|
||||
// QUrl url = info.requestUrl();
|
||||
// qDebug() <<"Request URL:" <<url;
|
||||
//}
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef SEARCHDETAILVIEW_H
|
||||
#define SEARCHDETAILVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
//#include <QWebEngineView>
|
||||
//#include <QWebEngineSettings>
|
||||
//#include <QWebEngineProfile>
|
||||
//#include <QWebEngineUrlRequestInterceptor>
|
||||
#include <QDesktopServices>
|
||||
#include "option-view.h"
|
||||
#include "global-settings.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class SearchDetailView : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SearchDetailView(QWidget *parent = nullptr);
|
||||
~SearchDetailView();
|
||||
|
||||
void setupWidget(const int&, const QString&);
|
||||
void clearLayout();
|
||||
void setContent(const QString&, const QString&);
|
||||
bool isEmpty();
|
||||
int getType();
|
||||
bool isContent = false;
|
||||
void setWebWidget(const QString&);
|
||||
void setAppWidget(const QString &name, const QString &path, const QString &icon, const QString &description);
|
||||
void closeWebWidget();
|
||||
bool doubleClickAction(const int&, const QString&);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
private:
|
||||
QVBoxLayout * m_layout = nullptr;
|
||||
QString m_contentText;
|
||||
QString m_keyword;
|
||||
bool openAction(const int&, const QString&);
|
||||
bool addDesktopShortcut(const QString&);
|
||||
bool addPanelShortcut(const QString&);
|
||||
bool openPathAction(const QString&);
|
||||
bool copyPathAction(const QString&);
|
||||
bool installAppAction(const QString&);
|
||||
QString getHtmlText(const QString&, const QString&);
|
||||
QString escapeHtml(const QString&);
|
||||
bool writeConfigFile(const QString&);
|
||||
bool m_isEmpty = true;
|
||||
int m_type = 0;
|
||||
QString m_path = 0;
|
||||
QString m_name = 0; //目前只有未安装应用在打开软件商店时需要此参数
|
||||
QString m_pkgname = 0; //目前只有未安装应用在打开软件商店时需要此参数
|
||||
|
||||
void initUI();
|
||||
void setIcon(const QString& path, const bool &installed = true);
|
||||
QString m_iconPath;
|
||||
QLabel * m_iconLabel = nullptr;
|
||||
QFrame * m_nameFrame = nullptr;
|
||||
QHBoxLayout * m_nameLayout = nullptr;
|
||||
QLabel * m_nameLabel = nullptr;
|
||||
QLabel * m_typeLabel = nullptr;
|
||||
QFrame * m_hLine = nullptr;
|
||||
QFrame * m_detailFrame = nullptr;
|
||||
QVBoxLayout * m_detailLyt = nullptr;
|
||||
QLabel * m_contentLabel = nullptr;
|
||||
QFrame * m_pathFrame = nullptr;
|
||||
QFrame * m_timeFrame = nullptr;
|
||||
QHBoxLayout * m_pathLyt = nullptr;
|
||||
QHBoxLayout * m_timeLyt = nullptr;
|
||||
QLabel * m_pathLabel_1 = nullptr;
|
||||
QLabel * m_pathLabel_2 = nullptr;
|
||||
QLabel * m_timeLabel_1 = nullptr;
|
||||
QLabel * m_timeLabel_2 = nullptr;
|
||||
QFrame * m_hLine_2 = nullptr;
|
||||
OptionView * m_optionView = nullptr;
|
||||
QFrame * m_noNetFrame = nullptr;
|
||||
QVBoxLayout * m_noNetLyt = nullptr;
|
||||
QLabel * m_noNetIconLabel = nullptr;
|
||||
QLabel * m_noNetTipsLabel = nullptr;
|
||||
|
||||
// QWebEngineView * m_webView = nullptr;
|
||||
// QWebEngineProfile * m_engineProfile = nullptr;
|
||||
bool m_reload = false;
|
||||
bool m_net_enable = true;
|
||||
QString m_currentKeyword;
|
||||
|
||||
Q_SIGNALS:
|
||||
void configFileChanged();
|
||||
void actionTriggerd();
|
||||
private Q_SLOTS:
|
||||
void execActions(const int&, const int&, const QString&);
|
||||
void refreshIcon();
|
||||
void resetLineColor();
|
||||
};
|
||||
|
||||
//此类用于url拦截
|
||||
//class RequestInterceptor : public QWebEngineUrlRequestInterceptor
|
||||
//{
|
||||
//public:
|
||||
// explicit RequestInterceptor(QObject * parent = nullptr) : QWebEngineUrlRequestInterceptor(parent) {}
|
||||
// virtual void interceptRequest(QWebEngineUrlRequestInfo & info) Q_DECL_OVERRIDE;
|
||||
//};
|
||||
}
|
||||
|
||||
#endif // SEARCHDETAILVIEW_H
|
|
@ -1,214 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "search-list-view.h"
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
|
||||
using namespace Zeeker;
|
||||
SearchListView::SearchListView(QWidget * parent, const QStringList& list, const int& type) : QTreeView(parent) {
|
||||
this->setFrameShape(QFrame::NoFrame);
|
||||
this->viewport()->setAutoFillBackground(false);
|
||||
setRootIsDecorated(false);
|
||||
|
||||
this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_model = new SearchItemModel(this);
|
||||
m_item = new SearchItem;
|
||||
m_item->setSearchList(type, list);
|
||||
m_model->setItem(m_item);
|
||||
this->setModel(m_model);
|
||||
this->setHeaderHidden(true);
|
||||
// this->setColumnWidth(0, 20);
|
||||
// this->setColumnWidth(1, 80);
|
||||
// this->setFixedHeight(list.count() * rowheight + 4);
|
||||
this->setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
this->setAutoFillBackground(false);
|
||||
m_styleDelegate = new HighlightItemDelegate(this);
|
||||
// m_styleDelegate->setSearchKeyword(keyword);
|
||||
this->setItemDelegate(m_styleDelegate);
|
||||
|
||||
m_type = type;
|
||||
connect(this->selectionModel(), &QItemSelectionModel::selectionChanged, this, [ = ](const QItemSelection & selected, const QItemSelection & deselected) {
|
||||
Q_EMIT this->currentRowChanged(this, getCurrentType(), m_item->m_pathlist.at(this->currentIndex().row()));
|
||||
m_isSelected = true;
|
||||
if(!selected.isEmpty()) {
|
||||
QRegion region = visualRegionForSelection(selected);
|
||||
QRect rect = region.boundingRect();
|
||||
Q_EMIT this->currentSelectPos(mapToParent(rect.topLeft()));
|
||||
}
|
||||
});
|
||||
|
||||
connect(this, &SearchListView::activated, this, [ = ](const QModelIndex & index) {
|
||||
Q_EMIT this->onRowDoubleClicked(this, getCurrentType(), m_item->m_pathlist.at(index.row()));
|
||||
});
|
||||
}
|
||||
|
||||
SearchListView::~SearchListView() {
|
||||
if(m_model) {
|
||||
delete m_model;
|
||||
m_model = NULL;
|
||||
}
|
||||
if(m_item) {
|
||||
delete m_item;
|
||||
m_item = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchListView::appendItem 单个添加
|
||||
*/
|
||||
void SearchListView::appendItem(QString path) {
|
||||
m_model->appendItem(path);
|
||||
rowheight = this->rowHeight(this->model()->index(0, 0, QModelIndex())) + 1;
|
||||
this->setFixedHeight(m_item->getCurrentSize() * rowheight + 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchListView::setList 设置整个列表
|
||||
*/
|
||||
void SearchListView::setList(QStringList list) {
|
||||
QModelIndex index = this->currentIndex();
|
||||
m_model->setList(list);
|
||||
if(index.row() >= 0 && index.row() < list.length() && m_isSelected) {
|
||||
this->blockSignals(true);
|
||||
this->setCurrentIndex(index);
|
||||
this->blockSignals(false);
|
||||
}
|
||||
rowheight = this->rowHeight(this->model()->index(0, 0, QModelIndex()));
|
||||
this->setFixedHeight(m_item->getCurrentSize() * rowheight + 4);
|
||||
}
|
||||
|
||||
void SearchListView::setAppList(const QStringList &pathlist, const QStringList &iconlist) {
|
||||
m_model->setAppList(pathlist, iconlist);
|
||||
}
|
||||
|
||||
void SearchListView::appendBestItem(const QPair<int, QString> &pair) {
|
||||
m_model->appendBestItem(pair);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchListView::removeItem
|
||||
*/
|
||||
void SearchListView::removeItem(QString path) {
|
||||
m_model->removeItem(path);
|
||||
}
|
||||
|
||||
void SearchListView::clear() {
|
||||
this->blockSignals(true);
|
||||
this->clearSelection();
|
||||
this->blockSignals(false);
|
||||
m_model->clear();
|
||||
this->setFixedHeight(0);
|
||||
this->isHidden = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchListView::refresh 重新绘制当前列表
|
||||
*/
|
||||
void SearchListView::refresh()
|
||||
{
|
||||
rowheight = this->rowHeight(this->model()->index(0, 0, QModelIndex())) + 1;
|
||||
this->setFixedHeight(m_item->getCurrentSize() * rowheight + 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchListView::setKeyword 设置关键词
|
||||
* @param keyword 关键词
|
||||
*/
|
||||
void SearchListView::setKeyword(QString keyword) {
|
||||
m_styleDelegate->setSearchKeyword(keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchListView::getType 获取此列表类型
|
||||
* @return
|
||||
*/
|
||||
int SearchListView::getType() {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchListView::getLength 获取当前显示的列表项数量
|
||||
* @return
|
||||
*/
|
||||
int SearchListView::getLength() {
|
||||
return m_item->getCurrentSize();
|
||||
}
|
||||
|
||||
void SearchListView::mousePressEvent(QMouseEvent *event) {
|
||||
if(event->button() == Qt::LeftButton) {
|
||||
Q_EMIT mousePressed();
|
||||
}
|
||||
QTreeView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
//获取当前选项所属搜索类型
|
||||
int SearchListView::getCurrentType() {
|
||||
switch(m_type) {
|
||||
case SearchItem::SearchType::Apps :
|
||||
// qDebug()<<"qDebug: One row selected, its type is application.";
|
||||
return ResType::App;
|
||||
case SearchItem::SearchType::Files:
|
||||
// qDebug()<<"qDebug: One row selected, its type is file.";
|
||||
return ResType::File;
|
||||
case SearchItem::SearchType::Settings:
|
||||
// qDebug()<<"qDebug: One row selected, its type is setting.";
|
||||
return ResType::Setting;
|
||||
case SearchItem::SearchType::Dirs:
|
||||
// qDebug()<<"qDebug: One row selected, its type is dir.";
|
||||
return ResType::Dir;
|
||||
case SearchItem::SearchType::Contents:
|
||||
// qDebug()<<"qDebug: One row selected, its type is content.";
|
||||
return ResType::Content;
|
||||
case SearchItem::SearchType::Web:
|
||||
return ResType::Web;
|
||||
default: //All或者Best的情况,需要自己判断文件类型
|
||||
// return getResType(m_item->m_pathlist.at(this->currentIndex().row()));
|
||||
return ResType::Best;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchListView::getResType 根据路径返回文件类型
|
||||
* @param path 路径
|
||||
* @return
|
||||
*/
|
||||
int SearchListView::getResType(const QString& path) {
|
||||
if(path.endsWith(".desktop")) {
|
||||
return SearchListView::ResType::App;
|
||||
} else if(QFileInfo(path).isFile()) {
|
||||
return SearchListView::ResType::Best;
|
||||
} else if(QFileInfo(path).isDir()) {
|
||||
return SearchListView::ResType::Dir;
|
||||
} else {
|
||||
return SearchListView::ResType::Setting;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchListView::clearSelection 取消当前选项的选中
|
||||
*/
|
||||
void SearchListView::clearSelection() {
|
||||
this->selectionModel()->clearSelection();
|
||||
m_isSelected = false;
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef SEARCHLISTVIEW_H
|
||||
#define SEARCHLISTVIEW_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QTreeView>
|
||||
#include <QMouseEvent>
|
||||
#include "model/search-item-model.h"
|
||||
#include "model/search-item.h"
|
||||
#include "highlight-item-delegate.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class SearchListView : public QTreeView {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SearchListView(QWidget *, const QStringList&, const int&);
|
||||
~SearchListView();
|
||||
|
||||
enum ResType { //搜索结果可能出现的类型:应用、文件、设置、文件夹
|
||||
Best,
|
||||
App,
|
||||
Setting,
|
||||
Dir,
|
||||
File,
|
||||
Content,
|
||||
Web
|
||||
};
|
||||
|
||||
int getCurrentType();
|
||||
static int getResType(const QString&);
|
||||
|
||||
bool is_current_list = false;
|
||||
int rowheight = 0;
|
||||
|
||||
void appendItem(QString);
|
||||
void setList(QStringList);
|
||||
void setAppList(const QStringList&, const QStringList&);
|
||||
void appendBestItem(const QPair<int, QString>&);
|
||||
void removeItem(QString);
|
||||
void clear();
|
||||
void refresh();
|
||||
void setKeyword(QString);
|
||||
int getType();
|
||||
int getLength();
|
||||
bool isHidden = false;
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
private:
|
||||
SearchItemModel * m_model = nullptr;
|
||||
SearchItem * m_item = nullptr;
|
||||
bool m_isSelected = false;
|
||||
|
||||
HighlightItemDelegate * m_styleDelegate = nullptr;
|
||||
|
||||
int m_type;
|
||||
|
||||
Q_SIGNALS:
|
||||
void currentRowChanged(SearchListView *, const int&, const QString&);
|
||||
void onRowDoubleClicked(SearchListView *, const int&, const QString&);
|
||||
void currentSelectPos(QPoint pos);
|
||||
void mousePressed();
|
||||
|
||||
public Q_SLOTS:
|
||||
void clearSelection();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SEARCHLISTVIEW_H
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "show-more-label.h"
|
||||
#include <QEvent>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace Zeeker;
|
||||
ShowMoreLabel::ShowMoreLabel(QWidget *parent) : QWidget(parent) {
|
||||
initUi();
|
||||
m_timer = new QTimer;
|
||||
connect(m_timer, &QTimer::timeout, this, &ShowMoreLabel::refreshLoadState);
|
||||
connect(this, &ShowMoreLabel::showMoreClicked, this, &ShowMoreLabel::startLoading);
|
||||
}
|
||||
|
||||
ShowMoreLabel::~ShowMoreLabel() {
|
||||
}
|
||||
|
||||
void ShowMoreLabel::resetLabel() {
|
||||
m_isOpen = false;
|
||||
m_textLabel->setText(tr("Show More..."));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ShowMoreLabel::getExpanded 获取当前是否是展开状态
|
||||
* @return true已展开,false已收起
|
||||
*/
|
||||
bool ShowMoreLabel::getExpanded() {
|
||||
return m_isOpen;
|
||||
}
|
||||
|
||||
void ShowMoreLabel::initUi() {
|
||||
QPalette pal = palette();
|
||||
pal.setColor(QPalette::WindowText, QColor(55, 144, 250, 255));
|
||||
m_layout = new QHBoxLayout(this);
|
||||
m_layout->setContentsMargins(0, 0, 0, 6);
|
||||
m_textLabel = new QLabel(this);
|
||||
m_textLabel->setText(tr("Show More..."));
|
||||
m_textLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
m_textLabel->installEventFilter(this);
|
||||
// m_loadingIconLabel = new QLabel(this); //使用图片显示加载状态时,取消此label的注释
|
||||
// m_loadingIconLabel->setFixedSize(18, 18);
|
||||
// m_loadingIconLabel->hide();
|
||||
m_layout->setAlignment(Qt::AlignRight);
|
||||
m_layout->addWidget(m_textLabel);
|
||||
m_textLabel->setPalette(pal);
|
||||
// m_layout->addWidget(m_loadingIconLabel);
|
||||
}
|
||||
|
||||
void ShowMoreLabel::startLoading() {
|
||||
// m_textLabel->hide();
|
||||
// m_loadingIconLabel->show();
|
||||
m_timer->start(0.4 * 1000);
|
||||
m_textLabel->setCursor(QCursor(Qt::ArrowCursor));
|
||||
}
|
||||
|
||||
void ShowMoreLabel::stopLoading() {
|
||||
// m_loadingIconLabel->hide();
|
||||
// m_textLabel->show();
|
||||
if(m_timer->isActive()) {
|
||||
m_timer->stop();
|
||||
}
|
||||
if(m_isOpen) {
|
||||
m_textLabel->setText(tr("Retract"));
|
||||
} else {
|
||||
m_textLabel->setText(tr("Show More..."));
|
||||
}
|
||||
m_textLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
}
|
||||
|
||||
void ShowMoreLabel::refreshLoadState() {
|
||||
switch(m_currentState) {
|
||||
case 0: {
|
||||
m_textLabel->setText(tr("Loading"));
|
||||
m_currentState ++;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
m_textLabel->setText(tr("Loading."));
|
||||
m_currentState ++;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
m_textLabel->setText(tr("Loading.."));
|
||||
m_currentState ++;
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
m_textLabel->setText(tr("Loading..."));
|
||||
m_currentState = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool ShowMoreLabel::eventFilter(QObject *watched, QEvent *event) {
|
||||
if(watched == m_textLabel) {
|
||||
if(event->type() == QEvent::MouseButtonPress) {
|
||||
if(! m_timer->isActive()) {
|
||||
if(!m_isOpen) {
|
||||
m_isOpen = true;
|
||||
Q_EMIT this->showMoreClicked();
|
||||
} else {
|
||||
m_isOpen = false;
|
||||
Q_EMIT this->retractClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef SHOWMORELABEL_H
|
||||
#define SHOWMORELABEL_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QHBoxLayout>
|
||||
#include <QTimer>
|
||||
|
||||
namespace Zeeker {
|
||||
class ShowMoreLabel : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ShowMoreLabel(QWidget *parent = nullptr);
|
||||
~ShowMoreLabel();
|
||||
void resetLabel();
|
||||
bool getExpanded();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *, QEvent *);
|
||||
|
||||
private:
|
||||
QHBoxLayout * m_layout = nullptr;
|
||||
QLabel * m_textLabel = nullptr;
|
||||
QLabel * m_loadingIconLabel = nullptr;
|
||||
QTimer * m_timer = nullptr;
|
||||
bool m_isOpen = false;
|
||||
int m_currentState = 0;
|
||||
|
||||
void initUi();
|
||||
|
||||
Q_SIGNALS:
|
||||
void showMoreClicked();
|
||||
void retractClicked();
|
||||
|
||||
public Q_SLOTS:
|
||||
void startLoading();
|
||||
void stopLoading();
|
||||
void refreshLoadState();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SHOWMORELABEL_H
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "title-label.h"
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
|
||||
using namespace Zeeker;
|
||||
TitleLabel::TitleLabel(QWidget * parent) : QLabel(parent) {
|
||||
this->setContentsMargins(8, 0, 0, 0);
|
||||
this->setFixedHeight(24);
|
||||
}
|
||||
|
||||
TitleLabel::~TitleLabel() {
|
||||
|
||||
}
|
||||
|
||||
void TitleLabel::paintEvent(QPaintEvent * event) {
|
||||
Q_UNUSED(event)
|
||||
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
|
||||
QRect rect = this->rect();
|
||||
p.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
p.setBrush(opt.palette.color(QPalette::Text));
|
||||
p.setOpacity(0.04);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(rect, 0, 0);
|
||||
return QLabel::paintEvent(event);
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef TITLELABEL_H
|
||||
#define TITLELABEL_H
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
namespace Zeeker {
|
||||
class TitleLabel : public QLabel {
|
||||
public:
|
||||
TitleLabel(QWidget * parent = nullptr);
|
||||
~TitleLabel();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TITLELABEL_H
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "create-index-ask-dialog.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
CreateIndexAskDialog::CreateIndexAskDialog(QWidget *parent) : QDialog(parent) {
|
||||
// this->setWindowIcon(QIcon::fromTheme("kylin-search"));
|
||||
this->setWindowTitle(tr("ukui-search"));
|
||||
|
||||
initUi();
|
||||
}
|
||||
|
||||
void CreateIndexAskDialog::initUi() {
|
||||
this->setFixedSize(380, 202);
|
||||
m_mainLyt = new QVBoxLayout(this);
|
||||
this->setLayout(m_mainLyt);
|
||||
m_mainLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_mainLyt->setSpacing(0);
|
||||
|
||||
//标题栏
|
||||
m_titleFrame = new QFrame(this);
|
||||
m_titleFrame->setFixedHeight(40);
|
||||
m_titleLyt = new QHBoxLayout(m_titleFrame);
|
||||
m_titleLyt->setContentsMargins(8, 8, 8, 8);
|
||||
m_titleFrame->setLayout(m_titleLyt);
|
||||
m_iconLabel = new QLabel(m_titleFrame);
|
||||
m_iconLabel->setFixedSize(24, 24);
|
||||
m_iconLabel->setPixmap(QIcon::fromTheme("kylin-search").pixmap(QSize(24, 24)));
|
||||
//主题改变时,更新自定义标题栏的图标
|
||||
connect(qApp, &QApplication::paletteChanged, this, [ = ]() {
|
||||
m_iconLabel->setPixmap(QIcon::fromTheme("kylin-search").pixmap(QSize(24, 24)));
|
||||
});
|
||||
m_titleLabel = new QLabel(m_titleFrame);
|
||||
m_titleLabel->setText(tr("Search"));
|
||||
m_closeBtn = new QPushButton(m_titleFrame);
|
||||
m_closeBtn->setFixedSize(24, 24);
|
||||
m_closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic"));
|
||||
m_closeBtn->setProperty("isWindowButton", 0x02);
|
||||
m_closeBtn->setProperty("useIconHighlightEffect", 0x08);
|
||||
m_closeBtn->setFlat(true);
|
||||
connect(m_closeBtn, &QPushButton::clicked, this, [ = ]() {
|
||||
this->hide();
|
||||
Q_EMIT this->closed();
|
||||
});
|
||||
m_titleLyt->addWidget(m_iconLabel);
|
||||
m_titleLyt->addWidget(m_titleLabel);
|
||||
m_titleLyt->addStretch();
|
||||
m_titleLyt->addWidget(m_closeBtn);
|
||||
|
||||
m_mainLyt->addWidget(m_titleFrame);
|
||||
|
||||
//内容区域
|
||||
m_contentFrame = new QFrame(this);
|
||||
m_contentLyt = new QVBoxLayout(m_contentFrame);
|
||||
m_contentFrame->setLayout(m_contentLyt);
|
||||
m_contentLyt->setContentsMargins(32, 0, 32, 24);
|
||||
|
||||
m_tipLabel = new QLabel(m_contentFrame);
|
||||
m_tipLabel->setText(tr("Creating index can help you getting results quickly, whether to create or not?"));
|
||||
m_tipLabel->setWordWrap(true);
|
||||
m_tipLabel->setAlignment(Qt::AlignVCenter);
|
||||
m_tipLabel->setMinimumHeight(64);
|
||||
m_contentLyt->addWidget(m_tipLabel);
|
||||
|
||||
m_checkFrame = new QFrame(m_contentFrame);
|
||||
m_checkLyt = new QHBoxLayout(m_checkFrame);
|
||||
m_checkLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_checkFrame->setLayout(m_checkLyt);
|
||||
m_checkBox = new QCheckBox(m_checkFrame);
|
||||
m_checkBox->setText(tr("Don't remind"));
|
||||
m_checkLyt->addWidget(m_checkBox);
|
||||
m_checkLyt->addStretch();
|
||||
m_contentLyt->addWidget(m_checkFrame);
|
||||
m_contentLyt->addStretch();
|
||||
|
||||
m_btnFrame = new QFrame(m_contentFrame);
|
||||
m_btnLyt = new QHBoxLayout(m_btnFrame);
|
||||
m_btnFrame->setLayout(m_btnLyt);
|
||||
m_btnLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_cancelBtn = new QPushButton(m_btnFrame);
|
||||
m_cancelBtn->setText(tr("No"));
|
||||
m_confirmBtn = new QPushButton(m_btnFrame);
|
||||
m_confirmBtn->setText(tr("Yes"));
|
||||
connect(m_cancelBtn, &QPushButton::clicked, this, [ = ]() {
|
||||
Q_EMIT this->btnClicked(false, m_checkBox->isChecked());
|
||||
this->hide();
|
||||
Q_EMIT this->closed();
|
||||
});
|
||||
connect(m_confirmBtn, &QPushButton::clicked, this, [ = ]() {
|
||||
Q_EMIT this->btnClicked(true, m_checkBox->isChecked());
|
||||
this->hide();
|
||||
Q_EMIT this->closed();
|
||||
});
|
||||
m_btnLyt->addStretch();
|
||||
m_btnLyt->addWidget(m_cancelBtn);
|
||||
m_btnLyt->addWidget(m_confirmBtn);
|
||||
m_contentLyt->addWidget(m_btnFrame);
|
||||
|
||||
m_mainLyt->addWidget(m_contentFrame);
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
|
||||
m_titleFrame->hide();
|
||||
this->setFixedSize(380, 162);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CreateIndexAskDialog::paintEvent 绘制窗口背景(默认背景较暗)
|
||||
*/
|
||||
void CreateIndexAskDialog::paintEvent(QPaintEvent *event) {
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
QPainterPath rectPath;
|
||||
rectPath.addRect(this->rect());
|
||||
p.save();
|
||||
p.fillPath(rectPath, palette().color(QPalette::Base));
|
||||
p.restore();
|
||||
return QDialog::paintEvent(event);
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CREATEINDEXASKDIALOG_H
|
||||
#define CREATEINDEXASKDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QFrame>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QStyleOption>
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
namespace Zeeker {
|
||||
class CreateIndexAskDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CreateIndexAskDialog(QWidget *parent = nullptr);
|
||||
~CreateIndexAskDialog() = default;
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
|
||||
QVBoxLayout * m_mainLyt = nullptr;
|
||||
//标题栏
|
||||
QFrame * m_titleFrame = nullptr;
|
||||
QHBoxLayout * m_titleLyt = nullptr;
|
||||
QLabel * m_iconLabel = nullptr;
|
||||
QLabel * m_titleLabel = nullptr;
|
||||
QPushButton * m_closeBtn = nullptr;
|
||||
|
||||
//内容区域
|
||||
QFrame * m_contentFrame = nullptr;
|
||||
QVBoxLayout * m_contentLyt = nullptr;
|
||||
QLabel * m_tipLabel = nullptr; //提示语
|
||||
QFrame * m_checkFrame = nullptr; //"不再提示"选项框区域
|
||||
QHBoxLayout * m_checkLyt = nullptr;
|
||||
QCheckBox * m_checkBox = nullptr;
|
||||
QFrame * m_btnFrame = nullptr; //底部按钮区域
|
||||
QHBoxLayout * m_btnLyt = nullptr;
|
||||
QPushButton * m_cancelBtn = nullptr;
|
||||
QPushButton * m_confirmBtn = nullptr;
|
||||
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
Q_SIGNALS:
|
||||
void closed();
|
||||
void btnClicked(const bool&, const bool&);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CREATEINDEXASKDIALOG_H
|
|
@ -1,261 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "input-box.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
/**
|
||||
* @brief ukui-search顶部搜索界面
|
||||
*/
|
||||
SeachBarWidget::SeachBarWidget(QWidget *parent): QWidget(parent) {
|
||||
}
|
||||
|
||||
SeachBarWidget::~SeachBarWidget() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ukui-search 顶部搜索框的ui,包含设置按钮
|
||||
*/
|
||||
SeachBar::SeachBar() {
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
SearchBarWidgetLayout::SearchBarWidgetLayout() {
|
||||
}
|
||||
|
||||
SearchBarWidgetLayout::~SearchBarWidgetLayout() {
|
||||
}
|
||||
|
||||
SeachBar::~SeachBar() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 顶部搜索框所在界面的布局
|
||||
*/
|
||||
SearchBarHLayout::SearchBarHLayout(QWidget *parent): QHBoxLayout(parent) {
|
||||
initUI();
|
||||
|
||||
m_timer = new QTimer;
|
||||
connect(m_timer, &QTimer::timeout, this, [ = ]() {
|
||||
m_timer->stop();
|
||||
Q_EMIT this->textChanged(m_queryLineEdit->text());
|
||||
});
|
||||
connect(m_queryLineEdit, &SearchLineEdit::textChanged, this, [ = ](QString text) {
|
||||
if(m_isEmpty) {
|
||||
m_isEmpty = false;
|
||||
Q_EMIT this->textChanged(text);
|
||||
} else {
|
||||
if(text == "") {
|
||||
m_isEmpty = true;
|
||||
m_timer->stop();
|
||||
Q_EMIT this->textChanged(m_queryLineEdit->text());
|
||||
return;
|
||||
}
|
||||
m_timer->stop();
|
||||
m_timer->start(0.1 * 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SearchBarHLayout::~SearchBarHLayout() {
|
||||
if(m_timer) {
|
||||
delete m_timer;
|
||||
m_timer = NULL;
|
||||
}
|
||||
if(m_queryLineEdit) {
|
||||
delete m_queryLineEdit;
|
||||
m_queryLineEdit = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化ui
|
||||
*/
|
||||
void SearchBarHLayout::initUI() {
|
||||
m_queryLineEdit = new SearchLineEdit(this->parentWidget());
|
||||
m_queryLineEdit->installEventFilter(this);
|
||||
m_queryLineEdit->setTextMargins(30, 1, 0, 1);
|
||||
this->setContentsMargins(0, 0, 0, 0);
|
||||
this->setAlignment(m_queryLineEdit, Qt::AlignCenter);
|
||||
this->addWidget(m_queryLineEdit);
|
||||
|
||||
m_queryWidget = new QWidget(m_queryLineEdit);
|
||||
m_queryWidget->setFocusPolicy(Qt::NoFocus);
|
||||
|
||||
QHBoxLayout* queryWidLayout = new QHBoxLayout;
|
||||
queryWidLayout->setContentsMargins(8, 4, 0, 0);
|
||||
queryWidLayout->setAlignment(Qt::AlignJustify);
|
||||
queryWidLayout->setSpacing(5);
|
||||
m_queryWidget->setLayout(queryWidLayout);
|
||||
|
||||
QPixmap pixmap(QIcon::fromTheme("system-search-symbolic", QIcon(":/res/icons/system-search.symbolic.png")).pixmap(QSize(20, 20)));
|
||||
m_queryIcon = new QLabel;
|
||||
m_queryIcon->setProperty("useIconHighlightEffect", 0x10);
|
||||
m_queryIcon->setFixedSize(pixmap.size());
|
||||
m_queryIcon->setPixmap(pixmap);
|
||||
|
||||
m_queryText = new QLabel;
|
||||
m_queryText->setText(tr("Search"));
|
||||
m_queryText->setEnabled(false);
|
||||
m_queryText->setContentsMargins(0, 0, 0, 4);
|
||||
m_queryText->adjustSize();
|
||||
|
||||
queryWidLayout->addWidget(m_queryIcon);
|
||||
queryWidLayout->addWidget(m_queryText);
|
||||
m_queryWidget->setGeometry(QRect((m_queryLineEdit->width() - (m_queryIcon->width() + m_queryText->width() + 15)) / 2 - 10, 0,
|
||||
m_queryIcon->width() + m_queryText->width() + 20, 35)); //设置图标初始位置
|
||||
|
||||
m_animation = new QPropertyAnimation(m_queryWidget, "geometry");
|
||||
m_animation->setDuration(100); //动画时长
|
||||
connect(m_animation, &QPropertyAnimation::finished, this, [ = ]() {
|
||||
if(m_isSearching) {
|
||||
m_queryWidget->layout()->removeWidget(m_queryText);
|
||||
m_queryText->setParent(nullptr);
|
||||
} else {
|
||||
m_queryWidget->layout()->addWidget(m_queryText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void SearchBarHLayout::effectiveSearchRecord() {
|
||||
m_queryLineEdit->record();
|
||||
}
|
||||
|
||||
void SearchBarHLayout::focusIn() {
|
||||
if (!m_queryLineEdit->hasFocus())
|
||||
m_queryLineEdit->setFocus(Qt::MouseFocusReason);
|
||||
}
|
||||
|
||||
void SearchBarHLayout::focusOut() {
|
||||
m_queryLineEdit->clearFocus();
|
||||
if(! m_queryText->parent()) {
|
||||
m_queryWidget->layout()->addWidget(m_queryText);
|
||||
m_queryText->adjustSize();
|
||||
}
|
||||
m_queryWidget->setGeometry(QRect((m_queryLineEdit->width() - (m_queryIcon->width() + m_queryText->width() + 15)) / 2 - 10, 0,
|
||||
m_queryIcon->width() + m_queryText->width() + 20, 35)); //使图标回到初始位置
|
||||
}
|
||||
|
||||
void SearchBarHLayout::clearText() {
|
||||
m_queryLineEdit->setText("");
|
||||
}
|
||||
|
||||
QString SearchBarHLayout::text() {
|
||||
return m_queryLineEdit->text();
|
||||
}
|
||||
|
||||
bool SearchBarHLayout::eventFilter(QObject *watched, QEvent *event) {
|
||||
if(watched == m_queryLineEdit) {
|
||||
if(event->type() == QEvent::FocusIn) {
|
||||
if(m_queryLineEdit->text().isEmpty()) {
|
||||
m_animation->stop();
|
||||
m_animation->setStartValue(m_queryWidget->geometry());
|
||||
m_animation->setEndValue(QRect(0, 0, m_queryIcon->width() + 10, 35));
|
||||
m_animation->setEasingCurve(QEasingCurve::OutQuad);
|
||||
m_animation->start();
|
||||
}
|
||||
m_isSearching = true;
|
||||
} else if(event->type() == QEvent::FocusOut) {
|
||||
if(m_queryLineEdit->text().isEmpty()) {
|
||||
if(m_isSearching) {
|
||||
m_animation->stop();
|
||||
m_queryText->adjustSize();
|
||||
m_animation->setStartValue(QRect(0, 0, m_queryIcon->width() + 5, 35));
|
||||
m_animation->setEndValue(QRect((m_queryLineEdit->width() - (m_queryIcon->width() + m_queryText->width() + 10)) / 2, 0,
|
||||
m_queryIcon->width() + m_queryText->width() + 20, 35));
|
||||
m_animation->setEasingCurve(QEasingCurve::InQuad);
|
||||
m_animation->start();
|
||||
}
|
||||
}
|
||||
m_isSearching = false;
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UKuiSearchLineEdit 全局搜索的输入框
|
||||
*/
|
||||
SearchLineEdit::SearchLineEdit(QWidget *parent) : QLineEdit(parent) {
|
||||
this->setFocusPolicy(Qt::ClickFocus);
|
||||
this->installEventFilter(this);
|
||||
// this->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
this->setMaxLength(100);
|
||||
|
||||
m_completer = new QCompleter(this);
|
||||
m_model = new QStringListModel(this);
|
||||
m_model->setStringList(GlobalSettings::getInstance()->getSearchRecord());
|
||||
m_completer->setModel(m_model);
|
||||
m_completer->setCompletionMode(QCompleter::InlineCompletion);
|
||||
//TODO make a popup window to show the completer.
|
||||
// QListView *popView = new QListView(this);
|
||||
// popView->setFocusPolicy(Qt::NoFocus);
|
||||
// popView->setProperty("useCustomShadow", true);
|
||||
// popView->setProperty("customShadowDarkness", 0.5);
|
||||
// popView->setProperty("customShadowWidth", 20);
|
||||
// popView->setProperty("customShadowRadius", QVector4D(6, 6, 6, 6));
|
||||
// popView->setProperty("customShadowMargins", QVector4D(20, 20, 20, 20));
|
||||
// popView->setAttribute(Qt::WA_TranslucentBackground);
|
||||
// m_completer->setPopup(popView);
|
||||
m_completer->setMaxVisibleItems(14);
|
||||
|
||||
setCompleter(m_completer);
|
||||
|
||||
//这是搜索框图标,要改
|
||||
// QAction *searchAction = new QAction(this);
|
||||
// searchAction->setIcon(QIcon(":/res/icons/edit-find-symbolic.svg"));
|
||||
// this->addAction(searchAction,QLineEdit::LeadingPosition);
|
||||
|
||||
/*发送输入框文字改变的dbus*/
|
||||
// QDBusConnection::sessionBus().unregisterService("org.ukui.search.service");
|
||||
// QDBusConnection::sessionBus().registerService("org.ukui.search.service");
|
||||
// QDBusConnection::sessionBus().registerObject("/lineEdit/textChanged", this, QDBusConnection :: ExportAllSlots | QDBusConnection :: ExportAllSignals);
|
||||
|
||||
connect(this, &QLineEdit::textChanged, this, &SearchLineEdit::lineEditTextChanged);
|
||||
connect(this, &QLineEdit::textChanged, this, [ = ]() {
|
||||
m_isRecorded = false;
|
||||
});
|
||||
}
|
||||
|
||||
void SearchLineEdit::record() {
|
||||
if(m_isRecorded == true || text().size() <= 1 || text().isEmpty())
|
||||
return;
|
||||
GlobalSettings::getInstance()->setSearchRecord(text(), QDateTime::currentDateTime());
|
||||
m_isRecorded = true;
|
||||
m_model->setStringList(GlobalSettings::getInstance()->getSearchRecord());
|
||||
}
|
||||
|
||||
SearchLineEdit::~SearchLineEdit() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief lineEditTextChange 监听到搜索框文字的textChanged信号,发送dbus信号给其他程序
|
||||
* @param arg 搜索框的文本
|
||||
*
|
||||
* 需要此点击信号的应用需要做如下绑定
|
||||
* QDBusConnection::sessionBus().connect(QString(), QString("/lineEdit/textChanged"), "org.ukui.search.inputbox", "InputBoxTextChanged", this, SLOT(client_get(QString)));
|
||||
* 在槽函数client_get(void) 中处理接受到的点击信号
|
||||
*/
|
||||
void SearchLineEdit::lineEditTextChanged(QString arg) {
|
||||
QDBusMessage message = QDBusMessage::createSignal("/lineEdit/textChanged", "org.ukui.search.inputbox", "InputBoxTextChanged");
|
||||
message << arg;
|
||||
QDBusConnection::sessionBus().send(message);
|
||||
}
|
114
src/input-box.h
114
src/input-box.h
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include <QWidget>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include <QPainter>
|
||||
#include <QAction>
|
||||
#include <QTimer>
|
||||
#include <QStringListModel>
|
||||
#include <QCompleter>
|
||||
#include <QAbstractItemView>
|
||||
#include <QVector4D>
|
||||
#include <QListView>
|
||||
#include "global-settings.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class SearchLineEdit;
|
||||
|
||||
class SeachBarWidget: public QWidget {
|
||||
public:
|
||||
SeachBarWidget(QWidget *parent = nullptr);
|
||||
~SeachBarWidget();
|
||||
};
|
||||
|
||||
class SeachBar: public QWidget {
|
||||
public:
|
||||
SeachBar();
|
||||
~SeachBar();
|
||||
|
||||
private:
|
||||
// QLineEdit *m_queryLineEdit=nullptr;
|
||||
};
|
||||
|
||||
class SearchBarHLayout : public QHBoxLayout {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SearchBarHLayout(QWidget *parent = nullptr);
|
||||
~SearchBarHLayout();
|
||||
void clearText();
|
||||
QString text();
|
||||
void focusIn();
|
||||
void focusOut();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event);
|
||||
|
||||
private:
|
||||
void initUI();
|
||||
bool m_isEmpty = true;
|
||||
QTimer * m_timer = nullptr;
|
||||
|
||||
SearchLineEdit * m_queryLineEdit = nullptr;
|
||||
QPropertyAnimation * m_animation = nullptr;
|
||||
QWidget * m_queryWidget = nullptr;
|
||||
QLabel * m_queryIcon = nullptr;
|
||||
QLabel * m_queryText = nullptr;
|
||||
bool m_isSearching = false;
|
||||
|
||||
Q_SIGNALS:
|
||||
void textChanged(QString text);
|
||||
public Q_SLOTS:
|
||||
void effectiveSearchRecord();
|
||||
|
||||
};
|
||||
class SearchBarWidgetLayout : public QHBoxLayout {
|
||||
public:
|
||||
SearchBarWidgetLayout();
|
||||
~SearchBarWidgetLayout();
|
||||
private:
|
||||
void initUI();
|
||||
|
||||
};
|
||||
|
||||
class SearchLineEdit : public QLineEdit {
|
||||
Q_OBJECT
|
||||
|
||||
// /*
|
||||
// * 负责与ukui桌面环境应用通信的dbus
|
||||
// * 搜索框文本改变的时候发送信号
|
||||
// */
|
||||
// Q_CLASSINFO("D-Bus Interface", "org.ukui.search.inputbox")
|
||||
public:
|
||||
SearchLineEdit(QWidget *parent = nullptr);
|
||||
void record();
|
||||
~SearchLineEdit();
|
||||
|
||||
private Q_SLOTS:
|
||||
void lineEditTextChanged(QString arg);
|
||||
private:
|
||||
QStringListModel *m_model = nullptr;
|
||||
QCompleter *m_completer = nullptr;
|
||||
bool m_isRecorded = false;
|
||||
};
|
||||
}
|
332
src/main.cpp
332
src/main.cpp
|
@ -1,332 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
* Modified by: zhangpengfei <zhangpengfei@kylinos.cn>
|
||||
* Modified by: zhangzihao <zhangzihao@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include <QDesktopWidget>
|
||||
#include <QFile>
|
||||
#include <QScreen>
|
||||
#include <QTranslator>
|
||||
#include <QLocale>
|
||||
#include <X11/Xlib.h>
|
||||
#include <syslog.h>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
#include <ukui-log4qt.h>
|
||||
#endif
|
||||
#include <QObject>
|
||||
#include <QApplication>
|
||||
#include "qt-single-application.h"
|
||||
#include "qt-local-peer.h"
|
||||
//#include "inotify-manager.h"
|
||||
#include "libsearch.h"
|
||||
#include "global-settings.h"
|
||||
#include "ukui-search-dbus-service.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
//void handler(int){
|
||||
// qDebug() << "Recieved SIGTERM!";
|
||||
|
||||
// GlobalSettings::getInstance()->setValue(INDEX_DATABASE_STATE, "2");
|
||||
// GlobalSettings::getInstance()->setValue(CONTENT_INDEX_DATABASE_STATE, "2");
|
||||
// GlobalSettings::getInstance()->setValue(INDEX_GENERATOR_NORMAL_EXIT, "2");
|
||||
// GlobalSettings::getInstance()->setValue(INOTIFY_NORMAL_EXIT, "2");
|
||||
// GlobalSettings::getInstance()->forceSync(INDEX_DATABASE_STATE);
|
||||
// GlobalSettings::getInstance()->forceSync(CONTENT_INDEX_DATABASE_STATE);
|
||||
// GlobalSettings::getInstance()->forceSync(INDEX_GENERATOR_NORMAL_EXIT);
|
||||
// GlobalSettings::getInstance()->forceSync(INOTIFY_NORMAL_EXIT);
|
||||
|
||||
// qDebug() << "indexDataBaseStatus: " << GlobalSettings::getInstance()->getValue(INDEX_DATABASE_STATE).toString();
|
||||
// qDebug() << "contentIndexDataBaseStatus: " << GlobalSettings::getInstance()->getValue(CONTENT_INDEX_DATABASE_STATE).toString();
|
||||
|
||||
// ::exit(0);
|
||||
|
||||
// InotifyIndex::getInstance("/home")->~InotifyIndex();
|
||||
|
||||
// //wait linux kill this thread forcedly
|
||||
// while (true);
|
||||
//}
|
||||
|
||||
|
||||
void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
||||
{
|
||||
QByteArray localMsg = msg.toLocal8Bit();
|
||||
QByteArray currentTime = QTime::currentTime().toString().toLocal8Bit();
|
||||
|
||||
bool showDebug = true;
|
||||
// QString logFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/ukui-search.log";
|
||||
// QString logFilePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/org.ukui/ukui-search/ukui-search.log";
|
||||
QString logFilePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/org.ukui/ukui-search.log";
|
||||
if (!QFile::exists(logFilePath)) {
|
||||
showDebug = false;
|
||||
}
|
||||
FILE *log_file = nullptr;
|
||||
|
||||
if (showDebug) {
|
||||
log_file = fopen(logFilePath.toLocal8Bit().constData(), "a+");
|
||||
}
|
||||
|
||||
const char *file = context.file ? context.file : "";
|
||||
const char *function = context.function ? context.function : "";
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
if (!log_file) {
|
||||
break;
|
||||
}
|
||||
fprintf(log_file, "Debug: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
|
||||
break;
|
||||
case QtInfoMsg:
|
||||
fprintf(log_file? log_file: stdout, "Info: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
fprintf(log_file? log_file: stderr, "Warning: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
fprintf(log_file? log_file: stderr, "Critical: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
fprintf(log_file? log_file: stderr, "Fatal: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
|
||||
break;
|
||||
}
|
||||
|
||||
if (log_file)
|
||||
fclose(log_file);
|
||||
}
|
||||
|
||||
void centerToScreen(QWidget* widget) {
|
||||
if(!widget)
|
||||
return;
|
||||
QDesktopWidget* m = QApplication::desktop();
|
||||
QRect desk_rect = m->screenGeometry(m->screenNumber(QCursor::pos()));
|
||||
int desk_x = desk_rect.width();
|
||||
int desk_y = desk_rect.height();
|
||||
int x = widget->width();
|
||||
int y = widget->height();
|
||||
widget->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top());
|
||||
}
|
||||
/*
|
||||
void searchMethod(FileUtils::SearchMethod sm){
|
||||
qWarning() << "searchMethod start: " << static_cast<int>(sm);
|
||||
if (FileUtils::SearchMethod::INDEXSEARCH == sm || FileUtils::SearchMethod::DIRECTSEARCH == sm) {
|
||||
FileUtils::searchMethod = sm;
|
||||
} else {
|
||||
printf("enum class error!!!\n");
|
||||
qWarning("enum class error!!!\n");
|
||||
}
|
||||
if (FileUtils::SearchMethod::INDEXSEARCH == sm && 0 == FileUtils::indexStatus) {
|
||||
qWarning() << "start first index";
|
||||
FirstIndex fi("/home/zhangzihao/Desktop");
|
||||
fi.start();
|
||||
qWarning() << "start inotify index";
|
||||
// InotifyIndex ii("/home");
|
||||
// ii.start();
|
||||
InotifyIndex* ii = InotifyIndex::getInstance("/home");
|
||||
if (!ii->isRunning()) {
|
||||
ii->start();
|
||||
}
|
||||
qDebug()<<"Search method has been set to INDEXSEARCH";
|
||||
}
|
||||
qWarning() << "searchMethod end: " << static_cast<int>(FileUtils::searchMethod);
|
||||
}
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
//v101日志模块
|
||||
//#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
// //Init log module
|
||||
// initUkuiLog4qt("ukui-search");
|
||||
//#endif
|
||||
|
||||
// Determine whether the home directory has been created, and if not, keep waiting.
|
||||
char *p_home = NULL;
|
||||
|
||||
unsigned int i = 0;
|
||||
while(p_home == NULL) {
|
||||
::sleep(1);
|
||||
++i;
|
||||
p_home = getenv("HOME");
|
||||
if(i % 5 == 0) {
|
||||
qWarning() << "I can't find home! I'm done here!!";
|
||||
printf("I can't find home! I'm done here!!");
|
||||
syslog(LOG_ERR, "I can't find home! I'm done here!!\n");
|
||||
}
|
||||
}
|
||||
p_home = NULL;
|
||||
while(!QDir(QDir::homePath()).exists()) {
|
||||
qWarning() << "Home is not exits!!";
|
||||
printf("Home is not exits!!");
|
||||
syslog(LOG_ERR, "Home is not exits!!\n");
|
||||
::sleep(1);
|
||||
}
|
||||
|
||||
// Output log to file
|
||||
qInstallMessageHandler(messageOutput);
|
||||
//若使用v101日志模块,可以解放如下判断条件
|
||||
//#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
|
||||
// // Output log to file
|
||||
// qInstallMessageHandler(messageOutput);
|
||||
//#endif
|
||||
|
||||
// Register meta type
|
||||
qDebug() << "ukui-search main start";
|
||||
qRegisterMetaType<QPair<QString, QStringList>>("QPair<QString,QStringList>");
|
||||
qRegisterMetaType<Document>("Document");
|
||||
|
||||
// If qt version bigger than 5.12, enable high dpi scaling and use high dpi pixmaps?
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
|
||||
// Make sure only one ukui-search is running.
|
||||
QtSingleApplication app("ukui-search", argc, argv);
|
||||
app.setQuitOnLastWindowClosed(false);
|
||||
|
||||
if(app.isRunning()) {
|
||||
app.sendMessage(QApplication::arguments().length() > 1 ? QApplication::arguments().at(1) : app.applicationFilePath());
|
||||
qDebug() << QObject::tr("ukui-search is already running!");
|
||||
return EXIT_SUCCESS;
|
||||
}/*else {
|
||||
QCommandLineParser parser;
|
||||
QCommandLineOption debugOption({"d", "debug"}, QObject::tr("Display debug information"));
|
||||
QCommandLineOption showsearch({"s", "show"}, QObject::tr("show search widget"));
|
||||
parser.addOptions({debugOption, showsearch});
|
||||
parser.process(app);
|
||||
}*/
|
||||
/*
|
||||
// Create a fifo at ~/.config/org.ukui/ukui-search, the fifo is used to control the order of child processes' running.
|
||||
QDir fifoDir = QDir(QDir::homePath()+"/.config/org.ukui/ukui-search");
|
||||
if(!fifoDir.exists())
|
||||
qDebug()<<"create fifo path"<<fifoDir.mkpath(fifoDir.absolutePath());
|
||||
|
||||
unlink(UKUI_SEARCH_PIPE_PATH);
|
||||
int retval = mkfifo(UKUI_SEARCH_PIPE_PATH, 0777);
|
||||
if(retval == -1)
|
||||
{
|
||||
qCritical()<<"creat fifo error!!";
|
||||
syslog(LOG_ERR,"creat fifo error!!\n");
|
||||
assert(false);
|
||||
return -1;
|
||||
}
|
||||
qDebug()<<"create fifo success\n";
|
||||
*/
|
||||
// Set max_user_watches to a number which is enough big.
|
||||
UkuiSearchQDBus usQDBus;
|
||||
usQDBus.setInotifyMaxUserWatches();
|
||||
|
||||
// load chinese character and pinyin file to a Map
|
||||
FileUtils::loadHanziTable("://index/pinyinWithoutTone.txt");
|
||||
/*-------------InotyifyRefact Test Start---------------*/
|
||||
// QTime t1 = QTime::currentTime();
|
||||
// InotifyManagerRefact* imr = new InotifyManagerRefact("/home");
|
||||
// imr->start();
|
||||
// QTime t2 = QTime::currentTime();
|
||||
// qDebug() << t1;
|
||||
// qDebug() << t2;
|
||||
/*-------------InotyifyRefact Test End-----------------*/
|
||||
|
||||
/*-------------content index Test Start---------------*/
|
||||
// QTime t3 = QTime::currentTime();
|
||||
// FileTypeFilter* ftf = new FileTypeFilter("/home");
|
||||
// ftf->Test();
|
||||
// QTime t4 = QTime::currentTime();
|
||||
// delete ftf;
|
||||
// ftf = nullptr;
|
||||
// qDebug() << t3;
|
||||
// qDebug() << t4;
|
||||
/*-------------content index Test End-----------------*/
|
||||
/*-------------文本搜索 Test start-----------------*/
|
||||
// FileSearcher *search = new FileSearcher();
|
||||
// search->onKeywordSearchContent("重要器官移植⑤白血病");
|
||||
// search->onKeywordSearchContent("g,e,x");
|
||||
/*-------------文本搜索 Test End-----------------*/
|
||||
|
||||
// Load translations
|
||||
QTranslator translator;
|
||||
try {
|
||||
if(! translator.load("/usr/share/ukui-search/translations/" + QLocale::system().name())) throw - 1;
|
||||
app.installTranslator(&translator);
|
||||
} catch(...) {
|
||||
qDebug() << "Load translations file" << QLocale() << "failed!";
|
||||
}
|
||||
|
||||
QTranslator qt_translator;
|
||||
try {
|
||||
if(! qt_translator.load(":/res/qt-translations/qt_zh_CN.qm")) throw - 1;
|
||||
app.installTranslator(&qt_translator);
|
||||
} catch(...) {
|
||||
qDebug() << "Load translations file" << QLocale() << "failed!";
|
||||
}
|
||||
|
||||
//set main window to the center of screen
|
||||
MainWindow *w = new MainWindow;
|
||||
UkuiSearchDbusServices dbusService(w);
|
||||
qApp->setWindowIcon(QIcon::fromTheme("kylin-search"));
|
||||
// centerToScreen(w);
|
||||
// w->moveToPanel();
|
||||
centerToScreen(w);
|
||||
|
||||
//请务必在connect之后初始化mainwindow的Gsettings,为了保证gsettings第一次读取到的配置值能成功应用
|
||||
w->initGsettings();
|
||||
|
||||
//使用窗管的无边框策略
|
||||
// w->setProperty("useStyleWindowManager", false); //禁用拖动
|
||||
// MotifWmHints hints;
|
||||
// hints.flags = MWM_HINTS_FUNCTIONS|MWM_HINTS_DECORATIONS;
|
||||
// hints.functions = MWM_FUNC_ALL;
|
||||
// hints.decorations = MWM_DECOR_BORDER;
|
||||
// XAtomHelper::getInstance()->setWindowMotifHint(w->winId(), hints);
|
||||
|
||||
app.setActivationWindow(w);
|
||||
|
||||
// Processing startup parameters
|
||||
if(QString::compare(QString("-s"), QString(QLatin1String(argv[1]))) == 0) {
|
||||
// w->moveToPanel();
|
||||
centerToScreen(w);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
XAtomHelper::getInstance()->setWindowMotifHint(w->winId(), w->m_hints);
|
||||
#endif
|
||||
w->show();
|
||||
}
|
||||
|
||||
QObject::connect(&app, &QtSingleApplication::messageReceived, w, &MainWindow::bootOptionsFilter);
|
||||
|
||||
// Start app search thread
|
||||
AppMatch::getAppMatch()->start();
|
||||
|
||||
// TODO
|
||||
// Set threads which in global thread pool expiry time in 5ms, some prolems here
|
||||
// QThreadPool::globalInstance()->setExpiryTimeout(5);
|
||||
|
||||
// TODO
|
||||
// First insdex start, the parameter us useless, should remove the parameter
|
||||
// FirstIndex fi("/home/zhangzihao/Desktop");
|
||||
// fi.start();
|
||||
|
||||
// TODO
|
||||
// Inotify index start, the parameter us useless, should remove the parameter
|
||||
// InotifyIndex* ii = InotifyIndex::getInstance("/home");
|
||||
// ii->start();
|
||||
|
||||
return app.exec();
|
||||
}
|
|
@ -1,646 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
* Modified by: zhangpengfei <zhangpengfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include <QHBoxLayout>
|
||||
#include <QDebug>
|
||||
#include <QDesktopWidget>
|
||||
#include <QtX11Extras/QX11Info>
|
||||
#include <syslog.h>
|
||||
#include <QPalette>
|
||||
#include <QScreen>
|
||||
#include <QStyleOption>
|
||||
#include <QPixmap>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
#include <KWindowEffects>
|
||||
#include "kwindowsystem.h"
|
||||
#endif
|
||||
#include "qt-single-application.h"
|
||||
|
||||
//#include "inotify-manager.h"
|
||||
//#include "settings-widget.h"
|
||||
|
||||
|
||||
#include "global-settings.h"
|
||||
#include "search-result.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);
|
||||
/**
|
||||
* @brief MainWindow 主界面
|
||||
* @param parent
|
||||
*
|
||||
* 慎用KWindowSystem::setShowingDesktop(!KWindowSystem::showingDesktop());
|
||||
* 可能造成窗口属性的混乱
|
||||
*/
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent) {
|
||||
|
||||
m_sys_tray_icon = new QSystemTrayIcon(this);
|
||||
if (!QIcon::fromTheme("system-search-symbolic").isNull())
|
||||
m_sys_tray_icon->setIcon(QIcon::fromTheme("system-search-symbolic"));
|
||||
else
|
||||
m_sys_tray_icon->setIcon(QIcon(":/res/icons/system-search.symbolic.png"));
|
||||
m_sys_tray_icon->setToolTip(tr("Global Search"));
|
||||
m_sys_tray_icon->show();
|
||||
|
||||
m_searcher = new SearchManager(this);
|
||||
m_settingsMatch = new SettingsMatch(this);
|
||||
|
||||
// this->setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
|
||||
// this->setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
|
||||
// this->setWindowIcon(QIcon::fromTheme("kylin-search"));
|
||||
this->setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
this->setAutoFillBackground(false);
|
||||
this->setFocusPolicy(Qt::StrongFocus);
|
||||
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
this->setWindowTitle(tr("ukui-search"));
|
||||
initUi();
|
||||
initTimer();
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
// setProperty("useStyleWindowManager", false); //禁止拖动
|
||||
m_hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
|
||||
m_hints.functions = MWM_FUNC_ALL;
|
||||
m_hints.decorations = MWM_DECOR_BORDER;
|
||||
XAtomHelper::getInstance()->setWindowMotifHint(winId(), m_hints);
|
||||
|
||||
QPainterPath path;
|
||||
auto rect = this->rect();
|
||||
rect.adjust(1, 1, -1, -1);
|
||||
// path.addRoundedRect(rect, 0, 0);
|
||||
path.addRect(rect);
|
||||
setProperty("blurRegion", QRegion(path.toFillPolygon().toPolygon()));
|
||||
KWindowEffects::enableBlurBehind(this->winId(), true, QRegion(path.toFillPolygon().toPolygon()));
|
||||
#endif
|
||||
|
||||
m_search_result_file = new QQueue<QString>;
|
||||
m_search_result_dir = new QQueue<QString>;
|
||||
m_search_result_content = new QQueue<QPair<QString, QStringList>>;
|
||||
m_search_result_thread = new SearchResult(this);
|
||||
m_seach_app_thread = new SearchAppThread(this);
|
||||
// m_search_result_thread->start();
|
||||
connect(m_search_result_thread, &SearchResult::searchResultFile, this, [ = ](QString path) {
|
||||
// qDebug()<<"Append a file into list: "<<path;
|
||||
m_contentFrame->appendSearchItem(SearchItem::SearchType::Files, path);
|
||||
});
|
||||
connect(m_search_result_thread, &SearchResult::searchResultDir, this, [ = ](QString path) {
|
||||
// qDebug()<<"Append a dir into list: "<<path;
|
||||
m_contentFrame->appendSearchItem(SearchItem::SearchType::Dirs, path);
|
||||
});
|
||||
connect(m_search_result_thread, &SearchResult::searchResultContent, this, [ = ](QPair<QString, QStringList> pair) {
|
||||
// qDebug()<<"Append a file content into list: "<<pair.first;
|
||||
m_contentFrame->appendSearchItem(SearchItem::SearchType::Contents, pair.first, pair.second);
|
||||
});
|
||||
qRegisterMetaType<QVector<QStringList>>("QVector<QStringList>");
|
||||
connect(m_seach_app_thread, &SearchAppThread::searchResultApp, this, [ = ](const QVector<QStringList>& applist) {
|
||||
qDebug() << "Append applist: " << applist;
|
||||
m_contentFrame->setAppList(applist);
|
||||
});
|
||||
|
||||
connect(m_sys_tray_icon, &QSystemTrayIcon::activated, this, [ = ](QSystemTrayIcon::ActivationReason reason) {
|
||||
if(reason == QSystemTrayIcon::Trigger) {
|
||||
if(!this->isVisible()) {
|
||||
clearSearchResult();
|
||||
// this->moveToPanel();
|
||||
centerToScreen(this);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
XAtomHelper::getInstance()->setWindowMotifHint(winId(), m_hints);
|
||||
#endif
|
||||
this->show();
|
||||
this->m_searchLayout->focusIn(); //打开主界面时输入框夺焦,可直接输入
|
||||
this->raise();
|
||||
this->activateWindow();
|
||||
} else if(this->isVisible()&&!this->isActiveWindow()) {
|
||||
this->activateWindow();
|
||||
} else {
|
||||
tryHideMainwindow();
|
||||
}
|
||||
}
|
||||
});
|
||||
QObject::connect(this, &MainWindow::searchMethodChanged, this, [ = ](FileUtils::SearchMethod sm) {
|
||||
this->m_searchMethodManager.searchMethod(sm);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow() {
|
||||
if(m_searchWidget) {
|
||||
delete m_searchWidget;
|
||||
m_searchWidget = NULL;
|
||||
}
|
||||
if(m_searchLayout) {
|
||||
delete m_searchLayout;
|
||||
m_searchLayout = NULL;
|
||||
}
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
|
||||
if(m_settingsWidget) {
|
||||
delete m_settingsWidget;
|
||||
m_settingsWidget = NULL;
|
||||
}
|
||||
#endif
|
||||
if(m_askDialog) {
|
||||
delete m_askDialog;
|
||||
m_askDialog = NULL;
|
||||
}
|
||||
if(m_askTimer) {
|
||||
delete m_askTimer;
|
||||
m_askTimer = NULL;
|
||||
}
|
||||
if(m_search_gsettings) {
|
||||
delete m_search_gsettings;
|
||||
m_search_gsettings = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initUi
|
||||
* 设置本窗口的大小 this->setFixedSize(640, 640);
|
||||
*/
|
||||
void MainWindow::initUi() {
|
||||
this->setFixedSize(680, 590);
|
||||
|
||||
m_frame = new QFrame(this);
|
||||
|
||||
this->setCentralWidget(m_frame);
|
||||
QVBoxLayout * mainlayout = new QVBoxLayout(m_frame);
|
||||
mainlayout->setContentsMargins(8, 0, 8, 6);
|
||||
m_frame->setLayout(mainlayout);
|
||||
|
||||
m_titleFrame = new QFrame(m_frame);//标题栏
|
||||
m_titleFrame->setFixedHeight(40);
|
||||
m_titleLyt = new QHBoxLayout(m_titleFrame);
|
||||
m_titleLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_iconLabel = new QLabel(m_titleFrame);
|
||||
m_iconLabel->setFixedSize(24, 24);
|
||||
m_iconLabel->setPixmap(QIcon::fromTheme("kylin-search").pixmap(QSize(24, 24)));
|
||||
//主题改变时,更新自定义标题栏的图标
|
||||
connect(qApp, &QApplication::paletteChanged, this, [ = ]() {
|
||||
m_iconLabel->setPixmap(QIcon::fromTheme("kylin-search").pixmap(QSize(24, 24)));
|
||||
});
|
||||
m_titleLabel = new QLabel(m_titleFrame);
|
||||
m_titleLabel->setText(tr("Search"));
|
||||
m_menuBtn = new QPushButton(m_titleFrame);
|
||||
m_menuBtn->setFixedSize(30, 30);
|
||||
// m_menuBtn->setIcon(QIcon(":/res/icons/commonuse.svg"));
|
||||
m_menuBtn->setIcon(QIcon::fromTheme("document-properties-symbolic"));
|
||||
m_menuBtn->setProperty("useIconHighlightEffect", 0x2);
|
||||
m_menuBtn->setProperty("isWindowButton", 0x01);
|
||||
m_menuBtn->setFlat(true);
|
||||
connect(m_menuBtn, &QPushButton::clicked, this, [ = ]() {
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
|
||||
if(m_settingsWidget) { //当此窗口已存在时,仅需置顶
|
||||
if(!m_settingsWidget->isVisible()) {
|
||||
centerToScreen(m_settingsWidget);
|
||||
}
|
||||
m_settingsWidget->showWidget();
|
||||
return;
|
||||
}
|
||||
m_settingsWidget = new SettingsWidget();
|
||||
connect(this, &MainWindow::webEngineChanged, m_settingsWidget, [ = ]() {
|
||||
m_settingsWidget->resetWebEngine();
|
||||
});
|
||||
connect(m_settingsWidget, &SettingsWidget::webEngineChanged, this, [ = ](const QString & engine) {
|
||||
if(m_search_gsettings && m_search_gsettings->keys().contains(WEB_ENGINE_KEY)) {
|
||||
m_search_gsettings->set(WEB_ENGINE_KEY, engine);
|
||||
} else {
|
||||
GlobalSettings::getInstance()->setValue(WEB_ENGINE, engine);
|
||||
}
|
||||
});
|
||||
centerToScreen(m_settingsWidget);
|
||||
m_settingsWidget->show();
|
||||
connect(m_settingsWidget, &SettingsWidget::settingWidgetClosed, this, [ = ]() {
|
||||
QTimer::singleShot(100, this, [ = ] {
|
||||
// clearSearchResult(); //现暂定从设置页返回主页面不清空搜索结果
|
||||
this->setWindowState(this->windowState() & ~Qt::WindowMinimized);
|
||||
this->raise();
|
||||
this->showNormal();
|
||||
this->activateWindow();
|
||||
});
|
||||
});
|
||||
#endif
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
//打开控制面板的设置页
|
||||
QProcess process;
|
||||
process.startDetached("ukui-control-center --search");
|
||||
#endif
|
||||
});
|
||||
m_titleLyt->addWidget(m_iconLabel);
|
||||
m_titleLyt->addWidget(m_titleLabel);
|
||||
m_titleLyt->addStretch();
|
||||
m_titleLyt->addWidget(m_menuBtn);
|
||||
|
||||
m_contentFrame = new ContentWidget(m_frame);//内容栏
|
||||
|
||||
m_searchWidget = new SeachBarWidget(this);
|
||||
m_searchLayout = new SearchBarHLayout(this);
|
||||
m_searchWidget->setLayout(m_searchLayout);
|
||||
m_searchWidget->setFixedHeight(44);
|
||||
|
||||
mainlayout->addWidget(m_titleFrame);
|
||||
mainlayout->addWidget(m_contentFrame);
|
||||
mainlayout->addWidget(m_searchWidget);
|
||||
connect(m_contentFrame, &ContentWidget::effectiveSearch, m_searchLayout, &SearchBarHLayout::effectiveSearchRecord);
|
||||
|
||||
connect(QApplication::primaryScreen(), &QScreen::geometryChanged,
|
||||
this, &MainWindow::monitorResolutionChange);
|
||||
connect(qApp, &QApplication::primaryScreenChanged, this,
|
||||
&MainWindow::primaryScreenChangedSlot);
|
||||
connect(m_searchLayout, &SearchBarHLayout::textChanged, this, [ = ](QString text) {
|
||||
if(text == "") {
|
||||
if(m_search_result_thread->isRunning()) {
|
||||
m_search_result_thread->requestInterruption();
|
||||
m_search_result_thread->quit();
|
||||
}
|
||||
// m_seach_app_thread->stop();
|
||||
m_contentFrame->setCurrentIndex(0);
|
||||
m_askTimer->stop();
|
||||
} else {
|
||||
m_contentFrame->setCurrentIndex(1);
|
||||
QTimer::singleShot(10, this, [ = ]() {
|
||||
startSearch(text);
|
||||
});
|
||||
}
|
||||
m_researchTimer->stop(); //如果搜索内容发生改变,则停止建索引后重新搜索的倒计时
|
||||
});
|
||||
|
||||
//初始化homepage
|
||||
// m_contentFrame->setQuicklyOpenList(list); //如需自定义快捷打开使用本函数
|
||||
m_contentFrame->initHomePage();
|
||||
|
||||
//创建索引询问弹窗
|
||||
m_askDialog = new CreateIndexAskDialog(this);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
MotifWmHints ask_dialog_hints;
|
||||
ask_dialog_hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
|
||||
ask_dialog_hints.functions = MWM_FUNC_ALL;
|
||||
ask_dialog_hints.decorations = MWM_DECOR_BORDER;
|
||||
XAtomHelper::getInstance()->setWindowMotifHint(m_askDialog->winId(), ask_dialog_hints);
|
||||
#endif
|
||||
connect(m_askDialog, &CreateIndexAskDialog::closed, this, [ = ]() {
|
||||
m_isAskDialogVisible = false;
|
||||
});
|
||||
connect(m_askDialog, &CreateIndexAskDialog::btnClicked, this, [ = ](const bool & create_index, const bool & no_longer_ask) {
|
||||
if(no_longer_ask) {
|
||||
GlobalSettings::getInstance()->setValue(ENABLE_CREATE_INDEX_ASK_DIALOG, "false");
|
||||
} else {
|
||||
GlobalSettings::getInstance()->setValue(ENABLE_CREATE_INDEX_ASK_DIALOG, "true");
|
||||
}
|
||||
if(create_index) {
|
||||
if(m_search_gsettings && m_search_gsettings->keys().contains(SEARCH_METHOD_KEY)) {
|
||||
m_search_gsettings->set(SEARCH_METHOD_KEY, true);
|
||||
} else {
|
||||
//调用创建索引接口
|
||||
Q_EMIT this->searchMethodChanged(FileUtils::SearchMethod::INDEXSEARCH);
|
||||
//创建索引十秒后重新搜索一次(如果用户十秒内没有退出搜索界面且没有重新搜索)
|
||||
m_researchTimer->start();
|
||||
}
|
||||
}
|
||||
});
|
||||
installEventFilter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief bootOptionsFilter 过滤终端命令
|
||||
* @param opt
|
||||
*/
|
||||
void MainWindow::bootOptionsFilter(QString opt) {
|
||||
if(opt == "-s" || opt == "--show") {
|
||||
clearSearchResult();
|
||||
// this->moveToPanel();
|
||||
centerToScreen(this);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
XAtomHelper::getInstance()->setWindowMotifHint(winId(), m_hints);
|
||||
#endif
|
||||
this->show();
|
||||
this->m_searchLayout->focusIn();
|
||||
this->raise();
|
||||
this->activateWindow();
|
||||
// m_search_result_thread->start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief clearSearchResult 清空搜索结果
|
||||
*/
|
||||
void MainWindow::clearSearchResult() {
|
||||
m_searchLayout->clearText();
|
||||
m_searchLayout->focusOut();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MainWindow::createIndexSlot 允许创建索引的槽函数
|
||||
*/
|
||||
void MainWindow::createIndexSlot() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief loadMainWindow 加载主界面的函数
|
||||
* 不删除的原因是在单例和main函数里面需要用
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief monitorResolutionChange 监听屏幕改变
|
||||
* @param rect
|
||||
*/
|
||||
void MainWindow::monitorResolutionChange(QRect rect) {
|
||||
Q_UNUSED(rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief primaryScreenChangedSlot 监听分辨率改变
|
||||
* @param screen
|
||||
*/
|
||||
void MainWindow::primaryScreenChangedSlot(QScreen *screen) {
|
||||
Q_UNUSED(screen);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief startSearch 搜索关键字
|
||||
* @param keyword
|
||||
*/
|
||||
void MainWindow::startSearch(QString keyword) {
|
||||
m_search_result_file->clear();
|
||||
m_search_result_dir->clear();
|
||||
m_search_result_content->clear();
|
||||
if(! m_search_result_thread->isRunning()) {
|
||||
m_search_result_thread->start();
|
||||
}
|
||||
//允许弹窗且当前次搜索(为关闭主界面,算一次搜索过程)未询问且当前为暴力搜索
|
||||
if(GlobalSettings::getInstance()->getValue(ENABLE_CREATE_INDEX_ASK_DIALOG).toString() != "false" && !m_currentSearchAsked && FileUtils::searchMethod == FileUtils::SearchMethod::DIRECTSEARCH)
|
||||
m_askTimer->start();
|
||||
|
||||
m_contentFrame->setKeyword(keyword);
|
||||
|
||||
//文件、文件夹、内容搜索
|
||||
this->m_searcher->onKeywordSearch(keyword, m_search_result_file, m_search_result_dir, m_search_result_content);
|
||||
|
||||
//设置搜索
|
||||
QStringList settingList;
|
||||
settingList = m_settingsMatch->startMatchApp(keyword);
|
||||
m_contentFrame->resetSearchList();
|
||||
m_contentFrame->setSettingList(settingList);
|
||||
|
||||
//应用搜索
|
||||
// m_seach_app_thread->stop();
|
||||
m_seach_app_thread->startSearch(keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MainWindow::moveToPanel 将主界面移动到任务栏旁边(跟随任务栏位置)
|
||||
*/
|
||||
void MainWindow::moveToPanel() {
|
||||
QRect availableGeometry = qApp->primaryScreen()->availableGeometry();
|
||||
QRect screenGeometry = qApp->primaryScreen()->geometry();
|
||||
|
||||
QDBusInterface primaryScreenInterface("org.ukui.SettingsDaemon",
|
||||
"/org/ukui/SettingsDaemon/wayland",
|
||||
"org.ukui.SettingsDaemon.wayland",
|
||||
QDBusConnection::sessionBus());
|
||||
if(QDBusReply<int>(primaryScreenInterface.call("x")).isValid()) {
|
||||
QDBusReply<int> x = primaryScreenInterface.call("x");
|
||||
QDBusReply<int> y = primaryScreenInterface.call("y");
|
||||
QDBusReply<int> width = primaryScreenInterface.call("width");
|
||||
QDBusReply<int> height = primaryScreenInterface.call("height");
|
||||
screenGeometry.setX(x);
|
||||
screenGeometry.setY(y);
|
||||
screenGeometry.setWidth(width);
|
||||
screenGeometry.setHeight(height);
|
||||
availableGeometry.setX(x);
|
||||
availableGeometry.setY(y);
|
||||
availableGeometry.setWidth(width);
|
||||
availableGeometry.setHeight(height);
|
||||
}
|
||||
|
||||
QDesktopWidget * desktopWidget = QApplication::desktop();
|
||||
QRect screenMainRect = desktopWidget->screenGeometry(0);//获取设备屏幕大小
|
||||
|
||||
QDBusInterface interface("com.ukui.panel.desktop",
|
||||
"/",
|
||||
"com.ukui.panel.desktop",
|
||||
QDBusConnection::sessionBus());
|
||||
|
||||
int position = QDBusReply<int>(interface.call("GetPanelPosition", "position"));
|
||||
int height = QDBusReply<int>(interface.call("GetPanelSize", "height"));
|
||||
int d = 8; //窗口边沿到任务栏距离
|
||||
|
||||
if(position == 0) {
|
||||
//任务栏在下侧
|
||||
this->move(availableGeometry.x() + availableGeometry.width() - this->width() - d, screenGeometry.y() + screenGeometry.height() - this->height() - height - d);
|
||||
} else if(position == 1) {
|
||||
//任务栏在上侧
|
||||
this->move(availableGeometry.x() + availableGeometry.width() - this->width() - d, screenGeometry.y() + height + d);
|
||||
} else if(position == 2) {
|
||||
//任务栏在左侧
|
||||
this->move(screenGeometry.x() + height + d, screenGeometry.y() + screenGeometry.height() - this->height() - d);
|
||||
} else if(position == 3) {
|
||||
//任务栏在右侧
|
||||
this->move(screenGeometry.x() + screenGeometry.width() - this->width() - height - d, screenGeometry.y() + screenGeometry.height() - this->height() - d);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MainWindow::centerToScreen 使窗口显示在屏幕中间
|
||||
* @param widget
|
||||
*/
|
||||
void MainWindow::centerToScreen(QWidget* widget) {
|
||||
if(!widget)
|
||||
return;
|
||||
QDesktopWidget* m = QApplication::desktop();
|
||||
QRect desk_rect = m->screenGeometry(m->screenNumber(QCursor::pos()));
|
||||
int desk_x = desk_rect.width();
|
||||
int desk_y = desk_rect.height();
|
||||
int x = widget->width();
|
||||
int y = widget->height();
|
||||
// QDBusInterface primaryScreenInterface("org.ukui.SettingsDaemon",
|
||||
// "/org/ukui/SettingsDaemon/wayland",
|
||||
// "org.ukui.SettingsDaemon.wayland",
|
||||
// QDBusConnection::sessionBus());
|
||||
// if(QDBusReply<int>(primaryScreenInterface.call("x")).isValid()) {
|
||||
// QDBusReply<int> width = primaryScreenInterface.call("width");
|
||||
// QDBusReply<int> height = primaryScreenInterface.call("height");
|
||||
// desk_x = width;
|
||||
// desk_y = height;
|
||||
// }
|
||||
widget->move(desk_x / 2 - x / 2 + desk_rect.left(), desk_y / 2 - y / 2 + desk_rect.top());
|
||||
}
|
||||
|
||||
void MainWindow::initGsettings() {
|
||||
const QByteArray id(UKUI_SEARCH_SCHEMAS);
|
||||
if(QGSettings::isSchemaInstalled(id)) {
|
||||
m_search_gsettings = new QGSettings(id);
|
||||
connect(m_search_gsettings, &QGSettings::changed, this, [ = ](const QString & key) {
|
||||
if(key == SEARCH_METHOD_KEY) {
|
||||
bool is_index_search = m_search_gsettings->get(SEARCH_METHOD_KEY).toBool();
|
||||
this->setSearchMethod(is_index_search);
|
||||
} else if(key == WEB_ENGINE_KEY) {
|
||||
QString web_engine = m_search_gsettings->get(WEB_ENGINE_KEY).toString();
|
||||
GlobalSettings::getInstance()->setValue(WEB_ENGINE, web_engine);
|
||||
Q_EMIT this->webEngineChanged();
|
||||
}
|
||||
});
|
||||
if(m_search_gsettings->keys().contains(SEARCH_METHOD_KEY)) {
|
||||
bool is_index_search = m_search_gsettings->get(SEARCH_METHOD_KEY).toBool();
|
||||
this->setSearchMethod(is_index_search);
|
||||
}
|
||||
if(m_search_gsettings->keys().contains(WEB_ENGINE_KEY)) {
|
||||
QString web_engine = m_search_gsettings->get(WEB_ENGINE_KEY).toString();
|
||||
GlobalSettings::getInstance()->setValue(WEB_ENGINE, web_engine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//使用GSetting获取当前窗口应该使用的透明度
|
||||
double MainWindow::getTransparentData() {
|
||||
return GlobalSettings::getInstance()->getValue(TRANSPARENCY_KEY).toDouble();
|
||||
}
|
||||
|
||||
void MainWindow::initTimer() {
|
||||
m_askTimer = new QTimer;
|
||||
m_askTimer->setInterval(5 * 1000);
|
||||
connect(m_askTimer, &QTimer::timeout, this, [ = ]() {
|
||||
if(this->isVisible()) {
|
||||
m_isAskDialogVisible = true;
|
||||
m_askDialog->show();
|
||||
m_currentSearchAsked = true;
|
||||
}
|
||||
m_askTimer->stop();
|
||||
});
|
||||
m_researchTimer = new QTimer;
|
||||
m_researchTimer->setInterval(10 * 1000);
|
||||
connect(m_researchTimer, &QTimer::timeout, this, [ = ]() {
|
||||
if(this->isVisible()) {
|
||||
startSearch(m_searchLayout->text());
|
||||
}
|
||||
m_researchTimer->stop();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MainWindow::tryHideMainwindow 尝试隐藏主界面并停止部分未完成的动作,重置部分状态值
|
||||
*/
|
||||
bool MainWindow::tryHideMainwindow()
|
||||
{
|
||||
if (!m_isAskDialogVisible) {
|
||||
qDebug()<<"Mainwindow will be hidden";
|
||||
m_currentSearchAsked = false;
|
||||
this->hide();
|
||||
m_askTimer->stop();
|
||||
m_researchTimer->stop();
|
||||
m_contentFrame->closeWebView();
|
||||
m_search_result_thread->requestInterruption();
|
||||
m_search_result_thread->quit();
|
||||
return true;
|
||||
} else {
|
||||
//有上层弹窗未关闭,不允许隐藏主界面
|
||||
qWarning()<<"There is a dialog onside, so that mainwindow can not be hidden.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MainWindow::setSearchMethod 设置搜索模式
|
||||
* @param is_index_search true为索引搜索,false为暴力搜索
|
||||
*/
|
||||
void MainWindow::setSearchMethod(const bool &is_index_search) {
|
||||
if(is_index_search) {
|
||||
//调用创建索引接口
|
||||
Q_EMIT this->searchMethodChanged(FileUtils::SearchMethod::INDEXSEARCH);
|
||||
//创建索引十秒后重新搜索一次(如果用户十秒内没有退出搜索界面且没有重新搜索)
|
||||
m_researchTimer->start();
|
||||
} else {
|
||||
Q_EMIT this->searchMethodChanged(FileUtils::SearchMethod::DIRECTSEARCH);
|
||||
m_researchTimer->stop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MainWindow::nativeEvent 处理窗口失焦事件
|
||||
* @param eventType
|
||||
* @param message
|
||||
* @param result
|
||||
* @return
|
||||
*/
|
||||
//bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
||||
//{
|
||||
// Q_UNUSED(result);
|
||||
// if (eventType != "xcb_generic_event_t") {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// xcb_generic_event_t *event = (xcb_generic_event_t*)message;
|
||||
|
||||
// switch (event->response_type & ~0x80) {
|
||||
// case XCB_FOCUS_OUT:
|
||||
// tryHideMainwindow();
|
||||
//// m_seach_app_thread->stop();
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief MainWindow::keyPressEvent 按esc键关闭主界面
|
||||
* @param event
|
||||
*/
|
||||
void MainWindow::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
tryHideMainwindow();
|
||||
// m_seach_app_thread->stop();
|
||||
}
|
||||
return QWidget::keyPressEvent(event);
|
||||
}
|
||||
|
||||
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ActivationChange) {
|
||||
if(QApplication::activeWindow() != this) {
|
||||
tryHideMainwindow();
|
||||
}
|
||||
}
|
||||
return QMainWindow::eventFilter(watched,event);
|
||||
}
|
||||
|
||||
void MainWindow::paintEvent(QPaintEvent *event) {
|
||||
Q_UNUSED(event)
|
||||
|
||||
double trans = getTransparentData();
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
|
||||
QRect rect = this->rect();
|
||||
p.setRenderHint(QPainter::Antialiasing); // 反锯齿;
|
||||
p.setBrush(opt.palette.color(QPalette::Base));
|
||||
p.setOpacity(trans);
|
||||
p.setPen(Qt::NoPen);
|
||||
// p.drawRoundedRect(rect, 6, 6);
|
||||
p.drawRect(rect);
|
||||
return QWidget::paintEvent(event);
|
||||
|
||||
}
|
165
src/mainwindow.h
165
src/mainwindow.h
|
@ -1,165 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
* Modified by: zhangpengfei <zhangpengfei@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainterPath>
|
||||
#include <QPainter>
|
||||
#include <QtMath>
|
||||
#include <QEvent>
|
||||
#include <QSpacerItem>
|
||||
#include <QKeyEvent>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
#include <QSettings>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QFileInfo>
|
||||
#include <QLabel>
|
||||
#include <QFrame>
|
||||
#include <QPushButton>
|
||||
#include <QKeyEvent>
|
||||
#include <QGSettings/QGSettings>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QTimer>
|
||||
|
||||
#include "content-widget.h"
|
||||
#include "input-box.h"
|
||||
#include "index/index-generator.h"
|
||||
#include "libsearch.h"
|
||||
#include "search-app-thread.h"
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
#include "xatom-helper.h"
|
||||
#endif
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
|
||||
#include "settings-widget.h"
|
||||
#endif
|
||||
#include "create-index-ask-dialog.h"
|
||||
|
||||
#define UKUI_SEARCH_SCHEMAS "org.ukui.search.settings"
|
||||
#define SEARCH_METHOD_KEY "indexSearch"
|
||||
#define WEB_ENGINE_KEY "webEngine"
|
||||
|
||||
namespace Zeeker {
|
||||
class SearchResult;
|
||||
class MainWindow : public QMainWindow {
|
||||
friend class SearchResult;
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
/**
|
||||
* @brief Load the main window
|
||||
*/
|
||||
|
||||
// The parameter:keyword is the word or sentence which users want to search.
|
||||
void startSearch(QString keyword);
|
||||
|
||||
// The position which mainwindow shows follow the ukui-panel.
|
||||
void moveToPanel();
|
||||
|
||||
// The position which mainwindow shows in the center of screen where the cursor in.
|
||||
void centerToScreen(QWidget* widget);
|
||||
void initGsettings();
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
MotifWmHints m_hints;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
// MainWindow quit when focus out.
|
||||
// bool nativeEvent(const QByteArray&, void*, long*);
|
||||
|
||||
QFrame * m_frame = nullptr; // Main frame
|
||||
QFrame * m_titleFrame = nullptr; // Title bar frame
|
||||
QHBoxLayout * m_titleLyt = nullptr; // Title layout
|
||||
QLabel * m_iconLabel = nullptr; // Icon lable
|
||||
QLabel * m_titleLabel = nullptr; // Title lable
|
||||
QPushButton * m_menuBtn = nullptr; // Menu button
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
|
||||
SettingsWidget * m_settingsWidget = nullptr; // Settings Widget
|
||||
#endif
|
||||
ContentWidget * m_contentFrame = nullptr; // Content frame
|
||||
SearchBarHLayout * m_searchLayout = nullptr; // Search bar layout
|
||||
SeachBarWidget * m_searchWidget = nullptr; // Search bar
|
||||
|
||||
QStringList m_dirList;
|
||||
|
||||
QQueue<QString> *m_search_result_file = nullptr;
|
||||
QQueue<QString> *m_search_result_dir = nullptr;
|
||||
QQueue<QPair<QString, QStringList>> *m_search_result_content = nullptr;
|
||||
SearchResult * m_search_result_thread = nullptr;
|
||||
SearchAppThread * m_seach_app_thread = nullptr;
|
||||
|
||||
SearchManager* m_searcher = nullptr;
|
||||
SettingsMatch *m_settingsMatch = nullptr;
|
||||
QSystemTrayIcon *m_sys_tray_icon = nullptr;
|
||||
CreateIndexAskDialog * m_askDialog = nullptr;
|
||||
bool m_isAskDialogVisible = false;
|
||||
|
||||
QTimer * m_askTimer = nullptr; //询问是否创建索引弹窗弹出的计时器
|
||||
QTimer * m_researchTimer = nullptr; //创建索引后重新执行一次搜索的计时器
|
||||
bool m_currentSearchAsked = false; //本次搜索是否已经询问过是否创建索引了
|
||||
QGSettings * m_search_gsettings = nullptr;
|
||||
|
||||
SearchMethodManager m_searchMethodManager;
|
||||
|
||||
void setSearchMethod(const bool&);
|
||||
double getTransparentData();
|
||||
void initTimer();
|
||||
bool tryHideMainwindow();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
void initUi();
|
||||
|
||||
Q_SIGNALS:
|
||||
void searchMethodChanged(FileUtils::SearchMethod);
|
||||
void webEngineChanged();
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* @brief Monitor screen resolution
|
||||
* @param rect: Screen resolution
|
||||
*/
|
||||
void monitorResolutionChange(QRect rect);
|
||||
/**
|
||||
* @brief Monitor primary screen changes
|
||||
* @param screen: Primary screen
|
||||
*/
|
||||
void primaryScreenChangedSlot(QScreen *screen);
|
||||
|
||||
void bootOptionsFilter(QString opt); // 过滤终端命令
|
||||
void clearSearchResult(); //清空搜索结果
|
||||
void createIndexSlot();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MAINWINDOW_H
|
|
@ -1,9 +0,0 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/search-item-model.h \
|
||||
$$PWD/search-item.h \
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/search-item-model.cpp \
|
||||
$$PWD/search-item.cpp \
|
|
@ -1,187 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "search-item-model.h"
|
||||
#include <QDebug>
|
||||
|
||||
using namespace Zeeker;
|
||||
SearchItemModel::SearchItemModel(QObject *parent) : QAbstractItemModel(parent) {
|
||||
|
||||
}
|
||||
SearchItemModel::~SearchItemModel() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FileItemModel::index
|
||||
* @param rowa
|
||||
* @param column
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
QModelIndex SearchItemModel::index(int row, int column, const QModelIndex &parent) const {
|
||||
if(row < 0 || row > m_item->m_pathlist.count() - 1)
|
||||
return QModelIndex();
|
||||
return createIndex(row, column, m_item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FileItemModel::parent
|
||||
* @param child
|
||||
* @return
|
||||
*/
|
||||
QModelIndex SearchItemModel::parent(const QModelIndex &child) const {
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::rowCount 重写的model行数函数
|
||||
* @param index 条目的索引
|
||||
* @return model显示的行数
|
||||
*/
|
||||
int SearchItemModel::rowCount(const QModelIndex& index) const {
|
||||
return index.isValid() ? 0 : m_item->m_pathlist.count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::columnCount 重写的model列数函数
|
||||
* @param index 条目的索引
|
||||
* @return model显示的列数
|
||||
*/
|
||||
int SearchItemModel::columnCount(const QModelIndex& index) const {
|
||||
return index.isValid() ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::headerData filemodel::columnCount 重写的model标头函数
|
||||
* @param section 列
|
||||
* @param orientation 显示方式
|
||||
* @param role 显示内容类型
|
||||
* @return 标头数据
|
||||
*/
|
||||
//QVariant SearchItemModel::headerData(int section,Qt::Orientation orientation ,int role) const {
|
||||
// return tr("");
|
||||
//// return QAbstractItemModel::headerData(section, orientation, role);
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::data model每条条目的数据,有显示内容,图片
|
||||
* @param index 条目索引
|
||||
* @param role 显示内容的类型
|
||||
* @return 显示内容数据
|
||||
*/
|
||||
|
||||
using namespace Zeeker;
|
||||
QVariant SearchItemModel::data(const QModelIndex &index, int role) const {
|
||||
if(!index.isValid())
|
||||
return QVariant();
|
||||
switch(role) {
|
||||
case Qt::DecorationRole: {
|
||||
return m_item->getIcon(index.row());
|
||||
}
|
||||
case Qt::DisplayRole: {
|
||||
return QVariant(m_item->getName(index.row()));
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool SearchItemModel::insertRows(int row, int count, const QModelIndex &parent) {
|
||||
this->beginInsertRows(parent, row, count);
|
||||
this->endInsertRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::setItem 传入存储数据的item
|
||||
* @param item
|
||||
*/
|
||||
void SearchItemModel::setItem(SearchItem * item) {
|
||||
m_item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::appendItem
|
||||
*/
|
||||
void SearchItemModel::appendItem(QString path) {
|
||||
this->beginResetModel();
|
||||
m_item->m_pathlist << path;
|
||||
this->endResetModel();
|
||||
// this->insertRow(rowCount(QModelIndex()) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::setList 直接以列表形式添加搜索结果
|
||||
* @param list
|
||||
*/
|
||||
void SearchItemModel::setList(QStringList list) {
|
||||
this->beginResetModel();
|
||||
m_item->m_pathlist = list;
|
||||
this->endResetModel();
|
||||
}
|
||||
|
||||
void SearchItemModel::setAppList(const QStringList &pathlist, const QStringList &iconlist) {
|
||||
this->beginResetModel();
|
||||
m_item->m_app_pathlist = pathlist;
|
||||
m_item->m_app_iconlist = iconlist;
|
||||
this->endResetModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::insertBestItem 向最佳匹配列表添加一项
|
||||
* @param pair <类型,路径或名称>
|
||||
*/
|
||||
void SearchItemModel::appendBestItem(const QPair<int, QString> & pair) {
|
||||
m_item->m_bestList.append(pair);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::removeItem
|
||||
*/
|
||||
void SearchItemModel::removeItem(QString path) {
|
||||
m_item->removeItem(path);
|
||||
}
|
||||
|
||||
void SearchItemModel::clear() {
|
||||
this->beginResetModel();
|
||||
m_item->clear();
|
||||
this->endResetModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItemModel::setBestAppIcon 设置最佳匹配应用的图标
|
||||
* @param str 图标名称或路径,应用安装时为图标名,未安装时为路径
|
||||
* @param is_installed 应用是否已安装
|
||||
*/
|
||||
void SearchItemModel::setBestAppIcon(const QString &str, const bool & is_installed) {
|
||||
if(is_installed) {
|
||||
m_item->m_bestAppIcon = QIcon::fromTheme(str);
|
||||
} else {
|
||||
m_item->m_bestAppIcon = QIcon(str);
|
||||
}
|
||||
}
|
||||
|
||||
int SearchItemModel::length()
|
||||
{
|
||||
return m_item->m_pathlist.length();
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef SEARCHITEMMODEL_H
|
||||
#define SEARCHITEMMODEL_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAbstractItemModel>
|
||||
#include "search-item.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class SearchItem;
|
||||
|
||||
class SearchItemModel : public QAbstractItemModel {
|
||||
friend class SearchItem;
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SearchItemModel(QObject *parent = nullptr);
|
||||
~SearchItemModel();
|
||||
|
||||
enum SearchInfo {
|
||||
Icon,
|
||||
Name
|
||||
};
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &child) const override;
|
||||
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex())override;
|
||||
// QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
void setItem(SearchItem *);
|
||||
|
||||
void appendItem(QString);
|
||||
void setList(QStringList);
|
||||
void setAppList(const QStringList&, const QStringList&);
|
||||
void appendBestItem(const QPair<int, QString>&);
|
||||
void removeItem(QString);
|
||||
void clear();
|
||||
void setBestAppIcon(const QString &, const bool &);
|
||||
int length();
|
||||
|
||||
private :
|
||||
SearchItem * m_item = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SEARCHITEMMODEL_H
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "search-item.h"
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
|
||||
|
||||
using namespace Zeeker;
|
||||
SearchItem::SearchItem(QObject *parent) : QObject(parent) {
|
||||
}
|
||||
|
||||
SearchItem::~SearchItem() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItem::getIcon 获取一个搜索项的图标
|
||||
* @param index 条目索引
|
||||
* @return 图标
|
||||
*/
|
||||
QIcon SearchItem::getIcon(int index) {
|
||||
if(index < 0 || index >= m_pathlist.count())
|
||||
return QIcon("");
|
||||
switch(m_searchtype) {
|
||||
case Settings : //设置项,返回控制面板对应插件的图标
|
||||
return FileUtils::getSettingIcon(m_pathlist.at(index), false);
|
||||
case Contents:
|
||||
case Dirs :
|
||||
case Files : //文件,返回文件图标
|
||||
// return FileUtils::getFileIcon(QString("file://%1").arg(m_pathlist.at(index)));
|
||||
return FileUtils::getFileIcon(QUrl::fromLocalFile(m_pathlist.at(index)).toString());
|
||||
case Apps : {//应用,返回应用图标
|
||||
// return FileUtils::getAppIcon(m_pathlist.at(index));
|
||||
if(m_app_pathlist.length() > index && m_app_pathlist.at(index) == "") { //未安装,存储的是图标路径
|
||||
return QIcon(m_app_iconlist.at(index));
|
||||
} else if(m_app_pathlist.length() > index) { //已安装,存储的是图标名
|
||||
if(QIcon::fromTheme(m_app_iconlist.at(index)).isNull()) {
|
||||
return QIcon(":/res/icons/desktop.png");
|
||||
} else {
|
||||
return QIcon::fromTheme(m_app_iconlist.at(index));
|
||||
}
|
||||
} else {
|
||||
return QIcon(":/res/icons/desktop.png");
|
||||
}
|
||||
}
|
||||
case Best : {//最佳匹配,含全部类型,需要自己判断,返回不同类型的图标
|
||||
return getBestIcon(index);
|
||||
}
|
||||
default:
|
||||
return QIcon(":/res/icons/edit-find-symbolic.svg");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItem::getIcon 获取一个搜索项的名称
|
||||
* @param index 条目索引
|
||||
* @return 名字
|
||||
*/
|
||||
QString SearchItem::getName(int index) {
|
||||
if(index < 0 || index >= m_pathlist.count())
|
||||
return 0;
|
||||
switch(m_searchtype) {
|
||||
case Settings : //设置项,返回功能点名
|
||||
return FileUtils::getSettingName(m_pathlist.at(index));
|
||||
case Contents:
|
||||
case Dirs :
|
||||
case Files : //文件,返回文件名
|
||||
return FileUtils::getFileName(m_pathlist.at(index));
|
||||
case Apps : {//应用,返回应用名
|
||||
QString whole_name = m_pathlist.at(index);
|
||||
QString app_name = whole_name.contains("/") ? whole_name.left(whole_name.indexOf("/")) : whole_name;
|
||||
return app_name;
|
||||
}
|
||||
case Best : //最佳匹配,含全部类型,需要自己判断,返回不同类型的名称
|
||||
return getBestName(index);
|
||||
default:
|
||||
return m_pathlist.at(index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItem::getBestIcon 获取最佳匹配结果的图标
|
||||
* @param index 索引行
|
||||
* @return
|
||||
*/
|
||||
QIcon SearchItem::getBestIcon(const int &index) {
|
||||
// if (m_pathlist.at(index).endsWith(".desktop")) {
|
||||
// return FileUtils::getAppIcon(m_pathlist.at(index));
|
||||
// } else if (QFileInfo(m_pathlist.at(index)).isFile() || QFileInfo(m_pathlist.at(index)).isDir()) {
|
||||
// return FileUtils::getFileIcon(QString("file://%1").arg(m_pathlist.at(index)));
|
||||
// } else {
|
||||
// return FileUtils::getSettingIcon(m_pathlist.at(index), false);
|
||||
// }
|
||||
if(m_bestList.isEmpty() || !m_bestList.length() > index) return QIcon::fromTheme("unknown");
|
||||
switch(m_bestList.at(index).first) {
|
||||
case Apps: {
|
||||
return this->m_bestAppIcon;
|
||||
// return FileUtils::getAppIcon(m_pathlist.at(index));
|
||||
}
|
||||
case Settings: {
|
||||
return FileUtils::getSettingIcon(m_pathlist.at(index), false);
|
||||
}
|
||||
default: {
|
||||
return FileUtils::getFileIcon(QUrl::fromLocalFile(m_pathlist.at(index)).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItem::getBestName 获取最佳匹配结果的名称
|
||||
* @param index 索引行
|
||||
* @return
|
||||
*/
|
||||
QString SearchItem::getBestName(const int &index) {
|
||||
if(m_bestList.isEmpty() || !m_bestList.length() > index) return "";
|
||||
switch(m_bestList.at(index).first) {
|
||||
case Apps: {
|
||||
QString whole_name = m_bestList.at(index).second;
|
||||
QString app_name = whole_name.contains("/") ? whole_name.left(whole_name.indexOf("/")) : whole_name;
|
||||
return app_name;
|
||||
}
|
||||
case Settings: {
|
||||
return FileUtils::getSettingName(m_pathlist.at(index));
|
||||
}
|
||||
default: {
|
||||
return FileUtils::getFileName(m_pathlist.at(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItem::setSearchList 存入搜索结果列表
|
||||
* @param type 搜索类型
|
||||
* @param searchResult 搜索结果
|
||||
*/
|
||||
void SearchItem::setSearchList(const int& type, const QStringList& searchResult) {
|
||||
m_searchtype = type;
|
||||
m_pathlist = searchResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchItem::removeItem
|
||||
*/
|
||||
void SearchItem::removeItem(QString path) {
|
||||
m_pathlist.removeOne(path);
|
||||
}
|
||||
|
||||
int SearchItem::getCurrentSize() {
|
||||
return m_pathlist.length();
|
||||
}
|
||||
|
||||
void SearchItem::clear() {
|
||||
m_pathlist.clear();
|
||||
m_app_pathlist.clear();
|
||||
m_app_iconlist.clear();
|
||||
m_bestList.clear();
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef SEARCHITEM_H
|
||||
#define SEARCHITEM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
#include "search-item-model.h"
|
||||
#include "file-utils.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class SearchItem : public QObject {
|
||||
friend class SearchItemModel;
|
||||
friend class SearchListView;
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SearchItem(QObject *parent = nullptr);
|
||||
~SearchItem();
|
||||
|
||||
enum SearchType {
|
||||
Best,
|
||||
Apps,
|
||||
Settings,
|
||||
Dirs,
|
||||
Files,
|
||||
Contents,
|
||||
Web
|
||||
};
|
||||
|
||||
void setSearchList(const int&, const QStringList&);
|
||||
void removeItem(QString);
|
||||
int getCurrentSize();
|
||||
void clear();
|
||||
|
||||
private:
|
||||
// SearchItem * m_parent = nullptr;
|
||||
// QVector<SearchItem*> * m_children = nullptr;
|
||||
|
||||
int m_searchtype = 0;
|
||||
QStringList m_pathlist;
|
||||
QStringList m_app_pathlist;
|
||||
QStringList m_app_iconlist;
|
||||
QList<QPair<int, QString>> m_bestList;
|
||||
|
||||
QIcon m_bestAppIcon = QIcon::fromTheme("unknown"); //由于未安装应用与已安装应用获取图标方式不一致,故引入此变量直接存储最佳匹配应用图标
|
||||
|
||||
QIcon getIcon(int);
|
||||
QString getName(int);
|
||||
QIcon getBestIcon(const int &);
|
||||
QString getBestName(const int &);
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SEARCHITEM_H
|
|
@ -1 +0,0 @@
|
|||
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{opacity:0.85;}</style></defs><title>close</title><path class="cls-1" d="M8.71,8l5.14-5.15a.49.49,0,0,0-.7-.7L8,7.29,2.85,2.15a.49.49,0,0,0-.7.7L7.29,8,2.15,13.15a.48.48,0,0,0,0,.7.48.48,0,0,0,.7,0L8,8.71l5.15,5.14a.48.48,0,0,0,.7,0,.48.48,0,0,0,0-.7Z"/></svg>
|
Before Width: | Height: | Size: 374 B |
Binary file not shown.
Before Width: | Height: | Size: 998 B |
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>edit-find-symbolic</title>
|
||||
<g id="Icon" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Icon-Sets" transform="translate(-68.000000, -2529.000000)" fill-rule="nonzero">
|
||||
<g id="编组-9" transform="translate(0.000000, 2399.000000)">
|
||||
<g id="编组" transform="translate(68.000000, 130.000000)">
|
||||
<polygon id="矩形备份" fill="#000000" opacity="0" points="0 0 16 0 16 16 0 16"/>
|
||||
<path d="M6.86630772,1 C8.48762671,1 9.95614366,1.64816049 11.0189488,2.69780957 C12.0771269,3.74288891 12.7327736,5.18634211 12.7327736,6.78146875 C12.7327736,8.28192337 12.1523076,9.64806734 11.2023613,10.6749557 L11.2023613,10.6749557 L14.9869478,14.4127374 L10.6532367,11.3057557 C9.58274699,12.0665702 8.28388099,12.5629531 6.86630772,12.5629531 C5.2449219,12.5629531 3.77647181,11.9148388 2.71373977,10.8652353 C1.65557494,9.82014255 1,8.37664384 1,6.78146875 C1,5.18630217 1.65557811,3.74280894 2.71374274,2.69771882 C3.77647668,1.64811584 5.24492743,1 6.86630772,1 Z" id="路径" stroke="#2FB3E8" stroke-width="2"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.3 KiB |
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="98px" height="87px" viewBox="0 0 98 87" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 59 (86127) - https://sketch.com -->
|
||||
<title>image-viewer-app-symbolic</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<filter x="-2.4%" y="-2.7%" width="104.7%" height="105.3%" filterUnits="objectBoundingBox" id="filter-1">
|
||||
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
|
||||
<feMerge>
|
||||
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
|
||||
<feMergeNode in="SourceGraphic"></feMergeNode>
|
||||
</feMerge>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="综合搜索" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.200000003">
|
||||
<g id="搜索结果——网页" transform="translate(-883.000000, -627.000000)">
|
||||
<g id="编组-2" filter="url(#filter-1)" transform="translate(447.000000, 427.000000)">
|
||||
<g id="image-viewer-app-symbolic" transform="translate(436.000000, 200.000000)">
|
||||
<g id="图层_2" transform="translate(4.000000, 5.000000)">
|
||||
<path d="M24,72 L12,72 C5.4,72 0,66.6 0,60 L0,12 C0,5.4 5.4,0 12,0 L78,0 C84.6,0 90,5.4 90,12 L90,60" id="路径" stroke="#1F2022" stroke-width="6" stroke-linecap="round"></path>
|
||||
<path d="M51,15 C34.2,15 21,28.2 21,45 C21,61.8 34.2,75 51,75 C67.8,75 81,61.8 81,45 C81,28.2 67.8,15 51,15 Z M51,21 C64.2,21 75,31.8 75,45 C75,58.2 64.2,69 51,69 C37.8,69 27,58.2 27,45 C27,31.8 37.8,21 51,21 Z" id="circle2567-9" fill="#1F2022" fill-rule="nonzero"></path>
|
||||
<path d="M71.4,60.6 L67.2,64.8 L80.1,77.7 C81.259798,78.859798 83.140202,78.859798 84.3,77.7 C85.459798,76.540202 85.459798,74.659798 84.3,73.5 L71.4,60.6 L71.4,60.6 Z" id="path2570-36" fill="#1F2022"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 498 B |
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
|
@ -1,10 +0,0 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>res/icons/edit-find-symbolic.svg</file>
|
||||
<file>res/icons/desktop.png</file>
|
||||
<file>res/icons/close.svg</file>
|
||||
<file>res/qt-translations/qt_zh_CN.qm</file>
|
||||
<file>res/icons/net-disconnected.svg</file>
|
||||
<file>res/icons/system-search.symbolic.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -1,88 +0,0 @@
|
|||
#include "search-app-thread.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
size_t uniqueSymbol = 0;
|
||||
QMutex m_mutex;
|
||||
|
||||
SearchAppThread::SearchAppThread(QObject *parent) : QObject(parent) {
|
||||
m_pool.setMaxThreadCount(2);
|
||||
m_pool.setExpiryTimeout(1000);
|
||||
}
|
||||
|
||||
void SearchAppThread::startSearch(const QString & keyword) {
|
||||
m_mutex.lock();
|
||||
++uniqueSymbol;
|
||||
m_mutex.unlock();
|
||||
SearchApp *appsearch;
|
||||
appsearch = new SearchApp(keyword,uniqueSymbol,this);
|
||||
// appsearch->setKeyword(keyword);
|
||||
// connect(appsearch, &SearchApp::searchResultApp, this, &SearchAppThread::searchResultApp);
|
||||
m_pool.start(appsearch);
|
||||
}
|
||||
|
||||
void SearchAppThread::sendResult(const QVector<QStringList> result)
|
||||
{
|
||||
Q_EMIT this->searchResultApp(result);
|
||||
}
|
||||
|
||||
|
||||
SearchApp::SearchApp(const QString& keyword, size_t uniqueSymbol, QObject * parent) : QObject(parent) {
|
||||
this->setAutoDelete(true);
|
||||
m_searchappThread = qobject_cast<SearchAppThread *>(parent);
|
||||
m_keyword = keyword;
|
||||
m_uniqueSymbol = uniqueSymbol;
|
||||
}
|
||||
|
||||
SearchApp::~SearchApp() {
|
||||
}
|
||||
|
||||
///**
|
||||
// * @brief SearchAppThread::startSearch 激活线程
|
||||
// * @param keyword 关键词
|
||||
// */
|
||||
//void SearchApp::setKeyword(const QString & keyword)
|
||||
//{
|
||||
// m_keyword = keyword;
|
||||
//}
|
||||
|
||||
void SearchApp::run() {
|
||||
//nameList:应用名,pathList:已安装的是.desktop路径,未安装为空,iconList:已安装的是图标名,未安装的是图标路径
|
||||
QStringList nameList, pathList, iconList, descList;
|
||||
QVector<QStringList> appVector;
|
||||
AppMatch::getAppMatch()->startMatchApp(m_keyword, m_installed_apps, m_uninstalled_apps);
|
||||
QMapIterator<NameString, QStringList> installed_iter(m_installed_apps);
|
||||
while(installed_iter.hasNext()) {
|
||||
installed_iter.next();
|
||||
nameList << installed_iter.key().app_name;
|
||||
pathList << installed_iter.value().at(0);
|
||||
iconList << installed_iter.value().at(1);
|
||||
descList << installed_iter.value().at(3);
|
||||
}
|
||||
QMapIterator<NameString, QStringList> uninstalled_iter(m_uninstalled_apps);
|
||||
while(uninstalled_iter.hasNext()) {
|
||||
uninstalled_iter.next();
|
||||
QString name;
|
||||
//当返回列表的value中含包名时,将名称按“应用名/包名”的格式存储
|
||||
if(!uninstalled_iter.value().at(2).isEmpty() && uninstalled_iter.value().at(2) != "") {
|
||||
name = uninstalled_iter.key().app_name + "/" + uninstalled_iter.value().at(2);
|
||||
} else name = uninstalled_iter.key().app_name;
|
||||
nameList << name;
|
||||
pathList << uninstalled_iter.value().at(0);
|
||||
iconList << uninstalled_iter.value().at(1);
|
||||
descList << uninstalled_iter.value().at(3);
|
||||
}
|
||||
appVector.append(nameList);
|
||||
appVector.append(pathList);
|
||||
appVector.append(iconList);
|
||||
appVector.append(descList);
|
||||
m_mutex.lock();
|
||||
if (m_uniqueSymbol == uniqueSymbol) {
|
||||
QMetaObject::invokeMethod(m_searchappThread, "sendResult", Q_ARG(const QVector<QStringList>, appVector));
|
||||
// Q_EMIT this->searchResultApp(appVector);
|
||||
}
|
||||
m_mutex.unlock();
|
||||
m_installed_apps.clear();
|
||||
m_uninstalled_apps.clear();
|
||||
}
|
||||
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
#ifndef SEARCHAPPTHREAD_H
|
||||
#define SEARCHAPPTHREAD_H
|
||||
#include <QThread>
|
||||
#include <QObject>
|
||||
#include <QRunnable>
|
||||
#include "libsearch.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class SearchAppThread : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SearchAppThread(QObject * parent = nullptr);
|
||||
~SearchAppThread() = default;
|
||||
void startSearch(const QString&);
|
||||
Q_INVOKABLE void sendResult(const QVector<QStringList> result);
|
||||
private:
|
||||
QThreadPool m_pool;
|
||||
Q_SIGNALS:
|
||||
void searchResultApp(const QVector<QStringList>);
|
||||
};
|
||||
|
||||
|
||||
class SearchApp : public QObject, public QRunnable {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SearchApp(const QString& keyword, size_t uniqueSymbol, QObject * parent = nullptr);
|
||||
~SearchApp();
|
||||
// void setKeyword(const QString&);
|
||||
protected:
|
||||
void run() override;
|
||||
private:
|
||||
SearchAppThread *m_searchappThread = nullptr;
|
||||
QString m_keyword;
|
||||
size_t m_uniqueSymbol;
|
||||
QMap<NameString, QStringList> m_installed_apps;
|
||||
QMap<NameString, QStringList> m_uninstalled_apps;
|
||||
//Q_SIGNALS:
|
||||
// void searchResultApp(const QVector<QStringList>&);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SEARCHAPPTHREAD_H
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "search-result.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
SearchResult::SearchResult(QObject * parent) : QThread(parent) {
|
||||
m_mainwindow = static_cast<MainWindow *>(parent);
|
||||
// m_timer = new QTimer;
|
||||
// QObject::connect(m_timer, &QTimer::timeout, this, [ = ](){
|
||||
// qWarning()<<"-------------------------------------------------------";
|
||||
// m_timer->stop();
|
||||
// this->requestInterruption();
|
||||
// });
|
||||
}
|
||||
|
||||
SearchResult::~SearchResult() {
|
||||
// if (m_timer) {
|
||||
// delete m_timer;
|
||||
// m_timer = NULL;
|
||||
// }
|
||||
}
|
||||
|
||||
void SearchResult::run() {
|
||||
QTimer * m_timer = new QTimer;
|
||||
m_timer->setInterval(3000);
|
||||
int emptyLists = 0;
|
||||
while(!isInterruptionRequested()) {
|
||||
emptyLists = 0;
|
||||
m_mainwindow->m_searcher->m_mutexFile.lock();
|
||||
if(!m_mainwindow->m_search_result_file->isEmpty()) {
|
||||
Q_EMIT this->searchResultFile(m_mainwindow->m_search_result_file->dequeue());
|
||||
m_mainwindow->m_searcher->m_mutexFile.unlock();
|
||||
} else {
|
||||
emptyLists ++;
|
||||
m_mainwindow->m_searcher->m_mutexFile.unlock();
|
||||
}
|
||||
m_mainwindow->m_searcher->m_mutexDir.lock();
|
||||
if(!m_mainwindow->m_search_result_dir->isEmpty()) {
|
||||
Q_EMIT this->searchResultDir(m_mainwindow->m_search_result_dir->dequeue());
|
||||
m_mainwindow->m_searcher->m_mutexDir.unlock();
|
||||
} else {
|
||||
emptyLists ++;
|
||||
m_mainwindow->m_searcher->m_mutexDir.unlock();
|
||||
}
|
||||
m_mainwindow->m_searcher->m_mutexContent.lock();
|
||||
// if (!m_mainwindow->m_search_result_content->isEmpty())
|
||||
// qDebug() << m_mainwindow->m_search_result_content->head();
|
||||
if(!m_mainwindow->m_search_result_content->isEmpty()) {
|
||||
Q_EMIT this->searchResultContent(m_mainwindow->m_search_result_content->dequeue());
|
||||
m_mainwindow->m_searcher->m_mutexContent.unlock();
|
||||
} else {
|
||||
emptyLists ++;
|
||||
m_mainwindow->m_searcher->m_mutexContent.unlock();
|
||||
}
|
||||
if(m_timer->isActive() && m_timer->remainingTime() < 0.01) {
|
||||
this->requestInterruption();
|
||||
}
|
||||
if(emptyLists == 3 && !m_timer->isActive()) {
|
||||
m_timer->start();
|
||||
} else if(emptyLists != 3) {
|
||||
m_timer->stop();
|
||||
} else {
|
||||
msleep(100);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef SEARCHRESULT_H
|
||||
#define SEARCHRESULT_H
|
||||
#include <QThread>
|
||||
#include <QWaitCondition>
|
||||
#include <QTimer>
|
||||
#include "mainwindow.h"
|
||||
|
||||
namespace Zeeker {
|
||||
class SearchResult : public QThread {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SearchResult(QObject * parent = nullptr);
|
||||
~SearchResult();
|
||||
protected:
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
MainWindow * m_mainwindow = nullptr;
|
||||
// QTimer * m_timer = nullptr;
|
||||
|
||||
Q_SIGNALS:
|
||||
void searchResultFile(const QString&);
|
||||
void searchResultDir(const QString&);
|
||||
// void searchResultContent(const QString&, const QStringList&);
|
||||
void searchResultContent(const QPair<QString, QStringList>);
|
||||
|
||||
};
|
||||
}
|
||||
#endif // SEARCHRESULT_H
|
|
@ -1,535 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#include "settings-widget.h"
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QFileDialog>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include "folder-list-item.h"
|
||||
#include "global-settings.h"
|
||||
#include "file-utils.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);
|
||||
SettingsWidget::SettingsWidget(QWidget *parent) : QWidget(parent) {
|
||||
// this->setWindowIcon(QIcon::fromTheme("kylin-search"));
|
||||
this->setWindowTitle(tr("ukui-search-settings"));
|
||||
// this->setWindowFlags(Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
|
||||
// this->setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
m_hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS;
|
||||
m_hints.functions = MWM_FUNC_ALL;
|
||||
m_hints.decorations = MWM_DECOR_BORDER;
|
||||
XAtomHelper::getInstance()->setWindowMotifHint(winId(), m_hints);
|
||||
#endif
|
||||
|
||||
initUi();
|
||||
refreshIndexState();
|
||||
setupBlackList(GlobalSettings::getInstance()->getBlockDirs());
|
||||
resetWebEngine();
|
||||
}
|
||||
|
||||
SettingsWidget::~SettingsWidget() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::initUi 初始化界面UI
|
||||
*/
|
||||
void SettingsWidget::initUi() {
|
||||
QPalette pal = palette();
|
||||
pal.setColor(QPalette::Window, QColor(0, 0, 0, 0));
|
||||
// this->setFixedWidth(528);
|
||||
// this->setMinimumHeight(460);
|
||||
// this->setMaximumHeight(680);
|
||||
m_mainLyt = new QVBoxLayout(this);
|
||||
m_mainLyt->setContentsMargins(16, 8, 16, 24);
|
||||
this->setLayout(m_mainLyt);
|
||||
|
||||
//标题栏
|
||||
m_titleFrame = new QFrame(this);
|
||||
m_titleFrame->setFixedHeight(40);
|
||||
m_titleLyt = new QHBoxLayout(m_titleFrame);
|
||||
m_titleLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_titleFrame->setLayout(m_titleLyt);
|
||||
m_titleIcon = new QLabel(m_titleFrame);
|
||||
m_titleIcon->setPixmap(QIcon::fromTheme("kylin-search").pixmap(QSize(24, 24)));
|
||||
//主题改变时,更新自定义标题栏的图标
|
||||
connect(qApp, &QApplication::paletteChanged, this, [ = ]() {
|
||||
m_titleIcon->setPixmap(QIcon::fromTheme("kylin-search").pixmap(QSize(24, 24)));
|
||||
});
|
||||
m_titleLabel = new QLabel(m_titleFrame);
|
||||
m_titleLabel->setText(tr("Search"));
|
||||
m_closeBtn = new QPushButton(m_titleFrame);
|
||||
m_closeBtn->setFixedSize(24, 24);
|
||||
// m_closeBtn->setIcon(QIcon(":/res/icons/close.svg"));
|
||||
m_closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic"));
|
||||
m_closeBtn->setProperty("isWindowButton", 0x02);
|
||||
m_closeBtn->setProperty("useIconHighlightEffect", 0x08);
|
||||
m_closeBtn->setFlat(true);
|
||||
connect(m_closeBtn, &QPushButton::clicked, this, [ = ]() {
|
||||
Q_EMIT this->settingWidgetClosed();
|
||||
m_timer->stop();
|
||||
this->close();
|
||||
});
|
||||
m_titleLyt->addWidget(m_titleIcon);
|
||||
m_titleLyt->addWidget(m_titleLabel);
|
||||
m_titleLyt->addStretch();
|
||||
m_titleLyt->addWidget(m_closeBtn);
|
||||
m_mainLyt->addWidget(m_titleFrame);
|
||||
|
||||
m_contentFrame = new QFrame(this);
|
||||
m_contentLyt = new QVBoxLayout(m_contentFrame);
|
||||
m_contentFrame->setLayout(m_contentLyt);
|
||||
m_contentLyt->setContentsMargins(8, 0, 8, 0);
|
||||
m_mainLyt->addWidget(m_contentFrame);
|
||||
|
||||
//设置
|
||||
m_settingLabel = new QLabel(m_contentFrame);
|
||||
m_settingLabel->setText(tr("<h2>Settings</h2>"));
|
||||
m_contentLyt->addWidget(m_settingLabel);
|
||||
|
||||
//文件索引
|
||||
m_indexTitleLabel = new QLabel(m_contentFrame);
|
||||
m_indexTitleLabel->setText(tr("<h3>Index State</h3>"));
|
||||
m_indexStateLabel = new QLabel(m_contentFrame);
|
||||
m_indexStateLabel->setText(tr("..."));
|
||||
m_indexNumLabel = new QLabel(m_contentFrame);
|
||||
m_indexNumLabel->setText(tr("..."));
|
||||
m_contentLyt->addWidget(m_indexTitleLabel);
|
||||
m_contentLyt->addWidget(m_indexStateLabel);
|
||||
// m_mainLyt->addWidget(m_indexNumLabel);
|
||||
m_indexNumLabel->hide();
|
||||
|
||||
//文件索引设置(黑名单)
|
||||
m_indexSettingLabel = new QLabel(m_contentFrame);
|
||||
m_indexSettingLabel->setText(tr("<h3>File Index Settings</h3>"));
|
||||
m_indexDescLabel = new QLabel(m_contentFrame);
|
||||
m_indexDescLabel->setText(tr("Following folders will not be searched. You can set it by adding and removing folders."));
|
||||
m_indexDescLabel->setWordWrap(true);
|
||||
m_indexBtnFrame = new QFrame(m_contentFrame);
|
||||
m_indexBtnLyt = new QHBoxLayout(m_indexBtnFrame);
|
||||
m_indexBtnLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_indexBtnFrame->setLayout(m_indexBtnLyt);
|
||||
m_addDirBtn = new QPushButton(m_indexBtnFrame);
|
||||
m_addDirBtn->setFixedHeight(32);
|
||||
m_addDirBtn->setMinimumWidth(164);
|
||||
m_addDirBtn->setText(tr("Add ignored folders"));
|
||||
connect(m_addDirBtn, &QPushButton::clicked, this, &SettingsWidget::onBtnAddClicked);
|
||||
m_indexBtnLyt->addWidget(m_addDirBtn);
|
||||
m_indexBtnLyt->addStretch();
|
||||
m_dirListArea = new QScrollArea(m_contentFrame);
|
||||
m_dirListArea->setPalette(pal);
|
||||
m_dirListArea->setFrameShape(QFrame::Shape::NoFrame);
|
||||
m_dirListWidget = new QWidget(m_contentFrame);
|
||||
m_dirListLyt = new QVBoxLayout(m_dirListWidget);
|
||||
m_dirListLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_dirListLyt->setSpacing(0);
|
||||
m_dirListWidget->setLayout(m_dirListLyt);
|
||||
m_dirListArea->setWidget(m_dirListWidget);
|
||||
m_dirListArea->setWidgetResizable(m_contentFrame);
|
||||
m_contentLyt->addWidget(m_indexSettingLabel);
|
||||
m_contentLyt->addWidget(m_indexDescLabel);
|
||||
m_contentLyt->addWidget(m_indexBtnFrame);
|
||||
m_contentLyt->addWidget(m_dirListArea);
|
||||
|
||||
//搜索引擎设置
|
||||
m_searchEngineLabel = new QLabel(m_contentFrame);
|
||||
m_searchEngineLabel->setText(tr("<h3>Search Engine Settings</h3>"));
|
||||
m_engineDescLabel = new QLabel(m_contentFrame);
|
||||
m_engineDescLabel->setText(tr("Please select search engine you preferred."));
|
||||
m_engineDescLabel->setWordWrap(true);
|
||||
m_engineBtnGroup = new QButtonGroup(m_contentFrame);
|
||||
m_baiduBtn = new QRadioButton(m_contentFrame);
|
||||
m_sougouBtn = new QRadioButton(m_contentFrame);
|
||||
m_360Btn = new QRadioButton(m_contentFrame);
|
||||
m_baiduBtn->setFixedSize(16, 16);
|
||||
m_sougouBtn->setFixedSize(16, 16);
|
||||
m_360Btn->setFixedSize(16, 16);
|
||||
m_radioBtnFrame = new QFrame(m_contentFrame);
|
||||
m_radioBtnLyt = new QHBoxLayout(m_radioBtnFrame);
|
||||
m_radioBtnFrame->setLayout(m_radioBtnLyt);
|
||||
m_baiduLabel = new QLabel();
|
||||
m_baiduLabel->setText(tr("baidu"));
|
||||
m_sougouLabel = new QLabel();
|
||||
m_sougouLabel->setText(tr("sougou"));
|
||||
m_360Label = new QLabel();
|
||||
m_360Label->setText(tr("360"));
|
||||
m_radioBtnLyt->setContentsMargins(0, 0, 0, 0);
|
||||
m_radioBtnLyt->addWidget(m_baiduBtn);
|
||||
m_radioBtnLyt->addWidget(m_baiduLabel);
|
||||
m_radioBtnLyt->addWidget(m_sougouBtn);
|
||||
m_radioBtnLyt->addWidget(m_sougouLabel);
|
||||
m_radioBtnLyt->addWidget(m_360Btn);
|
||||
m_radioBtnLyt->addWidget(m_360Label);
|
||||
m_radioBtnLyt->addStretch();
|
||||
m_engineBtnGroup->setExclusive(true);
|
||||
m_engineBtnGroup->addButton(m_baiduBtn);
|
||||
m_engineBtnGroup->addButton(m_sougouBtn);
|
||||
m_engineBtnGroup->addButton(m_360Btn);
|
||||
// m_engineBtnGroup->setId(m_baiduBtn, WebEngine::Baidu);
|
||||
// m_engineBtnGroup->setId(m_sougouBtn, WebEngine::Sougou);
|
||||
// m_engineBtnGroup->setId(m_360Btn, WebEngine::_360);
|
||||
// connect(m_engineBtnGroup, QOverload<int>::of(&QButtonGroup::buttonClicked), [ = ] (int id) {
|
||||
// setWebEngine(id);
|
||||
// });
|
||||
connect(m_baiduBtn, &QRadioButton::clicked, [ = ](bool checked) {
|
||||
if(checked) setWebEngine("baidu");
|
||||
});
|
||||
connect(m_sougouBtn, &QRadioButton::clicked, [ = ](bool checked) {
|
||||
if(checked) setWebEngine("sougou");
|
||||
});
|
||||
connect(m_360Btn, &QRadioButton::clicked, [ = ](bool checked) {
|
||||
if(checked) setWebEngine("360");
|
||||
});
|
||||
|
||||
m_contentLyt->addWidget(m_searchEngineLabel);
|
||||
m_contentLyt->addWidget(m_engineDescLabel);
|
||||
m_contentLyt->addWidget(m_radioBtnFrame);
|
||||
|
||||
//取消与确认按钮 (隐藏)
|
||||
// m_bottomBtnFrame = new QFrame(this);
|
||||
// m_bottomBtnLyt = new QHBoxLayout(m_bottomBtnFrame);
|
||||
// m_bottomBtnFrame->setLayout(m_bottomBtnLyt);
|
||||
// m_bottomBtnLyt->setSpacing(20);
|
||||
// m_cancelBtn = new QPushButton(m_bottomBtnFrame);
|
||||
// m_cancelBtn->setText(tr("Cancel"));
|
||||
// m_cancelBtn->setFixedSize(80, 32);
|
||||
// connect(m_cancelBtn, &QPushButton::clicked, this, &SettingsWidget::onBtnCancelClicked);
|
||||
// m_confirmBtn = new QPushButton(m_bottomBtnFrame);
|
||||
// m_confirmBtn->setText(tr("Confirm"));
|
||||
// m_confirmBtn->setFixedSize(80, 32);
|
||||
// connect(m_confirmBtn, &QPushButton::clicked, this, &SettingsWidget::onBtnConfirmClicked);
|
||||
// m_bottomBtnLyt->addStretch();
|
||||
// m_bottomBtnLyt->addWidget(m_cancelBtn);
|
||||
// m_bottomBtnLyt->addWidget(m_confirmBtn);
|
||||
// m_mainLyt->addWidget(m_bottomBtnFrame);
|
||||
|
||||
m_contentLyt->addStretch();
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(5, 12, 0))
|
||||
this->m_titleFrame->hide();
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::setupBlackList 创建黑名单列表
|
||||
* @param list 文件夹路径列表
|
||||
*/
|
||||
void SettingsWidget::setupBlackList(const QStringList& list) {
|
||||
clearLayout(m_dirListLyt);
|
||||
m_blockdirs = 0;
|
||||
Q_FOREACH(QString path, list) {
|
||||
FolderListItem * item = new FolderListItem(m_dirListWidget, path);
|
||||
m_dirListLyt->addWidget(item);
|
||||
item->setMaximumWidth(this->width() - 52);
|
||||
connect(item, &FolderListItem::onDelBtnClicked, this, &SettingsWidget::onBtnDelClicked);
|
||||
m_blockdirs ++;
|
||||
}
|
||||
this->resize();
|
||||
m_dirListWidget->setFixedWidth(this->width() - 68);
|
||||
// m_dirListLyt->addStretch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::clearLayout 清空某个布局
|
||||
* @param layout 需要清空的布局
|
||||
*/
|
||||
void SettingsWidget::clearLayout(QLayout * layout) {
|
||||
if(! layout) return;
|
||||
QLayoutItem * child;
|
||||
while((child = layout->takeAt(0)) != 0) {
|
||||
if(child->widget()) {
|
||||
child->widget()->setParent(NULL);
|
||||
}
|
||||
delete child;
|
||||
}
|
||||
child = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::refreshIndexState 定时刷新索引项
|
||||
*/
|
||||
void SettingsWidget::refreshIndexState() {
|
||||
// qDebug()<<"FileUtils::indexStatus: "<<FileUtils::indexStatus;
|
||||
if(FileUtils::indexStatus != 0) {
|
||||
this->setIndexState(true);
|
||||
} else {
|
||||
this->setIndexState(false);
|
||||
}
|
||||
m_indexNumLabel->setText(QString("%1/%2").arg(QString::number(SearchManager::getCurrentIndexCount())).arg(QString::number(FileUtils::_max_index_count)));
|
||||
m_timer = new QTimer;
|
||||
connect(m_timer, &QTimer::timeout, this, [ = ]() {
|
||||
qDebug() << "FileUtils::indexStatus: " << FileUtils::indexStatus;
|
||||
if(FileUtils::indexStatus != 0) {
|
||||
this->setIndexState(true);
|
||||
} else {
|
||||
this->setIndexState(false);
|
||||
}
|
||||
m_indexNumLabel->setText(QString("%1/%2").arg(QString::number(SearchManager::getCurrentIndexCount())).arg(QString::number(FileUtils::_max_index_count)));
|
||||
});
|
||||
m_timer->start(0.5 * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::onBtnDelClicked 删除黑名单中的目录
|
||||
* @param path 文件夹路径
|
||||
*/
|
||||
void SettingsWidget::onBtnDelClicked(const QString& path) {
|
||||
QMessageBox message(QMessageBox::Question, tr("Search"), tr("Whether to delete this directory?"));
|
||||
QPushButton * buttonYes = message.addButton(tr("Yes"), QMessageBox::YesRole);
|
||||
message.addButton(tr("No"), QMessageBox::NoRole);
|
||||
message.exec();
|
||||
if(message.clickedButton() != buttonYes) {
|
||||
return;
|
||||
}
|
||||
|
||||
int returnCode = 0;
|
||||
if(GlobalSettings::getInstance()->setBlockDirs(path, returnCode, true)) {
|
||||
qDebug() << "Remove block dir in onBtnDelClicked() successed.";
|
||||
Q_FOREACH(FolderListItem * item, m_dirListWidget->findChildren<FolderListItem*>()) {
|
||||
if(item->getPath() == path) {
|
||||
item->deleteLater();
|
||||
item = NULL;
|
||||
m_blockdirs --;
|
||||
this->resize();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
showWarningDialog(returnCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::resetWebEngine 获取当前的搜索引擎并反映在UI控件上
|
||||
*/
|
||||
void SettingsWidget::resetWebEngine() {
|
||||
QString engine = GlobalSettings::getInstance()->getValue(WEB_ENGINE).toString();
|
||||
m_engineBtnGroup->blockSignals(true);
|
||||
if(!engine.isEmpty()) {
|
||||
if(engine == "360") {
|
||||
m_360Btn->setChecked(true);
|
||||
} else if(engine == "sougou") {
|
||||
m_sougouBtn->setChecked(true);
|
||||
} else {
|
||||
m_baiduBtn->setChecked(true);
|
||||
}
|
||||
} else {
|
||||
m_baiduBtn->setChecked(true);
|
||||
}
|
||||
m_engineBtnGroup->blockSignals(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::setWebEngine
|
||||
* @param engine 选择的搜索引擎
|
||||
*/
|
||||
void SettingsWidget::setWebEngine(const QString& engine) {
|
||||
// GlobalSettings::getInstance()->setValue(WEB_ENGINE, engine);
|
||||
Q_EMIT this->webEngineChanged(engine);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setIndexState 设置当前索引状态
|
||||
* @param isCreatingIndex 是否正在创建索引
|
||||
*/
|
||||
void SettingsWidget::setIndexState(bool isCreatingIndex) {
|
||||
if(isCreatingIndex) {
|
||||
m_indexStateLabel->setText(tr("Creating ..."));
|
||||
return;
|
||||
}
|
||||
m_indexStateLabel->setText(tr("Done"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::setIndexNum 设置当前索引项数量
|
||||
* @param num 索引项数量
|
||||
*/
|
||||
void SettingsWidget::setIndexNum(int num) {
|
||||
m_indexNumLabel->setText(QString(tr("Index Entry: %1")).arg(QString::number(num)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::showWidget 显示此窗口
|
||||
*/
|
||||
void SettingsWidget::showWidget() {
|
||||
Qt::WindowFlags flags = this->windowFlags();
|
||||
flags |= Qt::WindowStaysOnTopHint;
|
||||
this->setWindowFlags(flags);
|
||||
flags &= ~Qt::WindowStaysOnTopHint;
|
||||
this->setWindowFlags(flags);
|
||||
m_timer->start();
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
XAtomHelper::getInstance()->setWindowMotifHint(winId(), m_hints);
|
||||
#endif
|
||||
this->show();
|
||||
}
|
||||
|
||||
///**
|
||||
// * @brief SettingsWidget::onBtnConfirmClicked 点击确认按钮的槽函数
|
||||
// */
|
||||
//void SettingsWidget::onBtnConfirmClicked() {
|
||||
// Q_EMIT this->settingWidgetClosed();
|
||||
// m_timer->stop();
|
||||
// this->close();
|
||||
//}
|
||||
|
||||
///**
|
||||
// * @brief SettingsWidget::onBtnCancelClicked 点击取消按钮的槽函数
|
||||
// */
|
||||
//void SettingsWidget::onBtnCancelClicked() {
|
||||
// Q_EMIT this->settingWidgetClosed();
|
||||
// m_timer->stop();
|
||||
// this->close();
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::onBtnAddClicked 点击添加黑名单按钮的槽函数
|
||||
*/
|
||||
void SettingsWidget::onBtnAddClicked() {
|
||||
QFileDialog * fileDialog = new QFileDialog(this);
|
||||
// fileDialog->setFileMode(QFileDialog::Directory); //允许查看文件和文件夹,但只允许选择文件夹
|
||||
fileDialog->setFileMode(QFileDialog::DirectoryOnly); //只允许查看文件夹
|
||||
// fileDialog->setViewMode(QFileDialog::Detail);
|
||||
fileDialog->setDirectory(QDir::homePath());
|
||||
fileDialog->setNameFilter(tr("Directories"));
|
||||
fileDialog->setWindowTitle(tr("select blocked folder"));
|
||||
fileDialog->setLabelText(QFileDialog::Accept, tr("Select"));
|
||||
fileDialog->setLabelText(QFileDialog::LookIn, tr("Position: "));
|
||||
fileDialog->setLabelText(QFileDialog::FileName, tr("FileName: "));
|
||||
fileDialog->setLabelText(QFileDialog::FileType, tr("FileType: "));
|
||||
fileDialog->setLabelText(QFileDialog::Reject, tr("Cancel"));
|
||||
if(fileDialog->exec() != QDialog::Accepted) {
|
||||
fileDialog->deleteLater();
|
||||
return;
|
||||
}
|
||||
QString selectedDir = 0;
|
||||
int returnCode;
|
||||
selectedDir = fileDialog->selectedFiles().first();
|
||||
qDebug() << "Selected a folder in onBtnAddClicked(): " << selectedDir << ". ->settings-widget.cpp #238";
|
||||
if(GlobalSettings::getInstance()->setBlockDirs(selectedDir, returnCode)) {
|
||||
setupBlackList(GlobalSettings::getInstance()->getBlockDirs());
|
||||
qDebug() << "Add block dir in onBtnAddClicked() successed. ->settings-widget.cpp #238";
|
||||
} else {
|
||||
showWarningDialog(returnCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::paintEvent 绘制弹窗阴影
|
||||
* @param event
|
||||
*/
|
||||
void SettingsWidget::paintEvent(QPaintEvent *event) {
|
||||
Q_UNUSED(event)
|
||||
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
QPainterPath rectPath;
|
||||
// rectPath.addRoundedRect(this->rect(), 6, 6);
|
||||
rectPath.addRect(this->rect());
|
||||
|
||||
// // 画一个黑底
|
||||
// QPixmap pixmap(this->rect().size());
|
||||
// pixmap.fill(Qt::transparent);
|
||||
// QPainter pixmapPainter(&pixmap);
|
||||
// pixmapPainter.setRenderHint(QPainter::Antialiasing);
|
||||
// pixmapPainter.setPen(Qt::transparent);
|
||||
// pixmapPainter.setBrush(Qt::black);
|
||||
// pixmapPainter.setOpacity(0.65);
|
||||
// pixmapPainter.drawPath(rectPath);
|
||||
// pixmapPainter.end();
|
||||
|
||||
// // 模糊这个黑底
|
||||
// QImage img = pixmap.toImage();
|
||||
// qt_blurImage(img, 10, false, false);
|
||||
|
||||
// // 挖掉中心
|
||||
// pixmap = QPixmap::fromImage(img);
|
||||
// QPainter pixmapPainter2(&pixmap);
|
||||
// pixmapPainter2.setRenderHint(QPainter::Antialiasing);
|
||||
// pixmapPainter2.setCompositionMode(QPainter::CompositionMode_Clear);
|
||||
// pixmapPainter2.setPen(Qt::transparent);
|
||||
// pixmapPainter2.setBrush(Qt::transparent);
|
||||
// pixmapPainter2.drawPath(rectPath);
|
||||
|
||||
// // 绘制阴影
|
||||
// p.drawPixmap(this->rect(), pixmap, pixmap.rect());
|
||||
|
||||
// 绘制一个背景
|
||||
p.save();
|
||||
p.fillPath(rectPath, palette().color(QPalette::Base));
|
||||
p.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::resize 重新计算窗口应有大小
|
||||
*/
|
||||
void SettingsWidget::resize() {
|
||||
// if (m_blockdirs <= 1) {
|
||||
// this->setFixedSize(528, 455);
|
||||
// } else if (m_blockdirs <= 3) {
|
||||
// this->setFixedSize(528, 425 + 30 * m_blockdirs);
|
||||
// } else {
|
||||
// this->setFixedSize(528, 515);
|
||||
// }
|
||||
if(m_blockdirs <= 4) {
|
||||
m_dirListArea->setFixedHeight(32 * m_blockdirs + 4);
|
||||
m_dirListWidget->setFixedHeight(32 * m_blockdirs);
|
||||
} else {
|
||||
m_dirListWidget->setFixedHeight(32 * m_blockdirs);
|
||||
m_dirListArea->setFixedHeight(32 * 4 + 4);
|
||||
}
|
||||
this->setFixedSize(528, 410 + m_dirListArea->height());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SettingsWidget::showWarningDialog 显示警告弹窗
|
||||
* @param errorCode 错误码
|
||||
*/
|
||||
void SettingsWidget::showWarningDialog(const int & errorCode) {
|
||||
qWarning() << "Add block dir in onBtnAddClicked() failed. Code: " << errorCode << " ->settings-widget.cpp #238";
|
||||
QString errorMessage;
|
||||
switch(errorCode) {
|
||||
case 1: {
|
||||
errorMessage = tr("Choosen path is Empty!");
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
errorMessage = tr("Choosen path is not in \"home\"!");
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
errorMessage = tr("Its' parent folder has been blocked!");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
errorMessage = tr("Set blocked folder failed!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
QMessageBox message(QMessageBox::Warning, tr("Search"), errorMessage);
|
||||
message.addButton(tr("OK"), QMessageBox::AcceptRole);
|
||||
message.exec();
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
#ifndef SETTINGSWIDGET_H
|
||||
#define SETTINGSWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
#include <QFrame>
|
||||
#include <QHBoxLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QRadioButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QPushButton>
|
||||
#include <QScrollArea>
|
||||
#include <QTimer>
|
||||
#include <libsearch.h>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
#include "xatom-helper.h"
|
||||
#endif
|
||||
|
||||
namespace Zeeker {
|
||||
class SettingsWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SettingsWidget(QWidget *parent = nullptr);
|
||||
~SettingsWidget();
|
||||
|
||||
void setIndexState(bool);
|
||||
void setIndexNum(int);
|
||||
void showWidget();
|
||||
void resetWebEngine();
|
||||
|
||||
private:
|
||||
void initUi();
|
||||
void setupBlackList(const QStringList &);
|
||||
void clearLayout(QLayout *);
|
||||
void refreshIndexState();
|
||||
void paintEvent(QPaintEvent *);
|
||||
void resize();
|
||||
void showWarningDialog(const int&);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
MotifWmHints m_hints;
|
||||
#endif
|
||||
|
||||
//标题栏
|
||||
QVBoxLayout * m_mainLyt = nullptr;
|
||||
QFrame * m_contentFrame = nullptr;
|
||||
QVBoxLayout * m_contentLyt = nullptr;
|
||||
QFrame * m_titleFrame = nullptr;
|
||||
QHBoxLayout * m_titleLyt = nullptr;
|
||||
QLabel * m_titleIcon = nullptr;
|
||||
QLabel * m_titleLabel = nullptr;
|
||||
QPushButton * m_closeBtn = nullptr;
|
||||
|
||||
//设置
|
||||
QLabel * m_settingLabel = nullptr;
|
||||
//文件索引
|
||||
QLabel * m_indexTitleLabel = nullptr;
|
||||
QLabel * m_indexStateLabel = nullptr;
|
||||
QLabel * m_indexNumLabel = nullptr;
|
||||
//文件索引设置(黑名单)
|
||||
QLabel * m_indexSettingLabel = nullptr;
|
||||
QLabel * m_indexDescLabel = nullptr;
|
||||
QFrame * m_indexBtnFrame = nullptr;
|
||||
QHBoxLayout * m_indexBtnLyt = nullptr;
|
||||
QPushButton * m_addDirBtn = nullptr;
|
||||
QScrollArea * m_dirListArea = nullptr;
|
||||
QWidget * m_dirListWidget = nullptr;
|
||||
QVBoxLayout * m_dirListLyt = nullptr;
|
||||
|
||||
//搜索引擎设置
|
||||
QLabel * m_searchEngineLabel = nullptr;
|
||||
QLabel * m_engineDescLabel = nullptr;
|
||||
QButtonGroup * m_engineBtnGroup = nullptr;
|
||||
QFrame * m_radioBtnFrame = nullptr;
|
||||
QHBoxLayout * m_radioBtnLyt = nullptr;
|
||||
QRadioButton * m_baiduBtn = nullptr;
|
||||
QLabel * m_baiduLabel = nullptr;
|
||||
QRadioButton * m_sougouBtn = nullptr;
|
||||
QLabel * m_sougouLabel = nullptr;
|
||||
QRadioButton * m_360Btn = nullptr;
|
||||
QLabel * m_360Label = nullptr;
|
||||
|
||||
//取消与确认按钮
|
||||
QFrame * m_bottomBtnFrame = nullptr;
|
||||
QHBoxLayout * m_bottomBtnLyt = nullptr;
|
||||
QPushButton * m_cancelBtn = nullptr;
|
||||
QPushButton * m_confirmBtn = nullptr;
|
||||
|
||||
QTimer * m_timer;
|
||||
|
||||
int m_blockdirs = 0; //黑名单文件夹数量
|
||||
|
||||
Q_SIGNALS:
|
||||
void settingWidgetClosed();
|
||||
void webEngineChanged(const QString&);
|
||||
|
||||
private Q_SLOTS:
|
||||
// void onBtnConfirmClicked();
|
||||
// void onBtnCancelClicked();
|
||||
void onBtnAddClicked();
|
||||
void onBtnDelClicked(const QString&);
|
||||
void setWebEngine(const QString&);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SETTINGSWIDGET_H
|
|
@ -1,205 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||
** 2020 KylinSoft Co., Ltd.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
**
|
||||
** This file is part of the Qt Solutions component.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "qt-local-peer.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QDataStream>
|
||||
#include <QTime>
|
||||
|
||||
#if defined(Q_OS_UNIX)
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace QtLP_Private {
|
||||
#include "qt-locked-file.cpp"
|
||||
#include "qt-locked-file-unix.cpp"
|
||||
}
|
||||
|
||||
const char* QtLocalPeer::ack = "ack";
|
||||
|
||||
QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
|
||||
: QObject(parent), id(appId) {
|
||||
QString prefix = id;
|
||||
if(id.isEmpty()) {
|
||||
id = QCoreApplication::applicationFilePath();
|
||||
#if defined(Q_OS_WIN)
|
||||
id = id.toLower();
|
||||
#endif
|
||||
prefix = id.section(QLatin1Char('/'), -1); //完整路径按‘/’分隔后取最后一个字段
|
||||
}
|
||||
prefix.remove(QRegExp("[^a-zA-Z]")); //去掉名称中的非字母
|
||||
prefix.truncate(6); //取前六位
|
||||
|
||||
QByteArray idc = id.toUtf8();
|
||||
quint16 idNum = qChecksum(idc.constData(), idc.size());
|
||||
socketName = QLatin1String("qtsingleapp-") + prefix
|
||||
+ QLatin1Char('-') + QString::number(idNum, 16);
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
if(!pProcessIdToSessionId) {
|
||||
QLibrary lib("kernel32");
|
||||
pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
|
||||
}
|
||||
if(pProcessIdToSessionId) {
|
||||
DWORD sessionId = 0;
|
||||
pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
|
||||
socketName += QLatin1Char('-') + QString::number(sessionId, 16);
|
||||
}
|
||||
#else
|
||||
socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
|
||||
#endif
|
||||
|
||||
server = new QLocalServer(this);
|
||||
QString lockName = QDir(QDir::tempPath()).absolutePath()
|
||||
+ QLatin1Char('/') + socketName
|
||||
+ QLatin1String("-lockfile"); //tmp目录下的锁文件
|
||||
lockFile.setFileName(lockName);
|
||||
lockFile.open(QIODevice::ReadWrite);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool QtLocalPeer::isClient() {
|
||||
if(lockFile.isLocked())
|
||||
return false;
|
||||
|
||||
if(!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false))
|
||||
return true;
|
||||
|
||||
//由于文件锁的存在,仅当本进程第一次启动时能执行到此并使server进行监听和关联槽函数
|
||||
bool res = server->listen(socketName);
|
||||
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0))
|
||||
// ### Workaround
|
||||
if(!res && server->serverError() == QAbstractSocket::AddressInUseError) {
|
||||
QFile::remove(QDir::cleanPath(QDir::tempPath()) + QLatin1Char('/') + socketName);
|
||||
res = server->listen(socketName);
|
||||
}
|
||||
#endif
|
||||
if(!res)
|
||||
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
||||
QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool QtLocalPeer::sendMessage(const QString &message, int timeout) {
|
||||
if(!isClient())
|
||||
return false;
|
||||
|
||||
QLocalSocket socket;
|
||||
bool connOk = false;
|
||||
for(int i = 0; i < 2; i++) {
|
||||
// Try twice, in case the other instance is just starting up
|
||||
socket.connectToServer(socketName);
|
||||
connOk = socket.waitForConnected(timeout / 2);
|
||||
if(connOk || i)
|
||||
break;
|
||||
int ms = 250;
|
||||
#if defined(Q_OS_WIN)
|
||||
Sleep(DWORD(ms));
|
||||
#else
|
||||
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
if(!connOk)
|
||||
return false;
|
||||
|
||||
QByteArray uMsg(message.toUtf8());
|
||||
QDataStream ds(&socket);
|
||||
ds.writeBytes(uMsg.constData(), uMsg.size());
|
||||
bool res = socket.waitForBytesWritten(timeout);
|
||||
if(res) {
|
||||
res &= socket.waitForReadyRead(timeout); // wait for ack
|
||||
if(res)
|
||||
res &= (socket.read(qstrlen(ack)) == ack);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QtLocalPeer::receiveConnection 当新进程启动时,会尝试连接此进程server,server接收到newConnection信号并触发此槽函数
|
||||
*/
|
||||
void QtLocalPeer::receiveConnection() {
|
||||
QLocalSocket* socket = server->nextPendingConnection(); //获取新进程的socket
|
||||
if(!socket)
|
||||
return;
|
||||
|
||||
while(true) {
|
||||
if(socket->state() == QLocalSocket::UnconnectedState) {
|
||||
qWarning("QtLocalPeer: Peer disconnected");
|
||||
delete socket;
|
||||
return;
|
||||
}
|
||||
if(socket->bytesAvailable() >= qint64(sizeof(quint32)))
|
||||
break;
|
||||
socket->waitForReadyRead();
|
||||
}
|
||||
|
||||
QDataStream ds(socket);
|
||||
QByteArray uMsg;
|
||||
quint32 remaining;
|
||||
ds >> remaining;
|
||||
uMsg.resize(remaining);
|
||||
int got = 0;
|
||||
char* uMsgBuf = uMsg.data();
|
||||
do {
|
||||
got = ds.readRawData(uMsgBuf, remaining);
|
||||
remaining -= got;
|
||||
uMsgBuf += got;
|
||||
} while(remaining && got >= 0 && socket->waitForReadyRead(2000));
|
||||
if(got < 0) {
|
||||
qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
|
||||
delete socket;
|
||||
return;
|
||||
}
|
||||
QString message(QString::fromUtf8(uMsg));
|
||||
socket->write(ack, qstrlen(ack));
|
||||
socket->waitForBytesWritten(1000);
|
||||
socket->waitForDisconnected(1000); // make sure client reads ack
|
||||
delete socket;
|
||||
Q_EMIT messageReceived(message); //获取新进程的启动信息并作为信号发送给前端
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||
** 2020 KylinSoft Co., Ltd.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
**
|
||||
** This file is part of the Qt Solutions component.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTLOCALPEER_H
|
||||
#define QTLOCALPEER_H
|
||||
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QDir>
|
||||
|
||||
#include "qt-locked-file.h"
|
||||
|
||||
class QtLocalPeer : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
|
||||
bool isClient();
|
||||
bool sendMessage(const QString &message, int timeout);
|
||||
QString applicationId() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void messageReceived(const QString &message);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void receiveConnection();
|
||||
|
||||
protected:
|
||||
QString id;
|
||||
QString socketName;
|
||||
QLocalServer* server;
|
||||
QtLP_Private::QtLockedFile lockFile;
|
||||
|
||||
private:
|
||||
static const char* ack;
|
||||
};
|
||||
|
||||
#endif // QTLOCALPEER_H
|
|
@ -1,113 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||
** 2020 KylinSoft Co., Ltd.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Solutions component.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "qt-locked-file.h"
|
||||
|
||||
bool QtLockedFile::lock(LockMode mode, bool block) {
|
||||
if(!isOpen()) {
|
||||
qWarning("QtLockedFile::lock(): file is not opened");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(mode == NoLock)
|
||||
return unlock();
|
||||
|
||||
if(mode == m_lock_mode)
|
||||
return true;
|
||||
|
||||
if(m_lock_mode != NoLock)
|
||||
unlock();
|
||||
|
||||
struct flock fl;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 0;
|
||||
fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
|
||||
int cmd = block ? F_SETLKW : F_SETLK;
|
||||
int ret = fcntl(handle(), cmd, &fl);
|
||||
|
||||
if(ret == -1) {
|
||||
if(errno != EINTR && errno != EAGAIN)
|
||||
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
m_lock_mode = mode;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool QtLockedFile::unlock() {
|
||||
if(!isOpen()) {
|
||||
qWarning("QtLockedFile::unlock(): file is not opened");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isLocked())
|
||||
return true;
|
||||
|
||||
struct flock fl;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_start = 0;
|
||||
fl.l_len = 0;
|
||||
fl.l_type = F_UNLCK;
|
||||
int ret = fcntl(handle(), F_SETLKW, &fl);
|
||||
|
||||
if(ret == -1) {
|
||||
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lock_mode = NoLock;
|
||||
return true;
|
||||
}
|
||||
|
||||
QtLockedFile::~QtLockedFile() {
|
||||
if(isOpen())
|
||||
unlock();
|
||||
}
|
||||
|
|
@ -1,189 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||
** 2020 KylinSoft Co., Ltd.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Solutions component.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qt-locked-file.h"
|
||||
|
||||
/*!
|
||||
\class QtLockedFile
|
||||
|
||||
\brief The QtLockedFile class extends QFile with advisory locking
|
||||
functions.
|
||||
|
||||
A file may be locked in read or write mode. Multiple instances of
|
||||
\e QtLockedFile, created in multiple processes running on the same
|
||||
machine, may have a file locked in read mode. Exactly one instance
|
||||
may have it locked in write mode. A read and a write lock cannot
|
||||
exist simultaneously on the same file.
|
||||
|
||||
The file locks are advisory. This means that nothing prevents
|
||||
another process from manipulating a locked file using QFile or
|
||||
file system functions offered by the OS. Serialization is only
|
||||
guaranteed if all processes that access the file use
|
||||
QLockedFile. Also, while holding a lock on a file, a process
|
||||
must not open the same file again (through any API), or locks
|
||||
can be unexpectedly lost.
|
||||
|
||||
The lock provided by an instance of \e QtLockedFile is released
|
||||
whenever the program terminates. This is true even when the
|
||||
program crashes and no destructors are called.
|
||||
*/
|
||||
|
||||
/*! \enum QtLockedFile::LockMode
|
||||
|
||||
This enum describes the available lock modes.
|
||||
|
||||
\value ReadLock A read lock.
|
||||
\value WriteLock A write lock.
|
||||
\value NoLock Neither a read lock nor a write lock.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs an unlocked \e QtLockedFile object. This constructor
|
||||
behaves in the same way as \e QFile::QFile().
|
||||
|
||||
\sa QFile::QFile()
|
||||
*/
|
||||
QtLockedFile::QtLockedFile()
|
||||
: QFile() {
|
||||
#ifdef Q_OS_WIN
|
||||
wmutex = 0;
|
||||
rmutex = 0;
|
||||
#endif
|
||||
m_lock_mode = NoLock;
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs an unlocked QtLockedFile object with file \a name. This
|
||||
constructor behaves in the same way as \e QFile::QFile(const
|
||||
QString&).
|
||||
|
||||
\sa QFile::QFile()
|
||||
*/
|
||||
QtLockedFile::QtLockedFile(const QString &name)
|
||||
: QFile(name) {
|
||||
#ifdef Q_OS_WIN
|
||||
wmutex = 0;
|
||||
rmutex = 0;
|
||||
#endif
|
||||
m_lock_mode = NoLock;
|
||||
}
|
||||
|
||||
/*!
|
||||
Opens the file in OpenMode \a mode.
|
||||
|
||||
This is identical to QFile::open(), with the one exception that the
|
||||
Truncate mode flag is disallowed. Truncation would conflict with the
|
||||
advisory file locking, since the file would be modified before the
|
||||
write lock is obtained. If truncation is required, use resize(0)
|
||||
after obtaining the write lock.
|
||||
|
||||
Returns true if successful; otherwise false.
|
||||
|
||||
\sa QFile::open(), QFile::resize()
|
||||
*/
|
||||
bool QtLockedFile::open(OpenMode mode) {
|
||||
if(mode & QIODevice::Truncate) {
|
||||
qWarning("QtLockedFile::open(): Truncate mode not allowed.");
|
||||
return false;
|
||||
}
|
||||
return QFile::open(mode);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \e true if this object has a in read or write lock;
|
||||
otherwise returns \e false.
|
||||
|
||||
\sa lockMode()
|
||||
*/
|
||||
bool QtLockedFile::isLocked() const {
|
||||
return m_lock_mode != NoLock;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the type of lock currently held by this object, or \e
|
||||
QtLockedFile::NoLock.
|
||||
|
||||
\sa isLocked()
|
||||
*/
|
||||
QtLockedFile::LockMode QtLockedFile::lockMode() const {
|
||||
return m_lock_mode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool QtLockedFile::lock(LockMode mode, bool block = true)
|
||||
|
||||
Obtains a lock of type \a mode. The file must be opened before it
|
||||
can be locked.
|
||||
|
||||
If \a block is true, this function will block until the lock is
|
||||
aquired. If \a block is false, this function returns \e false
|
||||
immediately if the lock cannot be aquired.
|
||||
|
||||
If this object already has a lock of type \a mode, this function
|
||||
returns \e true immediately. If this object has a lock of a
|
||||
different type than \a mode, the lock is first released and then a
|
||||
new lock is obtained.
|
||||
|
||||
This function returns \e true if, after it executes, the file is
|
||||
locked by this object, and \e false otherwise.
|
||||
|
||||
\sa unlock(), isLocked(), lockMode()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QtLockedFile::unlock()
|
||||
|
||||
Releases a lock.
|
||||
|
||||
If the object has no lock, this function returns immediately.
|
||||
|
||||
This function returns \e true if, after it executes, the file is
|
||||
not locked by this object, and \e false otherwise.
|
||||
|
||||
\sa lock(), isLocked(), lockMode()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QtLockedFile::~QtLockedFile()
|
||||
|
||||
Destroys the \e QtLockedFile object. If any locks were held, they
|
||||
are released.
|
||||
*/
|
|
@ -1,97 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||
** 2020 KylinSoft Co., Ltd.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the Qt Solutions component.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTLOCKEDFILE_H
|
||||
#define QTLOCKEDFILE_H
|
||||
|
||||
#include <QFile>
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QVector>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
|
||||
# define QT_QTLOCKEDFILE_EXPORT
|
||||
# elif defined(QT_QTLOCKEDFILE_IMPORT)
|
||||
# if defined(QT_QTLOCKEDFILE_EXPORT)
|
||||
# undef QT_QTLOCKEDFILE_EXPORT
|
||||
# endif
|
||||
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport)
|
||||
# elif defined(QT_QTLOCKEDFILE_EXPORT)
|
||||
# undef QT_QTLOCKEDFILE_EXPORT
|
||||
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport)
|
||||
# endif
|
||||
#else
|
||||
# define QT_QTLOCKEDFILE_EXPORT
|
||||
#endif
|
||||
|
||||
namespace QtLP_Private {
|
||||
|
||||
class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile {
|
||||
public:
|
||||
enum LockMode { NoLock = 0, ReadLock, WriteLock };
|
||||
|
||||
QtLockedFile();
|
||||
QtLockedFile(const QString &name);
|
||||
~QtLockedFile();
|
||||
|
||||
bool open(OpenMode mode);
|
||||
|
||||
bool lock(LockMode mode, bool block = true);
|
||||
bool unlock();
|
||||
bool isLocked() const;
|
||||
LockMode lockMode() const;
|
||||
|
||||
private:
|
||||
#ifdef Q_OS_WIN
|
||||
Qt::HANDLE wmutex;
|
||||
Qt::HANDLE rmutex;
|
||||
QVector<Qt::HANDLE> rmutexes;
|
||||
QString mutexname;
|
||||
|
||||
Qt::HANDLE getMutexHandle(int idx, bool doCreate);
|
||||
bool waitMutex(Qt::HANDLE mutex, bool doBlock);
|
||||
|
||||
#endif
|
||||
LockMode m_lock_mode;
|
||||
};
|
||||
}
|
||||
#endif
|
|
@ -1,357 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||
** 2020 KylinSoft Co., Ltd.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
**
|
||||
** This file is part of the Qt Solutions component.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "qt-single-application.h"
|
||||
#include "qt-local-peer.h"
|
||||
#include <QWidget>
|
||||
#include <QDesktopWidget>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusReply>
|
||||
#include "mainwindow.h"
|
||||
|
||||
|
||||
/*!
|
||||
\class QtSingleApplication qtsingleapplication.h
|
||||
\brief The QtSingleApplication class provides an API to detect and
|
||||
communicate with running instances of an application.
|
||||
|
||||
This class allows you to create applications where only one
|
||||
instance should be running at a time. I.e., if the user tries to
|
||||
launch another instance, the already running instance will be
|
||||
activated instead. Another usecase is a client-server system,
|
||||
where the first started instance will assume the role of server,
|
||||
and the later instances will act as clients of that server.
|
||||
|
||||
By default, the full path of the executable file is used to
|
||||
determine whether two processes are instances of the same
|
||||
application. You can also provide an explicit identifier string
|
||||
that will be compared instead.
|
||||
|
||||
The application should create the QtSingleApplication object early
|
||||
in the startup phase, and call isRunning() to find out if another
|
||||
instance of this application is already running. If isRunning()
|
||||
returns false, it means that no other instance is running, and
|
||||
this instance has assumed the role as the running instance. In
|
||||
this case, the application should continue with the initialization
|
||||
of the application user interface before entering the event loop
|
||||
with exec(), as normal.
|
||||
|
||||
The messageReceived() signal will be emitted when the running
|
||||
application receives messages from another instance of the same
|
||||
application. When a message is received it might be helpful to the
|
||||
user to raise the application so that it becomes visible. To
|
||||
facilitate this, QtSingleApplication provides the
|
||||
setActivationWindow() function and the activateWindow() slot.
|
||||
|
||||
If isRunning() returns true, another instance is already
|
||||
running. It may be alerted to the fact that another instance has
|
||||
started by using the sendMessage() function. Also data such as
|
||||
startup parameters (e.g. the name of the file the user wanted this
|
||||
new instance to open) can be passed to the running instance with
|
||||
this function. Then, the application should terminate (or enter
|
||||
client mode).
|
||||
|
||||
If isRunning() returns true, but sendMessage() fails, that is an
|
||||
indication that the running instance is frozen.
|
||||
|
||||
Here's an example that shows how to convert an existing
|
||||
application to use QtSingleApplication. It is very simple and does
|
||||
not make use of all QtSingleApplication's functionality (see the
|
||||
examples for that).
|
||||
|
||||
\code
|
||||
// Original
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
MyMainWidget mmw;
|
||||
mmw.show();
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
// Single instance
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QtSingleApplication app(argc, argv);
|
||||
|
||||
if (app.isRunning())
|
||||
return !app.sendMessage(someDataString);
|
||||
|
||||
MyMainWidget mmw;
|
||||
app.setActivationWindow(&mmw);
|
||||
mmw.show();
|
||||
return app.exec();
|
||||
}
|
||||
\endcode
|
||||
|
||||
Once this QtSingleApplication instance is destroyed (normally when
|
||||
the process exits or crashes), when the user next attempts to run the
|
||||
application this instance will not, of course, be encountered. The
|
||||
next instance to call isRunning() or sendMessage() will assume the
|
||||
role as the new running instance.
|
||||
|
||||
For console (non-GUI) applications, QtSingleCoreApplication may be
|
||||
used instead of this class, to avoid the dependency on the QtGui
|
||||
library.
|
||||
|
||||
\sa QtSingleCoreApplication
|
||||
*/
|
||||
|
||||
|
||||
void QtSingleApplication::sysInit(const QString &appId) {
|
||||
actWin = 0;
|
||||
peer = new QtLocalPeer(this, appId);
|
||||
// connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
|
||||
connect(peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::messageReceived);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Creates a QtSingleApplication object. The application identifier
|
||||
will be QCoreApplication::applicationFilePath(). \a argc, \a
|
||||
argv, and \a GUIenabled are passed on to the QAppliation constructor.
|
||||
|
||||
If you are creating a console application (i.e. setting \a
|
||||
GUIenabled to false), you may consider using
|
||||
QtSingleCoreApplication instead.
|
||||
*/
|
||||
|
||||
QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
|
||||
: QApplication(argc, argv, GUIenabled) {
|
||||
sysInit();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Creates a QtSingleApplication object with the application
|
||||
identifier \a appId. \a argc and \a argv are passed on to the
|
||||
QAppliation constructor.
|
||||
*/
|
||||
|
||||
QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
|
||||
: QApplication(argc, argv) {
|
||||
sysInit(appId);
|
||||
}
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
|
||||
/*!
|
||||
Creates a QtSingleApplication object. The application identifier
|
||||
will be QCoreApplication::applicationFilePath(). \a argc, \a
|
||||
argv, and \a type are passed on to the QAppliation constructor.
|
||||
*/
|
||||
QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type)
|
||||
: QApplication(argc, argv, type) {
|
||||
sysInit();
|
||||
}
|
||||
|
||||
|
||||
# if defined(Q_WS_X11)
|
||||
/*!
|
||||
Special constructor for X11, ref. the documentation of
|
||||
QApplication's corresponding constructor. The application identifier
|
||||
will be QCoreApplication::applicationFilePath(). \a dpy, \a visual,
|
||||
and \a cmap are passed on to the QApplication constructor.
|
||||
*/
|
||||
QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap)
|
||||
: QApplication(dpy, visual, cmap) {
|
||||
sysInit();
|
||||
}
|
||||
|
||||
/*!
|
||||
Special constructor for X11, ref. the documentation of
|
||||
QApplication's corresponding constructor. The application identifier
|
||||
will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a
|
||||
argv, \a visual, and \a cmap are passed on to the QApplication
|
||||
constructor.
|
||||
*/
|
||||
QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
|
||||
: QApplication(dpy, argc, argv, visual, cmap) {
|
||||
sysInit();
|
||||
}
|
||||
|
||||
/*!
|
||||
Special constructor for X11, ref. the documentation of
|
||||
QApplication's corresponding constructor. The application identifier
|
||||
will be \a appId. \a dpy, \a argc, \a
|
||||
argv, \a visual, and \a cmap are passed on to the QApplication
|
||||
constructor.
|
||||
*/
|
||||
QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
|
||||
: QApplication(dpy, argc, argv, visual, cmap) {
|
||||
sysInit(appId);
|
||||
}
|
||||
# endif // Q_WS_X11
|
||||
#endif // QT_VERSION < 0x050000
|
||||
|
||||
|
||||
/*!
|
||||
Returns true if another instance of this application is running;
|
||||
otherwise false.
|
||||
|
||||
This function does not find instances of this application that are
|
||||
being run by a different user (on Windows: that are running in
|
||||
another session).
|
||||
|
||||
\sa sendMessage()
|
||||
*/
|
||||
|
||||
bool QtSingleApplication::isRunning() {
|
||||
return peer->isClient();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Tries to send the text \a message to the currently running
|
||||
instance. The QtSingleApplication object in the running instance
|
||||
will emit the messageReceived() signal when it receives the
|
||||
message.
|
||||
|
||||
This function returns true if the message has been sent to, and
|
||||
processed by, the current instance. If there is no instance
|
||||
currently running, or if the running instance fails to process the
|
||||
message within \a timeout milliseconds, this function return false.
|
||||
|
||||
\sa isRunning(), messageReceived()
|
||||
*/
|
||||
bool QtSingleApplication::sendMessage(const QString &message, int timeout) {
|
||||
return peer->sendMessage(message, timeout);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Returns the application identifier. Two processes with the same
|
||||
identifier will be regarded as instances of the same application.
|
||||
*/
|
||||
QString QtSingleApplication::id() const {
|
||||
return peer->applicationId();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Sets the activation window of this application to \a aw. The
|
||||
activation window is the widget that will be activated by
|
||||
activateWindow(). This is typically the application's main window.
|
||||
|
||||
If \a activateOnMessage is true (the default), the window will be
|
||||
activated automatically every time a message is received, just prior
|
||||
to the messageReceived() signal being emitted.
|
||||
|
||||
\sa activateWindow(), messageReceived()
|
||||
*/
|
||||
|
||||
void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) {
|
||||
actWin = aw;
|
||||
//目前不需要用到此处的置顶方法,故此信号槽暂时注释掉,若后续需要根据新起进程传递的信号执行部分操作时可以把这里放开
|
||||
// if (activateOnMessage)
|
||||
// connect(peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow);
|
||||
// else
|
||||
// disconnect(peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Returns the applications activation window if one has been set by
|
||||
calling setActivationWindow(), otherwise returns 0.
|
||||
|
||||
\sa setActivationWindow()
|
||||
*/
|
||||
QWidget* QtSingleApplication::activationWindow() const {
|
||||
return actWin;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
De-minimizes, raises, and activates this application's activation window.
|
||||
This function does nothing if no activation window has been set.
|
||||
|
||||
This is a convenience function to show the user that this
|
||||
application instance has been activated when he has tried to start
|
||||
another instance.
|
||||
|
||||
This function should typically be called in response to the
|
||||
messageReceived() signal. By default, that will happen
|
||||
automatically, if an activation window has been set.
|
||||
|
||||
\sa setActivationWindow(), messageReceived(), initialize()
|
||||
*/
|
||||
void QtSingleApplication::activateWindow() {
|
||||
//单例置顶策略,由于bootOptionsFilter in mainwindow自带置顶策略,故注掉此处
|
||||
// if (actWin) {
|
||||
// if(this->applicationState() & Qt::ApplicationInactive)
|
||||
// {
|
||||
// MainWindow* w=qobject_cast<MainWindow*>(actWin);
|
||||
//// w->loadMainWindow();
|
||||
// w->clearSearchResult();
|
||||
// actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
|
||||
// actWin->raise();
|
||||
// actWin->showNormal();
|
||||
// actWin->activateWindow();
|
||||
// }
|
||||
// else {
|
||||
// actWin->setWindowState(actWin->windowState() & Qt::WindowMinimized);
|
||||
// actWin->hide();
|
||||
// }
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\fn void QtSingleApplication::messageReceived(const QString& message)
|
||||
|
||||
This signal is emitted when the current instance receives a \a
|
||||
message from another instance of this application.
|
||||
|
||||
\sa sendMessage(), setActivationWindow(), activateWindow()
|
||||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\fn void QtSingleApplication::initialize(bool dummy = true)
|
||||
|
||||
\obsolete
|
||||
*/
|
|
@ -1,109 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)
|
||||
** 2020 KylinSoft Co., Ltd.
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
**
|
||||
** This file is part of the Qt Solutions component.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||
** of its contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTSINGLEAPPLICATION_H
|
||||
#define QTSINGLEAPPLICATION_H
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
class QtLocalPeer;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT)
|
||||
# define QT_QTSINGLEAPPLICATION_EXPORT
|
||||
# elif defined(QT_QTSINGLEAPPLICATION_IMPORT)
|
||||
# if defined(QT_QTSINGLEAPPLICATION_EXPORT)
|
||||
# undef QT_QTSINGLEAPPLICATION_EXPORT
|
||||
# endif
|
||||
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport)
|
||||
# elif defined(QT_QTSINGLEAPPLICATION_EXPORT)
|
||||
# undef QT_QTSINGLEAPPLICATION_EXPORT
|
||||
# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport)
|
||||
# endif
|
||||
#else
|
||||
# define QT_QTSINGLEAPPLICATION_EXPORT
|
||||
#endif
|
||||
|
||||
class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
|
||||
QtSingleApplication(const QString &id, int &argc, char **argv);
|
||||
#if QT_VERSION < 0x050000
|
||||
QtSingleApplication(int &argc, char **argv, Type type);
|
||||
# if defined(Q_WS_X11)
|
||||
QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
|
||||
QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0);
|
||||
QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
|
||||
# endif // Q_WS_X11
|
||||
#endif // QT_VERSION < 0x050000
|
||||
|
||||
bool isRunning();
|
||||
QString id() const;
|
||||
|
||||
void setActivationWindow(QWidget* aw, bool activateOnMessage = true);
|
||||
QWidget* activationWindow() const;
|
||||
|
||||
// Obsolete:
|
||||
void initialize(bool dummy = true) {
|
||||
isRunning();
|
||||
Q_UNUSED(dummy)
|
||||
}
|
||||
|
||||
public Q_SLOTS:
|
||||
bool sendMessage(const QString &message, int timeout = 5000);
|
||||
void activateWindow();
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
void messageReceived(const QString &message);
|
||||
|
||||
|
||||
private:
|
||||
void sysInit(const QString &appId = QString());
|
||||
QtLocalPeer *peer;
|
||||
QWidget *actWin;
|
||||
};
|
||||
|
||||
#endif // QTSINGLEAPPLICATION_H
|
|
@ -1,27 +0,0 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
DEPENDPATH += $$PWD
|
||||
QT *= network
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT *= widgets
|
||||
|
||||
qtsingleapplication-uselib:!qtsingleapplication-buildlib {
|
||||
LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME
|
||||
} else {
|
||||
SOURCES +=
|
||||
HEADERS +=
|
||||
}
|
||||
|
||||
win32 {
|
||||
contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT
|
||||
else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/qt-local-peer.h \
|
||||
$$PWD/qt-locked-file.h \
|
||||
$$PWD/qt-single-application.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qt-local-peer.cpp \
|
||||
$$PWD/qt-locked-file-unix.cpp \
|
||||
$$PWD/qt-single-application.cpp \
|
||||
$$PWD/qt-locked-file.cpp
|
98
src/src.pro
98
src/src.pro
|
@ -1,98 +0,0 @@
|
|||
QT += core gui dbus KWindowSystem xml x11extras
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
VERSION = 0.0.1
|
||||
TARGET = ukui-search
|
||||
TEMPLATE = app
|
||||
|
||||
PKGCONFIG += gio-2.0 glib-2.0 gio-unix-2.0
|
||||
CONFIG += c++11 link_pkgconfig no_keywords lrelease
|
||||
LIBS += -lxapian -lgsettings-qt -lquazip5 -lX11
|
||||
LIBS += -lukui-log4qt #-L/usr/local/lib/libjemalloc -ljemalloc
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any Qt feature that has been marked deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
include(../libsearch/libukui-search-headers.pri)
|
||||
include(model/model.pri)
|
||||
include(control/control.pri)
|
||||
include(singleapplication/qt-single-application.pri)
|
||||
|
||||
|
||||
SOURCES += \
|
||||
content-widget.cpp \
|
||||
create-index-ask-dialog.cpp \
|
||||
input-box.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
search-app-thread.cpp \
|
||||
search-result.cpp \
|
||||
settings-widget.cpp \
|
||||
ukui-search-dbus-service.cpp \
|
||||
xatom-helper.cpp
|
||||
|
||||
|
||||
HEADERS += \
|
||||
content-widget.h \
|
||||
create-index-ask-dialog.h \
|
||||
input-box.h \
|
||||
mainwindow.h \
|
||||
search-app-thread.h \
|
||||
search-result.h \
|
||||
settings-widget.h \
|
||||
ukui-search-dbus-service.h \
|
||||
xatom-helper.h
|
||||
|
||||
# Default rules for deployment.
|
||||
|
||||
target.path = /usr/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
data-menu.path = /usr/share/applications
|
||||
data-menu.files += ../data/ukui-search-menu.desktop
|
||||
data.path = /etc/xdg/autostart
|
||||
data.files += ../data/ukui-search.desktop
|
||||
|
||||
INSTALLS += data data-menu
|
||||
|
||||
RESOURCES += \
|
||||
resource.qrc
|
||||
|
||||
TRANSLATIONS += \
|
||||
../translations/ukui-search/zh_CN.ts \
|
||||
../translations/ukui-search/tr.ts \
|
||||
../translations/ukui-search/bo.ts
|
||||
|
||||
qm_files.path = /usr/share/ukui-search/translations/
|
||||
qm_files.files = $$OUT_PWD/.qm/*.qm
|
||||
|
||||
schemes.path = /usr/share/glib-2.0/schemas/
|
||||
schemes.files += ../data/org.ukui.search.data.gschema.xml ../data/org.ukui.log4qt.ukui-search.gschema.xml
|
||||
|
||||
INSTALLS += qm_files schemes
|
||||
|
||||
LIBS += -L$$OUT_PWD/../libchinese-segmentation -lchinese-segmentation \
|
||||
-L$$OUT_PWD/../libsearch -lukui-search
|
||||
|
||||
INCLUDEPATH += $$PWD/../libchinese-segmentation
|
||||
DEPENDPATH += $$PWD/../libchinese-segmentation
|
||||
|
||||
INCLUDEPATH += $$PWD/../libsearch
|
||||
DEPENDPATH += $$PWD/../libsearch
|
||||
|
||||
#DISTFILES += \
|
||||
# ../data/ukui-search-menu.desktop \
|
||||
# $$OUT_PWD/.qm/bo.qm \
|
||||
# $$OUT_PWD/.qm/tr.qm \
|
||||
# $$OUT_PWD/.qm/zh_CN.qm
|
||||
|
||||
DISTFILES += \
|
||||
../data/org.ukui.log4qt.ukui-search.gschema.xml \
|
||||
../data/org.ukui.search.data.gschema.xml
|
|
@ -1,23 +0,0 @@
|
|||
#include "ukui-search-dbus-service.h"
|
||||
|
||||
using namespace Zeeker;
|
||||
void UkuiSearchDbusServices::showWindow(){
|
||||
m_mainWindow->bootOptionsFilter("-s");
|
||||
}
|
||||
|
||||
UkuiSearchDbusServices::UkuiSearchDbusServices(MainWindow *m)
|
||||
{
|
||||
m_mainWindow = m;
|
||||
//注册服务
|
||||
QDBusConnection sessionBus = QDBusConnection::sessionBus();
|
||||
QDBusConnection::sessionBus().unregisterService("com.ukui.search.service");
|
||||
if(!sessionBus.registerService("com.ukui.search.service")){
|
||||
qWarning() << "ukui-search dbus register service failed reason:" << sessionBus.lastError();
|
||||
}
|
||||
|
||||
if(!sessionBus.registerObject("/", this, QDBusConnection::ExportAllSlots)){
|
||||
qWarning() << "ukui-search dbus register object failed reason:" << sessionBus.lastError();
|
||||
}
|
||||
}
|
||||
UkuiSearchDbusServices::~UkuiSearchDbusServices(){
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef UKUISEARCHDBUSSERVICE_H
|
||||
#define UKUISEARCHDBUSSERVICE_H
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QObject>
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
namespace Zeeker {
|
||||
|
||||
class UkuiSearchDbusServices: public QObject{
|
||||
Q_OBJECT
|
||||
|
||||
Q_CLASSINFO("D-Bus Interface","org.ukui.search.service")
|
||||
|
||||
public:
|
||||
explicit UkuiSearchDbusServices(MainWindow *m);
|
||||
~UkuiSearchDbusServices();
|
||||
|
||||
public Q_SLOTS:
|
||||
void showWindow();
|
||||
|
||||
private:
|
||||
MainWindow *m_mainWindow;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // UKUISEARCHDBUSSERVICE_H
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* KWin Style UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xatom-helper.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <QX11Info>
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <NETWM>
|
||||
|
||||
static XAtomHelper *global_instance = nullptr;
|
||||
|
||||
XAtomHelper *XAtomHelper::getInstance() {
|
||||
if(!global_instance)
|
||||
global_instance = new XAtomHelper;
|
||||
return global_instance;
|
||||
}
|
||||
|
||||
bool XAtomHelper::isFrameLessWindow(int winId) {
|
||||
auto hints = getInstance()->getWindowMotifHint(winId);
|
||||
if(hints.flags == MWM_HINTS_DECORATIONS && hints.functions == 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XAtomHelper::isWindowDecorateBorderOnly(int winId) {
|
||||
return isWindowMotifHintDecorateBorderOnly(getInstance()->getWindowMotifHint(winId));
|
||||
}
|
||||
|
||||
bool XAtomHelper::isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint) {
|
||||
bool isDeco = false;
|
||||
if(hint.flags & MWM_HINTS_DECORATIONS && hint.flags != MWM_HINTS_DECORATIONS) {
|
||||
if(hint.decorations == MWM_DECOR_BORDER)
|
||||
isDeco = true;
|
||||
}
|
||||
return isDeco;
|
||||
}
|
||||
|
||||
bool XAtomHelper::isUKUICsdSupported() {
|
||||
// fixme:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool XAtomHelper::isUKUIDecorationWindow(int winId) {
|
||||
if(m_ukuiDecorationAtion == None)
|
||||
return false;
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
ulong nitems;
|
||||
ulong bytes_after;
|
||||
uchar *data;
|
||||
|
||||
bool isUKUIDecoration = false;
|
||||
|
||||
XGetWindowProperty(QX11Info::display(), winId, m_ukuiDecorationAtion,
|
||||
0, LONG_MAX, false,
|
||||
m_ukuiDecorationAtion, &type,
|
||||
&format, &nitems,
|
||||
&bytes_after, &data);
|
||||
|
||||
if(type == m_ukuiDecorationAtion) {
|
||||
if(nitems == 1) {
|
||||
isUKUIDecoration = data[0];
|
||||
}
|
||||
}
|
||||
|
||||
return isUKUIDecoration;
|
||||
}
|
||||
|
||||
UnityCorners XAtomHelper::getWindowBorderRadius(int winId) {
|
||||
UnityCorners corners;
|
||||
|
||||
Atom type;
|
||||
int format;
|
||||
ulong nitems;
|
||||
ulong bytes_after;
|
||||
uchar *data;
|
||||
|
||||
if(m_unityBorderRadiusAtom != None) {
|
||||
XGetWindowProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom,
|
||||
0, LONG_MAX, false,
|
||||
XA_CARDINAL, &type,
|
||||
&format, &nitems,
|
||||
&bytes_after, &data);
|
||||
|
||||
if(type == XA_CARDINAL) {
|
||||
if(nitems == 4) {
|
||||
corners.topLeft = static_cast<ulong>(data[0]);
|
||||
corners.topRight = static_cast<ulong>(data[1 * sizeof(ulong)]);
|
||||
corners.bottomLeft = static_cast<ulong>(data[2 * sizeof(ulong)]);
|
||||
corners.bottomRight = static_cast<ulong>(data[3 * sizeof(ulong)]);
|
||||
}
|
||||
XFree(data);
|
||||
}
|
||||
}
|
||||
|
||||
return corners;
|
||||
}
|
||||
|
||||
void XAtomHelper::setWindowBorderRadius(int winId, const UnityCorners &data) {
|
||||
if(m_unityBorderRadiusAtom == None)
|
||||
return;
|
||||
|
||||
ulong corners[4] = {data.topLeft, data.topRight, data.bottomLeft, data.bottomRight};
|
||||
|
||||
XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL,
|
||||
32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof(corners) / sizeof(corners[0]));
|
||||
}
|
||||
|
||||
void XAtomHelper::setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight) {
|
||||
if(m_unityBorderRadiusAtom == None)
|
||||
return;
|
||||
|
||||
ulong corners[4] = {(ulong)topLeft, (ulong)topRight, (ulong)bottomLeft, (ulong)bottomRight};
|
||||
|
||||
XChangeProperty(QX11Info::display(), winId, m_unityBorderRadiusAtom, XA_CARDINAL,
|
||||
32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &corners, sizeof(corners) / sizeof(corners[0]));
|
||||
}
|
||||
|
||||
void XAtomHelper::setUKUIDecoraiontHint(int winId, bool set) {
|
||||
if(m_ukuiDecorationAtion == None)
|
||||
return;
|
||||
|
||||
XChangeProperty(QX11Info::display(), winId, m_ukuiDecorationAtion, m_ukuiDecorationAtion, 32, XCB_PROP_MODE_REPLACE, (const unsigned char *) &set, 1);
|
||||
}
|
||||
|
||||
void XAtomHelper::setWindowMotifHint(int winId, const MotifWmHints &hints) {
|
||||
if(m_unityBorderRadiusAtom == None)
|
||||
return;
|
||||
|
||||
XChangeProperty(QX11Info::display(), winId, m_motifWMHintsAtom, m_motifWMHintsAtom,
|
||||
32, XCB_PROP_MODE_REPLACE, (const unsigned char *)&hints, sizeof(MotifWmHints) / sizeof(ulong));
|
||||
}
|
||||
|
||||
MotifWmHints XAtomHelper::getWindowMotifHint(int winId) {
|
||||
MotifWmHints hints;
|
||||
|
||||
if(m_unityBorderRadiusAtom == None)
|
||||
return hints;
|
||||
|
||||
uchar *data;
|
||||
Atom type;
|
||||
int format;
|
||||
ulong nitems;
|
||||
ulong bytes_after;
|
||||
|
||||
XGetWindowProperty(QX11Info::display(), winId, m_motifWMHintsAtom,
|
||||
0, sizeof(MotifWmHints) / sizeof(long), false, AnyPropertyType, &type,
|
||||
&format, &nitems, &bytes_after, &data);
|
||||
|
||||
if(type == None) {
|
||||
return hints;
|
||||
} else {
|
||||
hints = *(MotifWmHints *)data;
|
||||
XFree(data);
|
||||
}
|
||||
return hints;
|
||||
}
|
||||
|
||||
XAtomHelper::XAtomHelper(QObject *parent) : QObject(parent) {
|
||||
if(!QX11Info::isPlatformX11())
|
||||
return;
|
||||
|
||||
m_motifWMHintsAtom = XInternAtom(QX11Info::display(), "_MOTIF_WM_HINTS", true);
|
||||
m_unityBorderRadiusAtom = XInternAtom(QX11Info::display(), "_UNITY_GTK_BORDER_RADIUS", false);
|
||||
m_ukuiDecorationAtion = XInternAtom(QX11Info::display(), "_KWIN_UKUI_DECORAION", false);
|
||||
}
|
||||
|
||||
Atom XAtomHelper::registerUKUICsdNetWmSupportAtom() {
|
||||
// fixme:
|
||||
return None;
|
||||
}
|
||||
|
||||
void XAtomHelper::unregisterUKUICsdNetWmSupportAtom() {
|
||||
// fixme:
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* KWin Style UKUI
|
||||
*
|
||||
* Copyright (C) 2020, 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Yue Lan <lanyue@kylinos.cn>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef XATOMHELPER_H
|
||||
#define XATOMHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <NETWM>
|
||||
|
||||
struct UnityCorners {
|
||||
ulong topLeft = 0;
|
||||
ulong topRight = 0;
|
||||
ulong bottomLeft = 0;
|
||||
ulong bottomRight = 0;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
ulong flags = 0;
|
||||
ulong functions = 0;
|
||||
ulong decorations = 0;
|
||||
long input_mode = 0;
|
||||
ulong status = 0;
|
||||
} MotifWmHints, MwmHints;
|
||||
|
||||
#define MWM_HINTS_FUNCTIONS (1L << 0)
|
||||
#define MWM_HINTS_DECORATIONS (1L << 1)
|
||||
#define MWM_HINTS_INPUT_MODE (1L << 2)
|
||||
#define MWM_HINTS_STATUS (1L << 3)
|
||||
|
||||
#define MWM_FUNC_ALL (1L << 0)
|
||||
#define MWM_FUNC_RESIZE (1L << 1)
|
||||
#define MWM_FUNC_MOVE (1L << 2)
|
||||
#define MWM_FUNC_MINIMIZE (1L << 3)
|
||||
#define MWM_FUNC_MAXIMIZE (1L << 4)
|
||||
#define MWM_FUNC_CLOSE (1L << 5)
|
||||
|
||||
#define MWM_DECOR_ALL (1L << 0)
|
||||
#define MWM_DECOR_BORDER (1L << 1)
|
||||
#define MWM_DECOR_RESIZEH (1L << 2)
|
||||
#define MWM_DECOR_TITLE (1L << 3)
|
||||
#define MWM_DECOR_MENU (1L << 4)
|
||||
#define MWM_DECOR_MINIMIZE (1L << 5)
|
||||
#define MWM_DECOR_MAXIMIZE (1L << 6)
|
||||
|
||||
#define MWM_INPUT_MODELESS 0
|
||||
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
|
||||
#define MWM_INPUT_SYSTEM_MODAL 2
|
||||
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
|
||||
#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
|
||||
|
||||
#define MWM_TEAROFF_WINDOW (1L<<0)
|
||||
|
||||
namespace UKUI {
|
||||
class Decoration;
|
||||
}
|
||||
|
||||
class XAtomHelper : public QObject {
|
||||
// friend class UKUI::Decoration;
|
||||
Q_OBJECT
|
||||
public:
|
||||
static XAtomHelper *getInstance();
|
||||
|
||||
static bool isFrameLessWindow(int winId);
|
||||
|
||||
static bool isWindowDecorateBorderOnly(int winId);
|
||||
static bool isWindowMotifHintDecorateBorderOnly(const MotifWmHints &hint);
|
||||
bool isUKUICsdSupported();
|
||||
bool isUKUIDecorationWindow(int winId);
|
||||
|
||||
UnityCorners getWindowBorderRadius(int winId);
|
||||
void setWindowBorderRadius(int winId, const UnityCorners &data);
|
||||
void setWindowBorderRadius(int winId, int topLeft, int topRight, int bottomLeft, int bottomRight);
|
||||
void setUKUIDecoraiontHint(int winId, bool set = true);
|
||||
|
||||
void setWindowMotifHint(int winId, const MotifWmHints &hints);
|
||||
MotifWmHints getWindowMotifHint(int winId);
|
||||
|
||||
private:
|
||||
explicit XAtomHelper(QObject *parent = nullptr);
|
||||
|
||||
Atom registerUKUICsdNetWmSupportAtom();
|
||||
void unregisterUKUICsdNetWmSupportAtom();
|
||||
|
||||
Atom m_motifWMHintsAtom = None;
|
||||
Atom m_unityBorderRadiusAtom = None;
|
||||
Atom m_ukuiDecorationAtion = None;
|
||||
};
|
||||
|
||||
#endif // XATOMHELPER_H
|
Loading…
Reference in New Issue