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

Generated by: LCOV version 1.11