Logo Search packages:      
Sourcecode: kdegraphics-kde4 version File versions  Download package

kscanoption.cpp

/* This file is part of the KDE Project
   Copyright (C) 2000 Klaas Freitag <freitag@suse.de>  

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include <stdlib.h>
#include <qwidget.h>
#include <qobject.h>
#include <q3asciidict.h>
#include <qcombobox.h>
#include <qslider.h>
#include <qcheckbox.h>
#include <qlineedit.h>
#include <qlabel.h>
#include <qlayout.h>

#include <qimage.h>
#include <qregexp.h>
//Added by qt3to4:
#include <Q3StrList>
#include <QByteArray>
#include <Q3MemArray>

#include <kdebug.h>

#include <unistd.h>
#include "kgammatable.h"
#include "kscandevice.h"
#include "kscanslider.h"
#include "kscanoptset.h"


// #define MIN_PREVIEW_DPI 20
// this is nowhere used!? Additionally, it's defined to 75 in kscandevice.cpp

/* switch to show some from time to time useful alloc-messages */
#undef MEM_DEBUG

#undef APPLY_IN_SITU



/** inline-access to the option descriptor, object to changes with global vars. **/
inline const SANE_Option_Descriptor *getOptionDesc( const QByteArray& name )
{
   int *idx = (*KScanDevice::option_dic)[ name ];
   
   const SANE_Option_Descriptor *d = 0;
   // debug( "<< for option %s >>", name );
   if ( idx && *idx > 0 )
   {
      d = sane_get_option_descriptor( KScanDevice::scanner_handle, *idx );
      // debug( "retrieving Option %s", d->name );
   }
   else
   {
      kDebug(29000) << "no option descriptor for <" << name << ">";
      // debug( "Name survived !" );
   }
   // debug( "<< leaving option %s >>", name );

   return( d );
}



/* ************************************************************************ */
/* KScan Option                                                             */
/* ************************************************************************ */
00084 KScanOption::KScanOption( const QByteArray& new_name ) :
   QObject()
{
   if( initOption( new_name ) )
   {
      int  *num = (*KScanDevice::option_dic)[ getName() ];  
      if( !num || !buffer )
       return;

      SANE_Status sane_stat = sane_control_option( KScanDevice::scanner_handle, *num,
                                       SANE_ACTION_GET_VALUE,
                                       buffer, 0 );

      if( sane_stat == SANE_STATUS_GOOD )
      {
       buffer_untouched = false;
      }
   }
   else
   {
      kDebug(29000) << "Had problems to create KScanOption - initOption failed !";
   }
}


bool KScanOption::initOption( const QByteArray& new_name )
{
   desc = 0;
   if( new_name.isEmpty() ) return( false );

   name = new_name;
   desc = getOptionDesc( name );
   buffer = 0;
   internal_widget = 0;
   buffer_untouched = true;
   buffer_size = 0;

   if( desc )
   {
            
      /* Gamma-Table - initial values */
      gamma = 0; /* marks as unvalid */   
      brightness = 0;
      contrast = 0;
      gamma = 100;
      
      // allocate memory
      switch( desc->type )
      {
          case SANE_TYPE_INT:
          case SANE_TYPE_FIXED:
          case SANE_TYPE_STRING:          
            buffer = allocBuffer( desc->size );
          break;
          case SANE_TYPE_BOOL:
            buffer = allocBuffer( sizeof( SANE_Word ) );
          break;
            default:
            buffer_size = 0;
              buffer = 0;
      }

      KScanOption *gtOption = (*KScanDevice::gammaTables)[ new_name ];
      if( gtOption )
      {
         kDebug(29000) << "Is older GammaTable!";
         KGammaTable gt;
         gtOption->get( &gt );
      
         gamma = gt.getGamma();
         contrast = gt.getContrast();
         brightness = gt.getBrightness();
      }
      else
      {
         // kDebug(29000) << "Is NOT older GammaTable!";
      }
    }

   return desc;
}

