File indexing completed on 2024-12-01 07:26:16
0001 /* 0002 * SPDX-FileCopyrightText: 2009 Kare Sars <kare dot sars at iki dot fi> 0003 * SPDX-FileCopyrightText: 2014 Gregor Mitsch : port to KDE5 frameworks 0004 * SPDX-FileCopyrightText: 2021 Alexander Stippich <a.stippich@gmx.net> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "pagesizeoption.h" 0010 0011 #include <QPageSize> 0012 #include <QSizeF> 0013 0014 #include <ksanecore_debug.h> 0015 0016 static constexpr int PageSizeWiggleRoom = 2; // in mm 0017 0018 namespace KSaneCore 0019 { 0020 0021 PageSizeOption::PageSizeOption(BaseOption *optionTopLeftX, 0022 BaseOption *optionTopLeftY, 0023 BaseOption *optionBottomRightX, 0024 BaseOption *optionBottomRightY, 0025 BaseOption *optionResolution) 0026 : BaseOption() 0027 { 0028 if (optionTopLeftX == nullptr || optionTopLeftY == nullptr || optionBottomRightX == nullptr || optionBottomRightY == nullptr) { 0029 m_optionType = Option::TypeDetectFail; 0030 return; 0031 } 0032 0033 connect(optionTopLeftX, &BaseOption::valueChanged, this, &PageSizeOption::optionTopLeftXUpdated); 0034 connect(optionTopLeftY, &BaseOption::valueChanged, this, &PageSizeOption::optionTopLeftYUpdated); 0035 connect(optionBottomRightX, &BaseOption::valueChanged, this, &PageSizeOption::optionBottomRightXUpdated); 0036 connect(optionBottomRightY, &BaseOption::valueChanged, this, &PageSizeOption::optionBottomRightYUpdated); 0037 0038 m_optionTopLeftX = optionTopLeftX; 0039 m_optionTopLeftY = optionTopLeftY; 0040 m_optionBottomRightX = optionBottomRightX; 0041 m_optionBottomRightY = optionBottomRightY; 0042 m_optionResolution = optionResolution; 0043 0044 const QList<QPageSize::PageSizeId> possibleSizesList = { 0045 QPageSize::A3, 0046 QPageSize::A4, 0047 QPageSize::A5, 0048 QPageSize::A6, 0049 QPageSize::Letter, 0050 QPageSize::Legal, 0051 QPageSize::Tabloid, 0052 QPageSize::B3, 0053 QPageSize::B4, 0054 QPageSize::B5, 0055 QPageSize::B6, 0056 QPageSize::C5E, 0057 QPageSize::Comm10E, 0058 QPageSize::DLE, 0059 QPageSize::Executive, 0060 QPageSize::Folio, 0061 QPageSize::Ledger, 0062 QPageSize::JisB3, 0063 QPageSize::JisB4, 0064 QPageSize::JisB5, 0065 QPageSize::JisB6, 0066 }; 0067 0068 m_availableSizesList << QPageSize::size(QPageSize::Custom, QPageSize::Millimeter); 0069 m_availableSizesListNames << QPageSize::name(QPageSize::Custom); 0070 0071 double maxScannerWidth = ensureMilliMeter(m_optionBottomRightX, m_optionBottomRightX->maximumValue().toDouble()); 0072 double maxScannerHeight = ensureMilliMeter(m_optionBottomRightY, m_optionBottomRightY->maximumValue().toDouble()); 0073 0074 // Add portrait page sizes 0075 for (const auto sizeCode : possibleSizesList) { 0076 QSizeF size = QPageSize::size(sizeCode, QPageSize::Millimeter); 0077 if (size.width() - PageSizeWiggleRoom > maxScannerWidth) { 0078 continue; 0079 } 0080 if (size.height() - PageSizeWiggleRoom > maxScannerHeight) { 0081 continue; 0082 } 0083 m_availableSizesList << size; 0084 m_availableSizesListNames << QPageSize::name(sizeCode); 0085 } 0086 0087 // Add landscape page sizes 0088 for (const auto sizeCode : possibleSizesList) { 0089 QSizeF size = QPageSize::size(sizeCode, QPageSize::Millimeter); 0090 size.transpose(); 0091 if (size.width() - PageSizeWiggleRoom > maxScannerWidth) { 0092 continue; 0093 } 0094 if (size.height() - PageSizeWiggleRoom > maxScannerHeight) { 0095 continue; 0096 } 0097 m_availableSizesList << size; 0098 m_availableSizesListNames << i18nc("Page size landscape", "Landscape %1", QPageSize::name(sizeCode)); 0099 } 0100 0101 // Set custom as current 0102 m_currentIndex = 0; 0103 if (m_availableSizesList.count() > 1) { 0104 m_state = Option::StateActive; 0105 } else { 0106 m_state = Option::StateHidden; 0107 } 0108 m_optionType = Option::TypeValueList; 0109 } 0110 0111 bool PageSizeOption::setValue(const QVariant &value) 0112 { 0113 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0114 if (static_cast<QMetaType::Type>(value.type()) == QMetaType::QString) { 0115 #else 0116 if (value.userType() == QMetaType::QString) { 0117 #endif 0118 QString newValue = value.toString(); 0119 if (newValue == m_availableSizesListNames.at(m_currentIndex)) { 0120 return true; 0121 } 0122 for (int i = 0; i < m_availableSizesListNames.size(); i++) { 0123 QString sizeEntry = m_availableSizesListNames.at(i).toString(); 0124 if (sizeEntry == newValue) { 0125 m_currentIndex = i; 0126 0127 if (i != 0) { 0128 const auto size = m_availableSizesList.at(i); 0129 m_optionTopLeftX->setValue(0); 0130 m_optionTopLeftY->setValue(0); 0131 m_optionBottomRightX->setValue(size.width()); 0132 m_optionBottomRightY->setValue(size.height()); 0133 } 0134 Q_EMIT valueChanged(sizeEntry); 0135 return true; 0136 } 0137 } 0138 } 0139 return false; 0140 } 0141 0142 QVariant PageSizeOption::value() const 0143 { 0144 if (m_currentIndex >= 0 && m_currentIndex < m_availableSizesListNames.size()) { 0145 return m_availableSizesListNames.at(m_currentIndex); 0146 } else { 0147 return QVariant(); 0148 } 0149 } 0150 0151 QString PageSizeOption::valueAsString() const 0152 { 0153 if (m_currentIndex >= 0 && m_currentIndex < m_availableSizesListNames.size()) { 0154 return m_availableSizesListNames.at(m_currentIndex).toString(); 0155 } else { 0156 return QString(); 0157 } 0158 } 0159 0160 QVariantList PageSizeOption::valueList() const 0161 { 0162 return m_availableSizesListNames; 0163 } 0164 0165 Option::OptionState PageSizeOption::state() const 0166 { 0167 return m_state; 0168 } 0169 0170 QString PageSizeOption::name() const 0171 { 0172 return PageSizeOptionName; 0173 } 0174 0175 QString PageSizeOption::title() const 0176 { 0177 return i18n("Scan area size"); 0178 } 0179 0180 QString PageSizeOption::description() const 0181 { 0182 return i18n("Select a predefined page size for the scanning area."); 0183 } 0184 0185 void PageSizeOption::optionTopLeftXUpdated() 0186 { 0187 if (m_currentIndex > 0 && m_currentIndex < m_availableSizesList.size() && m_optionTopLeftY->value().toDouble() != 0) { 0188 m_currentIndex = 0; 0189 Q_EMIT valueChanged(QPageSize::name(QPageSize::Custom)); 0190 } 0191 } 0192 0193 void PageSizeOption::optionTopLeftYUpdated() 0194 { 0195 if (m_currentIndex > 0 && m_currentIndex < m_availableSizesList.size() && m_optionTopLeftY->value().toDouble() != 0) { 0196 m_currentIndex = 0; 0197 Q_EMIT valueChanged(QPageSize::name(QPageSize::Custom)); 0198 } 0199 } 0200 0201 void PageSizeOption::optionBottomRightXUpdated() 0202 { 0203 if (m_currentIndex > 0 && m_currentIndex < m_availableSizesList.size() 0204 && ensureMilliMeter(m_optionBottomRightX, m_optionBottomRightX->value().toDouble()) != m_availableSizesList.at(m_currentIndex).width()) { 0205 m_currentIndex = 0; 0206 Q_EMIT valueChanged(QPageSize::name(QPageSize::Custom)); 0207 } 0208 } 0209 0210 void PageSizeOption::optionBottomRightYUpdated() 0211 { 0212 if (m_currentIndex > 0 && m_currentIndex < m_availableSizesList.size() 0213 && ensureMilliMeter(m_optionBottomRightY, m_optionBottomRightY->value().toDouble()) != m_availableSizesList.at(m_currentIndex).height()) { 0214 m_currentIndex = 0; 0215 Q_EMIT valueChanged(QPageSize::name(QPageSize::Custom)); 0216 } 0217 } 0218 0219 double PageSizeOption::ensureMilliMeter(BaseOption *option, double value) 0220 { 0221 // convert if necessary with current DPI if available 0222 if (option->valueUnit() == Option::UnitPixel && m_optionResolution != nullptr) { 0223 double dpi = m_optionResolution->value().toDouble(); 0224 if (dpi > 1) { 0225 return value / (dpi / 25.4); 0226 } 0227 } 0228 return value; 0229 } 0230 0231 } // namespace KSaneCore 0232 0233 #include "moc_pagesizeoption.cpp"