You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
362 lines
11 KiB
362 lines
11 KiB
// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*- |
|
// pageSize.cpp |
|
// |
|
// Part of KVIEWSHELL - A framework for multipage text/gfx viewers |
|
// |
|
// (C) 2002-2003 Stefan Kebekus |
|
// Distributed under the GPL |
|
|
|
#include <config.h> |
|
|
|
#include "pageSize.h" |
|
#include "debug_dvi.h" |
|
#include "length.h" |
|
|
|
#include <KLocalizedString> |
|
|
|
#include <QLoggingCategory> |
|
|
|
struct pageSizeItem |
|
{ |
|
const char *name; |
|
float width; // in mm |
|
float height; // in mm |
|
const char *preferredUnit; |
|
}; |
|
|
|
#define defaultMetricPaperSize 4 // Default paper size is "DIN A4" |
|
#define defaultImperialPaperSize 8 // Default paper size is "US Letter" |
|
|
|
static const pageSizeItem staticList[] = { {"DIN A0", 841.0f, 1189.0f, "mm"}, |
|
{"DIN A1", 594.0f, 841.0f, "mm"}, |
|
{"DIN A2", 420.0f, 594.0f, "mm"}, |
|
{"DIN A3", 297.0f, 420.0f, "mm"}, |
|
{"DIN A4", 210.0f, 297.0f, "mm"}, |
|
{"DIN A5", 148.5f, 210.0f, "mm"}, |
|
{"DIN B4", 250.0f, 353.0f, "mm"}, |
|
{"DIN B5", 176.0f, 250.0f, "mm"}, |
|
{"US Letter", 215.9f, 279.4f, "in"}, |
|
{"US Legal", 215.9f, 355.6f, "in"}, |
|
{nullptr, 0.0f, 0.0f, nullptr} // marks the end of the list. |
|
}; |
|
|
|
|
|
pageSize::pageSize() |
|
{ |
|
currentSize = defaultPageSize(); |
|
pageWidth.setLength_in_mm(staticList[currentSize].width); |
|
pageHeight.setLength_in_mm(staticList[currentSize].height); |
|
} |
|
|
|
|
|
pageSize::pageSize(const SimplePageSize& s) |
|
{ |
|
pageWidth = s.width(); |
|
pageHeight = s.height(); |
|
|
|
rectifySizes(); |
|
reconstructCurrentSize(); |
|
} |
|
|
|
|
|
bool pageSize::setPageSize(const QString& name) |
|
{ |
|
// See if we can recognize the string |
|
QString currentName; |
|
for(int i=0; staticList[i].name != nullptr; i++) { |
|
currentName = QString::fromLocal8Bit(staticList[i].name); |
|
if (currentName == name) { |
|
currentSize = i; |
|
// Set page width/height accordingly |
|
pageWidth.setLength_in_mm(staticList[currentSize].width); |
|
pageHeight.setLength_in_mm(staticList[currentSize].height); |
|
emit(sizeChanged(*this)); |
|
return true; |
|
} |
|
} |
|
|
|
// Check if the string contains 'x'. If yes, we assume it is of type |
|
// "<number>x<number>". If yes, the first number is interpreted as |
|
// the width in mm, the second as the height in mm |
|
if (name.indexOf(QLatin1Char('x')) >= 0) { |
|
bool wok, hok; |
|
float pageWidth_tmp = name.section(QLatin1Char('x'),0,0).toFloat(&wok); |
|
float pageHeight_tmp = name.section(QLatin1Char('x'),1,1).toFloat(&hok); |
|
if (wok && hok) { |
|
pageWidth.setLength_in_mm(pageWidth_tmp); |
|
pageHeight.setLength_in_mm(pageHeight_tmp); |
|
|
|
rectifySizes(); |
|
reconstructCurrentSize(); |
|
emit(sizeChanged(*this)); |
|
return true; |
|
} |
|
} |
|
|
|
// Check if the string contains ','. If yes, we assume it is of type |
|
// "<number><unit>,<number><uni>". The first number is supposed to |
|
// be the width, the second the height. |
|
if (name.indexOf(QLatin1Char(',')) >= 0) { |
|
bool wok, hok; |
|
float pageWidth_tmp = Length::convertToMM(name.section(QLatin1Char(','),0,0), &wok); |
|
float pageHeight_tmp = Length::convertToMM(name.section(QLatin1Char(','),1,1), &hok); |
|
if (wok && hok) { |
|
pageWidth.setLength_in_mm(pageWidth_tmp); |
|
pageHeight.setLength_in_mm(pageHeight_tmp); |
|
|
|
rectifySizes(); |
|
reconstructCurrentSize(); |
|
emit(sizeChanged(*this)); |
|
return true; |
|
} |
|
} |
|
|
|
// Last resource. Set the default, in case the string is |
|
// unintelligible to us. |
|
currentSize = defaultPageSize(); |
|
pageWidth.setLength_in_mm(staticList[currentSize].width); |
|
pageHeight.setLength_in_mm(staticList[currentSize].height); |
|
qCCritical(OkularDviShellDebug) << "pageSize::setPageSize: could not parse '" << name << "'. Using " << staticList[currentSize].name << " as a default." << endl; |
|
emit(sizeChanged(*this)); |
|
return false; |
|
} |
|
|
|
|
|
void pageSize::setPageSize(double width, double height) |
|
{ |
|
SimplePageSize oldPage = *this; |
|
|
|
pageWidth.setLength_in_mm(width); |
|
pageHeight.setLength_in_mm(height); |
|
|
|
rectifySizes(); |
|
reconstructCurrentSize(); |
|
if ( !isNearlyEqual(oldPage)) |
|
emit(sizeChanged(*this)); |
|
} |
|
|
|
|
|
void pageSize::setPageSize(const QString& width, const QString& _widthUnits, const QString& height, const QString& _heightUnits) |
|
{ |
|
SimplePageSize oldPage = *this; |
|
|
|
double w = width.toFloat(); |
|
double h = height.toFloat(); |
|
|
|
QString widthUnits = _widthUnits; |
|
if ((widthUnits != QLatin1String("cm")) && (widthUnits != QLatin1String("mm")) && (widthUnits != QLatin1String("in"))) { |
|
qCCritical(OkularDviShellDebug) << "Unrecognized page width unit '" << widthUnits << "'. Assuming mm" << endl; |
|
widthUnits = QStringLiteral("mm"); |
|
} |
|
pageWidth.setLength_in_mm(w); |
|
if (widthUnits == QLatin1String("cm")) |
|
pageWidth.setLength_in_cm(w); |
|
if (widthUnits == QLatin1String("in")) |
|
pageWidth.setLength_in_inch(w); |
|
|
|
QString heightUnits = _heightUnits; |
|
if ((heightUnits != QLatin1String("cm")) && (heightUnits != QLatin1String("mm")) && (heightUnits != QLatin1String("in"))) { |
|
qCCritical(OkularDviShellDebug) << "Unrecognized page height unit '" << widthUnits << "'. Assuming mm" << endl; |
|
heightUnits = QStringLiteral("mm"); |
|
} |
|
pageHeight.setLength_in_mm(h); |
|
if (heightUnits == QLatin1String("cm")) |
|
pageHeight.setLength_in_cm(h); |
|
if (heightUnits == QLatin1String("in")) |
|
pageHeight.setLength_in_inch(h); |
|
|
|
rectifySizes(); |
|
reconstructCurrentSize(); |
|
if ( !isNearlyEqual(oldPage)) |
|
emit(sizeChanged(*this)); |
|
} |
|
|
|
|
|
pageSize &pageSize::operator= (const pageSize &src) |
|
{ |
|
SimplePageSize oldPage = *this; |
|
|
|
currentSize = src.currentSize; |
|
pageWidth = src.pageWidth; |
|
pageHeight = src.pageHeight; |
|
|
|
if ( !isNearlyEqual(oldPage)) |
|
emit(sizeChanged(*this)); |
|
return *this; |
|
} |
|
|
|
|
|
void pageSize::rectifySizes() |
|
{ |
|
// Now do some sanity checks to make sure that values are not |
|
// outrageous. We allow values between 5cm and 50cm. |
|
if (pageWidth.getLength_in_mm() < 50) |
|
pageWidth.setLength_in_mm(50.0); |
|
if (pageWidth.getLength_in_mm() > 1200) |
|
pageWidth.setLength_in_mm(1200); |
|
if (pageHeight.getLength_in_mm() < 50) |
|
pageHeight.setLength_in_mm(50); |
|
if (pageHeight.getLength_in_mm() > 1200) |
|
pageHeight.setLength_in_mm(1200); |
|
return; |
|
} |
|
|
|
|
|
QString pageSize::preferredUnit() const |
|
{ |
|
if (currentSize >= 0) |
|
return QString::fromLocal8Bit(staticList[currentSize].preferredUnit); |
|
|
|
// User-defined size. Give a preferred unit depending on the locale. |
|
if (QLocale::system().measurementSystem() == QLocale::MetricSystem) |
|
return QStringLiteral("mm"); |
|
else |
|
return QStringLiteral("in"); |
|
} |
|
|
|
|
|
QString pageSize::widthString(const QString& unit) const |
|
{ |
|
QString answer = QStringLiteral("--"); |
|
|
|
if (unit == QLatin1String("cm")) |
|
answer.setNum(pageWidth.getLength_in_cm()); |
|
if (unit == QLatin1String("mm")) |
|
answer.setNum(pageWidth.getLength_in_mm()); |
|
if (unit == QLatin1String("in")) |
|
answer.setNum(pageWidth.getLength_in_inch()); |
|
|
|
return answer; |
|
} |
|
|
|
|
|
QString pageSize::heightString(const QString& unit) const |
|
{ |
|
QString answer = QStringLiteral("--"); |
|
|
|
if (unit == QLatin1String("cm")) |
|
answer.setNum(pageHeight.getLength_in_cm()); |
|
if (unit == QLatin1String("mm")) |
|
answer.setNum(pageHeight.getLength_in_mm()); |
|
if (unit == QLatin1String("in")) |
|
answer.setNum(pageHeight.getLength_in_inch()); |
|
|
|
return answer; |
|
} |
|
|
|
|
|
QStringList pageSize::pageSizeNames() |
|
{ |
|
QStringList names; |
|
|
|
for(int i=0; staticList[i].name != nullptr; i++) |
|
names << QString::fromLocal8Bit(staticList[i].name); |
|
|
|
return names; |
|
} |
|
|
|
|
|
QString pageSize::formatName() const |
|
{ |
|
if (currentSize >= 0) |
|
return QString::fromLocal8Bit(staticList[currentSize].name); |
|
else |
|
return QString(); |
|
} |
|
|
|
|
|
int pageSize::getOrientation() const |
|
{ |
|
if (currentSize == -1) { |
|
qCCritical(OkularDviShellDebug) << "pageSize::getOrientation: getOrientation called for page format that does not have a name." << endl; |
|
return 0; |
|
} |
|
|
|
if (pageWidth.getLength_in_mm() == staticList[currentSize].width) |
|
return 0; |
|
else |
|
return 1; |
|
} |
|
|
|
|
|
void pageSize::setOrientation(int orient) |
|
{ |
|
if (currentSize == -1) { |
|
qCCritical(OkularDviShellDebug) << "pageSize::setOrientation: setOrientation called for page format that does not have a name." << endl; |
|
return; |
|
} |
|
|
|
if (orient == 1) { |
|
pageWidth.setLength_in_mm(staticList[currentSize].height); |
|
pageHeight.setLength_in_mm(staticList[currentSize].width); |
|
} else { |
|
pageWidth.setLength_in_mm(staticList[currentSize].width); |
|
pageHeight.setLength_in_mm(staticList[currentSize].height); |
|
} |
|
emit(sizeChanged(*this)); |
|
} |
|
|
|
|
|
QString pageSize::serialize() const |
|
{ |
|
if ((currentSize >= 0) && (fabs(staticList[currentSize].height-pageHeight.getLength_in_mm()) <= 0.5)) |
|
return QString::fromLocal8Bit(staticList[currentSize].name); |
|
else |
|
return QStringLiteral("%1x%2").arg(pageWidth.getLength_in_mm()).arg(pageHeight.getLength_in_mm()); |
|
} |
|
|
|
|
|
QString pageSize::description() const |
|
{ |
|
if (!isValid()) |
|
return QString(); |
|
|
|
QString size = QStringLiteral(" "); |
|
if (formatNumber() == -1) { |
|
if (QLocale::system().measurementSystem() == QLocale::MetricSystem) |
|
size += QStringLiteral("%1x%2 mm").arg(width().getLength_in_mm(), 0, 'f', 0).arg(height().getLength_in_mm(), 0, 'f', 0); |
|
else |
|
size += QStringLiteral("%1x%2 in").arg(width().getLength_in_inch(), 0, 'g', 2).arg(height().getLength_in_inch(), 0, 'g', 2); |
|
} else { |
|
size += formatName() + QLatin1Char('/'); |
|
if (getOrientation() == 0) |
|
size += i18n("portrait"); |
|
else |
|
size += i18n("landscape"); |
|
} |
|
return size + QLatin1Char(' '); |
|
} |
|
|
|
|
|
void pageSize::reconstructCurrentSize() |
|
{ |
|
for(int i=0; staticList[i].name != nullptr; i++) { |
|
if ((fabs(staticList[i].width - pageWidth.getLength_in_mm()) <= 2) && (fabs(staticList[i].height - pageHeight.getLength_in_mm()) <= 2)) { |
|
currentSize = i; |
|
pageWidth.setLength_in_mm(staticList[currentSize].width); |
|
pageHeight.setLength_in_mm(staticList[currentSize].height); |
|
return; |
|
} |
|
if ((fabs(staticList[i].height - pageWidth.getLength_in_mm()) <= 2) && (fabs(staticList[i].width - pageHeight.getLength_in_mm()) <= 2)) { |
|
currentSize = i; |
|
pageWidth.setLength_in_mm(staticList[currentSize].height); |
|
pageHeight.setLength_in_mm(staticList[currentSize].width); |
|
return; |
|
} |
|
} |
|
currentSize = -1; |
|
return; |
|
} |
|
|
|
int pageSize::defaultPageSize() |
|
{ |
|
// FIXME: static_cast<QPrinter::PageSize>(KLocale::global()->pageSize()) |
|
// is the proper solution here. Then you can determine the values |
|
// without using your hardcoded table too! |
|
if (QLocale::system().measurementSystem() == QLocale::MetricSystem) |
|
return defaultMetricPaperSize; |
|
else |
|
return defaultImperialPaperSize; |
|
} |
|
|
|
|
|
|