The QuiteInsane-Plugin

© Michael Herder, crapsite@gmx.net
24.03.2002


Contents

  1. Introduction
  2. Requirements
  3. Installation
  4. Usage

Introduction

While the list of scanners supported by SANE (Scanner Access Now Easy) steadily grows, the number of applications, that provide scanner-access is still very small. In fact, scanning under Unix/Linux most of the time still means:
  1. Start one of the SANE-frontends to do your scans,
  2. and transfer the scanned images to your application in a more or less awkward way, like "Drag & Drop", "Copy & Paste" or "Save & Load".
Compared to "Winblows", where almost all applications provide an (really) easy access to scanners through the TWAIN interface, the situation under Unix/Linux is still rather inconsistent, with the exception of a few applications like The Gimp, Star Office and some KDE programs, that provide an interface to the SANE library already.
The intention behind the QuiteInsane-Plugin is to provide a SANE-frontend as a plugin, which can be easily integrated in Qt based applications. If you wonder, what "easy" means in this context, I can assure you, that it's not much more than copying a few lines of code and doing some small modifications. You have to know nothing about the SANE library and it's API.

Requirements

Of course you need a full installation of Qt-3.x, that means that all neccessary components to compile a Qt application have to be present (header files, qmake and so on). The runtime libraries are not sufficient. This means, that if you installed a Qt rpm, make sure that the Qt-devel rpm is also installed.
Also required is SANE version >=1.0.3. Again, if you are using rpms, make sure that SANE-devel is installed too.
Hint:
The SANE package is only required to build and use the QuiteInsane-Plugin. Your application will not depend on the SANE library after you've added support for the plugin. People will still be able to compile your application if they don't have SANE installed. It's also possible, to install SANE and the plugin after your program, without a need to recompile.

Installation

  1. Unpack the tarball, e.g.: tar -Zxvf quiteinsane_plugin-0.2.tar.gz
  2. Change the directory: cd quiteinsane_plugin-0.2
  3. Run configure: configure
    (This will simply run qmake quiteinsaneplugin.pro -o Makefile)
  4. Run make: make
  5. Install it: make install (as root)
The default installation path is /usr/local/lib for the plugin and /usr/local/bin for the test program. Hints:
It might be neccesary to adapt the .pro files, especially, if your using a Qt library that has been compiled with thread support. Please take a look at the .pro files in the sub-directories "quiteinsaneplugin" and "plugintest". I've added some comments there.

Usage

Hint:
Before you integrate support for the QuiteInsane-Plugin, you should take a look at the example "plugintest". The code that's needed to access the plugin is commented.

These are the steps that are required to add support for the QuiteInsane-Plugin to your application:

Step 1: Add two slots and two signals to your QWidget derived class

In order to make use of the QuiteInsane-Plugin you need a QWidget derived class; in most cases this will be a class derived from QMainWindow or similiar. You must use the following names for the signals/slots. The plugin uses them to check, whether your class supports the QuiteInsane-Plugin.

Signals



void signalQisScanImage(QString device_name,bool allow_multiple_scans)

The application emits this signal to inform the plugin, that a scan is requested. This will start a modal scan-dialog, which is used to adjust the scanner-options and to do preview scans. If device_name is invalid, the device-selection dialog is shown first. The parameter allow_multiple_scans informs the plugin, whether the application is able to handle multiple images at a time. If set to true, you can select up to 20 regions in the preview window, which are scanned in a single pass. If set to false, this feature is disabled.

void signalQisGetDeviceName()

The application emits this signal to inform the plugin, that the user wants to select a device. The modal device-selection dialog is shown.

Public slots



void slotQisNewDeviceName(QString device_name)

This slot is called by the plugin, after the user made a selection in the device-selection dialog. The application can then use device_name to request a scan by emitting signalQisScanImage(device_name,true/false). Please note, that device_name can be empty (i.e. device_name.isEmpty() returns true) e.g. if the user cancelled the device-selection dialog. An Application might store the device_name using QSettings and use it when the next scan is requested. This will preserve the user from going through the device-selection dialog every time he/she wants to scan an image.

void slotQisScanReady(QPtrList <QImage>&)

This slot is called by the plugin, after the user has finished the scan-dialog. The number of images in the QPtrList can be 0, if the user cancelled the scan-dialog. Otherwise it can contain one image, if signalQisScanImage(QString device_name,bool allow_multiple_scans) has been emitted with the parameter allow_multiple_scans set to false, or up to 20 images, if allow_multiple_scans has been true.
Please note, that auto-deletion is enabled for the QPtrList. That means, that clearing the list will also delete the images it contains. The application should save the images, and call QPtrList::clear() directly afterwards to free unneccessary memory.

Step 2: Load the library

Add the following typedef to your code, e.g. in the header file of your class:

typedef bool (*quiteInsaneProc)(QWidget*);

Load the library, e.g in the constructer of the class:

MainWindow::MainWindow(QWidget* parent,const char* name)
           :QMainWindow(parent,name)
{
  QSettings settings;
  bool plugin_ok = false;
  QLibrary* lib = new QLibrary("quiteinsane_plugin");
  //calling resolve will load the library
  quiteInsaneProc qisp = (quiteInsaneProc) lib->resolve( "init_libquiteinsane_plugin" );
  if(qisp)
  {
    //if this call returns true, the plugin has been successfully initialised
      qisp(this);
      plugin_ok = true;
  }
  else
  {
    delete lib;
  }

  //We assume, that "file" is a QPopupMenu
  //Disable the menu items, if plugin couldn't be loaded
  int id;
  id = file->insertItem(tr("&Setup scanner..."),this,
                        SLOT(slotSetupScanner()),0,1);
  if(!plugin_ok)
    file->setItemEnabled(id,false);
  id = file->insertItem(tr("Scan &image..."),this,
                        SLOT(slotScanImage()),0,2);
  if(!plugin_ok)
    file->setItemEnabled(id,false);
 ...
}


That's about all. Please have a look at the "plugintest" example which is included in the tarball. Also included is a patch that adds scanner-support to the "showimg" example, which is part of the Qt package.