summaryrefslogtreecommitdiffstats
path: root/libkscan/kscanoption.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libkscan/kscanoption.cpp')
-rw-r--r--libkscan/kscanoption.cpp1221
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 <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"