Merge branch 'ukss-dev' into 'ukss-dev'

合并new-frontend的改动

See merge request kylin-desktop/ukui-search!275
This commit is contained in:
纪笑旭 2022-03-10 02:32:57 +00:00
commit 3682b99a4a
76 changed files with 9051 additions and 48821 deletions

6
debian/control vendored
View File

@ -11,7 +11,7 @@ Build-Depends: debhelper (>=9.0.0),
qtscript5-dev,
qttools5-dev-tools,
libxapian-dev,
libquazip5-dev(>=0.7.6-6build1),
libquazip5-dev(>=0.9.1-2),
libglib2.0-dev,
libkf5windowsystem-dev,
libgsettings-qt-dev,
@ -20,7 +20,9 @@ Build-Depends: debhelper (>=9.0.0),
libpoppler-qt5-dev,
libukui-log4qt-dev,
libqt5xdg-dev,
libukcc-dev
libukcc-dev,
libopencv-dev,
libtesseract-dev
Standards-Version: 4.5.0
Homepage: https://www.ukui.org/
Vcs-Git: https://github.com/ukui/ukui-search.git

View File

@ -21,6 +21,7 @@
#include "create-index-ask-dialog.h"
#include <QPainterPath>
#include "kwindowsystem.h"
#define MAIN_SIZE QSize(380, 202)
#define MAIN_SPACING 0
@ -43,6 +44,7 @@ CreateIndexAskDialog::CreateIndexAskDialog(QWidget *parent) : QDialog(parent) {
}
void CreateIndexAskDialog::initUi() {
KWindowSystem::setState(this->winId(),NET::SkipTaskbar | NET::SkipPager);
this->setFixedSize(MAIN_SIZE);
m_mainLyt = new QVBoxLayout(this);
this->setLayout(m_mainLyt);

View File

@ -30,13 +30,13 @@ ShowMoreLabel::ShowMoreLabel(QWidget *parent) : QWidget(parent) {
void ShowMoreLabel::resetLabel() {
m_isOpen = false;
m_iconLabel->setPixmap(QIcon::fromTheme("pan-down-symbolic").pixmap(QSize(16, 16)));
m_iconLabel->setPixmap(QIcon::fromTheme("pan-down-symbolic", QIcon(":/res/icons/pan-down-symbolic.svg")).pixmap(QSize(16, 16)));
}
void ShowMoreLabel::setLabel()
{
m_isOpen = true;
m_iconLabel->setPixmap(QIcon::fromTheme("pan-up-symbolic").pixmap(QSize(16, 16)));
m_iconLabel->setPixmap(QIcon::fromTheme("pan-up-symbolic", QIcon(":/res/icons/pan-up-symbolic.svg")).pixmap(QSize(16, 16)));
}
/**
@ -53,7 +53,7 @@ void ShowMoreLabel::initUi() {
m_layout = new QHBoxLayout(this);
m_layout->setContentsMargins(0, 0, 0, 6);
m_iconLabel = new QLabel(this);
m_iconLabel->setPixmap(QIcon::fromTheme("pan-down-symbolic").pixmap(QSize(16, 16)));
m_iconLabel->setPixmap(QIcon::fromTheme("pan-down-symbolic", QIcon(":/res/icons/pan-down-symbolic.svg")).pixmap(QSize(16, 16)));
m_iconLabel->setCursor(QCursor(Qt::PointingHandCursor));
m_iconLabel->installEventFilter(this);
// m_loadingIconLabel = new QLabel(this); //使用图片显示加载状态时取消此label的注释
@ -63,6 +63,7 @@ void ShowMoreLabel::initUi() {
m_layout->addWidget(m_iconLabel);
m_iconLabel->setPalette(pal);
m_iconLabel->setCursor(QCursor(Qt::PointingHandCursor));
m_iconLabel->setProperty("useIconHighlightEffect", 0x08);
// m_layout->addWidget(m_loadingIconLabel);
}
@ -71,11 +72,11 @@ bool ShowMoreLabel::eventFilter(QObject *watched, QEvent *event) {
if(event->type() == QEvent::MouseButtonPress) {
if(! m_timer->isActive()) {
if(!m_isOpen) {
m_iconLabel->setPixmap(QIcon::fromTheme("pan-up-symbolic").pixmap(QSize(16, 16)));
m_iconLabel->setPixmap(QIcon::fromTheme("pan-up-symbolic", QIcon(":/res/icons/pan-up-symbolic.svg")).pixmap(QSize(16, 16)));
m_isOpen = true;
Q_EMIT this->showMoreClicked();
} else {
m_iconLabel->setPixmap(QIcon::fromTheme("pan-down-symbolic").pixmap(QSize(16, 16)));
m_iconLabel->setPixmap(QIcon::fromTheme("pan-down-symbolic", QIcon(":/res/icons/pan-down-symbolic.svg")).pixmap(QSize(16, 16)));
m_isOpen = false;
Q_EMIT this->retractClicked();
}

View File

@ -20,6 +20,7 @@
*/
#include "search-line-edit.h"
#include <KWindowEffects>
#include <QPainterPath>
QT_BEGIN_NAMESPACE
extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);

View File

@ -19,6 +19,7 @@
*
*/
#include "search-result-page.h"
#include <QPainterPath>
QT_BEGIN_NAMESPACE
extern void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed);
QT_END_NAMESPACE

View File

@ -171,7 +171,7 @@ void MainWindow::initConnections()
connect(m_askDialog, &CreateIndexAskDialog::btnClicked, this, [ = ](const bool &is_create_index, const bool &is_ask_again) {
setSearchMethodConfig(is_create_index, is_ask_again);
});
connect(m_settingsBtn, &QPushButton::clicked, this, &MainWindow::settingsBtnClickedSlot);
// connect(m_settingsBtn, &QPushButton::clicked, this, &MainWindow::settingsBtnClickedSlot);
//主题改变时,更新自定义标题栏的图标
// connect(qApp, &QApplication::paletteChanged, this, [ = ]() {
// m_iconLabel->setPixmap(QIcon::fromTheme("kylin-search").pixmap(QSize(WINDOW_ICON_SIZE, WINDOW_ICON_SIZE)));
@ -403,6 +403,7 @@ void MainWindow::moveToPanel() {
void MainWindow::centerToScreen(QWidget* widget) {
if(!widget)
return;
KWindowSystem::setState(this->winId(),NET::SkipTaskbar | NET::SkipPager);
QDesktopWidget* m = QApplication::desktop();
QRect desk_rect = m->screenGeometry(m->screenNumber(QCursor::pos()));
int desk_x = desk_rect.width();

View File

@ -31,9 +31,7 @@ SearchResultManager::SearchResultManager(const QString& plugin_id, QObject *pare
void SearchResultManager::startSearch(const QString &keyword)
{
//NEW_TODO 加锁?停止线程?重新搜索?
// stopSearch();
qDebug()<<m_plugin_id<<"------------------>start by others";
qDebug()<<m_plugin_id<<"started";
if(! m_get_result_thread->isRunning()) {
m_get_result_thread->start();
}
@ -48,8 +46,10 @@ void SearchResultManager::startSearch(const QString &keyword)
void SearchResultManager::stopSearch()
{
if(m_get_result_thread->isRunning()) {
qDebug()<<m_plugin_id<<"-------------->stopped by others";
qDebug()<<m_plugin_id<<"stopped";
m_get_result_thread->stop();
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_plugin_id);
plugin->stopSearch();
// m_get_result_thread->quit();
}
}
@ -70,7 +70,6 @@ void ReceiveResultThread::stop()
this->quit();
}
//NEW_TODO 还未对队列加锁
void ReceiveResultThread::run()
{
QTimer * m_timer = new QTimer;
@ -86,7 +85,7 @@ void ReceiveResultThread::run()
}
if(m_timer->isActive() && m_timer->remainingTime() < 0.01) {
this->requestInterruption();
qWarning()<<"-------------->stopped by self";
qWarning()<<"-------------->stopped by itself";
}
if(is_empty && !m_timer->isActive()) {
m_timer->start();

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
<path d="m13 6-5 5-5-5z" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 153 B

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
<path d="m13 10-5-5-5 5z" fill="#2e3436"/>
</svg>

After

Width:  |  Height:  |  Size: 154 B

View File

@ -6,5 +6,7 @@
<file>res/qt-translations/qt_zh_CN.qm</file>
<file>res/icons/net-disconnected.svg</file>
<file>res/icons/system-search.symbolic.png</file>
<file>res/icons/pan-up-symbolic.svg</file>
<file>res/icons/pan-down-symbolic.svg</file>
</qresource>
</RCC>

View File

@ -8,7 +8,6 @@
#include "search-plugin-manager.h"
#include "document.h"
#include "file-utils.h"
using namespace UkuiSearch;
UkuiSearchGui::UkuiSearchGui(int &argc, char *argv[], const QString &applicationName): QtSingleApplication (applicationName, argc, argv)
{
@ -54,10 +53,6 @@ UkuiSearchGui::UkuiSearchGui(int &argc, char *argv[], const QString &application
SearchPluginManager::getInstance();
PluginManager::getInstance();
// load chinese character and pinyin file to a Map
FileUtils::loadHanziTable("://index/pinyinWithoutTone.txt");
qDebug() << "Finish loading plugins and resources";
m_mainWindow = new UkuiSearch::MainWindow();
m_dbusService = new UkuiSearch::UkuiSearchDbusServices(m_mainWindow);
qApp->setWindowIcon(QIcon::fromTheme("kylin-search"));

View File

@ -8,6 +8,7 @@
using namespace UkuiSearch;
BestListView::BestListView(QWidget *parent) : QTreeView(parent)
{
setStyle(ResultItemStyle::getStyle());
this->setFrameShape(QFrame::NoFrame);
this->viewport()->setAutoFillBackground(false);
this->setIconSize(QSize(VIEW_ICON_SIZE, VIEW_ICON_SIZE));

View File

@ -1,5 +1,7 @@
#include "result-view-delegate.h"
#include <QPainterPath>
using namespace UkuiSearch;
static ResultItemStyle *global_instance_of_item_style = nullptr;
ResultViewDelegate::ResultViewDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
@ -38,7 +40,8 @@ void ResultViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem &
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);
//使图标和文本间隔与原来保持一致故文本区域右移4
textRect.adjust(4, 0, 0, 0);
painter->save();
painter->translate(textRect.topLeft());
painter->setClipRect(textRect.translated(-textRect.topLeft()));
@ -52,7 +55,7 @@ QString ResultViewDelegate::getHtmlText(QPainter *painter, const QStyleOptionVie
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的长度时显示为省略号
QString indexColString = fm.elidedText(indexString, Qt::ElideRight, itemOption.rect.width() - 30 - 10); //当字体超过Item的长度时显示为省略号
QString htmlString;
if((indexColString.toUpper()).contains((m_regFindKeyWords.toUpper()))) {
indexFindLeft = indexColString.toUpper().indexOf(m_regFindKeyWords.toUpper()); //得到查找字体在当前整个Item字体中的位置
@ -77,7 +80,7 @@ QString ResultViewDelegate::getHtmlText(QPainter *painter, const QStyleOptionVie
}
}
// qDebug()<<indexColString<<"---->"<<htmlString;
return htmlString;
return "<pre>" + htmlString + "</pre>";
}
QString ResultViewDelegate::escapeHtml(const QString &str) const
@ -87,3 +90,71 @@ QString ResultViewDelegate::escapeHtml(const QString &str) const
temp.replace(">", "&gt;");
return temp;
}
ResultItemStyle *ResultItemStyle::getStyle()
{
if (!global_instance_of_item_style) {
global_instance_of_item_style = new ResultItemStyle;
}
return global_instance_of_item_style;
}
void ResultItemStyle::drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
switch (element) {
case CE_ItemViewItem: {
if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(option)) {
painter->save();
if (painter->clipPath().isEmpty()) {
painter->setClipRect(option->rect);
}
QRect checkRect = proxy()->subElementRect(SE_ItemViewItemCheckIndicator, vopt, widget);
QRect iconRect = proxy()->subElementRect(SE_ItemViewItemDecoration, vopt, widget);
// draw the background
proxy()->drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
// draw the check mark
if (vopt->features & QStyleOptionViewItem::HasCheckIndicator) {
QStyleOptionViewItem option(*vopt);
option.rect = checkRect;
option.state = option.state & ~QStyle::State_HasFocus;
switch (vopt->checkState) {
case Qt::Unchecked:
option.state |= QStyle::State_Off;
break;
case Qt::PartiallyChecked:
option.state |= QStyle::State_NoChange;
break;
case Qt::Checked:
option.state |= QStyle::State_On;
break;
default:
break;
}
proxy()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, painter, widget);
}
// draw the icon
QIcon::Mode mode = QIcon::Normal;
if (!(vopt->state & QStyle::State_Enabled)) {
mode = QIcon::Disabled;
} else if (vopt->state & QStyle::State_Selected) {
mode = QIcon::Selected;
}
QIcon::State state = vopt->state & QStyle::State_Open ? QIcon::On : QIcon::Off;
auto pixmap = vopt->icon.pixmap(vopt->decorationSize, mode, state);
iconRect.moveLeft(8);
QStyle::drawItemPixmap(painter, iconRect, vopt->decorationAlignment, pixmap);
painter->restore();
return;
}
break;
}
default:
break;
}
}

View File

@ -26,6 +26,7 @@
#include <QStyle>
#include <QTextDocument>
#include <QAbstractTextDocumentLayout>
#include <QProxyStyle>
#include "global-settings.h"
namespace UkuiSearch {
@ -43,6 +44,16 @@ private:
QString getHtmlText(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const;
QString escapeHtml(const QString&) const;
};
class ResultItemStyle : public QProxyStyle
{
public:
static ResultItemStyle *getStyle();
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override;
private:
explicit ResultItemStyle() {}
~ResultItemStyle() = default;
};
}
#endif // RESULTVIEWDELEGATE_H

View File

@ -160,6 +160,7 @@ void ResultWidget::initConnections()
ResultView::ResultView(const QString &plugin_id, QWidget *parent) : QTreeView(parent)
{
setStyle(ResultItemStyle::getStyle());
this->setFrameShape(QFrame::NoFrame);
this->viewport()->setAutoFillBackground(false);
this->setIconSize(QSize(VIEW_ICON_SIZE, VIEW_ICON_SIZE));

View File

@ -46,16 +46,17 @@ struct SKeyWord {
class CHINESESEGMENTATION_EXPORT ChineseSegmentation {
public:
static ChineseSegmentation *getInstance();
~ChineseSegmentation();
QVector<SKeyWord> callSegement(std::string s);
//新添加callSegementStd函数修改返回值为stdvector<cppjieba::KeywordExtractor::Word>并简化内部处理流程--jxx20210517
//修改函数入参形式为引用去掉Qstring与std::string转换代码--jxx20210519
std::vector<cppjieba::KeyWord> callSegementStd(const std::string& str);
private:
explicit ChineseSegmentation();
~ChineseSegmentation();
void convert(std::vector<cppjieba::KeyWord>& keywordres, QVector<SKeyWord>& kw);
private:
static QMutex m_mutex;
cppjieba::Jieba *m_jieba;
explicit ChineseSegmentation();
};

View File

@ -46,6 +46,16 @@ struct IdfElement {
}
};
struct PinYinElement
{
string word;
string tag;
bool operator < (const DatElement & b) const {
return this->word < b.word;
}
};
inline std::ostream & operator << (std::ostream& os, const DatElement & elem) {
return os << "word=" << elem.word << "/tag=" << elem.tag << "/weight=" << elem.weight;
}
@ -64,6 +74,19 @@ struct DatMemElem {
}
};
struct PinYinMemElem {
char tag[6] = {};
void SetTag(const string & str) {
memset(&tag[0], 0, sizeof(tag));
strncpy(&tag[0], str.c_str(), std::min(str.size(), sizeof(tag) - 1));
}
string GetTag() const {
return &tag[0];
}
};
inline std::ostream & operator << (std::ostream& os, const DatMemElem & elem) {
return os << "/tag=" << elem.GetTag() << "/weight=" << elem.weight;
}
@ -122,6 +145,17 @@ public:
return idf_elements_ptr_[ find_result.value ];
}
const PinYinMemElem * PinYinFind(const string & key) const {
JiebaDAT::result_pair_type find_result;
dat_.exactMatchSearch(key.c_str(), find_result);
if ((0 == find_result.length) || (find_result.value < 0) || ((size_t)find_result.value >= elements_num_)) {
return nullptr;
}
return &pinyin_elements_ptr_[ find_result.value ];
}
void Find(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end,
vector<struct DatDag>&res, size_t max_word_len) const {
@ -167,6 +201,7 @@ public:
}
}
/*
void Find_Reverse(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end,
vector<struct DatDag>&res, size_t max_word_len) const {
@ -208,7 +243,8 @@ public:
res[str_size - i - 1].nexts.push_back(pair<size_t, const DatMemElem *>(str_size - 1 - i + char_num, pValue));
}
}
}
}*/
void Find(RuneStrArray::const_iterator begin, RuneStrArray::const_iterator end,
vector<WordRange>& words, size_t max_word_len) const {
@ -300,6 +336,11 @@ public:
return InitIdfAttachDat(dat_cache_file, md5);
}
bool InitBuildDat(vector<PinYinElement>& elements, const string & dat_cache_file, const string & md5) {
BuildDatCache(elements, dat_cache_file, md5);
return InitPinYinAttachDat(dat_cache_file, md5);
}
bool InitAttachDat(const string & dat_cache_file, const string & md5) {
mmap_fd_ = ::open(dat_cache_file.c_str(), O_RDONLY);
@ -362,6 +403,37 @@ public:
return true;
}
bool InitPinYinAttachDat(const string & dat_cache_file, const string & md5) {
mmap_fd_ = ::open(dat_cache_file.c_str(), O_RDONLY);
if (mmap_fd_ < 0) {
return false;
}
const auto seek_off = ::lseek(mmap_fd_, 0, SEEK_END);
assert(seek_off >= 0);
mmap_length_ = seek_off;
mmap_addr_ = reinterpret_cast<char *>(mmap(NULL, mmap_length_, PROT_READ, MAP_SHARED, mmap_fd_, 0));
assert(MAP_FAILED != mmap_addr_);
assert(mmap_length_ >= sizeof(CacheFileHeader));
CacheFileHeader & header = *reinterpret_cast<CacheFileHeader*>(mmap_addr_);
elements_num_ = header.elements_num;
min_weight_ = header.min_weight;
assert(sizeof(header.md5_hex) == md5.size());
if (0 != memcmp(&header.md5_hex[0], md5.c_str(), md5.size())) {
return false;
}
assert(mmap_length_ == sizeof(header) + header.elements_num * sizeof(PinYinMemElem) + header.dat_size * dat_.unit_size());
pinyin_elements_ptr_ = (const PinYinMemElem *)(mmap_addr_ + sizeof(header));
const char * dat_ptr = mmap_addr_ + sizeof(header) + sizeof(PinYinMemElem) * elements_num_;
dat_.set_array(dat_ptr, header.dat_size);
return true;
}
private:
void BuildDatCache(vector<DatElement>& elements, const string & dat_cache_file, const string & md5) {
std::sort(elements.begin(), elements.end());
@ -464,13 +536,64 @@ private:
}
}
void BuildDatCache(vector<PinYinElement>& elements, const string & dat_cache_file, const string & md5) {
//std::sort(elements.begin(), elements.end());
vector<const char*> keys_ptr_vec;
vector<int> values_vec;
vector<PinYinMemElem> mem_elem_vec;
keys_ptr_vec.reserve(elements.size());
values_vec.reserve(elements.size());
mem_elem_vec.reserve(elements.size());
CacheFileHeader header;
header.min_weight = min_weight_;
assert(sizeof(header.md5_hex) == md5.size());
memcpy(&header.md5_hex[0], md5.c_str(), md5.size());
for (size_t i = 0; i < elements.size(); ++i) {
keys_ptr_vec.push_back(elements[i].word.data());
values_vec.push_back(i);
mem_elem_vec.push_back(PinYinMemElem());
auto & mem_elem = mem_elem_vec.back();
mem_elem.SetTag(elements[i].tag);
}
auto const ret = dat_.build(keys_ptr_vec.size(), &keys_ptr_vec[0], NULL, &values_vec[0]);
assert(0 == ret);
header.elements_num = mem_elem_vec.size();
header.dat_size = dat_.size();
{
string tmp_filepath = string(dat_cache_file) + "_XXXXXX";
::umask(S_IWGRP | S_IWOTH);
//const int fd =::mkstemp(&tmp_filepath[0]);
const int fd =::mkstemp((char *)tmp_filepath.data());
qDebug() << "mkstemp :" << errno << tmp_filepath.data();
assert(fd >= 0);
::fchmod(fd, 0644);
auto write_bytes = ::write(fd, (const char *)&header, sizeof(header));
write_bytes += ::write(fd, (const char *)&mem_elem_vec[0], sizeof(mem_elem_vec[0]) * mem_elem_vec.size());
write_bytes += ::write(fd, dat_.array(), dat_.total_size());
assert(write_bytes == sizeof(header) + mem_elem_vec.size() * sizeof(mem_elem_vec[0]) + dat_.total_size());
::close(fd);
const auto rename_ret = ::rename(tmp_filepath.c_str(), dat_cache_file.c_str());
assert(0 == rename_ret);
}
}
DatTrie(const DatTrie &);
DatTrie &operator=(const DatTrie &);
private:
JiebaDAT dat_;
const DatMemElem * elements_ptr_ = nullptr;
const double * idf_elements_ptr_= nullptr;
const double * idf_elements_ptr_ = nullptr;
const PinYinMemElem * pinyin_elements_ptr_ = nullptr;
size_t elements_num_ = 0;
double min_weight_ = 0;