00166 KScanOption::KScanOption( const KScanOption &so ) :
   QObject()
{
   /* desc is stored by sane-lib and may be copied */
   desc = so.desc;
   name = so.name;
   buffer_untouched = so.buffer_untouched;
   gamma = so.gamma;
   brightness = so.brightness;
   contrast = so.contrast;

   /* intialise */
   buffer = 0;
   buffer_size = 0;

   /* the widget is not copied ! */
   internal_widget = 0;
   
   if( ! ( desc && !name.isEmpty() ) )
   {
      kWarning( 29000) << "Trying to copy a not healthy option (no name nor desc)" ;
      return;
   }
   
   if( so.buffer_untouched )
      kDebug(29000) << "Buffer of source is untouched!";

   switch( desc->type )
   {
       case SANE_TYPE_INT:
       case SANE_TYPE_FIXED:
       case SANE_TYPE_STRING:             
          buffer = allocBuffer( desc->size );
          // desc->size / sizeof( SANE_Word )
          memcpy( buffer, so.buffer, buffer_size  );
       break;
       case SANE_TYPE_BOOL:
          buffer = allocBuffer( sizeof( SANE_Word ) );
          memcpy( buffer, so.buffer,  buffer_size );
       break;
       default:
        kWarning( 29000 ) << "unknown option type in copy constructor" ;
        break;
    }
}


const QString KScanOption::configLine( void )
{
   QByteArray strval = this->get();
   kDebug(29000) << "configLine returns <" << strval << ">";
   return( strval );
}


const KScanOption& KScanOption::operator= (const KScanOption& so )
{
   /* desc is stored by sane-lib and may be copied */
   if( this == &so ) return( *this );

   desc = so.desc;
   name = so.name;
   buffer_untouched = so.buffer_untouched;
   gamma = so.gamma;
   brightness = so.brightness;
   contrast = so.contrast;

   delete internal_widget;
   internal_widget = so.internal_widget;

   if( buffer ) {
      delete [] buffer;
      buffer = 0;
   }

   switch( desc->type )
   {
       case SANE_TYPE_INT:
       case SANE_TYPE_FIXED:
       case SANE_TYPE_STRING:             
          buffer = allocBuffer( desc->size );
          memcpy( buffer, so.buffer, buffer_size );
       break;
       case SANE_TYPE_BOOL:
          buffer = allocBuffer( sizeof( SANE_Word ) );
          memcpy( buffer, so.buffer,  buffer_size );
       break;
       default:
            buffer = 0;
            buffer_size = 0;
    }
    return( *this );
}

void KScanOption::slWidgetChange( const QByteArray& t )
{
    kDebug(29000) << "Received WidgetChange for " << getName() << " (const QCString&)";
    set( t );
    emit( guiChange( this ) );
    // emit( optionChanged( this ));
}

00268 void KScanOption::slWidgetChange( void )
{
    kDebug(29000) << "Received WidgetChange for " << getName() << " (void)";
    /* If Type is bool, the widget is a checkbox. */
    if( type() == BOOL )
    {
      bool b = ((QCheckBox*) internal_widget)->isChecked();
      kDebug(29000) << "Setting bool: " << b;
      set( b );
    }
    emit( guiChange( this ) );
    // emit( optionChanged( this ));

}

void KScanOption::slWidgetChange( int i )
{
    kDebug(29000) << "Received WidgetChange for " << getName() << " (int)";
    set( i );
    emit( guiChange( this ) );
    // emit( optionChanged( this ));
}

/* this slot is called on a widget change, if a widget was created.
 * In normal case, it is internally connected, so the param so and
 * this are equal !
 */
