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