KSaneCore

pagesizeoption.cpp
1/*
2 * SPDX-FileCopyrightText: 2009 Kare Sars <kare dot sars at iki dot fi>
3 * SPDX-FileCopyrightText: 2014 Gregor Mitsch : port to KDE5 frameworks
4 * SPDX-FileCopyrightText: 2021 Alexander Stippich <a.stippich@gmx.net>
5 *
6 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7 */
8
9#include "pagesizeoption.h"
10
11#include <QPageSize>
12#include <QSizeF>
13
14#include <ksanecore_debug.h>
15
16static constexpr int PageSizeWiggleRoom = 2; // in mm
17
18namespace KSaneCore
19{
20
21PageSizeOption::PageSizeOption(BaseOption *optionTopLeftX,
22 BaseOption *optionTopLeftY,
23 BaseOption *optionBottomRightX,
24 BaseOption *optionBottomRightY,
25 BaseOption *optionResolution,
26 BaseOption *optionPageWidth,
27 BaseOption *optionPageHeight)
28 : BaseOption()
29{
30 if (optionTopLeftX == nullptr || optionTopLeftY == nullptr || optionBottomRightX == nullptr || optionBottomRightY == nullptr) {
31 m_optionType = Option::TypeDetectFail;
32 return;
33 }
34
35 connect(optionTopLeftX, &BaseOption::valueChanged, this, &PageSizeOption::optionTopLeftXUpdated);
36 connect(optionTopLeftY, &BaseOption::valueChanged, this, &PageSizeOption::optionTopLeftYUpdated);
37 connect(optionBottomRightX, &BaseOption::valueChanged, this, &PageSizeOption::optionBottomRightXUpdated);
38 connect(optionBottomRightY, &BaseOption::valueChanged, this, &PageSizeOption::optionBottomRightYUpdated);
39
40 m_optionTopLeftX = optionTopLeftX;
41 m_optionTopLeftY = optionTopLeftY;
42 m_optionBottomRightX = optionBottomRightX;
43 m_optionBottomRightY = optionBottomRightY;
44 m_optionResolution = optionResolution;
45 m_optionPageWidth = optionPageWidth;
46 m_optionPageHeight = optionPageHeight;
47
48 /* some SANE backends set the maximum value of bottom right X and Y to the current page width and height values
49 * set current values of these option to maximum if available, such that we detect possible page sizes correctly
50 * see https://gitlab.com/sane-project/backends/-/issues/730 and https://bugs.kde.org/show_bug.cgi?id=476838 */
51 if (m_optionPageWidth != nullptr && m_optionPageHeight != nullptr) {
52 m_optionPageHeight->setValue(m_optionPageHeight->maximumValue());
53 m_optionPageWidth->setValue(m_optionPageWidth->maximumValue());
54 }
55
56 const QList<QPageSize::PageSizeId> possibleSizesList = {
78 };
79
81 m_availableSizesListNames << QPageSize::name(QPageSize::Custom);
82
83 double maxScannerWidth = ensureMilliMeter(m_optionBottomRightX, m_optionBottomRightX->maximumValue().toDouble());
84 double maxScannerHeight = ensureMilliMeter(m_optionBottomRightY, m_optionBottomRightY->maximumValue().toDouble());
85
86 // Add portrait page sizes
87 for (const auto sizeCode : possibleSizesList) {
89 if (size.width() - PageSizeWiggleRoom > maxScannerWidth) {
90 continue;
91 }
92 if (size.height() - PageSizeWiggleRoom > maxScannerHeight) {
93 continue;
94 }
95 m_availableSizesList << size;
96 m_availableSizesListNames << QPageSize::name(sizeCode);
97 }
98
99 // Add landscape page sizes
100 for (const auto sizeCode : possibleSizesList) {
102 size.transpose();
103 if (size.width() - PageSizeWiggleRoom > maxScannerWidth) {
104 continue;
105 }
106 if (size.height() - PageSizeWiggleRoom > maxScannerHeight) {
107 continue;
108 }
109 m_availableSizesList << size;
110 m_availableSizesListNames << i18nc("Page size landscape", "Landscape %1", QPageSize::name(sizeCode));
111 }
112
113 // Set custom as current
114 m_currentIndex = 0;
115 if (m_availableSizesList.count() > 1) {
116 m_state = Option::StateActive;
117 } else {
118 m_state = Option::StateHidden;
119 }
120 m_optionType = Option::TypeValueList;
121}
122
123bool PageSizeOption::setValue(const QVariant &value)
124{
125 if (value.userType() == QMetaType::QString) {
126 QString newValue = value.toString();
127 if (newValue == m_availableSizesListNames.at(m_currentIndex)) {
128 return true;
129 }
130 for (int i = 0; i < m_availableSizesListNames.size(); i++) {
131 QString sizeEntry = m_availableSizesListNames.at(i).toString();
132 if (sizeEntry == newValue) {
133 m_currentIndex = i;
134
135 if (i != 0) {
136 const auto size = m_availableSizesList.at(i);
137 if (m_optionPageWidth != nullptr && m_optionPageHeight != nullptr) {
138 m_optionPageWidth->setValue(size.width());
139 m_optionPageHeight->setValue(size.height());
140 }
141 m_optionTopLeftX->setValue(0);
142 m_optionTopLeftY->setValue(0);
143 m_optionBottomRightX->setValue(size.width());
144 m_optionBottomRightY->setValue(size.height());
145 }
146 Q_EMIT valueChanged(sizeEntry);
147 return true;
148 }
149 }
150 }
151 return false;
152}
153
154QVariant PageSizeOption::value() const
155{
156 if (m_currentIndex >= 0 && m_currentIndex < m_availableSizesListNames.size()) {
157 return m_availableSizesListNames.at(m_currentIndex);
158 } else {
159 return QVariant();
160 }
161}
162
163QString PageSizeOption::valueAsString() const
164{
165 if (m_currentIndex >= 0 && m_currentIndex < m_availableSizesListNames.size()) {
166 return m_availableSizesListNames.at(m_currentIndex).toString();
167 } else {
168 return QString();
169 }
170}
171
172QVariantList PageSizeOption::valueList() const
173{
174 return m_availableSizesListNames;
175}
176
177Option::OptionState PageSizeOption::state() const
178{
179 return m_state;
180}
181
182QString PageSizeOption::name() const
183{
184 return PageSizeOptionName;
185}
186
187QString PageSizeOption::title() const
188{
189 return i18n("Scan area size");
190}
191
192QString PageSizeOption::description() const
193{
194 return i18n("Select a predefined page size for the scanning area.");
195}
196
197void PageSizeOption::optionTopLeftXUpdated()
198{
199 if (m_currentIndex > 0 && m_currentIndex < m_availableSizesList.size() && m_optionTopLeftY->value().toDouble() != 0) {
200 m_currentIndex = 0;
201 Q_EMIT valueChanged(QPageSize::name(QPageSize::Custom));
202 }
203}
204
205void PageSizeOption::optionTopLeftYUpdated()
206{
207 if (m_currentIndex > 0 && m_currentIndex < m_availableSizesList.size() && m_optionTopLeftY->value().toDouble() != 0) {
208 m_currentIndex = 0;
209 Q_EMIT valueChanged(QPageSize::name(QPageSize::Custom));
210 }
211}
212
213void PageSizeOption::optionBottomRightXUpdated()
214{
215 if (m_currentIndex > 0 && m_currentIndex < m_availableSizesList.size()
216 && ensureMilliMeter(m_optionBottomRightX, m_optionBottomRightX->value().toDouble()) != m_availableSizesList.at(m_currentIndex).width()) {
217 m_currentIndex = 0;
218 Q_EMIT valueChanged(QPageSize::name(QPageSize::Custom));
219 }
220}
221
222void PageSizeOption::optionBottomRightYUpdated()
223{
224 if (m_currentIndex > 0 && m_currentIndex < m_availableSizesList.size()
225 && ensureMilliMeter(m_optionBottomRightY, m_optionBottomRightY->value().toDouble()) != m_availableSizesList.at(m_currentIndex).height()) {
226 m_currentIndex = 0;
227 Q_EMIT valueChanged(QPageSize::name(QPageSize::Custom));
228 }
229}
230
231double PageSizeOption::ensureMilliMeter(BaseOption *option, double value)
232{
233 // convert if necessary with current DPI if available
234 if (option->valueUnit() == Option::UnitPixel && m_optionResolution != nullptr) {
235 double dpi = m_optionResolution->value().toDouble();
236 if (dpi > 1) {
237 return value / (dpi / 25.4);
238 }
239 }
240 return value;
241}
242
243} // namespace KSaneCore
244
245#include "moc_pagesizeoption.cpp"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QString name() const const
QSizeF size(PageSizeId pageSizeId, Unit units)
qreal height() const const
void transpose()
qreal width() const const
const QChar at(qsizetype position) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QString toString() const const
int userType() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Dec 20 2024 11:57:02 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.