void KScanOption::slRedrawWidget( KScanOption *so )
{
  // qDebug( "Checking widget %s", (const char*) so->getName());
  int     help = 0;
  QString string;
      
  QWidget *w = so->widget();
      
  if( so->valid() && w && so->getBuffer() )
    {
      switch( so->type( ) )
      {
      case BOOL:
        if( so->get( &help ))
          ((QCheckBox*) w)->setChecked( (bool) help );
        /* Widget Type is ToggleButton */
        break;
      case SINGLE_VAL:
                        /* Widget Type is Entry-Field - not implemented yet */
                        
        break;
      case RANGE:
                        /* Widget Type is Slider */
        if( so->get( &help ))
          ((KScanSlider*)w)->slSetSlider( help );
                                                
        break;
      case GAMMA_TABLE:
                        /* Widget Type is GammaTable */
        // w = new QSlider( parent, "AUTO_GAMMA" );
        break;
      case STR_LIST:                
        // w = comboBox( parent, text );
        ((KScanCombo*)w)->slSetEntry( so->get() );                
                        /* Widget Type is Selection Box */
        break;
      case STRING:
        // w = entryField( parent, text );
        ((KScanEntry*)w)->slSetEntry( so->get() );                
                        /* Widget Type is Selection Box */
        break;
      default:
                        // w  = 0;
        break;
      }
    }
}

/* In this slot, the option queries the scanner for current values. */

00345 void KScanOption::slReload( void )
{
   int  *num = (*KScanDevice::option_dic)[ getName() ];     
   desc = getOptionDesc( getName() );     
      
   if( !desc || !num  )
      return;
            
   if( widget() )
   {
      kDebug(29000) << "constraint is " << desc->cap;
      if( !active() )
       kDebug(29000) << desc->name << " is not active now";

      if( !softwareSetable() )
       kDebug(29000) << desc->name << " is not software setable";

      if( !active() || !softwareSetable() )
      {
       kDebug(29000) << "Disabling widget " << getName() << " !";
       widget()->setEnabled( false );
      }
      else
       widget()->setEnabled( true );
   }
      
   /* first get mem if nothing is approbiate */
   if( !buffer )
   {
      kDebug(29000) << " *********** getting without space **********";
      // allocate memory
      switch( desc->type )
      {
       case SANE_TYPE_INT:
       case SANE_TYPE_FIXED:
       case SANE_TYPE_STRING:             
          buffer = allocBuffer( desc->size );
          break;
       case SANE_TYPE_BOOL:
          buffer = allocBuffer( sizeof( SANE_Word ) );
          break;
       default:
          if( desc->size > 0 )
          {
             buffer = allocBuffer( desc->size );
          }
      }
   }

   if( active())
   {
      if( (size_t) desc->size > buffer_size )
      {
       kDebug(29000) << "ERROR: Buffer to small";
      }
      else
      {
       SANE_Status sane_stat = sane_control_option( KScanDevice::scanner_handle, *num,
                                          SANE_ACTION_GET_VALUE, buffer, 0 );

       if( sane_stat != SANE_STATUS_GOOD )
       {
          kDebug(29000) << "ERROR: Cant get value for " << getName() << ": " << sane_strstatus( sane_stat );
       } else {
          buffer_untouched = false;
          kDebug(29000) << "Setting buffer untouched to FALSE";
       }
      }
   }
}


KScanOption::~KScanOption()
{
#ifdef MEM_DEBUG
   qDebug( "M: FREEing %d byte of option <%s>", buffer_size, (const char*) getName());
#endif
}

00424 bool KScanOption::valid( void ) const
{
  return( desc && 1 );
}

00429 bool KScanOption::autoSetable( void )
{
  /* Refresh description */
  desc = getOptionDesc( name );

  return( desc && ((desc->cap & SANE_CAP_AUTOMATIC) > 0 ) );
}

00437 bool KScanOption::commonOption( void )
{
  /* Refresh description */
  desc = getOptionDesc( name );

  return( desc && ((desc->cap & SANE_CAP_ADVANCED) == 0) );
}


00446 bool KScanOption::active( void )
{
  bool ret = false;
  /* Refresh description */
  desc = getOptionDesc( name );
  if( desc )
    ret = SANE_OPTION_IS_ACTIVE( desc->cap );
                  
  return( ret );
}

00457 bool KScanOption::softwareSetable( void )
{
  /* Refresh description */
  desc = getOptionDesc( name );
  if( desc )
  {
     if( SANE_OPTION_IS_SETTABLE(desc->cap) == SANE_TRUE )
      return( true );
  }
  return( false );
}


