Skip to content

Commit 82b15e9

Browse files
sync: from linuxdeepin/dtkwidget
Synchronize source files from linuxdeepin/dtkwidget. Source-pull-request: linuxdeepin/dtkwidget#673
1 parent 5633e71 commit 82b15e9

File tree

2 files changed

+173
-2
lines changed

2 files changed

+173
-2
lines changed

src/widgets/dprintpreviewwidget.cpp

Lines changed: 138 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include <cups/cups.h>
1717
#include <cups/ppd.h>
18-
18+
#include <pwd.h>
1919

2020
#define FIRST_PAGE 1
2121
#define FIRST_INDEX 0
@@ -29,6 +29,9 @@
2929

3030
#define WATER_DEFAULTFONTSIZE 65
3131
#define WATER_TEXTSPACE WATER_DEFAULTFONTSIZE
32+
#define DATE_TIME_FORMAT "yyyy-MM-dd hh:mm:ss"
33+
#define USER_USEC_CONFIG_FILE "/etc/usec/default/contexts/default_mls_type"
34+
#define USEC_STRICT_MODE_FILE "/sys/kernel/security/usec/strict_mode"
3235

3336
DGUI_USE_NAMESPACE
3437
DWIDGET_BEGIN_NAMESPACE
@@ -60,6 +63,77 @@ static void saveImageToFile(int index, const QString &outPutFileName, const QStr
6063
});
6164
}
6265

66+
//优先从环境变量中获取,如果环境变量为空,则通过系统调用获取。
67+
static QString getUserInfo(const QString &envVar, std::function<QString()> fallback) {
68+
QString value = qgetenv(envVar.toUtf8());
69+
if (value.isEmpty() && fallback) {
70+
value = fallback();
71+
}
72+
return value;
73+
}
74+
75+
static QString getUserName() {
76+
return getUserInfo("USER", []() {
77+
struct passwd *pw = getpwuid(getuid());
78+
return pw ? QString::fromLocal8Bit(pw->pw_name) : QString();
79+
});
80+
}
81+
82+
static QString getUserId() {
83+
return getUserInfo("UID", []() {
84+
return QString::number(getuid());
85+
});
86+
}
87+
88+
// 获取用户的安全标签
89+
static QPair<int, int> getUserSecurityLabel() {
90+
QPair<int, int> securityLabel = qMakePair(-1, -1);
91+
QFile file(USER_USEC_CONFIG_FILE);
92+
if (!file.exists()) {
93+
qWarning() << "Failed to open default_mls_type file:" << file.fileName();
94+
return securityLabel;
95+
}
96+
97+
bool res = file.open(QIODevice::ReadOnly | QIODevice::Text);
98+
if (!res) {
99+
qWarning() << "Failed to open file:" << file.fileName();
100+
return securityLabel;
101+
}
102+
103+
QString userName = getUserName();
104+
QString defaultSmodel;
105+
QString hexString;
106+
QTextStream in(&file);
107+
108+
while (!in.atEnd()) {
109+
QString line = in.readLine().trimmed();
110+
if (line.startsWith(userName + " ")) {
111+
hexString = line.split(' ').value(1).trimmed();
112+
break;
113+
}else if (line.startsWith("default ")) {
114+
defaultSmodel = line.split(' ').value(1).trimmed();
115+
}
116+
}
117+
118+
bool ok = false;
119+
quint32 hexValue = 0;
120+
if (!hexString.isEmpty() && hexString.startsWith("0x")) {
121+
hexValue = hexString.mid(2).toUInt(&ok, 16);
122+
}else if (defaultSmodel.startsWith("0x")) {
123+
hexValue = defaultSmodel.mid(2).toUInt(&ok, 16);
124+
} else {
125+
qWarning() << "Invalid security label format in file:" << file.fileName();
126+
}
127+
128+
if (ok) {
129+
int ilevel = (hexValue >> 16) & 0xFF;
130+
int slevel = hexValue & 0xFF;
131+
securityLabel = qMakePair(ilevel, slevel);
132+
}
133+
file.close();
134+
return securityLabel;
135+
}
136+
63137
DPrintPreviewWidgetPrivate::DPrintPreviewWidgetPrivate(DPrintPreviewWidget *qq)
64138
: DFramePrivate(qq)
65139
, imposition(DPrintPreviewWidget::One)
@@ -93,6 +167,16 @@ void DPrintPreviewWidgetPrivate::init()
93167
background->setZValue(-1);
94168
scene->addItem(background);
95169

170+
QFile file(USEC_STRICT_MODE_FILE);
171+
if (file.exists() && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
172+
if (file.readLine().trimmed() == "1") {
173+
baseWatermarkItem = new BaseWatermarkItem();
174+
scene->addItem(baseWatermarkItem);
175+
baseWatermarkItem->setZValue(2);
176+
}
177+
file.close();
178+
}
179+
96180
waterMark = new WaterMark;
97181
scene->addItem(waterMark);
98182
waterMark->setZValue(1);
@@ -143,6 +227,10 @@ void DPrintPreviewWidgetPrivate::populateScene()
143227
}
144228

145229
waterMark->setBoundingRect(pageRect);
230+
if (baseWatermarkItem) {
231+
baseWatermarkItem->updateBaseWatermark();
232+
baseWatermarkItem->setBoundingRect(pageRect);
233+
}
146234

