You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegraphics/libkscan/kscanoption.cpp

1222 lines
28 KiB

/* 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 <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( &gt );
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( &gt );
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"