00470 KSANE_Type KScanOption::type( void ) const
{
   KSANE_Type ret = INVALID_TYPE;
      
   if( valid() )
   {
      switch( desc->type )
      {     
       case SANE_TYPE_BOOL:
          ret = BOOL;
          break;
       case SANE_TYPE_INT:
       case SANE_TYPE_FIXED:
          if( desc->constraint_type == SANE_CONSTRAINT_RANGE )
          {
             /* FIXME ! Dies scheint nicht wirklich so zu sein */
             if( desc->size == sizeof( SANE_Word ))
              ret = RANGE;
             else
              ret = GAMMA_TABLE;
          }
          else if( desc->constraint_type == SANE_CONSTRAINT_NONE )
          {
             ret = SINGLE_VAL;
          }
          else if( desc->constraint_type == SANE_CONSTRAINT_WORD_LIST )
          {
            ret = STR_LIST;
            // ret = GAMMA_TABLE;
          }
          else
          {
             ret = INVALID_TYPE;
          }
          break;
       case SANE_TYPE_STRING:
          if( desc->constraint_type == SANE_CONSTRAINT_STRING_LIST )
             ret = STR_LIST;
          else
             ret = STRING;
          break;
       default:
          ret = INVALID_TYPE;
          break;
      }
   }
   return( ret );       
}


00520 bool KScanOption::set( int val )
{
   if( ! desc ) return( false );
   bool ret = false;

   int word_size       = 0;
   Q3MemArray<SANE_Word> qa;
   SANE_Word sw        = SANE_TRUE;
   const SANE_Word sw1 = val;
   const SANE_Word sw2 = SANE_FIX( (double) val );

   switch( desc->type )
   {
      case SANE_TYPE_BOOL:
      
       if( ! val )
          sw = SANE_FALSE;
       if( buffer ) {
          memcpy( buffer, &sw, sizeof( SANE_Word ));
          ret = true;
       }
       break;
       // Type int: Fill the whole buffer with that value
      case SANE_TYPE_INT:
       word_size = desc->size / sizeof( SANE_Word );

       qa.resize( word_size );
       qa.fill( sw1 );
      
       if( buffer ) {
          memcpy( buffer, qa.data(), desc->size );
          ret = true;
       }
       break;

       // Type fixed: Fill the whole buffer with that value
      case SANE_TYPE_FIXED:
       word_size = desc->size / sizeof( SANE_Word );

       qa.resize( word_size );
       qa.fill( sw2 );
      
       if( buffer ) {
          memcpy( buffer, qa.data(), desc->size );
          ret = true;
       }
       break;
       default:
       kDebug(29000) << "Cant set " << name << "  with type int";
   }
   if( ret )
   {
      buffer_untouched = false;
#ifdef APPLY_IN_SITU
      applyVal();
#endif

#if 0
      emit( optionChanged( this ));
#endif
   }

   return( ret );
}



bool KScanOption::set( double val )
{
   if( ! desc ) return( false );
   bool ret = false;
   int  word_size = 0;
   Q3MemArray<SANE_Word> qa;
   SANE_Word sw = SANE_FALSE;

   switch( desc->type )
   {
      case SANE_TYPE_BOOL:
      
       if( val > 0 )
          sw = SANE_TRUE;
       if( buffer ) {
          memcpy( buffer, &sw, sizeof( SANE_Word ));
          ret = true;
       }
       break;
       // Type int: Fill the whole buffer with that value
      case SANE_TYPE_INT:
       sw = (SANE_Word) val;
       word_size = desc->size / sizeof( SANE_Word );

       qa.resize( word_size );
       qa.fill( sw );
      
       if( buffer ) {
          memcpy( buffer, qa.data(), desc->size );
          ret = true;
       }
       break;

       // Type fixed: Fill the whole buffer with that value
      case SANE_TYPE_FIXED:
       sw = SANE_FIX( val );
       word_size = desc->size / sizeof( SANE_Word );

       qa.resize( word_size );
       qa.fill( sw );
      
       if( buffer ) {
          memcpy( buffer, qa.data(), desc->size );
          ret = true;
       }
       break;
      default:
       kDebug(29000) << "Cant set " << name << " with type double";
   }

   if( ret )
   {
      buffer_untouched = false;
#ifdef APPLY_IN_SITU
      applyVal();
#endif
#if 0
      emit( optionChanged( this ));
#endif
   }

   return( ret );
}



