File indexing completed on 2025-02-09 05:17:56
0001 /* SPDX-FileCopyrightText: 2023 Noah Davis <noahadvs@gmail.com> 0002 * SPDX-License-Identifier: LGPL-2.0-or-later 0003 */ 0004 0005 #pragma once 0006 0007 #include "ExportManager.h" 0008 0009 #include <KLocalizedString> 0010 0011 #include <QApplication> 0012 #include <QFontDatabase> 0013 #include <QGuiApplication> 0014 #include <QLabel> 0015 #include <QStyle> 0016 0017 using namespace Qt::StringLiterals; 0018 0019 /** 0020 * A small collection of functions to help prevent duplicating the implementations of the 0021 * image and video save options pages. 0022 */ 0023 0024 inline void updateFilenamePreview(QLabel *label, const QString &templateFilename) 0025 { 0026 auto exportManager = ExportManager::instance(); 0027 // If there is no window title, we need to change it to have a placeholder. 0028 const bool usePlaceholder = exportManager->windowTitle().isEmpty(); 0029 if (usePlaceholder) { 0030 exportManager->setWindowTitle(QGuiApplication::applicationDisplayName()); 0031 } 0032 // Likewise, if no timestamp was set yet, we'll produce a new one as placeholder. 0033 const QDateTime timestamp = exportManager->timestamp(); 0034 if (!timestamp.isValid()) { 0035 exportManager->updateTimestamp(); 0036 } 0037 const auto filename = exportManager->formattedFilename(templateFilename); 0038 label->setText(xi18nc("@info", "<filename>%1</filename>", filename)); 0039 0040 // Reset any previously empty values that we had temporarily set. 0041 if (!timestamp.isValid()) { 0042 exportManager->setTimestamp(timestamp); 0043 } 0044 if (usePlaceholder) { 0045 exportManager->setWindowTitle({}); 0046 } 0047 } 0048 0049 namespace CaptureInstructionHelpers 0050 { 0051 inline QString tableRow(const QString &href, const QString &label, const QString &description = {}) 0052 { 0053 QString cell1 = u"<a href='%1'><code>%2</code></a>"_s.arg(href, label); 0054 // clang-format off 0055 return uR"( 0056 <tr><td>%1</td> 0057 <td>%2</td></tr>)"_s.arg(cell1, description); 0058 // clang-format on 0059 } 0060 inline QString buttonRow(const QString &href, const QString &label) 0061 { 0062 QString cell2 = u"<a href='%1'>%2</a>"_s.arg(href, label); 0063 // clang-format off 0064 return uR"( 0065 <tr><td> </td> 0066 <td>%1</td></tr>)"_s.arg(cell2); 0067 // clang-format on 0068 } 0069 } 0070 0071 inline QString captureInstructions(bool showExtras) 0072 { 0073 using namespace CaptureInstructionHelpers; 0074 QString intro = i18n("You can use the following placeholders in the filename, which will be replaced with actual text when the file is saved:"); 0075 0076 QString tableBody; 0077 bool hasAnyExtras = false; 0078 for (auto it = ExportManager::filenamePlaceholders.cbegin(); it != ExportManager::filenamePlaceholders.cend(); ++it) { 0079 using Flag = ExportManager::Placeholder::Flag; 0080 if (it->flags.testFlag(Flag::Hidden)) { 0081 continue; 0082 } 0083 const bool isExtra = it->flags.testFlag(Flag::Extra); 0084 hasAnyExtras |= isExtra; 0085 if (showExtras || !isExtra) { 0086 tableBody += tableRow(it->plainKey, it->htmlKey, it->description.toString()); 0087 } 0088 } 0089 tableBody += tableRow(u"/"_s, u"/"_s, i18n("To save to a sub-folder")); 0090 if (hasAnyExtras) { 0091 if (showExtras) { 0092 tableBody += buttonRow(u"showfewer"_s, i18nc("show fewer filename placeholder templates", "Show Fewer")); 0093 } else { 0094 tableBody += buttonRow(u"showmore"_s, i18nc("show more filename placeholder templates", "Show More")); 0095 } 0096 } 0097 0098 auto hspacing = qApp->style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing); 0099 // Make the distance from the bottom of a typical capital letter to the top of another below it 0100 // equal to QLayout vertical spacing, unless it is less than the largest descent. 0101 qreal vspacing = qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing); 0102 QFontMetricsF generalMetrics(QFontDatabase::systemFont(QFontDatabase::GeneralFont)); 0103 QFontMetricsF fixedMetrics(QFontDatabase::systemFont(QFontDatabase::FixedFont)); 0104 vspacing = std::max(0.0, vspacing - std::max(generalMetrics.descent(), fixedMetrics.descent())); 0105 0106 static const QString html = // clang-format off 0107 // We simulate independent vertical and horizontal cell spacing by using padding for cells 0108 // and negative margins for the table. 0109 uR"(<html> 0110 <head> 0111 <style> 0112 table { 0113 border: 0px none transparent; 0114 margin-left: -%1px; 0115 margin-right: -%1px; 0116 margin-top: -%2px; 0117 margin-bottom: -%2px; 0118 } 0119 td { 0120 border: 0px none transparent; 0121 padding-left: %1px; 0122 padding-right: %1px; 0123 padding-top: %2px; 0124 padding-bottom: %2px; 0125 } 0126 </style> 0127 </head> 0128 <body> 0129 <p>%3</p> 0130 <p><table cellspacing='0' cellpadding='0'>%4 0131 </table></p> 0132 </body> 0133 </html>)"_s; // clang-format on 0134 return html.arg(QString::number(hspacing), QString::number(vspacing / 2.0), intro, tableBody); 0135 }