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

Generated by: LCOV version 1.10