bool KScanOption::set( int *val, int size )
{
    if( ! desc || ! val ) return( false );
    bool   ret    = false;

    int word_size = desc->size / sizeof( SANE_Word ); /* add 1 in case offset is needed */
    Q3MemArray<SANE_Word> qa( 1+word_size );
    int    offset = 0;
#if 0
    if( desc->constraint_type == SANE_CONSTRAINT_WORD_LIST )
    {
      /* That means that the first entry must contain the size */
      kDebug(29000) << "Size: " << size << ", word_size: " << word_size << ", descr-size: "<< desc->size;
      qa[0] = (SANE_Word) 1+size;
      kDebug(29000) << "set length field to " << qa[0];
      offset = 1;
    }
#endif

    switch( desc->type )
    {
      case SANE_TYPE_INT:
          for( int i = 0; i < word_size; i++ )
          {
            if( i < size )
                qa[offset+i] = (SANE_Word) *(val++);
            else
                qa[offset+i] = (SANE_Word) *val;
          }
          ret = true;
          break;

          // Type fixed: Fill the whole buffer with that value
      case SANE_TYPE_FIXED:
          for( int i = 0; i < word_size; i++ )
          {
            if( i < size )
                qa[offset+i] = SANE_FIX((double)*(val++));
            else
                qa[offset+i] = SANE_FIX((double) *val );
          }
          ret = true;
          break;
      default:
          kDebug(29000) << "Cant set " << name << " with type int*";
      
    }

    if( ret && buffer ) {
      int copybyte = desc->size;
      
#if 0
      if( offset )
          copybyte += sizeof( SANE_Word );
#endif

      kDebug(29000) << "Copying " << copybyte << " byte to options buffer";
      
      memcpy( buffer, qa.data(), copybyte );
    }

    if( ret )
    {
      buffer_untouched = false;
#ifdef APPLY_IN_SITU
      applyVal();
#endif
#if 0
      emit( optionChanged( this ));
#endif
    }

    return( ret );
}

bool KScanOption::set( const QByteArray& c_string )
{
   bool ret = false;
   int  val = 0;
   
   if( ! desc ) return( false );

   /* Check if it is a gammatable. If it is, convert to KGammaTable and call
    *  the approbiate set method.
    */
   QRegExp re( "\\d+, \\d+, \\d+" );
   re.setMinimal(true);
   
   if( QString(c_string).contains( re ))
   {
      QStringList relist = QString(c_string).split( ", ", QString::SkipEmptyParts );
      
      int brig = (relist[0]).toInt();
      int contr = (relist[1]).toInt();
      int gamm = (relist[2]).toInt();

      KGammaTable gt( brig, contr, gamm );
      ret = set( &gt );
      kDebug(29000) << "Setting GammaTable with int vals " << brig << "|" << contr << "|" << gamm;
      
      return( ret );
   }

   
   /* On String-type the buffer gets malloced in Constructor */
   switch( desc->type )
   {
       case SANE_TYPE_STRING:
         kDebug(29000) << "Setting " << c_string << " as String";
      
         if( buffer_size >= c_string.length() )
         {
             memset( buffer, 0, buffer_size );
             qstrncpy( (char*) buffer, (const char*) c_string, buffer_size );
             ret = true;
         }
         else
         {
             kDebug(29000) << "ERROR: Buffer for String " << c_string << " too small: " << buffer_size << "  < " << c_string.length();
         }
         break;
       case SANE_TYPE_INT:
       case SANE_TYPE_FIXED:
         kDebug(29000) << "Type is INT or FIXED, try to set value <" << c_string << ">";
         val = c_string.toInt( &ret );
         if( ret ) 
             set( &val, 1 );
         else
             kDebug(29000) << "Conversion of string value failed!";
         
         break;
      case SANE_TYPE_BOOL:
       kDebug(29000) << "Type is BOOL, setting value <" << c_string << ">";
       val = 0;
       if( c_string == "true" ) val = 1;
       set( val );
       break;
       default:
         kDebug(29000) << "Type of " << name << " is " << desc->type;
         kDebug(29000) << "Cant set " << name << " with type string";
         break;
   }

   if( ret )
   {
      buffer_untouched = false;
#ifdef APPLY_IN_SITU
      applyVal();
#endif
#if 0
      emit( optionChanged( this ));
#endif
   }
   kDebug(29000) << "Returning " << ret;
   return( ret );
}


