1 /* This file is part of the KDE Project -*- mode:c++; -*- 2 Copyright (C) 1999 Klaas Freitag <freitag@suse.de> 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Library General Public 6 License as published by the Free Software Foundation; either 7 version 2 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Library General Public License for more details. 13 14 You should have received a copy of the GNU Library General Public License 15 along with this library; see the file COPYING.LIB. If not, write to 16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Boston, MA 02110-1301, USA. 18 */ 19 20 #ifndef KSCANDEVICE_H 21 #define KSCANDEVICE_H 22 23 #include "kookascan_export.h" 24 25 #include <qobject.h> 26 #include <qbytearray.h> 27 #include <qimage.h> 28 #include <qlist.h> 29 #include <qhash.h> 30 #include <qmap.h> 31 32 #include <kconfigskeleton.h> 33 34 extern "C" { 35 #include <sane/sane.h> 36 } 37 38 class QWidget; 39 class QSocketNotifier; 40 41 class KConfigSkeletonItem; 42 43 class KScanOption; 44 class KScanOptSet; 45 class ImageMetaInfo; 46 47 /** 48 * @short Access and control a scanner. 49 * 50 * After constructing a @c KScanDevice, a scanner may be opened 51 * via @c openDevice() by specifying its SANE backend name. Having 52 * done so, the scanner options supported by the scanner may be set 53 * and read individually using a @c KScanOption. 54 * 55 * A scan or preview may be initiated, once the scan is finished the 56 * scanned image data is made available via a signal. 57 * 58 * The scan device may be closed (using @c closeDevice()) and opened 59 * again to change the scanner that is accessed. 60 * 61 * @author Klaas Freitag 62 * @author Jonathan Marten 63 **/ 64 65 class KOOKASCAN_EXPORT KScanDevice : public QObject 66 { 67 Q_OBJECT 68 69 public: 70 71 /** 72 * Scanning/control status. 73 **/ 74 enum Status { 75 Ok, 76 NoDevice, 77 ParamError, 78 OpenDevice, 79 ControlError, 80 ScanError, 81 EmptyPic, 82 NoMemory, 83 Reload, 84 Cancelled, 85 OptionNotActive, 86 NotSupported 87 }; 88 89 /** 90 * Construct a new scanner device object. 91 * 92 * @param parent The parent object 93 **/ 94 explicit KScanDevice(QObject *parent); 95 96 /** 97 * Destructor. 98 **/ 99 ~KScanDevice(); 100 101 /** 102 * Open a scanner device. 103 * 104 * @param backend SANE name of the backend to open 105 * @return The status of the operation 106 * 107 * @note This operation may prompt for SANE authentication if 108 * it is required. 109 **/ 110 KScanDevice::Status openDevice(const QByteArray &backend); 111 112 /** 113 * Close the scanner device and frees all related data. 114 * After doing so, a new scanner may be opened. 115 **/ 116 void closeDevice(); 117 118 /** 119 * Get the device name of the current scanner backend. 120 * It has the format, for example, "umax:/dev/sg1". 121 * 122 * @return The scanner backend name, or a null string if no scanner 123 * is currently open. 124 **/ scannerBackendName()125 const QByteArray &scannerBackendName() const { return (mScannerName); } 126 127 /** 128 * Get a readable name/description of the current scanner 129 * backend. It may read, for example, "Mustek SP1200 Flatbed scanner". 130 * 131 * @return The scanner description. If no scanner is currently open, 132 * the (I18N'ed) string "No scanner connected" is returned. 133 **/ 134 QString scannerDescription() const; 135 136 /** 137 * Check whether a scanner device is opened and connected: that is, 138 * whether the @c openDevice() returned @c KScanDevice::Ok). 139 **/ isScannerConnected()140 bool isScannerConnected() const 141 { 142 return (mScannerInitialised); 143 } 144 145 /** 146 * Get the SANE scanner handle of the current scanner. 147 * 148 * @return The scanner handle, or @c nullptr if no scanner is 149 * currently open. 150 **/ scannerHandle()151 SANE_Handle scannerHandle() const 152 { 153 return (mScannerHandle); 154 } 155 156 /** 157 * Acquires a preview from the current scanner device. 158 * When the scan is complete, a result image will be sent by 159 * @c sigNewPreview. 160 * 161 * @param forceGray If this is @c true, the preview is acquired 162 * in greyscale regardless of any other settings. 163 * @param dpi Resolution setting for the preview. If this is 0, 164 * a suitable low resolution is selected. 165 * @return The status of the operation 166 **/ 167 KScanDevice::Status acquirePreview(bool forceGray = false, int dpi = 0); 168 169 /** 170 * Acquires a scan from the current scanner device. 171 * When the scan is complete, a result image will be sent by 172 * @c sigNewImage. 173 * 174 * @param filename File name to load, for virtual scanner test mode. 175 * If this is a null or empty string, a real scan is performed. 176 * @return The status of the operation 177 **/ 178 KScanDevice::Status acquireScan(const QString &filename = QString()); 179 180 /** 181 * Get the standard file name for saving the preview image for the 182 * current scanner. 183 * 184 * @return Preview file name 185 * 186 * @note Saving the preview image this does not actually work unless a 187 * subdirectory called @c previews exists within the calling application's 188 * @c data resource directory. 189 * @see loadPreviewImage 190 * @see savePreviewImage 191 * @see KStandardDirs 192 **/ 193 const QString previewFile() const; 194 195 /** 196 * Load the last saved preview image for this device from the saved file. 197 * 198 * @return The preview image, or a null image if none could be loaded. 199 * 200 * @see previewFile 201 * @see savePreviewImage 202 **/ 203 QImage loadPreviewImage(); 204 205 /** 206 * Saves a preview image for this device to the standard save file. 207 * 208 * @param image Preview image which is to be saved 209 * @return @c true if the saving was successful 210 * 211 * @see previewFile 212 * @see loadPreviewImage 213 * @note For historical reasons, the image is saved in BMP format. 214 **/ 215 bool savePreviewImage(const QImage &image) const; 216 217 /** 218 * Get the names of all of the parameters supported by the 219 * current scanner device. 220 * 221 * @return A list of all known parameter names, in order of their SANE 222 * index. 223 * @see getCommonOptions 224 * @see getAdvancedOptions 225 **/ 226 QList<QByteArray> getAllOptions() const; 227 228 /** 229 * Get the common options of the device. An application will normally 230 * display these options in a convenient and easy to access way. 231 * 232 * @return A list of the names of the common options. 233 * @see getAllOptions 234 * @see getAdvancedOptions 235 **/ 236 QList<QByteArray> getCommonOptions() const; 237 238 /** 239 * Get the advanced options of the device. An application may hide 240 * these options away in a less obvious place. 241 * 242 * @return A list of the names of the advanced options. 243 * @see getAllOptions 244 * @see getCommonOptions 245 **/ 246 QList<QByteArray> getAdvancedOptions() const; 247 248 /** 249 * Retrieve the currently active parameters from the scanner. 250 * This includes all of those that have an associated GUI element, 251 * and also any others (e.g. the TL_X and 3 other scan area settings) 252 * that have been @c apply()'ed but do not have a GUI. 253 * 254 * @param optSet An option set which will receive the options 255 **/ 256 void getCurrentOptions(KScanOptSet *optSet) const; 257 258 /** 259 * Load a saved parameter set. All options that exist in the set 260 * and which the current scanner supports will be @c set() 261 * with the values from the @c KScanOptSet and @c apply()'ed. 262 * 263 * @param optSet An option set with the options to be loaded 264 **/ 265 void loadOptionSet(const KScanOptSet *optSet); 266 267 /** 268 * Check whether the current scanner device supports an option. 269 * 270 * @param name The name of a scanner parameter 271 * @return @c true if the option is known by this scanner 272 **/ 273 bool optionExists(const QByteArray &name) const; 274 275 /** 276 * Resolve a backend-specific option name into a generally known 277 * SANE option name. See the source code for those names supported. 278 * 279 * @param name The backend-specific parameter name 280 * @return The generally known SANE name, or the input @p name 281 * unchanged if it has no known alias. 282 **/ 283 QByteArray aliasName(const QByteArray &name) const; 284 285 /** 286 * Create a @c KScanOption and GUI widget suitable for the specified 287 * scanner parameter. 288 * 289 * @param name Name of the SANE parameter. 290 * @param parent Parent for widget. 291 * @return A @c KScanOption for the parameter, or @c nullptr if none 292 * could be created. 293 * 294 * @see KScanOption::createWidget 295 * @see KScanOption::widget 296 * @see getExistingGuiElement 297 **/ 298 KScanOption *getGuiElement(const QByteArray &name, QWidget *parent); 299 300 /** 301 * Find the @c KScanOption for an existing scanner parameter. 302 * 303 * @param name Name of the SANE parameter. 304 * @return The @c KScanOption for the parameter, or @c nullptr if the 305 * parameter does not exist or it has not been created yet. 306 **/ 307 KScanOption *getExistingGuiElement(const QByteArray &name) const; 308 309 /** 310 * Create or retrieve a @c KScanOption for the specified scanner 311 * parameter. 312 * 313 * @param name Name of the SANE parameter. 314 * @param create If the option does not yet exist, then create it if 315 * this is @c true (the default). If this is @c false, then do not 316 * create the option if it does not already exist but return nullptr 317 * instead. 318 * @return The existing or created option, or @c nullptr if @p create 319 * is @c false and the option does not currently exist. 320 * @note This is the only means for a calling library or application 321 * to create or obtain a @c KScanOption. 322 * @note The returned pointer is valid until the scanner device is 323 * closed or the @c KScanDevice object is destroyed. 324 **/ 325 KScanOption *getOption(const QByteArray &name, bool create = true); 326 327 /** 328 * Set the enabled/disabled state of the GUI widget for an option. 329 * 330 * @param name Name of the SANE parameter. 331 * @param state @c true to enable the widget, @c false to disable it. 332 * 333 * @note If the option is not software settable, it will be disabled 334 * regardless of the @p state parameter. 335 * @see KScanOption::isSoftwareSettable 336 **/ 337 void guiSetEnabled(const QByteArray &name, bool state); 338 339 /** 340 * Get the maximum scan area size. This can be used, for example, to 341 * set the size of a preview widget. 342 * 343 * @return The width and height of the scan area, in SANE units 344 * as returned by the backend. 345 * @note Currently it is assumed that these units are always 346 * millimetres, although according to the SANE documentation it is 347 * possible that the unit may be pixels instead. 348 **/ 349 QSize getMaxScanSize(); 350 351 /** 352 * Get the current scan image format and bit depth. 353 * 354 * @param format An integer to receive the format, this is a 355 * @c SANE_Frame value. 356 * @param depth An integer to receive the bit depth (the number of bits 357 * per sample). 358 **/ 359 void getCurrentFormat(int *format, int *depth); 360 361 /** 362 * Access a group in the global scanner configuration file. 363 * 364 * @param groupName The group name 365 * @return the group 366 */ 367 static KConfigGroup configGroup(const QString &groupName); 368 369 /** 370 * Get the global default value for a scanner configuration setting. 371 * 372 * @param item The settings template item 373 * @return The default value 374 **/ getDefault(const KConfigSkeletonItem * item)375 template <class T> static T getDefault(const KConfigSkeletonItem *item) 376 { 377 return (static_cast<const KConfigSkeletonGenericItem<T> *>(item)->value()); 378 } 379 380 /** 381 * Read a configuration setting for the current scanner 382 * from the global scanner configuration file. 383 * 384 * @param item The settings template item 385 * @return The configuration setting, or its default value if none is 386 * saved in the configuration. 387 * 388 * @see storeConfig 389 **/ getConfig(const KConfigSkeletonItem * item)390 template <class T> T getConfig(const KConfigSkeletonItem *item) const 391 { 392 const KConfigGroup grp = configGroup(mScannerName); 393 return (grp.readEntry(item->key(), getDefault<T>(item))); 394 } 395 396 /** 397 * Save a configuration setting for the current scanner 398 * to the global scanner configuration file. 399 * 400 * @param item The settings template item 401 * @param val Value to store 402 * 403 * @see getConfig 404 **/ storeConfig(const KConfigSkeletonItem * item,const T & val)405 template <class T> void storeConfig(const KConfigSkeletonItem *item, const T &val) 406 { 407 if (mScannerName.isNull()) return; 408 //kDebug() << "Storing config" << key << "in group" << mScannerName; 409 KConfigGroup grp = configGroup(mScannerName); 410 grp.writeEntry(item->key(), val); 411 grp.sync(); 412 } 413 414 /** 415 * Retrieve or prompt for a username/password to authenticate access 416 * to the scanner. If there is a saved username/password pair for 417 * the current scanner, these will be returned. Otherwise, 418 * the user is prompted to enter a username/password (via a 419 * @c KPasswordDialog) and the entries are saved in the global 420 * scanner configuration file. 421 * 422 * @param retuser String to receive the user name 423 * @param retpass String to receive the password 424 * @return @c true if a saved username/password was available or 425 * the user entered them, @c false if no saved username/password 426 * was available and the user cancelled the password dialogue. 427 * 428 * @note This will normally be called by @c KScanGlobal::authCallback() 429 * when a SANE operation requires authentication. 430 **/ 431 bool authenticate(QByteArray *retuser, QByteArray *retpass); 432 433 /** 434 * Get an error message for the last SANE operation, if it failed. 435 * 436 * @return the error message string 437 **/ 438 QString lastSaneErrorMessage() const; 439 440 /** 441 * Get an error message for the specified scan result status. 442 * 443 * @return the error message string 444 **/ 445 static QString statusMessage(KScanDevice::Status stat); 446 447 /** 448 * Find the SANE index of an option. 449 * 450 * @param name Name of the SANE parameter. 451 * @return Its option index, or 0 if the option is not known by the scanner. 452 **/ 453 int getOptionIndex(const QByteArray &name) const; 454 455 /** 456 * Update the scanner with the value of the specified option (using 457 * @c KScanOption::apply()), then reload and update the GUI widget 458 * of all of the other options if necessary. Their value or state 459 * may have changed due to the change in this option; if so, SANE 460 * will tell us to reload them. 461 * 462 * @param opt The option to @c apply(). If this is @c nullptr, this 463 * function is equivalent to @c reloadAllOptions(). 464 * 465 * @note Even if a reload is needed, the scanner option given as the 466 * @p opt parameter is not reloaded. This is ensures that no recursion 467 * happens while reloading the options. 468 * @see reloadAllOptions 469 **/ 470 void applyOption(KScanOption *opt); 471 472 /** 473 * Reload all of the scanner options and update their GUI widgets. 474 * 475 * @see applyOption 476 **/ 477 void reloadAllOptions(); 478 479 public slots: 480 /** 481 * Request the scan device to stop the scan currently in progress. 482 * The scan may continue until the current data block has been 483 * read and processed. 484 **/ 485 void slotStopScanning(); 486 487 signals: 488 /** 489 * Emitted to indicate that a scan is about to start. 490 * Depending on the scanner, there may be a delay (for example, 491 * while the lamp warms up) between this signal and the 492 * @c sigAcquireStart. 493 * 494 * @param info Image information, if it is currently available 495 * @see sigAcquireStart 496 * 497 * @note The @p info parameter may be nullptr, or it may not contain 498 * any useful format information. 499 **/ 500 void sigScanStart(const ImageMetaInfo *info); 501 502 /** 503 * Emitted to indicate that a scan is starting to acquire data. 504 * The first @c sigScanProgress will be emitted with progress value 0 505 * immediately after this signal. 506 * @see sigScanStart 507 **/ 508 void sigAcquireStart(); 509 510 /** 511 * Emitted to indicate the scanning progress. The first value sent 512 * is always 0 and the final value is always 100. If the scan results 513 * in multiple frames (for a 3-pass scanner) the sequence will 514 * repeat. 515 * 516 * @param progress The scan progress as a percentage 517 **/ 518 void sigScanProgress(int progress); 519 520 /** 521 * Emitted when a new scan image has been acquired. 522 * The receiver should take a deep copy of the image, as it will 523 * be destroyed after this signal has been delivered. 524 * 525 * @param img The acquired scan image 526 * @param info Additional information for the image 527 * @see sigNewPreview 528 **/ 529 void sigNewImage(const QImage *img, const ImageMetaInfo *info); 530 531 /** 532 * Emitted when a new preview image has been acquired. 533 * The receiver should take a deep copy of the image, as it will 534 * be destroyed after this signal has been delivered. 535 * 536 * @param img The acquired preview image 537 * @param info Additional information for the image 538 * @see sigNewImage 539 **/ 540 void sigNewPreview(const QImage *img, const ImageMetaInfo *info); 541 542 /** 543 * Emitted to indicate that a scan or preview has finished. 544 * This signal is always emitted, even if the scan failed with 545 * an error or was cancelled, and before the @c sigNewImage or 546 * the @c sigNewPreview. 547 * 548 * @param stat Status of the scan 549 **/ 550 void sigScanFinished(KScanDevice::Status stat); 551 552 /** 553 * Emitted when the device is about to be closed by @c closeDevice(). 554 * This gives any callers using this device a chance to give up any 555 * dependencies on it. While this signal is being emitted, the 556 * scanner device is still open and valid. 557 **/ 558 void sigCloseDevice(); 559 560 private slots: 561 void doProcessABlock(); 562 void slotScanFinished(KScanDevice::Status status); 563 564 private: 565 KScanDevice::Status findOptions(); 566 void showOptions(); 567 void loadOptionSetInternal(const KScanOptSet *optSet, bool prio); 568 void applyAllOptions(bool prio); 569 570 KScanDevice::Status createNewImage(const SANE_Parameters *p); 571 572 KScanDevice::Status acquireData(bool isPreview = false); 573 574 /** 575 * Clear any saved authentication for this scanner, to ensure that the 576 * user is prompted again next time. 577 **/ 578 void clearSavedAuth(); 579 580 /** 581 * Save the current option parameter set. 582 * Only active and GUI options are saved. 583 **/ 584 void saveStartupConfig(); 585 586 /** 587 * Scanning progress state. 588 **/ 589 enum ScanningState { // only used by KScanDevice 590 ScanIdle, 591 ScanStarting, 592 ScanInProgress, 593 ScanNextFrame, 594 ScanStopNow, 595 ScanStopAdfFinished 596 }; 597 598 typedef QHash<QByteArray, KScanOption *> OptionHash; 599 typedef QMap<int, QByteArray> IndexMap; 600 601 OptionHash mCreatedOptions; // option name -> KScanOption 602 IndexMap mKnownOptions; // SANE index -> option name 603 604 KScanOptSet *mSavedOptions; 605 606 QByteArray mScannerName; 607 bool mScannerInitialised; 608 SANE_Handle mScannerHandle; 609 610 KScanDevice::ScanningState mScanningState; 611 SANE_Status mSaneStatus; 612 613 SANE_Byte *mScanBuf; 614 QImage *mScanImage; 615 ImageMetaInfo *mImageInfo; 616 SANE_Parameters mSaneParameters; 617 long mBytesRead; 618 long mBlocksRead; 619 int mBytesUsed; 620 int mPixelX, mPixelY; 621 bool mScanningPreview; 622 QSocketNotifier *mSocketNotifier; 623 624 int mCurrScanResolutionX; 625 int mCurrScanResolutionY; 626 }; 627 628 #endif // KSCANDEVICE_H 629