xref: /AOO41X/main/extensions/source/scanner/sanedlg.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_extensions.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <stdio.h>
32*cdf0e10cSrcweir #include <stdlib.h>
33*cdf0e10cSrcweir #include <tools/config.hxx>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
36*cdf0e10cSrcweir #include <sanedlg.hxx>
37*cdf0e10cSrcweir #include <sanedlg.hrc>
38*cdf0e10cSrcweir #include <grid.hxx>
39*cdf0e10cSrcweir #include <math.h>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #define USE_SAVE_STATE
42*cdf0e10cSrcweir #undef  SAVE_ALL_STATES
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir ResId SaneResId( sal_uInt32 nID )
45*cdf0e10cSrcweir {
46*cdf0e10cSrcweir 	static ResMgr* pResMgr = ResMgr::CreateResMgr( "san" );
47*cdf0e10cSrcweir 	return ResId( nID, *pResMgr );
48*cdf0e10cSrcweir }
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir SaneDlg::SaneDlg( Window* pParent, Sane& rSane ) :
51*cdf0e10cSrcweir 		ModalDialog( pParent, SaneResId( RID_SANE_DIALOG ) ),
52*cdf0e10cSrcweir 		mrSane( rSane ),
53*cdf0e10cSrcweir 		mbIsDragging( sal_False ),
54*cdf0e10cSrcweir 		mbDragDrawn( sal_False ),
55*cdf0e10cSrcweir 		maMapMode( MAP_APPFONT ),
56*cdf0e10cSrcweir 		maOKButton( this, SaneResId( RID_SCAN_OK ) ),
57*cdf0e10cSrcweir 		maCancelButton( this, SaneResId( RID_SCAN_CANCEL ) ),
58*cdf0e10cSrcweir 		maDeviceInfoButton( this, SaneResId( RID_DEVICEINFO_BTN ) ),
59*cdf0e10cSrcweir 		maPreviewButton( this, SaneResId( RID_PREVIEW_BTN ) ),
60*cdf0e10cSrcweir 		maButtonOption( this, SaneResId( RID_SCAN_BUTTON_OPTION_BTN ) ),
61*cdf0e10cSrcweir 		maOptionsTxt( this, SaneResId( RID_SCAN_OPTION_TXT ) ),
62*cdf0e10cSrcweir 		maOptionTitle( this, SaneResId( RID_SCAN_OPTIONTITLE_TXT ) ),
63*cdf0e10cSrcweir 		maOptionDescTxt( this, SaneResId( RID_SCAN_OPTION_DESC_TXT ) ),
64*cdf0e10cSrcweir 		maVectorTxt( this, SaneResId( RID_SCAN_NUMERIC_VECTOR_TXT ) ),
65*cdf0e10cSrcweir 		maScanLeftTxt( this, SaneResId( RID_SCAN_LEFT_TXT ) ),
66*cdf0e10cSrcweir 		maLeftField( this, SaneResId( RID_SCAN_LEFT_BOX ) ),
67*cdf0e10cSrcweir 		maScanTopTxt( this, SaneResId( RID_SCAN_TOP_TXT ) ),
68*cdf0e10cSrcweir 		maTopField( this, SaneResId( RID_SCAN_TOP_BOX ) ),
69*cdf0e10cSrcweir 		maRightTxt( this, SaneResId( RID_SCAN_RIGHT_TXT ) ),
70*cdf0e10cSrcweir 		maRightField( this, SaneResId( RID_SCAN_RIGHT_BOX ) ),
71*cdf0e10cSrcweir 		maBottomTxt( this, SaneResId( RID_SCAN_BOTTOM_TXT ) ),
72*cdf0e10cSrcweir 		maBottomField( this, SaneResId( RID_SCAN_BOTTOM_BOX ) ),
73*cdf0e10cSrcweir 		maDeviceBoxTxt( this, SaneResId( RID_DEVICE_BOX_TXT ) ),
74*cdf0e10cSrcweir 		maDeviceBox( this, SaneResId( RID_DEVICE_BOX ) ),
75*cdf0e10cSrcweir 		maReslTxt( this, SaneResId( RID_SCAN_RESOLUTION_TXT ) ),
76*cdf0e10cSrcweir 		maReslBox( this, SaneResId( RID_SCAN_RESOLUTION_BOX ) ),
77*cdf0e10cSrcweir 		maAdvancedTxt( this, SaneResId( RID_SCAN_ADVANCED_TXT ) ),
78*cdf0e10cSrcweir 		maAdvancedBox( this, SaneResId( RID_SCAN_ADVANCED_BOX ) ),
79*cdf0e10cSrcweir 		maVectorBox( this, SaneResId( RID_SCAN_NUMERIC_VECTOR_BOX ) ),
80*cdf0e10cSrcweir 		maQuantumRangeBox( this, SaneResId( RID_SCAN_QUANTUM_RANGE_BOX ) ),
81*cdf0e10cSrcweir 		maStringRangeBox( this, SaneResId( RID_SCAN_STRING_RANGE_BOX ) ),
82*cdf0e10cSrcweir 		maPreviewBox( this, SaneResId( RID_PREVIEW_BOX ) ),
83*cdf0e10cSrcweir 		maAreaBox( this, SaneResId( RID_SCANAREA_BOX ) ),
84*cdf0e10cSrcweir 		maBoolCheckBox( this, SaneResId( RID_SCAN_BOOL_OPTION_BOX ) ),
85*cdf0e10cSrcweir 		maStringEdit( this, SaneResId( RID_SCAN_STRING_OPTION_EDT ) ),
86*cdf0e10cSrcweir 		maNumericEdit( this, SaneResId( RID_SCAN_NUMERIC_OPTION_EDT ) ),
87*cdf0e10cSrcweir 		maOptionBox( this, SaneResId( RID_SCAN_OPTION_BOX ) ),
88*cdf0e10cSrcweir 		mpRange( 0 )
89*cdf0e10cSrcweir {
90*cdf0e10cSrcweir 	if( Sane::IsSane() )
91*cdf0e10cSrcweir 	{
92*cdf0e10cSrcweir 		InitDevices(); // opens first sane device
93*cdf0e10cSrcweir 		DisableOption();
94*cdf0e10cSrcweir 		InitFields();
95*cdf0e10cSrcweir 	}
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir 	maDeviceInfoButton.SetClickHdl( LINK( this, SaneDlg, ClickBtnHdl ) );
98*cdf0e10cSrcweir 	maPreviewButton.SetClickHdl( LINK( this, SaneDlg, ClickBtnHdl ) );
99*cdf0e10cSrcweir 	maButtonOption.SetClickHdl( LINK( this, SaneDlg, ClickBtnHdl ) );
100*cdf0e10cSrcweir 	maDeviceBox.SetSelectHdl( LINK( this, SaneDlg, SelectHdl ) );
101*cdf0e10cSrcweir 	maOptionBox.SetSelectHdl( LINK( this, SaneDlg, OptionsBoxSelectHdl ) );
102*cdf0e10cSrcweir 	maOKButton.SetClickHdl( LINK( this, SaneDlg, ClickBtnHdl ) );
103*cdf0e10cSrcweir 	maCancelButton.SetClickHdl( LINK( this, SaneDlg, ClickBtnHdl ) );
104*cdf0e10cSrcweir 	maBoolCheckBox.SetClickHdl( LINK( this, SaneDlg, ClickBtnHdl ) );
105*cdf0e10cSrcweir 	maStringEdit.SetModifyHdl( LINK( this, SaneDlg, ModifyHdl ) );
106*cdf0e10cSrcweir 	maNumericEdit.SetModifyHdl( LINK( this, SaneDlg, ModifyHdl ) );
107*cdf0e10cSrcweir 	maVectorBox.SetModifyHdl( LINK( this, SaneDlg, ModifyHdl ) );
108*cdf0e10cSrcweir 	maReslBox.SetModifyHdl( LINK( this, SaneDlg, ModifyHdl ) );
109*cdf0e10cSrcweir 	maStringRangeBox.SetSelectHdl( LINK( this, SaneDlg, SelectHdl ) );
110*cdf0e10cSrcweir 	maQuantumRangeBox.SetSelectHdl( LINK( this, SaneDlg, SelectHdl ) );
111*cdf0e10cSrcweir 	maLeftField.SetModifyHdl( LINK( this, SaneDlg, ModifyHdl ) );
112*cdf0e10cSrcweir 	maRightField.SetModifyHdl( LINK( this, SaneDlg, ModifyHdl ) );
113*cdf0e10cSrcweir 	maTopField.SetModifyHdl( LINK( this, SaneDlg, ModifyHdl ) );
114*cdf0e10cSrcweir 	maBottomField.SetModifyHdl( LINK( this, SaneDlg, ModifyHdl ) );
115*cdf0e10cSrcweir 	maAdvancedBox.SetClickHdl( LINK( this, SaneDlg, ClickBtnHdl ) );
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir 	maOldLink = mrSane.SetReloadOptionsHdl( LINK( this, SaneDlg, ReloadSaneOptionsHdl ) );
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir 	maOptionBox.SetNodeBitmaps(
120*cdf0e10cSrcweir 		Bitmap( SaneResId( RID_SCAN_BITMAP_PLUS ) ),
121*cdf0e10cSrcweir 		Bitmap( SaneResId( RID_SCAN_BITMAP_MINUS ) )
122*cdf0e10cSrcweir 		);
123*cdf0e10cSrcweir 	maOptionBox.SetStyle( maOptionBox.GetStyle()|
124*cdf0e10cSrcweir                           WB_HASLINES           |
125*cdf0e10cSrcweir 						  WB_HASBUTTONS         |
126*cdf0e10cSrcweir 						  WB_NOINITIALSELECTION |
127*cdf0e10cSrcweir 						  WB_HASBUTTONSATROOT   |
128*cdf0e10cSrcweir 						  WB_HASLINESATROOT
129*cdf0e10cSrcweir 						);
130*cdf0e10cSrcweir 	FreeResource();
131*cdf0e10cSrcweir }
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir SaneDlg::~SaneDlg()
134*cdf0e10cSrcweir {
135*cdf0e10cSrcweir }
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir short SaneDlg::Execute()
138*cdf0e10cSrcweir {
139*cdf0e10cSrcweir 	if( ! Sane::IsSane() )
140*cdf0e10cSrcweir 	{
141*cdf0e10cSrcweir 		ErrorBox aErrorBox( NULL, WB_OK | WB_DEF_OK,
142*cdf0e10cSrcweir 							String( SaneResId( RID_SANE_NOSANELIB_TXT ) ) );
143*cdf0e10cSrcweir 		aErrorBox.Execute();
144*cdf0e10cSrcweir 		return sal_False;
145*cdf0e10cSrcweir 	}
146*cdf0e10cSrcweir 	LoadState();
147*cdf0e10cSrcweir 	return ModalDialog::Execute();
148*cdf0e10cSrcweir }
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir void SaneDlg::InitDevices()
151*cdf0e10cSrcweir {
152*cdf0e10cSrcweir 	if( ! Sane::IsSane() )
153*cdf0e10cSrcweir 		return;
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 	if( mrSane.IsOpen() )
156*cdf0e10cSrcweir 		mrSane.Close();
157*cdf0e10cSrcweir 	mrSane.ReloadDevices();
158*cdf0e10cSrcweir 	maDeviceBox.Clear();
159*cdf0e10cSrcweir 	for( int i = 0; i < Sane::CountDevices(); i++ )
160*cdf0e10cSrcweir 		maDeviceBox.InsertEntry( Sane::GetName( i ) );
161*cdf0e10cSrcweir 	if( Sane::CountDevices() )
162*cdf0e10cSrcweir 	{
163*cdf0e10cSrcweir 		mrSane.Open( 0 );
164*cdf0e10cSrcweir 		maDeviceBox.SelectEntry( Sane::GetName( 0 ) );
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir 	}
167*cdf0e10cSrcweir }
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir void SaneDlg::InitFields()
170*cdf0e10cSrcweir {
171*cdf0e10cSrcweir 	if( ! Sane::IsSane() )
172*cdf0e10cSrcweir 		return;
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 	int nOption, i, nValue;
175*cdf0e10cSrcweir 	double fValue;
176*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
177*cdf0e10cSrcweir 	const char *ppSpecialOptions[] = {
178*cdf0e10cSrcweir 		"resolution",
179*cdf0e10cSrcweir 		"tl-x",
180*cdf0e10cSrcweir 		"tl-y",
181*cdf0e10cSrcweir 		"br-x",
182*cdf0e10cSrcweir 		"br-y",
183*cdf0e10cSrcweir 		"preview"
184*cdf0e10cSrcweir 	};
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir     mbDragEnable = sal_True;
187*cdf0e10cSrcweir 	maReslBox.Clear();
188*cdf0e10cSrcweir 	maMinTopLeft = Point( 0, 0 );
189*cdf0e10cSrcweir 	maMaxBottomRight = Point( PREVIEW_WIDTH,  PREVIEW_HEIGHT );
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir 	if( ! mrSane.IsOpen() )
192*cdf0e10cSrcweir 		return;
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 	// set Resolution
195*cdf0e10cSrcweir 	nOption = mrSane.GetOptionByName( "resolution" );
196*cdf0e10cSrcweir 	if( nOption != -1 )
197*cdf0e10cSrcweir 	{
198*cdf0e10cSrcweir 		double fRes;
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir 		bSuccess = mrSane.GetOptionValue( nOption, fRes );
201*cdf0e10cSrcweir 		if( bSuccess )
202*cdf0e10cSrcweir 		{
203*cdf0e10cSrcweir 			maReslBox.Enable( sal_True );
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 			maReslBox.SetValue( (long)fRes );
206*cdf0e10cSrcweir 			double *pDouble = NULL;
207*cdf0e10cSrcweir 			nValue = mrSane.GetRange( nOption, pDouble );
208*cdf0e10cSrcweir 			if( nValue > -1 )
209*cdf0e10cSrcweir 			{
210*cdf0e10cSrcweir 				if( nValue )
211*cdf0e10cSrcweir 				{
212*cdf0e10cSrcweir 					maReslBox.SetMin( (long)pDouble[0] );
213*cdf0e10cSrcweir 					maReslBox.SetMax( (long)pDouble[ nValue-1 ] );
214*cdf0e10cSrcweir 					for( i=0; i<nValue; i++ )
215*cdf0e10cSrcweir 					{
216*cdf0e10cSrcweir 						if( i == 0 || i == nValue-1 || ! ( ((int)pDouble[i]) % 20) )
217*cdf0e10cSrcweir 							maReslBox.InsertValue( (long)pDouble[i] );
218*cdf0e10cSrcweir 					}
219*cdf0e10cSrcweir 				}
220*cdf0e10cSrcweir 				else
221*cdf0e10cSrcweir 				{
222*cdf0e10cSrcweir 					maReslBox.SetMin( (long)pDouble[0] );
223*cdf0e10cSrcweir 					maReslBox.SetMax( (long)pDouble[1] );
224*cdf0e10cSrcweir 					maReslBox.InsertValue( (long)pDouble[0] );
225*cdf0e10cSrcweir 					// mh@openoffice.org: issue 68557: Can only select 75 and 2400 dpi in Scanner dialogue
226*cdf0e10cSrcweir 					// scanner allows random setting of dpi resolution, a slider might be useful
227*cdf0e10cSrcweir 					// support that
228*cdf0e10cSrcweir 					// workaround: offer at least some more standard dpi resolution between
229*cdf0e10cSrcweir 					// min and max value
230*cdf0e10cSrcweir 					int bGot300 = 0;
231*cdf0e10cSrcweir 					for ( int nRes = (long) pDouble[0] * 2; nRes < (long) pDouble[1]; nRes = nRes * 2 )
232*cdf0e10cSrcweir 					{
233*cdf0e10cSrcweir 						if ( !bGot300 && nRes > 300 ) {
234*cdf0e10cSrcweir 							nRes = 300; bGot300 = 1;
235*cdf0e10cSrcweir 						}
236*cdf0e10cSrcweir 						maReslBox.InsertValue(nRes);
237*cdf0e10cSrcweir 					}
238*cdf0e10cSrcweir 					maReslBox.InsertValue( (long)pDouble[1] );
239*cdf0e10cSrcweir 				}
240*cdf0e10cSrcweir 				if( pDouble )
241*cdf0e10cSrcweir 					delete [] pDouble;
242*cdf0e10cSrcweir 			}
243*cdf0e10cSrcweir 			else
244*cdf0e10cSrcweir 				maReslBox.Enable( sal_False );
245*cdf0e10cSrcweir 		}
246*cdf0e10cSrcweir 	}
247*cdf0e10cSrcweir 	else
248*cdf0e10cSrcweir 		maReslBox.Enable( sal_False );
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 	// set scan area
251*cdf0e10cSrcweir 	for( i = 0; i < 4; i++ )
252*cdf0e10cSrcweir 	{
253*cdf0e10cSrcweir 		char const *pOptionName = NULL;
254*cdf0e10cSrcweir 		MetricField* pField = NULL;
255*cdf0e10cSrcweir 		switch( i )
256*cdf0e10cSrcweir 		{
257*cdf0e10cSrcweir 			case 0:
258*cdf0e10cSrcweir 				pOptionName = "tl-x";
259*cdf0e10cSrcweir 				pField = &maLeftField;
260*cdf0e10cSrcweir 				break;
261*cdf0e10cSrcweir 			case 1:
262*cdf0e10cSrcweir 				pOptionName = "tl-y";
263*cdf0e10cSrcweir 				pField = &maTopField;
264*cdf0e10cSrcweir 				break;
265*cdf0e10cSrcweir 			case 2:
266*cdf0e10cSrcweir 				pOptionName = "br-x";
267*cdf0e10cSrcweir 				pField = &maRightField;
268*cdf0e10cSrcweir 				break;
269*cdf0e10cSrcweir 			case 3:
270*cdf0e10cSrcweir 				pOptionName = "br-y";
271*cdf0e10cSrcweir 				pField = &maBottomField;
272*cdf0e10cSrcweir 		}
273*cdf0e10cSrcweir 		nOption = pOptionName ? mrSane.GetOptionByName( pOptionName ) : -1;
274*cdf0e10cSrcweir 		bSuccess = sal_False;
275*cdf0e10cSrcweir 		if( nOption != -1 )
276*cdf0e10cSrcweir 		{
277*cdf0e10cSrcweir 			bSuccess = mrSane.GetOptionValue( nOption, fValue, 0 );
278*cdf0e10cSrcweir 			if( bSuccess )
279*cdf0e10cSrcweir 			{
280*cdf0e10cSrcweir 				if( mrSane.GetOptionUnit( nOption ) == SANE_UNIT_MM )
281*cdf0e10cSrcweir 				{
282*cdf0e10cSrcweir 					pField->SetUnit( FUNIT_MM );
283*cdf0e10cSrcweir 					pField->SetValue( (int)fValue, FUNIT_MM );
284*cdf0e10cSrcweir 				}
285*cdf0e10cSrcweir 				else // SANE_UNIT_PIXEL
286*cdf0e10cSrcweir 				{
287*cdf0e10cSrcweir 					pField->SetValue( (int)fValue, FUNIT_CUSTOM );
288*cdf0e10cSrcweir 					pField->SetCustomUnitText( String::CreateFromAscii( "Pixel" ) );
289*cdf0e10cSrcweir 				}
290*cdf0e10cSrcweir 				switch( i ) {
291*cdf0e10cSrcweir 					case 0: maTopLeft.X() = (int)fValue;break;
292*cdf0e10cSrcweir 					case 1:	maTopLeft.Y() = (int)fValue;break;
293*cdf0e10cSrcweir 					case 2:	maBottomRight.X() = (int)fValue;break;
294*cdf0e10cSrcweir 					case 3: maBottomRight.Y() = (int)fValue;break;
295*cdf0e10cSrcweir 				}
296*cdf0e10cSrcweir 			}
297*cdf0e10cSrcweir 			double *pDouble = NULL;
298*cdf0e10cSrcweir 			nValue = mrSane.GetRange( nOption, pDouble );
299*cdf0e10cSrcweir 			if( nValue > -1 )
300*cdf0e10cSrcweir 			{
301*cdf0e10cSrcweir 				if( pDouble )
302*cdf0e10cSrcweir 				{
303*cdf0e10cSrcweir 					pField->SetMin( (long)pDouble[0] );
304*cdf0e10cSrcweir 					if( nValue )
305*cdf0e10cSrcweir 						pField->SetMax( (long)pDouble[ nValue-1 ] );
306*cdf0e10cSrcweir 					else
307*cdf0e10cSrcweir 						pField->SetMax( (long)pDouble[ 1 ] );
308*cdf0e10cSrcweir 					delete [] pDouble;
309*cdf0e10cSrcweir 				}
310*cdf0e10cSrcweir 				switch( i ) {
311*cdf0e10cSrcweir 					case 0: maMinTopLeft.X() = pField->GetMin();break;
312*cdf0e10cSrcweir 					case 1: maMinTopLeft.Y() = pField->GetMin();break;
313*cdf0e10cSrcweir 					case 2: maMaxBottomRight.X() = pField->GetMax();break;
314*cdf0e10cSrcweir 					case 3: maMaxBottomRight.Y() = pField->GetMax();break;
315*cdf0e10cSrcweir 				}
316*cdf0e10cSrcweir 			}
317*cdf0e10cSrcweir 			else
318*cdf0e10cSrcweir 			{
319*cdf0e10cSrcweir 				switch( i ) {
320*cdf0e10cSrcweir 					case 0: maMinTopLeft.X() = (int)fValue;break;
321*cdf0e10cSrcweir 					case 1: maMinTopLeft.Y() = (int)fValue;break;
322*cdf0e10cSrcweir 					case 2: maMaxBottomRight.X() = (int)fValue;break;
323*cdf0e10cSrcweir 					case 3: maMaxBottomRight.Y() = (int)fValue;break;
324*cdf0e10cSrcweir 				}
325*cdf0e10cSrcweir 			}
326*cdf0e10cSrcweir 			pField->Enable( sal_True );
327*cdf0e10cSrcweir 		}
328*cdf0e10cSrcweir 		else
329*cdf0e10cSrcweir         {
330*cdf0e10cSrcweir             mbDragEnable = sal_False;
331*cdf0e10cSrcweir             pField->SetMin( 0 );
332*cdf0e10cSrcweir             switch( i ) {
333*cdf0e10cSrcweir                 case 0:
334*cdf0e10cSrcweir                     maMinTopLeft.X() = 0;
335*cdf0e10cSrcweir                     maTopLeft.X() = 0;
336*cdf0e10cSrcweir                     pField->SetMax( PREVIEW_WIDTH );
337*cdf0e10cSrcweir                     pField->SetValue( 0 );
338*cdf0e10cSrcweir                     break;
339*cdf0e10cSrcweir                 case 1:
340*cdf0e10cSrcweir                     maMinTopLeft.Y() = 0;
341*cdf0e10cSrcweir                     maTopLeft.Y() = 0;
342*cdf0e10cSrcweir                     pField->SetMax( PREVIEW_HEIGHT );
343*cdf0e10cSrcweir                     pField->SetValue( 0 );
344*cdf0e10cSrcweir                     break;
345*cdf0e10cSrcweir                 case 2:
346*cdf0e10cSrcweir                     maMaxBottomRight.X() = PREVIEW_WIDTH;
347*cdf0e10cSrcweir                     maBottomRight.X() = PREVIEW_WIDTH;
348*cdf0e10cSrcweir                     pField->SetMax( PREVIEW_WIDTH );
349*cdf0e10cSrcweir                     pField->SetValue( PREVIEW_WIDTH );
350*cdf0e10cSrcweir                     break;
351*cdf0e10cSrcweir                 case 3:
352*cdf0e10cSrcweir                     maMaxBottomRight.Y() = PREVIEW_HEIGHT;
353*cdf0e10cSrcweir                     maBottomRight.Y() = PREVIEW_HEIGHT;
354*cdf0e10cSrcweir                     pField->SetMax( PREVIEW_HEIGHT );
355*cdf0e10cSrcweir                     pField->SetValue( PREVIEW_HEIGHT );
356*cdf0e10cSrcweir                     break;
357*cdf0e10cSrcweir             }
358*cdf0e10cSrcweir 			pField->Enable( sal_False );
359*cdf0e10cSrcweir         }
360*cdf0e10cSrcweir 	}
361*cdf0e10cSrcweir 	maTopLeft = GetPixelPos( maTopLeft );
362*cdf0e10cSrcweir 	maBottomRight = GetPixelPos( maBottomRight );
363*cdf0e10cSrcweir 	maPreviewRect = Rectangle( maTopLeft,
364*cdf0e10cSrcweir 							   Size( maBottomRight.X() - maTopLeft.X(),
365*cdf0e10cSrcweir 									 maBottomRight.Y() - maTopLeft.Y() )
366*cdf0e10cSrcweir 							   );
367*cdf0e10cSrcweir 	// fill OptionBox
368*cdf0e10cSrcweir 	maOptionBox.Clear();
369*cdf0e10cSrcweir 	SvLBoxEntry* pParentEntry = 0;
370*cdf0e10cSrcweir 	sal_Bool bGroupRejected = sal_False;
371*cdf0e10cSrcweir 	for( i = 1; i < mrSane.CountOptions(); i++ )
372*cdf0e10cSrcweir 	{
373*cdf0e10cSrcweir 		String aOption=mrSane.GetOptionName( i );
374*cdf0e10cSrcweir 		sal_Bool bInsertAdvanced =
375*cdf0e10cSrcweir 			mrSane.GetOptionCap( i ) & SANE_CAP_ADVANCED &&
376*cdf0e10cSrcweir 			! maAdvancedBox.IsChecked() ? sal_False : sal_True;
377*cdf0e10cSrcweir 		if( mrSane.GetOptionType( i ) == SANE_TYPE_GROUP )
378*cdf0e10cSrcweir 		{
379*cdf0e10cSrcweir 			if( bInsertAdvanced )
380*cdf0e10cSrcweir 			{
381*cdf0e10cSrcweir 				aOption = mrSane.GetOptionTitle( i );
382*cdf0e10cSrcweir 				pParentEntry = maOptionBox.InsertEntry( aOption );
383*cdf0e10cSrcweir 				bGroupRejected = sal_False;
384*cdf0e10cSrcweir 			}
385*cdf0e10cSrcweir 			else
386*cdf0e10cSrcweir 				bGroupRejected = sal_True;
387*cdf0e10cSrcweir 		}
388*cdf0e10cSrcweir 		else if( aOption.Len() &&
389*cdf0e10cSrcweir 				 ! ( mrSane.GetOptionCap( i ) &
390*cdf0e10cSrcweir 					 (
391*cdf0e10cSrcweir 						 SANE_CAP_HARD_SELECT |
392*cdf0e10cSrcweir 						 SANE_CAP_INACTIVE
393*cdf0e10cSrcweir 						 ) ) &&
394*cdf0e10cSrcweir 				 bInsertAdvanced && ! bGroupRejected )
395*cdf0e10cSrcweir 		{
396*cdf0e10cSrcweir 			sal_Bool bIsSpecial = sal_False;
397*cdf0e10cSrcweir 			for( size_t n = 0; !bIsSpecial &&
398*cdf0e10cSrcweir 					 n < sizeof(ppSpecialOptions)/sizeof(ppSpecialOptions[0]); n++ )
399*cdf0e10cSrcweir 			{
400*cdf0e10cSrcweir 				if( aOption.EqualsAscii( ppSpecialOptions[n] ) )
401*cdf0e10cSrcweir 					bIsSpecial=sal_True;
402*cdf0e10cSrcweir 			}
403*cdf0e10cSrcweir 			if( ! bIsSpecial )
404*cdf0e10cSrcweir 			{
405*cdf0e10cSrcweir 				if( pParentEntry )
406*cdf0e10cSrcweir 					maOptionBox.InsertEntry( aOption, pParentEntry );
407*cdf0e10cSrcweir 				else
408*cdf0e10cSrcweir 					maOptionBox.InsertEntry( aOption );
409*cdf0e10cSrcweir 			}
410*cdf0e10cSrcweir 		}
411*cdf0e10cSrcweir 	}
412*cdf0e10cSrcweir }
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir IMPL_LINK( SaneDlg, ClickBtnHdl, Button*, pButton )
415*cdf0e10cSrcweir {
416*cdf0e10cSrcweir 	if( mrSane.IsOpen() )
417*cdf0e10cSrcweir 	{
418*cdf0e10cSrcweir 		if( pButton == &maDeviceInfoButton )
419*cdf0e10cSrcweir 		{
420*cdf0e10cSrcweir 			String aString( SaneResId( RID_SANE_DEVICEINFO_TXT ) );
421*cdf0e10cSrcweir 			String aSR( RTL_CONSTASCII_USTRINGPARAM( "%s" ) );
422*cdf0e10cSrcweir 			aString.SearchAndReplace( aSR, Sane::GetName( mrSane.GetDeviceNumber() ) );
423*cdf0e10cSrcweir 			aString.SearchAndReplace( aSR, Sane::GetVendor( mrSane.GetDeviceNumber() ) );
424*cdf0e10cSrcweir 			aString.SearchAndReplace( aSR, Sane::GetModel( mrSane.GetDeviceNumber() ) );
425*cdf0e10cSrcweir 			aString.SearchAndReplace( aSR, Sane::GetType( mrSane.GetDeviceNumber() ) );
426*cdf0e10cSrcweir 			InfoBox aInfoBox( this, aString );
427*cdf0e10cSrcweir 			aInfoBox.Execute();
428*cdf0e10cSrcweir 		}
429*cdf0e10cSrcweir 		else if( pButton == &maPreviewButton )
430*cdf0e10cSrcweir 			AcquirePreview();
431*cdf0e10cSrcweir 		else if( pButton == &maBoolCheckBox )
432*cdf0e10cSrcweir 		{
433*cdf0e10cSrcweir 			mrSane.SetOptionValue( mnCurrentOption,
434*cdf0e10cSrcweir 								   maBoolCheckBox.IsChecked() ?
435*cdf0e10cSrcweir 								   (sal_Bool)sal_True : (sal_Bool)sal_False );
436*cdf0e10cSrcweir 		}
437*cdf0e10cSrcweir 		else if( pButton == &maButtonOption )
438*cdf0e10cSrcweir 		{
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir 			SANE_Value_Type nType = mrSane.GetOptionType( mnCurrentOption );
441*cdf0e10cSrcweir             switch( nType )
442*cdf0e10cSrcweir             {
443*cdf0e10cSrcweir                 case SANE_TYPE_BUTTON:
444*cdf0e10cSrcweir                     mrSane.ActivateButtonOption( mnCurrentOption );
445*cdf0e10cSrcweir                     break;
446*cdf0e10cSrcweir                 case SANE_TYPE_FIXED:
447*cdf0e10cSrcweir                 case SANE_TYPE_INT:
448*cdf0e10cSrcweir                 {
449*cdf0e10cSrcweir 					int nElements = mrSane.GetOptionElements( mnCurrentOption );
450*cdf0e10cSrcweir                     double* x = new double[ nElements ];
451*cdf0e10cSrcweir                     double* y = new double[ nElements ];
452*cdf0e10cSrcweir                     for( int i = 0; i < nElements; i++ )
453*cdf0e10cSrcweir                         x[ i ] = (double)i;
454*cdf0e10cSrcweir                     mrSane.GetOptionValue( mnCurrentOption, y );
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir                     GridWindow aGrid( x, y, nElements, this );
457*cdf0e10cSrcweir                     aGrid.SetText( mrSane.GetOptionName( mnCurrentOption ) );
458*cdf0e10cSrcweir                     aGrid.setBoundings( 0, mfMin, nElements, mfMax );
459*cdf0e10cSrcweir                     if( aGrid.Execute() && aGrid.getNewYValues() )
460*cdf0e10cSrcweir                         mrSane.SetOptionValue( mnCurrentOption, aGrid.getNewYValues() );
461*cdf0e10cSrcweir 
462*cdf0e10cSrcweir                     delete [] x;
463*cdf0e10cSrcweir                     delete [] y;
464*cdf0e10cSrcweir                 }
465*cdf0e10cSrcweir                 break;
466*cdf0e10cSrcweir                 case SANE_TYPE_BOOL:
467*cdf0e10cSrcweir                 case SANE_TYPE_STRING:
468*cdf0e10cSrcweir                 case SANE_TYPE_GROUP:
469*cdf0e10cSrcweir                     break;
470*cdf0e10cSrcweir             }
471*cdf0e10cSrcweir 		}
472*cdf0e10cSrcweir 		else if( pButton == &maAdvancedBox )
473*cdf0e10cSrcweir 		{
474*cdf0e10cSrcweir 			ReloadSaneOptionsHdl( NULL );
475*cdf0e10cSrcweir 		}
476*cdf0e10cSrcweir 	}
477*cdf0e10cSrcweir 	if( pButton == &maOKButton )
478*cdf0e10cSrcweir 	{
479*cdf0e10cSrcweir 		double fRes = (double)maReslBox.GetValue();
480*cdf0e10cSrcweir 		SetAdjustedNumericalValue( "resolution", fRes );
481*cdf0e10cSrcweir 		mrSane.SetReloadOptionsHdl( maOldLink );
482*cdf0e10cSrcweir 		UpdateScanArea( sal_True );
483*cdf0e10cSrcweir 		SaveState();
484*cdf0e10cSrcweir 		EndDialog( mrSane.IsOpen() ? 1 : 0 );
485*cdf0e10cSrcweir 	}
486*cdf0e10cSrcweir 	else if( pButton == &maCancelButton )
487*cdf0e10cSrcweir 	{
488*cdf0e10cSrcweir 		mrSane.SetReloadOptionsHdl( maOldLink );
489*cdf0e10cSrcweir 		mrSane.Close();
490*cdf0e10cSrcweir 		EndDialog( 0 );
491*cdf0e10cSrcweir 	}
492*cdf0e10cSrcweir 	return 0;
493*cdf0e10cSrcweir }
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir IMPL_LINK( SaneDlg, SelectHdl, ListBox*, pListBox )
496*cdf0e10cSrcweir {
497*cdf0e10cSrcweir 	if( pListBox == &maDeviceBox && Sane::IsSane() && Sane::CountDevices() )
498*cdf0e10cSrcweir 	{
499*cdf0e10cSrcweir 		String aNewDevice = maDeviceBox.GetSelectEntry();
500*cdf0e10cSrcweir 		int nNumber;
501*cdf0e10cSrcweir 		if( aNewDevice.Equals( Sane::GetName( nNumber = mrSane.GetDeviceNumber() ) ) )
502*cdf0e10cSrcweir 		{
503*cdf0e10cSrcweir 			mrSane.Close();
504*cdf0e10cSrcweir 			mrSane.Open( nNumber );
505*cdf0e10cSrcweir 			InitFields();
506*cdf0e10cSrcweir 		}
507*cdf0e10cSrcweir 	}
508*cdf0e10cSrcweir 	if( mrSane.IsOpen() )
509*cdf0e10cSrcweir 	{
510*cdf0e10cSrcweir 		if( pListBox == &maQuantumRangeBox )
511*cdf0e10cSrcweir 		{
512*cdf0e10cSrcweir 			ByteString aValue( maQuantumRangeBox.GetSelectEntry(), osl_getThreadTextEncoding() );
513*cdf0e10cSrcweir 			double fValue = atof( aValue.GetBuffer() );
514*cdf0e10cSrcweir 			mrSane.SetOptionValue( mnCurrentOption, fValue, mnCurrentElement );
515*cdf0e10cSrcweir 		}
516*cdf0e10cSrcweir 		else if( pListBox == &maStringRangeBox )
517*cdf0e10cSrcweir 		{
518*cdf0e10cSrcweir 			mrSane.SetOptionValue( mnCurrentOption, maStringRangeBox.GetSelectEntry() );
519*cdf0e10cSrcweir 		}
520*cdf0e10cSrcweir 	}
521*cdf0e10cSrcweir 	return 0;
522*cdf0e10cSrcweir }
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir IMPL_LINK( SaneDlg, OptionsBoxSelectHdl, SvTreeListBox*, pBox )
525*cdf0e10cSrcweir {
526*cdf0e10cSrcweir 	if( pBox == &maOptionBox && Sane::IsSane() )
527*cdf0e10cSrcweir 	{
528*cdf0e10cSrcweir 		String aOption =
529*cdf0e10cSrcweir 			maOptionBox.GetEntryText( maOptionBox.FirstSelected() );
530*cdf0e10cSrcweir 		int nOption = mrSane.GetOptionByName( ByteString( aOption, osl_getThreadTextEncoding() ).GetBuffer() );
531*cdf0e10cSrcweir 		if( nOption != -1 && nOption != mnCurrentOption )
532*cdf0e10cSrcweir 		{
533*cdf0e10cSrcweir 			DisableOption();
534*cdf0e10cSrcweir 			mnCurrentOption = nOption;
535*cdf0e10cSrcweir 			maOptionTitle.SetText( mrSane.GetOptionTitle( mnCurrentOption ) );
536*cdf0e10cSrcweir 			SANE_Value_Type nType = mrSane.GetOptionType( mnCurrentOption );
537*cdf0e10cSrcweir 			SANE_Constraint_Type nConstraint;
538*cdf0e10cSrcweir 			switch( nType )
539*cdf0e10cSrcweir 			{
540*cdf0e10cSrcweir 				case SANE_TYPE_BOOL:	EstablishBoolOption();break;
541*cdf0e10cSrcweir 				case SANE_TYPE_STRING:
542*cdf0e10cSrcweir 					nConstraint = mrSane.GetOptionConstraintType( mnCurrentOption );
543*cdf0e10cSrcweir 					if( nConstraint == SANE_CONSTRAINT_STRING_LIST )
544*cdf0e10cSrcweir 						EstablishStringRange();
545*cdf0e10cSrcweir 					else
546*cdf0e10cSrcweir 						EstablishStringOption();
547*cdf0e10cSrcweir 					break;
548*cdf0e10cSrcweir 				case SANE_TYPE_FIXED:
549*cdf0e10cSrcweir 				case SANE_TYPE_INT:
550*cdf0e10cSrcweir 				{
551*cdf0e10cSrcweir 					nConstraint = mrSane.GetOptionConstraintType( mnCurrentOption );
552*cdf0e10cSrcweir 					int nElements = mrSane.GetOptionElements( mnCurrentOption );
553*cdf0e10cSrcweir 					mnCurrentElement = 0;
554*cdf0e10cSrcweir                     if( nConstraint == SANE_CONSTRAINT_RANGE ||
555*cdf0e10cSrcweir                         nConstraint == SANE_CONSTRAINT_WORD_LIST )
556*cdf0e10cSrcweir                         EstablishQuantumRange();
557*cdf0e10cSrcweir                     else
558*cdf0e10cSrcweir                     {
559*cdf0e10cSrcweir                         mfMin = mfMax = 0.0;
560*cdf0e10cSrcweir                         EstablishNumericOption();
561*cdf0e10cSrcweir                     }
562*cdf0e10cSrcweir 					if( nElements > 1 )
563*cdf0e10cSrcweir 					{
564*cdf0e10cSrcweir 						if( nElements <= 10 )
565*cdf0e10cSrcweir 						{
566*cdf0e10cSrcweir 							maVectorBox.SetValue( 1 );
567*cdf0e10cSrcweir 							maVectorBox.SetMin( 1 );
568*cdf0e10cSrcweir 							maVectorBox.SetMax(
569*cdf0e10cSrcweir 								mrSane.GetOptionElements( mnCurrentOption ) );
570*cdf0e10cSrcweir 							maVectorBox.Show( sal_True );
571*cdf0e10cSrcweir 							maVectorTxt.Show( sal_True );
572*cdf0e10cSrcweir 						}
573*cdf0e10cSrcweir 						else
574*cdf0e10cSrcweir 						{
575*cdf0e10cSrcweir                             DisableOption();
576*cdf0e10cSrcweir                             // bring up dialog only on button click
577*cdf0e10cSrcweir                             EstablishButtonOption();
578*cdf0e10cSrcweir 						}
579*cdf0e10cSrcweir 					}
580*cdf0e10cSrcweir 				}
581*cdf0e10cSrcweir 				break;
582*cdf0e10cSrcweir 				case SANE_TYPE_BUTTON:
583*cdf0e10cSrcweir 					EstablishButtonOption();
584*cdf0e10cSrcweir 					break;
585*cdf0e10cSrcweir 				default: break;
586*cdf0e10cSrcweir 			}
587*cdf0e10cSrcweir 		}
588*cdf0e10cSrcweir 	}
589*cdf0e10cSrcweir 	return 0;
590*cdf0e10cSrcweir }
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir IMPL_LINK( SaneDlg, ModifyHdl, Edit*, pEdit )
593*cdf0e10cSrcweir {
594*cdf0e10cSrcweir 	if( mrSane.IsOpen() )
595*cdf0e10cSrcweir 	{
596*cdf0e10cSrcweir 		if( pEdit == &maStringEdit )
597*cdf0e10cSrcweir 		{
598*cdf0e10cSrcweir 			mrSane.SetOptionValue( mnCurrentOption, maStringEdit.GetText() );
599*cdf0e10cSrcweir 		}
600*cdf0e10cSrcweir 		else if( pEdit == &maReslBox )
601*cdf0e10cSrcweir 		{
602*cdf0e10cSrcweir 			double fRes = (double)maReslBox.GetValue();
603*cdf0e10cSrcweir 			int nOption = mrSane.GetOptionByName( "resolution" );
604*cdf0e10cSrcweir 			if( nOption != -1 )
605*cdf0e10cSrcweir 			{
606*cdf0e10cSrcweir 				double* pDouble = NULL;
607*cdf0e10cSrcweir 				int nValues = mrSane.GetRange( nOption, pDouble );
608*cdf0e10cSrcweir 				if( nValues > 0 )
609*cdf0e10cSrcweir 				{
610*cdf0e10cSrcweir 					int i;
611*cdf0e10cSrcweir 					for( i = 0; i < nValues; i++ )
612*cdf0e10cSrcweir 					{
613*cdf0e10cSrcweir 						if( fRes == pDouble[i] )
614*cdf0e10cSrcweir 							break;
615*cdf0e10cSrcweir 					}
616*cdf0e10cSrcweir 					if( i >= nValues )
617*cdf0e10cSrcweir 						fRes = pDouble[0];
618*cdf0e10cSrcweir 				}
619*cdf0e10cSrcweir 				else if( nValues == 0 )
620*cdf0e10cSrcweir 				{
621*cdf0e10cSrcweir 					if( fRes < pDouble[ 0 ] )
622*cdf0e10cSrcweir 						fRes = pDouble[ 0 ];
623*cdf0e10cSrcweir 					if( fRes > pDouble[ 1 ] )
624*cdf0e10cSrcweir 						fRes = pDouble[ 1 ];
625*cdf0e10cSrcweir 				}
626*cdf0e10cSrcweir 				maReslBox.SetValue( (sal_uLong)fRes );
627*cdf0e10cSrcweir 			}
628*cdf0e10cSrcweir 		}
629*cdf0e10cSrcweir 		else if( pEdit == &maNumericEdit )
630*cdf0e10cSrcweir 		{
631*cdf0e10cSrcweir 			double fValue;
632*cdf0e10cSrcweir 			char pBuf[256];
633*cdf0e10cSrcweir 			ByteString aContents( maNumericEdit.GetText(), osl_getThreadTextEncoding() );
634*cdf0e10cSrcweir 			fValue = atof( aContents.GetBuffer() );
635*cdf0e10cSrcweir 			if( mfMin != mfMax && ( fValue < mfMin || fValue > mfMax ) )
636*cdf0e10cSrcweir 			{
637*cdf0e10cSrcweir 				if( fValue < mfMin )
638*cdf0e10cSrcweir 					fValue = mfMin;
639*cdf0e10cSrcweir 				else if( fValue > mfMax )
640*cdf0e10cSrcweir 				fValue = mfMax;
641*cdf0e10cSrcweir 				sprintf( pBuf, "%g", fValue );
642*cdf0e10cSrcweir 				maNumericEdit.SetText( String( pBuf, osl_getThreadTextEncoding() ) );
643*cdf0e10cSrcweir 			}
644*cdf0e10cSrcweir 			mrSane.SetOptionValue( mnCurrentOption, fValue, mnCurrentElement );
645*cdf0e10cSrcweir 		}
646*cdf0e10cSrcweir 		else if( pEdit == &maVectorBox )
647*cdf0e10cSrcweir 		{
648*cdf0e10cSrcweir 			char pBuf[256];
649*cdf0e10cSrcweir 			mnCurrentElement = maVectorBox.GetValue()-1;
650*cdf0e10cSrcweir 			double fValue;
651*cdf0e10cSrcweir 			mrSane.GetOptionValue( mnCurrentOption, fValue, mnCurrentElement );
652*cdf0e10cSrcweir 			sprintf( pBuf, "%g", fValue );
653*cdf0e10cSrcweir 			String aValue( pBuf, osl_getThreadTextEncoding() );
654*cdf0e10cSrcweir 			maNumericEdit.SetText( aValue );
655*cdf0e10cSrcweir 			maQuantumRangeBox.SelectEntry( aValue );
656*cdf0e10cSrcweir 		}
657*cdf0e10cSrcweir 		else if( pEdit == &maTopField )
658*cdf0e10cSrcweir 		{
659*cdf0e10cSrcweir 			Point aPoint( 0, maTopField.GetValue() );
660*cdf0e10cSrcweir 			aPoint = GetPixelPos( aPoint );
661*cdf0e10cSrcweir 			maTopLeft.Y() = aPoint.Y();
662*cdf0e10cSrcweir 			DrawDrag();
663*cdf0e10cSrcweir 		}
664*cdf0e10cSrcweir 		else if( pEdit == &maLeftField )
665*cdf0e10cSrcweir 		{
666*cdf0e10cSrcweir 			Point aPoint( maLeftField.GetValue(), 0 );
667*cdf0e10cSrcweir 			aPoint = GetPixelPos( aPoint );
668*cdf0e10cSrcweir 			maTopLeft.X() = aPoint.X();
669*cdf0e10cSrcweir 			DrawDrag();
670*cdf0e10cSrcweir 		}
671*cdf0e10cSrcweir 		else if( pEdit == &maBottomField )
672*cdf0e10cSrcweir 		{
673*cdf0e10cSrcweir 			Point aPoint( 0, maBottomField.GetValue() );
674*cdf0e10cSrcweir 			aPoint = GetPixelPos( aPoint );
675*cdf0e10cSrcweir 			maBottomRight.Y() = aPoint.Y();
676*cdf0e10cSrcweir 			DrawDrag();
677*cdf0e10cSrcweir 		}
678*cdf0e10cSrcweir 		else if( pEdit == &maRightField )
679*cdf0e10cSrcweir 		{
680*cdf0e10cSrcweir 			Point aPoint( maRightField.GetValue(), 0 );
681*cdf0e10cSrcweir 			aPoint = GetPixelPos( aPoint );
682*cdf0e10cSrcweir 			maBottomRight.X() = aPoint.X();
683*cdf0e10cSrcweir 			DrawDrag();
684*cdf0e10cSrcweir 		}
685*cdf0e10cSrcweir 	}
686*cdf0e10cSrcweir 	return 0;
687*cdf0e10cSrcweir }
688*cdf0e10cSrcweir 
689*cdf0e10cSrcweir IMPL_LINK( SaneDlg, ReloadSaneOptionsHdl, Sane*, /*pSane*/ )
690*cdf0e10cSrcweir {
691*cdf0e10cSrcweir  	mnCurrentOption = -1;
692*cdf0e10cSrcweir  	mnCurrentElement = 0;
693*cdf0e10cSrcweir  	DisableOption();
694*cdf0e10cSrcweir     // #92024# preserve preview rect, should only be set
695*cdf0e10cSrcweir     // initially or in AcquirePreview
696*cdf0e10cSrcweir     Rectangle aPreviewRect = maPreviewRect;
697*cdf0e10cSrcweir 	InitFields();
698*cdf0e10cSrcweir     maPreviewRect = aPreviewRect;
699*cdf0e10cSrcweir 	Rectangle aDummyRect( Point( 0, 0 ), GetSizePixel() );
700*cdf0e10cSrcweir 	Paint( aDummyRect );
701*cdf0e10cSrcweir 	return 0;
702*cdf0e10cSrcweir }
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir void SaneDlg::AcquirePreview()
705*cdf0e10cSrcweir {
706*cdf0e10cSrcweir 	if( ! mrSane.IsOpen() )
707*cdf0e10cSrcweir 		return;
708*cdf0e10cSrcweir 
709*cdf0e10cSrcweir 	UpdateScanArea( sal_True );
710*cdf0e10cSrcweir 	// set small resolution for preview
711*cdf0e10cSrcweir 	double fResl = (double)maReslBox.GetValue();
712*cdf0e10cSrcweir 	SetAdjustedNumericalValue( "resolution", 30.0 );
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir 	int nOption = mrSane.GetOptionByName( "preview" );
715*cdf0e10cSrcweir 	if( nOption == -1 )
716*cdf0e10cSrcweir 	{
717*cdf0e10cSrcweir 		String aString( SaneResId( RID_SANE_NORESOLUTIONOPTION_TXT ) );
718*cdf0e10cSrcweir 		WarningBox aBox( this, WB_OK_CANCEL | WB_DEF_OK, aString );
719*cdf0e10cSrcweir 		if( aBox.Execute() == RET_CANCEL )
720*cdf0e10cSrcweir 			return;
721*cdf0e10cSrcweir 	}
722*cdf0e10cSrcweir 	else
723*cdf0e10cSrcweir 		mrSane.SetOptionValue( nOption, (sal_Bool)sal_True );
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir 	BitmapTransporter aTransporter;
726*cdf0e10cSrcweir 	if( ! mrSane.Start( aTransporter ) )
727*cdf0e10cSrcweir 	{
728*cdf0e10cSrcweir 		ErrorBox aErrorBox( this, WB_OK | WB_DEF_OK,
729*cdf0e10cSrcweir 							String( SaneResId( RID_SANE_SCANERROR_TXT ) ) );
730*cdf0e10cSrcweir 		aErrorBox.Execute();
731*cdf0e10cSrcweir 	}
732*cdf0e10cSrcweir 	else
733*cdf0e10cSrcweir 	{
734*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
735*cdf0e10cSrcweir 		aTransporter.getStream().Seek( STREAM_SEEK_TO_END );
736*cdf0e10cSrcweir 		fprintf( stderr, "Previewbitmapstream contains %d bytes\n", (int)aTransporter.getStream().Tell() );
737*cdf0e10cSrcweir #endif
738*cdf0e10cSrcweir 		aTransporter.getStream().Seek( STREAM_SEEK_TO_BEGIN );
739*cdf0e10cSrcweir 		maPreviewBitmap.Read( aTransporter.getStream(), sal_True );
740*cdf0e10cSrcweir 	}
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir 	SetAdjustedNumericalValue( "resolution", fResl );
743*cdf0e10cSrcweir 	maReslBox.SetValue( (sal_uLong)fResl );
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir     if( mbDragEnable )
746*cdf0e10cSrcweir         maPreviewRect = Rectangle( maTopLeft,
747*cdf0e10cSrcweir                                    Size( maBottomRight.X() - maTopLeft.X(),
748*cdf0e10cSrcweir                                          maBottomRight.Y() - maTopLeft.Y() )
749*cdf0e10cSrcweir                                    );
750*cdf0e10cSrcweir     else
751*cdf0e10cSrcweir     {
752*cdf0e10cSrcweir         Size aBMSize( maPreviewBitmap.GetSizePixel() );
753*cdf0e10cSrcweir         if( aBMSize.Width() > aBMSize.Height() )
754*cdf0e10cSrcweir         {
755*cdf0e10cSrcweir             int nVHeight = (maBottomRight.X() - maTopLeft.X()) * aBMSize.Height() / aBMSize.Width();
756*cdf0e10cSrcweir             maPreviewRect = Rectangle( Point( maTopLeft.X(), ( maTopLeft.Y() + maBottomRight.Y() )/2 - nVHeight/2 ),
757*cdf0e10cSrcweir                                        Size( maBottomRight.X() - maTopLeft.X(),
758*cdf0e10cSrcweir                                              nVHeight ) );
759*cdf0e10cSrcweir         }
760*cdf0e10cSrcweir         else
761*cdf0e10cSrcweir         {
762*cdf0e10cSrcweir             int nVWidth = (maBottomRight.Y() - maTopLeft.Y()) * aBMSize.Width() / aBMSize.Height();
763*cdf0e10cSrcweir             maPreviewRect = Rectangle( Point( ( maTopLeft.X() + maBottomRight.X() )/2 - nVWidth/2, maTopLeft.Y() ),
764*cdf0e10cSrcweir                                        Size( nVWidth,
765*cdf0e10cSrcweir                                              maBottomRight.Y() - maTopLeft.Y() ) );
766*cdf0e10cSrcweir         }
767*cdf0e10cSrcweir     }
768*cdf0e10cSrcweir 
769*cdf0e10cSrcweir 	Paint( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
770*cdf0e10cSrcweir }
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir void SaneDlg::Paint( const Rectangle& rRect )
773*cdf0e10cSrcweir {
774*cdf0e10cSrcweir 	SetMapMode( maMapMode );
775*cdf0e10cSrcweir 	SetFillColor( Color( COL_WHITE ) );
776*cdf0e10cSrcweir 	SetLineColor( Color( COL_WHITE ) );
777*cdf0e10cSrcweir 	DrawRect( Rectangle( Point( PREVIEW_UPPER_LEFT, PREVIEW_UPPER_TOP ),
778*cdf0e10cSrcweir 						 Size( PREVIEW_WIDTH, PREVIEW_HEIGHT ) ) );
779*cdf0e10cSrcweir 	SetMapMode( MapMode( MAP_PIXEL ) );
780*cdf0e10cSrcweir 	// check for sane values
781*cdf0e10cSrcweir 	DrawBitmap( maPreviewRect.TopLeft(), maPreviewRect.GetSize(),
782*cdf0e10cSrcweir 				maPreviewBitmap );
783*cdf0e10cSrcweir 
784*cdf0e10cSrcweir 	mbDragDrawn = sal_False;
785*cdf0e10cSrcweir 	DrawDrag();
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir 	ModalDialog::Paint( rRect );
788*cdf0e10cSrcweir }
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir void SaneDlg::DisableOption()
791*cdf0e10cSrcweir {
792*cdf0e10cSrcweir 	maBoolCheckBox.Show( sal_False );
793*cdf0e10cSrcweir 	maStringEdit.Show( sal_False );
794*cdf0e10cSrcweir 	maNumericEdit.Show( sal_False );
795*cdf0e10cSrcweir 	maQuantumRangeBox.Show( sal_False );
796*cdf0e10cSrcweir 	maStringRangeBox.Show( sal_False );
797*cdf0e10cSrcweir 	maButtonOption.Show( sal_False );
798*cdf0e10cSrcweir 	maVectorBox.Show( sal_False );
799*cdf0e10cSrcweir 	maVectorTxt.Show( sal_False );
800*cdf0e10cSrcweir 	maOptionDescTxt.Show( sal_False );
801*cdf0e10cSrcweir }
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir void SaneDlg::EstablishBoolOption()
804*cdf0e10cSrcweir {
805*cdf0e10cSrcweir 	sal_Bool bSuccess, bValue;
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir 	bSuccess = mrSane.GetOptionValue( mnCurrentOption, bValue );
808*cdf0e10cSrcweir 	if( bSuccess )
809*cdf0e10cSrcweir 	{
810*cdf0e10cSrcweir 		maOptionDescTxt.SetText( mrSane.GetOptionName( mnCurrentOption ) );
811*cdf0e10cSrcweir 		maOptionDescTxt.Show( sal_True );
812*cdf0e10cSrcweir 		maBoolCheckBox.Check( bValue );
813*cdf0e10cSrcweir 		maBoolCheckBox.Show( sal_True );
814*cdf0e10cSrcweir 	}
815*cdf0e10cSrcweir }
816*cdf0e10cSrcweir 
817*cdf0e10cSrcweir void SaneDlg::EstablishStringOption()
818*cdf0e10cSrcweir {
819*cdf0e10cSrcweir 	sal_Bool bSuccess;
820*cdf0e10cSrcweir 	ByteString aValue;
821*cdf0e10cSrcweir 
822*cdf0e10cSrcweir 	bSuccess = mrSane.GetOptionValue( mnCurrentOption, aValue );
823*cdf0e10cSrcweir 	if( bSuccess )
824*cdf0e10cSrcweir 	{
825*cdf0e10cSrcweir 		maOptionDescTxt.SetText( mrSane.GetOptionName( mnCurrentOption ) );
826*cdf0e10cSrcweir 		maOptionDescTxt.Show( sal_True );
827*cdf0e10cSrcweir 		maStringEdit.SetText( String( aValue, osl_getThreadTextEncoding() ) );
828*cdf0e10cSrcweir 		maStringEdit.Show( sal_True );
829*cdf0e10cSrcweir 	}
830*cdf0e10cSrcweir }
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir void SaneDlg::EstablishStringRange()
833*cdf0e10cSrcweir {
834*cdf0e10cSrcweir 	const char** ppStrings = mrSane.GetStringConstraint( mnCurrentOption );
835*cdf0e10cSrcweir 	maStringRangeBox.Clear();
836*cdf0e10cSrcweir 	for( int i = 0; ppStrings[i] != 0; i++ )
837*cdf0e10cSrcweir 		maStringRangeBox.InsertEntry( String( ppStrings[i], osl_getThreadTextEncoding() ) );
838*cdf0e10cSrcweir 	ByteString aValue;
839*cdf0e10cSrcweir 	mrSane.GetOptionValue( mnCurrentOption, aValue );
840*cdf0e10cSrcweir 	maStringRangeBox.SelectEntry( String( aValue, osl_getThreadTextEncoding() ) );
841*cdf0e10cSrcweir 	maStringRangeBox.Show( sal_True );
842*cdf0e10cSrcweir 	maOptionDescTxt.SetText( mrSane.GetOptionName( mnCurrentOption ) );
843*cdf0e10cSrcweir 	maOptionDescTxt.Show( sal_True );
844*cdf0e10cSrcweir }
845*cdf0e10cSrcweir 
846*cdf0e10cSrcweir void SaneDlg::EstablishQuantumRange()
847*cdf0e10cSrcweir {
848*cdf0e10cSrcweir 	if( mpRange )
849*cdf0e10cSrcweir 	{
850*cdf0e10cSrcweir 		delete [] mpRange;
851*cdf0e10cSrcweir 		mpRange = 0;
852*cdf0e10cSrcweir 	}
853*cdf0e10cSrcweir 	int nValues = mrSane.GetRange( mnCurrentOption, mpRange );
854*cdf0e10cSrcweir 	if( nValues == 0 )
855*cdf0e10cSrcweir 	{
856*cdf0e10cSrcweir 		mfMin = mpRange[ 0 ];
857*cdf0e10cSrcweir 		mfMax = mpRange[ 1 ];
858*cdf0e10cSrcweir 		delete [] mpRange;
859*cdf0e10cSrcweir 		mpRange = 0;
860*cdf0e10cSrcweir 		EstablishNumericOption();
861*cdf0e10cSrcweir 	}
862*cdf0e10cSrcweir 	else if( nValues > 0 )
863*cdf0e10cSrcweir 	{
864*cdf0e10cSrcweir 		char pBuf[ 256 ];
865*cdf0e10cSrcweir 		maQuantumRangeBox.Clear();
866*cdf0e10cSrcweir 		mfMin = mpRange[ 0 ];
867*cdf0e10cSrcweir 		mfMax = mpRange[ nValues-1 ];
868*cdf0e10cSrcweir 		for( int i = 0; i < nValues; i++ )
869*cdf0e10cSrcweir 		{
870*cdf0e10cSrcweir 			sprintf( pBuf, "%g", mpRange[ i ] );
871*cdf0e10cSrcweir 			maQuantumRangeBox.InsertEntry( String( pBuf, osl_getThreadTextEncoding() ) );
872*cdf0e10cSrcweir 		}
873*cdf0e10cSrcweir 		double fValue;
874*cdf0e10cSrcweir 		if( mrSane.GetOptionValue( mnCurrentOption, fValue, mnCurrentElement ) )
875*cdf0e10cSrcweir 		{
876*cdf0e10cSrcweir 			sprintf( pBuf, "%g", fValue );
877*cdf0e10cSrcweir 			maQuantumRangeBox.SelectEntry( String( pBuf, osl_getThreadTextEncoding() ) );
878*cdf0e10cSrcweir 		}
879*cdf0e10cSrcweir 		maQuantumRangeBox.Show( sal_True );
880*cdf0e10cSrcweir 		String aText( mrSane.GetOptionName( mnCurrentOption ) );
881*cdf0e10cSrcweir 		aText += ' ';
882*cdf0e10cSrcweir 		aText += mrSane.GetOptionUnitName( mnCurrentOption );
883*cdf0e10cSrcweir 		maOptionDescTxt.SetText( aText );
884*cdf0e10cSrcweir 		maOptionDescTxt.Show( sal_True );
885*cdf0e10cSrcweir 	}
886*cdf0e10cSrcweir }
887*cdf0e10cSrcweir 
888*cdf0e10cSrcweir void SaneDlg::EstablishNumericOption()
889*cdf0e10cSrcweir {
890*cdf0e10cSrcweir 	sal_Bool bSuccess;
891*cdf0e10cSrcweir 	double fValue;
892*cdf0e10cSrcweir 
893*cdf0e10cSrcweir 	bSuccess = mrSane.GetOptionValue( mnCurrentOption, fValue );
894*cdf0e10cSrcweir 	if( ! bSuccess )
895*cdf0e10cSrcweir 		return;
896*cdf0e10cSrcweir 
897*cdf0e10cSrcweir 	char pBuf[256];
898*cdf0e10cSrcweir 	String aText( mrSane.GetOptionName( mnCurrentOption ) );
899*cdf0e10cSrcweir 	aText += ' ';
900*cdf0e10cSrcweir 	aText += mrSane.GetOptionUnitName( mnCurrentOption );
901*cdf0e10cSrcweir 	if( mfMin != mfMax )
902*cdf0e10cSrcweir 	{
903*cdf0e10cSrcweir 		sprintf( pBuf, " < %g ; %g >", mfMin, mfMax );
904*cdf0e10cSrcweir 		aText += String( pBuf, osl_getThreadTextEncoding() );
905*cdf0e10cSrcweir 	}
906*cdf0e10cSrcweir 	maOptionDescTxt.SetText( aText );
907*cdf0e10cSrcweir 	maOptionDescTxt.Show( sal_True );
908*cdf0e10cSrcweir 	sprintf( pBuf, "%g", fValue );
909*cdf0e10cSrcweir 	maNumericEdit.SetText( String( pBuf, osl_getThreadTextEncoding() ) );
910*cdf0e10cSrcweir 	maNumericEdit.Show( sal_True );
911*cdf0e10cSrcweir }
912*cdf0e10cSrcweir 
913*cdf0e10cSrcweir void SaneDlg::EstablishButtonOption()
914*cdf0e10cSrcweir {
915*cdf0e10cSrcweir 	maOptionDescTxt.SetText( mrSane.GetOptionName( mnCurrentOption ) );
916*cdf0e10cSrcweir 	maOptionDescTxt.Show( sal_True );
917*cdf0e10cSrcweir 	maButtonOption.Show( sal_True );
918*cdf0e10cSrcweir }
919*cdf0e10cSrcweir 
920*cdf0e10cSrcweir #define RECT_SIZE_PIX 7
921*cdf0e10cSrcweir 
922*cdf0e10cSrcweir void SaneDlg::MouseMove( const MouseEvent& rMEvt )
923*cdf0e10cSrcweir {
924*cdf0e10cSrcweir 	if( mbIsDragging )
925*cdf0e10cSrcweir 	{
926*cdf0e10cSrcweir 		Point aMousePos = rMEvt.GetPosPixel();
927*cdf0e10cSrcweir 		// move into valid area
928*cdf0e10cSrcweir 		Point aLogicPos = GetLogicPos( aMousePos );
929*cdf0e10cSrcweir 		aMousePos = GetPixelPos( aLogicPos );
930*cdf0e10cSrcweir 		switch( meDragDirection )
931*cdf0e10cSrcweir 		{
932*cdf0e10cSrcweir 			case TopLeft:		maTopLeft = aMousePos; break;
933*cdf0e10cSrcweir 			case Top:			maTopLeft.Y() = aMousePos.Y(); break;
934*cdf0e10cSrcweir 			case TopRight:
935*cdf0e10cSrcweir 				maTopLeft.Y() = aMousePos.Y();
936*cdf0e10cSrcweir 				maBottomRight.X() = aMousePos.X();
937*cdf0e10cSrcweir 				break;
938*cdf0e10cSrcweir 			case Right:			maBottomRight.X() = aMousePos.X(); break;
939*cdf0e10cSrcweir 			case BottomRight:	maBottomRight = aMousePos; break;
940*cdf0e10cSrcweir 			case Bottom:		maBottomRight.Y() = aMousePos.Y(); break;
941*cdf0e10cSrcweir 			case BottomLeft:
942*cdf0e10cSrcweir 				maTopLeft.X() = aMousePos.X();
943*cdf0e10cSrcweir 				maBottomRight.Y() = aMousePos.Y();
944*cdf0e10cSrcweir 				break;
945*cdf0e10cSrcweir 			case Left:			maTopLeft.X() = aMousePos.X(); break;
946*cdf0e10cSrcweir 			default: break;
947*cdf0e10cSrcweir 		}
948*cdf0e10cSrcweir 		int nSwap;
949*cdf0e10cSrcweir 		if( maTopLeft.X() > maBottomRight.X() )
950*cdf0e10cSrcweir 		{
951*cdf0e10cSrcweir 			nSwap = maTopLeft.X();
952*cdf0e10cSrcweir 			maTopLeft.X() = maBottomRight.X();
953*cdf0e10cSrcweir 			maBottomRight.X() = nSwap;
954*cdf0e10cSrcweir 		}
955*cdf0e10cSrcweir 		if( maTopLeft.Y() > maBottomRight.Y() )
956*cdf0e10cSrcweir 		{
957*cdf0e10cSrcweir 			nSwap = maTopLeft.Y();
958*cdf0e10cSrcweir 			maTopLeft.Y() = maBottomRight.Y();
959*cdf0e10cSrcweir 			maBottomRight.Y() = nSwap;
960*cdf0e10cSrcweir 		}
961*cdf0e10cSrcweir 		DrawDrag();
962*cdf0e10cSrcweir 		UpdateScanArea( sal_False );
963*cdf0e10cSrcweir 	}
964*cdf0e10cSrcweir 	ModalDialog::MouseMove( rMEvt );
965*cdf0e10cSrcweir }
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir void SaneDlg::MouseButtonDown( const MouseEvent& rMEvt )
968*cdf0e10cSrcweir {
969*cdf0e10cSrcweir 	Point aMousePixel = rMEvt.GetPosPixel();
970*cdf0e10cSrcweir 
971*cdf0e10cSrcweir 	if( ! mbIsDragging  && mbDragEnable )
972*cdf0e10cSrcweir 	{
973*cdf0e10cSrcweir 		int nMiddleX = ( maBottomRight.X() - maTopLeft.X() ) / 2 - RECT_SIZE_PIX/2 + maTopLeft.X();
974*cdf0e10cSrcweir 		int nMiddleY = ( maBottomRight.Y() - maTopLeft.Y() ) / 2 - RECT_SIZE_PIX/2 + maTopLeft.Y();
975*cdf0e10cSrcweir 		if( aMousePixel.Y() >= maTopLeft.Y() &&
976*cdf0e10cSrcweir 			aMousePixel.Y() < maTopLeft.Y() + RECT_SIZE_PIX )
977*cdf0e10cSrcweir 		{
978*cdf0e10cSrcweir 			if( aMousePixel.X() >= maTopLeft.X() &&
979*cdf0e10cSrcweir 				aMousePixel.X() < maTopLeft.X() + RECT_SIZE_PIX )
980*cdf0e10cSrcweir 			{
981*cdf0e10cSrcweir 				meDragDirection = TopLeft;
982*cdf0e10cSrcweir 				aMousePixel = maTopLeft;
983*cdf0e10cSrcweir 				mbIsDragging = sal_True;
984*cdf0e10cSrcweir 			}
985*cdf0e10cSrcweir 			else if( aMousePixel.X() >= nMiddleX &&
986*cdf0e10cSrcweir 					 aMousePixel.X() < nMiddleX + RECT_SIZE_PIX )
987*cdf0e10cSrcweir 			{
988*cdf0e10cSrcweir 				meDragDirection = Top;
989*cdf0e10cSrcweir 				aMousePixel.Y() = maTopLeft.Y();
990*cdf0e10cSrcweir 				mbIsDragging = sal_True;
991*cdf0e10cSrcweir 			}
992*cdf0e10cSrcweir 			else if( aMousePixel.X() > maBottomRight.X() - RECT_SIZE_PIX &&
993*cdf0e10cSrcweir 					 aMousePixel.X() <= maBottomRight.X() )
994*cdf0e10cSrcweir 			{
995*cdf0e10cSrcweir 				meDragDirection = TopRight;
996*cdf0e10cSrcweir 				aMousePixel = Point( maBottomRight.X(), maTopLeft.Y() );
997*cdf0e10cSrcweir 				mbIsDragging = sal_True;
998*cdf0e10cSrcweir 			}
999*cdf0e10cSrcweir 		}
1000*cdf0e10cSrcweir 		else if( aMousePixel.Y() >= nMiddleY &&
1001*cdf0e10cSrcweir 				 aMousePixel.Y() < nMiddleY + RECT_SIZE_PIX )
1002*cdf0e10cSrcweir 		{
1003*cdf0e10cSrcweir 			if( aMousePixel.X() >= maTopLeft.X() &&
1004*cdf0e10cSrcweir 				aMousePixel.X() < maTopLeft.X() + RECT_SIZE_PIX )
1005*cdf0e10cSrcweir 			{
1006*cdf0e10cSrcweir 				meDragDirection = Left;
1007*cdf0e10cSrcweir 				aMousePixel.X() = maTopLeft.X();
1008*cdf0e10cSrcweir 				mbIsDragging = sal_True;
1009*cdf0e10cSrcweir 			}
1010*cdf0e10cSrcweir 			else if( aMousePixel.X() > maBottomRight.X() - RECT_SIZE_PIX &&
1011*cdf0e10cSrcweir 					 aMousePixel.X() <= maBottomRight.X() )
1012*cdf0e10cSrcweir 			{
1013*cdf0e10cSrcweir 				meDragDirection = Right;
1014*cdf0e10cSrcweir 				aMousePixel.X() = maBottomRight.X();
1015*cdf0e10cSrcweir 				mbIsDragging = sal_True;
1016*cdf0e10cSrcweir 			}
1017*cdf0e10cSrcweir 		}
1018*cdf0e10cSrcweir 		else if( aMousePixel.Y() <= maBottomRight.Y() &&
1019*cdf0e10cSrcweir 				 aMousePixel.Y() > maBottomRight.Y() - RECT_SIZE_PIX )
1020*cdf0e10cSrcweir 		{
1021*cdf0e10cSrcweir 			if( aMousePixel.X() >= maTopLeft.X() &&
1022*cdf0e10cSrcweir 				aMousePixel.X() < maTopLeft.X() + RECT_SIZE_PIX )
1023*cdf0e10cSrcweir 			{
1024*cdf0e10cSrcweir 				meDragDirection = BottomLeft;
1025*cdf0e10cSrcweir 				aMousePixel = Point( maTopLeft.X(), maBottomRight.Y() );
1026*cdf0e10cSrcweir 				mbIsDragging = sal_True;
1027*cdf0e10cSrcweir 			}
1028*cdf0e10cSrcweir 			else if( aMousePixel.X() >= nMiddleX &&
1029*cdf0e10cSrcweir 					 aMousePixel.X() < nMiddleX + RECT_SIZE_PIX )
1030*cdf0e10cSrcweir 			{
1031*cdf0e10cSrcweir 				meDragDirection = Bottom;
1032*cdf0e10cSrcweir 				aMousePixel.Y() = maBottomRight.Y();
1033*cdf0e10cSrcweir 				mbIsDragging = sal_True;
1034*cdf0e10cSrcweir 			}
1035*cdf0e10cSrcweir 			else if( aMousePixel.X() > maBottomRight.X() - RECT_SIZE_PIX &&
1036*cdf0e10cSrcweir 					 aMousePixel.X() <= maBottomRight.X() )
1037*cdf0e10cSrcweir 			{
1038*cdf0e10cSrcweir 				meDragDirection = BottomRight;
1039*cdf0e10cSrcweir 				aMousePixel = maBottomRight;
1040*cdf0e10cSrcweir 				mbIsDragging = sal_True;
1041*cdf0e10cSrcweir 			}
1042*cdf0e10cSrcweir 		}
1043*cdf0e10cSrcweir 	}
1044*cdf0e10cSrcweir 	if( mbIsDragging )
1045*cdf0e10cSrcweir 	{
1046*cdf0e10cSrcweir 		SetPointerPosPixel( aMousePixel );
1047*cdf0e10cSrcweir 		DrawDrag();
1048*cdf0e10cSrcweir 	}
1049*cdf0e10cSrcweir 	ModalDialog::MouseButtonDown( rMEvt );
1050*cdf0e10cSrcweir }
1051*cdf0e10cSrcweir 
1052*cdf0e10cSrcweir void SaneDlg::MouseButtonUp( const MouseEvent& rMEvt )
1053*cdf0e10cSrcweir {
1054*cdf0e10cSrcweir 	if( mbIsDragging )
1055*cdf0e10cSrcweir 	{
1056*cdf0e10cSrcweir 		UpdateScanArea( sal_True );
1057*cdf0e10cSrcweir 	}
1058*cdf0e10cSrcweir 	mbIsDragging = sal_False;
1059*cdf0e10cSrcweir 
1060*cdf0e10cSrcweir 	ModalDialog::MouseButtonUp( rMEvt );
1061*cdf0e10cSrcweir }
1062*cdf0e10cSrcweir 
1063*cdf0e10cSrcweir void SaneDlg::DrawRectangles( Point& rUL, Point& rBR )
1064*cdf0e10cSrcweir {
1065*cdf0e10cSrcweir 	int nMiddleX, nMiddleY;
1066*cdf0e10cSrcweir 	Point aBL, aUR;
1067*cdf0e10cSrcweir 
1068*cdf0e10cSrcweir 	aUR = Point( rBR.X(), rUL.Y() );
1069*cdf0e10cSrcweir 	aBL = Point( rUL.X(), rBR.Y() );
1070*cdf0e10cSrcweir 	nMiddleX = ( rBR.X() - rUL.X() ) / 2 + rUL.X();
1071*cdf0e10cSrcweir 	nMiddleY = ( rBR.Y() - rUL.Y() ) / 2 + rUL.Y();
1072*cdf0e10cSrcweir 
1073*cdf0e10cSrcweir 	DrawLine( rUL, aBL );
1074*cdf0e10cSrcweir 	DrawLine( aBL, rBR );
1075*cdf0e10cSrcweir 	DrawLine( rBR, aUR );
1076*cdf0e10cSrcweir 	DrawLine( aUR, rUL );
1077*cdf0e10cSrcweir 	DrawRect( Rectangle( rUL, Size( RECT_SIZE_PIX,RECT_SIZE_PIX ) ) );
1078*cdf0e10cSrcweir 	DrawRect( Rectangle( aBL, Size( RECT_SIZE_PIX, -RECT_SIZE_PIX ) ) );
1079*cdf0e10cSrcweir 	DrawRect( Rectangle( rBR, Size( -RECT_SIZE_PIX, -RECT_SIZE_PIX ) ) );
1080*cdf0e10cSrcweir 	DrawRect( Rectangle( aUR, Size( -RECT_SIZE_PIX, RECT_SIZE_PIX ) ) );
1081*cdf0e10cSrcweir 	DrawRect( Rectangle( Point( nMiddleX - RECT_SIZE_PIX/2, rUL.Y() ), Size( RECT_SIZE_PIX, RECT_SIZE_PIX ) ) );
1082*cdf0e10cSrcweir 	DrawRect( Rectangle( Point( nMiddleX - RECT_SIZE_PIX/2, rBR.Y() ), Size( RECT_SIZE_PIX, -RECT_SIZE_PIX ) ) );
1083*cdf0e10cSrcweir 	DrawRect( Rectangle( Point( rUL.X(), nMiddleY - RECT_SIZE_PIX/2 ), Size( RECT_SIZE_PIX, RECT_SIZE_PIX ) ) );
1084*cdf0e10cSrcweir 	DrawRect( Rectangle( Point( rBR.X(), nMiddleY - RECT_SIZE_PIX/2 ), Size( -RECT_SIZE_PIX, RECT_SIZE_PIX ) ) );
1085*cdf0e10cSrcweir }
1086*cdf0e10cSrcweir 
1087*cdf0e10cSrcweir void SaneDlg::DrawDrag()
1088*cdf0e10cSrcweir {
1089*cdf0e10cSrcweir 	static Point aLastUL, aLastBR;
1090*cdf0e10cSrcweir 
1091*cdf0e10cSrcweir     if( ! mbDragEnable )
1092*cdf0e10cSrcweir         return;
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir 	RasterOp eROP = GetRasterOp();
1095*cdf0e10cSrcweir 	SetRasterOp( ROP_INVERT );
1096*cdf0e10cSrcweir 	SetMapMode( MapMode( MAP_PIXEL ) );
1097*cdf0e10cSrcweir 
1098*cdf0e10cSrcweir 	if( mbDragDrawn )
1099*cdf0e10cSrcweir 		DrawRectangles( aLastUL, aLastBR );
1100*cdf0e10cSrcweir 
1101*cdf0e10cSrcweir 	aLastUL = maTopLeft;
1102*cdf0e10cSrcweir 	aLastBR = maBottomRight;
1103*cdf0e10cSrcweir 	DrawRectangles( maTopLeft, maBottomRight );
1104*cdf0e10cSrcweir 
1105*cdf0e10cSrcweir 	mbDragDrawn = sal_True;
1106*cdf0e10cSrcweir 	SetRasterOp( eROP );
1107*cdf0e10cSrcweir 	SetMapMode( maMapMode );
1108*cdf0e10cSrcweir }
1109*cdf0e10cSrcweir 
1110*cdf0e10cSrcweir Point SaneDlg::GetPixelPos( const Point& rIn )
1111*cdf0e10cSrcweir {
1112*cdf0e10cSrcweir 	Point aConvert(
1113*cdf0e10cSrcweir 		( ( rIn.X() * PREVIEW_WIDTH ) /
1114*cdf0e10cSrcweir 		  ( maMaxBottomRight.X() - maMinTopLeft.X() ) )
1115*cdf0e10cSrcweir 		+ PREVIEW_UPPER_LEFT,
1116*cdf0e10cSrcweir 		( ( rIn.Y() * PREVIEW_HEIGHT )
1117*cdf0e10cSrcweir 		  / ( maMaxBottomRight.Y() - maMinTopLeft.Y() ) )
1118*cdf0e10cSrcweir 		+ PREVIEW_UPPER_TOP );
1119*cdf0e10cSrcweir 
1120*cdf0e10cSrcweir 	return LogicToPixel( aConvert, maMapMode );
1121*cdf0e10cSrcweir }
1122*cdf0e10cSrcweir 
1123*cdf0e10cSrcweir Point SaneDlg::GetLogicPos( const Point& rIn )
1124*cdf0e10cSrcweir {
1125*cdf0e10cSrcweir 	Point aConvert = PixelToLogic( rIn, maMapMode );
1126*cdf0e10cSrcweir 	aConvert.X() -= PREVIEW_UPPER_LEFT;
1127*cdf0e10cSrcweir 	aConvert.Y() -= PREVIEW_UPPER_TOP;
1128*cdf0e10cSrcweir 	if( aConvert.X() < 0 )
1129*cdf0e10cSrcweir 		aConvert.X() = 0;
1130*cdf0e10cSrcweir 	if( aConvert.X() >= PREVIEW_WIDTH )
1131*cdf0e10cSrcweir 		aConvert.X() = PREVIEW_WIDTH-1;
1132*cdf0e10cSrcweir 	if( aConvert.Y() < 0 )
1133*cdf0e10cSrcweir 		aConvert.Y() = 0;
1134*cdf0e10cSrcweir 	if( aConvert.Y() >= PREVIEW_HEIGHT )
1135*cdf0e10cSrcweir 		aConvert.Y() = PREVIEW_HEIGHT-1;
1136*cdf0e10cSrcweir 
1137*cdf0e10cSrcweir 	aConvert.X() *= ( maMaxBottomRight.X() - maMinTopLeft.X() );
1138*cdf0e10cSrcweir 	aConvert.X() /= PREVIEW_WIDTH;
1139*cdf0e10cSrcweir 	aConvert.Y() *= ( maMaxBottomRight.Y() - maMinTopLeft.Y() );
1140*cdf0e10cSrcweir 	aConvert.Y() /= PREVIEW_HEIGHT;
1141*cdf0e10cSrcweir 	return aConvert;
1142*cdf0e10cSrcweir }
1143*cdf0e10cSrcweir 
1144*cdf0e10cSrcweir void SaneDlg::UpdateScanArea( sal_Bool bSend )
1145*cdf0e10cSrcweir {
1146*cdf0e10cSrcweir     if( ! mbDragEnable )
1147*cdf0e10cSrcweir         return;
1148*cdf0e10cSrcweir 
1149*cdf0e10cSrcweir 	Point aUL = GetLogicPos( maTopLeft );
1150*cdf0e10cSrcweir 	Point aBR = GetLogicPos( maBottomRight );
1151*cdf0e10cSrcweir 
1152*cdf0e10cSrcweir 	maLeftField.SetValue( aUL.X() );
1153*cdf0e10cSrcweir 	maTopField.SetValue( aUL.Y() );
1154*cdf0e10cSrcweir 	maRightField.SetValue( aBR.X() );
1155*cdf0e10cSrcweir 	maBottomField.SetValue( aBR.Y() );
1156*cdf0e10cSrcweir 
1157*cdf0e10cSrcweir 	if( ! bSend )
1158*cdf0e10cSrcweir 		return;
1159*cdf0e10cSrcweir 
1160*cdf0e10cSrcweir 	if( mrSane.IsOpen() )
1161*cdf0e10cSrcweir 	{
1162*cdf0e10cSrcweir 		SetAdjustedNumericalValue( "tl-x", (double)aUL.X() );
1163*cdf0e10cSrcweir 		SetAdjustedNumericalValue( "tl-y", (double)aUL.Y() );
1164*cdf0e10cSrcweir 		SetAdjustedNumericalValue( "br-x", (double)aBR.X() );
1165*cdf0e10cSrcweir 		SetAdjustedNumericalValue( "br-y", (double)aBR.Y() );
1166*cdf0e10cSrcweir 	}
1167*cdf0e10cSrcweir }
1168*cdf0e10cSrcweir 
1169*cdf0e10cSrcweir sal_Bool SaneDlg::LoadState()
1170*cdf0e10cSrcweir {
1171*cdf0e10cSrcweir #ifdef USE_SAVE_STATE
1172*cdf0e10cSrcweir 	int i;
1173*cdf0e10cSrcweir 
1174*cdf0e10cSrcweir 	if( ! Sane::IsSane() )
1175*cdf0e10cSrcweir 		return sal_False;
1176*cdf0e10cSrcweir 
1177*cdf0e10cSrcweir 	const char* pEnv = getenv("HOME");
1178*cdf0e10cSrcweir 	String aFileName( pEnv ? pEnv : "", osl_getThreadTextEncoding() );
1179*cdf0e10cSrcweir 	aFileName += String( RTL_CONSTASCII_USTRINGPARAM( "/.so_sane_state" ) );
1180*cdf0e10cSrcweir 	Config aConfig( aFileName );
1181*cdf0e10cSrcweir 	if( ! aConfig.HasGroup( "SANE" ) )
1182*cdf0e10cSrcweir 		return sal_False;
1183*cdf0e10cSrcweir 
1184*cdf0e10cSrcweir 	aConfig.SetGroup( "SANE" );
1185*cdf0e10cSrcweir 	ByteString aString = aConfig.ReadKey( "SO_LastSaneDevice" );
1186*cdf0e10cSrcweir 	for( i = 0; i < Sane::CountDevices() && ! aString.Equals( ByteString( Sane::GetName( i ), osl_getThreadTextEncoding() ) ); i++ ) ;
1187*cdf0e10cSrcweir 	if( i == Sane::CountDevices() )
1188*cdf0e10cSrcweir 		return sal_False;
1189*cdf0e10cSrcweir 
1190*cdf0e10cSrcweir 	mrSane.Close();
1191*cdf0e10cSrcweir 	mrSane.Open( aString.GetBuffer() );
1192*cdf0e10cSrcweir 
1193*cdf0e10cSrcweir 	DisableOption();
1194*cdf0e10cSrcweir 	InitFields();
1195*cdf0e10cSrcweir 
1196*cdf0e10cSrcweir 	if( mrSane.IsOpen() )
1197*cdf0e10cSrcweir 	{
1198*cdf0e10cSrcweir 		int iMax = aConfig.GetKeyCount();
1199*cdf0e10cSrcweir 		for( i = 0; i < iMax; i++ )
1200*cdf0e10cSrcweir 		{
1201*cdf0e10cSrcweir 			aString = aConfig.GetKeyName( i );
1202*cdf0e10cSrcweir 			ByteString aValue = aConfig.ReadKey( i );
1203*cdf0e10cSrcweir 			int nOption = mrSane.GetOptionByName( aString.GetBuffer() );
1204*cdf0e10cSrcweir 			if( nOption != -1 )
1205*cdf0e10cSrcweir 			{
1206*cdf0e10cSrcweir 				if( aValue.CompareTo( "BOOL=", 5 ) == COMPARE_EQUAL )
1207*cdf0e10cSrcweir 				{
1208*cdf0e10cSrcweir 					aValue.Erase( 0, 5 );
1209*cdf0e10cSrcweir 					sal_Bool aBOOL = (sal_Bool)aValue.ToInt32();
1210*cdf0e10cSrcweir 					mrSane.SetOptionValue( nOption, aBOOL );
1211*cdf0e10cSrcweir 				}
1212*cdf0e10cSrcweir 				else if( aValue.CompareTo( "STRING=", 7 ) == COMPARE_EQUAL )
1213*cdf0e10cSrcweir 				{
1214*cdf0e10cSrcweir 					aValue.Erase( 0, 7 );
1215*cdf0e10cSrcweir 					mrSane.SetOptionValue( nOption, String( aValue, osl_getThreadTextEncoding() ) );
1216*cdf0e10cSrcweir 				}
1217*cdf0e10cSrcweir 				else if( aValue.CompareTo( "NUMERIC=", 8 ) == COMPARE_EQUAL )
1218*cdf0e10cSrcweir 				{
1219*cdf0e10cSrcweir 					aValue.Erase( 0, 8 );
1220*cdf0e10cSrcweir 					int nMax = aValue.GetTokenCount( ':' );
1221*cdf0e10cSrcweir 					double fValue=0.0;
1222*cdf0e10cSrcweir 					for( int n = 0; n < nMax ; n++ )
1223*cdf0e10cSrcweir 					{
1224*cdf0e10cSrcweir 						ByteString aSub = aValue.GetToken( n, ':' );
1225*cdf0e10cSrcweir 						sscanf( aSub.GetBuffer(), "%lg", &fValue );
1226*cdf0e10cSrcweir 						SetAdjustedNumericalValue( aString.GetBuffer(), fValue, n );
1227*cdf0e10cSrcweir 					}
1228*cdf0e10cSrcweir 				}
1229*cdf0e10cSrcweir 			}
1230*cdf0e10cSrcweir 		}
1231*cdf0e10cSrcweir 	}
1232*cdf0e10cSrcweir 
1233*cdf0e10cSrcweir 	DisableOption();
1234*cdf0e10cSrcweir 	InitFields();
1235*cdf0e10cSrcweir 
1236*cdf0e10cSrcweir 	return sal_True;
1237*cdf0e10cSrcweir #else
1238*cdf0e10cSrcweir 	return sal_False;
1239*cdf0e10cSrcweir #endif
1240*cdf0e10cSrcweir }
1241*cdf0e10cSrcweir 
1242*cdf0e10cSrcweir void SaneDlg::SaveState()
1243*cdf0e10cSrcweir {
1244*cdf0e10cSrcweir #ifdef USE_SAVE_STATE
1245*cdf0e10cSrcweir 	if( ! Sane::IsSane() )
1246*cdf0e10cSrcweir 		return;
1247*cdf0e10cSrcweir 
1248*cdf0e10cSrcweir 	const char* pEnv = getenv( "HOME" );
1249*cdf0e10cSrcweir 	String aFileName( pEnv ? pEnv : "", osl_getThreadTextEncoding() );
1250*cdf0e10cSrcweir 	aFileName.AppendAscii( "/.so_sane_state" );
1251*cdf0e10cSrcweir 
1252*cdf0e10cSrcweir 	Config aConfig( aFileName );
1253*cdf0e10cSrcweir 	aConfig.DeleteGroup( "SANE" );
1254*cdf0e10cSrcweir 	aConfig.SetGroup( "SANE" );
1255*cdf0e10cSrcweir 	aConfig.WriteKey( "SO_LastSANEDevice", ByteString( maDeviceBox.GetSelectEntry(), RTL_TEXTENCODING_UTF8 ) );
1256*cdf0e10cSrcweir 
1257*cdf0e10cSrcweir #ifdef SAVE_ALL_STATES
1258*cdf0e10cSrcweir 	for( int i = 1; i < mrSane.CountOptions(); i++ )
1259*cdf0e10cSrcweir 	{
1260*cdf0e10cSrcweir 		String aOption=mrSane.GetOptionName( i );
1261*cdf0e10cSrcweir 		SANE_Value_Type nType = mrSane.GetOptionType( i );
1262*cdf0e10cSrcweir 		switch( nType )
1263*cdf0e10cSrcweir 		{
1264*cdf0e10cSrcweir 			case SANE_TYPE_BOOL:
1265*cdf0e10cSrcweir 			{
1266*cdf0e10cSrcweir 				sal_Bool bValue;
1267*cdf0e10cSrcweir 				if( mrSane.GetOptionValue( i, bValue ) )
1268*cdf0e10cSrcweir 				{
1269*cdf0e10cSrcweir 					ByteString aString( "BOOL=" );
1270*cdf0e10cSrcweir 					aString += (sal_uLong)bValue;
1271*cdf0e10cSrcweir 					aConfig.WriteKey( aOption, aString );
1272*cdf0e10cSrcweir 				}
1273*cdf0e10cSrcweir 			}
1274*cdf0e10cSrcweir 			break;
1275*cdf0e10cSrcweir 			case SANE_TYPE_STRING:
1276*cdf0e10cSrcweir 			{
1277*cdf0e10cSrcweir 				String aString( "STRING=" );
1278*cdf0e10cSrcweir 				String aValue;
1279*cdf0e10cSrcweir 				if( mrSane.GetOptionValue( i, aValue ) )
1280*cdf0e10cSrcweir 				{
1281*cdf0e10cSrcweir 					aString += aValue;
1282*cdf0e10cSrcweir 					aConfig.WriteKey( aOption, aString );
1283*cdf0e10cSrcweir 				}
1284*cdf0e10cSrcweir 			}
1285*cdf0e10cSrcweir 			break;
1286*cdf0e10cSrcweir 			case SANE_TYPE_FIXED:
1287*cdf0e10cSrcweir 			case SANE_TYPE_INT:
1288*cdf0e10cSrcweir 			{
1289*cdf0e10cSrcweir 				String aString( "NUMERIC=" );
1290*cdf0e10cSrcweir 				double fValue;
1291*cdf0e10cSrcweir 				char buf[256];
1292*cdf0e10cSrcweir 				for( int n = 0; n < mrSane.GetOptionElements( i ); n++ )
1293*cdf0e10cSrcweir 				{
1294*cdf0e10cSrcweir 					if( ! mrSane.GetOptionValue( i, fValue, n ) )
1295*cdf0e10cSrcweir 						break;
1296*cdf0e10cSrcweir 					if( n > 0 )
1297*cdf0e10cSrcweir 						aString += ":";
1298*cdf0e10cSrcweir 					sprintf( buf, "%lg", fValue );
1299*cdf0e10cSrcweir 					aString += buf;
1300*cdf0e10cSrcweir 				}
1301*cdf0e10cSrcweir 				if( n >= mrSane.GetOptionElements( i ) )
1302*cdf0e10cSrcweir 					aConfig.WriteKey( aOption, aString );
1303*cdf0e10cSrcweir 			}
1304*cdf0e10cSrcweir 			break;
1305*cdf0e10cSrcweir 			default:
1306*cdf0e10cSrcweir 				break;
1307*cdf0e10cSrcweir 		}
1308*cdf0e10cSrcweir  	}
1309*cdf0e10cSrcweir #else
1310*cdf0e10cSrcweir 	static char const* pSaveOptions[] = {
1311*cdf0e10cSrcweir 		"resolution",
1312*cdf0e10cSrcweir 		"tl-x",
1313*cdf0e10cSrcweir 		"tl-y",
1314*cdf0e10cSrcweir 		"br-x",
1315*cdf0e10cSrcweir 		"br-y"
1316*cdf0e10cSrcweir 	};
1317*cdf0e10cSrcweir 	for( size_t i = 0;
1318*cdf0e10cSrcweir 		 i < (sizeof(pSaveOptions)/sizeof(pSaveOptions[0]));
1319*cdf0e10cSrcweir 		 i++ )
1320*cdf0e10cSrcweir 	{
1321*cdf0e10cSrcweir 		ByteString aOption = pSaveOptions[i];
1322*cdf0e10cSrcweir 		int nOption = mrSane.GetOptionByName( pSaveOptions[i] );
1323*cdf0e10cSrcweir 		if( nOption > -1 )
1324*cdf0e10cSrcweir 		{
1325*cdf0e10cSrcweir 			SANE_Value_Type nType = mrSane.GetOptionType( nOption );
1326*cdf0e10cSrcweir 			switch( nType )
1327*cdf0e10cSrcweir 			{
1328*cdf0e10cSrcweir 				case SANE_TYPE_BOOL:
1329*cdf0e10cSrcweir 				{
1330*cdf0e10cSrcweir 					sal_Bool bValue;
1331*cdf0e10cSrcweir 					if( mrSane.GetOptionValue( nOption, bValue ) )
1332*cdf0e10cSrcweir 					{
1333*cdf0e10cSrcweir 						ByteString aString( "BOOL=" );
1334*cdf0e10cSrcweir 						aString += ByteString::CreateFromInt32(bValue);
1335*cdf0e10cSrcweir 						aConfig.WriteKey( aOption, aString );
1336*cdf0e10cSrcweir 					}
1337*cdf0e10cSrcweir 				}
1338*cdf0e10cSrcweir 				break;
1339*cdf0e10cSrcweir 				case SANE_TYPE_STRING:
1340*cdf0e10cSrcweir 				{
1341*cdf0e10cSrcweir 					ByteString aString( "STRING=" );
1342*cdf0e10cSrcweir 					ByteString aValue;
1343*cdf0e10cSrcweir 					if( mrSane.GetOptionValue( nOption, aValue ) )
1344*cdf0e10cSrcweir 					{
1345*cdf0e10cSrcweir 						aString += aValue;
1346*cdf0e10cSrcweir 						aConfig.WriteKey( aOption, aString );
1347*cdf0e10cSrcweir 					}
1348*cdf0e10cSrcweir 				}
1349*cdf0e10cSrcweir 				break;
1350*cdf0e10cSrcweir 				case SANE_TYPE_FIXED:
1351*cdf0e10cSrcweir 				case SANE_TYPE_INT:
1352*cdf0e10cSrcweir 				{
1353*cdf0e10cSrcweir 					ByteString aString( "NUMERIC=" );
1354*cdf0e10cSrcweir 					double fValue;
1355*cdf0e10cSrcweir 					char buf[256];
1356*cdf0e10cSrcweir 					int n;
1357*cdf0e10cSrcweir 
1358*cdf0e10cSrcweir 					for( n = 0; n < mrSane.GetOptionElements( nOption ); n++ )
1359*cdf0e10cSrcweir 					{
1360*cdf0e10cSrcweir 						if( ! mrSane.GetOptionValue( nOption, fValue, n ) )
1361*cdf0e10cSrcweir 							break;
1362*cdf0e10cSrcweir 						if( n > 0 )
1363*cdf0e10cSrcweir 							aString += ":";
1364*cdf0e10cSrcweir 						sprintf( buf, "%lg", fValue );
1365*cdf0e10cSrcweir 						aString += buf;
1366*cdf0e10cSrcweir 					}
1367*cdf0e10cSrcweir 					if( n >= mrSane.GetOptionElements( nOption ) )
1368*cdf0e10cSrcweir 						aConfig.WriteKey( aOption, aString );
1369*cdf0e10cSrcweir 				}
1370*cdf0e10cSrcweir 				break;
1371*cdf0e10cSrcweir 				default:
1372*cdf0e10cSrcweir 					break;
1373*cdf0e10cSrcweir 			}
1374*cdf0e10cSrcweir 		}
1375*cdf0e10cSrcweir 	}
1376*cdf0e10cSrcweir #endif
1377*cdf0e10cSrcweir #endif
1378*cdf0e10cSrcweir }
1379*cdf0e10cSrcweir 
1380*cdf0e10cSrcweir sal_Bool SaneDlg::SetAdjustedNumericalValue(
1381*cdf0e10cSrcweir 	const char* pOption,
1382*cdf0e10cSrcweir 	double fValue,
1383*cdf0e10cSrcweir 	int nElement )
1384*cdf0e10cSrcweir {
1385*cdf0e10cSrcweir 	int nOption;
1386*cdf0e10cSrcweir 	if( ! Sane::IsSane() || ! mrSane.IsOpen() || ( nOption = mrSane.GetOptionByName( pOption ) ) == -1 )
1387*cdf0e10cSrcweir 		return sal_False;
1388*cdf0e10cSrcweir 
1389*cdf0e10cSrcweir 	if( nElement < 0 || nElement >= mrSane.GetOptionElements( nOption ) )
1390*cdf0e10cSrcweir 		return sal_False;
1391*cdf0e10cSrcweir 
1392*cdf0e10cSrcweir 	double* pValues = NULL;
1393*cdf0e10cSrcweir 	int nValues;
1394*cdf0e10cSrcweir 	if( ( nValues = mrSane.GetRange( nOption, pValues ) ) < 0 )
1395*cdf0e10cSrcweir 		return sal_False;
1396*cdf0e10cSrcweir 
1397*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1398*cdf0e10cSrcweir 	fprintf( stderr, "SaneDlg::SetAdjustedNumericalValue( \"%s\", %lg ) ",
1399*cdf0e10cSrcweir 			 pOption, fValue );
1400*cdf0e10cSrcweir #endif
1401*cdf0e10cSrcweir 
1402*cdf0e10cSrcweir 	if( nValues )
1403*cdf0e10cSrcweir 	{
1404*cdf0e10cSrcweir 		int nNearest = 0;
1405*cdf0e10cSrcweir 		double fNearest = 1e6;
1406*cdf0e10cSrcweir 		for( int i = 0; i < nValues; i++ )
1407*cdf0e10cSrcweir 		{
1408*cdf0e10cSrcweir 			if( fabs( fValue - pValues[ i ] ) < fNearest )
1409*cdf0e10cSrcweir 			{
1410*cdf0e10cSrcweir 				fNearest = fabs( fValue - pValues[ i ] );
1411*cdf0e10cSrcweir 				nNearest = i;
1412*cdf0e10cSrcweir 			}
1413*cdf0e10cSrcweir 		}
1414*cdf0e10cSrcweir 		fValue = pValues[ nNearest ];
1415*cdf0e10cSrcweir 	}
1416*cdf0e10cSrcweir 	else
1417*cdf0e10cSrcweir 	{
1418*cdf0e10cSrcweir 		if( fValue < pValues[0] )
1419*cdf0e10cSrcweir 			fValue = pValues[0];
1420*cdf0e10cSrcweir 		if( fValue > pValues[1] )
1421*cdf0e10cSrcweir 			fValue = pValues[1];
1422*cdf0e10cSrcweir 	}
1423*cdf0e10cSrcweir 	delete [] pValues;
1424*cdf0e10cSrcweir 	mrSane.SetOptionValue( nOption, fValue, nElement );
1425*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1426*cdf0e10cSrcweir 	fprintf( stderr, "yields %lg\n", fValue );
1427*cdf0e10cSrcweir #endif
1428*cdf0e10cSrcweir 
1429*cdf0e10cSrcweir 
1430*cdf0e10cSrcweir 	return sal_True;
1431*cdf0e10cSrcweir }
1432