bool KScanOption::set( KGammaTable *gt )
{
   if( ! desc ) return( false );
   bool ret = true;
   int size = gt->tableSize();
   SANE_Word *run = gt->getTable();

   int word_size = desc->size / sizeof( SANE_Word );
   Q3MemArray<SANE_Word> qa( word_size );
   kDebug(29000) << "KScanOption::set for Gammatable !";
   switch( desc->type )
   {
      case SANE_TYPE_INT:
       for( int i = 0; i < word_size; i++ ){
          if( i < size )
             qa[i] = *run++;
          else
             qa[i] = *run;
       }
       break;

      // Type fixed: Fill the whole buffer with that value
      case SANE_TYPE_FIXED:
       for( int i = 0; i < word_size; i++ ){
          if( i < size )
             qa[i] = SANE_FIX((double)*(run++));
          else
             qa[i] = SANE_FIX((double) *run );
       }
       break;
      default:
       kDebug(29000) << "Cant set " << name << " with type GammaTable";
       ret = false;
      
   }

   if( ret && buffer )
   {
      /* remember raw vals */
      gamma      = gt->getGamma();
      brightness = gt->getBrightness();
      contrast   = gt->getContrast();

      memcpy( buffer, qa.data(), desc->size );
      buffer_untouched = false;
#ifdef APPLY_IN_SITU
      applyVal();
#endif
#if 0
      emit( optionChanged( this ));
#endif
   }

   return( ret );
}

00867 bool KScanOption::get( int *val ) const
{
  SANE_Word sane_word;
  double d;
  if( !valid() || !getBuffer())
    return( false );
                  
  switch( desc->type )
    {
    case SANE_TYPE_BOOL:
      /* Buffer has a SANE_Word */
      sane_word = *((SANE_Word*)buffer);
      if( sane_word == SANE_TRUE )
      *val = 1;
      else
      *val = 0;
      break;
      /* Type int: Fill the whole buffer with that value */
      /* reading the first is OK */
    case SANE_TYPE_INT:
      sane_word = *((SANE_Word*)buffer);
      *val = sane_word;
      break;

      // Type fixed: whole buffer filled with the same value
    case SANE_TYPE_FIXED:
      d = SANE_UNFIX(*(SANE_Word*)buffer);
      *val = (int)d;
      break;
    default:
      kDebug(29000) << "Cant get " << name << " to type int";
      return( false );
    }

  // qDebug( "option::get returns %d", *val );
  return( true );
}



QByteArray KScanOption::get( void ) const
{
   QByteArray retstr;

   SANE_Word sane_word;


   if( !valid() || !getBuffer())
      return( "parametererror" );
                  
   switch( desc->type )
   {
      case SANE_TYPE_BOOL:
       sane_word = *((SANE_Word*)buffer);
       if( sane_word == SANE_TRUE )
          retstr = "true";
       else 
          retstr = "false";
       break;
      case SANE_TYPE_STRING:
       retstr = (const char*) getBuffer();
       // retstr.sprintf( "%s", cc );
       break;
      case SANE_TYPE_INT:
       sane_word = *((SANE_Word*)buffer);
       retstr.setNum( sane_word );
       break;
      case SANE_TYPE_FIXED:
       sane_word = (SANE_Word) SANE_UNFIX(*(SANE_Word*)buffer);
       retstr.setNum( sane_word );
       break;
      
      default:
       kDebug(29000) << "Cant get " << getName() << " to type String !";
       retstr = "unknown";
   }

   /* Handle gamma-table correctly */
   ;
   if( type() == GAMMA_TABLE )
   {
      retstr= QByteArray::number(gamma) +", " + QByteArray::number(brightness) + ", "+ QByteArray::number(contrast);
   }

   kDebug(29000) << "option::get returns " << retstr;
   return( retstr );
}


