|
15 | 15 |
|
16 | 16 | #include <cups/cups.h> |
17 | 17 | #include <cups/ppd.h> |
18 | | - |
| 18 | +#include <pwd.h> |
19 | 19 |
|
20 | 20 | #define FIRST_PAGE 1 |
21 | 21 | #define FIRST_INDEX 0 |
|
29 | 29 |
|
30 | 30 | #define WATER_DEFAULTFONTSIZE 65 |
31 | 31 | #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" |
32 | 35 |
|
33 | 36 | DGUI_USE_NAMESPACE |
34 | 37 | DWIDGET_BEGIN_NAMESPACE |
@@ -60,6 +63,77 @@ static void saveImageToFile(int index, const QString &outPutFileName, const QStr |
60 | 63 | }); |
61 | 64 | } |
62 | 65 |
|
| 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 | + |
63 | 137 | DPrintPreviewWidgetPrivate::DPrintPreviewWidgetPrivate(DPrintPreviewWidget *qq) |
64 | 138 | : DFramePrivate(qq) |
65 | 139 | , imposition(DPrintPreviewWidget::One) |
@@ -93,6 +167,16 @@ void DPrintPreviewWidgetPrivate::init() |
93 | 167 | background->setZValue(-1); |
94 | 168 | scene->addItem(background); |
95 | 169 |
|
| 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 | + |
96 | 180 | waterMark = new WaterMark; |
97 | 181 | scene->addItem(waterMark); |
98 | 182 | waterMark->setZValue(1); |
@@ -143,6 +227,10 @@ void DPrintPreviewWidgetPrivate::populateScene() |
143 | 227 | } |
144 | 228 |
|
145 | 229 | waterMark->setBoundingRect(pageRect); |
| 230 | + if (baseWatermarkItem) { |
| 231 | + baseWatermarkItem->updateBaseWatermark(); |
| 232 | + baseWatermarkItem->setBoundingRect(pageRect); |
| 233 | + } |
146 | 234 |
|
147 | 235 | scene->setSceneRect(QRect(QPoint(0, 0), paperSize)); |
148 | 236 | } |
@@ -418,11 +506,19 @@ void DPrintPreviewWidgetPrivate::printSinglePageDrawUtil(QPainter *painter, cons |
418 | 506 | } |
419 | 507 | // 绘制水印 |
420 | 508 | if (!waterImage.isNull()) { |
| 509 | + painter->save(); |
421 | 510 | painter->resetTransform(); |
422 | 511 | painter->translate(translateSize.width() / 2, translateSize.height() / 2); |
423 | 512 | painter->rotate(waterMark->rotation()); |
424 | | - |
425 | 513 | 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); |
426 | 522 | } |
427 | 523 |
|
428 | 524 | painter->restore(); |
@@ -460,6 +556,13 @@ void DPrintPreviewWidgetPrivate::printMultiPageDrawUtil(QPainter *painter, const |
460 | 556 | // 绘制并打水印 此时不能再设置缩放比 |
461 | 557 | if (!waterImage.isNull()) |
462 | 558 | 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 | + } |
463 | 566 | } |
464 | 567 |
|
465 | 568 | void DPrintPreviewWidgetPrivate::print(bool printAsPicture) |
@@ -2087,6 +2190,39 @@ QList<const QPicture *> DPrinter::getPrinterPages() |
2087 | 2190 | return d_ptr->previewPages(); |
2088 | 2191 | } |
2089 | 2192 |
|
| 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 | + |
2090 | 2226 | void PageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) |
2091 | 2227 | { |
2092 | 2228 | Q_UNUSED(widget); |
|
0 commit comments