bool CDEditor::AdjustRect(CRect& rect)
{
	CRect rcOld=rect;

	CPoint point = rect.TopLeft();
	CSize size = rect.Size();
	CSize sizeVt = GetVirtualSize();
	int restraint = GetRestraints();	

	if (RESTRAINT_NONE != restraint) {
		int left=0,top=0,right=sizeVt.cx,bottom=sizeVt.cy; // m_restraint == RESTRAINT_VIRTUAL
		if (restraint == RESTRAINT_MARGIN) {
			GetMargins(left,top,right,bottom);
			right = sizeVt.cx - right;
			bottom = sizeVt.cy - bottom;
		}
		point.x = min(max(left,point.x),right-size.cx);
		point.y = min(max(top,point.y),bottom-size.cy);
	}

	if (GetSnapToGrid()) {
		point.x = SnapX(point.x);
		point.y = SnapY(point.y);
	}

	rect.SetRect(point,point+size);

	return rcOld==rect;
}
void ControlPointsWidget::mouseReleaseEvent( QMouseEvent * evnt )
{
    if ( evnt->button() == Qt::LeftButton )
    {
	if ( m_bDragging )
	{
	    QRect rcBounds = m_rcChartPlotArea.adjusted(0,0,1,1);
	    QPoint pt = ClipPoint( rcBounds, evnt->pos() );

	    // Convert screen coordinates back to CPOINT coordinates.
	    m_Points[m_nFocusPoint].lP = SnapX(UnscaleX(pt.x()));
	    m_Points[m_nFocusPoint].dwLog = SnapY(UnscaleY(pt.y()));
	    m_bChanged = true;

	    CalculateWorkingData();
	    update();
	    m_bDragging = false;
	    SetMouseCursor( evnt->pos() );
	    //ReleaseCapture();
	}
    }
}
void ControlPointsWidget::mouseMoveEvent ( QMouseEvent * evnt )
{
    QPoint pt = evnt->pos();

    if ( !m_bDragging )
    {
	SetMouseCursor( pt );
    }
    else
    {
	QRect rcBounds = m_rcChartPlotArea.adjusted(0,0,1,1);
	if ( !rcBounds.contains(pt) )
	{
	    // Cursor trying to move out of area
	    pt = ClipPoint( rcBounds, pt );
	}

	// Invalidate the rectangle that bounds the old point and joining line segments.
	//int x = ScaleX(m_Points[m_nFocusPoint].lP);
	//int y = ScaleY(m_Points[m_nFocusPoint].dwLog);
	//x += m_ptDragOffset.x;
	//y += m_ptDragOffset.y;
	//x = SnapScreenX(x);
	//y = SnapY(y);
	int x = ScaleX(m_ptDragCPoint.x());
	int y = ScaleY(m_ptDragCPoint.y());

	QRect rcInvalid;
	if ( m_nFocusPoint == 0 )
	{
	    int x1 = ScaleX(m_Points[1].lP);
	    int y1 = ScaleY(m_Points[1].dwLog);
	    QRect rc1(x-3,y-3,x+3,y+3 );
	    QRect rc2(x1-3,y1-3,x1+3,y1+3 );

	    rc1 = rc1.normalized();
	    rc2 = rc2.normalized();

	    rc1.adjust(-1,-1,1,1);
	    rc2.adjust(-1,-1,1,1);
	    rcInvalid = rc1.united( rc2 );
	}
	else if ( m_nFocusPoint == (int)m_Points.size()-1 )
	{
	    int x1 = ScaleX(m_Points[m_nFocusPoint-1].lP);
	    int y1 = ScaleY(m_Points[m_nFocusPoint-1].dwLog);

	    QRect rc1(x-3,y-3,x+3,y+3 );
	    QRect rc2(x1-3,y1-3,x1+3,y1+3 );

	    rc1 = rc1.normalized();
	    rc2 = rc2.normalized();

	    rc1.adjust(-1,-1,1,1);
	    rc2.adjust(-1,-1,1,1);
	    rcInvalid = rc1.united( rc2 );
	}
	else
	{
	    QRect rc1(x-3,y-3,x+3,y+3 );
	    rc1 = rc1.normalized();
	    rc1.adjust(-1,-1,1,1);

	    int x1 = ScaleX(m_Points[m_nFocusPoint-1].lP);
	    int y1 = ScaleY(m_Points[m_nFocusPoint-1].dwLog);
	    QRect rc2(x1-3,y1-3,x1+3,y1+3 );
	    rc2 = rc2.normalized();
	    rc2.adjust(-1,-1,1,1);

	    x1 = ScaleX(m_Points[m_nFocusPoint+1].lP);
	    y1 = ScaleY(m_Points[m_nFocusPoint+1].dwLog);
	    QRect rc3(x1-3,y1-3,x1+3,y1+3 );
	    rc3 = rc3.normalized();
	    rc3.adjust(-1,-1,1,1);

	    QRect temp;
	    temp = rc1.united(rc2);
	    rcInvalid = temp.united( rc3 );
	}

	// Update the drag offset.  This will be repainted in the paint routine.
	//m_ptDragOffset = pt - m_ptDragPickup;
	m_ptDragCPoint.setX( SnapX(UnscaleX(pt.x())) );
	m_ptDragCPoint.setY( SnapY(UnscaleY(pt.y())) );
	update( rcInvalid );
    }

    //CRect rcBounds(m_rcChartPlotArea.left, m_rcChartPlotArea.top, m_rcChartPlotArea.right+1, m_rcChartPlotArea.bottom + 1 );
    //if ( rcBounds.PtInRect(pt) )
    //{
    //	int x = UnscaleX( SnapScreenX(pt.x ));
    //	int y = UnscaleY( SnapY(pt.y ));
    //	TRACE("%d, %d\n", x, y );
    //}


    if ( m_rcChartPlotArea.contains( pt ) )
	emit mousePositionChanged( SnapX(UnscaleX(pt.x())), SnapX(UnscaleY(pt.y())) );
}
void ControlPointsWidget::mousePressEvent ( QMouseEvent * evnt )
{
    if ( evnt->button() == Qt::LeftButton )
    {
	if ( m_nFocusPoint >= 0 )	// Have we "mousemoved" over a point
	{
	    setCursor( Qt::ClosedHandCursor );

	    m_bDragging = true;
	    //m_ptDragPickup = pt;
	    //m_ptDragOffset.SetPoint(0,0);
	    m_ptDragCPoint.setX( SnapX(UnscaleX(evnt->x())) );
	    m_ptDragCPoint.setY( SnapY(UnscaleY(evnt->y())) );
	    //SetCapture();
	}
    }
    else if ( evnt->button() == Qt::RightButton && !m_bDragging )
    {
	if ( m_nFocusPoint >= 0 )
	    m_pRemove->setEnabled( true );
	else
	    m_pRemove->setEnabled( false );
	QAction *pAction = m_pPopupMenu->exec( QCursor::pos() );
	if ( pAction == m_pAdd )
	{
	    int index;
	    if ( m_nFocusPoint == (int)m_Points.size() - 1 )
		index = m_Points.size() - 2;
	    else if ( m_nFocusPoint >= 0 )
		index = m_nFocusPoint;
	    else
	    {
		int x = UnscaleX(evnt->x());
		int y = UnscaleY(evnt->y());

		// find the closest points
		double min_diff = 1E20;
		int index2=0;
		double min2_diff = 1E20;
		index=0;
		for ( int i = 0; i < (int)m_Points.size(); i++ )
		{
		    double diff = (double)(m_Points[i].lP - x) * (double)(m_Points[i].lP - x) + (double)(m_Points[i].dwLog - y)*(double)(m_Points[i].dwLog - y);
		    if ( diff < min_diff )
		    {
			min2_diff = min_diff;
			index2 = index;
			min_diff = diff;
			index = i;
		    }
		    else if ( diff < min2_diff )
		    {
			min2_diff = diff;
			index2 = i;
		    }
		}

		if ( index2 < index )
		    index = index2;
	    }

	    CPoint pt( (m_Points[index].lP + m_Points[index+1].lP)/2, (m_Points[index].dwLog + m_Points[index+1].dwLog)/2 );
	    m_Points.insert( m_Points.begin() + index + 1, pt );
	    m_bChanged = true;
	    m_rcScreenPoints.resize(m_rcScreenPoints.size()+1);	// just add any screen point - all will be recalculated.
	    CalculateWorkingData();
	    update();
	}
	else if ( m_nFocusPoint >= 0 )
	{
	    if ( m_Points.size() > 2 )
	    {
		m_Points.erase( m_Points.begin() + m_nFocusPoint );
		m_bChanged = true;
		m_rcScreenPoints.pop_back();	// just remove any screen point - all will be recalculated.
		CalculateWorkingData();
		update();
	    }
	}
    }
}