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