Remove useless code.

This commit is contained in:
iaom 2022-05-30 09:29:53 +08:00
parent e59c369221
commit c69c04207b
62 changed files with 0 additions and 8496 deletions

View File

@ -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();
}

View File

@ -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

View File

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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("<", "&lt;");
temp.replace(">", "&gt;");
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 &regFindKeyWords) {
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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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("<", "&lt;");
temp.replace(">", "&gt;");
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;
//}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;
};
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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

View File

View File

@ -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 \

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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>

View File

@ -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();
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -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); //获取新进程的启动信息并作为信号发送给前端
}

View File

@ -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

View File

@ -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();
}

View File

@ -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.
*/

View File

@ -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

View File

@ -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
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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(){
}

View File

@ -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

View File

@ -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:
}

View File

@ -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