File indexing completed on 2024-04-14 14:36:04

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