View File

@ -131,6 +131,7 @@ private:
const auto dict_list = dict_path + "|" + user_dict_paths;
size_t file_size_sum = 0;
const string md5 = CalcFileListMD5(dict_list, file_size_sum);
total_dict_size_ = file_size_sum;
if (dat_cache_path.empty()) {
//未指定词库数据文件存储位置的默认存储在tmp目录下--jxx20200519
@ -140,7 +141,6 @@ private:
qDebug() << "#########Dict path:" << path;
if (dat_.InitAttachDat(dat_cache_path, md5)) {
LoadUserDict(user_dict_paths, false); // for load user_dict_single_chinese_word_;
total_dict_size_ = file_size_sum;
return;
}
@ -154,7 +154,6 @@ private:
LoadUserDict(user_dict_paths);
const auto build_ret = dat_.InitBuildDat(static_node_infos_, dat_cache_path, md5);
assert(build_ret);
total_dict_size_ = file_size_sum;
vector<DatElement>().swap(static_node_infos_);
}

View File

@ -39,21 +39,6 @@ public:
return dat_.Find(word, length, node_pos);
}
void Find(RuneStrArray::const_iterator begin,
RuneStrArray::const_iterator end,
vector<struct DatDag>&res,
size_t max_word_len = MAX_WORD_LENGTH) const {
dat_.Find(begin, end, res, max_word_len);
}
bool IsUserDictSingleChineseWord(const Rune& word) const {
return IsIn(user_dict_single_chinese_word_, word);
}
double GetMinWeight() const {
return dat_.GetMinWeight();
}
size_t GetTotalDictSize() const {
return total_dict_size_;
}
@ -63,6 +48,7 @@ private:
UserWordWeightOption user_word_weight_opt) {
size_t file_size_sum = 0;
const string md5 = CalcFileListMD5(dict_path, file_size_sum);
total_dict_size_ = file_size_sum;
if (dat_cache_path.empty()) {
//未指定词库数据文件存储位置的默认存储在tmp目录下--jxx20200519
@ -71,7 +57,6 @@ private:
QString path = QString::fromStdString(dat_cache_path);
qDebug() << "#########Idf path:" << path;
if (dat_.InitIdfAttachDat(dat_cache_path, md5)) {
total_dict_size_ = file_size_sum;
return;
}
@ -85,7 +70,6 @@ private:
const auto build_ret = dat_.InitBuildDat(static_node_infos_, dat_cache_path, md5);
assert(build_ret);
total_dict_size_ = file_size_sum;
vector<IdfElement>().swap(static_node_infos_);
}
@ -128,7 +112,6 @@ private:
vector<IdfElement> static_node_infos_;
size_t total_dict_size_ = 0;
DatTrie dat_;
unordered_set<Rune> user_dict_single_chinese_word_;
};
}

View File

@ -84,6 +84,7 @@ private:
MixSegment segment_;
IdfTrie idf_trie_;
unordered_set<Rune> symbols_;
}; // class KeywordExtractor

View File

@ -0,0 +1,154 @@
#pragma once
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <cstring>
#include <cstdlib>
#include <stdint.h>
#include <cmath>
#include <limits>
#include "limonp/StringUtil.hpp"
#include "limonp/Logging.hpp"
#include "Unicode.hpp"
#include "DatTrie.hpp"
#include <QDebug>
namespace cppjieba {
using namespace limonp;
const size_t PINYIN_COLUMN_NUM = 2;
class PinYinTrie {
public:
enum UserWordWeightOption {
WordWeightMin,
WordWeightMedian,
WordWeightMax,
}; // enum UserWordWeightOption
PinYinTrie(const string& dict_path, const string & dat_cache_path = "",
UserWordWeightOption user_word_weight_opt = WordWeightMedian) {
Init(dict_path, dat_cache_path, user_word_weight_opt);
}
~PinYinTrie() {}
int getMultiTonResults(string word, QStringList &results) {
if (qmap_chinese2pinyin.contains(QString::fromStdString(word))) {
for (auto i:qmap_chinese2pinyin[QString::fromStdString(word)])
results.push_back(i);
return 0;
}
return -1;
}
int getSingleTonResult(string word, QString &result) {
const PinYinMemElem * tmp = dat_.PinYinFind(word);
if (tmp) {
result = QString::fromStdString(tmp->GetTag());
return 0;
}
return -1;
}
bool contains(string &word) {
if (qmap_chinese2pinyin.contains(QString::fromStdString(word))
or !dat_.PinYinFind(word))
return true;
// if (map_chinese2pinyin.contains(word)
// or !dat_.PinYinFind(word))
// return true;
return false;
}
bool isMultiTone(string &word) {
if (qmap_chinese2pinyin.contains(QString::fromStdString(word)))
return true;
// if (map_chinese2pinyin.contains(word))
// return true;
return false;
}
size_t GetTotalDictSize() const {
return total_dict_size_;
}
private:
void Init(const string& dict_path, string dat_cache_path,
UserWordWeightOption user_word_weight_opt) {
size_t file_size_sum = 0;
vector<PinYinElement> node_infos;
const string md5 = CalcFileListMD5(dict_path, file_size_sum);
total_dict_size_ = file_size_sum;
if (dat_cache_path.empty()) {
//未指定词库数据文件存储位置的默认存储在tmp目录下--jxx20200519
dat_cache_path = /*dict_path*/"/tmp/" + md5 + "." + to_string(user_word_weight_opt) + ".dat_cache";
}
QString path = QString::fromStdString(dat_cache_path);
qDebug() << "#########PinYin path:" << path << file_size_sum;
if (dat_.InitPinYinAttachDat(dat_cache_path, md5)) {
//多音字仍需遍历文件信息
LoadDefaultPinYin(node_infos, dict_path, true);
return;
}
LoadDefaultPinYin(node_infos, dict_path, false);
double min_weight = 0;
dat_.SetMinWeight(min_weight);
const auto build_ret = dat_.InitBuildDat(node_infos, dat_cache_path, md5);
assert(build_ret);
vector<PinYinElement>().swap(node_infos);
}
void LoadDefaultPinYin(vector<PinYinElement> &node_infos, const string& filePath, bool multiFlag) {
ifstream ifs(filePath.c_str());
if(not ifs.is_open()){
return ;
}
XCHECK(ifs.is_open()) << "open " << filePath << " failed.";
string line;
vector<string> buf;
size_t lineno = 0;
for (; getline(ifs, line); lineno++) {
if (line.empty()) {
XLOG(ERROR) << "lineno: " << lineno << " empty. skipped.";
continue;
}
Split(line, buf, " ");
if (buf.size() == PINYIN_COLUMN_NUM) {
if (multiFlag) {//非多音字
continue;
}
PinYinElement node_info;
node_info.word = buf[1];
node_info.tag = buf[0];
node_infos.push_back(node_info);
} else {//多音字
QString content = QString::fromUtf8(line.c_str());
qmap_chinese2pinyin[content.split(" ").last().trimmed()] = content.split(" ");
qmap_chinese2pinyin[content.split(" ").last().trimmed()].pop_back();
/*
//std map string list
list<string> tmpList;
for(int i = 0; i < buf.size() - 1; ++i){
tmpList.push_back(buf[i]);
}
map[buf[buf.size() - 1]] = tmpList;
*/
}
}
}
private:
QMap<QString, QStringList> qmap_chinese2pinyin;
//map<string, list<string>> map_chinese2pinyin;
size_t total_dict_size_ = 0;
DatTrie dat_;
};
}

View File

@ -3,6 +3,7 @@ INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/DictTrie.hpp \
$$PWD/IdfTrie.hpp \
$$PWD/PinYinTrie.hpp \
$$PWD/FullSegment.hpp \
$$PWD/HMMModel.hpp \
$$PWD/HMMSegment.hpp \

View File

