LCOV - code coverage report
Current view: top level - extensions/source/scanner - sanedlg.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 793 0.0 %
Date: 2014-04-11 Functions: 0 38 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10