/* Caller needs to have the space ;) */
bool KScanOption::get( KGammaTable *gt ) const
{
    if( gt )
    {
        gt->setAll( gamma, brightness, contrast );
        // gt->calcTable();
        return( true );
    }
    return( false );
}


QStringList KScanOption::getList( ) const
{
   if( desc==0L ) 
               return QStringList();
   const char     **sstring = 0;
   QStringList strList;

   if( desc->constraint_type == SANE_CONSTRAINT_STRING_LIST ) {
      sstring =  (const char**) desc->constraint.string_list;

      while( *sstring )
      {
       // qDebug( "This is in the stringlist: %s", *sstring );
       strList.append( *sstring );
       sstring++;
      }
   }
   if( desc->constraint_type == SANE_CONSTRAINT_WORD_LIST ) {
      const SANE_Int *sint =  desc->constraint.word_list;
      int amount_vals = *sint; sint ++;
      QString s;

      for( int i=0; i < amount_vals; i++ ) {
       if( desc->type == SANE_TYPE_FIXED )
          s.sprintf( "%f", SANE_UNFIX(*sint) );
       else
          s.sprintf( "%d", *sint );
       sint++;
       strList.append( s );
      }
   }
   return( strList );
}



bool KScanOption::getRangeFromList( double *min, double *max, double *q ) const
{
   if( !desc ) return( false );
   bool ret = true;

   if ( desc->constraint_type == SANE_CONSTRAINT_WORD_LIST ) {
          // Try to read resolutions from word list
          kDebug(29000) << "Resolutions are in a word list";
            const SANE_Int *sint =  desc->constraint.word_list;
            int amount_vals = *sint; sint ++;
          double value;
          *min = 0;
          *max = 0;
          *q = -1; // What is q?

            for( int i=0; i < amount_vals; i++ ) {
            if( desc->type == SANE_TYPE_FIXED ) {
                value = (double) SANE_UNFIX( *sint );
            } else {
                value = *sint;
            }
            if ((*min > value) || (*min == 0)) *min = value;
            if ((*max < value) || (*max == 0)) *max = value;
            
            if( *min != 0 && *max != 0 && *max > *min ) {
                double newq = max - min;
                *q = newq;
            }
            sint++;
            }
   } else {
      kDebug(29000) << "getRangeFromList: No list type " << desc->name;
      ret = false;
    }
    return( ret );
}



bool KScanOption::getRange( double *min, double *max, double *q ) const
{
   if( !desc ) return( false );
   bool ret = true;

   if( desc->constraint_type == SANE_CONSTRAINT_RANGE ||
         desc->constraint_type == SANE_CONSTRAINT_WORD_LIST ) {
      const SANE_Range *r = desc->constraint.range;

      if( desc->type == SANE_TYPE_FIXED ) {
        *min = (double) SANE_UNFIX( r->min );
        *max = (double) SANE_UNFIX( r->max );
        *q   = (double) SANE_UNFIX( r->quant );
      } else {
        *min = r->min ;
        *max = r->max ;
        *q   = r->quant ;
      }
   } else {
      kDebug(29000) << "getRange: No range type " << desc->name;
      ret = false;
   }
   return( ret );
}

