/*
*
* 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 .
*
* Authors: zhangjiaping
*
*/
#include "search-page-section.h"
#include
using namespace Zeeker;
#define RESULT_LAYOUT_MARGINS 0,0,0,0
#define RESULT_BACKGROUND_COLOR QColor(0, 0, 0, 0)
#define DETAIL_BACKGROUND_COLOR QColor(0, 0, 0, 0)
#define DETAIL_WIDGET_TRANSPARENT 0.04
#define DETAIL_WIDGET_BORDER_RADIUS 4
#define DETAIL_WIDGET_MARGINS 8,0,8,0
#define DETAIL_FRAME_MARGINS 8,0,0,0
#define DETAIL_ICON_HEIGHT 120
#define NAME_LABEL_WIDTH 280
#define ICON_SIZE QSize(120, 120)
#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)
{
qRegisterMetaType("SearchPluginIface::ResultInfo");
initUi();
}
void ResultArea::appendWidet(ResultWidget *widget)
{
//NEW_TODO
m_mainLyt->addWidget(widget);
setupConnectionsForWidget(widget);
m_widget_list.append(widget);
int spacing_height = m_widget_list.length() > 1 ? m_mainLyt->spacing() : 0;
m_widget->setFixedHeight(m_widget->height() + widget->height() + spacing_height);
}
/**
* @brief ResultArea::setVisibleList 设置哪些插件可见,默认全部可见
* @param list
*/
void ResultArea::setVisibleList(const QStringList &list)
{
Q_FOREACH (auto widget, m_widget_list) {
if (list.contains(widget->pluginId())) {
widget->setEnabled(true);
} else {
widget->setEnabled(false);
}
}
}
void ResultArea::onWidgetSizeChanged()
{
int whole_height = 0;
Q_FOREACH (ResultWidget *widget, m_widget_list) {
whole_height += widget->height();
}
int spacing_height = m_widget_list.length() > 1 ? m_mainLyt->spacing() : 0;
m_widget->setFixedHeight(whole_height + spacing_height * (m_widget_list.length() - 1));
}
void ResultArea::initUi()
{
QPalette pal = palette();
pal.setColor(QPalette::Base, RESULT_BACKGROUND_COLOR);
pal.setColor(QPalette::Window, RESULT_BACKGROUND_COLOR);
this->setFrameShape(QFrame::Shape::NoFrame);
this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
this->setPalette(pal);
this->setWidgetResizable(true);
this->setFrameShape(QFrame::Shape::NoFrame);
m_widget = new QWidget(this);
this->setWidget(m_widget);
m_mainLyt = new QVBoxLayout(m_widget);
m_widget->setLayout(m_mainLyt);
m_mainLyt->setContentsMargins(RESULT_LAYOUT_MARGINS);
}
void ResultArea::setupConnectionsForWidget(ResultWidget *widget)
{
connect(this, &ResultArea::startSearch, widget, &ResultWidget::startSearch);
connect(this, &ResultArea::stopSearch, widget, &ResultWidget::stopSearch);
connect(widget, &ResultWidget::sizeChanged, this, &ResultArea::onWidgetSizeChanged);
}
DetailArea::DetailArea(QWidget *parent) : QScrollArea(parent)
{
initUi();
connect(this, &DetailArea::setWidgetInfo, m_detailWidget, &DetailWidget::setWidgetInfo);
}
void DetailArea::initUi()
{
QPalette pal = palette();
pal.setColor(QPalette::Base, DETAIL_BACKGROUND_COLOR);
pal.setColor(QPalette::Window, DETAIL_BACKGROUND_COLOR);
this->setPalette(pal);
this->setFrameShape(QFrame::Shape::NoFrame);
this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
this->setWidgetResizable(true);
m_detailWidget = new DetailWidget(this);
this->setWidget(m_detailWidget);
this->hide();
}
DetailWidget::DetailWidget(QWidget *parent) : QWidget(parent)
{
initUi();
clear();
}
QString escapeHtml(const QString & str) {
QString temp = str;
temp.replace("<", "<");
temp.replace(">", ">");
return temp;
}
void DetailWidget::setWidgetInfo(const QString &plugin_name, const SearchPluginIface::ResultInfo &info)
{
clearLayout(m_descFrameLyt);
clearLayout(m_previewFrameLyt);
if(SearchPluginManager::getInstance()->getPlugin(plugin_name)->isPreviewEnable(info.actionKey,info.type)) {
m_iconLabel->hide();
m_previewFrameLyt->addWidget(SearchPluginManager::getInstance()->getPlugin(plugin_name)->previewPage(info.actionKey,info.type, m_previewFrame), 0 , Qt::AlignHCenter);
m_previewFrameLyt->setContentsMargins(0,0,0,0);
m_previewFrame->show();
} else {
m_previewFrame->hide();
m_iconLabel->setPixmap(info.icon.pixmap(info.icon.actualSize(ICON_SIZE)));
m_iconLabel->show();
}
QFontMetrics fontMetrics = m_nameLabel->fontMetrics();
QString name = fontMetrics.elidedText(info.name, Qt::ElideRight, NAME_LABEL_WIDTH - 8);
m_nameLabel->setText(QString("%1
").arg(escapeHtml(name)));
m_nameLabel->setToolTip(info.name);
m_pluginLabel->setText(plugin_name);
m_nameFrame->show();
m_line_1->show();
if (info.description.length() > 0) {
//NEW_TODO 样式待优化
clearLayout(m_descFrameLyt);
Q_FOREACH (SearchPluginIface::DescriptionInfo desc, info.description) {
QLabel * descLabel = new QLabel(m_descFrame);
descLabel->setTextFormat(Qt::PlainText);
descLabel->setWordWrap(true);
QString show_desc = desc.key + " " + desc.value;
descLabel->setText(show_desc);
m_descFrameLyt->addWidget(descLabel);
}
m_descFrame->show();
m_line_2->show();
}
clearLayout(m_actionFrameLyt);
Q_FOREACH (SearchPluginIface::Actioninfo actioninfo, SearchPluginManager::getInstance()->getPlugin(plugin_name)->getActioninfo(info.type)) {
ActionLabel * actionLabel = new ActionLabel(actioninfo.displayName, info.actionKey, actioninfo.actionkey, plugin_name, info.type, m_actionFrame);
m_actionFrameLyt->addWidget(actionLabel);
}
m_actionFrame->show();
}
void DetailWidget::clear()
{
m_iconLabel->hide();
m_nameFrame->hide();
m_line_1->hide();
m_descFrame->hide();
m_line_2->hide();
m_actionFrame->hide();
}
void DetailWidget::initUi()
{
this->setFixedSize(368, 516);
m_mainLyt = new QVBoxLayout(this);
this->setLayout(m_mainLyt);
m_mainLyt->setContentsMargins(DETAIL_WIDGET_MARGINS);
m_mainLyt->setAlignment(Qt::AlignHCenter);
m_iconLabel = new QLabel(this);
m_iconLabel->setFixedHeight(DETAIL_ICON_HEIGHT);
m_iconLabel->setAlignment(Qt::AlignCenter);
m_previewFrame = new QFrame(this);
m_previewFrameLyt = new QHBoxLayout(m_previewFrame);
m_nameFrame = new QFrame(this);
m_nameFrameLyt = new QHBoxLayout(m_nameFrame);
m_nameFrame->setLayout(m_nameFrameLyt);
m_nameFrameLyt->setContentsMargins(DETAIL_FRAME_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 QFrame(this);
m_line_1->setFixedHeight(1);
m_line_1->setLineWidth(0);
m_line_1->setStyleSheet(LINE_STYLE);
m_line_2 = new QFrame(this);
m_line_2->setFixedHeight(1);
m_line_2->setLineWidth(0);
m_line_2->setStyleSheet(LINE_STYLE);
m_descFrame = new QFrame(this);
m_descFrameLyt = new QVBoxLayout(m_descFrame);
m_descFrame->setLayout(m_descFrameLyt);
m_descFrameLyt->setContentsMargins(DETAIL_FRAME_MARGINS);
m_actionFrame = new QFrame(this);
m_actionFrameLyt = new QVBoxLayout(m_actionFrame);
m_actionFrame->setLayout(m_actionFrameLyt);
m_actionFrameLyt->setContentsMargins(DETAIL_FRAME_MARGINS);
m_mainLyt->addWidget(m_iconLabel);
m_mainLyt->addWidget(m_previewFrame, 0, Qt::AlignHCenter);
m_mainLyt->addWidget(m_nameFrame);
m_mainLyt->addWidget(m_line_1);
m_mainLyt->addWidget(m_descFrame);
m_mainLyt->addWidget(m_line_2);
m_mainLyt->addWidget(m_actionFrame);
m_mainLyt->addStretch();
}
void DetailWidget::paintEvent(QPaintEvent * event)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
QRect rect = this->rect();
p.setRenderHint(QPainter::Antialiasing); // 反锯齿;
p.setBrush(opt.palette.color(QPalette::Text));
p.setOpacity(DETAIL_WIDGET_TRANSPARENT);
p.setPen(Qt::NoPen);
p.drawRoundedRect(rect, DETAIL_WIDGET_BORDER_RADIUS, DETAIL_WIDGET_BORDER_RADIUS);
return QWidget::paintEvent(event);
}
void DetailWidget::clearLayout(QLayout *layout)
{
if(!layout) return;
QLayoutItem * child;
while((child = layout->takeAt(0)) != 0) {
if(child->widget()) {
child->widget()->setParent(NULL);
}
delete child;
}
child = NULL;
}
ActionLabel::ActionLabel(const QString &action, const QString &key, const int &ActionKey, const QString &pluginId, const int type, QWidget *parent) : QLabel(parent)
{
m_action = action;
m_key = key;
m_actionKey = ActionKey;
m_type = type;
m_pluginId = pluginId;
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_pluginId);
if (plugin)
plugin->openAction(m_actionKey, m_key, m_type);
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;
}
}
}