147235
scene->setSceneRect(QRect(QPoint(0, 0), paperSize));
148236
}
@@ -418,11 +506,19 @@ void DPrintPreviewWidgetPrivate::printSinglePageDrawUtil(QPainter *painter, cons
418506
}
419507
// 绘制水印
420508
if (!waterImage.isNull()) {
509+
painter->save();
421510
painter->resetTransform();
422511
painter->translate(translateSize.width() / 2, translateSize.height() / 2);
423512
painter->rotate(waterMark->rotation());
424-
425513
painter->drawImage(-waterImage.width() / 2, -waterImage.height() / 2, waterImage);
514+
painter->restore();
515+
}
516+
517+
// 绘制基底水印
518+
if (baseWatermarkItem) {
519+
QRectF boundingRect = QRectF(QPointF(0, 0), translateSize);
520+
baseWatermarkItem->setBoundingRect(boundingRect);
521+
baseWatermarkItem->paint(painter, nullptr, nullptr);
426522
}
427523

428524
painter->restore();
@@ -460,6 +556,13 @@ void DPrintPreviewWidgetPrivate::printMultiPageDrawUtil(QPainter *painter, const
460556
// 绘制并打水印 此时不能再设置缩放比
461557
if (!waterImage.isNull())
462558
painter->drawImage(leftTop, waterImage);
559+
560+
// 绘制基底水印
561+
if (baseWatermarkItem) {
562+
QRectF boundingRect = QRectF(leftTop, previewPrinter->pageLayout().paintRectPixels(previewPrinter->resolution()).size());
563+
baseWatermarkItem->setBoundingRect(boundingRect);
564+
baseWatermarkItem->paint(painter, nullptr, nullptr);
565+
}
463566
}
464567

465568
void DPrintPreviewWidgetPrivate::print(bool printAsPicture)
@@ -2087,6 +2190,39 @@ QList<const QPicture *> DPrinter::getPrinterPages()
20872190
return d_ptr->previewPages();
20882191
}
20892192

2193+
void BaseWatermarkItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
2194+
{
2195+
Q_UNUSED(option);
2196+
Q_UNUSED(widget);
2197+
2198+
if (m_text.isEmpty() || m_rect.isEmpty()) {
2199+
return;
2200+
}
2201+
2202+
painter->save();
2203+
painter->setPen(m_color);
2204+
painter->setFont(m_font);
2205+
//将水印文字绘制在底部
2206+
painter->drawText(m_rect.adjusted(0, 0, 0, -50), Qt::AlignBottom | Qt::AlignHCenter, m_text);
2207+
painter->restore();
2208+
}
2209+
2210+
void BaseWatermarkItem::updateBaseWatermark()
2211+
{
2212+
// 更新水印文字内容
2213+
prepareGeometryChange();
2214+
QString userName = getUserName();
2215+
QString userId = getUserId();
2216+
QPair<int,int> securityLabel = getUserSecurityLabel();
2217+
QString timeStr = QDateTime::currentDateTime().toString(DATE_TIME_FORMAT);
2218+
QString waterMarkText = QString("时间: %1\n"
2219+
"用户: %2 UID: %3\n"
2220+
"ilevel_%4 slevel_%5")
2221+
.arg(timeStr, userName, userId, QString::number(securityLabel.first), QString::number(securityLabel.second));
2222+
m_text = waterMarkText;
2223+
update();
2224+
}
2225+
20902226
void PageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
20912227
{
20922228
Q_UNUSED(widget);

src/widgets/private/dprintpreviewwidget_p.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <QPicture>
1717
#include <qmath.h>
1818
#include <QBasicTimer>
19+
#include <QFont>
1920

2021
DWIDGET_BEGIN_NAMESPACE
2122

@@ -57,6 +58,39 @@ private Q_SLOTS:
5758
double scaleRatio;
5859
};
5960

61+
// 基底水印图元类
62+
class BaseWatermarkItem : public QGraphicsItem
63+
{
64+
public:
65+
BaseWatermarkItem(QGraphicsItem *parent = nullptr) : QGraphicsItem(parent) {
66+
m_font.setFamily("SourceHanSansSC");
67+
m_font.setPointSize(12);
68+
// 设置默认颜色和透明度
69+
m_color.setRgb(0, 0, 0, 60);
70+
}
71+
72+
void setBoundingRect(const QRectF &rect) {
73+
if (m_rect != rect) {
74+
prepareGeometryChange();
75+
m_rect = rect;
76+
update();
77+
}
78+
}
79+
80+
QRectF boundingRect() const override {
81+
return m_rect;
82+
}
83+
84+
void updateBaseWatermark();
85+
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
86+
87+
private:
88+
QString m_text;
89+
QRectF m_rect;
90+
QFont m_font;
91+
QColor m_color;
92+
};
93+
6094
class ContentItem : public QGraphicsItem
6195
{
6296
public:
@@ -303,6 +337,7 @@ class DPrintPreviewWidgetPrivate : public DFramePrivate
303337
QList<QGraphicsItem *> pages;
304338
QGraphicsRectItem *background;
305339
WaterMark *waterMark;
340+
BaseWatermarkItem *baseWatermarkItem = nullptr;
306341
QVector<int> pageRange; // 选择的页码
307342
int currentPageNumber = 0; // 处理以后当前页,值一定是连续的,比如处理共10页,那么取值就是1到10
308343
DPrinter::ColorMode colorMode;

0 commit comments

Comments
 (0)