LCOV - code coverage report
Current view: top level - cui/source/dialogs - colorpicker.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 0 727 0.0 %
Date: 2014-11-03 Functions: 0 84 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/uno/XComponentContext.hpp>
      21             : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
      22             : #include <com/sun/star/beans/XPropertyAccess.hpp>
      23             : #include <com/sun/star/lang/XInitialization.hpp>
      24             : #include <com/sun/star/lang/XServiceInfo.hpp>
      25             : #include <com/sun/star/datatransfer/XTransferable.hpp>
      26             : #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
      27             : #include <com/sun/star/awt/XWindow.hpp>
      28             : #include <cppuhelper/compbase4.hxx>
      29             : #include <cppuhelper/supportsservice.hxx>
      30             : #include <comphelper/broadcasthelper.hxx>
      31             : #include <vcl/dialog.hxx>
      32             : #include <vcl/button.hxx>
      33             : #include <vcl/fixed.hxx>
      34             : #include <vcl/edit.hxx>
      35             : #include <vcl/field.hxx>
      36             : #include <vcl/bmpacc.hxx>
      37             : #include <vcl/decoview.hxx>
      38             : #include <vcl/svapp.hxx>
      39             : #include <toolkit/helper/vclunohelper.hxx>
      40             : #include <sot/exchange.hxx>
      41             : #include <sot/formats.hxx>
      42             : #include <sax/tools/converter.hxx>
      43             : #include <basegfx/color/bcolortools.hxx>
      44             : #include "dialmgr.hxx"
      45             : #include "colorpicker.hxx"
      46             : #include <cmath>
      47             : #include <limits>
      48             : 
      49             : using namespace ::com::sun::star::uno;
      50             : using namespace ::com::sun::star::lang;
      51             : using namespace ::com::sun::star::ui::dialogs;
      52             : using namespace ::com::sun::star::beans;
      53             : using namespace ::basegfx;
      54             : 
      55             : namespace cui
      56             : {
      57             : const sal_uInt16 COLORMODE_RGB =  0x10;
      58             : const sal_uInt16 COLORMODE_HSV =  0x20;
      59             : 
      60             : const sal_uInt16 COLORCOMP_RED   = 0x10;
      61             : const sal_uInt16 COLORCOMP_GREEN = 0x11;
      62             : const sal_uInt16 COLORCOMP_BLUE  = 0x12;
      63             : 
      64             : const sal_uInt16 COLORCOMP_HUE  = 0x20;
      65             : const sal_uInt16 COLORCOMP_SAT  = 0x21;
      66             : const sal_uInt16 COLORCOMP_BRI  = 0x22;
      67             : 
      68             : const sal_uInt16 COLORCOMP_CYAN    = 0x40;
      69             : const sal_uInt16 COLORCOMP_YELLOW  = 0x41;
      70             : const sal_uInt16 COLORCOMP_MAGENTA = 0x42;
      71             : const sal_uInt16 COLORCOMP_KEY     = 0x43;
      72             : 
      73             : // color space conversion helpers
      74             : 
      75           0 : static void RGBtoHSV( double dR, double dG, double dB, double& dH, double& dS, double& dV )
      76             : {
      77           0 :     BColor result = basegfx::tools::rgb2hsv( BColor( dR, dG, dB ) );
      78             : 
      79           0 :     dH = result.getX();
      80           0 :     dS = result.getY();
      81           0 :     dV = result.getZ();
      82           0 : }
      83             : 
      84           0 : static void HSVtoRGB(double dH, double dS, double dV, double& dR, double& dG, double& dB )
      85             : {
      86           0 :     BColor result = basegfx::tools::hsv2rgb( BColor( dH, dS, dV ) );
      87             : 
      88           0 :     dR = result.getRed();
      89           0 :     dG = result.getGreen();
      90           0 :     dB = result.getBlue();
      91           0 : }
      92             : 
      93             : // CMYK values from 0 to 1
      94           0 : static void CMYKtoRGB( double fCyan, double fMagenta, double fYellow, double fKey, double& dR, double& dG, double& dB )
      95             : {
      96           0 :     fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
      97           0 :     fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
      98           0 :     fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
      99             : 
     100           0 :     dR = std::max( std::min( ( 1.0 - fCyan ), 1.0), 0.0 );
     101           0 :     dG = std::max( std::min( ( 1.0 - fMagenta ), 1.0), 0.0 );
     102           0 :     dB = std::max( std::min( ( 1.0 - fYellow ), 1.0), 0.0 );
     103           0 : }
     104             : 
     105             : // CMY results from 0 to 1
     106           0 : static void RGBtoCMYK( double dR, double dG, double dB, double& fCyan, double& fMagenta, double& fYellow, double& fKey )
     107             : {
     108           0 :     fCyan = 1 - dR;
     109           0 :     fMagenta = 1 - dG;
     110           0 :     fYellow = 1 - dB;
     111             : 
     112             :     //CMYK and CMY values from 0 to 1
     113           0 :     fKey = 1.0;
     114           0 :     if( fCyan < fKey ) fKey = fCyan;
     115           0 :     if( fMagenta < fKey ) fKey = fMagenta;
     116           0 :     if( fYellow < fKey ) fKey = fYellow;
     117             : 
     118           0 :     if( fKey >= 1.0 )
     119             :     {
     120             :         //Black
     121           0 :        fCyan = 0.0;
     122           0 :        fMagenta = 0.0;
     123           0 :        fYellow = 0.0;
     124             :     }
     125             :     else
     126             :     {
     127           0 :        fCyan = ( fCyan - fKey ) / ( 1.0 - fKey );
     128           0 :        fMagenta = ( fMagenta - fKey ) / ( 1.0 - fKey );
     129           0 :        fYellow = ( fYellow - fKey ) / ( 1.0 - fKey );
     130             :     }
     131           0 : }
     132             : 
     133           0 : class HexColorControl : public Edit
     134             : {
     135             : public:
     136             :     HexColorControl( vcl::Window* pParent, const WinBits& nStyle );
     137             : 
     138             :     virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
     139             :     virtual void Paste() SAL_OVERRIDE;
     140             : 
     141             :     void SetColor( sal_Int32 nColor );
     142             :     sal_Int32 GetColor();
     143             : 
     144             : private:
     145             :     bool ImplProcessKeyInput( const KeyEvent& rKEv );
     146             : };
     147             : 
     148           0 : HexColorControl::HexColorControl( vcl::Window* pParent, const WinBits& nStyle )
     149           0 : : Edit( pParent, nStyle )
     150             : {
     151           0 :     SetMaxTextLen( 6 );
     152           0 : }
     153             : 
     154           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeHexColorControl(vcl::Window *pParent, VclBuilder::stringmap &)
     155             : {
     156           0 :     return new HexColorControl(pParent, WB_BORDER);
     157             : }
     158             : 
     159           0 : void HexColorControl::SetColor( sal_Int32 nColor )
     160             : {
     161           0 :     OUStringBuffer aBuffer;
     162           0 :     sax::Converter::convertColor( aBuffer, nColor );
     163           0 :     SetText( aBuffer.makeStringAndClear().copy(1) );
     164           0 : }
     165             : 
     166           0 : sal_Int32 HexColorControl::GetColor()
     167             : {
     168           0 :     sal_Int32 nColor = -1;
     169             : 
     170           0 :     OUString aStr( "#" );
     171           0 :     aStr += GetText();
     172           0 :     sal_Int32 nLen = aStr.getLength();
     173           0 :     if( nLen < 7 )
     174             :     {
     175             :         static const sal_Char* pNullStr = "000000";
     176           0 :         aStr += OUString::createFromAscii( &pNullStr[nLen-1] );
     177             :     }
     178             : 
     179           0 :     sax::Converter::convertColor( nColor, aStr );
     180             : 
     181           0 :     if( nColor == -1 )
     182           0 :         SetControlBackground( Color( COL_RED ) );
     183             :     else
     184           0 :         SetControlBackground();
     185             : 
     186           0 :     return nColor;
     187             : }
     188             : 
     189           0 : bool HexColorControl::PreNotify( NotifyEvent& rNEvt )
     190             : {
     191           0 :     if ( (rNEvt.GetType() == EVENT_KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
     192             :     {
     193           0 :         if ( ImplProcessKeyInput( *rNEvt.GetKeyEvent() ) )
     194           0 :             return true;
     195             :     }
     196             : 
     197           0 :     return Edit::PreNotify( rNEvt );
     198             : }
     199             : 
     200           0 : void HexColorControl::Paste()
     201             : {
     202           0 :     ::com::sun::star::uno::Reference<com::sun::star::datatransfer::clipboard::XClipboard> aClipboard(GetClipboard());
     203           0 :     if ( aClipboard.is() )
     204             :     {
     205           0 :         ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::XTransferable > xDataObj;
     206             : 
     207           0 :         const sal_uInt32 nRef = Application::ReleaseSolarMutex();
     208             : 
     209             :         try
     210             :         {
     211           0 :             xDataObj = aClipboard->getContents();
     212             :         }
     213           0 :         catch( const ::com::sun::star::uno::Exception& )
     214             :         {
     215             :         }
     216             : 
     217           0 :         Application::AcquireSolarMutex( nRef );
     218             : 
     219           0 :         if ( xDataObj.is() )
     220             :         {
     221           0 :             ::com::sun::star::datatransfer::DataFlavor aFlavor;
     222           0 :             SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
     223             :             try
     224             :             {
     225           0 :                 ::com::sun::star::uno::Any aData = xDataObj->getTransferData( aFlavor );
     226           0 :                 OUString aText;
     227           0 :                 aData >>= aText;
     228             : 
     229           0 :                 if( !aText.isEmpty() && aText.matchAsciiL( "#", 1, 0 ) )
     230           0 :                     aText = aText.copy(1);
     231             : 
     232           0 :                 if( aText.getLength() > 6 )
     233           0 :                     aText = aText.copy( 0, 6 );
     234             : 
     235           0 :                 SetText( aText );
     236             :             }
     237           0 :             catch( const ::com::sun::star::uno::Exception& )
     238             :             {
     239           0 :             }
     240           0 :         }
     241           0 :     }
     242           0 : }
     243             : 
     244           0 : bool HexColorControl::ImplProcessKeyInput( const KeyEvent& rKEv )
     245             : {
     246           0 :     const vcl::KeyCode& rKeyCode = rKEv.GetKeyCode();
     247             : 
     248           0 :     if( rKeyCode.GetGroup() == KEYGROUP_ALPHA && !rKeyCode.IsMod1() && !rKeyCode.IsMod2() )
     249             :     {
     250           0 :         if( (rKeyCode.GetCode() < KEY_A) || (rKeyCode.GetCode() > KEY_F) )
     251           0 :             return true;
     252             :     }
     253           0 :     else if( rKeyCode.GetGroup() == KEYGROUP_NUM )
     254             :     {
     255           0 :         if( rKeyCode.IsShift() )
     256           0 :             return true;
     257             :     }
     258           0 :     return false;
     259             : }
     260             : 
     261           0 : class ColorPreviewControl : public Control
     262             : {
     263             : public:
     264             :     ColorPreviewControl( vcl::Window* pParent, const WinBits& nStyle );
     265             : 
     266             :     virtual void        Paint( const Rectangle& rRect ) SAL_OVERRIDE;
     267             : 
     268             :     void SetColor( const Color& rColor );
     269             : private:
     270             :     Color maColor;
     271             : };
     272             : 
     273           0 : ColorPreviewControl::ColorPreviewControl( vcl::Window* pParent, const WinBits& nStyle )
     274           0 : : Control( pParent, nStyle )
     275             : {
     276           0 :     SetFillColor( maColor );
     277           0 :     SetLineColor( maColor );
     278           0 : }
     279             : 
     280           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeColorPreviewControl(vcl::Window *pParent, VclBuilder::stringmap &rMap)
     281             : {
     282           0 :     WinBits nBits = 0;
     283             : 
     284           0 :     OString sBorder = VclBuilder::extractCustomProperty(rMap);
     285           0 :     if (!sBorder.isEmpty())
     286           0 :         nBits |= WB_BORDER;
     287             : 
     288           0 :     return new ColorPreviewControl(pParent, nBits);
     289             : }
     290             : 
     291           0 : void ColorPreviewControl::SetColor( const Color& rCol )
     292             : {
     293           0 :     if( rCol != maColor )
     294             :     {
     295           0 :         maColor = rCol;
     296           0 :         SetFillColor( maColor );
     297           0 :         SetLineColor( maColor );
     298           0 :         Invalidate();
     299             :     }
     300           0 : }
     301             : 
     302           0 : void ColorPreviewControl::Paint( const Rectangle& rRect )
     303             : {
     304           0 :     DrawRect( rRect );
     305           0 : }
     306             : 
     307             : enum ColorMode { HUE, SATURATION, BRIGHTNESS, RED, GREEN, BLUE };
     308             : const ColorMode DefaultMode = HUE;
     309             : 
     310             : class ColorFieldControl : public Control
     311             : {
     312             : public:
     313             :     ColorFieldControl( vcl::Window* pParent, const WinBits& nStyle );
     314             :     virtual ~ColorFieldControl();
     315             : 
     316             :     virtual void        MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     317             :     virtual void        MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     318             :     virtual void        MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     319             :     virtual void        KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
     320             :     virtual void        Paint( const Rectangle& rRect ) SAL_OVERRIDE;
     321             :     virtual void        Resize() SAL_OVERRIDE;
     322             : 
     323             :     virtual Size GetOptimalSize() const SAL_OVERRIDE;
     324             : 
     325             :     void                UpdateBitmap();
     326             :     void                ShowPosition( const Point& rPos, bool bUpdate );
     327             :     void                UpdatePosition();
     328             :     void                Modify();
     329             : 
     330             :     void                SetValues( Color aColor, ColorMode eMode, double x, double y );
     331           0 :     double              GetX() { return mdX;}
     332           0 :     double              GetY() { return mdY;}
     333             : 
     334             :     void                KeyMove( int dx, int dy );
     335             : 
     336           0 :     void                SetModifyHdl( Link& rLink ) { maModifyHdl = rLink; }
     337             : 
     338             : private:
     339             :     Link maModifyHdl;
     340             :     ColorMode meMode;
     341             :     Color maColor;
     342             :     double mdX;
     343             :     double mdY;
     344             :     Point maPosition;
     345             :     Bitmap* mpBitmap;
     346             :     std::vector< sal_uInt8 > maRGB_Horiz;
     347             :     std::vector< sal_uInt16 > maGrad_Horiz;
     348             :     std::vector< sal_uInt16 > maPercent_Horiz;
     349             :     std::vector< sal_uInt8 > maRGB_Vert;
     350             :     std::vector< sal_uInt16 > maPercent_Vert;
     351             : };
     352             : 
     353           0 : ColorFieldControl::ColorFieldControl( vcl::Window* pParent, const WinBits& nStyle )
     354             : : Control( pParent, nStyle )
     355             : , meMode( DefaultMode )
     356             : , mdX( -1.0 )
     357             : , mdY( -1.0 )
     358           0 : , mpBitmap( 0 )
     359             : {
     360           0 :     SetControlBackground();
     361           0 : }
     362             : 
     363           0 : ColorFieldControl::~ColorFieldControl()
     364             : {
     365           0 :     delete mpBitmap;
     366           0 : }
     367             : 
     368           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeColorFieldControl(vcl::Window *pParent, VclBuilder::stringmap &rMap)
     369             : {
     370           0 :     WinBits nBits = 0;
     371             : 
     372           0 :     OString sBorder = VclBuilder::extractCustomProperty(rMap);
     373           0 :     if (!sBorder.isEmpty())
     374           0 :         nBits |= WB_BORDER;
     375             : 
     376           0 :     return new ColorFieldControl(pParent, nBits);
     377             : }
     378             : 
     379           0 : Size ColorFieldControl::GetOptimalSize() const
     380             : {
     381           0 :     return LogicToPixel(Size(158, 158), MAP_APPFONT);
     382             : }
     383             : 
     384           0 : void ColorFieldControl::UpdateBitmap()
     385             : {
     386           0 :     const Size aSize( GetOutputSizePixel() );
     387             : 
     388           0 :     if( mpBitmap && mpBitmap->GetSizePixel() != aSize )
     389           0 :         delete mpBitmap, mpBitmap = NULL;
     390             : 
     391           0 :     const sal_Int32 nWidth = aSize.Width();
     392           0 :     const sal_Int32 nHeight = aSize.Height();
     393             : 
     394           0 :     if (nWidth == 0 || nHeight == 0)
     395           0 :         return;
     396             : 
     397           0 :     if( !mpBitmap )
     398             :     {
     399           0 :         mpBitmap = new Bitmap( aSize, 24 );
     400             : 
     401           0 :         maRGB_Horiz.resize( nWidth );
     402           0 :         maGrad_Horiz.resize( nWidth );
     403           0 :         maPercent_Horiz.resize( nWidth );
     404             : 
     405           0 :         sal_uInt8* pRGB = &(*maRGB_Horiz.begin());
     406           0 :         sal_uInt16* pGrad = &(*maGrad_Horiz.begin());
     407           0 :         sal_uInt16* pPercent = &(*maPercent_Horiz.begin());
     408             : 
     409           0 :         for( sal_Int32 x = 0; x < nWidth; x++ )
     410             :         {
     411           0 :             *pRGB++ = static_cast< sal_uInt8 >( (x * 256) / nWidth );
     412           0 :             *pGrad++ = static_cast< sal_uInt16 >( (x * 359) / nWidth );
     413           0 :             *pPercent++ = static_cast< sal_uInt16 >( (x * 100) / nWidth );
     414             :         }
     415             : 
     416           0 :         maRGB_Vert.resize( nHeight );
     417           0 :         maPercent_Vert.resize( nHeight );
     418             : 
     419           0 :         pRGB = &(*maRGB_Vert.begin());
     420           0 :         pPercent = &(*maPercent_Vert.begin());
     421             : 
     422           0 :         sal_Int32 y = nHeight;
     423           0 :         while( y-- )
     424             :         {
     425           0 :             *pRGB++ = static_cast< sal_uInt8 >( (y * 256) / nHeight );
     426           0 :             *pPercent++ = static_cast< sal_uInt16 >( (y * 100) / nHeight );
     427             :         }
     428             :     }
     429             : 
     430           0 :     sal_uInt8* pRGB_Horiz = &(*maRGB_Horiz.begin());
     431           0 :     sal_uInt16* pGrad_Horiz = &(*maGrad_Horiz.begin());
     432           0 :     sal_uInt16* pPercent_Horiz = &(*maPercent_Horiz.begin());
     433           0 :     sal_uInt8* pRGB_Vert = &(*maRGB_Vert.begin());
     434           0 :     sal_uInt16* pPercent_Vert = &(*maPercent_Vert.begin());
     435             : 
     436           0 :     BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
     437           0 :     if( pWriteAccess )
     438             :     {
     439           0 :         BitmapColor aBitmapColor( maColor );
     440             : 
     441             :         sal_uInt16 nHue, nSat, nBri;
     442           0 :         maColor.RGBtoHSB( nHue, nSat, nBri );
     443             : 
     444             :         // this has been unlooped for performance reason, please do not merge back!
     445             : 
     446           0 :         sal_uInt16 y = nHeight,x;
     447             : 
     448           0 :         switch( meMode )
     449             :         {
     450             :         case HUE:
     451           0 :             while( y-- )
     452             :             {
     453           0 :                 nBri = pPercent_Vert[y];
     454           0 :                 x = nWidth;
     455           0 :                 while( x-- )
     456             :                 {
     457           0 :                     nSat = pPercent_Horiz[x];
     458           0 :                     pWriteAccess->SetPixel( y, x, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
     459             :                 }
     460             :             }
     461           0 :             break;
     462             :         case SATURATION:
     463           0 :             while( y-- )
     464             :             {
     465           0 :                 nBri = pPercent_Vert[y];
     466           0 :                 x = nWidth;
     467           0 :                 while( x-- )
     468             :                 {
     469           0 :                     nHue = pGrad_Horiz[x];
     470           0 :                     pWriteAccess->SetPixel( y, x, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
     471             :                 }
     472             :             }
     473           0 :             break;
     474             :         case BRIGHTNESS:
     475           0 :             while( y-- )
     476             :             {
     477           0 :                 nSat = pPercent_Vert[y];
     478           0 :                 x = nWidth;
     479           0 :                 while( x-- )
     480             :                 {
     481           0 :                     nHue = pGrad_Horiz[x];
     482           0 :                     pWriteAccess->SetPixel( y, x, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
     483             :                 }
     484             :             }
     485           0 :             break;
     486             :         case RED:
     487           0 :             while( y-- )
     488             :             {
     489           0 :                 aBitmapColor.SetGreen( pRGB_Vert[y] );
     490           0 :                 x = nWidth;
     491           0 :                 while( x-- )
     492             :                 {
     493           0 :                     aBitmapColor.SetBlue( pRGB_Horiz[x] );
     494           0 :                     pWriteAccess->SetPixel( y, x, aBitmapColor );
     495             :                 }
     496             :             }
     497           0 :             break;
     498             :         case GREEN:
     499           0 :             while( y-- )
     500             :             {
     501           0 :                 aBitmapColor.SetRed( pRGB_Vert[y] );
     502           0 :                 x = nWidth;
     503           0 :                 while( x-- )
     504             :                 {
     505           0 :                     aBitmapColor.SetBlue( pRGB_Horiz[x] );
     506           0 :                     pWriteAccess->SetPixel( y, x, aBitmapColor );
     507             :                 }
     508             :             }
     509           0 :             break;
     510             :         case BLUE:
     511           0 :             while( y-- )
     512             :             {
     513           0 :                 aBitmapColor.SetGreen( pRGB_Vert[y] );
     514           0 :                 x = nWidth;
     515           0 :                 while( x-- )
     516             :                 {
     517           0 :                     aBitmapColor.SetRed( pRGB_Horiz[x] );
     518           0 :                     pWriteAccess->SetPixel( y, x, aBitmapColor );
     519             :                 }
     520             :             }
     521           0 :             break;
     522             :         }
     523             : 
     524           0 :         mpBitmap->ReleaseAccess( pWriteAccess );
     525             :     }
     526             : }
     527             : 
     528           0 : void ColorFieldControl::ShowPosition( const Point& rPos, bool bUpdate )
     529             : {
     530           0 :     if( !mpBitmap )
     531             :     {
     532           0 :         UpdateBitmap();
     533           0 :         Invalidate();
     534             :     }
     535             : 
     536           0 :     if (!mpBitmap)
     537           0 :         return;
     538             : 
     539           0 :     const Size aSize( mpBitmap->GetSizePixel() );
     540             : 
     541           0 :     long nX = rPos.X();
     542           0 :     long nY = rPos.Y();
     543           0 :     if( nX < 0L )
     544           0 :         nX = 0L;
     545           0 :     else if( nX >= aSize.Width() )
     546           0 :         nX = aSize.Width() - 1L;
     547             : 
     548           0 :     if( nY < 0L )
     549           0 :         nY= 0L;
     550           0 :     else if( nY >= aSize.Height() )
     551           0 :         nY = aSize.Height() - 1L;
     552             : 
     553           0 :     Point aPos = maPosition;
     554           0 :     maPosition.X() = nX - 5;
     555           0 :     maPosition.Y() = nY - 5;
     556           0 :     Invalidate( Rectangle( aPos, Size( 11, 11) ) );
     557           0 :     Invalidate( Rectangle( maPosition, Size( 11, 11) ) );
     558             : 
     559           0 :     if( bUpdate )
     560             :     {
     561           0 :         mdX = (double)nX / (double)(aSize.Width()-1);
     562           0 :         mdY = (double)(aSize.Height()-1-nY) / (double)(aSize.Height()-1);
     563             : 
     564           0 :         BitmapReadAccess* pReadAccess = mpBitmap->AcquireReadAccess();
     565           0 :         if( pReadAccess != NULL )
     566             :         {
     567             :             // mpBitmap always has a bit count of 24 => use of GetPixel(...) is safe
     568           0 :             maColor = pReadAccess->GetPixel( nY, nX );
     569           0 :             mpBitmap->ReleaseAccess( pReadAccess );
     570           0 :             pReadAccess = NULL;
     571             :         }
     572             :     }
     573             : }
     574             : 
     575           0 : void ColorFieldControl::MouseMove( const MouseEvent& rMEvt )
     576             : {
     577           0 :     if( rMEvt.IsLeft() )
     578             :     {
     579           0 :         ShowPosition( rMEvt.GetPosPixel(), true );
     580           0 :         Modify();
     581             :     }
     582           0 : }
     583             : 
     584           0 : void ColorFieldControl::MouseButtonDown( const MouseEvent& rMEvt )
     585             : {
     586           0 :     if( rMEvt.IsLeft() && !rMEvt.IsShift() )
     587             :     {
     588           0 :         CaptureMouse();
     589           0 :         ShowPosition( rMEvt.GetPosPixel(), true );
     590           0 :         Modify();
     591             :     }
     592           0 : }
     593             : 
     594           0 : void ColorFieldControl::MouseButtonUp( const MouseEvent& )
     595             : {
     596           0 :     if( IsMouseCaptured() )
     597           0 :         ReleaseMouse();
     598           0 : }
     599             : 
     600           0 : void ColorFieldControl::KeyMove( int dx, int dy )
     601             : {
     602           0 :     Size aSize( GetOutputSizePixel() );
     603           0 :     Point aPos(static_cast<long>(mdX * aSize.Width()), static_cast<long>((1.0 - mdY) * aSize.Height()));
     604           0 :     aPos.X() += dx;
     605           0 :     aPos.Y() += dy;
     606           0 :     if( aPos.X() < 0 )
     607           0 :         aPos.X() += aSize.Width();
     608           0 :     else if( aPos.X() >= aSize.Width() )
     609           0 :         aPos.X() -= aSize.Width();
     610             : 
     611           0 :     if( aPos.Y() < 0 )
     612           0 :         aPos.Y() += aSize.Height();
     613           0 :     else if( aPos.Y() >= aSize.Height() )
     614           0 :         aPos.Y() -= aSize.Height();
     615             : 
     616           0 :     ShowPosition( aPos, true );
     617           0 :     Modify();
     618           0 : }
     619             : 
     620           0 : void ColorFieldControl::KeyInput( const KeyEvent& rKEvt )
     621             : {
     622           0 :     bool   bShift = rKEvt.GetKeyCode().IsShift();
     623           0 :     bool   bCtrl = rKEvt.GetKeyCode().IsMod1();
     624           0 :     bool   bAlt = rKEvt.GetKeyCode().IsMod2();
     625             : 
     626           0 :     if ( !bAlt && !bShift )
     627             :     {
     628           0 :         switch( rKEvt.GetKeyCode().GetCode() )
     629             :         {
     630           0 :         case KEY_DOWN:      KeyMove(  0, bCtrl ?  5  :  1 ); return;
     631           0 :         case KEY_UP:        KeyMove(  0, bCtrl ? -5  : -1 ); return;
     632           0 :         case KEY_LEFT:      KeyMove( bCtrl ? -5  : -1,  0 ); return;
     633           0 :         case KEY_RIGHT:     KeyMove( bCtrl ?  5  :  1,  0 ); return;
     634             :         }
     635             :     }
     636           0 :     Control::KeyInput( rKEvt );
     637             : }
     638             : 
     639           0 : void ColorFieldControl::Paint( const Rectangle& rRect )
     640             : {
     641           0 :     if( !mpBitmap )
     642           0 :         UpdateBitmap();
     643             : 
     644           0 :     if (mpBitmap)
     645             :     {
     646           0 :         Bitmap aOutputBitmap( *mpBitmap );
     647             : 
     648           0 :         if( GetBitCount() <= 8 )
     649           0 :             aOutputBitmap.Dither();
     650             : 
     651           0 :         DrawBitmap( rRect.TopLeft(), rRect.GetSize(), rRect.TopLeft(), rRect.GetSize(), aOutputBitmap );
     652             :     }
     653             : 
     654             :     // draw circle around current color
     655           0 :     if( maColor.IsDark() )
     656           0 :         SetLineColor( COL_WHITE );
     657             :     else
     658           0 :         SetLineColor( COL_BLACK );
     659             : 
     660           0 :     SetFillColor();
     661             : 
     662           0 :     DrawEllipse( Rectangle( maPosition, Size( 11, 11) ) );
     663           0 : }
     664             : 
     665           0 : void ColorFieldControl::Resize()
     666             : {
     667           0 :     UpdateBitmap();
     668           0 :     Control::Resize();
     669           0 : }
     670             : 
     671           0 : void ColorFieldControl::Modify()
     672             : {
     673           0 :     maModifyHdl.Call( this );
     674           0 : }
     675             : 
     676           0 : void ColorFieldControl::SetValues( Color aColor, ColorMode eMode, double x, double y )
     677             : {
     678           0 :     bool bUpdateBitmap = (maColor!= aColor) || (meMode != eMode);
     679           0 :     if( bUpdateBitmap || (mdX != x) || (mdY != y) )
     680             :     {
     681           0 :         maColor = aColor;
     682           0 :         meMode = eMode;
     683           0 :         mdX = x;
     684           0 :         mdY = y;
     685             : 
     686           0 :         if( bUpdateBitmap )
     687           0 :             UpdateBitmap();
     688           0 :         UpdatePosition();
     689           0 :         if( bUpdateBitmap )
     690           0 :             Invalidate();
     691             :     }
     692           0 : }
     693             : 
     694             : 
     695             : 
     696           0 : void ColorFieldControl::UpdatePosition()
     697             : {
     698           0 :     Size aSize( GetOutputSizePixel() );
     699           0 :     ShowPosition( Point(static_cast<long>(mdX * aSize.Width()), static_cast<long>((1.0 - mdY) * aSize.Height())), false );
     700           0 : }
     701             : 
     702             : class ColorSliderControl : public Control
     703             : {
     704             : public:
     705             :     ColorSliderControl( vcl::Window* pParent, const WinBits& nStyle );
     706             :     virtual ~ColorSliderControl();
     707             : 
     708             :     virtual void        MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     709             :     virtual void        MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     710             :     virtual void        MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
     711             :     virtual void        KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
     712             :     virtual void        Paint( const Rectangle& rRect ) SAL_OVERRIDE;
     713             :     virtual void        Resize() SAL_OVERRIDE;
     714             : 
     715             :     void                UpdateBitmap();
     716             :     void                ChangePosition( long nY );
     717             :     void                Modify();
     718             : 
     719             :     void SetValue( const Color& rColor, ColorMode eMode, double dValue );
     720           0 :     double GetValue() const { return mdValue; }
     721             : 
     722             :     void                KeyMove( int dy );
     723             : 
     724           0 :     void SetModifyHdl( Link& rLink ) { maModifyHdl = rLink; }
     725             : 
     726           0 :     sal_Int16 GetLevel() const { return mnLevel; }
     727             : 
     728             : private:
     729             :     Link maModifyHdl;
     730             :     Color maColor;
     731             :     ColorMode meMode;
     732             :     Bitmap* mpBitmap;
     733             :     sal_Int16 mnLevel;
     734             :     double mdValue;
     735             : };
     736             : 
     737           0 : ColorSliderControl::ColorSliderControl( vcl::Window* pParent, const WinBits& nStyle )
     738             : : Control( pParent, nStyle )
     739             : , meMode( DefaultMode )
     740             : , mpBitmap( 0 )
     741             : , mnLevel( 0 )
     742           0 : , mdValue( -1.0 )
     743             : {
     744           0 :     SetControlBackground();
     745           0 : }
     746             : 
     747           0 : ColorSliderControl::~ColorSliderControl()
     748             : {
     749           0 :     delete mpBitmap;
     750           0 : }
     751             : 
     752           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeColorSliderControl(vcl::Window *pParent, VclBuilder::stringmap &rMap)
     753             : {
     754           0 :     WinBits nBits = 0;
     755             : 
     756           0 :     OString sBorder = VclBuilder::extractCustomProperty(rMap);
     757           0 :     if (!sBorder.isEmpty())
     758           0 :         nBits |= WB_BORDER;
     759             : 
     760           0 :     return new ColorSliderControl(pParent, nBits);
     761             : }
     762             : 
     763           0 : void ColorSliderControl::UpdateBitmap()
     764             : {
     765           0 :     Size aSize( 1, GetOutputSizePixel().Height() );
     766             : 
     767           0 :     if( mpBitmap && mpBitmap->GetSizePixel() != aSize )
     768           0 :         delete mpBitmap, mpBitmap = NULL;
     769             : 
     770           0 :     if( !mpBitmap )
     771           0 :         mpBitmap = new Bitmap( aSize, 24 );
     772             : 
     773           0 :     BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
     774             : 
     775           0 :     if( pWriteAccess )
     776             :     {
     777           0 :         const long nY = aSize.Height()-1;
     778             : 
     779           0 :         BitmapColor aBitmapColor( maColor );
     780             : 
     781             :         sal_uInt16 nHue, nSat, nBri;
     782           0 :         maColor.RGBtoHSB( nHue, nSat, nBri );
     783             : 
     784             :         // this has been unlooped for performance reason, please do not merge back!
     785             : 
     786           0 :         switch( meMode )
     787             :         {
     788             :         case HUE:
     789           0 :             nSat = 100;
     790           0 :             nBri = 100;
     791           0 :             for( long y = 0; y <= nY; y++ )
     792             :             {
     793           0 :                 nHue = static_cast< sal_uInt16 >( (359 * y) / nY );
     794           0 :                 aBitmapColor = BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) );
     795           0 :                 pWriteAccess->SetPixel( nY-y, 0, aBitmapColor );
     796             :             }
     797           0 :             break;
     798             : 
     799             :         case SATURATION:
     800           0 :             nBri = std::max( (sal_uInt16)32, nBri );
     801           0 :             for( long y = 0; y <= nY; y++ )
     802             :             {
     803           0 :                 nSat = static_cast< sal_uInt16 >( (100 * y) / nY );
     804           0 :                 pWriteAccess->SetPixel( nY-y, 0, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
     805             :             }
     806           0 :             break;
     807             : 
     808             :         case BRIGHTNESS:
     809           0 :             for( long y = 0; y <= nY; y++ )
     810             :             {
     811           0 :                 nBri = static_cast< sal_uInt16 >( (100 * y) / nY );
     812           0 :                 pWriteAccess->SetPixel( nY-y, 0, BitmapColor( Color( Color::HSBtoRGB( nHue, nSat, nBri ) ) ) );
     813             :             }
     814           0 :             break;
     815             : 
     816             :         case RED:
     817           0 :             for( long y = 0; y <= nY; y++ )
     818             :             {
     819           0 :                 aBitmapColor.SetRed( sal_uInt8( ((long)255 * y) / nY ) );
     820           0 :                 pWriteAccess->SetPixel( nY-y, 0, aBitmapColor );
     821             :             }
     822           0 :             break;
     823             : 
     824             :         case GREEN:
     825           0 :             for( long y = 0; y <= nY; y++ )
     826             :             {
     827           0 :                 aBitmapColor.SetGreen( sal_uInt8( ((long)255 * y) / nY ) );
     828           0 :                 pWriteAccess->SetPixel( nY-y, 0, aBitmapColor );
     829             :             }
     830           0 :             break;
     831             : 
     832             :         case BLUE:
     833           0 :             for( long y = 0; y <= nY; y++ )
     834             :             {
     835           0 :                 aBitmapColor.SetBlue( sal_uInt8( ((long)255 * y) / nY ) );
     836           0 :                 pWriteAccess->SetPixel( nY-y, 0, aBitmapColor );
     837             :             }
     838           0 :             break;
     839             :         }
     840             : 
     841           0 :         mpBitmap->ReleaseAccess( pWriteAccess );
     842             :     }
     843           0 : }
     844             : 
     845           0 : void ColorSliderControl::ChangePosition( long nY )
     846             : {
     847           0 :     const long nHeight = GetOutputSizePixel().Height() - 1;
     848             : 
     849           0 :     if( nY < 0L )
     850           0 :         nY = 0;
     851           0 :     else if( nY > nHeight )
     852           0 :         nY = nHeight;
     853             : 
     854           0 :     mnLevel = nY;
     855           0 :     mdValue = ((double)(nHeight - nY)) / (double)nHeight;
     856           0 : }
     857             : 
     858           0 : void ColorSliderControl::MouseMove( const MouseEvent& rMEvt )
     859             : {
     860           0 :     if( rMEvt.IsLeft() )
     861             :     {
     862           0 :         ChangePosition( rMEvt.GetPosPixel().Y() );
     863           0 :         Modify();
     864             :     }
     865           0 : }
     866             : 
     867           0 : void ColorSliderControl::MouseButtonDown( const MouseEvent& rMEvt )
     868             : {
     869           0 :     if( rMEvt.IsLeft() && !rMEvt.IsShift() )
     870             :     {
     871           0 :         CaptureMouse();
     872           0 :         ChangePosition( rMEvt.GetPosPixel().Y() );
     873           0 :         Modify();
     874             :     }
     875           0 : }
     876             : 
     877           0 : void ColorSliderControl::MouseButtonUp( const MouseEvent& )
     878             : {
     879           0 :     if( IsMouseCaptured() )
     880           0 :         ReleaseMouse();
     881           0 : }
     882             : 
     883           0 : void ColorSliderControl::KeyMove( int dy )
     884             : {
     885           0 :     ChangePosition( mnLevel + dy );
     886           0 :     Modify();
     887           0 : }
     888             : 
     889           0 : void ColorSliderControl::KeyInput( const KeyEvent& rKEvt )
     890             : {
     891           0 :     if ( !rKEvt.GetKeyCode().IsMod2() && !rKEvt.GetKeyCode().IsShift() )
     892             :     {
     893           0 :         switch( rKEvt.GetKeyCode().GetCode() )
     894             :         {
     895           0 :         case KEY_DOWN:      KeyMove(  rKEvt.GetKeyCode().IsMod1() ?  5 :  1 ); return;
     896           0 :         case KEY_UP:        KeyMove(  rKEvt.GetKeyCode().IsMod1() ? -5 : -1 ); return;
     897             :         }
     898             :     }
     899             : 
     900           0 :     Control::KeyInput( rKEvt );
     901             : }
     902             : 
     903           0 : void ColorSliderControl::Paint( const Rectangle& /*rRect*/ )
     904             : {
     905           0 :     if( !mpBitmap )
     906           0 :         UpdateBitmap();
     907             : 
     908           0 :     const Size aSize( GetOutputSizePixel() );
     909             : 
     910           0 :     Bitmap aOutputBitmap( *mpBitmap );
     911             : 
     912           0 :     if( GetBitCount() <= 8 )
     913           0 :         aOutputBitmap.Dither();
     914             : 
     915           0 :     Point aPos;
     916           0 :     int x = aSize.Width();
     917           0 :     while( x-- )
     918             :     {
     919           0 :         DrawBitmap( aPos, aOutputBitmap );
     920           0 :         aPos.X() += 1;
     921           0 :     }
     922           0 : }
     923             : 
     924           0 : void ColorSliderControl::Resize()
     925             : {
     926           0 :     UpdateBitmap();
     927           0 :     Control::Resize();
     928           0 : }
     929             : 
     930           0 : void ColorSliderControl::Modify()
     931             : {
     932           0 :     maModifyHdl.Call( this );
     933           0 : }
     934             : 
     935           0 : void ColorSliderControl::SetValue( const Color& rColor, ColorMode eMode, double dValue )
     936             : {
     937           0 :     bool bUpdateBitmap = (rColor != maColor) || (eMode != meMode);
     938           0 :     if( bUpdateBitmap || (mdValue != dValue))
     939             :     {
     940           0 :         maColor = rColor;
     941           0 :         mdValue = dValue;
     942           0 :         mnLevel = static_cast<sal_Int16>((1.0-dValue) * GetOutputSizePixel().Height());
     943           0 :         meMode = eMode;
     944           0 :         if( bUpdateBitmap )
     945           0 :             UpdateBitmap();
     946           0 :         Invalidate();
     947             :     }
     948           0 : }
     949             : 
     950             : const sal_uInt16 UPDATE_RGB = 0x01;
     951             : const sal_uInt16 UPDATE_CMYK = 0x02;
     952             : const sal_uInt16 UPDATE_HSB = 0x04;
     953             : const sal_uInt16 UPDATE_COLORCHOOSER = 0x08;
     954             : const sal_uInt16 UPDATE_COLORSLIDER = 0x10;
     955             : const sal_uInt16 UPDATE_HEX = 0x20;
     956             : const sal_uInt16 UPDATE_ALL = 0xff;
     957             : 
     958           0 : class ColorPickerDialog : public ModalDialog
     959             : {
     960             : public:
     961             :     ColorPickerDialog( vcl::Window* pParent, sal_Int32 nColor, sal_Int16 nMode );
     962             : 
     963             :     void update_color( sal_uInt16 n = UPDATE_ALL );
     964             : 
     965             :     DECL_LINK( ColorModifyHdl, void * );
     966             :     DECL_LINK( ModeModifyHdl, void * );
     967             : 
     968             :     sal_Int32 GetColor() const;
     969             : 
     970             :     void setColorComponent( sal_uInt16 nComp, double dValue );
     971             : 
     972             : private:
     973             :     sal_Int16 mnDialogMode;
     974             :     ColorMode meMode;
     975             : 
     976             :     double mdRed, mdGreen, mdBlue;
     977             :     double mdHue, mdSat, mdBri;
     978             :     double mdCyan, mdMagenta, mdYellow, mdKey;
     979             : 
     980             : private:
     981             :     ColorFieldControl*    mpColorField;
     982             :     ColorSliderControl*   mpColorSlider;
     983             :     ColorPreviewControl*  mpColorPreview;
     984             :     ColorPreviewControl*  mpColorPrevious;
     985             : 
     986             :     FixedImage*   mpFISliderLeft;
     987             :     FixedImage*   mpFISliderRight;
     988             :     Image         maSliderImage;
     989             : 
     990             :     RadioButton*    mpRBRed;
     991             :     RadioButton*    mpRBGreen;
     992             :     RadioButton*    mpRBBlue;
     993             :     RadioButton*    mpRBHue;
     994             :     RadioButton*    mpRBSaturation;
     995             :     RadioButton*    mpRBBrightness;
     996             : 
     997             :     MetricField*        mpMFRed;
     998             :     MetricField*        mpMFGreen;
     999             :     MetricField*        mpMFBlue;
    1000             :     HexColorControl*    mpEDHex;
    1001             : 
    1002             :     MetricField*    mpMFHue;
    1003             :     MetricField*    mpMFSaturation;
    1004             :     MetricField*    mpMFBrightness;
    1005             : 
    1006             :     MetricField*    mpMFCyan;
    1007             :     MetricField*    mpMFMagenta;
    1008             :     MetricField*    mpMFYellow;
    1009             :     MetricField*    mpMFKey;
    1010             : };
    1011             : 
    1012           0 : ColorPickerDialog::ColorPickerDialog( vcl::Window* pParent, sal_Int32 nColor, sal_Int16 nMode )
    1013             : : ModalDialog( pParent, "ColorPicker", "cui/ui/colorpickerdialog.ui" )
    1014             : , mnDialogMode( nMode )
    1015             : , meMode( DefaultMode )
    1016           0 : , maSliderImage( FixedImage::loadThemeImage("res/colorslider.png") )
    1017             : {
    1018           0 :     get(mpColorField, "colorField");
    1019           0 :     get(mpColorSlider, "colorSlider");
    1020           0 :     get(mpColorPreview, "preview");
    1021           0 :     get(mpColorPrevious, "previous");
    1022           0 :     get(mpRBRed, "redRadiobutton");
    1023           0 :     get(mpRBGreen, "greenRadiobutton");
    1024           0 :     get(mpRBBlue, "blueRadiobutton");
    1025           0 :     get(mpRBHue, "hueRadiobutton");
    1026           0 :     get(mpRBSaturation, "satRadiobutton");
    1027           0 :     get(mpRBBrightness, "brightRadiobutton");
    1028           0 :     get(mpMFRed, "redSpinbutton");
    1029           0 :     get(mpMFGreen, "greenSpinbutton");
    1030           0 :     get(mpMFBlue, "blueSpinbutton");
    1031           0 :     get(mpEDHex, "hexEntry");
    1032           0 :     get(mpMFHue, "hueSpinbutton");
    1033           0 :     get(mpMFSaturation, "satSpinbutton");
    1034           0 :     get(mpMFBrightness, "brightSpinbutton");
    1035           0 :     get(mpMFCyan, "cyanSpinbutton");
    1036           0 :     get(mpMFMagenta, "magSpinbutton");
    1037           0 :     get(mpMFYellow, "yellowSpinbutton");
    1038           0 :     get(mpMFKey, "keySpinbutton");
    1039           0 :     get(mpFISliderLeft, "leftImage");
    1040           0 :     get(mpFISliderRight, "rightImage");
    1041             : 
    1042           0 :     Size aDialogSize = get_preferred_size();
    1043           0 :     set_width_request(aDialogSize.Width() + 50);
    1044           0 :     set_height_request(aDialogSize.Height() + 30);
    1045             : 
    1046           0 :     Link aLink( LINK( this, ColorPickerDialog, ColorModifyHdl ) );
    1047           0 :     mpColorField->SetModifyHdl( aLink );
    1048           0 :     mpColorSlider->SetModifyHdl( aLink );
    1049             : 
    1050           0 :     mpMFRed->SetModifyHdl( aLink );
    1051           0 :     mpMFGreen->SetModifyHdl( aLink );
    1052           0 :     mpMFBlue->SetModifyHdl( aLink );
    1053             : 
    1054           0 :     mpMFCyan->SetModifyHdl( aLink );
    1055           0 :     mpMFMagenta->SetModifyHdl( aLink );
    1056           0 :     mpMFYellow->SetModifyHdl( aLink );
    1057           0 :     mpMFKey->SetModifyHdl( aLink );
    1058             : 
    1059           0 :     mpMFHue->SetModifyHdl( aLink );
    1060           0 :     mpMFSaturation->SetModifyHdl( aLink );
    1061           0 :     mpMFBrightness->SetModifyHdl( aLink );
    1062             : 
    1063           0 :     mpEDHex->SetModifyHdl( aLink );
    1064             : 
    1065           0 :     aLink = LINK( this, ColorPickerDialog, ModeModifyHdl );
    1066           0 :     mpRBRed->SetToggleHdl( aLink );
    1067           0 :     mpRBGreen->SetToggleHdl( aLink );
    1068           0 :     mpRBBlue->SetToggleHdl( aLink );
    1069           0 :     mpRBHue->SetToggleHdl( aLink );
    1070           0 :     mpRBSaturation->SetToggleHdl( aLink );
    1071           0 :     mpRBBrightness->SetToggleHdl( aLink );
    1072             : 
    1073           0 :     Image aSliderImage( maSliderImage );
    1074             : 
    1075           0 :     mpFISliderLeft->SetImage( aSliderImage );
    1076           0 :     mpFISliderLeft->Show(true);
    1077             : 
    1078           0 :     BitmapEx aTmpBmp( maSliderImage.GetBitmapEx() );
    1079           0 :     aTmpBmp.Mirror( BMP_MIRROR_HORZ );
    1080           0 :     mpFISliderRight->SetImage( Image( aTmpBmp  ) );
    1081             : 
    1082           0 :     Size aSize( maSliderImage.GetSizePixel() );
    1083           0 :     mpFISliderLeft->SetSizePixel( aSize );
    1084           0 :     mpFISliderRight->SetSizePixel( aSize );
    1085             : 
    1086           0 :     Point aPos( mpColorSlider->GetPosPixel() );
    1087             : 
    1088           0 :     aPos.X() -= aSize.Width();
    1089           0 :     aPos.Y() -= aSize.Height() / 2;
    1090           0 :     mpFISliderLeft->SetPosPixel( aPos );
    1091             : 
    1092           0 :     aPos.X() += aSize.Width() + mpColorSlider->GetSizePixel().Width();
    1093           0 :     mpFISliderRight->SetPosPixel( aPos );
    1094             : 
    1095           0 :     Color aColor( nColor );
    1096             : 
    1097             :     // modify
    1098           0 :     if( mnDialogMode == 2 )
    1099             :     {
    1100           0 :         mpColorPreview->SetSizePixel( mpColorPrevious->GetSizePixel() );
    1101           0 :         mpColorPrevious->SetColor( aColor );
    1102           0 :         mpColorPrevious->Show( true );
    1103             :     }
    1104             : 
    1105           0 :     mdRed = ((double)aColor.GetRed()) / 255.0;
    1106           0 :     mdGreen = ((double)aColor.GetGreen()) / 255.0;
    1107           0 :     mdBlue = ((double)aColor.GetBlue()) / 255.0;
    1108             : 
    1109           0 :     RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
    1110           0 :     RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
    1111             : 
    1112           0 :     update_color();
    1113           0 : }
    1114             : 
    1115           0 : static int toInt( double dValue, double dRange )
    1116             : {
    1117           0 :     return static_cast< int >( std::floor((dValue * dRange) + 0.5 ) );
    1118             : }
    1119             : 
    1120           0 : sal_Int32 ColorPickerDialog::GetColor() const
    1121             : {
    1122           0 :     return Color( toInt(mdRed,255.0), toInt(mdGreen,255.0), toInt(mdBlue,255.0) ).GetColor();
    1123             : }
    1124             : 
    1125           0 : void ColorPickerDialog::update_color( sal_uInt16 n )
    1126             : {
    1127           0 :     sal_uInt8 nRed = toInt(mdRed,255.0);
    1128           0 :     sal_uInt8 nGreen = toInt(mdGreen,255.0);
    1129           0 :     sal_uInt8 nBlue = toInt(mdBlue,255.0);
    1130             : 
    1131           0 :     Color aColor( nRed, nGreen, nBlue );
    1132             : 
    1133           0 :     if( n & UPDATE_RGB ) // update RGB
    1134             :     {
    1135           0 :         mpMFRed->SetValue( nRed );
    1136           0 :         mpMFGreen->SetValue( nGreen );
    1137           0 :         mpMFBlue->SetValue( nBlue );
    1138             :     }
    1139             : 
    1140           0 :     if( n & UPDATE_CMYK ) // update CMYK
    1141             :     {
    1142           0 :         mpMFCyan->SetValue( toInt( mdCyan, 100.0 ) );
    1143           0 :         mpMFMagenta->SetValue( toInt( mdMagenta, 100.0 ) );
    1144           0 :         mpMFYellow->SetValue( toInt( mdYellow, 100.0 ) );
    1145           0 :         mpMFKey->SetValue( toInt( mdKey, 100.0 ) );
    1146             :     }
    1147             : 
    1148           0 :     if( n & UPDATE_HSB ) // update HSB
    1149             :     {
    1150           0 :         mpMFHue->SetValue( toInt( mdHue, 1.0 ) );
    1151           0 :         mpMFSaturation->SetValue( toInt( mdSat, 100.0 ) );
    1152           0 :         mpMFBrightness->SetValue( toInt( mdBri, 100.0 ) );
    1153             :     }
    1154             : 
    1155           0 :     if( n & UPDATE_COLORCHOOSER ) // update Color Chooser 1
    1156             :     {
    1157           0 :         switch( meMode )
    1158             :         {
    1159           0 :         case HUE:           mpColorField->SetValues( aColor, meMode, mdSat, mdBri ); break;
    1160           0 :         case SATURATION:    mpColorField->SetValues( aColor, meMode, mdHue / 360.0, mdBri ); break;
    1161           0 :         case BRIGHTNESS:    mpColorField->SetValues( aColor, meMode, mdHue / 360.0, mdSat ); break;
    1162           0 :         case RED:           mpColorField->SetValues( aColor, meMode, mdBlue, mdGreen ); break;
    1163           0 :         case GREEN:         mpColorField->SetValues( aColor, meMode, mdBlue, mdRed ); break;
    1164           0 :         case BLUE:          mpColorField->SetValues( aColor, meMode, mdRed, mdGreen ); break;
    1165             :         }
    1166             :     }
    1167             : 
    1168           0 :     if( n & UPDATE_COLORSLIDER ) // update Color Chooser 2
    1169             :     {
    1170           0 :         switch( meMode )
    1171             :         {
    1172           0 :         case HUE:           mpColorSlider->SetValue( aColor, meMode, mdHue / 360.0 ); break;
    1173           0 :         case SATURATION:    mpColorSlider->SetValue( aColor, meMode, mdSat ); break;
    1174           0 :         case BRIGHTNESS:    mpColorSlider->SetValue( aColor, meMode, mdBri ); break;
    1175           0 :         case RED:           mpColorSlider->SetValue( aColor, meMode, mdRed ); break;
    1176           0 :         case GREEN:         mpColorSlider->SetValue( aColor, meMode, mdGreen ); break;
    1177           0 :         case BLUE:          mpColorSlider->SetValue( aColor, meMode, mdBlue ); break;
    1178             :         }
    1179             :     }
    1180             : 
    1181           0 :     if( n & UPDATE_HEX ) // update hex
    1182             :     {
    1183           0 :         mpEDHex->SetColor( aColor.GetColor()  );
    1184             :     }
    1185             : 
    1186             :     {
    1187           0 :         Point aPos( 0, mpColorSlider->GetLevel() + mpColorSlider->GetPosPixel().Y() - 1 );
    1188             : 
    1189           0 :         aPos.X() = mpFISliderLeft->GetPosPixel().X();
    1190           0 :         if( aPos != mpFISliderLeft->GetPosPixel() )
    1191             :         {
    1192           0 :             mpFISliderLeft->SetPosPixel( aPos );
    1193             : 
    1194           0 :             aPos.X() = mpFISliderRight->GetPosPixel().X();
    1195           0 :             mpFISliderRight->SetPosPixel( aPos );
    1196             :         }
    1197             :     }
    1198             : 
    1199           0 :     mpColorPreview->SetColor( aColor );
    1200           0 : }
    1201             : 
    1202           0 : IMPL_LINK( ColorPickerDialog, ColorModifyHdl, void *, p )
    1203             : {
    1204           0 :     sal_uInt16 n = 0;
    1205             : 
    1206           0 :     if( p == mpColorField )
    1207             :     {
    1208           0 :         double x = mpColorField->GetX();
    1209           0 :         double y = mpColorField->GetY();
    1210             : 
    1211           0 :         switch( meMode )
    1212             :         {
    1213           0 :         case HUE:           mdSat = x; setColorComponent( COLORCOMP_BRI, y ); break;
    1214           0 :         case SATURATION:    mdHue = x * 360.0; setColorComponent( COLORCOMP_BRI, y ); break;
    1215           0 :         case BRIGHTNESS:    mdHue = x * 360.0; setColorComponent( COLORCOMP_SAT, y ); break;
    1216           0 :         case RED:           mdBlue = x; setColorComponent( COLORCOMP_GREEN, y ); break;
    1217           0 :         case GREEN:         mdBlue = x; setColorComponent( COLORCOMP_RED, y ); break;
    1218           0 :         case BLUE:          mdRed = x; setColorComponent( COLORCOMP_GREEN, y ); break;
    1219             :         }
    1220             : 
    1221           0 :         n = UPDATE_ALL&~(UPDATE_COLORCHOOSER);
    1222             :     }
    1223           0 :     else if( p == mpColorSlider )
    1224             :     {
    1225           0 :         double dValue = mpColorSlider->GetValue();
    1226           0 :         switch( meMode )
    1227             :         {
    1228           0 :         case HUE:           setColorComponent( COLORCOMP_HUE, dValue * 360.0 ); break;
    1229           0 :         case SATURATION:    setColorComponent( COLORCOMP_SAT, dValue ); break;
    1230           0 :         case BRIGHTNESS:    setColorComponent( COLORCOMP_BRI, dValue ); break;
    1231           0 :         case RED:           setColorComponent( COLORCOMP_RED, dValue ); break;
    1232           0 :         case GREEN:         setColorComponent( COLORCOMP_GREEN, dValue ); break;
    1233           0 :         case BLUE:          setColorComponent( COLORCOMP_BLUE, dValue ); break;
    1234             :         }
    1235             : 
    1236           0 :         n = UPDATE_ALL&~(UPDATE_COLORSLIDER);
    1237             :     }
    1238           0 :     else if( p == mpMFRed )
    1239             :     {
    1240           0 :         setColorComponent( COLORCOMP_RED, ((double)mpMFRed->GetValue()) / 255.0 );
    1241           0 :         n = UPDATE_ALL&~(UPDATE_RGB);
    1242             :     }
    1243           0 :     else if( p == mpMFGreen )
    1244             :     {
    1245           0 :         setColorComponent( COLORCOMP_GREEN, ((double)mpMFGreen->GetValue()) / 255.0 );
    1246           0 :         n = UPDATE_ALL&~(UPDATE_RGB);
    1247             :     }
    1248           0 :     else if( p == mpMFBlue )
    1249             :     {
    1250           0 :         setColorComponent( COLORCOMP_BLUE, ((double)mpMFBlue->GetValue()) / 255.0 );
    1251           0 :         n = UPDATE_ALL&~(UPDATE_RGB);
    1252             :     }
    1253           0 :     else if( p == mpMFHue )
    1254             :     {
    1255           0 :         setColorComponent( COLORCOMP_HUE, (double)mpMFHue->GetValue() );
    1256           0 :         n = UPDATE_ALL&~(UPDATE_HSB);
    1257             :     }
    1258           0 :     else if( p == mpMFSaturation )
    1259             :     {
    1260           0 :         setColorComponent( COLORCOMP_SAT, ((double)mpMFSaturation->GetValue()) / 100.0 );
    1261           0 :         n = UPDATE_ALL&~(UPDATE_HSB);
    1262             :     }
    1263           0 :     else if( p == mpMFBrightness )
    1264             :     {
    1265           0 :         setColorComponent( COLORCOMP_BRI, ((double)mpMFBrightness->GetValue()) / 100.0 );
    1266           0 :         n = UPDATE_ALL&~(UPDATE_HSB);
    1267             :     }
    1268           0 :     else if( p == mpMFCyan )
    1269             :     {
    1270           0 :         setColorComponent( COLORCOMP_CYAN, ((double)mpMFCyan->GetValue()) / 100.0 );
    1271           0 :         n = UPDATE_ALL&~(UPDATE_CMYK);
    1272             :     }
    1273           0 :     else if( p == mpMFMagenta )
    1274             :     {
    1275           0 :         setColorComponent( COLORCOMP_MAGENTA, ((double)mpMFMagenta->GetValue()) / 100.0 );
    1276           0 :         n = UPDATE_ALL&~(UPDATE_CMYK);
    1277             :     }
    1278           0 :     else if( p == mpMFYellow )
    1279             :     {
    1280           0 :         setColorComponent( COLORCOMP_YELLOW, ((double)mpMFYellow->GetValue()) / 100.0 );
    1281           0 :         n = UPDATE_ALL&~(UPDATE_CMYK);
    1282             :     }
    1283           0 :     else if( p == mpMFKey )
    1284             :     {
    1285           0 :         setColorComponent( COLORCOMP_KEY, ((double)mpMFKey->GetValue()) / 100.0 );
    1286           0 :         n = UPDATE_ALL&~(UPDATE_CMYK);
    1287             :     }
    1288           0 :     else if( p == mpEDHex )
    1289             :     {
    1290           0 :         sal_Int32 nColor = mpEDHex->GetColor();
    1291             : 
    1292           0 :         if( nColor != -1 )
    1293             :         {
    1294           0 :             Color aColor( nColor );
    1295             : 
    1296           0 :             if( aColor != GetColor() )
    1297             :             {
    1298           0 :                 mdRed = ((double)aColor.GetRed()) / 255.0;
    1299           0 :                 mdGreen = ((double)aColor.GetGreen()) / 255.0;
    1300           0 :                 mdBlue = ((double)aColor.GetBlue()) / 255.0;
    1301             : 
    1302           0 :                 RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
    1303           0 :                 RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
    1304           0 :                 n = UPDATE_ALL&~(UPDATE_HEX);
    1305             :             }
    1306             :         }
    1307             :     }
    1308             : 
    1309           0 :     if( n )
    1310           0 :         update_color( n );
    1311             : 
    1312           0 :     return 0;
    1313             : }
    1314             : 
    1315           0 : IMPL_LINK_NOARG(ColorPickerDialog, ModeModifyHdl)
    1316             : {
    1317           0 :     ColorMode eMode = HUE;
    1318             : 
    1319           0 :     if( mpRBRed->IsChecked() )
    1320             :     {
    1321           0 :         eMode = RED;
    1322             :     }
    1323           0 :     else if( mpRBGreen->IsChecked() )
    1324             :     {
    1325           0 :         eMode = GREEN;
    1326             :     }
    1327           0 :     else if( mpRBBlue->IsChecked() )
    1328             :     {
    1329           0 :         eMode = BLUE;
    1330             :     }
    1331           0 :     else if( mpRBSaturation->IsChecked() )
    1332             :     {
    1333           0 :         eMode = SATURATION;
    1334             :     }
    1335           0 :     else if( mpRBBrightness->IsChecked() )
    1336             :     {
    1337           0 :         eMode = BRIGHTNESS;
    1338             :     }
    1339             : 
    1340           0 :     if( meMode != eMode )
    1341             :     {
    1342           0 :         meMode = eMode;
    1343           0 :         update_color( UPDATE_COLORCHOOSER | UPDATE_COLORSLIDER );
    1344             :     }
    1345             : 
    1346           0 :     return 0;
    1347             : }
    1348             : 
    1349           0 : void ColorPickerDialog::setColorComponent( sal_uInt16 nComp, double dValue )
    1350             : {
    1351           0 :     switch( nComp )
    1352             :     {
    1353           0 :     case COLORCOMP_RED:     mdRed = dValue; break;
    1354           0 :     case COLORCOMP_GREEN:   mdGreen = dValue; break;
    1355           0 :     case COLORCOMP_BLUE:    mdBlue = dValue; break;
    1356           0 :     case COLORCOMP_HUE:     mdHue = dValue; break;
    1357           0 :     case COLORCOMP_SAT:     mdSat = dValue; break;
    1358           0 :     case COLORCOMP_BRI:     mdBri = dValue; break;
    1359           0 :     case COLORCOMP_CYAN:    mdCyan = dValue; break;
    1360           0 :     case COLORCOMP_YELLOW:  mdYellow = dValue; break;
    1361           0 :     case COLORCOMP_MAGENTA: mdMagenta = dValue; break;
    1362           0 :     case COLORCOMP_KEY:     mdKey = dValue; break;
    1363             :     }
    1364             : 
    1365           0 :     if( nComp & COLORMODE_RGB )
    1366             :     {
    1367           0 :         RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
    1368           0 :         RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
    1369             :     }
    1370           0 :     else if( nComp & COLORMODE_HSV )
    1371             :     {
    1372           0 :         HSVtoRGB( mdHue, mdSat, mdBri, mdRed, mdGreen, mdBlue );
    1373           0 :         RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
    1374             :     }
    1375             :     else
    1376             :     {
    1377           0 :         CMYKtoRGB( mdCyan, mdMagenta, mdYellow, mdKey, mdRed, mdGreen, mdBlue );
    1378           0 :         RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
    1379             :     }
    1380           0 : }
    1381             : 
    1382             : typedef ::cppu::WeakComponentImplHelper4< XServiceInfo, XExecutableDialog, XInitialization, XPropertyAccess > ColorPickerBase;
    1383             : 
    1384           0 : class ColorPicker : protected ::comphelper::OBaseMutex,    // Struct for right initalization of mutex member! Must be first of baseclasses.
    1385             :                     public ColorPickerBase
    1386             : {
    1387             : public:
    1388             :     ColorPicker( Reference< XComponentContext > const & xContext );
    1389             : 
    1390             :     // XInitialization
    1391             :     virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
    1392             : 
    1393             :     // XInitialization
    1394             :     virtual OUString SAL_CALL getImplementationName(  ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
    1395             :     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
    1396             :     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
    1397             : 
    1398             :     // XPropertyAccess
    1399             :     virtual Sequence< PropertyValue > SAL_CALL getPropertyValues(  ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
    1400             :     virtual void SAL_CALL setPropertyValues( const Sequence< PropertyValue >& aProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE;
    1401             : 
    1402             :     // XExecutableDialog
    1403             :     virtual void SAL_CALL setTitle( const OUString& aTitle ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
    1404             :     virtual sal_Int16 SAL_CALL execute(  ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
    1405             : 
    1406             : private:
    1407             :     Reference< XComponentContext > mxContext;
    1408             :     OUString msTitle;
    1409             :     const OUString msColorKey;
    1410             :     const OUString msModeKey;
    1411             :     sal_Int32 mnColor;
    1412             :     sal_Int16 mnMode;
    1413             :     Reference< ::com::sun::star::awt::XWindow > mxParent;
    1414             : };
    1415             : 
    1416           0 : OUString SAL_CALL ColorPicker_getImplementationName()
    1417             : {
    1418           0 :     return OUString( "com.sun.star.cui.ColorPicker" );
    1419             : }
    1420             : 
    1421           0 : Reference< XInterface > SAL_CALL ColorPicker_createInstance( Reference< XComponentContext > const & xContext )
    1422             : {
    1423           0 :     return static_cast<XWeak*>( new ColorPicker( xContext ) );
    1424             : }
    1425             : 
    1426           0 : Sequence< OUString > SAL_CALL ColorPicker_getSupportedServiceNames() throw( RuntimeException )
    1427             : {
    1428           0 :     Sequence< OUString > seq(1);
    1429           0 :     seq[0] = "com.sun.star.ui.dialogs.ColorPicker";
    1430           0 :     return seq;
    1431             : }
    1432             : 
    1433           0 : ColorPicker::ColorPicker( Reference< XComponentContext > const & xContext )
    1434             : : ColorPickerBase( m_aMutex )
    1435             : , mxContext( xContext )
    1436             : , msColorKey( "Color" )
    1437             : , msModeKey( "Mode" )
    1438             : , mnColor( 0 )
    1439           0 : , mnMode( 0 )
    1440             : {
    1441           0 : }
    1442             : 
    1443             : // XInitialization
    1444           0 : void SAL_CALL ColorPicker::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException, std::exception)
    1445             : {
    1446           0 :     if( aArguments.getLength() == 1 )
    1447             :     {
    1448           0 :         aArguments[0] >>= mxParent;
    1449             :     }
    1450           0 : }
    1451             : 
    1452             : // XInitialization
    1453           0 : OUString SAL_CALL ColorPicker::getImplementationName(  ) throw (RuntimeException, std::exception)
    1454             : {
    1455           0 :     return ColorPicker_getImplementationName();
    1456             : }
    1457             : 
    1458           0 : sal_Bool SAL_CALL ColorPicker::supportsService( const OUString& sServiceName ) throw (RuntimeException, std::exception)
    1459             : {
    1460           0 :     return cppu::supportsService(this, sServiceName);
    1461             : }
    1462             : 
    1463           0 : Sequence< OUString > SAL_CALL ColorPicker::getSupportedServiceNames(  ) throw (RuntimeException, std::exception)
    1464             : {
    1465           0 :     return ColorPicker_getSupportedServiceNames();
    1466             : }
    1467             : 
    1468             : // XPropertyAccess
    1469           0 : Sequence< PropertyValue > SAL_CALL ColorPicker::getPropertyValues(  ) throw (RuntimeException, std::exception)
    1470             : {
    1471           0 :     Sequence< PropertyValue > props(1);
    1472           0 :     props[0].Name = msColorKey;
    1473           0 :     props[0].Value <<= mnColor;
    1474           0 :     return props;
    1475             : }
    1476             : 
    1477           0 : void SAL_CALL ColorPicker::setPropertyValues( const Sequence< PropertyValue >& aProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception)
    1478             : {
    1479           0 :     for( sal_Int32 n = 0; n < aProps.getLength(); n++ )
    1480             :     {
    1481           0 :         if( aProps[n].Name.equals( msColorKey ) )
    1482             :         {
    1483           0 :             aProps[n].Value >>= mnColor;
    1484             :         }
    1485           0 :         else if( aProps[n].Name.equals( msModeKey ) )
    1486             :         {
    1487           0 :             aProps[n].Value >>= mnMode;
    1488             :         }
    1489             :     }
    1490           0 : }
    1491             : 
    1492             : // XExecutableDialog
    1493           0 : void SAL_CALL ColorPicker::setTitle( const OUString& sTitle ) throw (RuntimeException, std::exception)
    1494             : {
    1495           0 :     msTitle = sTitle;
    1496           0 : }
    1497             : 
    1498           0 : sal_Int16 SAL_CALL ColorPicker::execute(  ) throw (RuntimeException, std::exception)
    1499             : {
    1500           0 :     ColorPickerDialog aDlg( VCLUnoHelper::GetWindow( mxParent ), mnColor, mnMode );
    1501           0 :     sal_Int16 ret = aDlg.Execute();
    1502           0 :     if( ret )
    1503           0 :         mnColor = aDlg.GetColor();
    1504             : 
    1505           0 :     return ret;
    1506             : }
    1507             : 
    1508           0 : }
    1509             : 
    1510             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10