LCOV - code coverage report
Current view: top level - extensions/source/scanner - grid.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 295 0.0 %
Date: 2014-04-14 Functions: 0 25 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 <sal/config.h>
      21             : #include <osl/thread.h>
      22             : #include <grid.hrc>
      23             : #include <cstdio>
      24             : #include <math.h>
      25             : 
      26             : #include <cmath>
      27             : 
      28             : #include <grid.hxx>
      29             : 
      30             : // for ::std::sort
      31             : #include <algorithm>
      32             : #include <boost/scoped_array.hpp>
      33             : 
      34             : ResId SaneResId( sal_uInt32 );
      35             : 
      36             : /***********************************************************************
      37             :  *
      38             :  *  GridWindow
      39             :  *
      40             :  ***********************************************************************/
      41             : 
      42             : 
      43             : 
      44           0 : GridWindow::GridWindow(double* pXValues, double* pYValues, int nValues, Window* pParent, sal_Bool bCutValues )
      45             : :   ModalDialog( pParent, SaneResId( GRID_DIALOG ) ),
      46             :     m_aGridArea( 50, 15, 100, 100 ),
      47             :     m_pXValues( pXValues ),
      48             :     m_pOrigYValues( pYValues ),
      49             :     m_nValues( nValues ),
      50             :     m_pNewYValues( NULL ),
      51             :     m_bCutValues( bCutValues ),
      52             :     m_aHandles(),
      53             :     m_nDragIndex( 0xffffffff ),
      54             :     m_aMarkerBitmap( Bitmap( SaneResId( GRID_DIALOG_HANDLE_BMP ) ), Color( 255, 255, 255 ) ),
      55             :     m_aOKButton( this, SaneResId( GRID_DIALOG_OK_BTN ) ),
      56             :     m_aCancelButton( this, SaneResId( GRID_DIALOG_CANCEL_BTN ) ),
      57             :     m_aResetTypeBox( this, SaneResId( GRID_DIALOG_TYPE_BOX ) ),
      58           0 :     m_aResetButton( this, SaneResId( GRID_DIALOG_RESET_BTN ) )
      59             : {
      60           0 :     sal_uInt16 nPos = m_aResetTypeBox.InsertEntry( SaneResId( RESET_TYPE_LINEAR_ASCENDING ).toString() );
      61           0 :     m_aResetTypeBox.SetEntryData( nPos, (void *)RESET_TYPE_LINEAR_ASCENDING );
      62             : 
      63           0 :     nPos = m_aResetTypeBox.InsertEntry( SaneResId( RESET_TYPE_LINEAR_DESCENDING ).toString() );
      64           0 :     m_aResetTypeBox.SetEntryData( nPos, (void *)RESET_TYPE_LINEAR_DESCENDING );
      65             : 
      66           0 :     nPos = m_aResetTypeBox.InsertEntry( SaneResId( RESET_TYPE_RESET ).toString() );
      67           0 :     m_aResetTypeBox.SetEntryData( nPos, (void *)RESET_TYPE_RESET );
      68             : 
      69           0 :     nPos = m_aResetTypeBox.InsertEntry( SaneResId( RESET_TYPE_EXPONENTIAL ).toString() );
      70           0 :     m_aResetTypeBox.SetEntryData( nPos, (void *)RESET_TYPE_EXPONENTIAL );
      71             : 
      72           0 :     m_aResetTypeBox.SelectEntryPos( 0 );
      73             : 
      74           0 :     m_aResetButton.SetClickHdl( LINK( this, GridWindow, ClickButtonHdl ) );
      75             : 
      76           0 :     SetMapMode( MapMode( MAP_PIXEL ) );
      77           0 :     Size aSize = GetOutputSizePixel();
      78           0 :     Size aBtnSize = m_aOKButton.GetOutputSizePixel();
      79           0 :     m_aGridArea.setWidth( aSize.Width() - aBtnSize.Width() - 80 );
      80           0 :     m_aGridArea.setHeight( aSize.Height() - 40 );
      81             : 
      82           0 :     if( m_pOrigYValues && m_nValues )
      83             :     {
      84           0 :         m_pNewYValues = new double[ m_nValues ];
      85           0 :         memcpy( m_pNewYValues, m_pOrigYValues, sizeof( double ) * m_nValues );
      86             :     }
      87             : 
      88           0 :     setBoundings( 0, 0, 1023, 1023 );
      89           0 :     computeExtremes();
      90             : 
      91             :     // create left and right marker as first and last entry
      92           0 :     m_BmOffX = sal_uInt16(m_aMarkerBitmap.GetSizePixel().Width() >> 1);
      93           0 :     m_BmOffY = sal_uInt16(m_aMarkerBitmap.GetSizePixel().Height() >> 1);
      94           0 :     m_aHandles.push_back(impHandle(transform(findMinX(), findMinY()), m_BmOffX, m_BmOffY));
      95           0 :     m_aHandles.push_back(impHandle(transform(findMaxX(), findMaxY()), m_BmOffX, m_BmOffY));
      96             : 
      97           0 :     FreeResource();
      98           0 : }
      99             : 
     100           0 : GridWindow::~GridWindow()
     101             : {
     102           0 :     delete [] m_pNewYValues;
     103           0 : }
     104             : 
     105           0 : double GridWindow::findMinX()
     106             : {
     107           0 :     if( ! m_pXValues )
     108           0 :         return 0.0;
     109           0 :     double fMin = m_pXValues[0];
     110           0 :     for( int i = 1; i < m_nValues; i++ )
     111           0 :         if( m_pXValues[ i ] < fMin )
     112           0 :             fMin = m_pXValues[ i ];
     113           0 :     return fMin;
     114             : }
     115             : 
     116             : 
     117             : 
     118           0 : double GridWindow::findMinY()
     119             : {
     120           0 :     if( ! m_pNewYValues )
     121           0 :         return 0.0;
     122           0 :     double fMin = m_pNewYValues[0];
     123           0 :     for( int i = 1; i < m_nValues; i++ )
     124           0 :         if( m_pNewYValues[ i ] < fMin )
     125           0 :             fMin = m_pNewYValues[ i ];
     126           0 :     return fMin;
     127             : }
     128             : 
     129             : 
     130             : 
     131           0 : double GridWindow::findMaxX()
     132             : {
     133           0 :     if( ! m_pXValues )
     134           0 :         return 0.0;
     135           0 :     double fMax = m_pXValues[0];
     136           0 :     for( int i = 1; i < m_nValues; i++ )
     137           0 :         if( m_pXValues[ i ] > fMax )
     138           0 :             fMax = m_pXValues[ i ];
     139           0 :     return fMax;
     140             : }
     141             : 
     142             : 
     143             : 
     144           0 : double GridWindow::findMaxY()
     145             : {
     146           0 :     if( ! m_pNewYValues )
     147           0 :         return 0.0;
     148           0 :     double fMax = m_pNewYValues[0];
     149           0 :     for( int i = 1; i < m_nValues; i++ )
     150           0 :         if( m_pNewYValues[ i ] > fMax )
     151           0 :             fMax = m_pNewYValues[ i ];
     152           0 :     return fMax;
     153             : }
     154             : 
     155             : 
     156             : 
     157           0 : void GridWindow::computeExtremes()
     158             : {
     159           0 :     if( m_nValues && m_pXValues && m_pOrigYValues )
     160             :     {
     161           0 :         m_fMaxX = m_fMinX = m_pXValues[0];
     162           0 :         m_fMaxY = m_fMinY = m_pOrigYValues[0];
     163           0 :         for( int i = 1; i < m_nValues; i++ )
     164             :         {
     165           0 :             if( m_pXValues[ i ] > m_fMaxX )
     166           0 :                 m_fMaxX = m_pXValues[ i ];
     167           0 :             else if( m_pXValues[ i ] < m_fMinX )
     168           0 :                 m_fMinX = m_pXValues[ i ];
     169           0 :             if( m_pOrigYValues[ i ] > m_fMaxY )
     170           0 :                 m_fMaxY = m_pOrigYValues[ i ];
     171           0 :             else if( m_pOrigYValues[ i ] < m_fMinY )
     172           0 :                 m_fMinY = m_pOrigYValues[ i ];
     173             :         }
     174           0 :         setBoundings( m_fMinX, m_fMinY, m_fMaxX, m_fMaxY );
     175             :     }
     176           0 : }
     177             : 
     178             : 
     179             : 
     180           0 : Point GridWindow::transform( double x, double y )
     181             : {
     182           0 :     Point aRet;
     183             : 
     184           0 :     aRet.X() = (long)( ( x - m_fMinX ) *
     185           0 :         (double)m_aGridArea.GetWidth() / ( m_fMaxX - m_fMinX )
     186           0 :         + m_aGridArea.Left() );
     187           0 :     aRet.Y() = (long)(
     188           0 :         m_aGridArea.Bottom() -
     189           0 :         ( y - m_fMinY ) *
     190           0 :         (double)m_aGridArea.GetHeight() / ( m_fMaxY - m_fMinY ) );
     191           0 :     return aRet;
     192             : }
     193             : 
     194             : 
     195             : 
     196           0 : void GridWindow::transform( const Point& rOriginal, double& x, double& y )
     197             : {
     198           0 :     x = ( rOriginal.X() - m_aGridArea.Left() ) * (m_fMaxX - m_fMinX) / (double)m_aGridArea.GetWidth() + m_fMinX;
     199           0 :     y = ( m_aGridArea.Bottom() - rOriginal.Y() ) * (m_fMaxY - m_fMinY) / (double)m_aGridArea.GetHeight() + m_fMinY;
     200           0 : }
     201             : 
     202             : 
     203             : 
     204           0 : void GridWindow::drawLine( double x1, double y1, double x2, double y2 )
     205             : {
     206           0 :     DrawLine( transform( x1, y1 ), transform( x2, y2 ) );
     207           0 : }
     208             : 
     209             : 
     210             : 
     211           0 : void GridWindow::computeChunk( double fMin, double fMax, double& fChunkOut, double& fMinChunkOut )
     212             : {
     213             :     // get a nice chunk size like 10, 100, 25 or such
     214           0 :     fChunkOut = ( fMax - fMin ) / 6.0;
     215           0 :     int logchunk = (int)std::log10( fChunkOut );
     216           0 :     int nChunk = (int)( fChunkOut / std::exp( (double)(logchunk-1) * M_LN10 ) );
     217           0 :     if( nChunk >= 75 )
     218           0 :         nChunk = 100;
     219           0 :     else if( nChunk >= 35 )
     220           0 :         nChunk = 50;
     221           0 :     else if ( nChunk > 20 )
     222           0 :         nChunk = 25;
     223           0 :     else if ( nChunk >= 13 )
     224           0 :         nChunk = 20;
     225           0 :     else if( nChunk > 5 )
     226           0 :         nChunk = 10;
     227             :     else
     228           0 :         nChunk = 5;
     229           0 :     fChunkOut = (double) nChunk * exp( (double)(logchunk-1) * M_LN10 );
     230             :     // compute whole chunks fitting into fMin
     231           0 :     nChunk = (int)( fMin / fChunkOut );
     232           0 :     fMinChunkOut = (double)nChunk * fChunkOut;
     233           0 :     while( fMinChunkOut < fMin )
     234           0 :         fMinChunkOut += fChunkOut;
     235           0 : }
     236             : 
     237             : 
     238             : 
     239           0 : void GridWindow::computeNew()
     240             : {
     241           0 :     if(2L == m_aHandles.size())
     242             :     {
     243             :         // special case: only left and right markers
     244             :         double xleft, yleft;
     245             :         double xright, yright;
     246           0 :         transform(m_aHandles[0L].maPos, xleft, yleft);
     247           0 :         transform(m_aHandles[1L].maPos, xright, yright );
     248           0 :         double factor = (yright-yleft)/(xright-xleft);
     249           0 :         for( int i = 0; i < m_nValues; i++ )
     250             :         {
     251           0 :             m_pNewYValues[ i ] = yleft + ( m_pXValues[ i ] - xleft )*factor;
     252             :         }
     253             :     }
     254             :     else
     255             :     {
     256             :         // sort markers
     257           0 :         std::sort(m_aHandles.begin(), m_aHandles.end());
     258           0 :         const int nSorted = m_aHandles.size();
     259             :         int i;
     260             : 
     261             :         // get node arrays
     262           0 :         boost::scoped_array<double> nodex(new double[ nSorted ]);
     263           0 :         boost::scoped_array<double> nodey(new double[ nSorted ]);
     264             : 
     265           0 :         for( i = 0L; i < nSorted; i++ )
     266           0 :             transform( m_aHandles[i].maPos, nodex[ i ], nodey[ i ] );
     267             : 
     268           0 :         for( i = 0; i < m_nValues; i++ )
     269             :         {
     270           0 :             double x = m_pXValues[ i ];
     271           0 :             m_pNewYValues[ i ] = interpolate( x, nodex.get(), nodey.get(), nSorted );
     272           0 :             if( m_bCutValues )
     273             :             {
     274           0 :                 if( m_pNewYValues[ i ] > m_fMaxY )
     275           0 :                     m_pNewYValues[ i ] = m_fMaxY;
     276           0 :                 else if( m_pNewYValues[ i ] < m_fMinY )
     277           0 :                     m_pNewYValues[ i ] = m_fMinY;
     278             :             }
     279           0 :         }
     280             :     }
     281           0 : }
     282             : 
     283             : 
     284             : 
     285           0 : double GridWindow::interpolate(
     286             :     double x,
     287             :     double* pNodeX,
     288             :     double* pNodeY,
     289             :     int nNodes )
     290             : {
     291             :     // compute Lagrange interpolation
     292           0 :     double ret = 0;
     293           0 :     for( int i = 0; i < nNodes; i++ )
     294             :     {
     295           0 :         double sum = pNodeY[ i ];
     296           0 :         for( int n = 0; n < nNodes; n++ )
     297             :         {
     298           0 :             if( n != i )
     299             :             {
     300           0 :                 sum *= x - pNodeX[ n ];
     301           0 :                 sum /= pNodeX[ i ] - pNodeX[ n ];
     302             :             }
     303             :         }
     304           0 :         ret += sum;
     305             :     }
     306           0 :     return ret;
     307             : }
     308             : 
     309             : 
     310             : 
     311           0 : void GridWindow::setBoundings( double fMinX, double fMinY, double fMaxX, double fMaxY )
     312             : {
     313           0 :     m_fMinX = fMinX;
     314           0 :     m_fMinY = fMinY;
     315           0 :     m_fMaxX = fMaxX;
     316           0 :     m_fMaxY = fMaxY;
     317             : 
     318           0 :     computeChunk( m_fMinX, m_fMaxX, m_fChunkX, m_fMinChunkX );
     319           0 :     computeChunk( m_fMinY, m_fMaxY, m_fChunkY, m_fMinChunkY );
     320           0 : }
     321             : 
     322             : 
     323             : 
     324           0 : void GridWindow::drawGrid()
     325             : {
     326             :     char pBuf[256];
     327           0 :     SetLineColor( Color( COL_BLACK ) );
     328             :     // draw vertical lines
     329           0 :     for( double fX = m_fMinChunkX; fX < m_fMaxX; fX += m_fChunkX )
     330             :     {
     331           0 :         drawLine( fX, m_fMinY, fX, m_fMaxY );
     332             :         // draw tickmarks
     333           0 :         Point aPt = transform( fX, m_fMinY );
     334           0 :         std::sprintf( pBuf, "%g", fX );
     335           0 :         OUString aMark( pBuf, strlen(pBuf), osl_getThreadTextEncoding() );
     336           0 :         Size aTextSize( GetTextWidth( aMark ), GetTextHeight() );
     337           0 :         aPt.X() -= aTextSize.Width()/2;
     338           0 :         aPt.Y() += aTextSize.Height()/2;
     339           0 :         DrawText( aPt, aMark );
     340           0 :     }
     341             :     // draw horizontal lines
     342           0 :     for( double fY = m_fMinChunkY; fY < m_fMaxY; fY += m_fChunkY )
     343             :     {
     344           0 :         drawLine( m_fMinX, fY, m_fMaxX, fY );
     345             :         // draw tickmarks
     346           0 :         Point aPt = transform( m_fMinX, fY );
     347           0 :         std::sprintf( pBuf, "%g", fY );
     348           0 :         OUString aMark( pBuf, strlen(pBuf), osl_getThreadTextEncoding() );
     349           0 :         Size aTextSize( GetTextWidth( aMark ), GetTextHeight() );
     350           0 :         aPt.X() -= aTextSize.Width() + 2;
     351           0 :         aPt.Y() -= aTextSize.Height()/2;
     352           0 :         DrawText( aPt, aMark );
     353           0 :     }
     354             : 
     355             :     // draw boundings
     356           0 :     drawLine( m_fMinX, m_fMinY, m_fMaxX, m_fMinY );
     357           0 :     drawLine( m_fMinX, m_fMaxY, m_fMaxX, m_fMaxY );
     358           0 :     drawLine( m_fMinX, m_fMinY, m_fMinX, m_fMaxY );
     359           0 :     drawLine( m_fMaxX, m_fMinY, m_fMaxX, m_fMaxY );
     360           0 : }
     361             : 
     362             : 
     363             : 
     364           0 : void GridWindow::drawOriginal()
     365             : {
     366           0 :     if( m_nValues && m_pXValues && m_pOrigYValues )
     367             :     {
     368           0 :         SetLineColor( Color( COL_RED ) );
     369           0 :         for( int i = 0; i < m_nValues-1; i++ )
     370             :         {
     371           0 :             drawLine( m_pXValues[ i   ], m_pOrigYValues[ i   ],
     372           0 :                       m_pXValues[ i+1 ], m_pOrigYValues[ i+1 ] );
     373             :         }
     374             :     }
     375           0 : }
     376             : 
     377             : 
     378             : 
     379           0 : void GridWindow::drawNew()
     380             : {
     381           0 :     if( m_nValues && m_pXValues && m_pNewYValues )
     382             :     {
     383           0 :         SetClipRegion(Region(m_aGridArea));
     384           0 :         SetLineColor( Color( COL_YELLOW ) );
     385           0 :         for( int i = 0; i < m_nValues-1; i++ )
     386             :         {
     387           0 :             drawLine( m_pXValues[ i   ], m_pNewYValues[ i   ],
     388           0 :                       m_pXValues[ i+1 ], m_pNewYValues[ i+1 ] );
     389             :         }
     390           0 :         SetClipRegion();
     391             :     }
     392           0 : }
     393             : 
     394             : 
     395             : 
     396           0 : void GridWindow::drawHandles()
     397             : {
     398           0 :     for(sal_uInt32 i(0L); i < m_aHandles.size(); i++)
     399             :     {
     400           0 :         m_aHandles[i].draw(*this, m_aMarkerBitmap);
     401             :     }
     402           0 : }
     403             : 
     404             : 
     405             : 
     406           0 : void GridWindow::Paint( const Rectangle& rRect )
     407             : {
     408           0 :     ModalDialog::Paint( rRect );
     409           0 :     drawGrid();
     410           0 :     drawOriginal();
     411           0 :     drawNew();
     412           0 :     drawHandles();
     413           0 : }
     414             : 
     415             : 
     416             : 
     417           0 : void GridWindow::MouseMove( const MouseEvent& rEvt )
     418             : {
     419           0 :     if( rEvt.GetButtons() == MOUSE_LEFT && m_nDragIndex != 0xffffffff )
     420             :     {
     421           0 :         Point aPoint( rEvt.GetPosPixel() );
     422             : 
     423           0 :         if( m_nDragIndex == 0L || m_nDragIndex == m_aHandles.size() - 1L)
     424             :         {
     425           0 :             aPoint.X() = m_aHandles[m_nDragIndex].maPos.X();
     426             :         }
     427             :         else
     428             :         {
     429           0 :             if(aPoint.X() < m_aGridArea.Left())
     430           0 :                 aPoint.X() = m_aGridArea.Left();
     431           0 :             else if(aPoint.X() > m_aGridArea.Right())
     432           0 :                 aPoint.X() = m_aGridArea.Right();
     433             :         }
     434             : 
     435           0 :         if( aPoint.Y() < m_aGridArea.Top() )
     436           0 :             aPoint.Y() = m_aGridArea.Top();
     437           0 :         else if( aPoint.Y() > m_aGridArea.Bottom() )
     438           0 :             aPoint.Y() = m_aGridArea.Bottom();
     439             : 
     440           0 :         if( aPoint != m_aHandles[m_nDragIndex].maPos )
     441             :         {
     442           0 :             m_aHandles[m_nDragIndex].maPos = aPoint;
     443           0 :             Invalidate( m_aGridArea );
     444             :         }
     445             :     }
     446             : 
     447           0 :     ModalDialog::MouseMove( rEvt );
     448           0 : }
     449             : 
     450             : 
     451             : 
     452           0 : void GridWindow::MouseButtonUp( const MouseEvent& rEvt )
     453             : {
     454           0 :     if( rEvt.GetButtons() == MOUSE_LEFT )
     455             :     {
     456           0 :         if( m_nDragIndex != 0xffffffff )
     457             :         {
     458           0 :             m_nDragIndex = 0xffffffff;
     459           0 :             computeNew();
     460           0 :             Invalidate( m_aGridArea );
     461           0 :             Paint( m_aGridArea );
     462             :         }
     463             :     }
     464             : 
     465           0 :     ModalDialog::MouseButtonUp( rEvt );
     466           0 : }
     467             : 
     468             : 
     469             : 
     470           0 : void GridWindow::MouseButtonDown( const MouseEvent& rEvt )
     471             : {
     472           0 :     Point aPoint( rEvt.GetPosPixel() );
     473           0 :     sal_uInt32 nMarkerIndex = 0xffffffff;
     474             : 
     475           0 :     for(sal_uInt32 a(0L); nMarkerIndex == 0xffffffff && a < m_aHandles.size(); a++)
     476             :     {
     477           0 :         if(m_aHandles[a].isHit(*this, aPoint))
     478             :         {
     479           0 :             nMarkerIndex = a;
     480             :         }
     481             :     }
     482             : 
     483           0 :     if( rEvt.GetButtons() == MOUSE_LEFT )
     484             :     {
     485             :         // user wants to drag a button
     486           0 :         if( nMarkerIndex != 0xffffffff )
     487             :         {
     488           0 :             m_nDragIndex = nMarkerIndex;
     489             :         }
     490             :     }
     491           0 :     else if( rEvt.GetButtons() == MOUSE_RIGHT )
     492             :     {
     493             :         // user wants to add/delete a button
     494           0 :         if( nMarkerIndex != 0xffffffff )
     495             :         {
     496           0 :             if( nMarkerIndex != 0L && nMarkerIndex != m_aHandles.size() - 1L)
     497             :             {
     498             :                 // delete marker under mouse
     499           0 :                 if( m_nDragIndex == nMarkerIndex )
     500           0 :                     m_nDragIndex = 0xffffffff;
     501             : 
     502           0 :                 m_aHandles.erase(m_aHandles.begin() + nMarkerIndex);
     503             :             }
     504             :         }
     505             :         else
     506             :         {
     507           0 :             m_BmOffX = sal_uInt16(m_aMarkerBitmap.GetSizePixel().Width() >> 1);
     508           0 :             m_BmOffY = sal_uInt16(m_aMarkerBitmap.GetSizePixel().Height() >> 1);
     509           0 :             m_aHandles.push_back(impHandle(aPoint, m_BmOffX, m_BmOffY));
     510             :         }
     511             : 
     512           0 :         computeNew();
     513           0 :         Invalidate( m_aGridArea );
     514           0 :         Paint( m_aGridArea );
     515             :     }
     516             : 
     517           0 :     ModalDialog::MouseButtonDown( rEvt );
     518           0 : }
     519             : 
     520             : 
     521             : 
     522           0 : IMPL_LINK( GridWindow, ClickButtonHdl, Button*, pButton )
     523             : {
     524           0 :     if( pButton == &m_aResetButton )
     525             :     {
     526           0 :         int nType = (int)(sal_IntPtr)m_aResetTypeBox.GetEntryData( m_aResetTypeBox.GetSelectEntryPos() );
     527           0 :         switch( nType )
     528             :         {
     529             :             case RESET_TYPE_LINEAR_ASCENDING:
     530             :             {
     531           0 :                 for( int i = 0; i < m_nValues; i++ )
     532             :                 {
     533           0 :                     m_pNewYValues[ i ] = m_fMinY + (m_fMaxY-m_fMinY)/(m_fMaxX-m_fMinX)*(m_pXValues[i]-m_fMinX);
     534             :                 }
     535             :             }
     536           0 :             break;
     537             :             case RESET_TYPE_LINEAR_DESCENDING:
     538             :             {
     539           0 :                 for( int i = 0; i < m_nValues; i++ )
     540             :                 {
     541           0 :                     m_pNewYValues[ i ] = m_fMaxY - (m_fMaxY-m_fMinY)/(m_fMaxX-m_fMinX)*(m_pXValues[i]-m_fMinX);
     542             :                 }
     543             :             }
     544           0 :             break;
     545             :             case RESET_TYPE_RESET:
     546             :             {
     547           0 :                 if( m_pOrigYValues && m_pNewYValues && m_nValues )
     548           0 :                     memcpy( m_pNewYValues, m_pOrigYValues, m_nValues*sizeof(double) );
     549             :             }
     550           0 :             break;
     551             :             case RESET_TYPE_EXPONENTIAL:
     552             :             {
     553           0 :                 for( int i = 0; i < m_nValues; i++ )
     554             :                 {
     555           0 :                     m_pNewYValues[ i ] = m_fMinY + (m_fMaxY-m_fMinY)*(std::exp((m_pXValues[i]-m_fMinX)/(m_fMaxX-m_fMinX))-1.0)/(M_E-1.0);
     556             :                 }
     557             :             }
     558           0 :             break;
     559             : 
     560             :             default:
     561           0 :                 break;
     562             :         }
     563             : 
     564           0 :         if (m_pNewYValues)
     565             :         {
     566           0 :             for(sal_uInt32 i(0L); i < m_aHandles.size(); i++)
     567             :             {
     568             :                 // find nearest xvalue
     569             :                 double x, y;
     570           0 :                 transform( m_aHandles[i].maPos, x, y );
     571           0 :                 int nIndex = 0;
     572           0 :                 double delta = std::fabs( x-m_pXValues[0] );
     573           0 :                 for( int n = 1; n < m_nValues; n++ )
     574             :                 {
     575           0 :                     if( delta > std::fabs( x - m_pXValues[ n ] ) )
     576             :                     {
     577           0 :                         delta = std::fabs( x - m_pXValues[ n ] );
     578           0 :                         nIndex = n;
     579             :                     }
     580             :                 }
     581           0 :                 if( 0 == i )
     582           0 :                     m_aHandles[i].maPos = transform( m_fMinX, m_pNewYValues[ nIndex ] );
     583           0 :                 else if( m_aHandles.size() - 1L == i )
     584           0 :                     m_aHandles[i].maPos = transform( m_fMaxX, m_pNewYValues[ nIndex ] );
     585             :                 else
     586           0 :                     m_aHandles[i].maPos = transform( m_pXValues[ nIndex ], m_pNewYValues[ nIndex ] );
     587             :             }
     588             :         }
     589             : 
     590           0 :         Invalidate( m_aGridArea );
     591           0 :         Paint(Rectangle());
     592             :     }
     593           0 :     return 0;
     594             : }
     595             : 
     596             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10