File indexing completed on 2025-01-19 12:59:19
0001 /* This file is part of the KDE Project -*- mode:c++; -*- 0002 Copyright (C) 2000 Klaas Freitag <freitag@suse.de> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #ifndef KSCANOPTION_H 0021 #define KSCANOPTION_H 0022 0023 #include "kookascan_export.h" 0024 0025 #include <qobject.h> 0026 #include <qbytearray.h> 0027 0028 #include "kscandevice.h" 0029 0030 extern "C" { 0031 #include <sane/sane.h> 0032 } 0033 0034 class QLabel; 0035 0036 class KGammaTable; 0037 class KScanControl; 0038 class KScanDevice; 0039 0040 /** 0041 * @short A single scanner parameter. 0042 * 0043 * A scanner may support any number of these parameters, some are 0044 * well-known and common to almost all scanners while others may be 0045 * model-specific. 0046 * 0047 * Most options have an associated GUI element (a @c KScanControl), precisely 0048 * which sort of control depending on the type and constraint of the 0049 * scanner parameter. 0050 * 0051 * Only one KScanOption for each scanner parameter may exist. All options 0052 * for a particular scanner are owned by a KScanDevice, and options may only 0053 * be created by KScanDevice::getOption(). This ensures that all accesses 0054 * to a scanner parameter are consistent. 0055 * 0056 * KScanOption implements an internal memory buffer as an intermediary between 0057 * the scanner and its caller. There are four basic operations implemented to 0058 * access and control the scanner parameters: 0059 * 0060 * - @c set - Copy data from a variable or structure of an appropriate type 0061 * into the internal memory buffer. 0062 * 0063 * - @c apply - Send the data from the internal memory buffer to the scanner. 0064 * 0065 * - @c reload - Fetch the scanner data into the internal memory buffer. 0066 * 0067 * - @c get - Read the data from the internal memory buffer into a variable 0068 * or structure of an appropriate type. 0069 * 0070 * @author Klaas Freitag 0071 * @author Jonathan Marten 0072 **/ 0073 0074 class KOOKASCAN_EXPORT KScanOption : public QObject 0075 { 0076 Q_OBJECT 0077 0078 public: 0079 /** 0080 * Check whether the option is valid: that is, the parameter is known 0081 * by the scanner. 0082 * 0083 * @return @c true if the option is valid 0084 **/ 0085 bool isValid() const 0086 { 0087 return (mDesc != nullptr); 0088 } 0089 0090 /** 0091 * Check whether the option is initialised: that is, if the initial 0092 * value of the parameter has been read from the scanner. 0093 * 0094 * @return @c true if the option has been initialised 0095 **/ 0096 bool isInitialised() const 0097 { 0098 return (!mBufferClean); 0099 } 0100 0101 /** 0102 * Check whether the option is a group, if so this is a title only 0103 * and many of the operations will not be available. 0104 * 0105 * @return @c true if the option is a group 0106 **/ 0107 bool isGroup() const 0108 { 0109 return (mIsGroup); 0110 } 0111 0112 /** 0113 * Check whether the option value can be read from the scanner 0114 * (SANE_CAP_SOFT_SELECT with some special exceptions). Some 0115 * options that cannot be read may still be able to be set, 0116 * use @c isSoftwareSettable() to check. 0117 * 0118 * @return @c true if the option is readable 0119 * @see isSoftwareSettable 0120 **/ 0121 bool isReadable() const 0122 { 0123 return (mIsReadable); 0124 } 0125 0126 /** 0127 * Check whether the option is auto settable (SANE_CAP_AUTOMATIC): 0128 * that is, if the scanner can choose a setting for the option 0129 * automatically. 0130 * 0131 * @return @c true if the option can be set automatically 0132 **/ 0133 bool isAutoSettable() const { return (mDesc!=nullptr && (mDesc->cap & SANE_CAP_AUTOMATIC)); } 0134 0135 /** 0136 * Check whether the option is a common option (not SANE_CAP_ADVANCED). 0137 * 0138 * @return @c true if the option is a common option, 0139 * @c false if it is an advanced option. 0140 **/ 0141 bool isCommonOption() const { return (mDesc!=nullptr && !(mDesc->cap & SANE_CAP_ADVANCED)); } 0142 0143 /** 0144 * Check whether the option should be set as a priority, before any 0145 * other non-priority options. This a workaround for some scanners 0146 * which may reset other options when this option is changed. 0147 **/ 0148 bool isPriorityOption() const { return (mIsPriority); } 0149 0150 /** 0151 * Check whether the option is currently active (SANE_OPTION_IS_ACTIVE). 0152 * This may change at runtime depending on the settings of other options. 0153 * 0154 * @return @c true if the option is currently active 0155 **/ 0156 bool isActive() const { return (mDesc!=nullptr && SANE_OPTION_IS_ACTIVE(mDesc->cap)); } 0157 0158 /** 0159 * Check whether the option is can be set by software 0160 * (SANE_OPTION_IS_SETTABLE). Some scanner options cannot be set, 0161 * use @c isReadable() to check if they can be read. 0162 * 0163 * @return @c true if the option can be set 0164 * @see isReadable 0165 **/ 0166 bool isSoftwareSettable() const { return (mDesc!=nullptr && SANE_OPTION_IS_SETTABLE(mDesc->cap)); } 0167 0168 /** 0169 * Check whether the option has an associated GUI element 0170 * (not all types of options do). 0171 * 0172 * @return @c true if the option has a GUI widget 0173 **/ 0174 bool isGuiElement() const 0175 { 0176 return (mControl != nullptr); 0177 } 0178 0179 /** 0180 * Check whether the option value has been sent to the scanner: 0181 * that is, whether @c apply() has been used. This is used by 0182 * @c KScanDevice to maintain its list of "dirty" options. 0183 * 0184 * @return @c true if the option has been applied 0185 * @see KScanDevice 0186 * @see setApplied 0187 **/ 0188 bool isApplied() const 0189 { 0190 return (mApplied); 0191 } 0192 0193 /** 0194 * Set or clear the "applied" flag. 0195 * 0196 * @param app New value for the flag 0197 * @see isApplied 0198 * @see apply 0199 **/ 0200 void setApplied(bool app = true) 0201 { 0202 mApplied = app; 0203 } 0204 0205 /** 0206 * Set the option value. 0207 * 0208 * @param val A new integer value 0209 * @return @c true if the value was set successfully 0210 **/ 0211 bool set(int val); 0212 0213 /** 0214 * Set the option value. 0215 * 0216 * @param val A new @c double floating point value 0217 * @return @c true if the value was set successfully 0218 **/ 0219 bool set(double val); 0220 0221 /** 0222 * Set the option value. 0223 * 0224 * @param val A new formatted string value 0225 * @return @c true if the value was set successfully 0226 **/ 0227 bool set(const QByteArray &val); 0228 0229 /** 0230 * Set the option value. 0231 * 0232 * @param val A new boolean value 0233 * @return @c true if the value was set successfully 0234 **/ 0235 bool set(bool val) 0236 { 0237 return (set(val ? SANE_TRUE : SANE_FALSE)); 0238 } 0239 0240 /** 0241 * Set the option value. 0242 * 0243 * @param gt A new gamma table 0244 * @return @c true if the value was set successfully 0245 **/ 0246 bool set(const KGammaTable *gt); 0247 0248 /** 0249 * Retrieve the option value. 0250 * 0251 * @param val An integer to receive the value read 0252 * @return @c true if the value was read successfully 0253 * 0254 * @note If the scanner parameter is an array, only the first value 0255 * is retrieved from it. If the scanner parameter is of SANE_TYPE_FIXED, 0256 * the floating point value is cast to an integer. 0257 **/ 0258 bool get(int *val) const; 0259 0260 /** 0261 * Retrieve the option value. 0262 * 0263 * @param gt A gamma table to receive the value read 0264 * @return @c true in all cases (unless the @p gt parameter is @c nullptr) 0265 **/ 0266 bool get(KGammaTable *gt) const; 0267 0268 /** 0269 * Retrieve the option value. 0270 * 0271 * @return The formatted string value, or @c "?" if the value could 0272 * not be read. 0273 **/ 0274 QByteArray get() const; 0275 0276 /** 0277 * Retrieve the range of possible numeric values. 0278 * 0279 * @param minp A @c double to receive the minimum value 0280 * @param maxp A @c double to receive the maximum value 0281 * @param quantp A @c double to receive the step, if it is not @c nullptr. 0282 * @return @c true if the option is a range type 0283 * 0284 * @note For an option with SANE_CONSTRAINT_WORD_LIST, the minimum 0285 * and maximum values are those found in the word list and the step 0286 * is the range divided by the number of possible values. This does 0287 * not imply that any intermediate values calculated from these are valid. 0288 **/ 0289 bool getRange(double *minp, double *maxp, double *quantp = nullptr) const; 0290 0291 /** 0292 * Send the data (previously set by @c set()) to the scanner, if this 0293 * is possible - if the option is initialised, software settable and 0294 * active. 0295 * 0296 * @return @c true if a reload of other parameters is required 0297 * (@c sane_control_option() returned SANE_INFO_RELOAD_OPTIONS). 0298 **/ 0299 bool apply(); 0300 0301 /** 0302 * Retrieve the current data from the scanner, so that it can be 0303 * accessed by @c get(). If the option has an associated GUI control, 0304 * the enabled/disabled state of that is set appropriately. 0305 **/ 0306 void reload(); 0307 0308 /** 0309 * Create a GUI widget for the scanner option, depending on its type. 0310 * 0311 * - Boolean options have a check box (a @c KScanCheckbox). 0312 * - Numeric ranges have a slider/spinbox combination (a @c KScanSlider), 0313 * except for the special case of a resolution option which generates 0314 * a combo box (@c KScanCombo) - this is done for user convenience. 0315 * - String and numeric lists generate a combo box (@c KScanCombo). 0316 * - Unconstrained string and numeric options generate an entry box 0317 * (@c KScanStringEntry or @c KScanNumberEntry respectively). 0318 * - An option which is a file name (present in the SANE "pnm" test device) 0319 * generates a file requester (@c KScanFileRequester). 0320 * - Group options generate a separator line (@c KScanGroup), although 0321 * obviously no interaction is allowed. 0322 * - Button options generate a clickable button (@c KScanPushButton). 0323 * 0324 * Ownership of the widget is retained by the @c KScanOption object, so it 0325 * should not be deleted by the caller. 0326 * 0327 * @param parent Parent for the created widget. 0328 * @return The created widget, or @c nullptr if it could not be created. 0329 **/ 0330 KScanControl *createWidget(QWidget *parent); 0331 0332 /** 0333 * Create a label widget for the scanner option. @c createWidget() must 0334 * have been used to create the control first. 0335 * 0336 * If the option is a common option (i.e. not advanced), then the label's 0337 * buddy will be set to the control. 0338 0339 * @param parent Parent widget for the created label. 0340 * @param alwaysBuddy If this is @c true, the label's buddy will always 0341 * be set even if this is an advanced option. 0342 * @return The created label widget. 0343 **/ 0344 QLabel *getLabel(QWidget *parent, bool alwaysBuddy = false) const; 0345 0346 /** 0347 * Create a label widget for the SANE unit of this option. 0348 * @c createWidget() must have been used to create the control first. 0349 * 0350 * @param parent Parent widget for the created label. 0351 * @return The created label widget, or @c nullptr if no unit is 0352 * applicable. 0353 **/ 0354 QLabel *getUnit(QWidget *parent) const; 0355 0356 /** 0357 * Get the name of the option. 0358 * 0359 * @return The name of the option 0360 **/ 0361 QByteArray getName() const { return (mName); } 0362 0363 /** 0364 * Get the SANE capabilities for the option. 0365 * 0366 * @return The capabilities, or 0 if the option is not valid 0367 **/ 0368 int getCapabilities() const { return (mDesc!=nullptr ? mDesc->cap : 0); } 0369 0370 /** 0371 * Get the GUI widget for the option, if applicable and one has been 0372 * created by @c createWidget()). 0373 * 0374 * @return The widget, or @c nullptr if there is none. 0375 **/ 0376 KScanControl *widget() const { return (mControl); } 0377 0378 /** 0379 * Update the GUI widget to reflect the current value of the option. 0380 **/ 0381 void redrawWidget(); 0382 0383 protected slots: 0384 /** 0385 * Called when the contents of the GUI widget has changed, if the 0386 * option has a GUI element (not all have). This slot is used for 0387 * options that have a @c KScanControl of type @c KScanControl::Text. 0388 * 0389 * @param t New string contents of the widget 0390 **/ 0391 void slotWidgetChange(const QString &t); 0392 0393 /** 0394 * Called when the contents of the GUI widget has changed, if the 0395 * option has a GUI element (not all have). This slot is used for 0396 * options that have a @c KScanControl of type @c KScanControl::Number. 0397 * 0398 * @param i New index or setting of the widget 0399 **/ 0400 void slotWidgetChange(int i); 0401 0402 /** 0403 * Called when a GUI widget is activated, if the option has a GUI 0404 * element (not all have). This slot is used for options that have 0405 * a @c KScanControl of type @c KScanControl::Button. 0406 **/ 0407 void slotWidgetChange(); 0408 0409 signals: 0410 /** 0411 * Emitted when the user changes the GUI setting of the option. 0412 * The new setting will have been @c set(), but not yet @c apply()'ed. 0413 * 0414 * @param so The @c KScanOption which has changed 0415 **/ 0416 void guiChange(KScanOption *so); 0417 0418 private: 0419 /** 0420 * Create a new object for the named option belonging to the 0421 * specified scanner device. After construction, if the option 0422 * is valid it will initially contain the current parameter value 0423 * retrieved from the scanner. 0424 * 0425 * @param name Name of the scanner option 0426 * @param scandev Scanner device 0427 * 0428 * @note This constructor is private. All @c KScanOption's are 0429 * created by @c KScanDevice; a new or existing @c KScanOption can 0430 * be obtained via @c KScanDevice::getOption(). 0431 **/ 0432 KScanOption(const QByteArray &name, KScanDevice *scandev); 0433 friend KScanOption *KScanDevice::getOption(const QByteArray &, bool); 0434 0435 /** 0436 * Destructor. 0437 * 0438 * @note This destructor is private. All @c KScanOption's are 0439 * owned by @c KScanDevice, and are deleted when the scan device 0440 * is closed. 0441 **/ 0442 ~KScanOption(); 0443 friend void KScanDevice::closeDevice(); 0444 0445 /** 0446 * Set the option value. 0447 * 0448 * @param val A new array of integer or SANE_FIX()'ed values 0449 * @param size The length of the array 0450 * @return @c true if the value was set successfully 0451 **/ 0452 bool set(const int *val, int size); 0453 0454 /** 0455 * Retrieve a list of all possible option values. 0456 * 0457 * @return A list of formatted string values (as would be returned 0458 * by @c get()) 0459 * 0460 * @note This works for options with SANE_CONSTRAINT_STRING_LIST, 0461 * SANE_CONSTRAINT_WORD_LIST and for a SANE_CONSTRAINT_RANGE which is a 0462 * resolution setting. To retrieve the range for other constraint 0463 * types, use @c getRange(). 0464 **/ 0465 QList<QByteArray> getList() const; 0466 0467 /** 0468 * The type of an associated GUI widget (if there is one). 0469 **/ 0470 enum WidgetType 0471 { 0472 Invalid, 0473 Bool, 0474 SingleValue, 0475 Range, 0476 GammaTable, 0477 StringList, 0478 String, 0479 Resolution, 0480 File, 0481 Group, 0482 Button 0483 }; 0484 0485 bool initOption(const QByteArray &name); 0486 KScanOption::WidgetType resolveWidgetType() const; 0487 void allocForDesc(); 0488 void allocBuffer(long size); 0489 void updateList(); 0490 0491 KScanDevice *mScanDevice; 0492 int mIndex; 0493 const SANE_Option_Descriptor *mDesc; 0494 QByteArray mName; 0495 QString mText; 0496 0497 bool mIsGroup; 0498 bool mIsReadable; 0499 bool mIsPriority; 0500 0501 KScanControl *mControl; 0502 KScanOption::WidgetType mWidgetType; 0503 0504 QByteArray mBuffer; 0505 bool mBufferClean; 0506 bool mApplied; 0507 0508 KGammaTable *mGammaTable; 0509 }; 0510 0511 #endif // KSCANOPTION_H