Skip to content

Commit

Permalink
feat: Merge permission/watermark into master
Browse files Browse the repository at this point in the history
合并权限控制和水印需求到主线.
涉及提交 807a3b331bae04

* 新增权限控制功能, 允许配置功能开闭;
* 新增水印功能, 允许通过配置定制阅读和打印水印;
* 水印接口特殊, DTKWidget主线和定制线的接口不同.

Log: 回合看图权限控制和水印需求
Task: https://pms.uniontech.com/story-view-27785.html
Task: https://pms.uniontech.com/story-view-30217.html
Influence: Print Permission
  • Loading branch information
rb-union committed Jan 15, 2024
1 parent 31bae04 commit d87dbfd
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 151 deletions.
142 changes: 99 additions & 43 deletions libimageviewer/service/permissionconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,8 @@ bool PermissionConfig::eventFilter(QObject *watched, QEvent *event)
return false;
}

auto checkFunc = [&](const char *prop, qreal value, qreal limit){
if (QByteArray(prop) != propEvent->propertyName()
|| (value <= limit)) {
auto checkFunc = [&](const char *prop, qreal value, qreal limit) {
if (QByteArray(prop) != propEvent->propertyName() || (value <= limit)) {
return;
}

Expand Down Expand Up @@ -327,6 +326,14 @@ QString PermissionConfig::targetImage() const
return targetImagePath;
}

/**
@return 返回适配的数据,以便于外部进行打印水印的计算
*/
PermissionConfig::AdapterWaterMarkData PermissionConfig::adapterPrintWaterMarkData() const
{
return printAdapterWaterMark;
}

#ifdef DTKWIDGET_CLASS_DWaterMarkHelper

/**
Expand Down Expand Up @@ -548,30 +555,33 @@ void PermissionConfig::initReadWaterMark(const QJsonObject &param)
}

#ifdef DTKWIDGET_CLASS_DWaterMarkHelper
readWaterMark.type = WaterMarkType::Text;
readWaterMark.font.setFamily(param.value("font").toString());
readWaterMark.font.setPointSize(param.value("fontSize").toInt());
readAdapterWaterMark.type = AdapterWaterMarkData::Text;
readAdapterWaterMark.font.setFamily(param.value("font").toString());
readAdapterWaterMark.font.setPointSize(param.value("fontSize").toInt());

QString colorName = param.value("color").toString();
if (!colorName.startsWith('#')) {
colorName.prepend('#');
}
readWaterMark.color.setNamedColor(colorName);
readWaterMark.opacity = param.value("opacity").toDouble() / 255;
readWaterMark.layout = param.value("layout").toInt() ? WaterMarkLayout::Tiled : WaterMarkLayout::Center;
readWaterMark.rotation = param.value("angle").toDouble();
readWaterMark.lineSpacing = param.value("rowSpacing").toInt();
readWaterMark.spacing = param.value("columnSpacing").toInt();
readWaterMark.text = param.value("text").toString();
readAdapterWaterMark.color.setNamedColor(colorName);
readAdapterWaterMark.opacity = param.value("opacity").toDouble() / 255;
readAdapterWaterMark.layout = param.value("layout").toInt() ? AdapterWaterMarkData::Tiled : AdapterWaterMarkData::Center;
readAdapterWaterMark.rotation = param.value("angle").toDouble();
readAdapterWaterMark.lineSpacing = param.value("rowSpacing").toInt();
readAdapterWaterMark.spacing = param.value("columnSpacing").toInt();
readAdapterWaterMark.text = param.value("text").toString();

qreal deviceRatio = qApp->devicePixelRatio();
if (ignoreDevicePixelRatio && !qFuzzyCompare(1.0, deviceRatio) && deviceRatio > 0) {
readWaterMark.font.setPointSizeF(readWaterMark.font.pointSizeF() / deviceRatio);
readWaterMark.lineSpacing /= deviceRatio;
readWaterMark.spacing /= deviceRatio;
readAdapterWaterMark.font.setPointSizeF(readAdapterWaterMark.font.pointSizeF() / deviceRatio);
readAdapterWaterMark.lineSpacing /= deviceRatio;
readAdapterWaterMark.spacing /= deviceRatio;
}

authFlags.setFlag(EnableReadWaterMark, true);

// 转换为公共接口类型
readWaterMark = convertAdapterWaterMarkData(readAdapterWaterMark);
#endif // DTKWIDGET_CLASS_DWaterMarkHelper
}

Expand All @@ -586,43 +596,86 @@ void PermissionConfig::initPrintWaterMark(const QJsonObject &param)
}

#ifdef DTKWIDGET_CLASS_DWaterMarkHelper
printWaterMark.type = WaterMarkType::Text;
printWaterMark.font.setFamily(param.value("font").toString());
printWaterMark.font.setPointSize(param.value("fontSize").toInt());
printAdapterWaterMark.type = AdapterWaterMarkData::Text;
printAdapterWaterMark.font.setFamily(param.value("font").toString());
printAdapterWaterMark.font.setPointSize(param.value("fontSize").toInt());

QString colorName = param.value("color").toString();
if (!colorName.startsWith('#')) {
colorName.prepend('#');
}
printWaterMark.color.setNamedColor(colorName);
printWaterMark.opacity = param.value("opacity").toDouble() / 255;
printWaterMark.layout = param.value("layout").toInt() ? WaterMarkLayout::Tiled : WaterMarkLayout::Center;
printWaterMark.rotation = param.value("angle").toDouble();
printWaterMark.lineSpacing = param.value("rowSpacing").toInt();
printWaterMark.spacing = param.value("columnSpacing").toInt();
printWaterMark.text = param.value("text").toString();
printAdapterWaterMark.color.setNamedColor(colorName);
printAdapterWaterMark.opacity = param.value("opacity").toDouble() / 255;
printAdapterWaterMark.layout = param.value("layout").toInt() ? AdapterWaterMarkData::Tiled : AdapterWaterMarkData::Center;
printAdapterWaterMark.rotation = param.value("angle").toDouble();
printAdapterWaterMark.lineSpacing = param.value("rowSpacing").toInt();
printAdapterWaterMark.spacing = param.value("columnSpacing").toInt();
printAdapterWaterMark.text = param.value("text").toString();

authFlags.setFlag(EnablePrintWaterMark, true);

// 计算 DTK 打印水印的间距转换系数,限制提升到 10000.0
if (!printWaterMark.text.isEmpty()) {
QFontMetrics fm(printWaterMark.font);
QSize textSize = fm.size(Qt::TextSingleLine, printWaterMark.text);
if (!printAdapterWaterMark.text.isEmpty()) {
QFontMetrics fm(printAdapterWaterMark.font);
QSize textSize = fm.size(Qt::TextSingleLine, printAdapterWaterMark.text);
if (textSize.height() > 0) {
printRowSpacing = (qreal(printWaterMark.lineSpacing + textSize.height()) / textSize.height()) - 1.0;
printRowSpacing = (qreal(printAdapterWaterMark.lineSpacing + textSize.height()) / textSize.height()) - 1.0;
printRowSpacing = qBound(0.0, printRowSpacing, 10000.0);
}
if (textSize.width() > 0) {
printColumnSpacing = (qreal(printWaterMark.spacing + textSize.width()) / textSize.width()) - 1.0;
printColumnSpacing = (qreal(printAdapterWaterMark.spacing + textSize.width()) / textSize.width()) - 1.0;
printColumnSpacing = qBound(0.0, printColumnSpacing, 10000.0);
}

qInfo() << QString("Print config spacing ratio row: %1 column: %2").arg(printRowSpacing).arg(printColumnSpacing);
}

// 转换为公共接口类型
printWaterMark = convertAdapterWaterMarkData(printAdapterWaterMark);
#endif // DTKWIDGET_CLASS_DWaterMarkHelper
}

#ifdef DTKWIDGET_CLASS_DWaterMarkHelper
/**
@brief 将内部使用的数据 `adptData` 转换为可被外部使用的公共接口类型 `WaterMarkData` ,
`WaterMarkData` 在主线和定制分支的接口结构不同,需要转换以兼容不同版本
*/
WaterMarkData PermissionConfig::convertAdapterWaterMarkData(const PermissionConfig::AdapterWaterMarkData &adptData) const
{
WaterMarkData data;
#ifdef WATERMARK_5_4_42
data.type = AdapterWaterMarkData::Text == adptData.type ? WaterMarkType::Text : WaterMarkType::Image;
data.layout = AdapterWaterMarkData::Center == adptData.layout ? WaterMarkLayout::Center : WaterMarkLayout::Tiled;
data.scaleFactor = adptData.scaleFactor;
data.spacing = adptData.spacing;
data.lineSpacing = adptData.lineSpacing;
data.text = adptData.text;
data.font = adptData.font;
data.color = adptData.color;
data.rotation = adptData.rotation;
data.opacity = adptData.opacity;
data.image = adptData.image;
data.grayScale = adptData.grayScale;

#else
data.setType(AdapterWaterMarkData::Text == adptData.type ? WaterMarkData::Text : WaterMarkData::Image);
data.setLayout(AdapterWaterMarkData::Center == adptData.layout ? WaterMarkData::Center : WaterMarkData::Tiled);
data.setScaleFactor(adptData.scaleFactor);
data.setSpacing(adptData.spacing);
data.setLineSpacing(adptData.lineSpacing);
data.setText(adptData.text);
data.setFont(adptData.font);
data.setColor(adptData.color);
data.setRotation(adptData.rotation);
data.setOpacity(adptData.opacity);
data.setImage(adptData.image);
data.setGrayScale(adptData.grayScale);
#endif // WATERMARK_5_4_42

return data;
}
#endif // DTKWIDGET_CLASS_DWaterMarkHelper

/**
@brief 检测当前系统环境中是否存在打印水印插件
通过路径下是否存在指定的插件文件决定,使用DPKG判断不一定准确,
Expand Down Expand Up @@ -686,32 +739,35 @@ bool PermissionConfig::initWaterMarkPluginEnvironment()
{
QJsonObject envData;
#ifdef DTKWIDGET_CLASS_DWaterMarkHelper
envData.insert("angle", static_cast<int>(printWaterMark.rotation));
envData.insert("transparency", static_cast<int>(printWaterMark.opacity * 100));
QFontMetrics fm(printWaterMark.font);
QSize textSize = fm.size(Qt::TextSingleLine, printWaterMark.text);
envData.insert("angle", static_cast<int>(printAdapterWaterMark.rotation));
envData.insert("transparency", static_cast<int>(printAdapterWaterMark.opacity * 100));
QFontMetrics fm(printAdapterWaterMark.font);
QSize textSize = fm.size(Qt::TextSingleLine, printAdapterWaterMark.text);
if (textSize.height() > 0) {
envData.insert("rowSpacing", qMax(0.0, (qreal(printWaterMark.lineSpacing + textSize.height()) / textSize.height()) - 1.0));
envData.insert("rowSpacing",
qMax(0.0, (qreal(printAdapterWaterMark.lineSpacing + textSize.height()) / textSize.height()) - 1.0));
}
if (textSize.width() > 0) {
envData.insert("columnSpacing", qMax(0.0, (qreal(printWaterMark.spacing + textSize.width()) / textSize.width()) - 1.0));
envData.insert("columnSpacing",
qMax(0.0, (qreal(printAdapterWaterMark.spacing + textSize.width()) / textSize.width()) - 1.0));
}

envData.insert("layout",
static_cast<int>(printWaterMark.layout == WaterMarkLayout::Center ? DPrintPreviewWatermarkInfo::Center :
DPrintPreviewWatermarkInfo::Tiled));
static_cast<int>(printAdapterWaterMark.layout == AdapterWaterMarkData::Center ?
DPrintPreviewWatermarkInfo::Center :
DPrintPreviewWatermarkInfo::Tiled));
// 仅文本水印
envData.insert("watermarkType", static_cast<int>(DPrintPreviewWatermarkInfo::TextWatermark));
envData.insert("textType", static_cast<int>(DPrintPreviewWatermarkInfo::Custom));
envData.insert("customText", printWaterMark.text);
envData.insert("textColor", printWaterMark.color.name());
envData.insert("customText", printAdapterWaterMark.text);
envData.insert("textColor", printAdapterWaterMark.color.name());
// 兼容插件传参格式
QJsonArray fontList;
fontList.append(printWaterMark.font.family());
fontList.append(printAdapterWaterMark.font.family());
envData.insert("fontList", fontList);
static const qreal sc_defaultFontSize = 65.0;
// 字体使用缩放滑块处理 10%~200%, 默认字体大小为65
envData.insert("size", int(printWaterMark.font.pointSizeF() / sc_defaultFontSize * 100));
envData.insert("size", int(printAdapterWaterMark.font.pointSizeF() / sc_defaultFontSize * 100));
#endif

QJsonDocument doc;
Expand Down
45 changes: 41 additions & 4 deletions libimageviewer/service/permissionconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@
#include <DPrintPreviewDialog>
#include <dprintpreviewsettinginfo.h>

// DTKWidget 主线和定制线的水印接口不同,通过版本进行区分
// 主线水印接口在 5.6.9 之后引入.
// 因此,判断定制线:存在水印接口,版本不低于 5.4.42.7 且低于 5.5
#if DTK_VERSION_CHECK(5, 4, 42, 7) <= DTK_VERSION && DTK_VERSION < DTK_VERSION_CHECK(5, 5, 0, 0)
#define WATERMARK_5_4_42
#endif // VERSION CHECK

DWIDGET_USE_NAMESPACE
#endif // DTKWIDGET_CLASS_DWaterMarkHelper

Expand Down Expand Up @@ -76,6 +83,27 @@ class PermissionConfig : public QObject
Q_SIGNAL void currentImagePathChanged(const QString &fileName, bool isTargetImage);
QString targetImage() const;

// 用于兼容主线/定制线的通用水印定义,适配不同接口
struct AdapterWaterMarkData
{
enum AWaterMarkType { None, Text, Image }; // 水印类型
enum AWaterMarkLayout { Center, Tiled }; // 水印布局

AWaterMarkType type = None; // 水印类型
AWaterMarkLayout layout = Center; // 水印布局
qreal scaleFactor = 1.0; // 整体大小缩放系数
int spacing = 0; // 间距
int lineSpacing = 0; // 行间距
QString text; // 文本水印内容
QFont font; // 文本水印字体
QColor color; // 文本水印颜色
qreal rotation = 0; // 水印旋转角度(0~360)
qreal opacity = 1; // 水印透明度(0~1)
QImage image; // 图片水印中的图片
bool grayScale = true; // 是否灰度化图片
};
AdapterWaterMarkData adapterPrintWaterMarkData() const;

// 阅读/打印水印
#ifdef DTKWIDGET_CLASS_DWaterMarkHelper
WaterMarkData readWaterMarkData() const;
Expand All @@ -96,6 +124,10 @@ class PermissionConfig : public QObject
void detectWaterMarkPluginExists();
bool initWaterMarkPluginEnvironment();

#ifdef DTKWIDGET_CLASS_DWaterMarkHelper
WaterMarkData convertAdapterWaterMarkData(const AdapterWaterMarkData &adptData) const;
#endif // DTKWIDGET_CLASS_DWaterMarkHelper

bool checkAuthInvalid(const QString &fileName = QString()) const;
void reduceOnePrintCount();

Expand All @@ -113,16 +145,21 @@ class PermissionConfig : public QObject
Status status = NotOpen; // 被控制权限图片的状态
Authorises authFlags = NoAuth;

bool ignoreDevicePixelRatio = false; // 过滤设备显示比率,按照原生像素计算
bool useWaterMarkPlugin = false; // 是否使用水印插件
bool ignoreDevicePixelRatio = false; // 过滤设备显示比率,按照原生像素计算
bool useWaterMarkPlugin = false; // 是否使用水印插件

AdapterWaterMarkData readAdapterWaterMark; // 水印数据,不区分DTK版本
AdapterWaterMarkData printAdapterWaterMark;
#ifdef DTKWIDGET_CLASS_DWaterMarkHelper
WaterMarkData readWaterMark;
WaterMarkData readWaterMark; // 水印数据,根据不同DTK版本支持程度不同
WaterMarkData printWaterMark;
#endif // DTKWIDGET_CLASS_DWaterMarkHelper

bool breakPrintSpacingLimit = false; // 打破打印间距限制
bool breakPrintSpacingLimit = false; // 打破打印间距限制
qreal printRowSpacing = 0.0;
qreal printColumnSpacing = 0.0;

Q_DISABLE_COPY(PermissionConfig)
};

#endif // PERMISSIONCONFIG_H
Loading

0 comments on commit d87dbfd

Please sign in to comment.