forked from openkylin/ukui-search
Merge pull request #243 from mammonsama666/0525-frontend
Complete some API & Optimize ui.
This commit is contained in:
commit
b3eaec9c88
|
@ -56,6 +56,7 @@ void ShowMoreLabel::initUi() {
|
||||||
m_layout->setAlignment(Qt::AlignRight);
|
m_layout->setAlignment(Qt::AlignRight);
|
||||||
m_layout->addWidget(m_textLabel);
|
m_layout->addWidget(m_textLabel);
|
||||||
m_textLabel->setPalette(pal);
|
m_textLabel->setPalette(pal);
|
||||||
|
m_textLabel->setCursor(QCursor(Qt::PointingHandCursor));
|
||||||
// m_layout->addWidget(m_loadingIconLabel);
|
// m_layout->addWidget(m_loadingIconLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,9 +65,11 @@ bool ShowMoreLabel::eventFilter(QObject *watched, QEvent *event) {
|
||||||
if(event->type() == QEvent::MouseButtonPress) {
|
if(event->type() == QEvent::MouseButtonPress) {
|
||||||
if(! m_timer->isActive()) {
|
if(! m_timer->isActive()) {
|
||||||
if(!m_isOpen) {
|
if(!m_isOpen) {
|
||||||
|
m_textLabel->setText(tr("Retract"));
|
||||||
m_isOpen = true;
|
m_isOpen = true;
|
||||||
Q_EMIT this->showMoreClicked();
|
Q_EMIT this->showMoreClicked();
|
||||||
} else {
|
} else {
|
||||||
|
m_textLabel->setText(tr("Show More..."));
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
Q_EMIT this->retractClicked();
|
Q_EMIT this->retractClicked();
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,12 @@ void ItemWidget::initUi(HomePageItemShape shape, const QString& name, const QIco
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ItemWidget::eventFilter 处理悬停、离开、点击的窗格样式和点击时发出的信号
|
||||||
|
* @param watched
|
||||||
|
* @param event
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
bool ItemWidget::eventFilter(QObject *watched, QEvent *event) {
|
bool ItemWidget::eventFilter(QObject *watched, QEvent *event) {
|
||||||
if(watched == this) {
|
if(watched == this) {
|
||||||
if(event->type() == QEvent::MouseButtonPress) {
|
if(event->type() == QEvent::MouseButtonPress) {
|
||||||
|
|
|
@ -66,6 +66,7 @@ void HomePage::appendSection(HomePageSection *section)
|
||||||
|
|
||||||
//以下为homepage各版块的信息获取的回调
|
//以下为homepage各版块的信息获取的回调
|
||||||
|
|
||||||
|
//NEW_TODO
|
||||||
//获取快速打开应用的列表
|
//获取快速打开应用的列表
|
||||||
QVector<HomePageItem> get_quickly_cb()
|
QVector<HomePageItem> get_quickly_cb()
|
||||||
{
|
{
|
||||||
|
@ -114,18 +115,25 @@ QVector<HomePageItem> get_commonly_cb()
|
||||||
void HomePage::registerSections()
|
void HomePage::registerSections()
|
||||||
{
|
{
|
||||||
//快速打开
|
//快速打开
|
||||||
HomePageSection *quickly_section = new HomePageSection(tr("Open Quickly"), HomePageItemShape::Square, m_widget);
|
createSection(tr("Open Quickly"), HomePageItemShape::Square, get_quickly_cb());
|
||||||
quickly_section->setItems(get_quickly_cb());
|
|
||||||
if (quickly_section->length())
|
|
||||||
this->appendSection(quickly_section);
|
|
||||||
//最近打开
|
//最近打开
|
||||||
HomePageSection *recently_section = new HomePageSection(tr("Recently Opened"), HomePageItemShape::Bar, m_widget);
|
createSection(tr("Recently Opened"), HomePageItemShape::Bar, get_recently_cb());
|
||||||
recently_section->setItems(get_recently_cb());
|
|
||||||
if (recently_section->length())
|
|
||||||
this->appendSection(recently_section);
|
|
||||||
//常用应用
|
//常用应用
|
||||||
HomePageSection *commonly_section = new HomePageSection(tr("Commonly Used"), HomePageItemShape::Square, m_widget);
|
createSection(tr("Commonly Used"), HomePageItemShape::Square, get_commonly_cb());
|
||||||
commonly_section->setItems(get_commonly_cb());
|
}
|
||||||
if (commonly_section->length())
|
|
||||||
this->appendSection(commonly_section);
|
void HomePage::createSection(const QString §ion_name, const HomePageItemShape &shape, QVector<HomePageItem> items)
|
||||||
|
{
|
||||||
|
HomePageSection *section = new HomePageSection(section_name, shape, m_widget);
|
||||||
|
section->setItems(items);
|
||||||
|
if (section->length())
|
||||||
|
this->appendSection(section);
|
||||||
|
connect(section, &HomePageSection::requestAction, this, [ = ](const QString &key, const QString &action, const QString &pluginId) {
|
||||||
|
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(pluginId);
|
||||||
|
if (plugin) {
|
||||||
|
plugin->openAction(action, key);
|
||||||
|
} else {
|
||||||
|
qWarning()<<"Get plugin failed!";
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include "home-page-section.h"
|
#include "home-page-section.h"
|
||||||
#include "file-utils.h"
|
#include "file-utils.h"
|
||||||
|
#include "pluginmanage/search-plugin-manager.h"
|
||||||
|
|
||||||
namespace Zeeker {
|
namespace Zeeker {
|
||||||
class HomePage : public QScrollArea
|
class HomePage : public QScrollArea
|
||||||
|
@ -40,6 +41,7 @@ private:
|
||||||
QVBoxLayout * m_mainLyt = nullptr;
|
QVBoxLayout * m_mainLyt = nullptr;
|
||||||
|
|
||||||
void registerSections();
|
void registerSections();
|
||||||
|
void createSection(const QString &, const HomePageItemShape &, QVector<HomePageItem>);
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,6 +33,9 @@ using namespace Zeeker;
|
||||||
#define NAME_LABEL_WIDTH 280
|
#define NAME_LABEL_WIDTH 280
|
||||||
#define ICON_SIZE QSize(96, 96)
|
#define ICON_SIZE QSize(96, 96)
|
||||||
#define LINE_STYLE "QFrame{background: rgba(0,0,0,0.2);}"
|
#define LINE_STYLE "QFrame{background: rgba(0,0,0,0.2);}"
|
||||||
|
#define ACTION_NORMAL_COLOR QColor(55, 144, 250, 255)
|
||||||
|
#define ACTION_HOVER_COLOR QColor(64, 169, 251, 255)
|
||||||
|
#define ACTION_PRESS_COLOR QColor(41, 108, 217, 255)
|
||||||
|
|
||||||
ResultArea::ResultArea(QWidget *parent) : QScrollArea(parent)
|
ResultArea::ResultArea(QWidget *parent) : QScrollArea(parent)
|
||||||
{
|
{
|
||||||
|
@ -110,6 +113,7 @@ void DetailArea::initUi()
|
||||||
DetailWidget::DetailWidget(QWidget *parent) : QWidget(parent)
|
DetailWidget::DetailWidget(QWidget *parent) : QWidget(parent)
|
||||||
{
|
{
|
||||||
initUi();
|
initUi();
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString escapeHtml(const QString & str) {
|
QString escapeHtml(const QString & str) {
|
||||||
|
@ -131,21 +135,22 @@ void DetailWidget::setWidgetInfo(const QString &plugin_name, const SearchPluginI
|
||||||
m_nameFrame->show();
|
m_nameFrame->show();
|
||||||
m_line_1->show();
|
m_line_1->show();
|
||||||
if (info.description.length() > 0) {
|
if (info.description.length() > 0) {
|
||||||
//NEW_TODO
|
//NEW_TODO 样式待优化
|
||||||
clearLayout(m_descFrameLyt);
|
clearLayout(m_descFrameLyt);
|
||||||
Q_FOREACH (SearchPluginIface::DescriptionInfo desc, info.description) {
|
Q_FOREACH (SearchPluginIface::DescriptionInfo desc, info.description) {
|
||||||
QLabel * descLabel = new QLabel(m_descFrame);
|
QLabel * descLabel = new QLabel(m_descFrame);
|
||||||
|
descLabel->setTextFormat(Qt::PlainText);
|
||||||
|
descLabel->setWordWrap(true);
|
||||||
QString show_desc = desc.key + ": " + desc.value;
|
QString show_desc = desc.key + ": " + desc.value;
|
||||||
descLabel->setText(show_desc);
|
descLabel->setText(show_desc);
|
||||||
m_descFrameLyt->addWidget(descLabel);
|
m_descFrameLyt->addWidget(descLabel);
|
||||||
}
|
}
|
||||||
|
m_descFrame->show();
|
||||||
m_line_2->show();
|
m_line_2->show();
|
||||||
}
|
}
|
||||||
clearLayout(m_actionFrameLyt);
|
clearLayout(m_actionFrameLyt);
|
||||||
Q_FOREACH (auto action, info.actionMap) {
|
Q_FOREACH (auto action, info.actionList) {
|
||||||
//NEW_TODO
|
ActionLabel * actionLabel = new ActionLabel(action, info.key, plugin_name, m_actionFrame);
|
||||||
QLabel * actionLabel = new QLabel(m_actionFrame);
|
|
||||||
actionLabel->setText(action);
|
|
||||||
m_actionFrameLyt->addWidget(actionLabel);
|
m_actionFrameLyt->addWidget(actionLabel);
|
||||||
}
|
}
|
||||||
m_actionFrame->show();
|
m_actionFrame->show();
|
||||||
|
@ -179,6 +184,7 @@ void DetailWidget::initUi()
|
||||||
m_nameLabel = new QLabel(m_nameFrame);
|
m_nameLabel = new QLabel(m_nameFrame);
|
||||||
m_nameLabel->setMaximumWidth(NAME_LABEL_WIDTH);
|
m_nameLabel->setMaximumWidth(NAME_LABEL_WIDTH);
|
||||||
m_pluginLabel = new QLabel(m_nameFrame);
|
m_pluginLabel = new QLabel(m_nameFrame);
|
||||||
|
m_pluginLabel->setEnabled(false);
|
||||||
m_nameFrameLyt->addWidget(m_nameLabel);
|
m_nameFrameLyt->addWidget(m_nameLabel);
|
||||||
m_nameFrameLyt->addStretch();
|
m_nameFrameLyt->addStretch();
|
||||||
m_nameFrameLyt->addWidget(m_pluginLabel);
|
m_nameFrameLyt->addWidget(m_pluginLabel);
|
||||||
|
@ -239,3 +245,48 @@ void DetailWidget::clearLayout(QLayout *layout)
|
||||||
}
|
}
|
||||||
child = NULL;
|
child = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActionLabel::ActionLabel(const QString &action, const QString &key, const QString &plugin, QWidget *parent) : QLabel(parent)
|
||||||
|
{
|
||||||
|
m_action = action;
|
||||||
|
m_key = key;
|
||||||
|
m_plugin = plugin;
|
||||||
|
this->initUi();
|
||||||
|
this->installEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionLabel::initUi()
|
||||||
|
{
|
||||||
|
this->setText(m_action);
|
||||||
|
QPalette pal = palette();
|
||||||
|
pal.setColor(QPalette::WindowText, ACTION_NORMAL_COLOR);
|
||||||
|
pal.setColor(QPalette::Light, ACTION_HOVER_COLOR);
|
||||||
|
pal.setColor(QPalette::Dark, ACTION_PRESS_COLOR);
|
||||||
|
this->setPalette(pal);
|
||||||
|
this->setForegroundRole(QPalette::WindowText);
|
||||||
|
this->setCursor(QCursor(Qt::PointingHandCursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ActionLabel::eventFilter(QObject *watched, QEvent *event)
|
||||||
|
{
|
||||||
|
if (watched == this) {
|
||||||
|
if(event->type() == QEvent::MouseButtonPress) {
|
||||||
|
this->setForegroundRole(QPalette::Dark);
|
||||||
|
return true;
|
||||||
|
} else if(event->type() == QEvent::MouseButtonRelease) {
|
||||||
|
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_plugin);
|
||||||
|
if (plugin)
|
||||||
|
plugin->openAction(m_action, m_key);
|
||||||
|
else
|
||||||
|
qWarning()<<"Get plugin failed!";
|
||||||
|
this->setForegroundRole(QPalette::Light);
|
||||||
|
return true;
|
||||||
|
} else if(event->type() == QEvent::Enter) {
|
||||||
|
this->setForegroundRole(QPalette::Light);
|
||||||
|
return true;
|
||||||
|
} else if(event->type() == QEvent::Leave) {
|
||||||
|
this->setForegroundRole(QPalette::WindowText);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -91,6 +91,23 @@ private:
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void setWidgetInfo(const QString&, const SearchPluginIface::ResultInfo&);
|
void setWidgetInfo(const QString&, const SearchPluginIface::ResultInfo&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ActionLabel : public QLabel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ActionLabel(const QString &action, const QString &key, const QString &plugin, QWidget *parent = nullptr);
|
||||||
|
~ActionLabel() = default;
|
||||||
|
private:
|
||||||
|
void initUi();
|
||||||
|
QString m_action;
|
||||||
|
QString m_key;
|
||||||
|
QString m_plugin;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *, QEvent *);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SEARCHPAGESECTION_H
|
#endif // SEARCHPAGESECTION_H
|
||||||
|
|
|
@ -32,7 +32,11 @@ SearchResultManager::SearchResultManager(const QString& plugin_id, QObject *pare
|
||||||
void SearchResultManager::startSearch(const QString &keyword)
|
void SearchResultManager::startSearch(const QString &keyword)
|
||||||
{
|
{
|
||||||
//NEW_TODO 加锁?停止线程?重新搜索?
|
//NEW_TODO 加锁?停止线程?重新搜索?
|
||||||
stopSearch();
|
// stopSearch();
|
||||||
|
qDebug()<<m_plugin_id<<"------------------>start by others";
|
||||||
|
if(! m_get_result_thread->isRunning()) {
|
||||||
|
m_get_result_thread->start();
|
||||||
|
}
|
||||||
m_result_queue->clear();
|
m_result_queue->clear();
|
||||||
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_plugin_id);
|
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_plugin_id);
|
||||||
// plugin->KeywordSearch(keyword, m_result_queue);
|
// plugin->KeywordSearch(keyword, m_result_queue);
|
||||||
|
@ -46,34 +50,31 @@ void SearchResultManager::startSearch(const QString &keyword)
|
||||||
desc_1.key = "描述";
|
desc_1.key = "描述";
|
||||||
desc_1.value = "控制面板搜索插件";
|
desc_1.value = "控制面板搜索插件";
|
||||||
desc.append(desc_1);
|
desc.append(desc_1);
|
||||||
QMap<QString,QString> actions;
|
QStringList actions;
|
||||||
actions.insert("ukcc-search","打开");
|
actions.append("打开");
|
||||||
test_info.description = desc;
|
test_info.description = desc;
|
||||||
test_info.actionMap = actions;
|
test_info.actionList = actions;
|
||||||
m_result_queue->append(test_info);
|
m_result_queue->append(test_info);
|
||||||
} else {
|
} else {
|
||||||
test_info.icon = QIcon::fromTheme("ukui-control-center");
|
test_info.icon = QIcon::fromTheme("unknown");
|
||||||
test_info.name = "文件";
|
test_info.name = "文件12345abcde.txt";
|
||||||
QVector<SearchPluginIface::DescriptionInfo> desc;
|
QVector<SearchPluginIface::DescriptionInfo> desc;
|
||||||
SearchPluginIface::DescriptionInfo desc_1;
|
SearchPluginIface::DescriptionInfo desc_1;
|
||||||
SearchPluginIface::DescriptionInfo desc_2;
|
SearchPluginIface::DescriptionInfo desc_2;
|
||||||
desc_1.key = "描述";
|
desc_1.key = "描述";
|
||||||
desc_1.value = "一个文件";
|
desc_1.value = "一个文件";
|
||||||
desc_2.key = "路径";
|
desc_2.key = "路径";
|
||||||
desc_2.value = "一个路径";
|
desc_2.value = "一个路径/a/b/c/d/e/fffffff/文件12345abcde.txt";
|
||||||
desc.append(desc_1);
|
desc.append(desc_1);
|
||||||
desc.append(desc_2);
|
desc.append(desc_2);
|
||||||
QMap<QString,QString> actions;
|
QStringList actions;
|
||||||
actions.insert("file1","打开");
|
actions.append("打开");
|
||||||
actions.insert("file2","复制路径");
|
actions.append("复制路径");
|
||||||
test_info.description = desc;
|
test_info.description = desc;
|
||||||
test_info.actionMap = actions;
|
test_info.actionList = actions;
|
||||||
m_result_queue->append(test_info);
|
m_result_queue->append(test_info);
|
||||||
}
|
}
|
||||||
/********************测试用数据********************/
|
/********************测试用数据********************/
|
||||||
|
|
||||||
qWarning()<<m_plugin_id<<"------------------>start by others";
|
|
||||||
m_get_result_thread->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,9 +83,9 @@ void SearchResultManager::startSearch(const QString &keyword)
|
||||||
void SearchResultManager::stopSearch()
|
void SearchResultManager::stopSearch()
|
||||||
{
|
{
|
||||||
if(m_get_result_thread->isRunning()) {
|
if(m_get_result_thread->isRunning()) {
|
||||||
qWarning()<<m_plugin_id<<"-------------->stopped by others";
|
qDebug()<<m_plugin_id<<"-------------->stopped by others";
|
||||||
m_get_result_thread->requestInterruption();
|
m_get_result_thread->stop();
|
||||||
m_get_result_thread->quit();
|
// m_get_result_thread->quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +99,12 @@ ReceiveResultThread::ReceiveResultThread(QQueue<SearchPluginIface::ResultInfo> *
|
||||||
m_result_queue = result_queue;
|
m_result_queue = result_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReceiveResultThread::stop()
|
||||||
|
{
|
||||||
|
this->requestInterruption();
|
||||||
|
this->quit();
|
||||||
|
}
|
||||||
|
|
||||||
//NEW_TODO 还未对队列加锁
|
//NEW_TODO 还未对队列加锁
|
||||||
void ReceiveResultThread::run()
|
void ReceiveResultThread::run()
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,13 +34,13 @@ class ReceiveResultThread : public QThread {
|
||||||
public:
|
public:
|
||||||
ReceiveResultThread(QQueue<SearchPluginIface::ResultInfo> * result_queue, QObject * parent = nullptr);
|
ReceiveResultThread(QQueue<SearchPluginIface::ResultInfo> * result_queue, QObject * parent = nullptr);
|
||||||
~ReceiveResultThread() = default;
|
~ReceiveResultThread() = default;
|
||||||
|
void stop();
|
||||||
protected:
|
protected:
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQueue<SearchPluginIface::ResultInfo> * m_result_queue;
|
QQueue<SearchPluginIface::ResultInfo> * m_result_queue;
|
||||||
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void gotResultInfo(const SearchPluginIface::ResultInfo&);
|
void gotResultInfo(const SearchPluginIface::ResultInfo&);
|
||||||
|
|
||||||
|
|
|
@ -79,14 +79,23 @@ QVariant SearchResultModel::data(const QModelIndex &index, int role) const
|
||||||
void SearchResultModel::appendInfo(const SearchPluginIface::ResultInfo &info)
|
void SearchResultModel::appendInfo(const SearchPluginIface::ResultInfo &info)
|
||||||
{
|
{
|
||||||
this->beginResetModel();
|
this->beginResetModel();
|
||||||
qWarning()<<"Got a result. name ="<<info.name;
|
qDebug()<<"Got a result. name ="<<info.name;
|
||||||
m_item->m_result_info_list.append(info);
|
m_item->m_result_info_list.append(info);
|
||||||
this->endResetModel();
|
this->endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchResultModel::startSearch(const QString &keyword)
|
||||||
|
{
|
||||||
|
if (!m_item->m_result_info_list.isEmpty()) {
|
||||||
|
this->beginResetModel();
|
||||||
|
m_item->m_result_info_list.clear();
|
||||||
|
this->endResetModel();
|
||||||
|
}
|
||||||
|
m_search_manager->startSearch(keyword);
|
||||||
|
}
|
||||||
|
|
||||||
void SearchResultModel::initConnections()
|
void SearchResultModel::initConnections()
|
||||||
{
|
{
|
||||||
connect(this, &SearchResultModel::startSearch, m_search_manager, &SearchResultManager::startSearch);
|
|
||||||
connect(this, &SearchResultModel::stopSearch, m_search_manager, &SearchResultManager::stopSearch);
|
connect(this, &SearchResultModel::stopSearch, m_search_manager, &SearchResultManager::stopSearch);
|
||||||
connect(m_search_manager, &SearchResultManager::gotResultInfo, this, &SearchResultModel::appendInfo);
|
connect(m_search_manager, &SearchResultManager::gotResultInfo, this, &SearchResultModel::appendInfo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,9 @@ public:
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void appendInfo(const SearchPluginIface::ResultInfo &);
|
void appendInfo(const SearchPluginIface::ResultInfo &);
|
||||||
|
void startSearch(const QString &);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void startSearch(const QString &);
|
|
||||||
void stopSearch();
|
void stopSearch();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include "result-view-delegate.h"
|
||||||
|
using namespace Zeeker;
|
||||||
|
|
||||||
|
ResultViewDelegate::ResultViewDelegate(QObject *parent) : QStyledItemDelegate(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResultViewDelegate::setSearchKeyword(const QString ®FindKeyWords)
|
||||||
|
{
|
||||||
|
m_regFindKeyWords.clear();
|
||||||
|
m_regFindKeyWords = regFindKeyWords;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResultViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
||||||
|
QStyleOptionViewItemV4 optionV4 = option;
|
||||||
|
initStyleOption(&optionV4, index);
|
||||||
|
|
||||||
|
QStyle *style = optionV4.widget ? optionV4.widget->style() : QApplication::style();
|
||||||
|
|
||||||
|
optionV4.text = QString();
|
||||||
|
style->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter); //绘制非文本区域内容
|
||||||
|
if(index.model()->data(index, Qt::DisplayRole).toString().isEmpty()) return;
|
||||||
|
|
||||||
|
QTextDocument doc;
|
||||||
|
doc.setHtml(getHtmlText(painter, option, index)); //提取富文本
|
||||||
|
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||||
|
|
||||||
|
if(optionV4.state & QStyle::State_Selected)
|
||||||
|
ctx.palette.setColor(QPalette::Text, optionV4.palette.color(QPalette::Active, QPalette::HighlightedText));
|
||||||
|
|
||||||
|
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &optionV4);
|
||||||
|
textRect.adjust(0, -5, 0, 0);
|
||||||
|
painter->save();
|
||||||
|
painter->translate(textRect.topLeft());
|
||||||
|
painter->setClipRect(textRect.translated(-textRect.topLeft()));
|
||||||
|
doc.documentLayout()->draw(painter, ctx); //绘制文本区域内容
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ResultViewDelegate::getHtmlText(QPainter *painter, const QStyleOptionViewItem &itemOption, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
int indexFindLeft = 0;
|
||||||
|
QString indexString = index.model()->data(index, Qt::DisplayRole).toString();
|
||||||
|
QFont ft(painter->font().family(), GlobalSettings::getInstance()->getValue(FONT_SIZE_KEY).toInt());
|
||||||
|
QFontMetrics fm(ft);
|
||||||
|
QString indexColString = fm.elidedText(indexString, Qt::ElideRight, itemOption.rect.width() - 30); //当字体超过Item的长度时显示为省略号
|
||||||
|
QString htmlString;
|
||||||
|
if((indexColString.toUpper()).contains((m_regFindKeyWords.toUpper()))) {
|
||||||
|
indexFindLeft = indexColString.toUpper().indexOf(m_regFindKeyWords.toUpper()); //得到查找字体在当前整个Item字体中的位置
|
||||||
|
htmlString = escapeHtml(indexColString.left(indexFindLeft)) + "<b>" + escapeHtml(indexColString.mid(indexFindLeft, m_regFindKeyWords.length())) + "</b>" + escapeHtml(indexColString.right(indexColString.length() - indexFindLeft - m_regFindKeyWords.length()));
|
||||||
|
} else {
|
||||||
|
bool boldOpenned = false;
|
||||||
|
for(int i = 0; i < indexColString.length(); i++) {
|
||||||
|
if((m_regFindKeyWords.toUpper()).contains(QString(indexColString.at(i)).toUpper())) {
|
||||||
|
if(! boldOpenned) {
|
||||||
|
boldOpenned = true;
|
||||||
|
htmlString.append(QString("<b>"));
|
||||||
|
}
|
||||||
|
htmlString.append(escapeHtml(QString(indexColString.at(i))));
|
||||||
|
} else {
|
||||||
|
if(boldOpenned) {
|
||||||
|
boldOpenned = false;
|
||||||
|
htmlString.append(QString("</b>"));
|
||||||
|
}
|
||||||
|
htmlString.append(escapeHtml(QString(indexColString.at(i))));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// qDebug()<<indexColString<<"---->"<<htmlString;
|
||||||
|
return htmlString;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ResultViewDelegate::escapeHtml(const QString &str) const
|
||||||
|
{
|
||||||
|
QString temp = str;
|
||||||
|
temp.replace("<", "<");
|
||||||
|
temp.replace(">", ">");
|
||||||
|
return temp;
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020, KylinSoft Co., Ltd.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors: zhangjiaping <zhangjiaping@kylinos.cn>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef RESULTVIEWDELEGATE_H
|
||||||
|
#define RESULTVIEWDELEGATE_H
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QStyle>
|
||||||
|
#include <QTextDocument>
|
||||||
|
#include <QAbstractTextDocumentLayout>
|
||||||
|
#include "global-settings.h"
|
||||||
|
|
||||||
|
namespace Zeeker {
|
||||||
|
class ResultViewDelegate : public QStyledItemDelegate {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ResultViewDelegate(QObject *parent = nullptr);
|
||||||
|
~ResultViewDelegate() = default;
|
||||||
|
void setSearchKeyword(const QString &);
|
||||||
|
private:
|
||||||
|
QString m_regFindKeyWords = 0;
|
||||||
|
void paint(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const override;
|
||||||
|
QString getHtmlText(QPainter *, const QStyleOptionViewItem &, const QModelIndex &) const;
|
||||||
|
QString escapeHtml(const QString&) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // RESULTVIEWDELEGATE_H
|
|
@ -22,6 +22,24 @@ void ResultWidget::setEnabled(const bool &enabled)
|
||||||
m_enabled = enabled;
|
m_enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ResultWidget::expandListSlot 展开列表的槽函数
|
||||||
|
*/
|
||||||
|
void ResultWidget::expandListSlot()
|
||||||
|
{
|
||||||
|
//NEW_TODO
|
||||||
|
qWarning()<<"List will be expanded!";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ResultWidget::reduceListSlot 收起列表的槽函数
|
||||||
|
*/
|
||||||
|
void ResultWidget::reduceListSlot()
|
||||||
|
{
|
||||||
|
//NEW_TODO
|
||||||
|
qWarning()<<"List will be reduced!";
|
||||||
|
}
|
||||||
|
|
||||||
void ResultWidget::initUi()
|
void ResultWidget::initUi()
|
||||||
{
|
{
|
||||||
m_mainLyt = new QVBoxLayout(this);
|
m_mainLyt = new QVBoxLayout(this);
|
||||||
|
@ -35,9 +53,10 @@ void ResultWidget::initUi()
|
||||||
|
|
||||||
m_resultView = new ResultView(m_plugin_id, this);
|
m_resultView = new ResultView(m_plugin_id, this);
|
||||||
|
|
||||||
//NEW_TODO
|
//NEW_TODO 当列表条目大于n?时显示
|
||||||
m_showMoreLabel = new ShowMoreLabel(this);
|
m_showMoreLabel = new ShowMoreLabel(this);
|
||||||
m_showMoreLabel->setFixedHeight(UNFOLD_LABEL_HEIGHT);
|
m_showMoreLabel->setFixedHeight(UNFOLD_LABEL_HEIGHT);
|
||||||
|
// m_showMoreLabel->hide();
|
||||||
|
|
||||||
m_mainLyt->addWidget(m_titleLabel);
|
m_mainLyt->addWidget(m_titleLabel);
|
||||||
m_mainLyt->addWidget(m_resultView);
|
m_mainLyt->addWidget(m_resultView);
|
||||||
|
@ -48,9 +67,17 @@ void ResultWidget::initUi()
|
||||||
void ResultWidget::initConnections()
|
void ResultWidget::initConnections()
|
||||||
{
|
{
|
||||||
connect(this, &ResultWidget::startSearch, m_resultView, &ResultView::startSearch);
|
connect(this, &ResultWidget::startSearch, m_resultView, &ResultView::startSearch);
|
||||||
|
connect(this, &ResultWidget::startSearch, this, [ = ]() {
|
||||||
|
m_showMoreLabel->resetLabel();
|
||||||
|
});
|
||||||
connect(this, &ResultWidget::stopSearch, m_resultView, &ResultView::stopSearch);
|
connect(this, &ResultWidget::stopSearch, m_resultView, &ResultView::stopSearch);
|
||||||
|
connect(this, &ResultWidget::stopSearch, this, [ = ]() {
|
||||||
|
m_showMoreLabel->resetLabel();
|
||||||
|
});
|
||||||
connect(m_resultView, &ResultView::currentRowChanged, this, &ResultWidget::currentRowChanged);
|
connect(m_resultView, &ResultView::currentRowChanged, this, &ResultWidget::currentRowChanged);
|
||||||
connect(this, &ResultWidget::clearSelectedRow, m_resultView, &ResultView::clearSelectedRow);
|
connect(this, &ResultWidget::clearSelectedRow, m_resultView, &ResultView::clearSelectedRow);
|
||||||
|
connect(m_showMoreLabel, &ShowMoreLabel::showMoreClicked, this, &ResultWidget::expandListSlot);
|
||||||
|
connect(m_showMoreLabel, &ShowMoreLabel::retractClicked, this, &ResultWidget::reduceListSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultView::ResultView(const QString &plugin_id, QWidget *parent) : QTreeView(parent)
|
ResultView::ResultView(const QString &plugin_id, QWidget *parent) : QTreeView(parent)
|
||||||
|
@ -66,6 +93,8 @@ ResultView::ResultView(const QString &plugin_id, QWidget *parent) : QTreeView(pa
|
||||||
this->setModel(m_model);
|
this->setModel(m_model);
|
||||||
initConnections();
|
initConnections();
|
||||||
m_plugin_id = plugin_id;
|
m_plugin_id = plugin_id;
|
||||||
|
m_style_delegate = new ResultViewDelegate(this);
|
||||||
|
this->setItemDelegate(m_style_delegate);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResultView::isSelected()
|
bool ResultView::isSelected()
|
||||||
|
@ -82,23 +111,55 @@ void ResultView::clearSelectedRow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ResultView::onRowDoubleClickedSlot 处理列表中的双击打开事件
|
||||||
|
* @param index 点击的条目
|
||||||
|
*/
|
||||||
|
void ResultView::onRowDoubleClickedSlot(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
const SearchPluginIface::ResultInfo &info = m_model->getInfo(index);
|
||||||
|
SearchPluginIface *plugin = SearchPluginManager::getInstance()->getPlugin(m_plugin_id);
|
||||||
|
try {
|
||||||
|
if (plugin) {
|
||||||
|
if (!info.actionList.isEmpty()) {
|
||||||
|
plugin->openAction(info.actionList.at(0), info.key);
|
||||||
|
} else {
|
||||||
|
throw -2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw -1;
|
||||||
|
}
|
||||||
|
} catch(int e) {
|
||||||
|
qWarning()<<"Open failed, reason="<<e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ResultView::onRowSelectedSlot 处理列表项选中事件
|
||||||
|
* @param selected
|
||||||
|
* @param deselected
|
||||||
|
*/
|
||||||
|
void ResultView::onRowSelectedSlot(const QItemSelection &selected, const QItemSelection &deselected)
|
||||||
|
{
|
||||||
|
//NEW_TODO
|
||||||
|
m_is_selected = true;
|
||||||
|
Q_EMIT this->currentRowChanged(m_plugin_id, m_model->getInfo(this->currentIndex()));
|
||||||
|
m_is_selected = false;
|
||||||
|
if(!selected.isEmpty()) {
|
||||||
|
QRegion region = visualRegionForSelection(selected);
|
||||||
|
QRect rect = region.boundingRect();
|
||||||
|
// Q_EMIT this->currentSelectPos(mapToParent(rect.topLeft()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ResultView::initConnections()
|
void ResultView::initConnections()
|
||||||
{
|
{
|
||||||
connect(this, &ResultView::startSearch, m_model, &SearchResultModel::startSearch);
|
// connect(this, &ResultView::startSearch, m_model, &SearchResultModel::startSearch);
|
||||||
|
connect(this, &ResultView::startSearch, [ = ](const QString &keyword) {
|
||||||
|
m_style_delegate->setSearchKeyword(keyword);
|
||||||
|
m_model->startSearch(keyword);
|
||||||
|
});
|
||||||
connect(this, &ResultView::stopSearch, m_model, &SearchResultModel::stopSearch);
|
connect(this, &ResultView::stopSearch, m_model, &SearchResultModel::stopSearch);
|
||||||
connect(this->selectionModel(), &QItemSelectionModel::selectionChanged, this, [ = ](const QItemSelection & selected, const QItemSelection & deselected) {
|
connect(this->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ResultView::onRowSelectedSlot);
|
||||||
//NEW_TODO 处理选中事件
|
connect(this, &ResultView::activated, this, &ResultView::onRowDoubleClickedSlot);
|
||||||
m_is_selected = true;
|
|
||||||
Q_EMIT this->currentRowChanged(m_plugin_id, m_model->getInfo(this->currentIndex()));
|
|
||||||
m_is_selected = false;
|
|
||||||
if(!selected.isEmpty()) {
|
|
||||||
QRegion region = visualRegionForSelection(selected);
|
|
||||||
QRect rect = region.boundingRect();
|
|
||||||
// Q_EMIT this->currentSelectPos(mapToParent(rect.topLeft()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(this, &ResultView::activated, this, [ = ](const QModelIndex & index) {
|
|
||||||
//NEW_TODO 处理双击打开事件
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "search-result-model.h"
|
#include "search-result-model.h"
|
||||||
#include "show-more-label.h"
|
#include "show-more-label.h"
|
||||||
#include "title-label.h"
|
#include "title-label.h"
|
||||||
|
#include "result-view-delegate.h"
|
||||||
|
|
||||||
namespace Zeeker {
|
namespace Zeeker {
|
||||||
|
|
||||||
|
@ -19,12 +20,15 @@ public:
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void clearSelectedRow();
|
void clearSelectedRow();
|
||||||
|
void onRowDoubleClickedSlot(const QModelIndex &);
|
||||||
|
void onRowSelectedSlot(const QItemSelection &, const QItemSelection &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initConnections();
|
void initConnections();
|
||||||
SearchResultModel * m_model = nullptr;
|
SearchResultModel * m_model = nullptr;
|
||||||
QString m_plugin_id;
|
QString m_plugin_id;
|
||||||
bool m_is_selected = false;
|
bool m_is_selected = false;
|
||||||
|
ResultViewDelegate * m_style_delegate = nullptr;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void startSearch(const QString &);
|
void startSearch(const QString &);
|
||||||
|
@ -41,6 +45,11 @@ public:
|
||||||
~ResultWidget() = default;
|
~ResultWidget() = default;
|
||||||
QString pluginId();
|
QString pluginId();
|
||||||
void setEnabled(const bool&);
|
void setEnabled(const bool&);
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void expandListSlot();
|
||||||
|
void reduceListSlot();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_plugin_id;
|
QString m_plugin_id;
|
||||||
bool m_enabled = true;
|
bool m_enabled = true;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
INCLUDEPATH += $$PWD
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
$$PWD/result-view-delegate.h \
|
||||||
$$PWD/result-view.h \
|
$$PWD/result-view.h \
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
$$PWD/result-view-delegate.cpp \
|
||||||
$$PWD/result-view.cpp \
|
$$PWD/result-view.cpp \
|
||||||
|
|
Loading…
Reference in New Issue