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