@ -23,14 +23,17 @@ include(cppjieba/cppjieba.pri)
SOURCES += \
chinese-segmentation.cpp \
pinyinmanager.cpp
HEADERS += \
chinese-segmentation.h \
libchinese-segmentation_global.h
libchinese-segmentation_global.h \
pinyinmanager.h
dict_files.path = /usr/share/ukui-search/res/dict/
dict_files.files = $$PWD/dict/*.utf8\
dict_files.files += $$PWD/dict/pos_dict/*.utf8\
dict_files.files += $$PWD/dict/*.txt\
INSTALLS += \
dict_files \
@ -60,5 +63,6 @@ DISTFILES += \
dict/pos_dict/prob_start.utf8 \
dict/pos_dict/prob_trans.utf8 \
dict/stop_words.utf8 \
dict/user.dict.utf8
dict/user.dict.utf8 \
dict/pinyinWithoutTone.txt

View File

@ -0,0 +1,55 @@
#include "pinyinmanager.h"
#include <mutex>
PinYinManager * PinYinManager::g_pinYinManager = nullptr;
std::once_flag g_singleFlag;
PinYinManager * PinYinManager::getInstance()
{
call_once(g_singleFlag, []() {
g_pinYinManager = new PinYinManager;
});
return g_pinYinManager;
}
bool PinYinManager::contains(string &word)
{
return m_pinYinTrie->contains(word);
}
bool PinYinManager::isMultiTon(string &word)
{
return m_pinYinTrie->isMultiTone(word);
}
bool PinYinManager::isMultiTon(string word)
{
return m_pinYinTrie->isMultiTone(word);
}
int PinYinManager::getResults(string word, QStringList &results)
{
results.clear();
if (-1 != m_pinYinTrie->getMultiTonResults(word, results)) {
return 0;
}
QString tmp;
if (-1 != m_pinYinTrie->getSingleTonResult(word, tmp)) {
results.append(tmp);
return 0;
}
return -1;
}
PinYinManager::PinYinManager()
{
const char * const PINYIN_PATH = "/usr/share/ukui-search/res/dict/pinyinWithoutTone.txt";
m_pinYinTrie = new cppjieba::PinYinTrie(PINYIN_PATH);
}
PinYinManager::~PinYinManager()
{
if (m_pinYinTrie){
delete m_pinYinTrie;
m_pinYinTrie = nullptr;
}
}

View File

@ -0,0 +1,33 @@
#ifndef PINYINMANAGER_H
#define PINYINMANAGER_H
#include <QtCore/qglobal.h>
#include "cppjieba/PinYinTrie.hpp"
#define PINYINMANAGER_EXPORT Q_DECL_IMPORT
using namespace std;
class PINYINMANAGER_EXPORT PinYinManager
{
public:
static PinYinManager * getInstance();
public:
bool contains(string &word);
bool isMultiTon(string &word);
bool isMultiTon(string word);
int getResults(string word, QStringList &results);
protected:
PinYinManager();
~PinYinManager();
private:
static PinYinManager *g_pinYinManager;
cppjieba::PinYinTrie *m_pinYinTrie = nullptr;
};
#endif // PINYINMANAGER_H

View File

@ -44,6 +44,13 @@ void AppSearchPlugin::KeywordSearch(QString keyword, DataQueue<SearchPluginIface
m_pool.start(appsearch);
}
void AppSearchPlugin::stopSearch()
{
m_mutex.lock();
++uniqueSymbol;
m_mutex.unlock();
}
QList<SearchPluginIface::Actioninfo> AppSearchPlugin::getActioninfo(int type)
{
switch (type) {
@ -99,9 +106,11 @@ QWidget *AppSearchPlugin::detailPage(const ResultInfo &ri)
m_iconLabel->setPixmap(ri.icon.pixmap(120, 120));
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
QString showname = fontMetrics.elidedText(ri.name, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(FileUtils::escapeHtml(showname)));
m_nameLabel->setText(FileUtils::setAllTextBold(showname));
if(QString::compare(showname, ri.name)) {
m_nameLabel->setToolTip(ri.name);
} else {
m_nameLabel->setToolTip("");
}
m_pluginLabel->setText(tr("Application"));
if(ri.type == 1) {
@ -148,10 +157,7 @@ void AppSearchPlugin::initDetailPage()
m_nameFrameLyt->addStretch();
m_nameFrameLyt->addWidget(m_pluginLabel);
m_line_1 = new QFrame(m_detailPage);
m_line_1->setLineWidth(0);
m_line_1->setFixedHeight(1);
m_line_1->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_1 = new SeparationLine(m_detailPage);
m_descFrame = new QFrame(m_detailPage);
m_descFrameLyt = new QVBoxLayout(m_descFrame);
m_descLabel = new QLabel(m_descFrame);
@ -160,10 +166,7 @@ void AppSearchPlugin::initDetailPage()
m_descFrameLyt->addWidget(m_descLabel);
m_descFrame->setLayout(m_descFrameLyt);
m_descFrameLyt->setContentsMargins(8, 0, 0, 0);
m_line_2 = new QFrame(m_detailPage);
m_line_2->setLineWidth(0);
m_line_2->setFixedHeight(1);
m_line_2->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_2 = new SeparationLine(m_detailPage);
m_actionFrame = new QFrame(m_detailPage);
m_actionFrameLyt = new QVBoxLayout(m_actionFrame);

View File

@ -11,6 +11,7 @@
#include "search-plugin-iface.h"
#include "app-match.h"
#include "action-label.h"
#include "separation-line.h"
#include "libsearch_global.h"
namespace UkuiSearch {
class LIBSEARCH_EXPORT AppSearchPlugin : public QObject, public SearchPluginIface
@ -29,6 +30,7 @@ public:
QString getPluginName();
void KeywordSearch(QString keyword,DataQueue<ResultInfo> *searchResult);
void stopSearch();
QList<SearchPluginIface::Actioninfo> getActioninfo(int type);
void openAction(int actionkey, QString key, int type);
// bool isPreviewEnable(QString key, int type);
@ -55,11 +57,11 @@ private:
QHBoxLayout *m_nameFrameLyt = nullptr;
QLabel *m_nameLabel = nullptr;
QLabel *m_pluginLabel = nullptr;
QFrame *m_line_1 = nullptr;
SeparationLine *m_line_1 = nullptr;
QFrame *m_descFrame = nullptr;
QLabel *m_descLabel = nullptr;
QVBoxLayout *m_descFrameLyt = nullptr;
QFrame *m_line_2 = nullptr;
SeparationLine *m_line_2 = nullptr;
QFrame *m_actionFrame = nullptr;
QVBoxLayout *m_actionFrameLyt = nullptr;
ActionLabel *m_actionLabel1 = nullptr;

View File

@ -27,5 +27,11 @@ static const QMap<QString, bool> targetFileTypeMap = {
std::map<QString, bool>::value_type("et", true),
std::map<QString, bool>::value_type("pdf", true)
};
static const QMap<QString, bool> targetPhotographTypeMap = {
std::map<QString, bool>::value_type("png", true),
std::map<QString, bool>::value_type("jpg", true),
std::map<QString, bool>::value_type("jpeg", true)//TODO 待完善,后续改为配置文件
};
//TODO Put things that needed to be put here here.
#endif // COMMON_H

View File

@ -27,6 +27,7 @@
#include <QDBusConnection>
#include <QDomDocument>
#include "gobject-template.h"
#include "pinyinmanager.h"
using namespace UkuiSearch;
size_t FileUtils::_max_index_count = 0;
@ -58,7 +59,7 @@ QIcon FileUtils::getFileIcon(const QString &uri, bool checkValid) {
nullptr,
nullptr));
if(!G_IS_FILE_INFO(info.get()->get()))
return QIcon::fromTheme("unknown",QIcon(":res/icons/unknown.png"));
return QIcon::fromTheme("unknown",QIcon(":/res/icons/unknown.svg"));
GIcon *g_icon = g_file_info_get_icon(info.get()->get());
//do not unref the GIcon from info.
@ -76,7 +77,7 @@ QIcon FileUtils::getFileIcon(const QString &uri, bool checkValid) {
}
}
}
return QIcon::fromTheme("unknown",QIcon(":res/icons/unknown.png"));
return QIcon::fromTheme("unknown",QIcon(":/res/icons/unknown.svg"));
}
/**
@ -91,7 +92,7 @@ QIcon FileUtils::getAppIcon(const QString &path) {
keyfile = g_key_file_new();
if(!g_key_file_load_from_file(keyfile, ba.data(), G_KEY_FILE_NONE, NULL)) {
g_key_file_free(keyfile);
return QIcon::fromTheme("unknown",QIcon(":res/icons/unknown.png"));
return QIcon::fromTheme("unknown",QIcon(":/res/icons/unknown.svg"));
}
QString icon = QString(g_key_file_get_locale_string(keyfile, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, NULL, NULL));
g_key_file_free(keyfile);
@ -107,7 +108,7 @@ QIcon FileUtils::getAppIcon(const QString &path) {
* @param is_white
* @return
*/
QIcon FileUtils::getSettingIcon(const QString& setting, const bool& is_white) {
QIcon FileUtils::getSettingIcon(const QString &setting, const bool is_white) {
QString name = setting.left(setting.indexOf("/"));
if(! name.isEmpty()) {
name.replace(QString(name.at(0)), QString(name.at(0).toUpper()));
@ -122,7 +123,7 @@ QIcon FileUtils::getSettingIcon(const QString& setting, const bool& is_white) {
if(file.exists()) {
return QIcon(path);
} else {
return QIcon::fromTheme("ukui-control-center"); //无插件图标时,返回控制面板应用图标
return QIcon::fromTheme("ukui-control-center", QIcon(":/res/icons/ukui-control-center.svg")); //无插件图标时,返回控制面板应用图标
// if (is_white) {
// return QIcon(QString("/usr/share/ukui-control-center/shell/res/secondaryleftmenu/%1White.svg").arg("About"));
// } else {
@ -132,7 +133,7 @@ QIcon FileUtils::getSettingIcon(const QString& setting, const bool& is_white) {
}
QIcon FileUtils::getSettingIcon() {
return QIcon::fromTheme("ukui-control-center"); //返回控制面板应用图标
return QIcon::fromTheme("ukui-control-center", QIcon(":/res/icons/ukui-control-center.svg")); //返回控制面板应用图标
}
/**
@ -140,7 +141,7 @@ QIcon FileUtils::getSettingIcon() {
* @param uri "file:///home/xxx/xxx/xxxx.txt"
* @return
*/
QString FileUtils::getFileName(const QString& uri) {
QString FileUtils::getFileName(const QString &uri) {
QFileInfo info(uri);
if(info.exists()) {
return info.fileName();
@ -159,7 +160,7 @@ QString FileUtils::getFileName(const QString& uri) {
* @param path .destop文件的完整路径
* @return
*/
QString FileUtils::getAppName(const QString& path) {
QString FileUtils::getAppName(const QString &path) {
QByteArray ba;
ba = path.toUtf8();
GKeyFile * keyfile;
@ -178,7 +179,7 @@ QString FileUtils::getAppName(const QString& path) {
* @param setting About/About->Properties
* @return
*/
QString FileUtils::getSettingName(const QString& setting) {
QString FileUtils::getSettingName(const QString &setting) {
return setting.right(setting.length() - setting.lastIndexOf("/") - 1);
}
@ -242,7 +243,7 @@ QString FileUtils::find(const QString &hanzi) {
}
//DFS多音字太多直接GG
void stitchMultiToneWordsDFS(const QString& hanzi, const QString& resultAllPinYin, const QString& resultFirst, QStringList& resultList) {
void stitchMultiToneWordsDFS(const QString &hanzi, const QString &resultAllPinYin, const QString &resultFirst, QStringList &resultList) {
if(hanzi.size() == 0) {
resultList.append(resultAllPinYin);
resultList.append(resultFirst);
@ -258,7 +259,7 @@ void stitchMultiToneWordsDFS(const QString& hanzi, const QString& resultAllPinYi
}
//BFS+Stack多音字太多会爆栈
void stitchMultiToneWordsBFSStack(const QString& hanzi, QStringList& resultList) {
void stitchMultiToneWordsBFSStack(const QString &hanzi, QStringList &resultList) {
QString tempHanzi, resultAllPinYin, resultFirst;
QQueue<QString> tempQueue;
tempHanzi = hanzi;
@ -293,7 +294,7 @@ void stitchMultiToneWordsBFSStack(const QString& hanzi, QStringList& resultList)
}
}
//BFS+Heap多音字太多会耗尽内存
void stitchMultiToneWordsBFSHeap(const QString& hanzi, QStringList& resultList) {
void stitchMultiToneWordsBFSHeap(const QString &hanzi, QStringList &resultList) {
QString tempHanzi, resultAllPinYin, resultFirst;
QQueue<QString>* tempQueue = new QQueue<QString>;
tempHanzi = hanzi;
@ -331,7 +332,7 @@ void stitchMultiToneWordsBFSHeap(const QString& hanzi, QStringList& resultList)
}
//BFS+Heap+超过3个多音字只建一个索引比较折中的方案
void stitchMultiToneWordsBFSHeapLess3(const QString& hanzi, QStringList& resultList) {
void stitchMultiToneWordsBFSHeapLess3(const QString &hanzi, QStringList &resultList) {
QString tempHanzi, resultAllPinYin, resultFirst;
QQueue<QString>* tempQueue = new QQueue<QString>;
QQueue<QString>* tempQueueFirst = new QQueue<QString>;
@ -404,26 +405,26 @@ void stitchMultiToneWordsBFSHeapLess3(const QString& hanzi, QStringList& resultL
}
//BFS+Stack+超过3个多音字只建一个索引比较折中的方案
void stitchMultiToneWordsBFSStackLess3(const QString& hanzi, QStringList& resultList) {
QString tempHanzi, resultAllPinYin, resultFirst;
void stitchMultiToneWordsBFSStackLess3(const QString &hanzi, QStringList &resultList) {
QString tempHanzi;
QQueue<QString> tempQueue;
QQueue<QString> tempQueueFirst;
tempHanzi = hanzi;
int tempQueueSize = 0;
int multiToneWordNum = 0;
for(auto i : hanzi) {
if(FileUtils::map_chinese2pinyin.contains(i)) {
if(FileUtils::map_chinese2pinyin[i].size() > 1) {
++multiToneWordNum;
}
}
for (auto i:hanzi) {
if (PinYinManager::getInstance()->isMultiTon(QString(i).toStdString()))
++multiToneWordNum;
}
if(multiToneWordNum > 3) {
QString oneResult, oneResultFirst;
for(auto i : hanzi) {
if(FileUtils::map_chinese2pinyin.contains(i)) {
oneResult += FileUtils::map_chinese2pinyin[i].first();
oneResultFirst += FileUtils::map_chinese2pinyin[i].first().at(0);
QStringList results;
PinYinManager::getInstance()->getResults(QString(i).toStdString(), results);
if(results.size()) {
oneResult += results.first();
oneResultFirst += results.first().at(0);
} else {
oneResult += i;
oneResultFirst += i;
@ -434,8 +435,10 @@ void stitchMultiToneWordsBFSStackLess3(const QString& hanzi, QStringList& result
return;
}
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
QStringList results;
PinYinManager::getInstance()->getResults(QString(tempHanzi.at(0)).toStdString(), results);
if(results.size()) {
for(auto i : results) {
tempQueue.enqueue(i);
tempQueueFirst.enqueue(i.at(0));
}
@ -445,10 +448,11 @@ void stitchMultiToneWordsBFSStackLess3(const QString& hanzi, QStringList& result
}
tempHanzi = tempHanzi.right(tempHanzi.size() - 1);
while(tempHanzi.size() != 0) {
PinYinManager::getInstance()->getResults(QString(tempHanzi.at(0)).toStdString(), results);
tempQueueSize = tempQueue.size();
if(FileUtils::map_chinese2pinyin.contains(tempHanzi.at(0))) {
if(results.size()) {
for(int j = 0; j < tempQueueSize; ++j) {
for(auto i : FileUtils::map_chinese2pinyin[tempHanzi.at(0)]) {
for(auto i : results) {
tempQueue.enqueue(tempQueue.head() + i);
tempQueueFirst.enqueue(tempQueueFirst.head() + i.at(0));
}
@ -469,22 +473,12 @@ void stitchMultiToneWordsBFSStackLess3(const QString& hanzi, QStringList& result
resultList.append(tempQueue.dequeue());
resultList.append(tempQueueFirst.dequeue());
}
// delete tempQueue;
// delete tempQueueFirst;
// tempQueue = nullptr;
// tempQueueFirst = nullptr;
return;
}
QStringList FileUtils::findMultiToneWords(const QString& hanzi) {
// QStringList* output = new QStringList();
QStringList FileUtils::findMultiToneWords(const QString &hanzi) {
QStringList output;
QString tempAllPinYin, tempFirst;
QStringList stringList = hanzi.split("");
// stitchMultiToneWordsDFS(hanzi, tempAllPinYin, tempFirst, output);
stitchMultiToneWordsBFSStackLess3(hanzi, output);
// qDebug() << output;
return output;
}
@ -779,6 +773,7 @@ void FileUtils::getTxtContent(QString &path, QString &textcontent) {
int FileUtils::openFile(QString &path, bool openInDir)
{
int res = -1;
if(openInDir) {
QStringList list;
list.append(path);
@ -787,12 +782,12 @@ int FileUtils::openFile(QString &path, bool openInDir)
"org.freedesktop.FileManager1",
"ShowItems");
message.setArguments({list, "ukui-search"});
QDBusMessage res = QDBusConnection::sessionBus().call(message);
if (QDBusMessage::ReplyMessage == res.ReplyMessage) {
return 0;
QDBusMessage messageRes = QDBusConnection::sessionBus().call(message);
if (QDBusMessage::ReplyMessage == messageRes.ReplyMessage) {
res = 0;
} else {
qDebug() << "Error! QDBusMessage reply error! ReplyMessage:" << res.ReplyMessage;
return -1;
qDebug() << "Error! QDBusMessage reply error! ReplyMessage:" << messageRes.ReplyMessage;
res = -1;
}
} else {
auto file = wrapGFile(g_file_new_for_uri(QUrl::fromLocalFile(path).toString().toUtf8().constData()));
@ -807,6 +802,7 @@ int FileUtils::openFile(QString &path, bool openInDir)
mimeType = g_file_info_get_attribute_string(fileInfo.get()->get(), "standard::fast-content-type");
}
}
GError *error = NULL;
GAppInfo *info = NULL;
/*
@ -832,11 +828,14 @@ int FileUtils::openFile(QString &path, bool openInDir)
}
g_key_file_free (keyfile);
if(!G_IS_APP_INFO(info)) {
return -1;
res = -1;
} else {
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
res = 0;
}
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
return 0;
g_object_unref(info);
}
return res;
}
bool FileUtils::copyPath(QString &path)
@ -983,7 +982,12 @@ QString FileUtils::getHtmlText(const QString &text, const QString &keyword)
}
}
htmlString.replace("\n", "<br />");//替换换行符
return htmlString;
return "<pre>" + htmlString + "</pre>";
}
QString FileUtils::setAllTextBold(const QString &name)
{
return QString("<h3 style=\"font-weight:normal;\"><pre>%1</pre></h3>").arg(escapeHtml(name));
}
QString FileUtils::wrapData(QLabel *p_label, const QString &text)

View File

@ -51,7 +51,6 @@
#include <uchardet/uchardet.h>
//#include <poppler-qt5.h>
#include <poppler/qt5/poppler-qt5.h>
#include <common.h>
#include "libsearch_global.h"
#include "common.h"
@ -62,25 +61,26 @@
namespace UkuiSearch {
class LIBSEARCH_EXPORT FileUtils {
public:
static QString getHtmlText(const QString & text, const QString & keyword);
static QString getHtmlText(const QString &text, const QString &keyword);
static QString setAllTextBold(const QString &name);
static QString wrapData(QLabel *p_label, const QString &text);
static std::string makeDocUterm(QString);
static QIcon getFileIcon(const QString &, bool checkValid = true);
static QIcon getAppIcon(const QString &);
static QIcon getSettingIcon(const QString &, const bool&);
static std::string makeDocUterm(QString path);
static QIcon getFileIcon(const QString &uri, bool checkValid = true);
static QIcon getAppIcon(const QString &path);
static QIcon getSettingIcon(const QString &setting, const bool is_white);
static QIcon getSettingIcon();
static QString getFileName(const QString &);
static QString getAppName(const QString &);
static QString getSettingName(const QString &);
static QString getFileName(const QString &uri);
static QString getAppName(const QString &path);
static QString getSettingName(const QString &setting);
//A is or under B
static bool isOrUnder(QString pathA, QString pathB);
//chinese character to pinyin
static QMap<QString, QStringList> map_chinese2pinyin;
static QString find(const QString&);
static QStringList findMultiToneWords(const QString&);
static void loadHanziTable(const QString&);
static QString find(const QString &hanzi);
static QStringList findMultiToneWords(const QString &hanzi);
static void loadHanziTable(const QString &fileName);
//parse text,docx.....
static QMimeType getMimetype(QString &path);
@ -92,9 +92,9 @@ public:
static int openFile(QString &path, bool openInDir = false);
static bool copyPath(QString &path);
static QString escapeHtml(const QString & str);
static QString escapeHtml(const QString &str);
static QString chineseSubString(const std::string &myStr,int start,int length);
static QIcon iconFromTheme(const QString& name, const QIcon &iconDefault);
static QIcon iconFromTheme(const QString &name, const QIcon &iconDefault);
static bool isOpenXMLFileEncrypted(QString &path);
static bool isEncrypedOrUnreadable(QString path);
static size_t _max_index_count;

View File

@ -130,3 +130,40 @@ void ConstructDocumentForContent::run() {
return;
}
ConstructDocumentForOcr::ConstructDocumentForOcr(QString path)
{
this->setAutoDelete(true);
m_path = std::move(path);
}
void ConstructDocumentForOcr::run()
{
QString content;
FileReader::getTextContent(m_path, content);
Document doc;
doc.setUniqueTerm(FileUtils::makeDocUterm(m_path));
doc.addTerm("ZEEKERUPTERM" + FileUtils::makeDocUterm(m_path.section("/", 0, -2, QString::SectionIncludeLeadingSep)));
doc.addValue(1, m_path);
if(content.isEmpty()) {
doc.reuireDeleted();
} else {
doc.setData(content);
//'\xEF\xBC\x8C' is "" "\xE3\x80\x82" is "。" use three " " to replace ,to ensure the offset info.
content = content.replace("\t", " ").replace("\xEF\xBC\x8C", " ").replace("\xE3\x80\x82", " ");
std::vector<cppjieba::KeyWord> term = ChineseSegmentation::getInstance()->callSegementStd(content.toStdString());
for(size_t i = 0; i < term.size(); ++i) {
doc.addPosting(term.at(i).word, term.at(i).offsets, static_cast<int>(term.at(i).weight));
}
term.clear();
term.shrink_to_fit();
}
IndexGenerator::g_mutexDocListForOcr.lock();
IndexGenerator::g_docListForOcr.append(doc);
IndexGenerator::g_mutexDocListForOcr.unlock();
content.clear();
content.squeeze();
}

View File

@ -48,6 +48,16 @@ protected:
private:
QString m_path;
};
class ConstructDocumentForOcr : public QRunnable {
public:
explicit ConstructDocumentForOcr(QString path);
~ConstructDocumentForOcr() = default;
protected:
void run();
private:
QString m_path;
};
}
#endif // CONSTRUCTDOCUMENT_H

View File

@ -20,6 +20,7 @@
#include "file-reader.h"
#include "file-utils.h"
#include "binary-parser.h"
#include "ocrobject.h"
using namespace UkuiSearch;
FileReader::FileReader(QObject *parent) : QObject(parent) {
@ -41,6 +42,8 @@ void FileReader::getTextContent(QString path, QString &textContent) {
searchdata.RunParser(path, textContent);
} else if (strsfx == "pdf") {
FileUtils::getPdfTextContent(path, textContent);
} else if (strsfx == "png" || strsfx == "jpg" || strsfx == "jpeg"){
OcrObject::getInstance()->getTxtContent(path, textContent);;
}
return;
}

View File

@ -49,6 +49,13 @@ void UkuiSearch::FileSearchPlugin::KeywordSearch(QString keyword, DataQueue<Resu
}
}
void FileSearchPlugin::stopSearch()
{
SearchManager::m_mutexFile.lock();
++SearchManager::uniqueSymbolFile;
SearchManager::m_mutexFile.unlock();
}
QList<SearchPluginIface::Actioninfo> FileSearchPlugin::getActioninfo(int type)
{
return m_actionInfo;
@ -86,10 +93,12 @@ QWidget *FileSearchPlugin::detailPage(const ResultInfo &ri)
m_iconLabel->setPixmap(ri.icon.pixmap(120, 120));
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
QString showname = fontMetrics.elidedText(ri.name, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(FileUtils::escapeHtml(showname)));
//if(QString::compare(showname, ri.name)) {
m_nameLabel->setText(FileUtils::setAllTextBold(showname));
if(QString::compare(showname, ri.name)) {
m_nameLabel->setToolTip(ri.name);
//}
} else {
m_nameLabel->setToolTip("");
}
m_pluginLabel->setText(tr("File"));
m_pathLabel2->setText(m_pathLabel2->fontMetrics().elidedText(m_currentActionKey, Qt::ElideRight, m_pathLabel2->width()));
@ -121,10 +130,7 @@ void FileSearchPlugin::initDetailPage()
m_nameFrameLyt->addStretch();
m_nameFrameLyt->addWidget(m_pluginLabel);
m_line_1 = new QFrame(m_detailPage);
m_line_1->setLineWidth(0);
m_line_1->setFixedHeight(1);
m_line_1->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_1 = new SeparationLine(m_detailPage);
m_pathFrame = new QFrame(m_detailPage);
m_pathFrameLyt = new QHBoxLayout(m_pathFrame);
@ -147,10 +153,7 @@ void FileSearchPlugin::initDetailPage()
m_timeFrameLyt->addStretch();
m_timeFrameLyt->addWidget(m_timeLabel2);
m_line_2 = new QFrame(m_detailPage);
m_line_2->setLineWidth(0);
m_line_2->setFixedHeight(1);
m_line_2->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_2 = new SeparationLine(m_detailPage);
m_actionFrame = new QFrame(m_detailPage);
m_actionFrameLyt = new QVBoxLayout(m_actionFrame);
@ -256,6 +259,13 @@ void UkuiSearch::DirSearchPlugin::KeywordSearch(QString keyword, DataQueue<Resul
}
}
void DirSearchPlugin::stopSearch()
{
SearchManager::m_mutexDir.lock();
++SearchManager::uniqueSymbolDir;
SearchManager::m_mutexDir.unlock();
}
QList<SearchPluginIface::Actioninfo> DirSearchPlugin::getActioninfo(int type)
{
return m_actionInfo;
@ -283,10 +293,12 @@ QWidget *DirSearchPlugin::detailPage(const ResultInfo &ri)
m_iconLabel->setPixmap(ri.icon.pixmap(120, 120));
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
QString showname = fontMetrics.elidedText(ri.name, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(FileUtils::escapeHtml(showname)));
//if(QString::compare(showname, ri.name)) {
m_nameLabel->setText(FileUtils::setAllTextBold(showname));
if(QString::compare(showname, ri.name)) {
m_nameLabel->setToolTip(ri.name);
//}
} else {
m_nameLabel->setToolTip("");
}
m_pluginLabel->setText(tr("directory"));
m_pathLabel2->setText(m_pathLabel2->fontMetrics().elidedText(m_currentActionKey, Qt::ElideRight, m_pathLabel2->width()));
@ -318,10 +330,7 @@ void DirSearchPlugin::initDetailPage()
m_nameFrameLyt->addStretch();
m_nameFrameLyt->addWidget(m_pluginLabel);
m_line_1 = new QFrame(m_detailPage);
m_line_1->setLineWidth(0);
m_line_1->setFixedHeight(1);
m_line_1->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_1 = new SeparationLine(m_detailPage);
m_pathFrame = new QFrame(m_detailPage);
m_pathFrameLyt = new QHBoxLayout(m_pathFrame);
@ -344,10 +353,7 @@ void DirSearchPlugin::initDetailPage()
m_timeFrameLyt->addStretch();
m_timeFrameLyt->addWidget(m_timeLabel2);
m_line_2 = new QFrame(m_detailPage);
m_line_2->setLineWidth(0);
m_line_2->setFixedHeight(1);
m_line_2->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_2 = new SeparationLine(m_detailPage);
m_actionFrame = new QFrame(m_detailPage);
m_actionFrameLyt = new QVBoxLayout(m_actionFrame);
@ -435,6 +441,13 @@ void UkuiSearch::FileContengSearchPlugin::KeywordSearch(QString keyword, DataQue
}
}
void FileContengSearchPlugin::stopSearch()
{
SearchManager::m_mutexContent.lock();
++SearchManager::uniqueSymbolContent;
SearchManager::m_mutexContent.unlock();
}
QList<SearchPluginIface::Actioninfo> FileContengSearchPlugin::getActioninfo(int type)
{
return m_actionInfo;
@ -464,10 +477,12 @@ QWidget *FileContengSearchPlugin::detailPage(const ResultInfo &ri)
m_pluginLabel->setText(tr("File"));
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
QString showname = fontMetrics.elidedText(ri.name, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(FileUtils::escapeHtml(showname)));
//if(QString::compare(showname, ri.name)) {
m_nameLabel->setText(FileUtils::setAllTextBold(showname));
if(QString::compare(showname, ri.name)) {
m_nameLabel->setToolTip(ri.name);
//}
} else {
m_nameLabel->setToolTip("");
}
m_snippetLabel->setText(getHtmlText(wrapData(m_snippetLabel,ri.description.at(0).value), m_keyWord));
m_pathLabel2->setText(m_pathLabel2->fontMetrics().elidedText(m_currentActionKey, Qt::ElideRight, m_pathLabel2->width()));
@ -496,7 +511,7 @@ QString FileContengSearchPlugin::getHtmlText(const QString &text, const QString
}
}
htmlString.replace("\n", "<br />");//替换换行符
return htmlString;
return "<pre>" + htmlString + "</pre>";
}
QString FileContengSearchPlugin::wrapData(QLabel *p_label, const QString &text)
@ -555,10 +570,7 @@ void FileContengSearchPlugin::initDetailPage()
m_nameFrameLyt->addStretch();
m_nameFrameLyt->addWidget(m_pluginLabel);
m_line_1 = new QFrame(m_detailPage);
m_line_1->setLineWidth(0);
m_line_1->setFixedHeight(1);
m_line_1->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_1 = new SeparationLine(m_detailPage);
m_snippetLabel = new QLabel(m_detailPage);
// m_snippetLabel->setWordWrap(true);
@ -585,10 +597,7 @@ void FileContengSearchPlugin::initDetailPage()
m_timeFrameLyt->addStretch();
m_timeFrameLyt->addWidget(m_timeLabel2);
m_line_2 = new QFrame(m_detailPage);
m_line_2->setLineWidth(0);
m_line_2->setFixedHeight(1);
m_line_2->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_2 = new SeparationLine(m_detailPage);
m_actionFrame = new QFrame(m_detailPage);
m_actionFrameLyt = new QVBoxLayout(m_actionFrame);

View File

@ -14,6 +14,7 @@
#include "search-plugin-iface.h"
#include "common.h"
#include "action-label.h"
#include "separation-line.h"
namespace UkuiSearch {
//internal plugin
class LIBSEARCH_EXPORT FileSearchPlugin : public QObject, public SearchPluginIface
@ -30,6 +31,7 @@ public:
QString getPluginName();
void KeywordSearch(QString keyword,DataQueue<ResultInfo> *searchResult);
void stopSearch();
QList<SearchPluginIface::Actioninfo> getActioninfo(int type);
void openAction(int actionkey, QString key, int type = 0);
// bool isPreviewEnable(QString key, int type);
@ -46,7 +48,7 @@ private:
QHBoxLayout *m_nameFrameLyt = nullptr;
QLabel *m_nameLabel = nullptr;
QLabel *m_pluginLabel = nullptr;
QFrame *m_line_1 = nullptr;
SeparationLine *m_line_1 = nullptr;
QFrame *m_pathFrame = nullptr;
QLabel *m_pathLabel1 = nullptr;
QLabel *m_pathLabel2 = nullptr;
@ -56,7 +58,7 @@ private:
QLabel *m_timeLabel2 = nullptr;
QHBoxLayout *m_timeFrameLyt = nullptr;
QFrame *m_line_2 = nullptr;
SeparationLine *m_line_2 = nullptr;
QFrame *m_actionFrame = nullptr;
QVBoxLayout *m_actionFrameLyt = nullptr;
ActionLabel *m_actionLabel1 = nullptr;
@ -84,6 +86,7 @@ public:
QString getPluginName();
void KeywordSearch(QString keyword,DataQueue<ResultInfo> *searchResult);
void stopSearch();
QList<SearchPluginIface::Actioninfo> getActioninfo(int type);
void openAction(int actionkey, QString key, int type = 0);
// bool isPreviewEnable(QString key, int type);
@ -99,7 +102,7 @@ private:
QHBoxLayout *m_nameFrameLyt = nullptr;
QLabel *m_nameLabel = nullptr;
QLabel *m_pluginLabel = nullptr;
QFrame *m_line_1 = nullptr;
SeparationLine *m_line_1 = nullptr;
QFrame *m_pathFrame = nullptr;
QLabel *m_pathLabel1 = nullptr;
QLabel *m_pathLabel2 = nullptr;
@ -109,7 +112,7 @@ private:
QLabel *m_timeLabel2 = nullptr;
QHBoxLayout *m_timeFrameLyt = nullptr;
QFrame *m_line_2 = nullptr;
SeparationLine *m_line_2 = nullptr;
QFrame *m_actionFrame = nullptr;
QVBoxLayout *m_actionFrameLyt = nullptr;
ActionLabel *m_actionLabel1 = nullptr;
@ -137,6 +140,7 @@ public:
QString getPluginName();
void KeywordSearch(QString keyword,DataQueue<ResultInfo> *searchResult);
void stopSearch();
QList<SearchPluginIface::Actioninfo> getActioninfo(int type);
void openAction(int actionkey, QString key, int type = 0);
// bool isPreviewEnable(QString key, int type);
@ -154,7 +158,7 @@ private:
QHBoxLayout *m_nameFrameLyt = nullptr;
QLabel *m_nameLabel = nullptr;
QLabel *m_pluginLabel = nullptr;
QFrame *m_line_1 = nullptr;
SeparationLine *m_line_1 = nullptr;
QLabel *m_snippetLabel = nullptr;
QFrame *m_pathFrame = nullptr;
QLabel *m_pathLabel1 = nullptr;
@ -165,7 +169,7 @@ private:
QLabel *m_timeLabel2 = nullptr;
QHBoxLayout *m_timeFrameLyt = nullptr;
QFrame *m_line_2 = nullptr;
SeparationLine *m_line_2 = nullptr;
QFrame *m_actionFrame = nullptr;
QVBoxLayout *m_actionFrameLyt = nullptr;
ActionLabel *m_actionLabel1 = nullptr;

View File

@ -39,6 +39,9 @@ FirstIndex::~FirstIndex() {
if(this->q_content_index)
delete this->q_content_index;
this->q_content_index = nullptr;
if(this->m_ocr_index)
delete this->m_ocr_index;
this->m_ocr_index = nullptr;
if(this->p_indexGenerator)
delete this->p_indexGenerator;
this->p_indexGenerator = nullptr;
@ -48,10 +51,10 @@ FirstIndex::~FirstIndex() {
void FirstIndex::DoSomething(const QFileInfo& fileInfo) {
// qDebug() << "there are some shit here"<<fileInfo.fileName() << fileInfo.absoluteFilePath() << QString(fileInfo.isDir() ? "1" : "0");
this->q_index->enqueue(QVector<QString>() << fileInfo.fileName() << fileInfo.absoluteFilePath() << QString((fileInfo.isDir() && (!fileInfo.isSymLink())) ? "1" : "0"));
if((fileInfo.fileName().split(".", QString::SkipEmptyParts).length() > 1)
&& (true == targetFileTypeMap[fileInfo.fileName().split(".").last()])
&& (!FileUtils::isEncrypedOrUnreadable(fileInfo.absoluteFilePath()))) {
//this->q_content_index->enqueue(fileInfo.absoluteFilePath());
if (fileInfo.fileName().split(".", QString::SkipEmptyParts).length() < 2)
return;
if (true == targetFileTypeMap[fileInfo.fileName().split(".").last()]
and false == FileUtils::isEncrypedOrUnreadable(fileInfo.absoluteFilePath())) {
if (fileInfo.fileName().split(".").last() == "docx") {
QuaZip file(fileInfo.absoluteFilePath());
if(!file.open(QuaZip::mdUnzip))
@ -93,6 +96,8 @@ void FirstIndex::DoSomething(const QFileInfo& fileInfo) {
} else {
this->q_content_index->enqueue(qMakePair(fileInfo.absoluteFilePath(),fileInfo.size()));
}
} else if (true == targetPhotographTypeMap[fileInfo.fileName().split(".").last()]) {
this->m_ocr_index->enqueue(qMakePair(fileInfo.absoluteFilePath(),fileInfo.size()));
}
}
@ -120,6 +125,7 @@ void FirstIndex::run() {
this->q_index = new QQueue<QVector<QString>>();
this->q_content_index = new QQueue<QPair<QString,qint64>>();
this->m_ocr_index = new QQueue<QPair<QString,qint64>>();
int fifo_fd;
char buffer[2];
@ -214,7 +220,34 @@ void FirstIndex::run() {
qDebug() << "content index end;";
sem.release(2);
});
//OCR功能暂时屏蔽
// QtConcurrent::run(&m_pool,[&]() {
// sem.acquire(5);
// QQueue<QString>* tmpOcr = new QQueue<QString>();
// qDebug() << "m_ocr_index:" << m_ocr_index->size();
// while(!this->m_ocr_index->empty()) {
// qint64 fileSize = 0;
// //一次处理的数据量文件总大小为50M以下50M为暂定值
// for(size_t i = 0;/* (i < 30) && (fileSize < 52428800) && */(!this->m_ocr_index->empty()); ++i) {
// QPair<QString,qint64> tempPair = this->m_ocr_index->dequeue();
// fileSize += tempPair.second;
// if (fileSize > 52428800) {
// if (tmpOcr->size() == 0) {
// tmpOcr->enqueue(tempPair.first);
// break;
// }
// this->m_ocr_index->enqueue(tempPair);
// break;
// }
// tmpOcr->enqueue(tempPair.first);
// }
// this->p_indexGenerator->creatOcrIndex(tmpOcr);
// tmpOcr->clear();
// }
// delete tmpOcr;
// qDebug() << "OCR index end;";
// sem.release(5);
// });
mutex1.lock();
mutex2.lock();
mutex3.lock();
@ -223,14 +256,15 @@ void FirstIndex::run() {
mutex2.unlock();
mutex3.unlock();
if(this->q_index)
delete this->q_index;
this->q_index = nullptr;
if(this->q_content_index)
delete this->q_content_index;
this->q_content_index = nullptr;
if(this->m_ocr_index)
delete this->m_ocr_index;
this->m_ocr_index = nullptr;
if(p_indexGenerator)
delete p_indexGenerator;
p_indexGenerator = nullptr;

View File

@ -60,7 +60,8 @@ private:
// QQueue<QString>* q_content_index;
//修改QQueue存储数据为QPair<QString,qint64>,增加存储文件大小数据便于处理时统计--jxx20210519
QQueue<QPair<QString,qint64>>* q_content_index;
//新增ocr队列存储ocr可识别处理的图片信息及大小
QQueue<QPair<QString,qint64>>* m_ocr_index;
//xapian will auto commit per 10,000 changes, donnot change it!!!
const size_t u_send_length = 8192;
};

View File

@ -33,6 +33,7 @@
#define INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/index_data").toStdString()
#define CONTENT_INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/content_index_data").toStdString()
#define OCR_INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/ocr_index_data").toStdString()
using namespace UkuiSearch;
@ -44,8 +45,11 @@ QMutex IndexGenerator::m_mutex;
//QMutex UkuiSearch::g_mutexDocListForContent;
QMutex IndexGenerator::g_mutexDocListForPath;
QMutex IndexGenerator::g_mutexDocListForContent;
QMutex IndexGenerator::g_mutexDocListForOcr;
QVector<Document> IndexGenerator::g_docListForPath = QVector<Document>();
QVector<Document> IndexGenerator::g_docListForContent = QVector<Document>();
QVector<Document> IndexGenerator::g_docListForOcr = QVector<Document>();
IndexGenerator *IndexGenerator::getInstance(bool rebuild, QObject *parent) {
QMutexLocker locker(&m_mutex);
@ -134,6 +138,44 @@ bool IndexGenerator::creatAllIndex(QQueue<QString> *messageList) {
}
bool IndexGenerator::creatOcrIndex(QQueue<QString> *messageList)
{
HandleOcrPathList(messageList);
if(IndexGenerator::g_docListForOcr.isEmpty()) {
return false;
}
int size = IndexGenerator::g_docListForOcr.size();
qDebug() << "begin creatAllIndex for ocr" << size;
if(!size == 0) {
try {
int count = 0;
for(Document i : IndexGenerator::g_docListForOcr) {
if(!i.isRequiredDeleted()) {
m_database_ocr->replace_document(i.getUniqueTerm(), i.getXapianDocument());
} else {
m_database_ocr->delete_document(i.getUniqueTerm());
}
if(++count > 999) {
count = 0;
m_database_ocr->commit();
}
}
m_database_ocr->commit();
} catch(const Xapian::Error &e) {
qWarning() << "creat ocr Index fail!" << QString::fromStdString(e.get_description());
IndexStatusRecorder::getInstance()->setStatus(CONTENT_INDEX_DATABASE_STATE, "1");
assert(false);
}
qDebug() << "finish creatAllIndex for ocr";
IndexGenerator::g_docListForOcr.clear();
IndexGenerator::g_docListForOcr.squeeze();
QVector<Document>().swap(IndexGenerator::g_docListForOcr);
malloc_trim(0);
}
return true;
}
IndexGenerator::IndexGenerator(bool rebuild, QObject *parent) : QObject(parent) {
QDir database(QString::fromStdString(INDEX_PATH));
@ -153,6 +195,7 @@ IndexGenerator::IndexGenerator(bool rebuild, QObject *parent) : QObject(parent)
m_database_path = new Xapian::WritableDatabase(INDEX_PATH, Xapian::DB_CREATE_OR_OPEN);
m_database_content = new Xapian::WritableDatabase(CONTENT_INDEX_PATH, Xapian::DB_CREATE_OR_OPEN);
m_database_ocr = new Xapian::WritableDatabase(OCR_INDEX_PATH, Xapian::DB_CREATE_OR_OPEN);
}
IndexGenerator::~IndexGenerator() {
@ -165,8 +208,11 @@ IndexGenerator::~IndexGenerator() {
if(m_database_content)
m_database_content->~WritableDatabase();
// delete m_database_content;
if(m_database_ocr)
m_database_ocr->~WritableDatabase();
m_database_path = nullptr;
m_database_content = nullptr;
m_database_ocr = nullptr;
global_instance = nullptr;
// if(m_index_map)
// delete m_index_map;
@ -266,28 +312,25 @@ void IndexGenerator::HandlePathList(QQueue<QString> *messageList) {
pool.start(constructer);
}
qDebug() << "pool finish" << pool.waitForDone(-1);
// if(constructer)
// delete constructer;
// constructer = nullptr;
// QFuture<Document> future = QtConcurrent::mapped(*messageList,&IndexGenerator::GenerateContentDocument);
// future.waitForFinished();
// ChineseSegmentation::getInstance()->~ChineseSegmentation();
// QList<Document> docList = future.results();
// mg_docListForContent = new QList<Document>(docList);
// qDebug()<<g_docListForContent->size();
// QList<Document> docList = future.results();
// mg_docListForContent = new QList<Document>(docList);
// mg_docListForContent = std::move(future.results());
// future.cancel();
qDebug() << "Finish HandlePathList for content index!";
return;
}
void IndexGenerator::HandleOcrPathList(QQueue<QString> *messageList)
{
qDebug() << "Begin HandlePathList for ocr index!";
qDebug() << messageList->size();
ConstructDocumentForOcr *constructer;
QThreadPool pool;
pool.setMaxThreadCount(1);
pool.setExpiryTimeout(100);
while(!messageList->isEmpty()) {
constructer = new ConstructDocumentForOcr(messageList->dequeue());
pool.start(constructer);
}
qDebug() << "pool finish" << pool.waitForDone(-1);
qDebug() << "Finish HandlePathList for content index!";
return;
}
//deprecated
Document IndexGenerator::GenerateDocument(const QVector<QString> &list) {
@ -460,10 +503,13 @@ bool IndexGenerator::deleteAllIndex(QStringList *pathlist) {
m_database_path->delete_document(uniqueterm);
m_database_content->delete_document(uniqueterm);
m_database_ocr->delete_document(uniqueterm);
//delete all files under it if it's a dir.
m_database_path->delete_document(upterm);
m_database_content->delete_document(upterm);
m_database_ocr->delete_document(upterm);
qDebug() << "delete path" << doc;
// qDebug() << "delete md5" << QString::fromStdString(uniqueterm);
@ -472,6 +518,7 @@ bool IndexGenerator::deleteAllIndex(QStringList *pathlist) {
}
m_database_path->commit();
m_database_content->commit();
m_database_ocr->commit();
qDebug() << "--delete finish--";
} catch(const Xapian::Error &e) {
qWarning() << QString::fromStdString(e.get_description());
@ -503,43 +550,85 @@ bool IndexGenerator::deleteContentIndex(QStringList *pathlist)
return true;
}
bool IndexGenerator::deleteOcrIndex(QStringList *pathlist)
{
if(pathlist->isEmpty())
return true;
try {
qDebug() << "--delete start--";
for(int i = 0; i < pathlist->size(); i++) {
QString doc = pathlist->at(i);
std::string uniqueterm = FileUtils::makeDocUterm(doc);
m_database_ocr->delete_document(uniqueterm);
qDebug() << "delete path" << doc;
}
m_database_ocr->commit();
qDebug() << "--delete finish--";
} catch(const Xapian::Error &e) {
qWarning() << QString::fromStdString(e.get_description());
return false;
}
return true;
}
bool IndexGenerator::updateIndex(QVector<PendingFile> *pendingFiles)
{
QQueue<QVector<QString>> *fileIndexInfo = new QQueue<QVector<QString>>;
QQueue<QString> *fileContentIndexInfo = new QQueue<QString>;
QQueue<QString> *fileOcrIndexInfo = new QQueue<QString>;
QStringList *deleteList = new QStringList;
QStringList *contentDeleteList = new QStringList;
for(PendingFile file : *pendingFiles) {
if(file.shouldRemoveIndex()) {
for (PendingFile file : *pendingFiles) {
if (file.shouldRemoveIndex()) {
deleteList->append(file.path());
continue;
}
fileIndexInfo->append(QVector<QString>() << file.path().section("/" , -1) << file.path() << QString(file.isDir() ? "1" : "0"));
if((!file.path().split(".").isEmpty()) && (true == targetFileTypeMap[file.path().section("/" , -1) .split(".").last()])) {
if(!FileUtils::isEncrypedOrUnreadable(file.path())) {
if ((!file.path().split(".").isEmpty()) && (true == targetFileTypeMap[file.path().section("/" , -1) .split(".").last()])) {
if (!FileUtils::isEncrypedOrUnreadable(file.path())) {
fileContentIndexInfo->append(file.path());
} else {
contentDeleteList->append(file.path());
}
}
}
if(!deleteList->isEmpty()) {
if (!deleteList->isEmpty()) {
deleteAllIndex(deleteList);
}
if(!contentDeleteList->isEmpty()) {
if (!contentDeleteList->isEmpty()) {
deleteContentIndex(contentDeleteList);
}
if(!fileIndexInfo->isEmpty()) {
if (!fileIndexInfo->isEmpty()) {
creatAllIndex(fileIndexInfo);
}
if(!fileContentIndexInfo->isEmpty()) {
if (!fileContentIndexInfo->isEmpty()) {
creatAllIndex(fileContentIndexInfo);
}
delete fileIndexInfo;
delete fileContentIndexInfo;
if (!fileOcrIndexInfo->isEmpty()) {
creatOcrIndex(fileOcrIndexInfo);
}
if (fileIndexInfo) {
delete fileIndexInfo;
fileIndexInfo = nullptr;
}
if (fileContentIndexInfo) {
delete fileContentIndexInfo;
fileContentIndexInfo = nullptr;
}
if (fileOcrIndexInfo) {
delete fileOcrIndexInfo;
fileOcrIndexInfo = nullptr;
}
if (deleteList) {
delete deleteList;
deleteList = nullptr;
}
if (contentDeleteList) {
delete contentDeleteList;
contentDeleteList = nullptr;
}
return true;
}

View File

@ -45,6 +45,7 @@ namespace UkuiSearch {
class IndexGenerator : public QObject {
friend class ConstructDocumentForPath;
friend class ConstructDocumentForContent;
friend class ConstructDocumentForOcr;
Q_OBJECT
public:
static IndexGenerator *getInstance(bool rebuild = false, QObject *parent = nullptr);
@ -61,8 +62,10 @@ Q_SIGNALS:
public Q_SLOTS:
bool creatAllIndex(QQueue<QVector<QString>> *messageList);
bool creatAllIndex(QQueue<QString> *messageList);
bool creatOcrIndex(QQueue<QString> *messageList);
bool deleteAllIndex(QStringList *pathlist);
bool deleteContentIndex(QStringList *pathlist);
bool deleteOcrIndex(QStringList *pathlist);
bool updateIndex(QVector<PendingFile> *pendingFiles);
private:
@ -72,6 +75,8 @@ private:
void HandlePathList(QQueue<QVector<QString> > *messageList);
//For file content index
void HandlePathList(QQueue<QString> *messageList);
//For ocr index
void HandleOcrPathList(QQueue<QString> *messageList);
static Document GenerateDocument(const QVector<QString> &list);
static Document GenerateContentDocument(const QString &list);
//add one data in database
@ -82,10 +87,13 @@ private:
static QMutex g_mutexDocListForPath;
static QVector<Document> g_docListForContent;
static QMutex g_mutexDocListForContent;
static QVector<Document> g_docListForOcr;
static QMutex g_mutexDocListForOcr;
QMap<QString, QStringList> m_index_map;
QString m_index_data_path;
Xapian::WritableDatabase* m_database_path;
Xapian::WritableDatabase* m_database_content;
Xapian::WritableDatabase* m_database_ocr;
std::string m_docstr;
std::string m_index_text_str;
Xapian::TermGenerator m_indexer;

View File

@ -9,6 +9,7 @@ HEADERS += \
$$PWD/index-generator.h \
$$PWD/index-status-recorder.h \
$$PWD/inotify-watch.h \
$$PWD/ocrobject.h \
$$PWD/pending-file-queue.h \
$$PWD/pending-file.h \
$$PWD/search-manager.h \
@ -25,6 +26,7 @@ SOURCES += \
$$PWD/index-generator.cpp \
$$PWD/index-status-recorder.cpp \
$$PWD/inotify-watch.cpp \
$$PWD/ocrobject.cpp \
$$PWD/pending-file-queue.cpp \
$$PWD/pending-file.cpp \
$$PWD/search-manager.cpp \

View File

@ -0,0 +1,98 @@
#include "ocrobject.h"
OcrObject *OcrObject::m_instance = nullptr;
once_flag g_instanceFlag;
OcrObject *OcrObject::getInstance()
{
std::call_once(g_instanceFlag, [] () {
m_instance = new OcrObject;
});
return m_instance;
}
void OcrObject::getTxtContent(QString &path, QString &textcontent)
{
m_api = new tesseract::TessBaseAPI();
if (m_api->Init(NULL, "chi_sim")) {
qDebug() << "Could not initialize tesseract.\n";
return;
}
m_api->SetVariable("user_defined_dpi", "1080");//图片中未标明分辨率的默认设置为1080
Pix *image = pixRead(path.toStdString().data());
if (!image) {
qDebug() << "path:" << path <<" pixRead error!";
if (m_api) {
m_api->End();
delete m_api;
m_api = nullptr;
}
return;
}
m_api->SetImage(image);
textcontent = m_api->GetUTF8Text();
qDebug() << "path:" << path << " Text:" << textcontent;
pixDestroy(&image);
m_api->Clear();
if (m_api) {
m_api->End();
delete m_api;
m_api = nullptr;
}
//多进程版本
// tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
// if (api->Init(NULL, "chi_sim")) {
// qDebug() << "Could not initialize tesseract.\n";
// return;
// }
// api->SetVariable("user_defined_dpi", "1080");//图片中未标明分辨率的默认设置为1080
// Pix *image = pixRead(path.toStdString().data());
// if (!image) {
// qDebug() << "path:" << path <<" pixRead error!";
// if (api) {
// api->End();
// delete api;
// api = nullptr;
// }
// return;
// }
// api->SetImage(image);
// textcontent = api->GetUTF8Text();
// qDebug() << "path:" << path << " Text:" << textcontent;
// pixDestroy(&image);
// api->Clear();
// if (api) {
// api->End();
// delete api;
// api = nullptr;
// }
}
OcrObject::OcrObject(QObject *parent) : QObject(parent)
{
init();
}
OcrObject::~OcrObject()
{
if (m_api) {
m_api->End();
delete m_api;
m_api = nullptr;
}
}
void OcrObject::init()
{
m_api = new tesseract::TessBaseAPI();
if (m_api->Init(NULL, "chi_sim")) {
qDebug() << "Could not initialize tesseract.\n";
return;
}
m_api->SetVariable("user_defined_dpi", "1080");//图片中未标明分辨率的默认设置为1080
}

View File

@ -0,0 +1,41 @@
#ifndef OCROBJECT_H
#define OCROBJECT_H
#include <QObject>
#include <mutex>
#include <tesseract/baseapi.h>
#include <leptonica/allheaders.h>
#include <QDebug>
using namespace std;
class OcrObject : public QObject
{
Q_OBJECT
public:
static OcrObject* getInstance();
void getTxtContent(QString &path, QString &textcontent);
protected:
explicit OcrObject(QObject *parent = nullptr);
~OcrObject();
private:
static OcrObject *m_instance;
tesseract::TessBaseAPI *m_api = nullptr;
void init();
class Garbo
{
public:
~Garbo() {
if (OcrObject::m_instance)
delete OcrObject::m_instance;
}
static Garbo g_garbo;
};
};
#endif // OCROBJECT_H

File diff suppressed because it is too large Load Diff

View File

@ -19,15 +19,17 @@
*/
#include "search-manager.h"
using namespace UkuiSearch;
size_t SearchManager::uniqueSymbolFile = 0;
size_t SearchManager::uniqueSymbolDir = 0;
size_t SearchManager::uniqueSymbolContent = 0;
size_t SearchManager::uniqueSymbolOcr = 0;
QMutex SearchManager::m_mutexFile;
QMutex SearchManager::m_mutexDir;
QMutex SearchManager::m_mutexContent;
QMutex SearchManager::m_mutexOcr;
SearchManager::SearchManager(QObject *parent) : QObject(parent) {
m_pool.setMaxThreadCount(3);
m_pool.setExpiryTimeout(1000);
}
SearchManager::~SearchManager() {
@ -43,39 +45,6 @@ int SearchManager::getCurrentIndexCount() {
}
}
void SearchManager::onKeywordSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir,
QQueue<QPair<QString, QStringList>> *searchResultContent) {
// m_mutexFile.lock();
// ++uniqueSymbolFile;
// m_mutexFile.unlock();
// m_mutexDir.lock();
// ++uniqueSymbolDir;
// m_mutexDir.unlock();
// m_mutexContent.lock();
// ++uniqueSymbolContent;
// m_mutexContent.unlock();
// if(FileUtils::SearchMethod::DIRECTSEARCH == FileUtils::searchMethod) {
// DirectSearch *directSearch;
// directSearch = new DirectSearch(keyword, searchResultFile, searchResultDir, uniqueSymbolFile);
// m_pool.start(directSearch);
// } else if(FileUtils::SearchMethod::INDEXSEARCH == FileUtils::searchMethod) {
// FileSearch *filesearch;
// filesearch = new FileSearch(searchResultFile, uniqueSymbolFile, keyword, "0", 1, 0, 5);
// m_pool.start(filesearch);
// FileSearch *dirsearch;
// dirsearch = new FileSearch(searchResultDir, uniqueSymbolDir, keyword, "1", 1, 0, 5);
// m_pool.start(dirsearch);
// FileContentSearch *contentSearch;
// contentSearch = new FileContentSearch(searchResultContent, uniqueSymbolContent, keyword, 0, 5);
// m_pool.start(contentSearch);
// } else {
// qWarning() << "Unknown search method! FileUtils::searchMethod: " << static_cast<int>(FileUtils::searchMethod);
// }
return;
}
bool SearchManager::isBlocked(QString &path) {
QStringList blockList = GlobalSettings::getInstance()->getBlockDirs();
for(QString i : blockList) {
@ -101,6 +70,7 @@ bool SearchManager::creatResultInfo(SearchPluginIface::ResultInfo &ri, QString p
ri.type = 0;
return true;
}
FileSearch::FileSearch(DataQueue<SearchPluginIface::ResultInfo> *searchResult, size_t uniqueSymbol, QString keyword, QString value, unsigned slot, int begin, int num) {
this->setAutoDelete(true);
m_search_result = searchResult;
@ -428,6 +398,121 @@ int FileContentSearch::getResult(Xapian::MSet &result, std::string &keyWord) {
return 0;
}
OcrSearch::OcrSearch(DataQueue<SearchPluginIface::ResultInfo> *searchResult, size_t uniqueSymbol, QString keyword, int begin, int num) {
this->setAutoDelete(true);
m_search_result = searchResult;
m_uniqueSymbol = uniqueSymbol;
m_keyword = keyword;
m_begin = begin;
m_num = num;
m_matchDecider = new OcrMatchDecider();
}
OcrSearch::~OcrSearch() {
m_search_result = nullptr;
if(m_matchDecider)
delete m_matchDecider;
}
void OcrSearch::run() {
SearchManager::m_mutexOcr.lock();
if(!m_search_result->isEmpty()) {
m_search_result->clear();
}
SearchManager::m_mutexOcr.unlock();
//这里同文件搜索,待优化。
m_begin = 0;
m_num = 100;
int resultCount = 1;
int totalCount = 0;
while(resultCount > 0) {
resultCount = keywordSearchOcr();
m_begin += m_num;
totalCount += resultCount;
}
qDebug() << "Total count:" << totalCount;
return;
}
int OcrSearch::keywordSearchOcr() {
try {
qDebug() << "--keywordSearch OCR search start--";
Xapian::Database db(OCR_INDEX_PATH);
Xapian::Enquire enquire(db);
Xapian::QueryParser qp;
qp.set_default_op(Xapian::Query::OP_AND);
qp.set_database(db);
QVector<SKeyWord> sKeyWord = ChineseSegmentation::getInstance()->callSegement(m_keyword.toStdString());
//Creat a query
std::string words;
for(int i = 0; i < sKeyWord.size(); i++) {
words.append(sKeyWord.at(i).word).append(" ");
}
std::vector<Xapian::Query> v;
for(int i=0; i<sKeyWord.size(); i++) {
v.push_back(Xapian::Query(sKeyWord.at(i).word));
qDebug() << QString::fromStdString(sKeyWord.at(i).word);
}
Xapian::Query query = Xapian::Query(Xapian::Query::OP_AND, v.begin(), v.end());
qDebug() << "keywordSearch OCR:" << QString::fromStdString(query.get_description());
enquire.set_query(query);
Xapian::MSet result = enquire.get_mset(m_begin, m_num, 0, m_matchDecider);
int resultCount = result.size();
if(result.size() == 0) {
return 0;
}
qDebug() << "keywordSearch OCR results count=" << resultCount;
if(getResult(result, words) == -1) {
return -1;
}
qDebug() << "--keywordSearch OCR search finish--";
return resultCount;
} catch(const Xapian::Error &e) {
qWarning() << QString::fromStdString(e.get_description());
qDebug() << "--keywordSearch OCR search finish--";
return -1;
}
}
int OcrSearch::getResult(Xapian::MSet &result, std::string &keyWord) {
for(auto it = result.begin(); it != result.end(); ++it) {
Xapian::Document doc = it.get_document();
std::string data = doc.get_data();
QString path = QString::fromStdString(doc.get_value(1));
SearchPluginIface::ResultInfo ri;
if(!SearchManager::creatResultInfo(ri, path)) {
continue;
}
// Construct snippets containing keyword.
auto term = doc.termlist_begin();
std::string wordTobeFound = QString::fromStdString(keyWord).section(" ", 0, 0).toStdString();
term.skip_to(wordTobeFound);
//fix me: make a snippet without cut cjk char.
auto pos = term.positionlist_begin();
QString snippet = FileUtils::chineseSubString(data,*pos,120);
ri.description.prepend(SearchPluginIface::DescriptionInfo{"",snippet});
QString().swap(snippet);
std::string().swap(data);
SearchManager::m_mutexOcr.lock();
if(m_uniqueSymbol == SearchManager::uniqueSymbolOcr) {
m_search_result->enqueue(ri);
SearchManager::m_mutexOcr.unlock();
} else {
SearchManager::m_mutexOcr.unlock();
return -1;
}
}
return 0;
}
DirectSearch::DirectSearch(QString keyword, DataQueue<SearchPluginIface::ResultInfo> *searchResult, QString value, size_t uniqueSymbol) {
this->setAutoDelete(true);
m_keyword = keyword;
@ -472,8 +557,8 @@ void DirectSearch::run() {
}
if(i.fileName().contains(m_keyword, Qt::CaseInsensitive)) {
// qWarning() << i.fileName() << m_keyword;
if(m_searchResult->length() > 49)
return;
// if(m_searchResult->length() > 49)
// return;
if((i.isDir() && m_value == DIR_SEARCH_VALUE)) {
SearchPluginIface::ResultInfo ri;
if(SearchManager::creatResultInfo(ri,i.absoluteFilePath())) {
@ -521,3 +606,12 @@ bool FileContentMatchDecider::operator ()(const Xapian::Document &doc) const
}
return true;
}
bool OcrMatchDecider::operator ()(const Xapian::Document &doc) const
{
QString path = QString::fromStdString(doc.get_value(1));
if(SearchManager::isBlocked(path)) {
return false;
}
return true;
}

View File

@ -45,15 +45,19 @@
#define INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/index_data").toStdString()
#define CONTENT_INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/content_index_data").toStdString()
#define OCR_INDEX_PATH (QStandardPaths::writableLocation(QStandardPaths::HomeLocation)+"/.config/org.ukui/ukui-search/ocr_index_data").toStdString()
namespace UkuiSearch {
class FileMatchDecider;
class FileContentMatchDecider;
class OcrMatchDecider;
class LIBSEARCH_EXPORT SearchManager : public QObject {
friend class FileSearch;
friend class FileContentSearch;
friend class OcrSearch;
friend class DirectSearch;
friend class FileMatchDecider;
friend class FileContentMatchDecider;
friend class OcrMatchDecider;
Q_OBJECT
public:
explicit SearchManager(QObject *parent = nullptr);
@ -64,22 +68,15 @@ public:
static size_t uniqueSymbolFile;
static size_t uniqueSymbolDir;
static size_t uniqueSymbolContent;
static size_t uniqueSymbolOcr;
static QMutex m_mutexFile;
static QMutex m_mutexDir;
static QMutex m_mutexContent;
static QMutex m_mutexOcr;
public Q_SLOTS:
void onKeywordSearch(QString keyword, QQueue<QString> *searchResultFile, QQueue<QString> *searchResultDir, QQueue<QPair<QString, QStringList>> *searchResultContent);
Q_SIGNALS:
void resultFile(QQueue<QString> *);
void resultDir(QQueue<QString> *);
void resultContent(QQueue<QPair<QString, QStringList>> *);
private:
static bool isBlocked(QString &path);
static bool creatResultInfo(UkuiSearch::SearchPluginIface::ResultInfo &ri, QString path);
QThreadPool m_pool;
};
class FileSearch : public QRunnable {
@ -121,6 +118,24 @@ private:
int m_num = 20;
};
class OcrSearch : public QRunnable {
public:
explicit OcrSearch(DataQueue<SearchPluginIface::ResultInfo> *searchResult, size_t uniqueSymbol, QString keyword, int begin = 0, int num = 20);
~OcrSearch();
protected:
void run();
private:
int keywordSearchOcr();
int getResult(Xapian::MSet &result, std::string &keyWord);
DataQueue<SearchPluginIface::ResultInfo> *m_search_result = nullptr;
OcrMatchDecider *m_matchDecider;
size_t m_uniqueSymbol;
QString m_keyword;
int m_begin = 0;
int m_num = 20;
};
class DirectSearch : public QRunnable {
public:
explicit DirectSearch(QString keyword, DataQueue<SearchPluginIface::ResultInfo> *searchResult, QString value, size_t uniqueSymbol);
@ -133,11 +148,15 @@ private:
QString m_value;
};
class FileMatchDecider :public Xapian::MatchDecider {
class FileMatchDecider : public Xapian::MatchDecider {
public:
bool operator ()(const Xapian::Document &doc) const;
};
class FileContentMatchDecider :public Xapian::MatchDecider {
class FileContentMatchDecider : public Xapian::MatchDecider {
public:
bool operator ()(const Xapian::Document &doc) const;
};
class OcrMatchDecider : public Xapian::MatchDecider {
public:
bool operator ()(const Xapian::Document &doc) const;
};

View File

@ -1,5 +1,5 @@
QT += core xml widgets dbus concurrent sql
VERSION = 1.0.0
VERSION = 1.1.0
DEFINES += VERSION='\\"$${VERSION}\\"'
TARGET = ukui-search
@ -38,9 +38,10 @@ include(settingsearch/settingsearch.pri)
include(websearch/websearch.pri)
include(searchinterface/search-interface.pri)
include(dirwatcher/dirwatcher.pri)
include(mailsearch/mailsearch.pri)
LIBS += -L$$OUT_PWD/../libchinese-segmentation/ -lchinese-segmentation
LIBS += -lxapian -lquazip5 -luchardet -lQt5Xdg#-L/usr/local/lib/libjemalloc -ljemalloc
LIBS += -lxapian -luchardet -lQt5Xdg -lquazip5 -ltesseract #-L/usr/local/lib/libjemalloc -ljemalloc
SOURCES += \
file-utils.cpp \

View File

@ -0,0 +1,407 @@
#include "mail-search-plugin.h"
#include "file-utils.h"
#include "chinese-segmentation.h"
using namespace UkuiSearch;
#define ICON_SIZE QSize(120,120)
#define DETAIL_WIDTH 360
#define DETAIL_MARGINS 8, 0, 16, 0
#define DETAIL_ICON_HEIGHT 128
#define NAME_LABEL_MARGINS 8, 0, 0, 0
#define NAME_LABEL_WIDTH 282
#define DETAIL_ACTION_MARGINS 8, 0, 0, 0
#define DESC_PAGE_WIDTH 316
#define DESC_LABEL_MARGINS 0, 0, 0, 0
#define DESC_LABEL_SIZE QSize(87, 34)
#define DESC_LABEL_SPACING 16
#define SCROLL_BAR_COLOR QColor(0, 0, 0, 0)
#define SCROLL_AREA_MARGINS 8, 0, 0, 0
#define SCROLL_AREA_MAX_HEIGHT 212
#define SCROLL_AREA_MAX_WIDTH 344
#define AREA_CONTENT_MARGINS 8, 0, 0, 0
size_t MailSearchPlugin::uniqueSymbol = 0;
QMutex MailSearchPlugin::m_mutex;
MailSearchPlugin::MailSearchPlugin(QObject *parent) : QObject(parent)
{
SearchPluginIface::Actioninfo open { 0, tr("open")};
m_actionInfo << open;
m_pool.setMaxThreadCount(1);
m_pool.setExpiryTimeout(1000);
initDetailPage();
}
const QString MailSearchPlugin::name()
{
return tr("Mail Search");
}
const QString MailSearchPlugin::description()
{
return tr("Mail Search");
}
QString MailSearchPlugin::getPluginName()
{
return tr("Mail Search");
}
void MailSearchPlugin::KeywordSearch(QString keyword, DataQueue<SearchPluginIface::ResultInfo> *searchResult)
{
m_mutex.lock();
++uniqueSymbol;
m_mutex.unlock();
m_keyword = keyword;
MailSearch *mailSearch = new MailSearch(searchResult, keyword, uniqueSymbol);
m_pool.start(mailSearch);
}
void MailSearchPlugin::stopSearch()
{
m_mutex.lock();
++uniqueSymbol;
m_mutex.unlock();
}
QList<SearchPluginIface::Actioninfo> MailSearchPlugin::getActioninfo(int type)
{
return m_actionInfo;
}
void MailSearchPlugin::openAction(int actionkey, QString key, int type)
{
QProcess process;
switch(actionkey) {
case 0:
process.startDetached(QString("evolution"));
break;
default:
break;
}
}
QWidget *MailSearchPlugin::detailPage(const SearchPluginIface::ResultInfo &ri)
{
m_currentActionKey = ri.actionKey;
m_iconLabel->setPixmap(ri.icon.pixmap(ICON_SIZE));
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
QString showname = fontMetrics.elidedText(ri.name, Qt::ElideRight, 215);//当字体长度超过215时显示为省略号
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(FileUtils::escapeHtml(showname)));
if (QString::compare(showname, ri.name)) {
m_nameLabel->setToolTip(ri.name);
}
m_pluginLabel->setText(tr("Mail"));
m_senderLabel->setText(ri.description.at(0).key);
QString senderName = fontMetrics.elidedText(ri.description.at(0).value, Qt::ElideRight, 246);//当字体长度超过246时显示为省略号
m_senderFieldsLabel->setText(FileUtils::escapeHtml(senderName));
if (QString::compare(senderName, ri.description.at(0).value)) {
m_senderFieldsLabel->setToolTip(ri.description.at(0).value);
} else {
m_nameLabel->setToolTip("");
}
m_timeLabel->setText(ri.description.at(1).key);
m_timeFieldsLabel->setText(ri.description.at(1).value);
m_recipientsLabel->setText(ri.description.at(2).key);
QString recipientsStr = ri.description.at(2).value;
// QString recipientsStr = fontMetrics.elidedText(ri.description.at(2).value, Qt::ElideRight, 200);
// recipientsStr.replace(QRegExp("\\, "), "\n");
m_recipientsFieldsLabel->setText(FileUtils::getHtmlText(recipientsStr, m_keyword));
resizeTextEdit(m_recipientsFieldsLabel);
m_ccLabel->setText(ri.description.at(3).key);
QString ccStr = ri.description.at(3).value;
// QString ccStr = fontMetrics.elidedText(ri.description.at(3).value, Qt::ElideRight, 200);
m_ccFieldsLabel->setText(FileUtils::getHtmlText(ccStr, m_keyword));
resizeTextEdit(m_ccFieldsLabel);
// if (QString::compare(ccStr, ri.description.at(3).value)) {
// m_ccFieldsLabel->setToolTip(ri.description.at(3).value);
// }
//重置滚动条位置
m_descListArea->verticalScrollBar()->setValue(0);
return m_detailPage;
}
void MailSearchPlugin::initDetailPage()
{
m_detailPage = new QWidget();
m_detailPage->setFixedWidth(DETAIL_WIDTH);
m_detailPage->setAttribute(Qt::WA_TranslucentBackground);
m_detailLyt = new QVBoxLayout(m_detailPage);
m_detailLyt->setContentsMargins(DETAIL_MARGINS);
m_iconLabel = new QLabel(m_detailPage);
m_iconLabel->setAlignment(Qt::AlignCenter);
m_iconLabel->setFixedHeight(DETAIL_ICON_HEIGHT);
m_nameFrame = new QFrame(m_detailPage);
m_nameFrameLyt = new QHBoxLayout(m_nameFrame);
m_nameFrame->setLayout(m_nameFrameLyt);
m_nameFrameLyt->setContentsMargins(NAME_LABEL_MARGINS);
m_nameLabel = new QLabel(m_nameFrame);
m_nameLabel->setMaximumWidth(NAME_LABEL_WIDTH);
m_pluginLabel = new QLabel(m_nameFrame);
m_pluginLabel->setEnabled(false);
m_nameFrameLyt->addWidget(m_nameLabel);
m_nameFrameLyt->addStretch();
m_nameFrameLyt->addWidget(m_pluginLabel);
m_line_1 = new SeparationLine(m_detailPage);
m_descListArea = new MailDescArea(m_detailPage);
QPalette scroll_bar_pal = m_descListArea->verticalScrollBar()->palette();
scroll_bar_pal.setColor(QPalette::Base, SCROLL_BAR_COLOR);
m_descListArea->verticalScrollBar()->setPalette(scroll_bar_pal);
m_descPage = new QWidget(m_descListArea);
m_descListArea->setWidget(m_descPage);
m_descPageLyt = new QFormLayout(m_descPage);
m_descPage->setLayout(m_descPageLyt);
m_descPage->setContentsMargins(DESC_LABEL_MARGINS);
m_descPage->setFixedWidth(DESC_PAGE_WIDTH);
m_senderLabel = new QLabel(m_descPage);
m_senderFieldsLabel = new QLabel(m_descPage);
m_senderLabel->setMaximumSize(DESC_LABEL_SIZE);
m_senderFieldsLabel->setAlignment(Qt::AlignRight);
m_timeLabel = new QLabel(m_descPage);
m_timeFieldsLabel = new QLabel(m_descPage);
m_timeLabel->setMaximumSize(DESC_LABEL_SIZE);
m_timeFieldsLabel->setAlignment(Qt::AlignRight);
m_recipientsLabel = new QLabel(m_descPage);
// m_recipientsFieldsLabel = new QLabel(m_descPage);
m_recipientsFieldsLabel = new QTextBrowser(m_descPage);
m_recipientsLabel->setMaximumSize(DESC_LABEL_SIZE);
// m_recipientsLabel->setMaximumHeight(35);
// m_recipientsFieldsLabel->setAlignment(Qt::AlignRight);
// m_recipientsFieldsLabel->setFixedWidth(260);
// m_recipientsFieldsLabel->setWordWrap(true);
m_recipientsFieldsLabel->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_recipientsFieldsLabel->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_recipientsFieldsLabel->setWordWrapMode(QTextOption::WrapAnywhere);
// m_recipientsFieldsLabel->setLineWrapMode(QTextEdit::FixedPixelWidth);
// m_recipientsFieldsLabel->setLineWrapColumnOrWidth(260);
m_recipientsFieldsLabel->setPalette(scroll_bar_pal);
m_recipientsFieldsLabel->setFrameShape(QFrame::Shape::NoFrame);
m_ccLabel = new QLabel(m_descPage);
// m_ccFieldsLabel = new QLabel(m_descPage);
m_ccFieldsLabel = new QTextBrowser(m_descPage);
m_ccLabel->setMaximumSize(DESC_LABEL_SIZE);
// m_ccFieldsLabel->setAlignment(Qt::AlignRight);
// m_ccFieldsLabel->setFixedWidth(262);
// m_ccFieldsLabel->setWordWrap(true);
m_ccFieldsLabel->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_ccFieldsLabel->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_ccFieldsLabel->setWordWrapMode(QTextOption::WrapAnywhere);
m_ccFieldsLabel->setPalette(scroll_bar_pal);
m_ccFieldsLabel->setFrameShape(QFrame::Shape::NoFrame);
/*
m_attachmentLabel = new QLabel(m_descPage);
m_attachmentFieldsLabel = new QLabel(m_descPage);
m_attachmentLabel->setMaximumSize(DESC_LABEL_SIZE);
m_attachmentLabel->setText(QString(tr("Attachment")));
m_attachmentFieldsLabel->setAlignment(Qt::AlignRight);
*/
m_descPageLyt->setContentsMargins(DESC_LABEL_MARGINS);
m_descPageLyt->setVerticalSpacing(DESC_LABEL_SPACING);
m_descPageLyt->addRow(m_senderLabel, m_senderFieldsLabel);
m_descPageLyt->addRow(m_timeLabel, m_timeFieldsLabel);
m_descPageLyt->addRow(m_recipientsLabel, m_recipientsFieldsLabel);
m_descPageLyt->addRow(m_ccLabel, m_ccFieldsLabel);
// m_descPageLyt->addRow(m_attachmentLabel, m_attachmentFieldsLabel);
m_line_2 = new SeparationLine(m_detailPage);
m_actionFrame = new QFrame(m_detailPage);
m_actionFrameLyt = new QVBoxLayout(m_actionFrame);
m_actionFrameLyt->setContentsMargins(DETAIL_ACTION_MARGINS);
m_actionLabel1 = new ActionLabel(tr("Open"), m_currentActionKey, m_actionFrame);
m_actionFrameLyt->addWidget(m_actionLabel1);
m_actionFrame->setLayout(m_actionFrameLyt);
m_detailLyt->addSpacing(50);
m_detailLyt->addWidget(m_iconLabel);
m_detailLyt->addWidget(m_nameFrame);
m_detailLyt->addWidget(m_line_1);
m_detailLyt->addWidget(m_descListArea);
m_detailLyt->addWidget(m_line_2);
m_detailLyt->addWidget(m_actionFrame);
m_detailLyt->addStretch();
m_detailPage->setLayout(m_detailLyt);
connect(m_actionLabel1, &ActionLabel::actionTriggered, [ & ](){
openAction(m_actionInfo.at(0).actionkey, m_currentActionKey,0);
});
// connect(m_recipientsFieldsLabel->document(), &QTextDocument::contentsChanged, this, &MailSearchPlugin::resetHeight);
}
void MailSearchPlugin::resizeTextEdit(QTextEdit *textEdit)
{
QTextDocument *doc = textEdit->document();
int height = doc->size().height();
textEdit->setMinimumHeight(32);
int minheight = textEdit->minimumHeight();
if (height < minheight)
{
height = minheight;
}
textEdit->setFixedHeight(height);
}
void MailSearchPlugin::resetHeight()
{
QTextDocument *document=qobject_cast<QTextDocument*>(sender());
if (!document) {
return;
}
QTextEdit *editor=qobject_cast<QTextEdit*>(document->parent()->parent());
if (!editor) {
return;
}
int newheight = document->size().rheight();
if (newheight != editor->height()) {
editor->setFixedHeight(newheight);
} else {
return;
}
// m_recipientsFieldsLabel->setFixedHeight(m_recipientsFieldsLabel->document()->size().rheight());
}
MailSearch::MailSearch(DataQueue<SearchPluginIface::ResultInfo> *searchResult, const QString &keyword, size_t uniqueSymbol)
{
this->setAutoDelete(true);
this->m_searchResult = searchResult;
this->m_keyword = keyword;
this->m_uniqueSymbol = uniqueSymbol;
}
void MailSearch::run()
{
QDBusInterface mailDataInterface("org.gnome.EvolutionMailData", "/", "org.gnome.EvolutionMailData", QDBusConnection::sessionBus());
QDBusReply<QVariantMap> reply = mailDataInterface.call("keywordMatch",m_keyword);
if (reply.isValid()) {
if (m_uniqueSymbol == MailSearchPlugin::uniqueSymbol) {
for (std::pair<QString, QVariant> result : reply.value().toStdMap()) {
const QDBusArgument &dbusArgs = result.second.value<QDBusArgument>();
QStringList resultList;
dbusArgs.beginArray();
while (!dbusArgs.atEnd()) {
QVariant tmp;
dbusArgs >> tmp;
resultList.append(tmp.toString());
}
dbusArgs.endArray();
SearchPluginIface::ResultInfo ri;
createResultInfo(ri, resultList);
if (m_uniqueSymbol == MailSearchPlugin::uniqueSymbol) {
m_searchResult->enqueue(ri);
} else {
qDebug() << "uniqueSymbol don't match:" << m_uniqueSymbol << MailSearchPlugin::uniqueSymbol;
return;
}
}
} else {
qDebug() << "uniqueSymbol don't match:" << m_uniqueSymbol << MailSearchPlugin::uniqueSymbol;
return;
}
} else {
qWarning() << "Error!Mail dbus call failed:" << mailDataInterface.lastError();
return;
}
}
void MailSearch::createResultInfo(SearchPluginIface::ResultInfo &ri, QStringList &resultList)
{
QString recipientsStr = resultList.at(5);
recipientsStr.replace(QRegExp("\\, "), "\n");
// recipientsStr.toUtf8().data();
QString ccStr = resultList.at(6);
ccStr.replace(QRegExp("\\, "), "\n");
ri.icon = XdgIcon::fromTheme("evolution");
ri.name = resultList.at(3);
ri.description = QVector<SearchPluginIface::DescriptionInfo>() \
<< SearchPluginIface::DescriptionInfo{tr("From"), resultList.at(4)} \
<< SearchPluginIface::DescriptionInfo{tr("Time"), resultList.at(7)} \
<< SearchPluginIface::DescriptionInfo{tr("To"), recipientsStr/*resultList.at(5)*/} \
<< SearchPluginIface::DescriptionInfo{tr("Cc"), ccStr/*resultList.at(6)*/};
ri.type = 0;
}
MailDescArea::MailDescArea(QWidget *parent) : QScrollArea(parent)
{
initUi();
}
void MailDescArea::initUi()
{
this->setFrameShape(QFrame::Shape::NoFrame);
this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
this->setWidgetResizable(true);
this->setFixedWidth(SCROLL_AREA_MAX_WIDTH);
this->setMaximumHeight(SCROLL_AREA_MAX_HEIGHT);
this->setViewportMargins(AREA_CONTENT_MARGINS);
// this->setContentsMargins(SCROLL_AREA_MARGINS);
/*
m_descPage = new QWidget(this);
this->setWidget(m_descPage);
m_descPageLyt = new QFormLayout(m_descPage);
m_descPage->setLayout(m_descPageLyt);
m_descPage->setContentsMargins(8, 0, 8, 0);
m_senderLabel = new QLabel(m_descPage);
m_senderFieldsLabel = new QLabel(m_descPage);
m_senderLabel->setMaximumSize(DESC_LABEL_SIZE);
m_senderLabel->setText(QString(tr("From:")));
m_senderFieldsLabel->setText("<jianbingguozi@kylinos.cn>");
m_senderFieldsLabel->setAlignment(Qt::AlignRight);
m_senderFieldsLabel->setStyleSheet(LINE_STYLE);
m_timeLabel = new QLabel(m_descPage);
m_timeFieldsLabel = new QLabel(m_descPage);
m_timeLabel->setMaximumSize(DESC_LABEL_SIZE);
m_timeLabel->setText(QString(tr("Time:")));
m_timeFieldsLabel->setAlignment(Qt::AlignRight);
m_recipientsLabel = new QLabel(m_descPage);
m_recipientsFieldsLabel = new QLabel(m_descPage);
m_recipientsLabel->setMaximumSize(DESC_LABEL_SIZE);
m_recipientsLabel->setText(QString(tr("To:")));
m_recipientsFieldsLabel->setAlignment(Qt::AlignRight);
m_ccLabel = new QLabel(m_descPage);
m_ccFieldsLabel = new QLabel(m_descPage);
m_ccLabel->setMaximumSize(DESC_LABEL_SIZE);
m_ccLabel->setText(QString(tr("Cc:")));
m_ccFieldsLabel->setAlignment(Qt::AlignRight);
m_attachmentLabel = new QLabel(m_descPage);
m_attachmentFieldsLabel = new QLabel(m_descPage);
m_attachmentLabel->setMaximumSize(DESC_LABEL_SIZE);
m_attachmentLabel->setText(QString(tr("Attachment:")));
m_attachmentFieldsLabel->setAlignment(Qt::AlignRight);
m_descPageLyt->setContentsMargins(DESC_LABEL_MARGINS);
m_descPageLyt->setVerticalSpacing(DESC_LABEL_SPACING);
m_descPageLyt->addRow(m_senderLabel, m_senderFieldsLabel);
m_descPageLyt->addRow(m_timeLabel, m_timeFieldsLabel);
m_descPageLyt->addRow(m_recipientsLabel, m_recipientsFieldsLabel);
m_descPageLyt->addRow(m_ccLabel, m_ccFieldsLabel);
m_descPageLyt->addRow(m_attachmentLabel, m_attachmentFieldsLabel);
*/
}

View File

@ -0,0 +1,120 @@
#ifndef MAILSEARCHPLUGIN_H
#define MAILSEARCHPLUGIN_H
#include <QObject>
#include <QWidget>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFormLayout>
#include <QFrame>
#include <QLabel>
//#include <QTextEdit>
//#include <QLineEdit>
#include <QTextBrowser>
//#include <QListWidget>
#include <QAction>
#include <QScrollArea>
#include <QScrollBar>
#include <QDBusInterface>
#include <QDBusReply>
#include <QThreadPool>
#include <QProcess>
#include <qt5xdg/xdgicon.h>
#include "search-plugin-iface.h"
#include "action-label.h"
#include "separation-line.h"
#include "libsearch_global.h"
namespace UkuiSearch {
class MailDescArea : public QScrollArea {
Q_OBJECT
public:
MailDescArea(QWidget *parent = nullptr);
~MailDescArea() = default;
private:
void initUi();
};
class LIBSEARCH_EXPORT MailSearchPlugin : public QObject , public SearchPluginIface
{
Q_OBJECT
friend class MailSearch;
public:
MailSearchPlugin(QObject *parent = nullptr);
const QString name();
const QString description();
PluginType pluginType() {return PluginType::SearchPlugin;}
const QIcon icon() {return XdgIcon::fromTheme("evolution");}
void setEnable(bool enable) {m_enable = enable;}
bool isEnable() {return m_enable;}
QString getPluginName();
void KeywordSearch(QString keyword, DataQueue<ResultInfo> *searchResult);
void stopSearch();
QList<SearchPluginIface::Actioninfo> getActioninfo(int type);
void openAction(int actionkey, QString key, int type);
QWidget *detailPage(const ResultInfo &ri);
private:
void initDetailPage();
void resizeTextEdit(QTextEdit *textEdit = nullptr);
bool m_enable = true;
static size_t uniqueSymbol;
static QMutex m_mutex;
QList<SearchPluginIface::Actioninfo> m_actionInfo;
QThreadPool m_pool;
QString m_keyword;
QString m_currentActionKey;
QWidget *m_detailPage = nullptr;
QVBoxLayout *m_detailLyt = nullptr;
QLabel *m_iconLabel = nullptr;
QFrame *m_nameFrame = nullptr;
QHBoxLayout *m_nameFrameLyt = nullptr;
QLabel *m_nameLabel = nullptr;
QLabel *m_pluginLabel = nullptr;
SeparationLine *m_line_1 = nullptr;
MailDescArea *m_descListArea = nullptr;
QWidget *m_descPage = nullptr;
QFormLayout *m_descPageLyt = nullptr;
QLabel *m_senderLabel = nullptr;
QLabel *m_timeLabel = nullptr;
QLabel *m_recipientsLabel = nullptr;
QLabel *m_ccLabel = nullptr;
QLabel *m_attachmentLabel = nullptr;
QLabel *m_senderFieldsLabel = nullptr;
QLabel *m_timeFieldsLabel = nullptr;
// QListWidget *m_recipientsFieldsLabel = nullptr;
QTextBrowser *m_recipientsFieldsLabel = nullptr;
// QTextEdit *m_recipientsFieldsLabel = nullptr;
// QLabel *m_recipientsFieldsLabel = nullptr;
// QLabel *m_ccFieldsLabel = nullptr;
QTextBrowser *m_ccFieldsLabel = nullptr;
QLabel *m_attachmentFieldsLabel = nullptr;
SeparationLine *m_line_2 = nullptr;
QFrame *m_actionFrame = nullptr;
QVBoxLayout *m_actionFrameLyt = nullptr;
ActionLabel *m_actionLabel1 = nullptr;
QVBoxLayout * m_actionLyt = nullptr;
private Q_SLOTS:
void resetHeight();
};
class MailSearch : public QObject, public QRunnable {
Q_OBJECT
public:
MailSearch(DataQueue<SearchPluginIface::ResultInfo> *searchResult, const QString &keyword, size_t uniqueSymbol);
~MailSearch() = default;
protected:
void run() override;
void createResultInfo(SearchPluginIface::ResultInfo &ri, QStringList &resultList);
private:
DataQueue<SearchPluginIface::ResultInfo> *m_searchResult = nullptr;
QString m_keyword;
size_t m_uniqueSymbol;
};
}
#endif // MAILSEARCHPLUGIN_H

View File

@ -0,0 +1,7 @@
INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/mail-search-plugin.h
SOURCES += \
$$PWD/mail-search-plugin.cpp

View File

@ -41,6 +41,13 @@ void NoteSearchPlugin::KeywordSearch(QString keyword, DataQueue<SearchPluginIfac
m_pool.start(ns);
}
void NoteSearchPlugin::stopSearch()
{
g_mutex.lock();
++g_uniqueSymbol;
g_mutex.unlock();
}
QList<SearchPluginIface::Actioninfo> NoteSearchPlugin::getActioninfo(int type)
{
return m_actionInfo;
@ -64,9 +71,11 @@ QWidget *NoteSearchPlugin::detailPage(const SearchPluginIface::ResultInfo &ri)
m_iconLabel->setPixmap(ri.icon.pixmap(120, 120));
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
QString showname = fontMetrics.elidedText(ri.name, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(FileUtils::escapeHtml(showname)));
m_nameLabel->setText(FileUtils::setAllTextBold(showname));
if(QString::compare(showname, ri.name)) {
m_nameLabel->setToolTip(ri.name);
} else {
m_nameLabel->setToolTip("");
}
m_pluginLabel->setText(tr("Application"));
QString showDesc = fontMetrics.elidedText(/*ri.description.at(0).key + " " + */ri.description.at(0).value, Qt::ElideRight, m_descLabel->width() * 2); //当字体长度超过215时显示为省略号
@ -100,10 +109,8 @@ void NoteSearchPlugin::initDetailPage()
m_nameFrameLyt->addStretch();
m_nameFrameLyt->addWidget(m_pluginLabel);
m_line_1 = new QFrame(m_detailPage);
m_line_1->setLineWidth(0);
m_line_1->setFixedHeight(1);
m_line_1->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_1 = new SeparationLine(m_detailPage);
m_descFrame = new QFrame(m_detailPage);
m_descFrameLyt = new QVBoxLayout(m_descFrame);
m_descLabel = new QLabel(m_descFrame);
@ -112,15 +119,8 @@ void NoteSearchPlugin::initDetailPage()
m_descFrameLyt->addWidget(m_descLabel);
m_descFrame->setLayout(m_descFrameLyt);
m_descFrameLyt->setContentsMargins(8, 0, 0, 0);
m_line_2 = new QFrame(m_detailPage);
m_line_2->setLineWidth(0);
m_line_2->setFixedHeight(1);
m_line_2->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_1 = new QFrame(m_detailPage);
m_line_1->setLineWidth(0);
m_line_1->setFixedHeight(1);
m_line_1->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_2 = new SeparationLine(m_detailPage);
m_actionFrame = new QFrame(m_detailPage);
m_actionFrameLyt = new QVBoxLayout(m_actionFrame);

View File

@ -15,6 +15,7 @@
#include <typeinfo>
#include "search-plugin-iface.h"
#include "action-label.h"
#include "separation-line.h"
#include "libsearch_global.h"
namespace UkuiSearch {
@ -38,6 +39,7 @@ public:
QString getPluginName();
void KeywordSearch(QString keyword,DataQueue<ResultInfo> *searchResult);
void stopSearch();
QList<SearchPluginIface::Actioninfo> getActioninfo(int type);
void openAction(int actionkey, QString key, int type);
// bool isPreviewEnable(QString key, int type);
@ -55,11 +57,11 @@ private:
QHBoxLayout *m_nameFrameLyt = nullptr;
QLabel *m_nameLabel = nullptr;
QLabel *m_pluginLabel = nullptr;
QFrame *m_line_1 = nullptr;
SeparationLine *m_line_1 = nullptr;
QFrame *m_descFrame = nullptr;
QLabel *m_descLabel = nullptr;
QVBoxLayout *m_descFrameLyt = nullptr;
QFrame *m_line_2 = nullptr;
SeparationLine *m_line_2 = nullptr;
QFrame *m_actionFrame = nullptr;
QVBoxLayout *m_actionFrameLyt = nullptr;
ActionLabel *m_actionLabel1 = nullptr;

View File

@ -5018,6 +5018,7 @@ int KBinaryParser:: readSSTRecord(readDataParam &rdParam, ppsInfoType PPS_info,
if(!eRrd.bUni)
ustotalLen += uscharlen;
UCHAR* chData = (UCHAR*)xmalloc(ustotalLen);
ushort ustotalLenTmp = ustotalLen;
if(ulNextOff < usPartLen && (ulNextOff + ustotalLen) >= usPartLen) {
ushort usIdf = usPartLen - ulNextOff;
uchar chTemp[MAX_BUFF_SIZE];
@ -5073,7 +5074,7 @@ int KBinaryParser:: readSSTRecord(readDataParam &rdParam, ppsInfoType PPS_info,
qWarning() << "Unsupport excel type:" << m_strFileName;
} else {
ushort* usData = (ushort*)chData;
content.append(QString::fromUtf16(usData, ustotalLen/2).replace("\n", "").replace("\r", " ")).append(" ");//每个单元格数据之间使用空格,//char num/2=short num
content.append(QString::fromUtf16(usData, ustotalLenTmp/2).replace("\n", "").replace("\r", " ")).append(" ");//每个单元格数据之间使用空格,//char num/2=short num
usData = (ushort*)xfree((void*)usData);
chData = NULL;
if(content.length() >= 682666) //20480000/3
@ -5132,6 +5133,7 @@ ULONG KBinaryParser::readPPtRecord(FILE* pFile, ppsInfoType* PPS_info, ULONG* au
} else {
if(usType == PPT_TEXTBYTEATOM || usType == PPT_TEXTCHARATOM) {
long llen = (long)ulLen;
long llenTmp = llen;
UCHAR* chData = (UCHAR*)xmalloc(llen);
if(!bReadBuffer(pFile, PPS_info->tPPTDocument.ulSB,
aulBBD, tBBDLen, BIG_BLOCK_SIZE,
@ -5139,7 +5141,7 @@ ULONG KBinaryParser::readPPtRecord(FILE* pFile, ppsInfoType* PPS_info, ULONG* au
return -1;
ushort* usData = (ushort*)chData;
content.append(QString::fromUtf16(usData, llen/2).replace("\n", "").replace("\r", " "));//char num/2=short num
content.append(QString::fromUtf16(usData, llenTmp/2).replace("\n", "").replace("\r", " "));//char num/2=short num
usData = (ushort*)xfree((void*)usData);
chData = NULL;

View File

@ -7,7 +7,7 @@
namespace UkuiSearch {
// TODO I want a unlocked queue
template <typename T>
class LIBSEARCH_EXPORT DataQueue : public QList<T>
class LIBSEARCH_EXPORT DataQueue : protected QList<T>
{
public:
inline void enqueue(const T &t) {

View File

@ -5,9 +5,11 @@ HEADERS += \
$$PWD/common-defines.h \
$$PWD/plugin-iface.h \
$$PWD/search-plugin-iface.h \
$$PWD/search-task-plugin-iface.h \
$$PWD/data-queue.h \
$$PWD/search-task-plugin-iface.h
$$PWD/separation-line.h
SOURCES += \
$$PWD/action-label.cpp
$$PWD/action-label.cpp \
$$PWD/separation-line.cpp

View File

@ -39,6 +39,7 @@ public:
virtual ~SearchPluginIface() {}
virtual QString getPluginName() = 0;
virtual void KeywordSearch(QString keyword,DataQueue<ResultInfo> *searchResult) = 0;
virtual void stopSearch() = 0;
virtual QList<Actioninfo> getActioninfo(int type) = 0;
virtual void openAction(int actionkey, QString key, int type) = 0;
// virtual bool isPreviewEnable(QString key, int type) = 0;

View File

@ -0,0 +1,24 @@
#include "separation-line.h"
#include "global-settings.h"
#define NOMORL_LINE_STYLE "QFrame{background: rgba(0,0,0,0.1);}"
#define DARK_LINE_STYLE "QFrame{background: rgba(255, 255, 255, 0.16);}"
using namespace UkuiSearch;
SeparationLine::SeparationLine(QWidget *parent) : QFrame(parent)
{
this->setLineWidth(0);
this->setFixedHeight(1);
setLineStyle();
connect(qApp, &QApplication::paletteChanged, this, &SeparationLine::setLineStyle);
}
void SeparationLine::setLineStyle()
{
QString type = GlobalSettings::getInstance()->getValue(STYLE_NAME_KEY).toString();
if (type == "ukui-dark") {
this->setStyleSheet(DARK_LINE_STYLE);
} else {
this->setStyleSheet(NOMORL_LINE_STYLE);
}
}

View File

@ -0,0 +1,17 @@
#ifndef SEPARATIONLINE_H
#define SEPARATIONLINE_H
#include <QObject>
#include <QFrame>
class SeparationLine : public QFrame
{
Q_OBJECT
public:
SeparationLine(QWidget *parent = nullptr);
~SeparationLine() = default;
public Q_SLOTS:
void setLineStyle();
};
#endif // SEPARATIONLINE_H

View File

@ -5,6 +5,7 @@
#include "settings-search-plugin.h"
#include "note-search-plugin.h"
#include "web-search-plugin.h"
#include "mail-search-plugin.h"
using namespace UkuiSearch;
@ -17,6 +18,7 @@ SearchPluginManager::SearchPluginManager(QObject *parent)
registerPlugin(new DirSearchPlugin(this));
registerPlugin(new FileSearchPlugin(this));
registerPlugin(new FileContengSearchPlugin(this));
// registerPlugin(new MailSearchPlugin(this));
registerPlugin(new WebSearchPlugin(this));
}

View File

@ -1,14 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="100px" height="96px" viewBox="0 0 100 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg width="100px" height="95px" viewBox="0 0 100 95" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title> Search-web-深色模式</title>
<g id="综合搜索SP2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.100000001">
<g id="搜索-网页-预览" transform="translate(-1404.000000, -393.000000)">
<g id="搜索-网页-预览" transform="translate(-1404.000000, -393.000000)" fill="#FFFFFF">
<g id="-Search-web-深色模式" transform="translate(1404.000000, 393.000000)">
<rect id="矩形" fill="#FFFFFF" transform="translate(85.000000, 85.000000) rotate(45.000000) translate(-85.000000, -85.000000) " x="74" y="81" width="22" height="8" rx="4"></rect>
<circle id="椭圆形" stroke="#FFFFFF" stroke-width="8" cx="62.5" cy="62.5" r="23.5"></circle>
<path d="M92,0 C96.418278,-8.11624501e-16 100,3.581722 100,8 L100,19 L0,19 L0,8 C-5.41083001e-16,3.581722 3.581722,8.11624501e-16 8,0 L92,0 Z M90.5,6 C88.5670034,6 87,7.56700338 87,9.5 C87,11.4329966 88.5670034,13 90.5,13 C92.4329966,13 94,11.4329966 94,9.5 C94,7.56700338 92.4329966,6 90.5,6 Z M78.5,6 C76.5670034,6 75,7.56700338 75,9.5 C75,11.4329966 76.5670034,13 78.5,13 C80.4329966,13 82,11.4329966 82,9.5 C82,7.56700338 80.4329966,6 78.5,6 Z M66.5,6 C64.5670034,6 63,7.56700338 63,9.5 C63,11.4329966 64.5670034,13 66.5,13 C68.4329966,13 70,11.4329966 70,9.5 C70,7.56700338 68.4329966,6 66.5,6 Z" id="形状结合" fill="#FFFFFF"></path>
<path d="M92,19 L100,19 L100,39 C100,41.209139 98.209139,43 96,43 C93.790861,43 92,41.209139 92,39 L92,19 L92,19 Z" id="矩形备份" fill="#FFFFFF"></path>
<path d="M4,19 L4,79 C4,83.418278 7.581722,87 12,87 L31,87 L31,87" id="路径-2" stroke="#FFFFFF" stroke-width="8" stroke-linecap="round"></path>
<path d="M62.5,35 C77.6878306,35 90,47.3121694 90,62.5 C90,68.6508474 87.9806435,74.3300488 84.5687305,78.9108043 L92.8847763,87.2279221 C94.4468735,88.7900192 94.4468735,91.3226791 92.8847763,92.8847763 C91.3226791,94.4468735 88.7900192,94.4468735 87.2279221,92.8847763 L78.9118053,84.5679849 C74.3308761,87.9803493 68.6512954,90 62.5,90 C47.3121694,90 35,77.6878306 35,62.5 C35,47.3121694 47.3121694,35 62.5,35 Z M62.5,43 C51.7304474,43 43,51.7304474 43,62.5 C43,73.2695526 51.7304474,82 62.5,82 C73.2695526,82 82,73.2695526 82,62.5 C82,51.7304474 73.2695526,43 62.5,43 Z" id="形状结合"></path>
<path d="M92,0 C96.418278,-8.11624501e-16 100,3.581722 100,8 L100,19 L0,19 L0,8 C-5.41083001e-16,3.581722 3.581722,8.11624501e-16 8,0 L92,0 Z M90.5,6 C88.5670034,6 87,7.56700338 87,9.5 C87,11.4329966 88.5670034,13 90.5,13 C92.4329966,13 94,11.4329966 94,9.5 C94,7.56700338 92.4329966,6 90.5,6 Z M78.5,6 C76.5670034,6 75,7.56700338 75,9.5 C75,11.4329966 76.5670034,13 78.5,13 C80.4329966,13 82,11.4329966 82,9.5 C82,7.56700338 80.4329966,6 78.5,6 Z M66.5,6 C64.5670034,6 63,7.56700338 63,9.5 C63,11.4329966 64.5670034,13 66.5,13 C68.4329966,13 70,11.4329966 70,9.5 C70,7.56700338 68.4329966,6 66.5,6 Z" id="形状结合"></path>
<path d="M92,19 L100,19 L100,39 C100,41.209139 98.209139,43 96,43 C93.790861,43 92,41.209139 92,39 L92,19 L92,19 Z" id="矩形备份"></path>
<path d="M8,19 L8,79.0141845 C8,81.1538477 9.68396847,82.900664 11.8003597,83.0045668 L12,83.0094564 L31,83.0094564 C33.209139,83.0094564 35,84.7982005 35,87.0047282 C35,89.1443914 33.3160315,90.8912076 31.1996403,90.9951105 L31,91 L12,91 C5.47454326,91 0.165607248,85.7976124 0.00379985776,79.3187988 L0,79.0141845 L0,19 L8,19 Z" id="路径-2" fill-rule="nonzero"></path>
</g>
</g>
</g>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,16 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="100px" height="96px" viewBox="0 0 100 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg width="100px" height="95px" viewBox="0 0 100 95" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title> Search-web-浅色模式</title>
<g id="综合搜索SP2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.100000001">
<g id="搜索-网页-预览" transform="translate(-1058.000000, -393.000000)">
<g id="搜索-网页-预览" transform="translate(-1058.000000, -394.000000)" fill="#262626">
<g id="编组" transform="translate(620.000000, 161.000000)">
<g id="编组-12备份-2" transform="translate(8.000000, 66.000000)">
<g id="-Search-web-浅色模式" transform="translate(430.000000, 166.000000)">
<rect id="矩形" fill="#262626" transform="translate(85.000000, 85.000000) rotate(45.000000) translate(-85.000000, -85.000000) " x="74" y="81" width="22" height="8" rx="4"></rect>
<circle id="椭圆形" stroke="#262626" stroke-width="8" cx="62.5" cy="62.5" r="23.5"></circle>
<path d="M92,0 C96.418278,-8.11624501e-16 100,3.581722 100,8 L100,19 L0,19 L0,8 C-5.41083001e-16,3.581722 3.581722,8.11624501e-16 8,0 L92,0 Z M90.5,6 C88.5670034,6 87,7.56700338 87,9.5 C87,11.4329966 88.5670034,13 90.5,13 C92.4329966,13 94,11.4329966 94,9.5 C94,7.56700338 92.4329966,6 90.5,6 Z M78.5,6 C76.5670034,6 75,7.56700338 75,9.5 C75,11.4329966 76.5670034,13 78.5,13 C80.4329966,13 82,11.4329966 82,9.5 C82,7.56700338 80.4329966,6 78.5,6 Z M66.5,6 C64.5670034,6 63,7.56700338 63,9.5 C63,11.4329966 64.5670034,13 66.5,13 C68.4329966,13 70,11.4329966 70,9.5 C70,7.56700338 68.4329966,6 66.5,6 Z" id="形状结合" fill="#262626"></path>
<path d="M92,19 L100,19 L100,39 C100,41.209139 98.209139,43 96,43 C93.790861,43 92,41.209139 92,39 L92,19 L92,19 Z" id="矩形备份" fill="#262626"></path>
<path d="M4,19 L4,79 C4,83.418278 7.581722,87 12,87 L31,87 L31,87" id="路径-2" stroke="#262626" stroke-width="8" stroke-linecap="round"></path>
<g id="-Search-web-浅色模式" transform="translate(430.000000, 167.000000)">
<path d="M62.5,35 C77.6878306,35 90,47.3121694 90,62.5 C90,68.6508474 87.9806435,74.3300488 84.5687305,78.9108043 L92.8847763,87.2279221 C94.4468735,88.7900192 94.4468735,91.3226791 92.8847763,92.8847763 C91.3226791,94.4468735 88.7900192,94.4468735 87.2279221,92.8847763 L78.9118053,84.5679849 C74.3308761,87.9803493 68.6512954,90 62.5,90 C47.3121694,90 35,77.6878306 35,62.5 C35,47.3121694 47.3121694,35 62.5,35 Z M62.5,43 C51.7304474,43 43,51.7304474 43,62.5 C43,73.2695526 51.7304474,82 62.5,82 C73.2695526,82 82,73.2695526 82,62.5 C82,51.7304474 73.2695526,43 62.5,43 Z" id="形状结合"></path>
<path d="M92,0 C96.418278,-8.11624501e-16 100,3.581722 100,8 L100,19 L0,19 L0,8 C-5.41083001e-16,3.581722 3.581722,8.11624501e-16 8,0 L92,0 Z M90.5,6 C88.5670034,6 87,7.56700338 87,9.5 C87,11.4329966 88.5670034,13 90.5,13 C92.4329966,13 94,11.4329966 94,9.5 C94,7.56700338 92.4329966,6 90.5,6 Z M78.5,6 C76.5670034,6 75,7.56700338 75,9.5 C75,11.4329966 76.5670034,13 78.5,13 C80.4329966,13 82,11.4329966 82,9.5 C82,7.56700338 80.4329966,6 78.5,6 Z M66.5,6 C64.5670034,6 63,7.56700338 63,9.5 C63,11.4329966 64.5670034,13 66.5,13 C68.4329966,13 70,11.4329966 70,9.5 C70,7.56700338 68.4329966,6 66.5,6 Z" id="形状结合"></path>
<path d="M92,19 L100,19 L100,39 C100,41.209139 98.209139,43 96,43 C93.790861,43 92,41.209139 92,39 L92,19 L92,19 Z" id="矩形备份"></path>
<path d="M8,19 L8,79.0141845 C8,81.1538477 9.68396847,82.900664 11.8003597,83.0045668 L12,83.0094564 L31,83.0094564 C33.209139,83.0094564 35,84.7982005 35,87.0047282 C35,89.1443914 33.3160315,90.8912076 31.1996403,90.9951105 L31,91 L12,91 C5.47454326,91 0.165607248,85.7976124 0.00379985776,79.3187988 L0,79.0141845 L0,19 L8,19 Z" id="路径-2" fill-rule="nonzero"></path>
</g>
</g>
</g>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="控制面板" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve">
<title>128</title>
<g id="图层_170">
<g id="_128">
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="64" y1="6" x2="64" y2="122" gradientTransform="matrix(1 0 0 -1 0 128)">
<stop offset="0" style="stop-color:#A6A6A6"/>
<stop offset="1" style="stop-color:#BFBFBF"/>
</linearGradient>
<circle fill="url(#SVGID_1_)" cx="64" cy="64" r="58"/>
<path fill="#EBECED" d="M64,7c31.5,0,57,25.5,57,57s-25.5,57-57,57S7,95.5,7,64C7,32.5,32.5,7,64,7 M64,5C31.4,5,5,31.4,5,64
s26.4,59,59,59s59-26.4,59-59S96.6,5,64,5z"/>
<path fill="#303030" d="M64,41c-12.7,0-23,10.3-23,23s10.3,23,23,23s23-10.3,23-23l0,0C87,51.3,76.7,41,64,41z M64,75.5
c-6.4,0-11.5-5.2-11.5-11.5S57.7,52.5,64,52.5c6.3,0,11.5,5.2,11.5,11.5C75.5,70.4,70.4,75.5,64,75.5C64,75.5,64,75.5,64,75.5z"/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="63.9949" y1="20.0112" x2="63.9949" y2="108.0218" gradientTransform="matrix(1 0 0 -1 0 128)">
<stop offset="0" style="stop-color:#242424"/>
<stop offset="1" style="stop-color:#383838"/>
</linearGradient>
<path fill="url(#SVGID_2_)" d="M106,72.8c-3.5-1.5-5.7-5-5.5-8.8c-0.2-3.8,2-7.3,5.5-8.8c1.5-0.5,2.3-2,1.9-3.5
c-1-3.5-2.3-6.8-4.1-9.9c-0.8-1.4-2.5-1.9-3.9-1.2c-3.5,1.4-7.6,0.5-10.1-2.3c-2.8-2.6-3.7-6.6-2.3-10.1c0.7-1.4,0.2-3.1-1.2-3.9
c-3.1-1.8-6.5-3.1-9.9-4.1c-1.5-0.4-3.1,0.4-3.6,1.9c-1.5,3.5-5,5.7-8.8,5.5c-3.8,0.2-7.3-2-8.8-5.5c-0.5-1.5-2.1-2.3-3.6-1.9
c-3.5,1-6.8,2.3-9.9,4.1c-1.4,0.8-1.9,2.5-1.2,3.9c1.4,3.5,0.5,7.6-2.3,10.1c-2.6,2.8-6.6,3.7-10.1,2.3c-1.4-0.7-3.1-0.2-3.9,1.2
c-1.8,3.1-3.1,6.5-4.1,9.9c-0.4,1.5,0.4,3.1,1.9,3.6c3.5,1.5,5.7,5,5.5,8.8c0.2,3.8-2,7.3-5.5,8.8c-1.5,0.5-2.3,2-1.9,3.6
c1,3.5,2.3,6.8,4.1,9.9c0.8,1.4,2.5,1.9,3.9,1.2c3.5-1.4,7.6-0.5,10.1,2.3c2.8,2.6,3.7,6.6,2.3,10.1c-0.7,1.4-0.2,3.1,1.2,3.9
c3.1,1.8,6.5,3.1,9.9,4.1c1.5,0.4,3.1-0.4,3.6-1.9c1.5-3.5,5-5.7,8.8-5.5c3.8-0.2,7.3,2,8.8,5.5c0.4,1.2,1.5,2,2.8,2
c0.3,0,0.5,0,0.8-0.1c3.5-1,6.8-2.3,9.9-4.1c1.3-0.8,1.9-2.5,1.2-3.9c-1.8-5.1,0.9-10.7,6-12.5c2.1-0.7,4.4-0.7,6.5,0
c1.4,0.7,3.1,0.2,3.9-1.2c1.8-3.1,3.1-6.5,4.1-9.9C108.3,74.9,107.5,73.3,106,72.8z M64,90.4c-14.6,0-26.4-11.8-26.4-26.4
c0-14.6,11.8-26.4,26.4-26.4c14.6,0,26.4,11.8,26.4,26.4C90.4,78.6,78.6,90.4,64,90.4C64,90.4,64,90.4,64,90.4z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">
<title>96</title>
<g id="白色">
<g id="_96">
<g id="_48">
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="48" y1="6.5" x2="48" y2="89.5" gradientTransform="matrix(1 0 0 -1 0 96)">
<stop offset="0" style="stop-color:#D6D9E6"/>
<stop offset="1" style="stop-color:#F5F5F5"/>
</linearGradient>
<path fill="url(#SVGID_1_)" d="M23,89.5c-4.7,0-8.5-3.8-8.5-8.5V15c0-4.7,3.8-8.5,8.5-8.5h50c4.7,0,8.5,3.8,8.5,8.5v53.8
L60.8,89.5H23z"/>
<path fill="#C4C6CC" d="M73,7c4.4,0,8,3.6,8,8v53.6L60.6,89H23c-4.4,0-8-3.6-8-8V15c0-4.4,3.6-8,8-8H73 M73,6H23c-5,0-9,4-9,9v66
c0,5,4,9,9,9h38l21-21V15C82,10,78,6,73,6z"/>
</g>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="63.6598" y1="46.9703" x2="70.4798" y2="52.6503" gradientTransform="matrix(1 0 0 1 0 26)">
<stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
<stop offset="1" style="stop-color:#000000;stop-opacity:5.000000e-02"/>
</linearGradient>
<path fill="url(#SVGID_2_)" d="M67,69h15L61,90V75C61,71.7,63.7,69,67,69z"/>
<path fill="#898989" d="M47.9,52.6h-4.1v-2c0-1.5,0.3-2.9,1-4.2c0.9-1.5,2.1-2.7,3.5-3.7c1.4-1,2.6-2.2,3.5-3.6
c0.7-1.1,1.1-2.5,1.1-3.8c0-1.5-0.6-2.9-1.7-3.8c-1.3-1.1-2.9-1.6-4.5-1.5c-3,0-5.8,1.2-7.9,3.4v-4.8c2.5-1.6,5.5-2.5,8.5-2.5
c2.6-0.1,5.2,0.7,7.3,2.4c1.8,1.6,2.8,3.9,2.7,6.3c0,1.7-0.4,3.4-1.3,4.9c-1.1,1.8-2.5,3.4-4.2,4.7c-1.2,0.9-2.3,2-3.2,3.2
c-0.6,1-0.9,2.1-0.8,3.3L47.9,52.6z M45.8,57.5c0.8,0,1.6,0.3,2.1,0.9c1.2,1.1,1.2,3,0.1,4.2c0,0,0,0-0.1,0.1
c-0.6,0.6-1.3,0.9-2.1,0.8c-0.8,0-1.5-0.3-2.1-0.8c-0.6-0.5-0.9-1.3-0.9-2.1c0-0.8,0.3-1.6,0.9-2.1C44.3,57.8,45.1,57.5,45.8,57.5
z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,7 +1,5 @@
<RCC>
<qresource prefix="/">
<file>index/pinyinWithTone.txt</file>
<file>index/pinyinWithoutTone.txt</file>
<file>res/icons/desktop.png</file>
<file>res/icons/close.svg</file>
<file>res/icons/edit-find-symbolic.svg</file>
@ -10,5 +8,7 @@
<file>res/icons/search-web-icon.svg</file>
<file>res/icons/search-web-dark.svg</file>
<file>res/icons/search-web-default.svg</file>
<file>res/icons/unknown.svg</file>
<file>res/icons/ukui-control-center.svg</file>
</qresource>
</RCC>

View File

@ -44,6 +44,13 @@ void UkuiSearch::SettingsSearchPlugin::KeywordSearch(QString keyword, DataQueue<
m_pool.start(settingSearch);
}
void SettingsSearchPlugin::stopSearch()
{
m_mutex.lock();
++m_uniqueSymbolForSettings;
m_mutex.unlock();
}
QList<SearchPluginIface::Actioninfo> SettingsSearchPlugin::getActioninfo(int type)
{
return m_actionInfo;
@ -70,9 +77,11 @@ QWidget *SettingsSearchPlugin::detailPage(const ResultInfo &ri)
m_iconLabel->setPixmap(ri.icon.pixmap(120, 120));
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
QString showname = fontMetrics.elidedText(ri.name, Qt::ElideRight, 215); //当字体长度超过215时显示为省略号
m_nameLabel->setText(QString("<h3 style=\"font-weight:normal;\">%1</h3>").arg(FileUtils::escapeHtml(showname)));
m_nameLabel->setText(FileUtils::setAllTextBold(showname));
if(QString::compare(showname, ri.name)) {
m_nameLabel->setToolTip(ri.name);
} else {
m_nameLabel->setToolTip("");
}
return m_detailPage;
}
@ -111,10 +120,7 @@ void SettingsSearchPlugin::initDetailPage()
m_nameFrameLyt->addStretch();
m_nameFrameLyt->addWidget(m_pluginLabel);
m_line_1 = new QFrame(m_detailPage);
m_line_1->setLineWidth(0);
m_line_1->setFixedHeight(1);
m_line_1->setStyleSheet("QFrame{background: rgba(0,0,0,0.2);}");
m_line_1 = new SeparationLine(m_detailPage);
m_actionFrame = new QFrame(m_detailPage);
m_actionFrameLyt = new QVBoxLayout(m_actionFrame);
@ -282,6 +288,7 @@ void SettingsMatch::matchDataMap(QString &key, QString &keyword, size_t uniqueSy
if (data.contains(keyword, Qt::CaseInsensitive)) {
createResultInfo(resultInfo, m_dataMap.value(key), key);
//判断是否为同一次搜索
SettingsSearchPlugin::m_mutex.lock();
if (uniqueSymbol == SettingsSearchPlugin::m_uniqueSymbolForSettings) {
searchResult->enqueue(resultInfo);
SettingsSearchPlugin::m_mutex.unlock();

View File

@ -11,6 +11,7 @@
#include <QAction>
#include <QDomDocument>
#include "action-label.h"
#include "separation-line.h"
#include "search-plugin-iface.h"
namespace UkuiSearch {
@ -30,6 +31,7 @@ public:
QString getPluginName();
void KeywordSearch(QString keyword,DataQueue<ResultInfo> *searchResult);
void stopSearch();
QList<SearchPluginIface::Actioninfo> getActioninfo(int type);
void openAction(int actionkey, QString key, int type);
// bool isPreviewEnable(QString key, int type);
@ -52,7 +54,7 @@ private:
QHBoxLayout *m_nameFrameLyt = nullptr;
QLabel *m_nameLabel = nullptr;
QLabel *m_pluginLabel = nullptr;
QFrame *m_line_1 = nullptr;
SeparationLine *m_line_1 = nullptr;
QFrame *m_actionFrame = nullptr;
QVBoxLayout *m_actionFrameLyt = nullptr;
ActionLabel *m_actionLabel1 = nullptr;

View File

@ -1,5 +1,8 @@
#include "web-search-plugin.h"
#include "global-settings.h"
#define WEB_ENGINE_KEY "webEngine"
#define BROWSERTYPE "x-scheme-handler/http"
#define DESKTOPPATH "/usr/share/applications/"
using namespace UkuiSearch;
WebSearchPlugin::WebSearchPlugin(QObject *parent) : QObject(parent)
@ -30,9 +33,26 @@ void UkuiSearch::WebSearchPlugin::KeywordSearch(QString keyword, DataQueue<UkuiS
ResultInfo resultInfo;
resultInfo.name = m_keyWord;
resultInfo.type = 0;
resultInfo.icon = QIcon(":/res/icons/search-web-icon.svg");
QString defaultwebengines(getDefaultAppId(BROWSERTYPE));
QByteArray ba = QString(DESKTOPPATH + defaultwebengines).toUtf8();
GDesktopAppInfo * textinfo = g_desktop_app_info_new_from_filename(ba.constData());
const char * iconname = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(textinfo)));
QIcon appicon;
appicon = QIcon::fromTheme(QString(QLatin1String(iconname)),
QIcon(QString("/usr/share/pixmaps/"+QString(QLatin1String(iconname))
+".png")));
resultInfo.icon = QIcon(appicon);
resultInfo.actionKey = m_keyWord;
searchResult->enqueue(resultInfo);
g_object_unref(textinfo);
}
void WebSearchPlugin::stopSearch()
{
}
QList<UkuiSearch::SearchPluginIface::Actioninfo> UkuiSearch::WebSearchPlugin::getActioninfo(int type)
@ -108,3 +128,16 @@ void UkuiSearch::WebSearchPlugin::initDetailPage()
openAction(0, m_currentActionKey, 0);
});
}
QString WebSearchPlugin::getDefaultAppId(const char *contentType)
{
GAppInfo * app = g_app_info_get_default_for_type(contentType, false);
if(app != NULL){
const char * id = g_app_info_get_id(app);
QString strId(id);
g_object_unref(app);
return strId;
} else {
return QString("");
}
}

View File

@ -12,8 +12,10 @@
#include <QAction>
#include "action-label.h"
#include "search-plugin-iface.h"
#include <gio/gdesktopappinfo.h>
namespace UkuiSearch {
class LIBSEARCH_EXPORT WebSearchPlugin : public QObject, public SearchPluginIface
{
Q_OBJECT
@ -28,6 +30,7 @@ public:
bool isEnable() {return m_enable;}
QString getPluginName();
void KeywordSearch(QString keyword,DataQueue<ResultInfo> *searchResult);
void stopSearch();
QList<SearchPluginIface::Actioninfo> getActioninfo(int type);
void openAction(int actionkey, QString key, int type);
QWidget *detailPage(const ResultInfo &ri);
@ -47,6 +50,8 @@ private:
bool m_enable = true;
QList<WebSearchPlugin::Actioninfo> m_actionInfo;
QString getDefaultAppId(const char * contentType);
};
}
#endif // WEBSEARCHPLUGIN_H

View File

@ -5,123 +5,123 @@
<name>Search</name>
<message>
<location filename="../search.cpp" line="13"/>
<location filename="../search.cpp" line="125"/>
<location filename="../search.cpp" line="130"/>
<source>Search</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="149"/>
<location filename="../search.cpp" line="154"/>
<source>Create index</source>
<translation></translation>
<extra-contents_path>/Search/Create index</extra-contents_path>
</message>
<message>
<location filename="../search.cpp" line="150"/>
<location filename="../search.cpp" line="155"/>
<source>Creating index can help you getting results quickly.</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="169"/>
<location filename="../search.cpp" line="174"/>
<source>Default web searching engine</source>
<translation></translation>
<extra-contents_path>/Search/Default web searching engine</extra-contents_path>
</message>
<message>
<location filename="../search.cpp" line="173"/>
<location filename="../search.cpp" line="178"/>
<source>baidu</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="174"/>
<location filename="../search.cpp" line="179"/>
<source>sougou</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="175"/>
<location filename="../search.cpp" line="180"/>
<source>360</source>
<translation>360</translation>
</message>
<message>
<location filename="../search.cpp" line="183"/>
<location filename="../search.cpp" line="188"/>
<source>Block Folders</source>
<translation></translation>
<extra-contents_path>/Search/Block Folders</extra-contents_path>
</message>
<message>
<location filename="../search.cpp" line="186"/>
<location filename="../search.cpp" line="193"/>
<source>Following folders will not be searched. You can set it by adding and removing folders.</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="228"/>
<location filename="../search.cpp" line="233"/>
<source>Choose folder</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="341"/>
<location filename="../search.cpp" line="346"/>
<source>delete</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="396"/>
<location filename="../search.cpp" line="401"/>
<source>Directories</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="397"/>
<location filename="../search.cpp" line="402"/>
<source>select blocked folder</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="398"/>
<location filename="../search.cpp" line="403"/>
<source>Select</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="399"/>
<location filename="../search.cpp" line="404"/>
<source>Position: </source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="400"/>
<location filename="../search.cpp" line="405"/>
<source>FileName: </source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="401"/>
<location filename="../search.cpp" line="406"/>
<source>FileType: </source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="402"/>
<location filename="../search.cpp" line="407"/>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="418"/>
<location filename="../search.cpp" line="422"/>
<location filename="../search.cpp" line="426"/>
<location filename="../search.cpp" line="430"/>
<location filename="../search.cpp" line="423"/>
<location filename="../search.cpp" line="427"/>
<location filename="../search.cpp" line="431"/>
<location filename="../search.cpp" line="435"/>
<source>Warning</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="418"/>
<location filename="../search.cpp" line="423"/>
<source>Add blocked folder failed, choosen path is empty!</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="422"/>
<location filename="../search.cpp" line="427"/>
<source>Add blocked folder failed, it is not in home path!</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="426"/>
<location filename="../search.cpp" line="431"/>
<source>Add blocked folder failed, its parent dir is exist!</source>
<translation></translation>
</message>
<message>
<location filename="../search.cpp" line="430"/>
<location filename="../search.cpp" line="435"/>
<source>Add blocked folder failed, it has been already blocked!</source>
<translation></translation>
</message>

View File

@ -20,25 +20,25 @@
<name>UkuiSearch::AppSearchPlugin</name>
<message>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="11"/>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="171"/>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="174"/>
<source>Open</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="12"/>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="172"/>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="175"/>
<source>Add Shortcut to Desktop</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="13"/>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="173"/>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="176"/>
<source>Add Shortcut to Panel</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="14"/>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="174"/>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="177"/>
<source>Install</source>
<translation></translation>
</message>
@ -49,7 +49,7 @@
<translation></translation>
</message>
<message>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="106"/>
<location filename="../../libsearch/appsearch/app-search-plugin.cpp" line="115"/>
<source>Application</source>
<translation></translation>
</message>
@ -61,49 +61,49 @@
<context>
<name>UkuiSearch::DirSearchPlugin</name>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="218"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="355"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="221"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="361"/>
<source>Open</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="219"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="356"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="222"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="362"/>
<source>Open path</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="220"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="223"/>
<source>Copy Path</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="239"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="242"/>
<source>Dir Search</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="234"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="237"/>
<source>Dir search.</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="290"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="302"/>
<source>directory</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="330"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="339"/>
<source>Path</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="342"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="351"/>
<source>Last time modified</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="357"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="363"/>
<source>Copy path</source>
<translation></translation>
</message>
@ -111,19 +111,19 @@
<context>
<name>UkuiSearch::FileContengSearchPlugin</name>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="398"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="596"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="404"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="605"/>
<source>Open</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="399"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="597"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="405"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="606"/>
<source>Open path</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="400"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="406"/>
<source>Copy Path</source>
<translation></translation>
</message>
@ -132,32 +132,32 @@
<translation type="vanished"></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="414"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="420"/>
<source>File content search.</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="419"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="425"/>
<source>File content search</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="464"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="477"/>
<source>File</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="571"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="583"/>
<source>Path</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="583"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="595"/>
<source>Last time modified</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="598"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="607"/>
<source>Copy path</source>
<translation></translation>
</message>
@ -166,13 +166,13 @@
<name>UkuiSearch::FileSearchPlugin</name>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="11"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="158"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="161"/>
<source>Open</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="12"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="159"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="162"/>
<source>Open path</source>
<translation></translation>
</message>
@ -192,38 +192,86 @@
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="67"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="183"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="74"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="186"/>
<source>Yes</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="69"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="185"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="76"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="188"/>
<source>Can not get a default application for opening %1.</source>
<translation>%1</translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="93"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="102"/>
<source>File</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="133"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="139"/>
<source>Path</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="145"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="151"/>
<source>Last time modified</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="160"/>
<location filename="../../libsearch/index/file-search-plugin.cpp" line="163"/>
<source>Copy path</source>
<translation></translation>
</message>
</context>
<context>
<name>UkuiSearch::MailSearch</name>
<message>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="337"/>
<source>From</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="338"/>
<source>Time</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="339"/>
<source>To</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="340"/>
<source>Cc</source>
<translation></translation>
</message>
</context>
<context>
<name>UkuiSearch::MailSearchPlugin</name>
<message>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="28"/>
<source>open</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="37"/>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="42"/>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="47"/>
<source>Mail Search</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="94"/>
<source>Mail</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/mailsearch/mail-search-plugin.cpp" line="231"/>
<source>Open</source>
<translation></translation>
</message>
</context>
<context>
<name>UkuiSearch::NoteSearch</name>
<message>
@ -244,7 +292,7 @@
</message>
<message>
<location filename="../../libsearch/notesearch/note-search-plugin.cpp" line="31"/>
<location filename="../../libsearch/notesearch/note-search-plugin.cpp" line="97"/>
<location filename="../../libsearch/notesearch/note-search-plugin.cpp" line="106"/>
<source>Note Search</source>
<translatorcomment>便</translatorcomment>
<translation>便</translation>
@ -256,7 +304,7 @@
<translation>便.</translation>
</message>
<message>
<location filename="../../libsearch/notesearch/note-search-plugin.cpp" line="71"/>
<location filename="../../libsearch/notesearch/note-search-plugin.cpp" line="80"/>
<source>Application</source>
<translatorcomment></translatorcomment>
<translation></translation>
@ -265,12 +313,12 @@
<context>
<name>UkuiSearch::SearchManager</name>
<message>
<location filename="../../libsearch/index/search-manager.cpp" line="98"/>
<location filename="../../libsearch/index/search-manager.cpp" line="67"/>
<source>Path:</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/index/search-manager.cpp" line="99"/>
<location filename="../../libsearch/index/search-manager.cpp" line="68"/>
<source>Modified time:</source>
<translation></translation>
</message>
@ -278,23 +326,23 @@
<context>
<name>UkuiSearch::SettingsSearchPlugin</name>
<message>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="11"/>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="405"/>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="15"/>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="128"/>
<source>Open</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="31"/>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="35"/>
<source>Settings Search</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="26"/>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="30"/>
<source>Settings search.</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="391"/>
<location filename="../../libsearch/settingsearch/settings-search-plugin.cpp" line="117"/>
<source>Settings</source>
<translation></translation>
</message>
@ -302,14 +350,14 @@
<context>
<name>UkuiSearch::WebSearchPlugin</name>
<message>
<location filename="../../libsearch/websearch/web-search-plugin.cpp" line="7"/>
<location filename="../../libsearch/websearch/web-search-plugin.cpp" line="94"/>
<location filename="../../libsearch/websearch/web-search-plugin.cpp" line="10"/>
<location filename="../../libsearch/websearch/web-search-plugin.cpp" line="114"/>
<source>Start browser search</source>
<translation></translation>
</message>
<message>
<location filename="../../libsearch/websearch/web-search-plugin.cpp" line="19"/>
<location filename="../../libsearch/websearch/web-search-plugin.cpp" line="24"/>
<location filename="../../libsearch/websearch/web-search-plugin.cpp" line="22"/>
<location filename="../../libsearch/websearch/web-search-plugin.cpp" line="27"/>
<source>Web Page</source>
<translation></translation>
</message>

View File

@ -1,18 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>QObject</name>
<message>
<location filename="../../frontend/main.cpp" line="184"/>
<source>ukui-search is already running!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UkuiSearch::BestListWidget</name>
<message>
<location filename="../../frontend/view/best-list-view.cpp" line="309"/>
<location filename="../../frontend/view/best-list-view.cpp" line="312"/>
<source>Best Matches</source>
<translation type="unfinished"></translation>
</message>
@ -20,32 +12,32 @@
<context>
<name>UkuiSearch::CreateIndexAskDialog</name>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="40"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="41"/>
<source>ukui-search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="66"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="68"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="91"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="93"/>
<source>Creating index can help you getting results quickly, whether to create or not?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="102"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="104"/>
<source>Don&apos;t remind</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="113"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="115"/>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="115"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="117"/>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
@ -61,12 +53,12 @@
<context>
<name>UkuiSearch::MainWindow</name>
<message>
<location filename="../../frontend/mainwindow.cpp" line="70"/>
<location filename="../../frontend/mainwindow.cpp" line="69"/>
<source>ukui-search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/mainwindow.cpp" line="76"/>
<location filename="../../frontend/mainwindow.cpp" line="75"/>
<source>Global Search</source>
<translation type="unfinished"></translation>
</message>
@ -74,7 +66,7 @@
<context>
<name>UkuiSearch::SearchLineEdit</name>
<message>
<location filename="../../frontend/control/search-line-edit.cpp" line="55"/>
<location filename="../../frontend/control/search-line-edit.cpp" line="56"/>
<source>Search</source>
<translation type="unfinished"></translation>
</message>
@ -240,10 +232,23 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UkuiSearch::UkuiSearchGui</name>
<message>
<location filename="../../frontend/ukui-search-gui.cpp" line="88"/>
<source>Quit ukui-search application</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/ukui-search-gui.cpp" line="91"/>
<source>Show main window</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UkuiSearch::WebSearchWidget</name>
<message>
<location filename="../../frontend/view/web-search-view.cpp" line="150"/>
<location filename="../../frontend/view/web-search-view.cpp" line="152"/>
<source>Web Page</source>
<translation type="unfinished"></translation>
</message>

View File

@ -99,9 +99,8 @@
<context>
<name>QObject</name>
<message>
<location filename="../../frontend/main.cpp" line="184"/>
<source>ukui-search is already running!</source>
<translation>ukui-bul zaten çalışıyor!</translation>
<translation type="vanished">ukui-bul zaten çalışıyor!</translation>
</message>
</context>
<context>
@ -247,7 +246,7 @@
<context>
<name>UkuiSearch::BestListWidget</name>
<message>
<location filename="../../frontend/view/best-list-view.cpp" line="309"/>
<location filename="../../frontend/view/best-list-view.cpp" line="312"/>
<source>Best Matches</source>
<translation type="unfinished">En İyi Eşleşen</translation>
</message>
@ -298,32 +297,32 @@
<context>
<name>UkuiSearch::CreateIndexAskDialog</name>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="40"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="41"/>
<source>ukui-search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="66"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="68"/>
<source>Search</source>
<translation type="unfinished">Ara</translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="91"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="93"/>
<source>Creating index can help you getting results quickly, whether to create or not?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="102"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="104"/>
<source>Don&apos;t remind</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="113"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="115"/>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="115"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="117"/>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
@ -354,12 +353,12 @@
<context>
<name>UkuiSearch::MainWindow</name>
<message>
<location filename="../../frontend/mainwindow.cpp" line="70"/>
<location filename="../../frontend/mainwindow.cpp" line="69"/>
<source>ukui-search</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/mainwindow.cpp" line="76"/>
<location filename="../../frontend/mainwindow.cpp" line="75"/>
<source>Global Search</source>
<translation type="unfinished">Genel Arama</translation>
</message>
@ -420,7 +419,7 @@
<context>
<name>UkuiSearch::SearchLineEdit</name>
<message>
<location filename="../../frontend/control/search-line-edit.cpp" line="55"/>
<location filename="../../frontend/control/search-line-edit.cpp" line="56"/>
<source>Search</source>
<translation type="unfinished">Ara</translation>
</message>
@ -613,10 +612,23 @@
<translation type="obsolete">Yükleniyor...</translation>
</message>
</context>
<context>
<name>UkuiSearch::UkuiSearchGui</name>
<message>
<location filename="../../frontend/ukui-search-gui.cpp" line="88"/>
<source>Quit ukui-search application</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../../frontend/ukui-search-gui.cpp" line="91"/>
<source>Show main window</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>UkuiSearch::WebSearchWidget</name>
<message>
<location filename="../../frontend/view/web-search-view.cpp" line="150"/>
<location filename="../../frontend/view/web-search-view.cpp" line="152"/>
<source>Web Page</source>
<translation type="unfinished"></translation>
</message>

View File

@ -1,18 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
<context>
<name>QObject</name>
<message>
<location filename="../../frontend/main.cpp" line="184"/>
<source>ukui-search is already running!</source>
<translation></translation>
</message>
</context>
<context>
<name>UkuiSearch::BestListWidget</name>
<message>
<location filename="../../frontend/view/best-list-view.cpp" line="309"/>
<location filename="../../frontend/view/best-list-view.cpp" line="312"/>
<source>Best Matches</source>
<translation></translation>
</message>
@ -67,32 +59,32 @@
<context>
<name>UkuiSearch::CreateIndexAskDialog</name>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="40"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="41"/>
<source>ukui-search</source>
<translation></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="66"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="68"/>
<source>Search</source>
<translation></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="91"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="93"/>
<source>Creating index can help you getting results quickly, whether to create or not?</source>
<translation></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="102"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="104"/>
<source>Don&apos;t remind</source>
<translation></translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="113"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="115"/>
<source>No</source>
<translation>(N)</translation>
</message>
<message>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="115"/>
<location filename="../../frontend/control/create-index-ask-dialog.cpp" line="117"/>
<source>Yes</source>
<translation>(Y)</translation>
</message>
@ -123,12 +115,12 @@
<context>
<name>UkuiSearch::MainWindow</name>
<message>
<location filename="../../frontend/mainwindow.cpp" line="70"/>
<location filename="../../frontend/mainwindow.cpp" line="69"/>
<source>ukui-search</source>
<translation></translation>
</message>
<message>
<location filename="../../frontend/mainwindow.cpp" line="76"/>
<location filename="../../frontend/mainwindow.cpp" line="75"/>
<source>Global Search</source>
<translation></translation>
</message>
@ -201,7 +193,7 @@
<context>
<name>UkuiSearch::SearchLineEdit</name>
<message>
<location filename="../../frontend/control/search-line-edit.cpp" line="55"/>
<location filename="../../frontend/control/search-line-edit.cpp" line="56"/>
<source>Search</source>
<translation></translation>
</message>
@ -394,12 +386,25 @@
<translation type="vanished">...</translation>
</message>
</context>
<context>
<name>UkuiSearch::UkuiSearchGui</name>
<message>
<location filename="../../frontend/ukui-search-gui.cpp" line="88"/>
<source>Quit ukui-search application</source>
<translation>退</translation>
</message>
<message>
<location filename="../../frontend/ukui-search-gui.cpp" line="91"/>
<source>Show main window</source>
<translation></translation>
</message>
</context>
<context>
<name>UkuiSearch::WebSearchWidget</name>
<message>
<location filename="../../frontend/view/web-search-view.cpp" line="150"/>
<location filename="../../frontend/view/web-search-view.cpp" line="152"/>
<source>Web Page</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
</context>
</TS>

View File

@ -16,7 +16,6 @@ UkuiSearchService::UkuiSearchService(int &argc, char *argv[], const QString &app
});
DirWatcher::getDirWatcher();
FileUtils::loadHanziTable("://index/pinyinWithoutTone.txt");
initGsettings();
}

View File

@ -7,7 +7,6 @@
#include "qtsingleapplication.h"
#include "search-method-manager.h"
#include "common.h"
#include "file-utils.h"
namespace UkuiSearch {
class UkuiSearchService : public QtSingleApplication

View File

@ -23,7 +23,8 @@ DEFINES += QT_DEPRECATED_WARNINGS
include(../libsearch/libukui-search-headers.pri)
include(../3rd-parties/qtsingleapplication/qtsingleapplication.pri)
LIBS += -L$$OUT_PWD/../libsearch -lukui-search
LIBS += -L$$OUT_PWD/../libchinese-segmentation -lchinese-segmentation \
-L$$OUT_PWD/../libsearch -lukui-search
SOURCES += \
main.cpp \