diff options
Diffstat (limited to 'libkscan/kscanoption.cpp')
-rw-r--r-- | libkscan/kscanoption.cpp | 1221 |
1 files changed, 1221 insertions, 0 deletions
diff --git a/libkscan/kscanoption.cpp b/libkscan/kscanoption.cpp new file mode 100644 index 00000000..1aae1602 --- /dev/null +++ b/libkscan/kscanoption.cpp @@ -0,0 +1,1221 @@ +/* This file is part of the KDE Project + Copyright (C) 2000 Klaas Freitag <[email protected]> + + 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 <qasciidict.h> +#include <qcombobox.h> +#include <qslider.h> +#include <qcheckbox.h> +#include <qlineedit.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qimage.h> +#include <qregexp.h> + +#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 QCString& 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 + { + kdDebug(29000) << "no option descriptor for <" << name << ">" << endl; + // debug( "Name survived !" ); + } + // debug( "<< leaving option %s >>", name ); + + return( d ); +} + + + +/* ************************************************************************ */ +/* KScan Option */ +/* ************************************************************************ */ +KScanOption::KScanOption( const QCString& 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 + { + kdDebug(29000) << "Had problems to create KScanOption - initOption failed !" << endl; + } +} + + +bool KScanOption::initOption( const QCString& 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 ) + { + kdDebug(29000) << "Is older GammaTable!" << endl; + KGammaTable gt; + gtOption->get( > ); + + gamma = gt.getGamma(); + contrast = gt.getContrast(); + brightness = gt.getBrightness(); + } + else + { + // kdDebug(29000) << "Is NOT older GammaTable!" << endl; + } + } + + return desc; +} + +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 ) ) + { + kdWarning( 29000) << "Trying to copy a not healthy option (no name nor desc)" << endl; + return; + } + + if( so.buffer_untouched ) + kdDebug(29000) << "Buffer of source is untouched!" << endl; + + 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: + kdWarning( 29000 ) << "unknown option type in copy constructor" << endl; + break; + } +} + + +const QString KScanOption::configLine( void ) +{ + QCString strval = this->get(); + kdDebug(29000) << "configLine returns <" << strval << ">" << endl; + 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 QCString& t ) +{ + kdDebug(29000) << "Received WidgetChange for " << getName() << " (const QCString&)" << endl; + set( t ); + emit( guiChange( this ) ); + // emit( optionChanged( this )); +} + +void KScanOption::slWidgetChange( void ) +{ + kdDebug(29000) << "Received WidgetChange for " << getName() << " (void)" << endl; + /* If Type is bool, the widget is a checkbox. */ + if( type() == BOOL ) + { + bool b = ((QCheckBox*) internal_widget)->isChecked(); + kdDebug(29000) << "Setting bool: " << b << endl; + set( b ); + } + emit( guiChange( this ) ); + // emit( optionChanged( this )); + +} + +void KScanOption::slWidgetChange( int i ) +{ + kdDebug(29000) << "Received WidgetChange for " << getName() << " (int)" << endl; + 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. */ + +void KScanOption::slReload( void ) +{ + int *num = (*KScanDevice::option_dic)[ getName() ]; + desc = getOptionDesc( getName() ); + + if( !desc || !num ) + return; + + if( widget() ) + { + kdDebug(29000) << "constraint is " << desc->cap << endl; + if( !active() ) + kdDebug(29000) << desc->name << " is not active now" << endl; + + if( !softwareSetable() ) + kdDebug(29000) << desc->name << " is not software setable" << endl; + + if( !active() || !softwareSetable() ) + { + kdDebug(29000) << "Disabling widget " << getName() << " !" << endl; + widget()->setEnabled( false ); + } + else + widget()->setEnabled( true ); + } + + /* first get mem if nothing is approbiate */ + if( !buffer ) + { + kdDebug(29000) << " *********** getting without space **********" << endl; + // 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 ) + { + kdDebug(29000) << "ERROR: Buffer to small" << endl; + } + else + { + SANE_Status sane_stat = sane_control_option( KScanDevice::scanner_handle, *num, + SANE_ACTION_GET_VALUE, buffer, 0 ); + + if( sane_stat != SANE_STATUS_GOOD ) + { + kdDebug(29000) << "ERROR: Cant get value for " << getName() << ": " << sane_strstatus( sane_stat ) << endl; + } else { + buffer_untouched = false; + kdDebug(29000) << "Setting buffer untouched to FALSE" << endl; + } + } + } +} + + +KScanOption::~KScanOption() +{ +#ifdef MEM_DEBUG + qDebug( "M: FREEing %d byte of option <%s>", buffer_size, (const char*) getName()); +#endif +} + +bool KScanOption::valid( void ) const +{ + return( desc && 1 ); +} + +bool KScanOption::autoSetable( void ) +{ + /* Refresh description */ + desc = getOptionDesc( name ); + + return( desc && ((desc->cap & SANE_CAP_AUTOMATIC) > 0 ) ); +} + +bool KScanOption::commonOption( void ) +{ + /* Refresh description */ + desc = getOptionDesc( name ); + + return( desc && ((desc->cap & SANE_CAP_ADVANCED) == 0) ); +} + + +bool KScanOption::active( void ) +{ + bool ret = false; + /* Refresh description */ + desc = getOptionDesc( name ); + if( desc ) + ret = SANE_OPTION_IS_ACTIVE( desc->cap ); + + return( ret ); +} + +bool KScanOption::softwareSetable( void ) +{ + /* Refresh description */ + desc = getOptionDesc( name ); + if( desc ) + { + if( SANE_OPTION_IS_SETTABLE(desc->cap) == SANE_TRUE ) + return( true ); + } + return( false ); +} + + +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 ); +} + + +bool KScanOption::set( int val ) +{ + if( ! desc ) return( false ); + bool ret = false; + + int word_size = 0; + QMemArray<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: + kdDebug(29000) << "Cant set " << name << " with type int" << endl; + } + 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; + QMemArray<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: + kdDebug(29000) << "Cant set " << name << " with type double" << endl; + } + + 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 offset = 0; + + int word_size = desc->size / sizeof( SANE_Word ); /* add 1 in case offset is needed */ + QMemArray<SANE_Word> qa( 1+word_size ); +#if 0 + if( desc->constraint_type == SANE_CONSTRAINT_WORD_LIST ) + { + /* That means that the first entry must contain the size */ + kdDebug(29000) << "Size: " << size << ", word_size: " << word_size << ", descr-size: "<< desc->size << endl; + qa[0] = (SANE_Word) 1+size; + kdDebug(29000) << "set length field to " << qa[0] <<endl; + 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: + kdDebug(29000) << "Cant set " << name << " with type int*" << endl; + + } + + if( ret && buffer ) { + int copybyte = desc->size; + + if( offset ) + copybyte += sizeof( SANE_Word ); + + kdDebug(29000) << "Copying " << copybyte << " byte to options buffer" << endl; + + 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 QCString& 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 = QStringList::split( ", ", QString(c_string) ); + + int brig = (relist[0]).toInt(); + int contr = (relist[1]).toInt(); + int gamm = (relist[2]).toInt(); + + KGammaTable gt( brig, contr, gamm ); + ret = set( > ); + kdDebug(29000) << "Setting GammaTable with int vals " << brig << "|" << contr << "|" << gamm << endl; + + return( ret ); + } + + + /* On String-type the buffer gets malloced in Constructor */ + switch( desc->type ) + { + case SANE_TYPE_STRING: + kdDebug(29000) << "Setting " << c_string << " as String" << endl; + + if( buffer_size >= c_string.length() ) + { + memset( buffer, 0, buffer_size ); + qstrncpy( (char*) buffer, (const char*) c_string, buffer_size ); + ret = true; + } + else + { + kdDebug(29000) << "ERROR: Buffer for String " << c_string << " too small: " << buffer_size << " < " << c_string.length() << endl; + } + break; + case SANE_TYPE_INT: + case SANE_TYPE_FIXED: + kdDebug(29000) << "Type is INT or FIXED, try to set value <" << c_string << ">" << endl; + val = c_string.toInt( &ret ); + if( ret ) + set( &val, 1 ); + else + kdDebug(29000) << "Conversion of string value failed!" << endl; + + break; + case SANE_TYPE_BOOL: + kdDebug(29000) << "Type is BOOL, setting value <" << c_string << ">" << endl; + val = 0; + if( c_string == "true" ) val = 1; + set( val ); + break; + default: + kdDebug(29000) << "Type of " << name << " is " << desc->type << endl; + kdDebug(29000) << "Cant set " << name << " with type string" << endl; + break; + } + + if( ret ) + { + buffer_untouched = false; +#ifdef APPLY_IN_SITU + applyVal(); +#endif +#if 0 + emit( optionChanged( this )); +#endif + } + kdDebug(29000) << "Returning " << ret << endl; + 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 ); + QMemArray<SANE_Word> qa( word_size ); + kdDebug(29000) << "KScanOption::set for Gammatable !" << endl; + 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: + kdDebug(29000) << "Cant set " << name << " with type GammaTable" << endl; + 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 ); +} + +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: + kdDebug(29000) << "Cant get " << name << " to type int" << endl; + return( false ); + } + + // qDebug( "option::get returns %d", *val ); + return( true ); +} + + + +QCString KScanOption::get( void ) const +{ + QCString 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: + kdDebug(29000) << "Cant get " << getName() << " to type String !" << endl; + retstr = "unknown"; + } + + /* Handle gamma-table correctly */ + ; + if( type() == GAMMA_TABLE ) + { + retstr.sprintf( "%d, %d, %d", gamma, brightness, contrast ); + } + + kdDebug(29000) << "option::get returns " << retstr << endl; + 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 ); +} + + +QStrList KScanOption::getList( ) const +{ + if( ! desc ) return( false ); + const char **sstring = 0; + QStrList 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.local8Bit() ); + } + } + 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 + kdDebug(29000) << "Resolutions are in a word list" << endl; + 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 { + kdDebug(29000) << "getRangeFromList: No list type " << desc->name << endl; + 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 { + kdDebug(29000) << "getRange: No range type " << desc->name << endl; + ret = false; + } + return( ret ); +} + +QWidget *KScanOption::createWidget( QWidget *parent, const QString& w_desc, + const QString& tooltip ) +{ + QStrList list; + if( ! valid() ) + { + kdDebug(29000) << "The option is not valid!" << endl; + 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, "AUTO_TOGGLE_BUTTON" ); + connect( w, SIGNAL(clicked()), this, + SLOT(slWidgetChange())); + break; + case SINGLE_VAL: + /* Widget Type is Entry-Field */ + w = 0; // new QEntryField( + kdDebug(29000) << "can not create widget for SINGLE_VAL!" << endl; + break; + case RANGE: + /* Widget Type is Slider */ + w = KSaneSlider( parent, text ); + break; + case GAMMA_TABLE: + /* Widget Type is Slider */ + // w = KSaneSlider( parent, text ); + kdDebug(29000) << "can not create widget for GAMMA_TABLE!" << endl; + 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: + kdDebug(29000) << "returning zero for default widget creation!" << endl; + 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() ) + QToolTip::add( internal_widget, tt ); + } + + /* Check if option is active, setEnabled etc. */ + slReload(); + if( w ) slRedrawWidget( this ); + return( w ); +} + + +QWidget *KScanOption::comboBox( QWidget *parent, const QString& text ) +{ + QStrList list = getList(); + + KScanCombo *cb = new KScanCombo( parent, text, list); + + connect( cb, SIGNAL( valueChanged( const QCString& )), this, + SLOT( slWidgetChange( const QCString& ))); + + return( cb ); +} + + +QWidget *KScanOption::entryField( QWidget *parent, const QString& text ) +{ + KScanEntry *ent = new KScanEntry( parent, text ); + connect( ent, SIGNAL( valueChanged( QCString )), this, + SLOT( slWidgetChange( QCString ))); + + 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 ) + { + kdDebug(29000) << "Error in in situ appliance " << getName() << ": " << sane_strstatus( stat ) << endl; + res = false; + } + else + { + kdDebug(29000) << "IN SITU appliance " << getName() << ": OK" << endl; + + } + return( res ); +} +#include "kscanoption.moc" |