1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include <tools/config.hxx>
25 #include <vcl/msgbox.hxx>
26 #include <sanedlg.hxx>
27 #include <sanedlg.hrc>
30 #include <sal/macros.h>
31 #include <rtl/strbuf.hxx>
33 ResId
SaneResId( sal_uInt32 nID
)
35 static ResMgr
* pResMgr
= ResMgr::CreateResMgr( "scn" );
36 return ResId( nID
, *pResMgr
);
39 SaneDlg::SaneDlg( Window
* pParent
, Sane
& rSane
, bool bScanEnabled
) :
40 ModalDialog( pParent
, SaneResId( RID_SANE_DIALOG
) ),
42 mbIsDragging( sal_False
),
43 mbScanEnabled( bScanEnabled
),
44 mbDragDrawn( sal_False
),
45 maMapMode( MAP_APPFONT
),
46 maOKButton( this, SaneResId( RID_SCAN_OK
) ),
47 maCancelButton( this, SaneResId( RID_SCAN_CANCEL
) ),
48 maDeviceInfoButton( this, SaneResId( RID_DEVICEINFO_BTN
) ),
49 maPreviewButton( this, SaneResId( RID_PREVIEW_BTN
) ),
50 maScanButton( this, SaneResId( RID_SCAN_BTN
) ),
51 maButtonOption( this, SaneResId( RID_SCAN_BUTTON_OPTION_BTN
) ),
52 maOptionsTxt( this, SaneResId( RID_SCAN_OPTION_TXT
) ),
53 maOptionTitle( this, SaneResId( RID_SCAN_OPTIONTITLE_TXT
) ),
54 maOptionDescTxt( this, SaneResId( RID_SCAN_OPTION_DESC_TXT
) ),
55 maVectorTxt( this, SaneResId( RID_SCAN_NUMERIC_VECTOR_TXT
) ),
56 maScanLeftTxt( this, SaneResId( RID_SCAN_LEFT_TXT
) ),
57 maLeftField( this, SaneResId( RID_SCAN_LEFT_BOX
) ),
58 maScanTopTxt( this, SaneResId( RID_SCAN_TOP_TXT
) ),
59 maTopField( this, SaneResId( RID_SCAN_TOP_BOX
) ),
60 maRightTxt( this, SaneResId( RID_SCAN_RIGHT_TXT
) ),
61 maRightField( this, SaneResId( RID_SCAN_RIGHT_BOX
) ),
62 maBottomTxt( this, SaneResId( RID_SCAN_BOTTOM_TXT
) ),
63 maBottomField( this, SaneResId( RID_SCAN_BOTTOM_BOX
) ),
64 maDeviceBoxTxt( this, SaneResId( RID_DEVICE_BOX_TXT
) ),
65 maDeviceBox( this, SaneResId( RID_DEVICE_BOX
) ),
66 maReslTxt( this, SaneResId( RID_SCAN_RESOLUTION_TXT
) ),
67 maReslBox( this, SaneResId( RID_SCAN_RESOLUTION_BOX
) ),
68 maAdvancedTxt( this, SaneResId( RID_SCAN_ADVANCED_TXT
) ),
69 maAdvancedBox( this, SaneResId( RID_SCAN_ADVANCED_BOX
) ),
70 maVectorBox( this, SaneResId( RID_SCAN_NUMERIC_VECTOR_BOX
) ),
71 maQuantumRangeBox( this, SaneResId( RID_SCAN_QUANTUM_RANGE_BOX
) ),
72 maStringRangeBox( this, SaneResId( RID_SCAN_STRING_RANGE_BOX
) ),
73 maPreviewBox( this, SaneResId( RID_PREVIEW_BOX
) ),
74 maAreaBox( this, SaneResId( RID_SCANAREA_BOX
) ),
75 maBoolCheckBox( this, SaneResId( RID_SCAN_BOOL_OPTION_BOX
) ),
76 maStringEdit( this, SaneResId( RID_SCAN_STRING_OPTION_EDT
) ),
77 maNumericEdit( this, SaneResId( RID_SCAN_NUMERIC_OPTION_EDT
) ),
78 maOptionBox( this, SaneResId( RID_SCAN_OPTION_BOX
) ),
84 InitDevices(); // opens first sane device
89 maDeviceInfoButton
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
90 maPreviewButton
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
91 maScanButton
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
92 maButtonOption
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
93 maDeviceBox
.SetSelectHdl( LINK( this, SaneDlg
, SelectHdl
) );
94 maOptionBox
.SetSelectHdl( LINK( this, SaneDlg
, OptionsBoxSelectHdl
) );
95 maOKButton
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
96 maCancelButton
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
97 maBoolCheckBox
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
98 maStringEdit
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
99 maNumericEdit
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
100 maVectorBox
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
101 maReslBox
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
102 maStringRangeBox
.SetSelectHdl( LINK( this, SaneDlg
, SelectHdl
) );
103 maQuantumRangeBox
.SetSelectHdl( LINK( this, SaneDlg
, SelectHdl
) );
104 maLeftField
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
105 maRightField
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
106 maTopField
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
107 maBottomField
.SetModifyHdl( LINK( this, SaneDlg
, ModifyHdl
) );
108 maAdvancedBox
.SetClickHdl( LINK( this, SaneDlg
, ClickBtnHdl
) );
110 maOldLink
= mrSane
.SetReloadOptionsHdl( LINK( this, SaneDlg
, ReloadSaneOptionsHdl
) );
112 maOptionBox
.SetNodeBitmaps(
113 Bitmap( SaneResId( RID_SCAN_BITMAP_PLUS
) ),
114 Bitmap( SaneResId( RID_SCAN_BITMAP_MINUS
) )
116 maOptionBox
.SetStyle( maOptionBox
.GetStyle()|
119 WB_NOINITIALSELECTION
|
120 WB_HASBUTTONSATROOT
|
128 mrSane
.SetReloadOptionsHdl( maOldLink
);
131 short SaneDlg::Execute()
133 if( ! Sane::IsSane() )
135 ErrorBox
aErrorBox( NULL
, WB_OK
| WB_DEF_OK
,
136 String( SaneResId( RID_SANE_NOSANELIB_TXT
) ) );
141 return ModalDialog::Execute();
144 void SaneDlg::InitDevices()
146 if( ! Sane::IsSane() )
149 if( mrSane
.IsOpen() )
151 mrSane
.ReloadDevices();
153 for( int i
= 0; i
< Sane::CountDevices(); i
++ )
154 maDeviceBox
.InsertEntry( Sane::GetName( i
) );
155 if( Sane::CountDevices() )
158 maDeviceBox
.SelectEntry( Sane::GetName( 0 ) );
163 void SaneDlg::InitFields()
165 if( ! Sane::IsSane() )
168 int nOption
, i
, nValue
;
170 sal_Bool bSuccess
= sal_False
;
171 const char *ppSpecialOptions
[] = {
180 mbDragEnable
= sal_True
;
182 maMinTopLeft
= Point( 0, 0 );
183 maMaxBottomRight
= Point( PREVIEW_WIDTH
, PREVIEW_HEIGHT
);
184 maScanButton
.Show( mbScanEnabled
);
186 if( ! mrSane
.IsOpen() )
190 nOption
= mrSane
.GetOptionByName( "resolution" );
195 bSuccess
= mrSane
.GetOptionValue( nOption
, fRes
);
198 maReslBox
.Enable( sal_True
);
200 maReslBox
.SetValue( (long)fRes
);
201 double *pDouble
= NULL
;
202 nValue
= mrSane
.GetRange( nOption
, pDouble
);
207 maReslBox
.SetMin( (long)pDouble
[0] );
208 maReslBox
.SetMax( (long)pDouble
[ nValue
-1 ] );
209 for( i
=0; i
<nValue
; i
++ )
211 if( i
== 0 || i
== nValue
-1 || ! ( ((int)pDouble
[i
]) % 20) )
212 maReslBox
.InsertValue( (long)pDouble
[i
] );
217 maReslBox
.SetMin( (long)pDouble
[0] );
218 maReslBox
.SetMax( (long)pDouble
[1] );
219 maReslBox
.InsertValue( (long)pDouble
[0] );
220 // Can only select 75 and 2400 dpi in Scanner dialogue
221 // scanner allows random setting of dpi resolution, a slider might be useful
223 // workaround: offer at least some more standard dpi resolution between
226 for ( int nRes
= (long) pDouble
[0] * 2; nRes
< (long) pDouble
[1]; nRes
= nRes
* 2 )
228 if ( !bGot300
&& nRes
> 300 ) {
229 nRes
= 300; bGot300
= 1;
231 maReslBox
.InsertValue(nRes
);
233 maReslBox
.InsertValue( (long)pDouble
[1] );
239 maReslBox
.Enable( sal_False
);
243 maReslBox
.Enable( sal_False
);
246 for( i
= 0; i
< 4; i
++ )
248 char const *pOptionName
= NULL
;
249 MetricField
* pField
= NULL
;
253 pOptionName
= "tl-x";
254 pField
= &maLeftField
;
257 pOptionName
= "tl-y";
258 pField
= &maTopField
;
261 pOptionName
= "br-x";
262 pField
= &maRightField
;
265 pOptionName
= "br-y";
266 pField
= &maBottomField
;
268 nOption
= pOptionName
? mrSane
.GetOptionByName( pOptionName
) : -1;
269 bSuccess
= sal_False
;
272 bSuccess
= mrSane
.GetOptionValue( nOption
, fValue
, 0 );
275 if( mrSane
.GetOptionUnit( nOption
) == SANE_UNIT_MM
)
277 pField
->SetUnit( FUNIT_MM
);
278 pField
->SetValue( (int)fValue
, FUNIT_MM
);
280 else // SANE_UNIT_PIXEL
282 pField
->SetValue( (int)fValue
, FUNIT_CUSTOM
);
283 pField
->SetCustomUnitText(OUString("Pixel"));
286 case 0: maTopLeft
.X() = (int)fValue
;break;
287 case 1: maTopLeft
.Y() = (int)fValue
;break;
288 case 2: maBottomRight
.X() = (int)fValue
;break;
289 case 3: maBottomRight
.Y() = (int)fValue
;break;
292 double *pDouble
= NULL
;
293 nValue
= mrSane
.GetRange( nOption
, pDouble
);
298 pField
->SetMin( (long)pDouble
[0] );
300 pField
->SetMax( (long)pDouble
[ nValue
-1 ] );
302 pField
->SetMax( (long)pDouble
[ 1 ] );
306 case 0: maMinTopLeft
.X() = pField
->GetMin();break;
307 case 1: maMinTopLeft
.Y() = pField
->GetMin();break;
308 case 2: maMaxBottomRight
.X() = pField
->GetMax();break;
309 case 3: maMaxBottomRight
.Y() = pField
->GetMax();break;
315 case 0: maMinTopLeft
.X() = (int)fValue
;break;
316 case 1: maMinTopLeft
.Y() = (int)fValue
;break;
317 case 2: maMaxBottomRight
.X() = (int)fValue
;break;
318 case 3: maMaxBottomRight
.Y() = (int)fValue
;break;
321 pField
->Enable( sal_True
);
325 mbDragEnable
= sal_False
;
329 maMinTopLeft
.X() = 0;
331 pField
->SetMax( PREVIEW_WIDTH
);
332 pField
->SetValue( 0 );
335 maMinTopLeft
.Y() = 0;
337 pField
->SetMax( PREVIEW_HEIGHT
);
338 pField
->SetValue( 0 );
341 maMaxBottomRight
.X() = PREVIEW_WIDTH
;
342 maBottomRight
.X() = PREVIEW_WIDTH
;
343 pField
->SetMax( PREVIEW_WIDTH
);
344 pField
->SetValue( PREVIEW_WIDTH
);
347 maMaxBottomRight
.Y() = PREVIEW_HEIGHT
;
348 maBottomRight
.Y() = PREVIEW_HEIGHT
;
349 pField
->SetMax( PREVIEW_HEIGHT
);
350 pField
->SetValue( PREVIEW_HEIGHT
);
353 pField
->Enable( sal_False
);
356 maTopLeft
= GetPixelPos( maTopLeft
);
357 maBottomRight
= GetPixelPos( maBottomRight
);
358 maPreviewRect
= Rectangle( maTopLeft
,
359 Size( maBottomRight
.X() - maTopLeft
.X(),
360 maBottomRight
.Y() - maTopLeft
.Y() )
364 SvTreeListEntry
* pParentEntry
= 0;
365 sal_Bool bGroupRejected
= sal_False
;
366 for( i
= 1; i
< mrSane
.CountOptions(); i
++ )
368 String aOption
=mrSane
.GetOptionName( i
);
369 sal_Bool bInsertAdvanced
=
370 mrSane
.GetOptionCap( i
) & SANE_CAP_ADVANCED
&&
371 ! maAdvancedBox
.IsChecked() ? sal_False
: sal_True
;
372 if( mrSane
.GetOptionType( i
) == SANE_TYPE_GROUP
)
374 if( bInsertAdvanced
)
376 aOption
= mrSane
.GetOptionTitle( i
);
377 pParentEntry
= maOptionBox
.InsertEntry( aOption
);
378 bGroupRejected
= sal_False
;
381 bGroupRejected
= sal_True
;
383 else if( aOption
.Len() &&
384 ! ( mrSane
.GetOptionCap( i
) &
386 SANE_CAP_HARD_SELECT
|
389 bInsertAdvanced
&& ! bGroupRejected
)
391 sal_Bool bIsSpecial
= sal_False
;
392 for( size_t n
= 0; !bIsSpecial
&&
393 n
< SAL_N_ELEMENTS(ppSpecialOptions
); n
++ )
395 if( aOption
.EqualsAscii( ppSpecialOptions
[n
] ) )
401 maOptionBox
.InsertEntry( aOption
, pParentEntry
);
403 maOptionBox
.InsertEntry( aOption
);
409 IMPL_LINK( SaneDlg
, ClickBtnHdl
, Button
*, pButton
)
411 if( mrSane
.IsOpen() )
413 if( pButton
== &maDeviceInfoButton
)
415 String
aString( SaneResId( RID_SANE_DEVICEINFO_TXT
) );
416 String
aSR( RTL_CONSTASCII_USTRINGPARAM( "%s" ) );
417 aString
.SearchAndReplace( aSR
, Sane::GetName( mrSane
.GetDeviceNumber() ) );
418 aString
.SearchAndReplace( aSR
, Sane::GetVendor( mrSane
.GetDeviceNumber() ) );
419 aString
.SearchAndReplace( aSR
, Sane::GetModel( mrSane
.GetDeviceNumber() ) );
420 aString
.SearchAndReplace( aSR
, Sane::GetType( mrSane
.GetDeviceNumber() ) );
421 InfoBox
aInfoBox( this, aString
);
424 else if( pButton
== &maPreviewButton
)
426 else if( pButton
== &maBoolCheckBox
)
428 mrSane
.SetOptionValue( mnCurrentOption
,
429 maBoolCheckBox
.IsChecked() ?
430 (sal_Bool
)sal_True
: (sal_Bool
)sal_False
);
432 else if( pButton
== &maButtonOption
)
435 SANE_Value_Type nType
= mrSane
.GetOptionType( mnCurrentOption
);
438 case SANE_TYPE_BUTTON
:
439 mrSane
.ActivateButtonOption( mnCurrentOption
);
441 case SANE_TYPE_FIXED
:
444 int nElements
= mrSane
.GetOptionElements( mnCurrentOption
);
445 double* x
= new double[ nElements
];
446 double* y
= new double[ nElements
];
447 for( int i
= 0; i
< nElements
; i
++ )
449 mrSane
.GetOptionValue( mnCurrentOption
, y
);
451 GridWindow
aGrid( x
, y
, nElements
, this );
452 aGrid
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
453 aGrid
.setBoundings( 0, mfMin
, nElements
, mfMax
);
454 if( aGrid
.Execute() && aGrid
.getNewYValues() )
455 mrSane
.SetOptionValue( mnCurrentOption
, aGrid
.getNewYValues() );
462 case SANE_TYPE_STRING
:
463 case SANE_TYPE_GROUP
:
467 else if( pButton
== &maAdvancedBox
)
469 ReloadSaneOptionsHdl( NULL
);
472 if( pButton
== &maOKButton
|| pButton
== &maScanButton
)
474 double fRes
= (double)maReslBox
.GetValue();
475 SetAdjustedNumericalValue( "resolution", fRes
);
476 UpdateScanArea( sal_True
);
478 EndDialog( mrSane
.IsOpen() ? 1 : 0 );
479 doScan
= (pButton
== &maScanButton
);
481 else if( pButton
== &maCancelButton
)
489 IMPL_LINK( SaneDlg
, SelectHdl
, ListBox
*, pListBox
)
491 if( pListBox
== &maDeviceBox
&& Sane::IsSane() && Sane::CountDevices() )
493 String aNewDevice
= maDeviceBox
.GetSelectEntry();
495 if( aNewDevice
.Equals( Sane::GetName( nNumber
= mrSane
.GetDeviceNumber() ) ) )
498 mrSane
.Open( nNumber
);
502 if( mrSane
.IsOpen() )
504 if( pListBox
== &maQuantumRangeBox
)
506 OString
aValue(OUStringToOString(maQuantumRangeBox
.GetSelectEntry(),
507 osl_getThreadTextEncoding()));
508 double fValue
= atof(aValue
.getStr());
509 mrSane
.SetOptionValue( mnCurrentOption
, fValue
, mnCurrentElement
);
511 else if( pListBox
== &maStringRangeBox
)
513 mrSane
.SetOptionValue( mnCurrentOption
, maStringRangeBox
.GetSelectEntry() );
519 IMPL_LINK( SaneDlg
, OptionsBoxSelectHdl
, SvTreeListBox
*, pBox
)
521 if( pBox
== &maOptionBox
&& Sane::IsSane() )
524 maOptionBox
.GetEntryText( maOptionBox
.FirstSelected() );
525 int nOption
= mrSane
.GetOptionByName(OUStringToOString(aOption
,
526 osl_getThreadTextEncoding()).getStr());
527 if( nOption
!= -1 && nOption
!= mnCurrentOption
)
530 mnCurrentOption
= nOption
;
531 maOptionTitle
.SetText( mrSane
.GetOptionTitle( mnCurrentOption
) );
532 SANE_Value_Type nType
= mrSane
.GetOptionType( mnCurrentOption
);
533 SANE_Constraint_Type nConstraint
;
536 case SANE_TYPE_BOOL
: EstablishBoolOption();break;
537 case SANE_TYPE_STRING
:
538 nConstraint
= mrSane
.GetOptionConstraintType( mnCurrentOption
);
539 if( nConstraint
== SANE_CONSTRAINT_STRING_LIST
)
540 EstablishStringRange();
542 EstablishStringOption();
544 case SANE_TYPE_FIXED
:
547 nConstraint
= mrSane
.GetOptionConstraintType( mnCurrentOption
);
548 int nElements
= mrSane
.GetOptionElements( mnCurrentOption
);
549 mnCurrentElement
= 0;
550 if( nConstraint
== SANE_CONSTRAINT_RANGE
||
551 nConstraint
== SANE_CONSTRAINT_WORD_LIST
)
552 EstablishQuantumRange();
556 EstablishNumericOption();
560 if( nElements
<= 10 )
562 maVectorBox
.SetValue( 1 );
563 maVectorBox
.SetMin( 1 );
565 mrSane
.GetOptionElements( mnCurrentOption
) );
566 maVectorBox
.Show( sal_True
);
567 maVectorTxt
.Show( sal_True
);
572 // bring up dialog only on button click
573 EstablishButtonOption();
578 case SANE_TYPE_BUTTON
:
579 EstablishButtonOption();
588 IMPL_LINK( SaneDlg
, ModifyHdl
, Edit
*, pEdit
)
590 if( mrSane
.IsOpen() )
592 if( pEdit
== &maStringEdit
)
594 mrSane
.SetOptionValue( mnCurrentOption
, maStringEdit
.GetText() );
596 else if( pEdit
== &maReslBox
)
598 double fRes
= (double)maReslBox
.GetValue();
599 int nOption
= mrSane
.GetOptionByName( "resolution" );
602 double* pDouble
= NULL
;
603 int nValues
= mrSane
.GetRange( nOption
, pDouble
);
607 for( i
= 0; i
< nValues
; i
++ )
609 if( fRes
== pDouble
[i
] )
615 else if( nValues
== 0 )
617 if( fRes
< pDouble
[ 0 ] )
619 if( fRes
> pDouble
[ 1 ] )
623 maReslBox
.SetValue( (sal_uLong
)fRes
);
626 else if( pEdit
== &maNumericEdit
)
629 OString
aContents(OUStringToOString(maNumericEdit
.GetText(),
630 osl_getThreadTextEncoding()));
631 fValue
= atof(aContents
.getStr());
632 if( mfMin
!= mfMax
&& ( fValue
< mfMin
|| fValue
> mfMax
) )
637 else if( fValue
> mfMax
)
639 sprintf( pBuf
, "%g", fValue
);
640 maNumericEdit
.SetText( String( pBuf
, osl_getThreadTextEncoding() ) );
642 mrSane
.SetOptionValue( mnCurrentOption
, fValue
, mnCurrentElement
);
644 else if( pEdit
== &maVectorBox
)
647 mnCurrentElement
= maVectorBox
.GetValue()-1;
649 mrSane
.GetOptionValue( mnCurrentOption
, fValue
, mnCurrentElement
);
650 sprintf( pBuf
, "%g", fValue
);
651 String
aValue( pBuf
, osl_getThreadTextEncoding() );
652 maNumericEdit
.SetText( aValue
);
653 maQuantumRangeBox
.SelectEntry( aValue
);
655 else if( pEdit
== &maTopField
)
657 Point
aPoint( 0, maTopField
.GetValue() );
658 aPoint
= GetPixelPos( aPoint
);
659 maTopLeft
.Y() = aPoint
.Y();
662 else if( pEdit
== &maLeftField
)
664 Point
aPoint( maLeftField
.GetValue(), 0 );
665 aPoint
= GetPixelPos( aPoint
);
666 maTopLeft
.X() = aPoint
.X();
669 else if( pEdit
== &maBottomField
)
671 Point
aPoint( 0, maBottomField
.GetValue() );
672 aPoint
= GetPixelPos( aPoint
);
673 maBottomRight
.Y() = aPoint
.Y();
676 else if( pEdit
== &maRightField
)
678 Point
aPoint( maRightField
.GetValue(), 0 );
679 aPoint
= GetPixelPos( aPoint
);
680 maBottomRight
.X() = aPoint
.X();
687 IMPL_LINK( SaneDlg
, ReloadSaneOptionsHdl
, Sane
*, /*pSane*/ )
689 mnCurrentOption
= -1;
690 mnCurrentElement
= 0;
692 // #92024# preserve preview rect, should only be set
693 // initially or in AcquirePreview
694 Rectangle aPreviewRect
= maPreviewRect
;
696 maPreviewRect
= aPreviewRect
;
697 Rectangle
aDummyRect( Point( 0, 0 ), GetSizePixel() );
702 void SaneDlg::AcquirePreview()
704 if( ! mrSane
.IsOpen() )
707 UpdateScanArea( sal_True
);
708 // set small resolution for preview
709 double fResl
= (double)maReslBox
.GetValue();
710 SetAdjustedNumericalValue( "resolution", 30.0 );
712 int nOption
= mrSane
.GetOptionByName( "preview" );
715 String
aString( SaneResId( RID_SANE_NORESOLUTIONOPTION_TXT
) );
716 WarningBox
aBox( this, WB_OK_CANCEL
| WB_DEF_OK
, aString
);
717 if( aBox
.Execute() == RET_CANCEL
)
721 mrSane
.SetOptionValue( nOption
, (sal_Bool
)sal_True
);
723 BitmapTransporter aTransporter
;
724 if( ! mrSane
.Start( aTransporter
) )
726 ErrorBox
aErrorBox( this, WB_OK
| WB_DEF_OK
,
727 String( SaneResId( RID_SANE_SCANERROR_TXT
) ) );
732 #if OSL_DEBUG_LEVEL > 1
733 aTransporter
.getStream().Seek( STREAM_SEEK_TO_END
);
734 fprintf( stderr
, "Previewbitmapstream contains %d bytes\n", (int)aTransporter
.getStream().Tell() );
736 aTransporter
.getStream().Seek( STREAM_SEEK_TO_BEGIN
);
737 maPreviewBitmap
.Read( aTransporter
.getStream(), sal_True
);
740 SetAdjustedNumericalValue( "resolution", fResl
);
741 maReslBox
.SetValue( (sal_uLong
)fResl
);
745 maPreviewRect
= Rectangle( maTopLeft
,
746 Size( maBottomRight
.X() - maTopLeft
.X(),
747 maBottomRight
.Y() - maTopLeft
.Y() )
752 Size
aBMSize( maPreviewBitmap
.GetSizePixel() );
753 if( aBMSize
.Width() > aBMSize
.Height() && aBMSize
.Width() )
755 int nVHeight
= (maBottomRight
.X() - maTopLeft
.X()) * aBMSize
.Height() / aBMSize
.Width();
756 maPreviewRect
= Rectangle( Point( maTopLeft
.X(), ( maTopLeft
.Y() + maBottomRight
.Y() )/2 - nVHeight
/2 ),
757 Size( maBottomRight
.X() - maTopLeft
.X(),
760 else if (aBMSize
.Height())
762 int nVWidth
= (maBottomRight
.Y() - maTopLeft
.Y()) * aBMSize
.Width() / aBMSize
.Height();
763 maPreviewRect
= Rectangle( Point( ( maTopLeft
.X() + maBottomRight
.X() )/2 - nVWidth
/2, maTopLeft
.Y() ),
765 maBottomRight
.Y() - maTopLeft
.Y() ) );
769 Paint( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
772 void SaneDlg::Paint( const Rectangle
& rRect
)
774 SetMapMode( maMapMode
);
775 SetFillColor( Color( COL_WHITE
) );
776 SetLineColor( Color( COL_WHITE
) );
777 DrawRect( Rectangle( Point( PREVIEW_UPPER_LEFT
, PREVIEW_UPPER_TOP
),
778 Size( PREVIEW_WIDTH
, PREVIEW_HEIGHT
) ) );
779 SetMapMode( MapMode( MAP_PIXEL
) );
780 // check for sane values
781 DrawBitmap( maPreviewRect
.TopLeft(), maPreviewRect
.GetSize(),
784 mbDragDrawn
= sal_False
;
787 ModalDialog::Paint( rRect
);
790 void SaneDlg::DisableOption()
792 maBoolCheckBox
.Show( sal_False
);
793 maStringEdit
.Show( sal_False
);
794 maNumericEdit
.Show( sal_False
);
795 maQuantumRangeBox
.Show( sal_False
);
796 maStringRangeBox
.Show( sal_False
);
797 maButtonOption
.Show( sal_False
);
798 maVectorBox
.Show( sal_False
);
799 maVectorTxt
.Show( sal_False
);
800 maOptionDescTxt
.Show( sal_False
);
803 void SaneDlg::EstablishBoolOption()
805 sal_Bool bSuccess
, bValue
;
807 bSuccess
= mrSane
.GetOptionValue( mnCurrentOption
, bValue
);
810 maOptionDescTxt
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
811 maOptionDescTxt
.Show( sal_True
);
812 maBoolCheckBox
.Check( bValue
);
813 maBoolCheckBox
.Show( sal_True
);
817 void SaneDlg::EstablishStringOption()
822 bSuccess
= mrSane
.GetOptionValue( mnCurrentOption
, aValue
);
825 maOptionDescTxt
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
826 maOptionDescTxt
.Show( sal_True
);
827 maStringEdit
.SetText(OStringToOUString(aValue
, osl_getThreadTextEncoding()));
828 maStringEdit
.Show( sal_True
);
832 void SaneDlg::EstablishStringRange()
834 const char** ppStrings
= mrSane
.GetStringConstraint( mnCurrentOption
);
835 maStringRangeBox
.Clear();
836 for( int i
= 0; ppStrings
[i
] != 0; i
++ )
837 maStringRangeBox
.InsertEntry( String( ppStrings
[i
], osl_getThreadTextEncoding() ) );
839 mrSane
.GetOptionValue( mnCurrentOption
, aValue
);
840 maStringRangeBox
.SelectEntry(OStringToOUString(aValue
, osl_getThreadTextEncoding()));
841 maStringRangeBox
.Show( sal_True
);
842 maOptionDescTxt
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
843 maOptionDescTxt
.Show( sal_True
);
846 void SaneDlg::EstablishQuantumRange()
853 int nValues
= mrSane
.GetRange( mnCurrentOption
, mpRange
);
856 mfMin
= mpRange
[ 0 ];
857 mfMax
= mpRange
[ 1 ];
860 EstablishNumericOption();
862 else if( nValues
> 0 )
865 maQuantumRangeBox
.Clear();
866 mfMin
= mpRange
[ 0 ];
867 mfMax
= mpRange
[ nValues
-1 ];
868 for( int i
= 0; i
< nValues
; i
++ )
870 sprintf( pBuf
, "%g", mpRange
[ i
] );
871 maQuantumRangeBox
.InsertEntry( String( pBuf
, osl_getThreadTextEncoding() ) );
874 if( mrSane
.GetOptionValue( mnCurrentOption
, fValue
, mnCurrentElement
) )
876 sprintf( pBuf
, "%g", fValue
);
877 maQuantumRangeBox
.SelectEntry( String( pBuf
, osl_getThreadTextEncoding() ) );
879 maQuantumRangeBox
.Show( sal_True
);
880 String
aText( mrSane
.GetOptionName( mnCurrentOption
) );
882 aText
+= mrSane
.GetOptionUnitName( mnCurrentOption
);
883 maOptionDescTxt
.SetText( aText
);
884 maOptionDescTxt
.Show( sal_True
);
888 void SaneDlg::EstablishNumericOption()
893 bSuccess
= mrSane
.GetOptionValue( mnCurrentOption
, fValue
);
898 String
aText( mrSane
.GetOptionName( mnCurrentOption
) );
900 aText
+= mrSane
.GetOptionUnitName( mnCurrentOption
);
903 sprintf( pBuf
, " < %g ; %g >", mfMin
, mfMax
);
904 aText
+= String( pBuf
, osl_getThreadTextEncoding() );
906 maOptionDescTxt
.SetText( aText
);
907 maOptionDescTxt
.Show( sal_True
);
908 sprintf( pBuf
, "%g", fValue
);
909 maNumericEdit
.SetText( String( pBuf
, osl_getThreadTextEncoding() ) );
910 maNumericEdit
.Show( sal_True
);
913 void SaneDlg::EstablishButtonOption()
915 maOptionDescTxt
.SetText( mrSane
.GetOptionName( mnCurrentOption
) );
916 maOptionDescTxt
.Show( sal_True
);
917 maButtonOption
.Show( sal_True
);
920 #define RECT_SIZE_PIX 7
922 void SaneDlg::MouseMove( const MouseEvent
& rMEvt
)
926 Point aMousePos
= rMEvt
.GetPosPixel();
927 // move into valid area
928 Point aLogicPos
= GetLogicPos( aMousePos
);
929 aMousePos
= GetPixelPos( aLogicPos
);
930 switch( meDragDirection
)
932 case TopLeft
: maTopLeft
= aMousePos
; break;
933 case Top
: maTopLeft
.Y() = aMousePos
.Y(); break;
935 maTopLeft
.Y() = aMousePos
.Y();
936 maBottomRight
.X() = aMousePos
.X();
938 case Right
: maBottomRight
.X() = aMousePos
.X(); break;
939 case BottomRight
: maBottomRight
= aMousePos
; break;
940 case Bottom
: maBottomRight
.Y() = aMousePos
.Y(); break;
942 maTopLeft
.X() = aMousePos
.X();
943 maBottomRight
.Y() = aMousePos
.Y();
945 case Left
: maTopLeft
.X() = aMousePos
.X(); break;
949 if( maTopLeft
.X() > maBottomRight
.X() )
951 nSwap
= maTopLeft
.X();
952 maTopLeft
.X() = maBottomRight
.X();
953 maBottomRight
.X() = nSwap
;
955 if( maTopLeft
.Y() > maBottomRight
.Y() )
957 nSwap
= maTopLeft
.Y();
958 maTopLeft
.Y() = maBottomRight
.Y();
959 maBottomRight
.Y() = nSwap
;
962 UpdateScanArea( sal_False
);
964 ModalDialog::MouseMove( rMEvt
);
967 void SaneDlg::MouseButtonDown( const MouseEvent
& rMEvt
)
969 Point aMousePixel
= rMEvt
.GetPosPixel();
971 if( ! mbIsDragging
&& mbDragEnable
)
973 int nMiddleX
= ( maBottomRight
.X() - maTopLeft
.X() ) / 2 - RECT_SIZE_PIX
/2 + maTopLeft
.X();
974 int nMiddleY
= ( maBottomRight
.Y() - maTopLeft
.Y() ) / 2 - RECT_SIZE_PIX
/2 + maTopLeft
.Y();
975 if( aMousePixel
.Y() >= maTopLeft
.Y() &&
976 aMousePixel
.Y() < maTopLeft
.Y() + RECT_SIZE_PIX
)
978 if( aMousePixel
.X() >= maTopLeft
.X() &&
979 aMousePixel
.X() < maTopLeft
.X() + RECT_SIZE_PIX
)
981 meDragDirection
= TopLeft
;
982 aMousePixel
= maTopLeft
;
983 mbIsDragging
= sal_True
;
985 else if( aMousePixel
.X() >= nMiddleX
&&
986 aMousePixel
.X() < nMiddleX
+ RECT_SIZE_PIX
)
988 meDragDirection
= Top
;
989 aMousePixel
.Y() = maTopLeft
.Y();
990 mbIsDragging
= sal_True
;
992 else if( aMousePixel
.X() > maBottomRight
.X() - RECT_SIZE_PIX
&&
993 aMousePixel
.X() <= maBottomRight
.X() )
995 meDragDirection
= TopRight
;
996 aMousePixel
= Point( maBottomRight
.X(), maTopLeft
.Y() );
997 mbIsDragging
= sal_True
;
1000 else if( aMousePixel
.Y() >= nMiddleY
&&
1001 aMousePixel
.Y() < nMiddleY
+ RECT_SIZE_PIX
)
1003 if( aMousePixel
.X() >= maTopLeft
.X() &&
1004 aMousePixel
.X() < maTopLeft
.X() + RECT_SIZE_PIX
)
1006 meDragDirection
= Left
;
1007 aMousePixel
.X() = maTopLeft
.X();
1008 mbIsDragging
= sal_True
;
1010 else if( aMousePixel
.X() > maBottomRight
.X() - RECT_SIZE_PIX
&&
1011 aMousePixel
.X() <= maBottomRight
.X() )
1013 meDragDirection
= Right
;
1014 aMousePixel
.X() = maBottomRight
.X();
1015 mbIsDragging
= sal_True
;
1018 else if( aMousePixel
.Y() <= maBottomRight
.Y() &&
1019 aMousePixel
.Y() > maBottomRight
.Y() - RECT_SIZE_PIX
)
1021 if( aMousePixel
.X() >= maTopLeft
.X() &&
1022 aMousePixel
.X() < maTopLeft
.X() + RECT_SIZE_PIX
)
1024 meDragDirection
= BottomLeft
;
1025 aMousePixel
= Point( maTopLeft
.X(), maBottomRight
.Y() );
1026 mbIsDragging
= sal_True
;
1028 else if( aMousePixel
.X() >= nMiddleX
&&
1029 aMousePixel
.X() < nMiddleX
+ RECT_SIZE_PIX
)
1031 meDragDirection
= Bottom
;
1032 aMousePixel
.Y() = maBottomRight
.Y();
1033 mbIsDragging
= sal_True
;
1035 else if( aMousePixel
.X() > maBottomRight
.X() - RECT_SIZE_PIX
&&
1036 aMousePixel
.X() <= maBottomRight
.X() )
1038 meDragDirection
= BottomRight
;
1039 aMousePixel
= maBottomRight
;
1040 mbIsDragging
= sal_True
;
1046 SetPointerPosPixel( aMousePixel
);
1049 ModalDialog::MouseButtonDown( rMEvt
);
1052 void SaneDlg::MouseButtonUp( const MouseEvent
& rMEvt
)
1056 UpdateScanArea( sal_True
);
1058 mbIsDragging
= sal_False
;
1060 ModalDialog::MouseButtonUp( rMEvt
);
1063 void SaneDlg::DrawRectangles( Point
& rUL
, Point
& rBR
)
1065 int nMiddleX
, nMiddleY
;
1068 aUR
= Point( rBR
.X(), rUL
.Y() );
1069 aBL
= Point( rUL
.X(), rBR
.Y() );
1070 nMiddleX
= ( rBR
.X() - rUL
.X() ) / 2 + rUL
.X();
1071 nMiddleY
= ( rBR
.Y() - rUL
.Y() ) / 2 + rUL
.Y();
1073 DrawLine( rUL
, aBL
);
1074 DrawLine( aBL
, rBR
);
1075 DrawLine( rBR
, aUR
);
1076 DrawLine( aUR
, rUL
);
1077 DrawRect( Rectangle( rUL
, Size( RECT_SIZE_PIX
,RECT_SIZE_PIX
) ) );
1078 DrawRect( Rectangle( aBL
, Size( RECT_SIZE_PIX
, -RECT_SIZE_PIX
) ) );
1079 DrawRect( Rectangle( rBR
, Size( -RECT_SIZE_PIX
, -RECT_SIZE_PIX
) ) );
1080 DrawRect( Rectangle( aUR
, Size( -RECT_SIZE_PIX
, RECT_SIZE_PIX
) ) );
1081 DrawRect( Rectangle( Point( nMiddleX
- RECT_SIZE_PIX
/2, rUL
.Y() ), Size( RECT_SIZE_PIX
, RECT_SIZE_PIX
) ) );
1082 DrawRect( Rectangle( Point( nMiddleX
- RECT_SIZE_PIX
/2, rBR
.Y() ), Size( RECT_SIZE_PIX
, -RECT_SIZE_PIX
) ) );
1083 DrawRect( Rectangle( Point( rUL
.X(), nMiddleY
- RECT_SIZE_PIX
/2 ), Size( RECT_SIZE_PIX
, RECT_SIZE_PIX
) ) );
1084 DrawRect( Rectangle( Point( rBR
.X(), nMiddleY
- RECT_SIZE_PIX
/2 ), Size( -RECT_SIZE_PIX
, RECT_SIZE_PIX
) ) );
1087 void SaneDlg::DrawDrag()
1089 static Point aLastUL
, aLastBR
;
1091 if( ! mbDragEnable
)
1094 RasterOp eROP
= GetRasterOp();
1095 SetRasterOp( ROP_INVERT
);
1096 SetMapMode( MapMode( MAP_PIXEL
) );
1099 DrawRectangles( aLastUL
, aLastBR
);
1101 aLastUL
= maTopLeft
;
1102 aLastBR
= maBottomRight
;
1103 DrawRectangles( maTopLeft
, maBottomRight
);
1105 mbDragDrawn
= sal_True
;
1106 SetRasterOp( eROP
);
1107 SetMapMode( maMapMode
);
1110 Point
SaneDlg::GetPixelPos( const Point
& rIn
)
1113 ( ( rIn
.X() * PREVIEW_WIDTH
) /
1114 ( maMaxBottomRight
.X() - maMinTopLeft
.X() ) )
1115 + PREVIEW_UPPER_LEFT
,
1116 ( ( rIn
.Y() * PREVIEW_HEIGHT
)
1117 / ( maMaxBottomRight
.Y() - maMinTopLeft
.Y() ) )
1118 + PREVIEW_UPPER_TOP
);
1120 return LogicToPixel( aConvert
, maMapMode
);
1123 Point
SaneDlg::GetLogicPos( const Point
& rIn
)
1125 Point aConvert
= PixelToLogic( rIn
, maMapMode
);
1126 aConvert
.X() -= PREVIEW_UPPER_LEFT
;
1127 aConvert
.Y() -= PREVIEW_UPPER_TOP
;
1128 if( aConvert
.X() < 0 )
1130 if( aConvert
.X() >= PREVIEW_WIDTH
)
1131 aConvert
.X() = PREVIEW_WIDTH
-1;
1132 if( aConvert
.Y() < 0 )
1134 if( aConvert
.Y() >= PREVIEW_HEIGHT
)
1135 aConvert
.Y() = PREVIEW_HEIGHT
-1;
1137 aConvert
.X() *= ( maMaxBottomRight
.X() - maMinTopLeft
.X() );
1138 aConvert
.X() /= PREVIEW_WIDTH
;
1139 aConvert
.Y() *= ( maMaxBottomRight
.Y() - maMinTopLeft
.Y() );
1140 aConvert
.Y() /= PREVIEW_HEIGHT
;
1144 void SaneDlg::UpdateScanArea( sal_Bool bSend
)
1146 if( ! mbDragEnable
)
1149 Point aUL
= GetLogicPos( maTopLeft
);
1150 Point aBR
= GetLogicPos( maBottomRight
);
1152 maLeftField
.SetValue( aUL
.X() );
1153 maTopField
.SetValue( aUL
.Y() );
1154 maRightField
.SetValue( aBR
.X() );
1155 maBottomField
.SetValue( aBR
.Y() );
1160 if( mrSane
.IsOpen() )
1162 SetAdjustedNumericalValue( "tl-x", (double)aUL
.X() );
1163 SetAdjustedNumericalValue( "tl-y", (double)aUL
.Y() );
1164 SetAdjustedNumericalValue( "br-x", (double)aBR
.X() );
1165 SetAdjustedNumericalValue( "br-y", (double)aBR
.Y() );
1169 sal_Bool
SaneDlg::LoadState()
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 OString aString
= aConfig
.ReadKey( "SO_LastSaneDevice" );
1185 for( i
= 0; i
< Sane::CountDevices() && !aString
.equals(OUStringToOString(Sane::GetName(i
), osl_getThreadTextEncoding())); i
++ ) ;
1186 if( i
== Sane::CountDevices() )
1190 mrSane
.Open( aString
.getStr() );
1195 if( mrSane
.IsOpen() )
1197 int iMax
= aConfig
.GetKeyCount();
1198 for (i
= 0; i
< iMax
; ++i
)
1200 aString
= aConfig
.GetKeyName( i
);
1201 OString aValue
= aConfig
.ReadKey( i
);
1202 int nOption
= mrSane
.GetOptionByName( aString
.getStr() );
1206 if (aValue
.matchL(RTL_CONSTASCII_STRINGPARAM("BOOL=")))
1208 aValue
= aValue
.copy(RTL_CONSTASCII_LENGTH("BOOL="));
1209 sal_Bool aBOOL
= (sal_Bool
)aValue
.toInt32();
1210 mrSane
.SetOptionValue( nOption
, aBOOL
);
1212 else if (aValue
.matchL(RTL_CONSTASCII_STRINGPARAM("STRING=")))
1214 aValue
= aValue
.copy(RTL_CONSTASCII_LENGTH("STRING="));
1215 mrSane
.SetOptionValue(nOption
,OStringToOUString(aValue
, osl_getThreadTextEncoding()) );
1217 else if (aValue
.matchL(RTL_CONSTASCII_STRINGPARAM("NUMERIC=")))
1219 aValue
= aValue
.copy(RTL_CONSTASCII_LENGTH("NUMERIC="));
1221 sal_Int32 nIndex
= 0;
1225 OString aSub
= aValue
.getToken(0, ':', nIndex
);
1227 sscanf(aSub
.getStr(), "%lg", &fValue
);
1228 SetAdjustedNumericalValue(aString
.getStr(), fValue
, n
++);
1230 while ( nIndex
>= 0 );
1241 void SaneDlg::SaveState()
1243 if( ! Sane::IsSane() )
1246 const char* pEnv
= getenv( "HOME" );
1247 String
aFileName( pEnv
? pEnv
: "", osl_getThreadTextEncoding() );
1248 aFileName
.AppendAscii( "/.so_sane_state" );
1250 Config
aConfig( aFileName
);
1251 aConfig
.DeleteGroup( "SANE" );
1252 aConfig
.SetGroup( "SANE" );
1253 aConfig
.WriteKey( "SO_LastSANEDevice",
1254 OUStringToOString(maDeviceBox
.GetSelectEntry(), RTL_TEXTENCODING_UTF8
) );
1256 static char const* pSaveOptions
[] = {
1263 for( size_t i
= 0; i
< SAL_N_ELEMENTS(pSaveOptions
); ++i
)
1265 OString aOption
= pSaveOptions
[i
];
1266 int nOption
= mrSane
.GetOptionByName( pSaveOptions
[i
] );
1269 SANE_Value_Type nType
= mrSane
.GetOptionType( nOption
);
1272 case SANE_TYPE_BOOL
:
1275 if( mrSane
.GetOptionValue( nOption
, bValue
) )
1277 OStringBuffer
aString(RTL_CONSTASCII_STRINGPARAM(
1279 aString
.append(static_cast<sal_Int32
>(bValue
));
1280 aConfig
.WriteKey(aOption
, aString
.makeStringAndClear());
1284 case SANE_TYPE_STRING
:
1287 if( mrSane
.GetOptionValue( nOption
, aValue
) )
1289 OStringBuffer
aString(RTL_CONSTASCII_STRINGPARAM("STRING="));
1290 aString
.append(aValue
);
1291 aConfig
.WriteKey( aOption
, aString
.makeStringAndClear() );
1295 case SANE_TYPE_FIXED
:
1298 OStringBuffer
aString(RTL_CONSTASCII_STRINGPARAM("NUMERIC="));
1303 for( n
= 0; n
< mrSane
.GetOptionElements( nOption
); n
++ )
1305 if( ! mrSane
.GetOptionValue( nOption
, fValue
, n
) )
1308 aString
.append(':');
1309 sprintf( buf
, "%lg", fValue
);
1310 aString
.append(buf
);
1312 if( n
>= mrSane
.GetOptionElements( nOption
) )
1313 aConfig
.WriteKey( aOption
, aString
.makeStringAndClear() );
1323 sal_Bool
SaneDlg::SetAdjustedNumericalValue(
1324 const char* pOption
,
1329 if( ! Sane::IsSane() || ! mrSane
.IsOpen() || ( nOption
= mrSane
.GetOptionByName( pOption
) ) == -1 )
1332 if( nElement
< 0 || nElement
>= mrSane
.GetOptionElements( nOption
) )
1335 double* pValues
= NULL
;
1337 if( ( nValues
= mrSane
.GetRange( nOption
, pValues
) ) < 0 )
1340 #if OSL_DEBUG_LEVEL > 1
1341 fprintf( stderr
, "SaneDlg::SetAdjustedNumericalValue( \"%s\", %lg ) ",
1348 double fNearest
= 1e6
;
1349 for( int i
= 0; i
< nValues
; i
++ )
1351 if( fabs( fValue
- pValues
[ i
] ) < fNearest
)
1353 fNearest
= fabs( fValue
- pValues
[ i
] );
1357 fValue
= pValues
[ nNearest
];
1361 if( fValue
< pValues
[0] )
1362 fValue
= pValues
[0];
1363 if( fValue
> pValues
[1] )
1364 fValue
= pValues
[1];
1367 mrSane
.SetOptionValue( nOption
, fValue
, nElement
);
1368 #if OSL_DEBUG_LEVEL > 1
1369 fprintf( stderr
, "yields %lg\n", fValue
);
1376 bool SaneDlg::getDoScan()
1381 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */