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