File indexing completed on 2024-05-12 04:33:58
0001 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- 0002 // pageSize.cpp 0003 // 0004 // Part of KVIEWSHELL - A framework for multipage text/gfx viewers 0005 // 0006 // SPDX-FileCopyrightText: 2002-2003 Stefan Kebekus 0007 // SPDX-License-Identifier: GPL-2.0-or-later 0008 0009 #include <config.h> 0010 0011 #include "debug_dvi.h" 0012 #include "length.h" 0013 #include "pageSize.h" 0014 0015 #include <KLocalizedString> 0016 0017 #include <QLocale> 0018 #include <QLoggingCategory> 0019 0020 struct pageSizeItem { 0021 const char *name; 0022 float width; // in mm 0023 float height; // in mm 0024 const char *preferredUnit; 0025 }; 0026 0027 #define defaultMetricPaperSize 4 // Default paper size is "DIN A4" 0028 #define defaultImperialPaperSize 8 // Default paper size is "US Letter" 0029 0030 static const pageSizeItem staticList[] = { 0031 {"DIN A0", 841.0f, 1189.0f, "mm"}, 0032 {"DIN A1", 594.0f, 841.0f, "mm"}, 0033 {"DIN A2", 420.0f, 594.0f, "mm"}, 0034 {"DIN A3", 297.0f, 420.0f, "mm"}, 0035 {"DIN A4", 210.0f, 297.0f, "mm"}, 0036 {"DIN A5", 148.5f, 210.0f, "mm"}, 0037 {"DIN B4", 250.0f, 353.0f, "mm"}, 0038 {"DIN B5", 176.0f, 250.0f, "mm"}, 0039 {"US Letter", 215.9f, 279.4f, "in"}, 0040 {"US Legal", 215.9f, 355.6f, "in"}, 0041 {nullptr, 0.0f, 0.0f, nullptr} // marks the end of the list. 0042 }; 0043 0044 pageSize::pageSize() 0045 { 0046 currentSize = defaultPageSize(); 0047 pageWidth.setLength_in_mm(staticList[currentSize].width); 0048 pageHeight.setLength_in_mm(staticList[currentSize].height); 0049 } 0050 0051 pageSize::pageSize(const SimplePageSize &s) 0052 { 0053 pageWidth = s.width(); 0054 pageHeight = s.height(); 0055 0056 rectifySizes(); 0057 reconstructCurrentSize(); 0058 } 0059 0060 bool pageSize::setPageSize(const QString &name) 0061 { 0062 // See if we can recognize the string 0063 QString currentName; 0064 for (int i = 0; staticList[i].name != nullptr; i++) { 0065 currentName = QString::fromLocal8Bit(staticList[i].name); 0066 if (currentName == name) { 0067 currentSize = i; 0068 // Set page width/height accordingly 0069 pageWidth.setLength_in_mm(staticList[currentSize].width); 0070 pageHeight.setLength_in_mm(staticList[currentSize].height); 0071 Q_EMIT sizeChanged(*this); 0072 return true; 0073 } 0074 } 0075 0076 // Check if the string contains 'x'. If yes, we assume it is of type 0077 // "<number>x<number>". If yes, the first number is interpreted as 0078 // the width in mm, the second as the height in mm 0079 if (name.indexOf(QLatin1Char('x')) >= 0) { 0080 bool wok, hok; 0081 float pageWidth_tmp = name.section(QLatin1Char('x'), 0, 0).toFloat(&wok); 0082 float pageHeight_tmp = name.section(QLatin1Char('x'), 1, 1).toFloat(&hok); 0083 if (wok && hok) { 0084 pageWidth.setLength_in_mm(pageWidth_tmp); 0085 pageHeight.setLength_in_mm(pageHeight_tmp); 0086 0087 rectifySizes(); 0088 reconstructCurrentSize(); 0089 Q_EMIT sizeChanged(*this); 0090 return true; 0091 } 0092 } 0093 0094 // Check if the string contains ','. If yes, we assume it is of type 0095 // "<number><unit>,<number><uni>". The first number is supposed to 0096 // be the width, the second the height. 0097 if (name.indexOf(QLatin1Char(',')) >= 0) { 0098 bool wok, hok; 0099 float pageWidth_tmp = Length::convertToMM(name.section(QLatin1Char(','), 0, 0), &wok); 0100 float pageHeight_tmp = Length::convertToMM(name.section(QLatin1Char(','), 1, 1), &hok); 0101 if (wok && hok) { 0102 pageWidth.setLength_in_mm(pageWidth_tmp); 0103 pageHeight.setLength_in_mm(pageHeight_tmp); 0104 0105 rectifySizes(); 0106 reconstructCurrentSize(); 0107 Q_EMIT sizeChanged(*this); 0108 return true; 0109 } 0110 } 0111 0112 // Last resource. Set the default, in case the string is 0113 // unintelligible to us. 0114 currentSize = defaultPageSize(); 0115 pageWidth.setLength_in_mm(staticList[currentSize].width); 0116 pageHeight.setLength_in_mm(staticList[currentSize].height); 0117 qCCritical(OkularDviShellDebug) << "pageSize::setPageSize: could not parse '" << name << "'. Using " << staticList[currentSize].name << " as a default."; 0118 Q_EMIT sizeChanged(*this); 0119 return false; 0120 } 0121 0122 void pageSize::setPageSize(double width, double height) 0123 { 0124 SimplePageSize oldPage = *this; 0125 0126 pageWidth.setLength_in_mm(width); 0127 pageHeight.setLength_in_mm(height); 0128 0129 rectifySizes(); 0130 reconstructCurrentSize(); 0131 if (!isNearlyEqual(oldPage)) { 0132 Q_EMIT sizeChanged(*this); 0133 } 0134 } 0135 0136 void pageSize::setPageSize(const QString &width, const QString &_widthUnits, const QString &height, const QString &_heightUnits) 0137 { 0138 SimplePageSize oldPage = *this; 0139 0140 double w = width.toFloat(); 0141 double h = height.toFloat(); 0142 0143 QString widthUnits = _widthUnits; 0144 if ((widthUnits != QLatin1String("cm")) && (widthUnits != QLatin1String("mm")) && (widthUnits != QLatin1String("in"))) { 0145 qCCritical(OkularDviShellDebug) << "Unrecognized page width unit '" << widthUnits << "'. Assuming mm"; 0146 widthUnits = QStringLiteral("mm"); 0147 } 0148 pageWidth.setLength_in_mm(w); 0149 if (widthUnits == QLatin1String("cm")) { 0150 pageWidth.setLength_in_cm(w); 0151 } 0152 if (widthUnits == QLatin1String("in")) { 0153 pageWidth.setLength_in_inch(w); 0154 } 0155 0156 QString heightUnits = _heightUnits; 0157 if ((heightUnits != QLatin1String("cm")) && (heightUnits != QLatin1String("mm")) && (heightUnits != QLatin1String("in"))) { 0158 qCCritical(OkularDviShellDebug) << "Unrecognized page height unit '" << widthUnits << "'. Assuming mm"; 0159 heightUnits = QStringLiteral("mm"); 0160 } 0161 pageHeight.setLength_in_mm(h); 0162 if (heightUnits == QLatin1String("cm")) { 0163 pageHeight.setLength_in_cm(h); 0164 } 0165 if (heightUnits == QLatin1String("in")) { 0166 pageHeight.setLength_in_inch(h); 0167 } 0168 0169 rectifySizes(); 0170 reconstructCurrentSize(); 0171 if (!isNearlyEqual(oldPage)) { 0172 Q_EMIT sizeChanged(*this); 0173 } 0174 } 0175 0176 void pageSize::rectifySizes() 0177 { 0178 // Now do some sanity checks to make sure that values are not 0179 // outrageous. We allow values between 5cm and 50cm. 0180 if (pageWidth.getLength_in_mm() < 50) { 0181 pageWidth.setLength_in_mm(50.0); 0182 } 0183 if (pageWidth.getLength_in_mm() > 1200) { 0184 pageWidth.setLength_in_mm(1200); 0185 } 0186 if (pageHeight.getLength_in_mm() < 50) { 0187 pageHeight.setLength_in_mm(50); 0188 } 0189 if (pageHeight.getLength_in_mm() > 1200) { 0190 pageHeight.setLength_in_mm(1200); 0191 } 0192 return; 0193 } 0194 0195 QString pageSize::preferredUnit() const 0196 { 0197 if (currentSize >= 0) { 0198 return QString::fromLocal8Bit(staticList[currentSize].preferredUnit); 0199 } 0200 0201 // User-defined size. Give a preferred unit depending on the locale. 0202 if (QLocale::system().measurementSystem() == QLocale::MetricSystem) { 0203 return QStringLiteral("mm"); 0204 } else { 0205 return QStringLiteral("in"); 0206 } 0207 } 0208 0209 QString pageSize::widthString(const QString &unit) const 0210 { 0211 QString answer = QStringLiteral("--"); 0212 0213 if (unit == QLatin1String("cm")) { 0214 answer.setNum(pageWidth.getLength_in_cm()); 0215 } 0216 if (unit == QLatin1String("mm")) { 0217 answer.setNum(pageWidth.getLength_in_mm()); 0218 } 0219 if (unit == QLatin1String("in")) { 0220 answer.setNum(pageWidth.getLength_in_inch()); 0221 } 0222 0223 return answer; 0224 } 0225 0226 QString pageSize::heightString(const QString &unit) const 0227 { 0228 QString answer = QStringLiteral("--"); 0229 0230 if (unit == QLatin1String("cm")) { 0231 answer.setNum(pageHeight.getLength_in_cm()); 0232 } 0233 if (unit == QLatin1String("mm")) { 0234 answer.setNum(pageHeight.getLength_in_mm()); 0235 } 0236 if (unit == QLatin1String("in")) { 0237 answer.setNum(pageHeight.getLength_in_inch()); 0238 } 0239 0240 return answer; 0241 } 0242 0243 QStringList pageSize::pageSizeNames() 0244 { 0245 QStringList names; 0246 0247 for (int i = 0; staticList[i].name != nullptr; i++) { 0248 names << QString::fromLocal8Bit(staticList[i].name); 0249 } 0250 0251 return names; 0252 } 0253 0254 QString pageSize::formatName() const 0255 { 0256 if (currentSize >= 0) { 0257 return QString::fromLocal8Bit(staticList[currentSize].name); 0258 } else { 0259 return QString(); 0260 } 0261 } 0262 0263 int pageSize::getOrientation() const 0264 { 0265 if (currentSize == -1) { 0266 qCCritical(OkularDviShellDebug) << "pageSize::getOrientation: getOrientation called for page format that does not have a name."; 0267 return 0; 0268 } 0269 0270 if (pageWidth.getLength_in_mm() == staticList[currentSize].width) { 0271 return 0; 0272 } else { 0273 return 1; 0274 } 0275 } 0276 0277 void pageSize::setOrientation(int orient) 0278 { 0279 if (currentSize == -1) { 0280 qCCritical(OkularDviShellDebug) << "pageSize::setOrientation: setOrientation called for page format that does not have a name."; 0281 return; 0282 } 0283 0284 if (orient == 1) { 0285 pageWidth.setLength_in_mm(staticList[currentSize].height); 0286 pageHeight.setLength_in_mm(staticList[currentSize].width); 0287 } else { 0288 pageWidth.setLength_in_mm(staticList[currentSize].width); 0289 pageHeight.setLength_in_mm(staticList[currentSize].height); 0290 } 0291 Q_EMIT sizeChanged(*this); 0292 } 0293 0294 QString pageSize::serialize() const 0295 { 0296 if ((currentSize >= 0) && (fabs(staticList[currentSize].height - pageHeight.getLength_in_mm()) <= 0.5)) { 0297 return QString::fromLocal8Bit(staticList[currentSize].name); 0298 } else { 0299 return QStringLiteral("%1x%2").arg(pageWidth.getLength_in_mm()).arg(pageHeight.getLength_in_mm()); 0300 } 0301 } 0302 0303 QString pageSize::description() const 0304 { 0305 if (!isValid()) { 0306 return QString(); 0307 } 0308 0309 QString size = QStringLiteral(" "); 0310 if (formatNumber() == -1) { 0311 if (QLocale::system().measurementSystem() == QLocale::MetricSystem) { 0312 size += QStringLiteral("%1x%2 mm").arg(width().getLength_in_mm(), 0, 'f', 0).arg(height().getLength_in_mm(), 0, 'f', 0); 0313 } else { 0314 size += QStringLiteral("%1x%2 in").arg(width().getLength_in_inch(), 0, 'g', 2).arg(height().getLength_in_inch(), 0, 'g', 2); 0315 } 0316 } else { 0317 size += formatName() + QLatin1Char('/'); 0318 if (getOrientation() == 0) { 0319 size += i18n("portrait"); 0320 } else { 0321 size += i18n("landscape"); 0322 } 0323 } 0324 return size + QLatin1Char(' '); 0325 } 0326 0327 void pageSize::reconstructCurrentSize() 0328 { 0329 for (int i = 0; staticList[i].name != nullptr; i++) { 0330 if ((fabs(staticList[i].width - pageWidth.getLength_in_mm()) <= 2) && (fabs(staticList[i].height - pageHeight.getLength_in_mm()) <= 2)) { 0331 currentSize = i; 0332 pageWidth.setLength_in_mm(staticList[currentSize].width); 0333 pageHeight.setLength_in_mm(staticList[currentSize].height); 0334 return; 0335 } 0336 if ((fabs(staticList[i].height - pageWidth.getLength_in_mm()) <= 2) && (fabs(staticList[i].width - pageHeight.getLength_in_mm()) <= 2)) { 0337 currentSize = i; 0338 pageWidth.setLength_in_mm(staticList[currentSize].height); 0339 pageHeight.setLength_in_mm(staticList[currentSize].width); 0340 return; 0341 } 0342 } 0343 currentSize = -1; 0344 return; 0345 } 0346 0347 int pageSize::defaultPageSize() 0348 { 0349 // FIXME: static_cast<QPrinter::PageSize>(KLocale::global()->pageSize()) 0350 // is the proper solution here. Then you can determine the values 0351 // without using your hardcoded table too! 0352 if (QLocale::system().measurementSystem() == QLocale::MetricSystem) { 0353 return defaultMetricPaperSize; 0354 } else { 0355 return defaultImperialPaperSize; 0356 } 0357 }