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 :
21 : #include <stdio.h>
22 : #include <stdlib.h>
23 : #include <tools/config.hxx>
24 :
25 : #include <vcl/msgbox.hxx>
26 : #include <sanedlg.hxx>
27 : #include <sanedlg.hrc>
28 : #include <grid.hxx>
29 : #include <math.h>
30 : #include <sal/macros.h>
31 : #include <rtl/strbuf.hxx>
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 : Bitmap( SaneResId( RID_SCAN_BITMAP_PLUS ) ),
114 : 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 : String( SaneResId( RID_SANE_NOSANELIB_TXT ) ) );
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 : 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 : 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( sal_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 0 : if( pDouble )
236 0 : delete [] pDouble;
237 : }
238 : else
239 0 : maReslBox.Enable( sal_False );
240 : }
241 : }
242 : else
243 0 : maReslBox.Enable( sal_False );
244 :
245 : // set scan area
246 0 : for( i = 0; i < 4; i++ )
247 : {
248 0 : char const *pOptionName = NULL;
249 0 : MetricField* pField = NULL;
250 0 : switch( i )
251 : {
252 : case 0:
253 0 : pOptionName = "tl-x";
254 0 : pField = &maLeftField;
255 0 : break;
256 : case 1:
257 0 : pOptionName = "tl-y";
258 0 : pField = &maTopField;
259 0 : break;
260 : case 2:
261 0 : pOptionName = "br-x";
262 0 : pField = &maRightField;
263 0 : break;
264 : case 3:
265 0 : pOptionName = "br-y";
266 0 : pField = &maBottomField;
267 : }
268 0 : nOption = pOptionName ? mrSane.GetOptionByName( pOptionName ) : -1;
269 0 : bSuccess = sal_False;
270 0 : if( nOption != -1 )
271 : {
272 0 : bSuccess = mrSane.GetOptionValue( nOption, fValue, 0 );
273 0 : if( bSuccess )
274 : {
275 0 : if( mrSane.GetOptionUnit( nOption ) == SANE_UNIT_MM )
276 : {
277 0 : pField->SetUnit( FUNIT_MM );
278 0 : pField->SetValue( (int)fValue, FUNIT_MM );
279 : }
280 : else // SANE_UNIT_PIXEL
281 : {
282 0 : pField->SetValue( (int)fValue, FUNIT_CUSTOM );
283 0 : pField->SetCustomUnitText(rtl::OUString("Pixel"));
284 : }
285 0 : switch( i ) {
286 0 : case 0: maTopLeft.X() = (int)fValue;break;
287 0 : case 1: maTopLeft.Y() = (int)fValue;break;
288 0 : case 2: maBottomRight.X() = (int)fValue;break;
289 0 : case 3: maBottomRight.Y() = (int)fValue;break;
290 : }
291 : }
292 0 : double *pDouble = NULL;
293 0 : nValue = mrSane.GetRange( nOption, pDouble );
294 0 : if( nValue > -1 )
295 : {
296 0 : if( pDouble )
297 : {
298 0 : pField->SetMin( (long)pDouble[0] );
299 0 : if( nValue )
300 0 : pField->SetMax( (long)pDouble[ nValue-1 ] );
301 : else
302 0 : pField->SetMax( (long)pDouble[ 1 ] );
303 0 : delete [] pDouble;
304 : }
305 0 : switch( i ) {
306 0 : case 0: maMinTopLeft.X() = pField->GetMin();break;
307 0 : case 1: maMinTopLeft.Y() = pField->GetMin();break;
308 0 : case 2: maMaxBottomRight.X() = pField->GetMax();break;
309 0 : case 3: maMaxBottomRight.Y() = pField->GetMax();break;
310 : }
311 : }
312 : else
313 : {
314 0 : switch( i ) {
315 0 : case 0: maMinTopLeft.X() = (int)fValue;break;
316 0 : case 1: maMinTopLeft.Y() = (int)fValue;break;
317 0 : case 2: maMaxBottomRight.X() = (int)fValue;break;
318 0 : case 3: maMaxBottomRight.Y() = (int)fValue;break;
319 : }
320 : }
321 0 : pField->Enable( sal_True );
322 : }
323 : else
324 : {
325 0 : mbDragEnable = sal_False;
326 0 : pField->SetMin( 0 );
327 0 : switch( i ) {
328 : case 0:
329 0 : maMinTopLeft.X() = 0;
330 0 : maTopLeft.X() = 0;
331 0 : pField->SetMax( PREVIEW_WIDTH );
332 0 : pField->SetValue( 0 );
333 0 : break;
334 : case 1:
335 0 : maMinTopLeft.Y() = 0;
336 0 : maTopLeft.Y() = 0;
337 0 : pField->SetMax( PREVIEW_HEIGHT );
338 0 : pField->SetValue( 0 );
339 0 : break;
340 : case 2:
341 0 : maMaxBottomRight.X() = PREVIEW_WIDTH;
342 0 : maBottomRight.X() = PREVIEW_WIDTH;
343 0 : pField->SetMax( PREVIEW_WIDTH );
344 0 : pField->SetValue( PREVIEW_WIDTH );
345 0 : break;
346 : case 3:
347 0 : maMaxBottomRight.Y() = PREVIEW_HEIGHT;
348 0 : maBottomRight.Y() = PREVIEW_HEIGHT;
349 0 : pField->SetMax( PREVIEW_HEIGHT );
350 0 : pField->SetValue( PREVIEW_HEIGHT );
351 0 : break;
352 : }
353 0 : pField->Enable( sal_False );
354 : }
355 : }
356 0 : maTopLeft = GetPixelPos( maTopLeft );
357 0 : maBottomRight = GetPixelPos( maBottomRight );
358 : maPreviewRect = Rectangle( maTopLeft,
359 0 : Size( maBottomRight.X() - maTopLeft.X(),
360 0 : maBottomRight.Y() - maTopLeft.Y() )
361 0 : );
362 : // fill OptionBox
363 0 : maOptionBox.Clear();
364 0 : SvTreeListEntry* pParentEntry = 0;
365 0 : sal_Bool bGroupRejected = sal_False;
366 0 : for( i = 1; i < mrSane.CountOptions(); i++ )
367 : {
368 0 : String aOption=mrSane.GetOptionName( i );
369 : sal_Bool bInsertAdvanced =
370 0 : mrSane.GetOptionCap( i ) & SANE_CAP_ADVANCED &&
371 0 : ! maAdvancedBox.IsChecked() ? sal_False : sal_True;
372 0 : if( mrSane.GetOptionType( i ) == SANE_TYPE_GROUP )
373 : {
374 0 : if( bInsertAdvanced )
375 : {
376 0 : aOption = mrSane.GetOptionTitle( i );
377 0 : pParentEntry = maOptionBox.InsertEntry( aOption );
378 0 : bGroupRejected = sal_False;
379 : }
380 : else
381 0 : bGroupRejected = sal_True;
382 : }
383 0 : else if( aOption.Len() &&
384 0 : ! ( mrSane.GetOptionCap( i ) &
385 : (
386 : SANE_CAP_HARD_SELECT |
387 : SANE_CAP_INACTIVE
388 0 : ) ) &&
389 : bInsertAdvanced && ! bGroupRejected )
390 : {
391 0 : sal_Bool bIsSpecial = sal_False;
392 0 : for( size_t n = 0; !bIsSpecial &&
393 : n < SAL_N_ELEMENTS(ppSpecialOptions); n++ )
394 : {
395 0 : if( aOption.EqualsAscii( ppSpecialOptions[n] ) )
396 0 : bIsSpecial=sal_True;
397 : }
398 0 : if( ! bIsSpecial )
399 : {
400 0 : if( pParentEntry )
401 0 : maOptionBox.InsertEntry( aOption, pParentEntry );
402 : else
403 0 : maOptionBox.InsertEntry( aOption );
404 : }
405 : }
406 0 : }
407 : }
408 :
409 0 : IMPL_LINK( SaneDlg, ClickBtnHdl, Button*, pButton )
410 : {
411 0 : if( mrSane.IsOpen() )
412 : {
413 0 : if( pButton == &maDeviceInfoButton )
414 : {
415 0 : String aString( SaneResId( RID_SANE_DEVICEINFO_TXT ) );
416 0 : String aSR( RTL_CONSTASCII_USTRINGPARAM( "%s" ) );
417 0 : aString.SearchAndReplace( aSR, Sane::GetName( mrSane.GetDeviceNumber() ) );
418 0 : aString.SearchAndReplace( aSR, Sane::GetVendor( mrSane.GetDeviceNumber() ) );
419 0 : aString.SearchAndReplace( aSR, Sane::GetModel( mrSane.GetDeviceNumber() ) );
420 0 : aString.SearchAndReplace( aSR, Sane::GetType( mrSane.GetDeviceNumber() ) );
421 0 : InfoBox aInfoBox( this, aString );
422 0 : aInfoBox.Execute();
423 : }
424 0 : else if( pButton == &maPreviewButton )
425 0 : AcquirePreview();
426 0 : else if( pButton == &maBoolCheckBox )
427 : {
428 : mrSane.SetOptionValue( mnCurrentOption,
429 0 : maBoolCheckBox.IsChecked() ?
430 0 : (sal_Bool)sal_True : (sal_Bool)sal_False );
431 : }
432 0 : else if( pButton == &maButtonOption )
433 : {
434 :
435 0 : SANE_Value_Type nType = mrSane.GetOptionType( mnCurrentOption );
436 0 : switch( nType )
437 : {
438 : case SANE_TYPE_BUTTON:
439 0 : mrSane.ActivateButtonOption( mnCurrentOption );
440 0 : break;
441 : case SANE_TYPE_FIXED:
442 : case SANE_TYPE_INT:
443 : {
444 0 : int nElements = mrSane.GetOptionElements( mnCurrentOption );
445 0 : double* x = new double[ nElements ];
446 0 : double* y = new double[ nElements ];
447 0 : for( int i = 0; i < nElements; i++ )
448 0 : x[ i ] = (double)i;
449 0 : mrSane.GetOptionValue( mnCurrentOption, y );
450 :
451 0 : GridWindow aGrid( x, y, nElements, this );
452 0 : aGrid.SetText( mrSane.GetOptionName( mnCurrentOption ) );
453 0 : aGrid.setBoundings( 0, mfMin, nElements, mfMax );
454 0 : if( aGrid.Execute() && aGrid.getNewYValues() )
455 0 : mrSane.SetOptionValue( mnCurrentOption, aGrid.getNewYValues() );
456 :
457 0 : delete [] x;
458 0 : delete [] y;
459 : }
460 0 : break;
461 : case SANE_TYPE_BOOL:
462 : case SANE_TYPE_STRING:
463 : case SANE_TYPE_GROUP:
464 0 : break;
465 : }
466 : }
467 0 : else if( pButton == &maAdvancedBox )
468 : {
469 0 : ReloadSaneOptionsHdl( NULL );
470 : }
471 : }
472 0 : if( pButton == &maOKButton || pButton == &maScanButton )
473 : {
474 0 : double fRes = (double)maReslBox.GetValue();
475 0 : SetAdjustedNumericalValue( "resolution", fRes );
476 0 : UpdateScanArea( sal_True );
477 0 : SaveState();
478 0 : EndDialog( mrSane.IsOpen() ? 1 : 0 );
479 0 : doScan = (pButton == &maScanButton);
480 : }
481 0 : else if( pButton == &maCancelButton )
482 : {
483 0 : mrSane.Close();
484 0 : EndDialog( 0 );
485 : }
486 0 : return 0;
487 : }
488 :
489 0 : IMPL_LINK( SaneDlg, SelectHdl, ListBox*, pListBox )
490 : {
491 0 : if( pListBox == &maDeviceBox && Sane::IsSane() && Sane::CountDevices() )
492 : {
493 0 : String aNewDevice = maDeviceBox.GetSelectEntry();
494 : int nNumber;
495 0 : if( aNewDevice.Equals( Sane::GetName( nNumber = mrSane.GetDeviceNumber() ) ) )
496 : {
497 0 : mrSane.Close();
498 0 : mrSane.Open( nNumber );
499 0 : InitFields();
500 0 : }
501 : }
502 0 : if( mrSane.IsOpen() )
503 : {
504 0 : if( pListBox == &maQuantumRangeBox )
505 : {
506 : rtl::OString aValue(rtl::OUStringToOString(maQuantumRangeBox.GetSelectEntry(),
507 0 : osl_getThreadTextEncoding()));
508 0 : double fValue = atof(aValue.getStr());
509 0 : mrSane.SetOptionValue( mnCurrentOption, fValue, mnCurrentElement );
510 : }
511 0 : else if( pListBox == &maStringRangeBox )
512 : {
513 0 : mrSane.SetOptionValue( mnCurrentOption, maStringRangeBox.GetSelectEntry() );
514 : }
515 : }
516 0 : return 0;
517 : }
518 :
519 0 : IMPL_LINK( SaneDlg, OptionsBoxSelectHdl, SvTreeListBox*, pBox )
520 : {
521 0 : if( pBox == &maOptionBox && Sane::IsSane() )
522 : {
523 : String aOption =
524 0 : maOptionBox.GetEntryText( maOptionBox.FirstSelected() );
525 : int nOption = mrSane.GetOptionByName(rtl::OUStringToOString(aOption,
526 0 : osl_getThreadTextEncoding()).getStr());
527 0 : if( nOption != -1 && nOption != mnCurrentOption )
528 : {
529 0 : DisableOption();
530 0 : mnCurrentOption = nOption;
531 0 : maOptionTitle.SetText( mrSane.GetOptionTitle( mnCurrentOption ) );
532 0 : SANE_Value_Type nType = mrSane.GetOptionType( mnCurrentOption );
533 : SANE_Constraint_Type nConstraint;
534 0 : switch( nType )
535 : {
536 0 : case SANE_TYPE_BOOL: EstablishBoolOption();break;
537 : case SANE_TYPE_STRING:
538 0 : nConstraint = mrSane.GetOptionConstraintType( mnCurrentOption );
539 0 : if( nConstraint == SANE_CONSTRAINT_STRING_LIST )
540 0 : EstablishStringRange();
541 : else
542 0 : EstablishStringOption();
543 0 : break;
544 : case SANE_TYPE_FIXED:
545 : case SANE_TYPE_INT:
546 : {
547 0 : nConstraint = mrSane.GetOptionConstraintType( mnCurrentOption );
548 0 : int nElements = mrSane.GetOptionElements( mnCurrentOption );
549 0 : mnCurrentElement = 0;
550 0 : if( nConstraint == SANE_CONSTRAINT_RANGE ||
551 : nConstraint == SANE_CONSTRAINT_WORD_LIST )
552 0 : EstablishQuantumRange();
553 : else
554 : {
555 0 : mfMin = mfMax = 0.0;
556 0 : EstablishNumericOption();
557 : }
558 0 : if( nElements > 1 )
559 : {
560 0 : if( nElements <= 10 )
561 : {
562 0 : maVectorBox.SetValue( 1 );
563 0 : maVectorBox.SetMin( 1 );
564 : maVectorBox.SetMax(
565 0 : mrSane.GetOptionElements( mnCurrentOption ) );
566 0 : maVectorBox.Show( sal_True );
567 0 : maVectorTxt.Show( sal_True );
568 : }
569 : else
570 : {
571 0 : DisableOption();
572 : // bring up dialog only on button click
573 0 : EstablishButtonOption();
574 : }
575 : }
576 : }
577 0 : break;
578 : case SANE_TYPE_BUTTON:
579 0 : EstablishButtonOption();
580 0 : break;
581 0 : default: break;
582 : }
583 0 : }
584 : }
585 0 : return 0;
586 : }
587 :
588 0 : IMPL_LINK( SaneDlg, ModifyHdl, Edit*, pEdit )
589 : {
590 0 : if( mrSane.IsOpen() )
591 : {
592 0 : if( pEdit == &maStringEdit )
593 : {
594 0 : mrSane.SetOptionValue( mnCurrentOption, maStringEdit.GetText() );
595 : }
596 0 : else if( pEdit == &maReslBox )
597 : {
598 0 : double fRes = (double)maReslBox.GetValue();
599 0 : int nOption = mrSane.GetOptionByName( "resolution" );
600 0 : if( nOption != -1 )
601 : {
602 0 : double* pDouble = NULL;
603 0 : int nValues = mrSane.GetRange( nOption, pDouble );
604 0 : if( nValues > 0 )
605 : {
606 : int i;
607 0 : for( i = 0; i < nValues; i++ )
608 : {
609 0 : if( fRes == pDouble[i] )
610 0 : break;
611 : }
612 0 : if( i >= nValues )
613 0 : fRes = pDouble[0];
614 : }
615 0 : else if( nValues == 0 )
616 : {
617 0 : if( fRes < pDouble[ 0 ] )
618 0 : fRes = pDouble[ 0 ];
619 0 : if( fRes > pDouble[ 1 ] )
620 0 : fRes = pDouble[ 1 ];
621 : }
622 0 : maReslBox.SetValue( (sal_uLong)fRes );
623 : }
624 : }
625 0 : else if( pEdit == &maNumericEdit )
626 : {
627 : double fValue;
628 : char pBuf[256];
629 : rtl::OString aContents(rtl::OUStringToOString(maNumericEdit.GetText(),
630 0 : osl_getThreadTextEncoding()));
631 0 : fValue = atof(aContents.getStr());
632 0 : if( mfMin != mfMax && ( fValue < mfMin || fValue > mfMax ) )
633 : {
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 : 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 : maPreviewBitmap.Read( aTransporter.getStream(), sal_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 : rtl::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(rtl::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 : rtl::OString aValue;
838 0 : mrSane.GetOptionValue( mnCurrentOption, aValue );
839 0 : maStringRangeBox.SelectEntry(rtl::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 : 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 : 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 : rtl::OString aString = aConfig.ReadKey( "SO_LastSaneDevice" );
1184 0 : for( i = 0; i < Sane::CountDevices() && !aString.equals(rtl::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 : rtl::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,rtl::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 : rtl::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 : 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 : String aFileName( pEnv ? pEnv : "", osl_getThreadTextEncoding() );
1247 0 : aFileName.AppendAscii( "/.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 : rtl::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 : rtl::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 : rtl::OStringBuffer aString(RTL_CONSTASCII_STRINGPARAM(
1277 0 : "BOOL="));
1278 0 : aString.append(static_cast<sal_Int32>(bValue));
1279 0 : aConfig.WriteKey(aOption, aString.makeStringAndClear());
1280 : }
1281 : }
1282 0 : break;
1283 : case SANE_TYPE_STRING:
1284 : {
1285 0 : rtl::OString aValue;
1286 0 : if( mrSane.GetOptionValue( nOption, aValue ) )
1287 : {
1288 0 : rtl::OStringBuffer aString(RTL_CONSTASCII_STRINGPARAM("STRING="));
1289 0 : aString.append(aValue);
1290 0 : aConfig.WriteKey( aOption, aString.makeStringAndClear() );
1291 0 : }
1292 : }
1293 0 : break;
1294 : case SANE_TYPE_FIXED:
1295 : case SANE_TYPE_INT:
1296 : {
1297 0 : rtl::OStringBuffer aString(RTL_CONSTASCII_STRINGPARAM("NUMERIC="));
1298 : double fValue;
1299 : char buf[256];
1300 : int n;
1301 :
1302 0 : for( n = 0; n < mrSane.GetOptionElements( nOption ); n++ )
1303 : {
1304 0 : if( ! mrSane.GetOptionValue( nOption, fValue, n ) )
1305 0 : break;
1306 0 : if( n > 0 )
1307 0 : aString.append(':');
1308 0 : sprintf( buf, "%lg", fValue );
1309 0 : aString.append(buf);
1310 : }
1311 0 : if( n >= mrSane.GetOptionElements( nOption ) )
1312 0 : aConfig.WriteKey( aOption, aString.makeStringAndClear() );
1313 : }
1314 0 : break;
1315 : default:
1316 0 : break;
1317 : }
1318 : }
1319 0 : }
1320 : }
1321 :
1322 0 : sal_Bool SaneDlg::SetAdjustedNumericalValue(
1323 : const char* pOption,
1324 : double fValue,
1325 : int nElement )
1326 : {
1327 : int nOption;
1328 0 : if( ! Sane::IsSane() || ! mrSane.IsOpen() || ( nOption = mrSane.GetOptionByName( pOption ) ) == -1 )
1329 0 : return sal_False;
1330 :
1331 0 : if( nElement < 0 || nElement >= mrSane.GetOptionElements( nOption ) )
1332 0 : return sal_False;
1333 :
1334 0 : double* pValues = NULL;
1335 : int nValues;
1336 0 : if( ( nValues = mrSane.GetRange( nOption, pValues ) ) < 0 )
1337 0 : return sal_False;
1338 :
1339 : #if OSL_DEBUG_LEVEL > 1
1340 : fprintf( stderr, "SaneDlg::SetAdjustedNumericalValue( \"%s\", %lg ) ",
1341 : pOption, fValue );
1342 : #endif
1343 :
1344 0 : if( nValues )
1345 : {
1346 0 : int nNearest = 0;
1347 0 : double fNearest = 1e6;
1348 0 : for( int i = 0; i < nValues; i++ )
1349 : {
1350 0 : if( fabs( fValue - pValues[ i ] ) < fNearest )
1351 : {
1352 0 : fNearest = fabs( fValue - pValues[ i ] );
1353 0 : nNearest = i;
1354 : }
1355 : }
1356 0 : fValue = pValues[ nNearest ];
1357 : }
1358 : else
1359 : {
1360 0 : if( fValue < pValues[0] )
1361 0 : fValue = pValues[0];
1362 0 : if( fValue > pValues[1] )
1363 0 : fValue = pValues[1];
1364 : }
1365 0 : delete [] pValues;
1366 0 : mrSane.SetOptionValue( nOption, fValue, nElement );
1367 : #if OSL_DEBUG_LEVEL > 1
1368 : fprintf( stderr, "yields %lg\n", fValue );
1369 : #endif
1370 :
1371 :
1372 0 : return sal_True;
1373 : }
1374 :
1375 0 : bool SaneDlg::getDoScan()
1376 : {
1377 0 : return doScan;
1378 : }
1379 :
1380 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|