1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
33 #include <tools/config.hxx>
35 #include <vcl/msgbox.hxx>
36 #include <sanedlg.hxx>
37 #include <sanedlg.hrc>
41 #define USE_SAVE_STATE
42 #undef SAVE_ALL_STATES
44 ResId
SaneResId( sal_uInt32 nID
)
46 static ResMgr
* pResMgr
= ResMgr::CreateResMgr( "san" );
47 return ResId( nID
, *pResMgr
);
50 SaneDlg::SaneDlg( Window
* pParent
, Sane
& rSane
) :
51 ModalDialog( pParent
, SaneResId( RID_SANE_DIALOG
) ),
53 mbIsDragging( FALSE
),
55 maMapMode( MAP_APPFONT
),
56 maOKButton( this, SaneResId( RID_SCAN_OK
) ),
57 maCancelButton( this, SaneResId( RID_SCAN_CANCEL
) ),
58 maDeviceInfoButton( this, SaneResId( RID_DEVICEINFO_BTN
) ),
59 maPreviewButton( this, SaneResId( RID_PREVIEW_BTN
) ),
60 maButtonOption( this, SaneResId( RID_SCAN_BUTTON_OPTION_BTN
) ),
61 maOptionsTxt( this, SaneResId( RID_SCAN_OPTION_TXT
) ),
62 maOptionTitle( this, SaneResId( RID_SCAN_OPTIONTITLE_TXT
) ),
63 maOptionDescTxt( this, SaneResId( RID_SCAN_OPTION_DESC_TXT
) ),
64 maVectorTxt( this, SaneResId( RID_SCAN_NUMERIC_VECTOR_TXT
) ),
65 maScanLeftTxt( this, SaneResId( RID_SCAN_LEFT_TXT
) ),
66 maLeftField( this, SaneResId( RID_SCAN_LEFT_BOX
) ),
67 maScanTopTxt( this, SaneResId( RID_SCAN_TOP_TXT
) ),
68 maTopField( this, SaneResId( RID_SCAN_TOP_BOX
) ),
69 maRightTxt( this, SaneResId( RID_SCAN_RIGHT_TXT
) ),
70 maRightField( this, SaneResId( RID_SCAN_RIGHT_BOX
) ),
71 maBottomTxt( this, SaneResId( RID_SCAN_BOTTOM_TXT
) ),
72 maBottomField( this, SaneResId( RID_SCAN_BOTTOM_BOX
) ),
73 maDeviceBoxTxt( this, SaneResId( RID_DEVICE_BOX_TXT
) ),
74 maDeviceBox( this, SaneResId( RID_DEVICE_BOX
) ),
75 maReslTxt( this, SaneResId( RID_SCAN_RESOLUTION_TXT
) ),
76 maReslBox( this, SaneResId( RID_SCAN_RESOLUTION_BOX
) ),
77 maAdvancedTxt( this, SaneResId( RID_SCAN_ADVANCED_TXT
) ),
78 maAdvancedBox( this, SaneResId( RID_SCAN_ADVANCED_BOX
) ),
79 maVectorBox( this, SaneResId( RID_SCAN_NUMERIC_VECTOR_BOX
) ),
80 maQuantumRangeBox( this, SaneResId( RID_SCAN_QUANTUM_RANGE_BOX
) ),
81 maStringRangeBox( this, SaneResId( RID_SCAN_STRING_RANGE_BOX
) ),
82 maPreviewBox( this, SaneResId( RID_PREVIEW_BOX
) ),
83 maAreaBox( this, SaneResId( RID_SCANAREA_BOX
) ),
84 maBoolCheckBox( this, SaneResId( RID_SCAN_BOOL_OPTION_BOX
) ),
85 maStringEdit( this, SaneResId( RID_SCAN_STRING_OPTION_EDT
) ),
86 maNumericEdit( this, SaneResId( RID_SCAN_NUMERIC_OPTION_EDT
) ),
87 maOptionBox( this, SaneResId( RID_SCAN_OPTION_BOX
) ),
92 InitDevices(); // opens first sane device
97 maDeviceInfoButton
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
98 maPreviewButton
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
99 maButtonOption
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
100 maDeviceBox
.SetSelectHdl( LINK( this, SaneDlg
, SelectHdl
) );
101 maOptionBox
.SetSelectHdl( LINK( this, SaneDlg
, OptionsBoxSelectHdl
) );
102 maOKButton
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
103 maCancelButton
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
104 maBoolCheckBox
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
105 maStringEdit
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
106 maNumericEdit
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
107 maVectorBox
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
108 maReslBox
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
109 maStringRangeBox
.SetSelectHdl( LINK( this, SaneDlg
, SelectHdl
) );
110 maQuantumRangeBox
.SetSelectHdl( LINK( this, SaneDlg
, SelectHdl
) );
111 maLeftField
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
112 maRightField
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
113 maTopField
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
114 maBottomField
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
115 maAdvancedBox
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
117 maOldLink
= mrSane
.SetReloadOptionsHdl( LINK( this, SaneDlg
, ReloadSaneOptionsHdl
) );
119 maOptionBox
.SetNodeBitmaps(
120 Bitmap( SaneResId( RID_SCAN_BITMAP_PLUS
) ),
121 Bitmap( SaneResId( RID_SCAN_BITMAP_MINUS
) )
123 maOptionBox
.SetWindowBits( WB_HASLINES
|
125 WB_NOINITIALSELECTION
|
126 WB_HASBUTTONSATROOT
|
136 short SaneDlg::Execute()
138 if( ! Sane::IsSane() )
140 ErrorBox
aErrorBox( NULL
, WB_OK
| WB_DEF_OK
,
141 String( SaneResId( RID_SANE_NOSANELIB_TXT
) ) );
146 return ModalDialog::Execute();
149 void SaneDlg::InitDevices()
151 if( ! Sane::IsSane() )
154 if( mrSane
.IsOpen() )
156 mrSane
.ReloadDevices();
158 for( int i
= 0; i
< Sane::CountDevices(); i
++ )
159 maDeviceBox
.InsertEntry( Sane::GetName( i
) );
160 if( Sane::CountDevices() )
163 maDeviceBox
.SelectEntry( Sane::GetName( 0 ) );
168 void SaneDlg::InitFields()
170 if( ! Sane::IsSane() )
173 int nOption
, i
, nValue
;
175 BOOL bSuccess
= FALSE
;
176 const char *ppSpecialOptions
[] = {
187 maMinTopLeft
= Point( 0, 0 );
188 maMaxBottomRight
= Point( PREVIEW_WIDTH
, PREVIEW_HEIGHT
);
190 if( ! mrSane
.IsOpen() )
194 nOption
= mrSane
.GetOptionByName( "resolution" );
199 bSuccess
= mrSane
.GetOptionValue( nOption
, fRes
);
202 maReslBox
.Enable( TRUE
);
204 maReslBox
.SetValue( (long)fRes
);
205 double *pDouble
= NULL
;
206 nValue
= mrSane
.GetRange( nOption
, pDouble
);
211 maReslBox
.SetMin( (long)pDouble
[0] );
212 maReslBox
.SetMax( (long)pDouble
[ nValue
-1 ] );
213 for( i
=0; i
<nValue
; i
++ )
215 if( i
== 0 || i
== nValue
-1 || ! ( ((int)pDouble
[i
]) % 20) )
216 maReslBox
.InsertValue( (long)pDouble
[i
] );
221 maReslBox
.SetMin( (long)pDouble
[0] );
222 maReslBox
.SetMax( (long)pDouble
[1] );
223 maReslBox
.InsertValue( (long)pDouble
[0] );
224 // mh@openoffice.org: issue 68557: Can only select 75 and 2400 dpi in Scanner dialogue
225 // scanner allows random setting of dpi resolution, a slider might be useful
227 // workaround: offer at least some more standard dpi resolution between
230 for ( int nRes
= (long) pDouble
[0] * 2; nRes
< (long) pDouble
[1]; nRes
= nRes
* 2 )
232 if ( !bGot300
&& nRes
> 300 ) {
233 nRes
= 300; bGot300
= 1;
235 maReslBox
.InsertValue(nRes
);
237 maReslBox
.InsertValue( (long)pDouble
[1] );
243 maReslBox
.Enable( FALSE
);
247 maReslBox
.Enable( FALSE
);
250 for( i
= 0; i
< 4; i
++ )
252 char const *pOptionName
= NULL
;
253 MetricField
* pField
= NULL
;
257 pOptionName
= "tl-x";
258 pField
= &maLeftField
;
261 pOptionName
= "tl-y";
262 pField
= &maTopField
;
265 pOptionName
= "br-x";
266 pField
= &maRightField
;
269 pOptionName
= "br-y";
270 pField
= &maBottomField
;
272 nOption
= pOptionName
? mrSane
.GetOptionByName( pOptionName
) : -1;
276 bSuccess
= mrSane
.GetOptionValue( nOption
, fValue
, 0 );
279 if( mrSane
.GetOptionUnit( nOption
) == SANE_UNIT_MM
)
281 pField
->SetUnit( FUNIT_MM
);
282 pField
->SetValue( (int)fValue
, FUNIT_MM
);
284 else // SANE_UNIT_PIXEL
286 pField
->SetValue( (int)fValue
, FUNIT_CUSTOM
);
287 pField
->SetCustomUnitText( String::CreateFromAscii( "Pixel" ) );
290 case 0: maTopLeft
.X() = (int)fValue
;break;
291 case 1: maTopLeft
.Y() = (int)fValue
;break;
292 case 2: maBottomRight
.X() = (int)fValue
;break;
293 case 3: maBottomRight
.Y() = (int)fValue
;break;
296 double *pDouble
= NULL
;
297 nValue
= mrSane
.GetRange( nOption
, pDouble
);
302 pField
->SetMin( (long)pDouble
[0] );
304 pField
->SetMax( (long)pDouble
[ nValue
-1 ] );
306 pField
->SetMax( (long)pDouble
[ 1 ] );
310 case 0: maMinTopLeft
.X() = pField
->GetMin();break;
311 case 1: maMinTopLeft
.Y() = pField
->GetMin();break;
312 case 2: maMaxBottomRight
.X() = pField
->GetMax();break;
313 case 3: maMaxBottomRight
.Y() = pField
->GetMax();break;
319 case 0: maMinTopLeft
.X() = (int)fValue
;break;
320 case 1: maMinTopLeft
.Y() = (int)fValue
;break;
321 case 2: maMaxBottomRight
.X() = (int)fValue
;break;
322 case 3: maMaxBottomRight
.Y() = (int)fValue
;break;
325 pField
->Enable( TRUE
);
329 mbDragEnable
= FALSE
;
333 maMinTopLeft
.X() = 0;
335 pField
->SetMax( PREVIEW_WIDTH
);
336 pField
->SetValue( 0 );
339 maMinTopLeft
.Y() = 0;
341 pField
->SetMax( PREVIEW_HEIGHT
);
342 pField
->SetValue( 0 );
345 maMaxBottomRight
.X() = PREVIEW_WIDTH
;
346 maBottomRight
.X() = PREVIEW_WIDTH
;
347 pField
->SetMax( PREVIEW_WIDTH
);
348 pField
->SetValue( PREVIEW_WIDTH
);
351 maMaxBottomRight
.Y() = PREVIEW_HEIGHT
;
352 maBottomRight
.Y() = PREVIEW_HEIGHT
;
353 pField
->SetMax( PREVIEW_HEIGHT
);
354 pField
->SetValue( PREVIEW_HEIGHT
);
357 pField
->Enable( FALSE
);
360 maTopLeft
= GetPixelPos( maTopLeft
);
361 maBottomRight
= GetPixelPos( maBottomRight
);
362 maPreviewRect
= Rectangle( maTopLeft
,
363 Size( maBottomRight
.X() - maTopLeft
.X(),
364 maBottomRight
.Y() - maTopLeft
.Y() )
368 SvLBoxEntry
* pParentEntry
= 0;
369 BOOL bGroupRejected
= FALSE
;
370 for( i
= 1; i
< mrSane
.CountOptions(); i
++ )
372 String aOption
=mrSane
.GetOptionName( i
);
373 BOOL bInsertAdvanced
=
374 mrSane
.GetOptionCap( i
) & SANE_CAP_ADVANCED
&&
375 ! maAdvancedBox
.IsChecked() ? FALSE
: TRUE
;
376 if( mrSane
.GetOptionType( i
) == SANE_TYPE_GROUP
)
378 if( bInsertAdvanced
)
380 aOption
= mrSane
.GetOptionTitle( i
);
381 pParentEntry
= maOptionBox
.InsertEntry( aOption
);
382 bGroupRejected
= FALSE
;
385 bGroupRejected
= TRUE
;
387 else if( aOption
.Len() &&
388 ! ( mrSane
.GetOptionCap( i
) &
390 SANE_CAP_HARD_SELECT
|
393 bInsertAdvanced
&& ! bGroupRejected
)
395 BOOL bIsSpecial
= FALSE
;
396 for( size_t n
= 0; !bIsSpecial
&&
397 n
< sizeof(ppSpecialOptions
)/sizeof(ppSpecialOptions
[0]); n
++ )
399 if( aOption
.EqualsAscii( ppSpecialOptions
[n
] ) )
405 maOptionBox
.InsertEntry( aOption
, pParentEntry
);
407 maOptionBox
.InsertEntry( aOption
);
413 IMPL_LINK( SaneDlg
, ClickBtnHdl
, Button
*, pButton
)
415 if( mrSane
.IsOpen() )
417 if( pButton
== &maDeviceInfoButton
)
419 String
aString( SaneResId( RID_SANE_DEVICEINFO_TXT
) );
420 String
aSR( RTL_CONSTASCII_USTRINGPARAM( "%s" ) );
421 aString
.SearchAndReplace( aSR
, Sane::GetName( mrSane
.GetDeviceNumber() ) );
422 aString
.SearchAndReplace( aSR
, Sane::GetVendor( mrSane
.GetDeviceNumber() ) );
423 aString
.SearchAndReplace( aSR
, Sane::GetModel( mrSane
.GetDeviceNumber() ) );
424 aString
.SearchAndReplace( aSR
, Sane::GetType( mrSane
.GetDeviceNumber() ) );
425 InfoBox
aInfoBox( this, aString
);
428 else if( pButton
== &maPreviewButton
)
430 else if( pButton
== &maBoolCheckBox
)
432 mrSane
.SetOptionValue( mnCurrentOption
,
433 maBoolCheckBox
.IsChecked() ?
434 (BOOL
)TRUE
: (BOOL
)FALSE
);
436 else if( pButton
== &maButtonOption
)
439 SANE_Value_Type nType
= mrSane
.GetOptionType( mnCurrentOption
);
442 case SANE_TYPE_BUTTON
:
443 mrSane
.ActivateButtonOption( mnCurrentOption
);
445 case SANE_TYPE_FIXED
:
448 int nElements
= mrSane
.GetOptionElements( mnCurrentOption
);
449 double* x
= new double[ nElements
];
450 double* y
= new double[ nElements
];
451 for( int i
= 0; i
< nElements
; i
++ )
453 mrSane
.GetOptionValue( mnCurrentOption
, y
);
455 GridWindow
aGrid( x
, y
, nElements
, this );
456 aGrid
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
457 aGrid
.setBoundings( 0, mfMin
, nElements
, mfMax
);
458 if( aGrid
.Execute() && aGrid
.getNewYValues() )
459 mrSane
.SetOptionValue( mnCurrentOption
, aGrid
.getNewYValues() );
466 case SANE_TYPE_STRING
:
467 case SANE_TYPE_GROUP
:
471 else if( pButton
== &maAdvancedBox
)
473 ReloadSaneOptionsHdl( NULL
);
476 if( pButton
== &maOKButton
)
478 double fRes
= (double)maReslBox
.GetValue();
479 SetAdjustedNumericalValue( "resolution", fRes
);
480 mrSane
.SetReloadOptionsHdl( maOldLink
);
481 UpdateScanArea( TRUE
);
483 EndDialog( mrSane
.IsOpen() ? 1 : 0 );
485 else if( pButton
== &maCancelButton
)
487 mrSane
.SetReloadOptionsHdl( maOldLink
);
494 IMPL_LINK( SaneDlg
, SelectHdl
, ListBox
*, pListBox
)
496 if( pListBox
== &maDeviceBox
&& Sane::IsSane() && Sane::CountDevices() )
498 String aNewDevice
= maDeviceBox
.GetSelectEntry();
500 if( aNewDevice
.Equals( Sane::GetName( nNumber
= mrSane
.GetDeviceNumber() ) ) )
503 mrSane
.Open( nNumber
);
507 if( mrSane
.IsOpen() )
509 if( pListBox
== &maQuantumRangeBox
)
511 ByteString
aValue( maQuantumRangeBox
.GetSelectEntry(), osl_getThreadTextEncoding() );
512 double fValue
= atof( aValue
.GetBuffer() );
513 mrSane
.SetOptionValue( mnCurrentOption
, fValue
, mnCurrentElement
);
515 else if( pListBox
== &maStringRangeBox
)
517 mrSane
.SetOptionValue( mnCurrentOption
, maStringRangeBox
.GetSelectEntry() );
523 IMPL_LINK( SaneDlg
, OptionsBoxSelectHdl
, SvTreeListBox
*, pBox
)
525 if( pBox
== &maOptionBox
&& Sane::IsSane() )
528 maOptionBox
.GetEntryText( maOptionBox
.FirstSelected() );
529 int nOption
= mrSane
.GetOptionByName( ByteString( aOption
, osl_getThreadTextEncoding() ).GetBuffer() );
530 if( nOption
!= -1 && nOption
!= mnCurrentOption
)
533 mnCurrentOption
= nOption
;
534 maOptionTitle
.SetText( mrSane
.GetOptionTitle( mnCurrentOption
) );
535 SANE_Value_Type nType
= mrSane
.GetOptionType( mnCurrentOption
);
536 SANE_Constraint_Type nConstraint
;
539 case SANE_TYPE_BOOL
: EstablishBoolOption();break;
540 case SANE_TYPE_STRING
:
541 nConstraint
= mrSane
.GetOptionConstraintType( mnCurrentOption
);
542 if( nConstraint
== SANE_CONSTRAINT_STRING_LIST
)
543 EstablishStringRange();
545 EstablishStringOption();
547 case SANE_TYPE_FIXED
:
550 nConstraint
= mrSane
.GetOptionConstraintType( mnCurrentOption
);
551 int nElements
= mrSane
.GetOptionElements( mnCurrentOption
);
552 mnCurrentElement
= 0;
553 if( nConstraint
== SANE_CONSTRAINT_RANGE
||
554 nConstraint
== SANE_CONSTRAINT_WORD_LIST
)
555 EstablishQuantumRange();
559 EstablishNumericOption();
563 if( nElements
<= 10 )
565 maVectorBox
.SetValue( 1 );
566 maVectorBox
.SetMin( 1 );
568 mrSane
.GetOptionElements( mnCurrentOption
) );
569 maVectorBox
.Show( TRUE
);
570 maVectorTxt
.Show( TRUE
);
575 // bring up dialog only on button click
576 EstablishButtonOption();
581 case SANE_TYPE_BUTTON
:
582 EstablishButtonOption();
591 IMPL_LINK( SaneDlg
, ModifyHdl
, Edit
*, pEdit
)
593 if( mrSane
.IsOpen() )
595 if( pEdit
== &maStringEdit
)
597 mrSane
.SetOptionValue( mnCurrentOption
, maStringEdit
.GetText() );
599 else if( pEdit
== &maReslBox
)
601 double fRes
= (double)maReslBox
.GetValue();
602 int nOption
= mrSane
.GetOptionByName( "resolution" );
605 double* pDouble
= NULL
;
606 int nValues
= mrSane
.GetRange( nOption
, pDouble
);
610 for( i
= 0; i
< nValues
; i
++ )
612 if( fRes
== pDouble
[i
] )
618 else if( nValues
== 0 )
620 if( fRes
< pDouble
[ 0 ] )
622 if( fRes
> pDouble
[ 1 ] )
625 maReslBox
.SetValue( (ULONG
)fRes
);
628 else if( pEdit
== &maNumericEdit
)
632 ByteString
aContents( maNumericEdit
.GetText(), osl_getThreadTextEncoding() );
633 fValue
= atof( aContents
.GetBuffer() );
634 if( mfMin
!= mfMax
&& ( fValue
< mfMin
|| fValue
> mfMax
) )
638 else if( fValue
> mfMax
)
640 sprintf( pBuf
, "%g", fValue
);
641 maNumericEdit
.SetText( String( pBuf
, osl_getThreadTextEncoding() ) );
643 mrSane
.SetOptionValue( mnCurrentOption
, fValue
, mnCurrentElement
);
645 else if( pEdit
== &maVectorBox
)
648 mnCurrentElement
= maVectorBox
.GetValue()-1;
650 mrSane
.GetOptionValue( mnCurrentOption
, fValue
, mnCurrentElement
);
651 sprintf( pBuf
, "%g", fValue
);
652 String
aValue( pBuf
, osl_getThreadTextEncoding() );
653 maNumericEdit
.SetText( aValue
);
654 maQuantumRangeBox
.SelectEntry( aValue
);
656 else if( pEdit
== &maTopField
)
658 Point
aPoint( 0, maTopField
.GetValue() );
659 aPoint
= GetPixelPos( aPoint
);
660 maTopLeft
.Y() = aPoint
.Y();
663 else if( pEdit
== &maLeftField
)
665 Point
aPoint( maLeftField
.GetValue(), 0 );
666 aPoint
= GetPixelPos( aPoint
);
667 maTopLeft
.X() = aPoint
.X();
670 else if( pEdit
== &maBottomField
)
672 Point
aPoint( 0, maBottomField
.GetValue() );
673 aPoint
= GetPixelPos( aPoint
);
674 maBottomRight
.Y() = aPoint
.Y();
677 else if( pEdit
== &maRightField
)
679 Point
aPoint( maRightField
.GetValue(), 0 );
680 aPoint
= GetPixelPos( aPoint
);
681 maBottomRight
.X() = aPoint
.X();
688 IMPL_LINK( SaneDlg
, ReloadSaneOptionsHdl
, Sane
*, /*pSane*/ )
690 mnCurrentOption
= -1;
691 mnCurrentElement
= 0;
693 // #92024# preserve preview rect, should only be set
694 // initially or in AcquirePreview
695 Rectangle aPreviewRect
= maPreviewRect
;
697 maPreviewRect
= aPreviewRect
;
698 Rectangle
aDummyRect( Point( 0, 0 ), GetSizePixel() );
703 void SaneDlg::AcquirePreview()
705 if( ! mrSane
.IsOpen() )
708 UpdateScanArea( TRUE
);
709 // set small resolution for preview
710 double fResl
= (double)maReslBox
.GetValue();
711 SetAdjustedNumericalValue( "resolution", 30.0 );
713 int nOption
= mrSane
.GetOptionByName( "preview" );
716 String
aString( SaneResId( RID_SANE_NORESOLUTIONOPTION_TXT
) );
717 WarningBox
aBox( this, WB_OK_CANCEL
| WB_DEF_OK
, aString
);
718 if( aBox
.Execute() == RET_CANCEL
)
722 mrSane
.SetOptionValue( nOption
, (BOOL
)TRUE
);
724 BitmapTransporter aTransporter
;
725 if( ! mrSane
.Start( aTransporter
) )
727 ErrorBox
aErrorBox( this, WB_OK
| WB_DEF_OK
,
728 String( SaneResId( RID_SANE_SCANERROR_TXT
) ) );
733 #if OSL_DEBUG_LEVEL > 1
734 aTransporter
.getStream().Seek( STREAM_SEEK_TO_END
);
735 fprintf( stderr
, "Previewbitmapstream contains %d bytes\n", (int)aTransporter
.getStream().Tell() );
737 aTransporter
.getStream().Seek( STREAM_SEEK_TO_BEGIN
);
738 maPreviewBitmap
.Read( aTransporter
.getStream(), TRUE
);
741 SetAdjustedNumericalValue( "resolution", fResl
);
742 maReslBox
.SetValue( (ULONG
)fResl
);
745 maPreviewRect
= Rectangle( maTopLeft
,
746 Size( maBottomRight
.X() - maTopLeft
.X(),
747 maBottomRight
.Y() - maTopLeft
.Y() )
751 Size
aBMSize( maPreviewBitmap
.GetSizePixel() );
752 if( aBMSize
.Width() > aBMSize
.Height() )
754 int nVHeight
= (maBottomRight
.X() - maTopLeft
.X()) * aBMSize
.Height() / aBMSize
.Width();
755 maPreviewRect
= Rectangle( Point( maTopLeft
.X(), ( maTopLeft
.Y() + maBottomRight
.Y() )/2 - nVHeight
/2 ),
756 Size( maBottomRight
.X() - maTopLeft
.X(),
761 int nVWidth
= (maBottomRight
.Y() - maTopLeft
.Y()) * aBMSize
.Width() / aBMSize
.Height();
762 maPreviewRect
= Rectangle( Point( ( maTopLeft
.X() + maBottomRight
.X() )/2 - nVWidth
/2, maTopLeft
.Y() ),
764 maBottomRight
.Y() - maTopLeft
.Y() ) );
768 Paint( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
771 void SaneDlg::Paint( const Rectangle
& rRect
)
773 SetMapMode( maMapMode
);
774 SetFillColor( Color( COL_WHITE
) );
775 SetLineColor( Color( COL_WHITE
) );
776 DrawRect( Rectangle( Point( PREVIEW_UPPER_LEFT
, PREVIEW_UPPER_TOP
),
777 Size( PREVIEW_WIDTH
, PREVIEW_HEIGHT
) ) );
778 SetMapMode( MapMode( MAP_PIXEL
) );
779 // check for sane values
780 DrawBitmap( maPreviewRect
.TopLeft(), maPreviewRect
.GetSize(),
786 ModalDialog::Paint( rRect
);
789 void SaneDlg::DisableOption()
791 maBoolCheckBox
.Show( FALSE
);
792 maStringEdit
.Show( FALSE
);
793 maNumericEdit
.Show( FALSE
);
794 maQuantumRangeBox
.Show( FALSE
);
795 maStringRangeBox
.Show( FALSE
);
796 maButtonOption
.Show( FALSE
);
797 maVectorBox
.Show( FALSE
);
798 maVectorTxt
.Show( FALSE
);
799 maOptionDescTxt
.Show( FALSE
);
802 void SaneDlg::EstablishBoolOption()
804 BOOL bSuccess
, bValue
;
806 bSuccess
= mrSane
.GetOptionValue( mnCurrentOption
, bValue
);
809 maOptionDescTxt
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
810 maOptionDescTxt
.Show( TRUE
);
811 maBoolCheckBox
.Check( bValue
);
812 maBoolCheckBox
.Show( TRUE
);
816 void SaneDlg::EstablishStringOption()
821 bSuccess
= mrSane
.GetOptionValue( mnCurrentOption
, aValue
);
824 maOptionDescTxt
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
825 maOptionDescTxt
.Show( TRUE
);
826 maStringEdit
.SetText( String( aValue
, osl_getThreadTextEncoding() ) );
827 maStringEdit
.Show( TRUE
);
831 void SaneDlg::EstablishStringRange()
833 const char** ppStrings
= mrSane
.GetStringConstraint( mnCurrentOption
);
834 maStringRangeBox
.Clear();
835 for( int i
= 0; ppStrings
[i
] != 0; i
++ )
836 maStringRangeBox
.InsertEntry( String( ppStrings
[i
], osl_getThreadTextEncoding() ) );
838 mrSane
.GetOptionValue( mnCurrentOption
, aValue
);
839 maStringRangeBox
.SelectEntry( String( aValue
, osl_getThreadTextEncoding() ) );
840 maStringRangeBox
.Show( TRUE
);
841 maOptionDescTxt
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
842 maOptionDescTxt
.Show( TRUE
);
845 void SaneDlg::EstablishQuantumRange()
852 int nValues
= mrSane
.GetRange( mnCurrentOption
, mpRange
);
855 mfMin
= mpRange
[ 0 ];
856 mfMax
= mpRange
[ 1 ];
859 EstablishNumericOption();
861 else if( nValues
> 0 )
864 maQuantumRangeBox
.Clear();
865 mfMin
= mpRange
[ 0 ];
866 mfMax
= mpRange
[ nValues
-1 ];
867 for( int i
= 0; i
< nValues
; i
++ )
869 sprintf( pBuf
, "%g", mpRange
[ i
] );
870 maQuantumRangeBox
.InsertEntry( String( pBuf
, osl_getThreadTextEncoding() ) );
873 if( mrSane
.GetOptionValue( mnCurrentOption
, fValue
, mnCurrentElement
) )
875 sprintf( pBuf
, "%g", fValue
);
876 maQuantumRangeBox
.SelectEntry( String( pBuf
, osl_getThreadTextEncoding() ) );
878 maQuantumRangeBox
.Show( TRUE
);
879 String
aText( mrSane
.GetOptionName( mnCurrentOption
) );
881 aText
+= mrSane
.GetOptionUnitName( mnCurrentOption
);
882 maOptionDescTxt
.SetText( aText
);
883 maOptionDescTxt
.Show( TRUE
);
887 void SaneDlg::EstablishNumericOption()
892 bSuccess
= mrSane
.GetOptionValue( mnCurrentOption
, fValue
);
897 String
aText( mrSane
.GetOptionName( mnCurrentOption
) );
899 aText
+= mrSane
.GetOptionUnitName( mnCurrentOption
);
902 sprintf( pBuf
, " < %g ; %g >", mfMin
, mfMax
);
903 aText
+= String( pBuf
, osl_getThreadTextEncoding() );
905 maOptionDescTxt
.SetText( aText
);
906 maOptionDescTxt
.Show( TRUE
);
907 sprintf( pBuf
, "%g", fValue
);
908 maNumericEdit
.SetText( String( pBuf
, osl_getThreadTextEncoding() ) );
909 maNumericEdit
.Show( TRUE
);
912 void SaneDlg::EstablishButtonOption()
914 maOptionDescTxt
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
915 maOptionDescTxt
.Show( TRUE
);
916 maButtonOption
.Show( TRUE
);
919 #define RECT_SIZE_PIX 7
921 void SaneDlg::MouseMove( const MouseEvent
& rMEvt
)
925 Point aMousePos
= rMEvt
.GetPosPixel();
926 // move into valid area
927 Point aLogicPos
= GetLogicPos( aMousePos
);
928 aMousePos
= GetPixelPos( aLogicPos
);
929 switch( meDragDirection
)
931 case TopLeft
: maTopLeft
= aMousePos
; break;
932 case Top
: maTopLeft
.Y() = aMousePos
.Y(); break;
934 maTopLeft
.Y() = aMousePos
.Y();
935 maBottomRight
.X() = aMousePos
.X();
937 case Right
: maBottomRight
.X() = aMousePos
.X(); break;
938 case BottomRight
: maBottomRight
= aMousePos
; break;
939 case Bottom
: maBottomRight
.Y() = aMousePos
.Y(); break;
941 maTopLeft
.X() = aMousePos
.X();
942 maBottomRight
.Y() = aMousePos
.Y();
944 case Left
: maTopLeft
.X() = aMousePos
.X(); break;
948 if( maTopLeft
.X() > maBottomRight
.X() )
950 nSwap
= maTopLeft
.X();
951 maTopLeft
.X() = maBottomRight
.X();
952 maBottomRight
.X() = nSwap
;
954 if( maTopLeft
.Y() > maBottomRight
.Y() )
956 nSwap
= maTopLeft
.Y();
957 maTopLeft
.Y() = maBottomRight
.Y();
958 maBottomRight
.Y() = nSwap
;
961 UpdateScanArea( FALSE
);
963 ModalDialog::MouseMove( rMEvt
);
966 void SaneDlg::MouseButtonDown( const MouseEvent
& rMEvt
)
968 Point aMousePixel
= rMEvt
.GetPosPixel();
970 if( ! mbIsDragging
&& mbDragEnable
)
972 int nMiddleX
= ( maBottomRight
.X() - maTopLeft
.X() ) / 2 - RECT_SIZE_PIX
/2 + maTopLeft
.X();
973 int nMiddleY
= ( maBottomRight
.Y() - maTopLeft
.Y() ) / 2 - RECT_SIZE_PIX
/2 + maTopLeft
.Y();
974 if( aMousePixel
.Y() >= maTopLeft
.Y() &&
975 aMousePixel
.Y() < maTopLeft
.Y() + RECT_SIZE_PIX
)
977 if( aMousePixel
.X() >= maTopLeft
.X() &&
978 aMousePixel
.X() < maTopLeft
.X() + RECT_SIZE_PIX
)
980 meDragDirection
= TopLeft
;
981 aMousePixel
= maTopLeft
;
984 else if( aMousePixel
.X() >= nMiddleX
&&
985 aMousePixel
.X() < nMiddleX
+ RECT_SIZE_PIX
)
987 meDragDirection
= Top
;
988 aMousePixel
.Y() = maTopLeft
.Y();
991 else if( aMousePixel
.X() > maBottomRight
.X() - RECT_SIZE_PIX
&&
992 aMousePixel
.X() <= maBottomRight
.X() )
994 meDragDirection
= TopRight
;
995 aMousePixel
= Point( maBottomRight
.X(), maTopLeft
.Y() );
999 else if( aMousePixel
.Y() >= nMiddleY
&&
1000 aMousePixel
.Y() < nMiddleY
+ RECT_SIZE_PIX
)
1002 if( aMousePixel
.X() >= maTopLeft
.X() &&
1003 aMousePixel
.X() < maTopLeft
.X() + RECT_SIZE_PIX
)
1005 meDragDirection
= Left
;
1006 aMousePixel
.X() = maTopLeft
.X();
1007 mbIsDragging
= TRUE
;
1009 else if( aMousePixel
.X() > maBottomRight
.X() - RECT_SIZE_PIX
&&
1010 aMousePixel
.X() <= maBottomRight
.X() )
1012 meDragDirection
= Right
;
1013 aMousePixel
.X() = maBottomRight
.X();
1014 mbIsDragging
= TRUE
;
1017 else if( aMousePixel
.Y() <= maBottomRight
.Y() &&
1018 aMousePixel
.Y() > maBottomRight
.Y() - RECT_SIZE_PIX
)
1020 if( aMousePixel
.X() >= maTopLeft
.X() &&
1021 aMousePixel
.X() < maTopLeft
.X() + RECT_SIZE_PIX
)
1023 meDragDirection
= BottomLeft
;
1024 aMousePixel
= Point( maTopLeft
.X(), maBottomRight
.Y() );
1025 mbIsDragging
= TRUE
;
1027 else if( aMousePixel
.X() >= nMiddleX
&&
1028 aMousePixel
.X() < nMiddleX
+ RECT_SIZE_PIX
)
1030 meDragDirection
= Bottom
;
1031 aMousePixel
.Y() = maBottomRight
.Y();
1032 mbIsDragging
= TRUE
;
1034 else if( aMousePixel
.X() > maBottomRight
.X() - RECT_SIZE_PIX
&&
1035 aMousePixel
.X() <= maBottomRight
.X() )
1037 meDragDirection
= BottomRight
;
1038 aMousePixel
= maBottomRight
;
1039 mbIsDragging
= TRUE
;
1045 SetPointerPosPixel( aMousePixel
);
1048 ModalDialog::MouseButtonDown( rMEvt
);
1051 void SaneDlg::MouseButtonUp( const MouseEvent
& rMEvt
)
1055 UpdateScanArea( TRUE
);
1057 mbIsDragging
= FALSE
;
1059 ModalDialog::MouseButtonUp( rMEvt
);
1062 void SaneDlg::DrawRectangles( Point
& rUL
, Point
& rBR
)
1064 int nMiddleX
, nMiddleY
;
1067 aUR
= Point( rBR
.X(), rUL
.Y() );
1068 aBL
= Point( rUL
.X(), rBR
.Y() );
1069 nMiddleX
= ( rBR
.X() - rUL
.X() ) / 2 + rUL
.X();
1070 nMiddleY
= ( rBR
.Y() - rUL
.Y() ) / 2 + rUL
.Y();
1072 DrawLine( rUL
, aBL
);
1073 DrawLine( aBL
, rBR
);
1074 DrawLine( rBR
, aUR
);
1075 DrawLine( aUR
, rUL
);
1076 DrawRect( Rectangle( rUL
, Size( RECT_SIZE_PIX
,RECT_SIZE_PIX
) ) );
1077 DrawRect( Rectangle( aBL
, Size( RECT_SIZE_PIX
, -RECT_SIZE_PIX
) ) );
1078 DrawRect( Rectangle( rBR
, Size( -RECT_SIZE_PIX
, -RECT_SIZE_PIX
) ) );
1079 DrawRect( Rectangle( aUR
, Size( -RECT_SIZE_PIX
, RECT_SIZE_PIX
) ) );
1080 DrawRect( Rectangle( Point( nMiddleX
- RECT_SIZE_PIX
/2, rUL
.Y() ), Size( RECT_SIZE_PIX
, RECT_SIZE_PIX
) ) );
1081 DrawRect( Rectangle( Point( nMiddleX
- RECT_SIZE_PIX
/2, rBR
.Y() ), Size( RECT_SIZE_PIX
, -RECT_SIZE_PIX
) ) );
1082 DrawRect( Rectangle( Point( rUL
.X(), nMiddleY
- RECT_SIZE_PIX
/2 ), Size( RECT_SIZE_PIX
, RECT_SIZE_PIX
) ) );
1083 DrawRect( Rectangle( Point( rBR
.X(), nMiddleY
- RECT_SIZE_PIX
/2 ), Size( -RECT_SIZE_PIX
, RECT_SIZE_PIX
) ) );
1086 void SaneDlg::DrawDrag()
1088 static Point aLastUL
, aLastBR
;
1090 if( ! mbDragEnable
)
1093 RasterOp eROP
= GetRasterOp();
1094 SetRasterOp( ROP_INVERT
);
1095 SetMapMode( MapMode( MAP_PIXEL
) );
1098 DrawRectangles( aLastUL
, aLastBR
);
1100 aLastUL
= maTopLeft
;
1101 aLastBR
= maBottomRight
;
1102 DrawRectangles( maTopLeft
, maBottomRight
);
1105 SetRasterOp( eROP
);
1106 SetMapMode( maMapMode
);
1109 Point
SaneDlg::GetPixelPos( const Point
& rIn
)
1112 ( ( rIn
.X() * PREVIEW_WIDTH
) /
1113 ( maMaxBottomRight
.X() - maMinTopLeft
.X() ) )
1114 + PREVIEW_UPPER_LEFT
,
1115 ( ( rIn
.Y() * PREVIEW_HEIGHT
)
1116 / ( maMaxBottomRight
.Y() - maMinTopLeft
.Y() ) )
1117 + PREVIEW_UPPER_TOP
);
1119 return LogicToPixel( aConvert
, maMapMode
);
1122 Point
SaneDlg::GetLogicPos( const Point
& rIn
)
1124 Point aConvert
= PixelToLogic( rIn
, maMapMode
);
1125 aConvert
.X() -= PREVIEW_UPPER_LEFT
;
1126 aConvert
.Y() -= PREVIEW_UPPER_TOP
;
1127 if( aConvert
.X() < 0 )
1129 if( aConvert
.X() >= PREVIEW_WIDTH
)
1130 aConvert
.X() = PREVIEW_WIDTH
-1;
1131 if( aConvert
.Y() < 0 )
1133 if( aConvert
.Y() >= PREVIEW_HEIGHT
)
1134 aConvert
.Y() = PREVIEW_HEIGHT
-1;
1136 aConvert
.X() *= ( maMaxBottomRight
.X() - maMinTopLeft
.X() );
1137 aConvert
.X() /= PREVIEW_WIDTH
;
1138 aConvert
.Y() *= ( maMaxBottomRight
.Y() - maMinTopLeft
.Y() );
1139 aConvert
.Y() /= PREVIEW_HEIGHT
;
1143 void SaneDlg::UpdateScanArea( BOOL bSend
)
1145 if( ! mbDragEnable
)
1148 Point aUL
= GetLogicPos( maTopLeft
);
1149 Point aBR
= GetLogicPos( maBottomRight
);
1151 maLeftField
.SetValue( aUL
.X() );
1152 maTopField
.SetValue( aUL
.Y() );
1153 maRightField
.SetValue( aBR
.X() );
1154 maBottomField
.SetValue( aBR
.Y() );
1159 if( mrSane
.IsOpen() )
1161 SetAdjustedNumericalValue( "tl-x", (double)aUL
.X() );
1162 SetAdjustedNumericalValue( "tl-y", (double)aUL
.Y() );
1163 SetAdjustedNumericalValue( "br-x", (double)aBR
.X() );
1164 SetAdjustedNumericalValue( "br-y", (double)aBR
.Y() );
1168 BOOL
SaneDlg::LoadState()
1170 #ifdef USE_SAVE_STATE
1173 if( ! Sane::IsSane() )
1176 const char* pEnv
= getenv("HOME");
1177 String
aFileName( pEnv
? pEnv
: "", osl_getThreadTextEncoding() );
1178 aFileName
+= String( RTL_CONSTASCII_USTRINGPARAM( "/.so_sane_state" ) );
1179 Config
aConfig( aFileName
);
1180 if( ! aConfig
.HasGroup( "SANE" ) )
1183 aConfig
.SetGroup( "SANE" );
1184 ByteString aString
= aConfig
.ReadKey( "SO_LastSaneDevice" );
1185 for( i
= 0; i
< Sane::CountDevices() && ! aString
.Equals( ByteString( Sane::GetName( i
), osl_getThreadTextEncoding() ) ); i
++ ) ;
1186 if( i
== Sane::CountDevices() )
1190 mrSane
.Open( aString
.GetBuffer() );
1195 if( mrSane
.IsOpen() )
1197 int iMax
= aConfig
.GetKeyCount();
1198 for( i
= 0; i
< iMax
; i
++ )
1200 aString
= aConfig
.GetKeyName( i
);
1201 ByteString aValue
= aConfig
.ReadKey( i
);
1202 int nOption
= mrSane
.GetOptionByName( aString
.GetBuffer() );
1205 if( aValue
.CompareTo( "BOOL=", 5 ) == COMPARE_EQUAL
)
1207 aValue
.Erase( 0, 5 );
1208 BOOL aBOOL
= (BOOL
)aValue
.ToInt32();
1209 mrSane
.SetOptionValue( nOption
, aBOOL
);
1211 else if( aValue
.CompareTo( "STRING=", 7 ) == COMPARE_EQUAL
)
1213 aValue
.Erase( 0, 7 );
1214 mrSane
.SetOptionValue( nOption
, String( aValue
, osl_getThreadTextEncoding() ) );
1216 else if( aValue
.CompareTo( "NUMERIC=", 8 ) == COMPARE_EQUAL
)
1218 aValue
.Erase( 0, 8 );
1219 int nMax
= aValue
.GetTokenCount( ':' );
1221 for( int n
= 0; n
< nMax
; n
++ )
1223 ByteString aSub
= aValue
.GetToken( n
, ':' );
1224 sscanf( aSub
.GetBuffer(), "%lg", &fValue
);
1225 SetAdjustedNumericalValue( aString
.GetBuffer(), fValue
, n
);
1241 void SaneDlg::SaveState()
1243 #ifdef USE_SAVE_STATE
1244 if( ! Sane::IsSane() )
1247 const char* pEnv
= getenv( "HOME" );
1248 String
aFileName( pEnv
? pEnv
: "", osl_getThreadTextEncoding() );
1249 aFileName
.AppendAscii( "/.so_sane_state" );
1251 Config
aConfig( aFileName
);
1252 aConfig
.DeleteGroup( "SANE" );
1253 aConfig
.SetGroup( "SANE" );
1254 aConfig
.WriteKey( "SO_LastSANEDevice", ByteString( maDeviceBox
.GetSelectEntry(), RTL_TEXTENCODING_UTF8
) );
1256 #ifdef SAVE_ALL_STATES
1257 for( int i
= 1; i
< mrSane
.CountOptions(); i
++ )
1259 String aOption
=mrSane
.GetOptionName( i
);
1260 SANE_Value_Type nType
= mrSane
.GetOptionType( i
);
1263 case SANE_TYPE_BOOL
:
1266 if( mrSane
.GetOptionValue( i
, bValue
) )
1268 ByteString
aString( "BOOL=" );
1269 aString
+= (ULONG
)bValue
;
1270 aConfig
.WriteKey( aOption
, aString
);
1274 case SANE_TYPE_STRING
:
1276 String
aString( "STRING=" );
1278 if( mrSane
.GetOptionValue( i
, aValue
) )
1281 aConfig
.WriteKey( aOption
, aString
);
1285 case SANE_TYPE_FIXED
:
1288 String
aString( "NUMERIC=" );
1291 for( int n
= 0; n
< mrSane
.GetOptionElements( i
); n
++ )
1293 if( ! mrSane
.GetOptionValue( i
, fValue
, n
) )
1297 sprintf( buf
, "%lg", fValue
);
1300 if( n
>= mrSane
.GetOptionElements( i
) )
1301 aConfig
.WriteKey( aOption
, aString
);
1309 static char const* pSaveOptions
[] = {
1317 i
< (sizeof(pSaveOptions
)/sizeof(pSaveOptions
[0]));
1320 ByteString aOption
= pSaveOptions
[i
];
1321 int nOption
= mrSane
.GetOptionByName( pSaveOptions
[i
] );
1324 SANE_Value_Type nType
= mrSane
.GetOptionType( nOption
);
1327 case SANE_TYPE_BOOL
:
1330 if( mrSane
.GetOptionValue( nOption
, bValue
) )
1332 ByteString
aString( "BOOL=" );
1333 aString
+= ByteString::CreateFromInt32(bValue
);
1334 aConfig
.WriteKey( aOption
, aString
);
1338 case SANE_TYPE_STRING
:
1340 ByteString
aString( "STRING=" );
1342 if( mrSane
.GetOptionValue( nOption
, aValue
) )
1345 aConfig
.WriteKey( aOption
, aString
);
1349 case SANE_TYPE_FIXED
:
1352 ByteString
aString( "NUMERIC=" );
1357 for( n
= 0; n
< mrSane
.GetOptionElements( nOption
); n
++ )
1359 if( ! mrSane
.GetOptionValue( nOption
, fValue
, n
) )
1363 sprintf( buf
, "%lg", fValue
);
1366 if( n
>= mrSane
.GetOptionElements( nOption
) )
1367 aConfig
.WriteKey( aOption
, aString
);
1379 BOOL
SaneDlg::SetAdjustedNumericalValue(
1380 const char* pOption
,
1385 if( ! Sane::IsSane() || ! mrSane
.IsOpen() || ( nOption
= mrSane
.GetOptionByName( pOption
) ) == -1 )
1388 if( nElement
< 0 || nElement
>= mrSane
.GetOptionElements( nOption
) )
1391 double* pValues
= NULL
;
1393 if( ( nValues
= mrSane
.GetRange( nOption
, pValues
) ) < 0 )
1396 #if OSL_DEBUG_LEVEL > 1
1397 fprintf( stderr
, "SaneDlg::SetAdjustedNumericalValue( \"%s\", %lg ) ",
1404 double fNearest
= 1e6
;
1405 for( int i
= 0; i
< nValues
; i
++ )
1407 if( fabs( fValue
- pValues
[ i
] ) < fNearest
)
1409 fNearest
= fabs( fValue
- pValues
[ i
] );
1413 fValue
= pValues
[ nNearest
];
1417 if( fValue
< pValues
[0] )
1418 fValue
= pValues
[0];
1419 if( fValue
> pValues
[1] )
1420 fValue
= pValues
[1];
1423 mrSane
.SetOptionValue( nOption
, fValue
, nElement
);
1424 #if OSL_DEBUG_LEVEL > 1
1425 fprintf( stderr
, "yields %lg\n", fValue
);