01069 QWidget *KScanOption::createWidget( QWidget *parent, const QString& w_desc,
                                    const QString& tooltip )
{
  Q3StrList list;
  if( ! valid() )
  {
     kDebug(29000) << "The option is not valid!";
     return( 0 );
  }
  QWidget *w = 0;
  /* free the old widget */
  delete internal_widget;
  internal_widget = 0;
      
  /* check for text */
  QString text = w_desc;
  if( text.isEmpty() && desc ) {
    text = QString::fromLocal8Bit( desc->title );
  }
      
      
  switch( type( ) )
    {
    case BOOL:
      /* Widget Type is ToggleButton */
      w = new  QCheckBox( text, parent );
      w->setObjectName( QLatin1String( "AUTO_TOGGLE_BUTTON" ) );
      connect( w, SIGNAL(clicked()), this,
             SLOT(slWidgetChange()));
      break;
    case SINGLE_VAL:
      /* Widget Type is Entry-Field */
      w = 0; // new QEntryField(
      kDebug(29000) << "can not create widget for SINGLE_VAL!";
      break;
    case RANGE:
      /* Widget Type is Slider */
      w = KSaneSlider( parent, text );
      break;
    case GAMMA_TABLE:
      /* Widget Type is Slider */
      // w = KSaneSlider( parent, text );
      kDebug(29000) << "can not create widget for GAMMA_TABLE!";
      w = 0; // No widget, needs to be a set !
      break;
    case STR_LIST:                  
      w = comboBox( parent, text );
      /* Widget Type is Selection Box */
      break;
    case STRING:
      w = entryField( parent, text );
      /* Widget Type is Selection Box */
      break;
    default:
       kDebug(29000) << "returning zero for default widget creation!";
      w  = 0;
      break;
    }
      
  if( w )
    {
      internal_widget = w;
      connect( this, SIGNAL( optionChanged( KScanOption*)),
             SLOT( slRedrawWidget( KScanOption* )));
      QString tt = tooltip;
      if( tt.isEmpty() && desc )
      tt = QString::fromLocal8Bit( desc->desc );
                  
      if( !tt.isEmpty() )
      internal_widget->setToolTip( tt );
    }
      
  /* Check if option is active, setEnabled etc. */
  slReload();
  if( w ) slRedrawWidget( this );
  return( w );
}


QWidget *KScanOption::comboBox( QWidget *parent, const QString& text )
{
  QStringList list = getList();

  KScanCombo *cb = new KScanCombo( parent, text, list);

  connect( cb, SIGNAL( valueChanged( const QByteArray& )), this,
         SLOT( slWidgetChange( const QByteArray& )));

  return( cb );
}


QWidget *KScanOption::entryField( QWidget *parent, const QString& text )
{
  KScanEntry *ent = new KScanEntry( parent, text );
  connect( ent, SIGNAL( valueChanged( QByteArray )), this,
         SLOT( slWidgetChange( QByteArray )));
      
  return( ent );
}


QWidget *KScanOption::KSaneSlider( QWidget *parent, const QString& text )
{
  double min, max, quant;
  getRange( &min, &max, &quant );

  KScanSlider *slider = new KScanSlider( parent, text, min, max );
  /* Connect to the options change Slot */
  connect( slider, SIGNAL( valueChanged(int)), this,
         SLOT( slWidgetChange(int)));

  return( slider );
}




void *KScanOption::allocBuffer( long size )
{
  if( size < 1 ) return( 0 );

#ifdef MEM_DEBUG
  qDebug( "M: Reserving %ld bytes of mem for <%s>", size, (const char*) getName() );
#endif

  void *r = new char[ size ];
  buffer_size = size;

  if( r ) memset( r, 0, size );

  return( r );

}



bool KScanOption::applyVal( void )
{
   bool res = true;
   int *idx = (*KScanDevice::option_dic)[ name ];

   if( *idx == 0 ) return( false );
   if( ! buffer )  return( false );

   SANE_Status stat = sane_control_option ( KScanDevice::scanner_handle, *idx,
                                  SANE_ACTION_SET_VALUE, buffer,
                                  0 );
   if( stat != SANE_STATUS_GOOD )
   {
      kDebug(29000) << "Error in in situ appliance " << getName() << ": " << sane_strstatus( stat );
      res = false;
   }
   else
   {
      kDebug(29000) << "IN SITU appliance " << getName() << ": OK";

   }
   return( res );
}     
#include "kscanoption.moc"

Generated by  Doxygen 1.6.0   Back to index