File indexing completed on 2025-01-12 12:39:35
0001 /* This file is part of the KDE Project -*- mode:c++; -*- 0002 Copyright (C) 1999 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 KSCANDEVICE_H 0021 #define KSCANDEVICE_H 0022 0023 #include "kookascan_export.h" 0024 0025 #include <qobject.h> 0026 #include <qbytearray.h> 0027 #include <qimage.h> 0028 #include <qlist.h> 0029 #include <qhash.h> 0030 #include <qmap.h> 0031 0032 #include <kconfigskeleton.h> 0033 0034 #include "scanimage.h" 0035 0036 extern "C" { 0037 #include <sane/sane.h> 0038 } 0039 0040 class QWidget; 0041 class QSocketNotifier; 0042 0043 class KConfigSkeletonItem; 0044 0045 class KScanOption; 0046 class KScanOptSet; 0047 0048 /** 0049 * @short Access and control a scanner. 0050 * 0051 * After constructing a @c KScanDevice, a scanner may be opened 0052 * via @c openDevice() by specifying its SANE backend name. Having 0053 * done so, the scanner options supported by the scanner may be set 0054 * and read individually using a @c KScanOption. 0055 * 0056 * A scan or preview may be initiated, once the scan is finished the 0057 * scanned image data is made available via a signal. 0058 * 0059 * The scan device may be closed (using @c closeDevice()) and opened 0060 * again to change the scanner that is accessed. 0061 * 0062 * @author Klaas Freitag 0063 * @author Jonathan Marten 0064 **/ 0065 0066 class KOOKASCAN_EXPORT KScanDevice : public QObject 0067 { 0068 Q_OBJECT 0069 0070 public: 0071 0072 /** 0073 * Scanning/control status. 0074 **/ 0075 enum Status { 0076 Ok, 0077 NoDevice, 0078 ParamError, 0079 OpenDevice, 0080 ControlError, 0081 ScanError, 0082 EmptyPic, 0083 NoMemory, 0084 Reload, 0085 Cancelled, 0086 OptionNotActive, 0087 NotSupported 0088 }; 0089 0090 /** 0091 * Construct a new scanner device object. 0092 * 0093 * @param parent The parent object 0094 **/ 0095 explicit KScanDevice(QObject *parent); 0096 0097 /** 0098 * Destructor. 0099 **/ 0100 ~KScanDevice(); 0101 0102 /** 0103 * Open a scanner device. 0104 * 0105 * @param backend SANE name of the backend to open 0106 * @return The status of the operation 0107 * 0108 * @note This operation may prompt for SANE authentication if 0109 * it is required. 0110 **/ 0111 KScanDevice::Status openDevice(const QByteArray &backend); 0112 0113 /** 0114 * Close the scanner device and frees all related data. 0115 * After doing so, a new scanner may be opened. 0116 **/ 0117 void closeDevice(); 0118 0119 /** 0120 * Get the device name of the current scanner backend. 0121 * It has the format, for example, "umax:/dev/sg1". 0122 * 0123 * @return The scanner backend name, or a null string if no scanner 0124 * is currently open. 0125 **/ 0126 const QByteArray &scannerBackendName() const { return (mScannerName); } 0127 0128 /** 0129 * Get a readable name/description of the current scanner 0130 * backend. It may read, for example, "Mustek SP1200 Flatbed scanner". 0131 * 0132 * @return The scanner description. If no scanner is currently open, 0133 * the (I18N'ed) string "No scanner connected" is returned. 0134 **/ 0135 QString scannerDescription() const; 0136 0137 /** 0138 * Check whether a scanner device is opened and connected: that is, 0139 * whether the @c openDevice() returned @c KScanDevice::Ok). 0140 **/ 0141 bool isScannerConnected() const 0142 { 0143 return (mScannerInitialised); 0144 } 0145 0146 /** 0147 * Get the SANE scanner handle of the current scanner. 0148 * 0149 * @return The scanner handle, or @c nullptr if no scanner is 0150 * currently open. 0151 **/ 0152 SANE_Handle scannerHandle() const 0153 { 0154 return (mScannerHandle); 0155 } 0156 0157 /** 0158 * Acquires a preview from the current scanner device. 0159 * When the scan is complete, a result image will be sent by 0160 * @c sigNewPreview. 0161 * 0162 * @param forceGray If this is @c true, the preview is acquired 0163 * in greyscale regardless of any other settings. 0164 * @param dpi Resolution setting for the preview. If this is 0, 0165 * a suitable low resolution is selected. 0166 * @return The status of the operation 0167 **/ 0168 KScanDevice::Status acquirePreview(bool forceGray = false, int dpi = 0); 0169 0170 /** 0171 * Acquires a scan from the current scanner device. 0172 * When the scan is complete, a result image will be sent by 0173 * @c sigNewImage. 0174 * 0175 * @param filename File name to load, for virtual scanner test mode. 0176 * If this is a null or empty string, a real scan is performed. 0177 * @return The status of the operation 0178 **/ 0179 KScanDevice::Status acquireScan(const QString &filename = QString()); 0180 0181 /** 0182 * Load the last saved preview image for this device from the saved file. 0183 * 0184 * @return The preview image, or a null image if none could be loaded. 0185 * 0186 * @see previewFile 0187 * @see savePreviewImage 0188 **/ 0189 QImage loadPreviewImage() const; 0190 0191 /** 0192 * Saves a preview image for this device to the standard save file. 0193 * 0194 * @param image Preview image which is to be saved 0195 * @return @c true if the saving was successful 0196 * 0197 * @see previewFile 0198 * @see loadPreviewImage 0199 * @note For historical reasons, the image is saved in BMP format. 0200 **/ 0201 bool savePreviewImage(const QImage &image) const; 0202 0203 /** 0204 * Get the names of all of the parameters supported by the 0205 * current scanner device. 0206 * 0207 * @return A list of all known parameter names, in order of their SANE 0208 * index. 0209 * @see getCommonOptions 0210 * @see getAdvancedOptions 0211 **/ 0212 QList<QByteArray> getAllOptions() const; 0213 0214 /** 0215 * Get the common options of the device. An application will normally 0216 * display these options in a convenient and easy to access way. 0217 * 0218 * @return A list of the names of the common options. 0219 * @see getAllOptions 0220 * @see getAdvancedOptions 0221 **/ 0222 QList<QByteArray> getCommonOptions() const; 0223 0224 /** 0225 * Get the advanced options of the device. An application may hide 0226 * these options away in a less obvious place. 0227 * 0228 * @return A list of the names of the advanced options. 0229 * @see getAllOptions 0230 * @see getCommonOptions 0231 **/ 0232 QList<QByteArray> getAdvancedOptions() const; 0233 0234 /** 0235 * Retrieve the currently active parameters from the scanner. 0236 * This includes all of those that have an associated GUI element, 0237 * and also any others (e.g. the TL_X and 3 other scan area settings) 0238 * that have been @c apply()'ed but do not have a GUI. 0239 * 0240 * @param optSet An option set which will receive the options 0241 **/ 0242 void getCurrentOptions(KScanOptSet *optSet) const; 0243 0244 /** 0245 * Load a saved parameter set. All options that exist in the set 0246 * and which the current scanner supports will be @c set() 0247 * with the values from the @c KScanOptSet and @c apply()'ed. 0248 * 0249 * @param optSet An option set with the options to be loaded 0250 **/ 0251 void loadOptionSet(const KScanOptSet *optSet); 0252 0253 /** 0254 * Check whether the current scanner device supports an option. 0255 * 0256 * @param name The name of a scanner parameter 0257 * @return @c true if the option is known by this scanner 0258 **/ 0259 bool optionExists(const QByteArray &name) const; 0260 0261 /** 0262 * Resolve a backend-specific option name into a generally known 0263 * SANE option name. See the source code for those names supported. 0264 * 0265 * @param name The backend-specific parameter name 0266 * @return The generally known SANE name, or the input @p name 0267 * unchanged if it has no known alias. 0268 **/ 0269 QByteArray aliasName(const QByteArray &name) const; 0270 0271 /** 0272 * Create a @c KScanOption and GUI widget suitable for the specified 0273 * scanner parameter. 0274 * 0275 * @param name Name of the SANE parameter. 0276 * @param parent Parent for widget. 0277 * @return A @c KScanOption for the parameter, or @c nullptr if none 0278 * could be created. 0279 * 0280 * @see KScanOption::createWidget 0281 * @see KScanOption::widget 0282 * @see getExistingGuiElement 0283 **/ 0284 KScanOption *getGuiElement(const QByteArray &name, QWidget *parent); 0285 0286 /** 0287 * Find the @c KScanOption for an existing scanner parameter. 0288 * 0289 * @param name Name of the SANE parameter. 0290 * @return The @c KScanOption for the parameter, or @c nullptr if the 0291 * parameter does not exist or it has not been created yet. 0292 **/ 0293 KScanOption *getExistingGuiElement(const QByteArray &name) const; 0294 0295 /** 0296 * Create or retrieve a @c KScanOption for the specified scanner 0297 * parameter. 0298 * 0299 * @param name Name of the SANE parameter. 0300 * @param create If the option does not yet exist, then create it if 0301 * this is @c true (the default). If this is @c false, then do not 0302 * create the option if it does not already exist but return nullptr 0303 * instead. 0304 * @return The existing or created option, or @c nullptr if @p create 0305 * is @c false and the option does not currently exist. 0306 * @note This is the only means for a calling library or application 0307 * to create or obtain a @c KScanOption. 0308 * @note The returned pointer is valid until the scanner device is 0309 * closed or the @c KScanDevice object is destroyed. 0310 **/ 0311 KScanOption *getOption(const QByteArray &name, bool create = true); 0312 0313 /** 0314 * Set the enabled/disabled state of the GUI widget for an option. 0315 * 0316 * @param name Name of the SANE parameter. 0317 * @param state @c true to enable the widget, @c false to disable it. 0318 * 0319 * @note If the option is not software settable, it will be disabled 0320 * regardless of the @p state parameter. 0321 * @see KScanOption::isSoftwareSettable 0322 **/ 0323 void guiSetEnabled(const QByteArray &name, bool state); 0324 0325 /** 0326 * Get the maximum scan area size. This can be used, for example, to 0327 * set the size of a preview widget. 0328 * 0329 * @return The width and height of the scan area, in SANE units 0330 * as returned by the backend. 0331 * @note Currently it is assumed that these units are always 0332 * millimetres, although according to the SANE documentation it is 0333 * possible that the unit may be pixels instead. 0334 **/ 0335 QSize getMaxScanSize(); 0336 0337 /** 0338 * Get the current scan image format and bit depth. 0339 * 0340 * @param format An integer to receive the format, this is a 0341 * @c SANE_Frame value. 0342 * @param depth An integer to receive the bit depth (the number of bits 0343 * per sample). 0344 **/ 0345 void getCurrentFormat(int *format, int *depth); 0346 0347 /** 0348 * Access a group in the global scanner configuration file. 0349 * 0350 * @param groupName The group name 0351 * @return the group 0352 */ 0353 static KConfigGroup configGroup(const QString &groupName); 0354 0355 /** 0356 * Get the global default value for a scanner configuration setting. 0357 * 0358 * @param item The settings template item 0359 * @return The default value 0360 **/ 0361 template <class T> static T getDefault(const KConfigSkeletonItem *item) 0362 { 0363 return (static_cast<const KConfigSkeletonGenericItem<T> *>(item)->value()); 0364 } 0365 0366 /** 0367 * Read a configuration setting for the current scanner 0368 * from the global scanner configuration file. 0369 * 0370 * @param item The settings template item 0371 * @return The configuration setting, or its default value if none is 0372 * saved in the configuration. 0373 * 0374 * @see storeConfig 0375 **/ 0376 template <class T> T getConfig(const KConfigSkeletonItem *item) const 0377 { 0378 const KConfigGroup grp = configGroup(mScannerName); 0379 return (grp.readEntry(item->key(), getDefault<T>(item))); 0380 } 0381 0382 /** 0383 * Save a configuration setting for the current scanner 0384 * to the global scanner configuration file. 0385 * 0386 * @param item The settings template item 0387 * @param val Value to store 0388 * 0389 * @see getConfig 0390 **/ 0391 template <class T> void storeConfig(const KConfigSkeletonItem *item, const T &val) 0392 { 0393 if (mScannerName.isNull()) return; 0394 //kDebug() << "Storing config" << key << "in group" << mScannerName; 0395 KConfigGroup grp = configGroup(mScannerName); 0396 grp.writeEntry(item->key(), val); 0397 grp.sync(); 0398 } 0399 0400 /** 0401 * Retrieve or prompt for a username/password to authenticate access 0402 * to the scanner. If there is a saved username/password pair for 0403 * the current scanner, these will be returned. Otherwise, 0404 * the user is prompted to enter a username/password (via a 0405 * @c KPasswordDialog) and the entries are saved in the global 0406 * scanner configuration file. 0407 * 0408 * @param retuser String to receive the user name 0409 * @param retpass String to receive the password 0410 * @return @c true if a saved username/password was available or 0411 * the user entered them, @c false if no saved username/password 0412 * was available and the user cancelled the password dialogue. 0413 * 0414 * @note This will normally be called by @c KScanGlobal::authCallback() 0415 * when a SANE operation requires authentication. 0416 **/ 0417 bool authenticate(QByteArray *retuser, QByteArray *retpass); 0418 0419 /** 0420 * Get an error message for the last SANE operation, if it failed. 0421 * 0422 * @return the error message string 0423 **/ 0424 QString lastSaneErrorMessage() const; 0425 0426 /** 0427 * Get an error message for the specified scan result status. 0428 * 0429 * @return the error message string 0430 **/ 0431 static QString statusMessage(KScanDevice::Status stat); 0432 0433 /** 0434 * Find the SANE index of an option. 0435 * 0436 * @param name Name of the SANE parameter. 0437 * @return Its option index, or 0 if the option is not known by the scanner. 0438 **/ 0439 int getOptionIndex(const QByteArray &name) const; 0440 0441 /** 0442 * Update the scanner with the value of the specified option (using 0443 * @c KScanOption::apply()), then reload and update the GUI widget 0444 * of all of the other options if necessary. Their value or state 0445 * may have changed due to the change in this option; if so, SANE 0446 * will tell us to reload them. 0447 * 0448 * @param opt The option to @c apply(). If this is @c nullptr, this 0449 * function is equivalent to @c reloadAllOptions(). 0450 * 0451 * @note Even if a reload is needed, the scanner option given as the 0452 * @p opt parameter is not reloaded. This is ensures that no recursion 0453 * happens while reloading the options. 0454 * @see reloadAllOptions 0455 **/ 0456 void applyOption(KScanOption *opt); 0457 0458 /** 0459 * Reload all of the scanner options and update their GUI widgets. 0460 * 0461 * @see applyOption 0462 **/ 0463 void reloadAllOptions(); 0464 0465 /** 0466 * Set a format to be used for indicating the image type to the 0467 * application. The GUI control is only shown when using the SANE 0468 * "test" device, normally the image type is resolved from the SANE 0469 * parameters. 0470 * 0471 * @param type the image type 0472 * @see sigScanStart() 0473 **/ 0474 void setTestFormat(ScanImage::ImageType type) { mTestFormat = type; } 0475 0476 public slots: 0477 /** 0478 * Request the scan device to stop the scan currently in progress. 0479 * The scan may continue until the current data block has been 0480 * read and processed. 0481 **/ 0482 void slotStopScanning(); 0483 0484 signals: 0485 /** 0486 * Emitted to indicate that a scan is about to start. 0487 * Depending on the scanner, there may be a delay (for example, 0488 * while the lamp warms up) between this signal and the 0489 * @c sigAcquireStart. 0490 * 0491 * @param type Image type information, if a scan is being started 0492 * and the image information is is currently available. This will 0493 * be @c ScanImage::Preview if a preview is being started, and may 0494 * be @c ScanImage::None if not enough image information is available. 0495 * 0496 * @see sigAcquireStart 0497 **/ 0498 void sigScanStart(ScanImage::ImageType type); 0499 0500 /** 0501 * Emitted to indicate that a scan is starting to acquire data. 0502 * The first @c sigScanProgress will be emitted with progress value 0 0503 * immediately after this signal. 0504 * 0505 * @see sigScanStart 0506 **/ 0507 void sigAcquireStart(); 0508 0509 /** 0510 * Emitted to indicate the scanning progress. The first value sent 0511 * is always 0 and the final value is always 100. If the scan results 0512 * in multiple frames (for a 3-pass scanner) the sequence will 0513 * repeat. 0514 * 0515 * @param progress The scan progress as a percentage 0516 **/ 0517 void sigScanProgress(int progress); 0518 0519 /** 0520 * Emitted when a new scan image has been acquired. 0521 * 0522 * @param img The acquired scan image 0523 * 0524 * @see sigNewPreview 0525 **/ 0526 void sigNewImage(ScanImage::Ptr img); 0527 0528 /** 0529 * Emitted when a new preview image has been acquired. 0530 * 0531 * @param img The acquired preview image 0532 * @param info Additional information for the image 0533 * 0534 * @see sigNewImage 0535 **/ 0536 void sigNewPreview(ScanImage::Ptr img); 0537 0538 /** 0539 * Emitted to indicate that a scan or preview has finished. 0540 * This signal is always emitted, even if the scan failed with 0541 * an error or was cancelled, and after the @c sigNewImage or 0542 * the @c sigNewPreview. 0543 * 0544 * @param stat Status of the scan 0545 **/ 0546 void sigScanFinished(KScanDevice::Status stat); 0547 0548 /** 0549 * Emitted when the device is about to be closed by @c closeDevice(). 0550 * This gives any callers using this device a chance to give up any 0551 * dependencies on it. While this signal is being emitted, the 0552 * scanner device is still open and valid. 0553 **/ 0554 void sigCloseDevice(); 0555 0556 private slots: 0557 void doProcessABlock(); 0558 0559 private: 0560 /** 0561 * Get the standard file name for saving the preview image for the 0562 * current scanner. 0563 * 0564 * @return the preview file name 0565 * 0566 * @note Saving the preview image does not actually work unless a 0567 * subdirectory called @c previews exists within the calling 0568 * application's @c data resource directory. 0569 * 0570 * @see loadPreviewImage 0571 * @see savePreviewImage 0572 * @see KStandardDirs 0573 **/ 0574 const QString previewFile() const; 0575 0576 KScanDevice::Status findOptions(); 0577 void showOptions(); 0578 void loadOptionSetInternal(const KScanOptSet *optSet, bool prio); 0579 void applyAllOptions(bool prio); 0580 0581 KScanDevice::Status createNewImage(const SANE_Parameters *p); 0582 0583 KScanDevice::Status acquireData(bool isPreview); 0584 void scanFinished(KScanDevice::Status status); 0585 0586 /** 0587 * Clear any saved authentication for this scanner, to ensure that the 0588 * user is prompted again next time. 0589 **/ 0590 void clearSavedAuth(); 0591 0592 /** 0593 * Save the current option parameter set. 0594 * Only active and GUI options are saved. 0595 **/ 0596 void saveStartupConfig(); 0597 0598 /** 0599 * Scanning progress state. 0600 **/ 0601 enum ScanningState { // only used by KScanDevice 0602 ScanIdle, 0603 ScanStarting, 0604 ScanInProgress, 0605 ScanNextFrame, 0606 ScanStopNow, 0607 ScanStopAdfFinished 0608 }; 0609 0610 typedef QHash<QByteArray, KScanOption *> OptionHash; 0611 typedef QMap<int, QByteArray> IndexMap; 0612 0613 OptionHash mCreatedOptions; // option name -> KScanOption 0614 IndexMap mKnownOptions; // SANE index -> option name 0615 0616 QByteArray mScannerName; 0617 bool mScannerInitialised; 0618 SANE_Handle mScannerHandle; 0619 0620 KScanDevice::ScanningState mScanningState; 0621 SANE_Status mSaneStatus; 0622 0623 SANE_Byte *mScanBuf; 0624 SANE_Parameters mSaneParameters; 0625 long mBytesRead; 0626 long mBlocksRead; 0627 int mBytesUsed; 0628 int mPixelX, mPixelY; 0629 bool mScanningPreview; 0630 QSocketNotifier *mSocketNotifier; 0631 0632 int mCurrScanResolutionX; 0633 int mCurrScanResolutionY; 0634 0635 ScanImage::Ptr mScanImage; 0636 ScanImage::ImageType mTestFormat; 0637 }; 0638 0639 #endif // KSCANDEVICE_H