Commit 07db7c8d authored by Blair Bonnett's avatar Blair Bonnett Committed by Wayne Stambaugh
Browse files

Prevent Pcbnew edit graphics property dialog from excepting zero length...

Prevent Pcbnew edit graphics property dialog from excepting zero length objects.  (fixes lp:1392117)
parent 88ce5920
Loading
Loading
Loading
Loading
+124 −48
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2010 Jean-Pierre Charras <jp.charras@wanadoo.fr>
 * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
 * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
@@ -49,6 +49,7 @@

#include <dialog_graphic_item_properties_base.h>
#include <class_pcb_layer_box_selector.h>
#include <html_messagebox.h>


class DIALOG_GRAPHIC_ITEM_PROPERTIES : public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE
@@ -56,7 +57,7 @@ class DIALOG_GRAPHIC_ITEM_PROPERTIES: public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE
private:
    PCB_EDIT_FRAME*       m_parent;
    wxDC*                 m_DC;
    DRAWSEGMENT* m_Item;
    DRAWSEGMENT*          m_item;
    BOARD_DESIGN_SETTINGS m_brdSettings;

public:
@@ -68,6 +69,7 @@ private:
    void OnOkClick( wxCommandEvent& event );
    void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
    void OnLayerChoice( wxCommandEvent& event );
    bool itemValuesOK();
};

DIALOG_GRAPHIC_ITEM_PROPERTIES::DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_EDIT_FRAME* aParent,
@@ -76,7 +78,7 @@ DIALOG_GRAPHIC_ITEM_PROPERTIES::DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_EDIT_FRAME*
{
    m_parent = aParent;
    m_DC = aDC;
    m_Item = aItem;
    m_item = aItem;
    m_brdSettings = m_parent->GetDesignSettings();
    initDlg();
    Layout();
@@ -87,11 +89,7 @@ DIALOG_GRAPHIC_ITEM_PROPERTIES::DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_EDIT_FRAME*

void PCB_EDIT_FRAME::InstallGraphicItemPropertiesDialog( DRAWSEGMENT* aItem, wxDC* aDC )
{
    if ( aItem == NULL )
    {
        DisplayError( this, wxT( "InstallGraphicItemPropertiesDialog() error: NULL item" ) );
        return;
    }
    wxCHECK_RET( aItem != NULL, wxT( "InstallGraphicItemPropertiesDialog() error: NULL item" ) );

    m_canvas->SetIgnoreMouseEvents( true );
    DIALOG_GRAPHIC_ITEM_PROPERTIES dlg( this, aItem, aDC );
@@ -128,9 +126,10 @@ void DIALOG_GRAPHIC_ITEM_PROPERTIES::initDlg( )
    wxString msg;

    // Change texts according to the segment shape:
    switch ( m_Item->GetShape() )
    switch( m_item->GetShape() )
    {
    case S_CIRCLE:
        SetTitle( _( "Circle Properties" ) );
        m_StartPointXLabel->SetLabel( _( "Center X" ) );
        m_StartPointYLabel->SetLabel( _( "Center Y" ) );
        m_EndPointXLabel->SetLabel( _( "Point X" ) );
@@ -141,16 +140,21 @@ void DIALOG_GRAPHIC_ITEM_PROPERTIES::initDlg( )
        break;

    case S_ARC:
        SetTitle( _( "Arc Properties" ) );
        m_StartPointXLabel->SetLabel( _( "Center X" ) );
        m_StartPointYLabel->SetLabel( _( "Center Y" ) );
        m_EndPointXLabel->SetLabel( _( "Start Point X" ) );
        m_EndPointYLabel->SetLabel( _( "Start Point Y" ) );

        // Here the angle is a double, but the UI is still working with integers.
        msg << int( m_Item->GetAngle() );
        msg << int( m_item->GetAngle() );
        m_Angle_Ctrl->SetValue( msg );
        break;

    case S_SEGMENT:
        SetTitle( _( "Line Segment Properties" ) );

        // Fall through.
    default:
        m_Angle_Text->Show( false );
        m_Angle_Ctrl->Show( false );
@@ -158,19 +162,19 @@ void DIALOG_GRAPHIC_ITEM_PROPERTIES::initDlg( )
        break;
    }

    PutValueInLocalUnits( *m_Center_StartXCtrl, m_Item->GetStart().x );
    PutValueInLocalUnits( *m_Center_StartXCtrl, m_item->GetStart().x );

    PutValueInLocalUnits( *m_Center_StartYCtrl, m_Item->GetStart().y );
    PutValueInLocalUnits( *m_Center_StartYCtrl, m_item->GetStart().y );

    PutValueInLocalUnits( *m_EndX_Radius_Ctrl, m_Item->GetEnd().x );
    PutValueInLocalUnits( *m_EndX_Radius_Ctrl, m_item->GetEnd().x );

    PutValueInLocalUnits( *m_EndY_Ctrl, m_Item->GetEnd().y );
    PutValueInLocalUnits( *m_EndY_Ctrl, m_item->GetEnd().y );

    PutValueInLocalUnits( *m_ThicknessCtrl, m_Item->GetWidth() );
    PutValueInLocalUnits( *m_ThicknessCtrl, m_item->GetWidth() );

    int thickness;

    if( m_Item->GetLayer() == Edge_Cuts )
    if( m_item->GetLayer() == Edge_Cuts )
        thickness = m_brdSettings.m_EdgeSegmentWidth;
    else
        thickness = m_brdSettings.m_DrawSegmentWidth;
@@ -183,10 +187,10 @@ void DIALOG_GRAPHIC_ITEM_PROPERTIES::initDlg( )
    m_LayerSelectionCtrl->SetBoardFrame( m_parent );
    m_LayerSelectionCtrl->Resync();

    if( m_LayerSelectionCtrl->SetLayerSelection( m_Item->GetLayer() ) < 0 )
    if( m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() ) < 0 )
    {
        wxMessageBox( _( "This item has an illegal layer id.\n"
                         "Now, forced on the drawings layer. Please, fix it" ) );
        wxMessageBox( _( "This item was on an unknown layer.\n"
                         "It has been moved to the drawings layer. Please fix it." ) );
        m_LayerSelectionCtrl->SetLayerSelection( Dwgs_User );
    }
}
@@ -207,54 +211,126 @@ void DIALOG_GRAPHIC_ITEM_PROPERTIES::OnLayerChoice( wxCommandEvent& event )

void DIALOG_GRAPHIC_ITEM_PROPERTIES::OnOkClick( wxCommandEvent& event )
{
    m_parent->SaveCopyInUndoList( m_Item, UR_CHANGED );
    if( !itemValuesOK() )
        return;

    m_parent->SaveCopyInUndoList( m_item, UR_CHANGED );

    wxString msg;

    if( m_DC )
        m_Item->Draw( m_parent->GetCanvas(), m_DC, GR_XOR );
        m_item->Draw( m_parent->GetCanvas(), m_DC, GR_XOR );

    msg = m_Center_StartXCtrl->GetValue();
    m_Item->SetStartX( ValueFromString( g_UserUnit, msg ) );
    m_item->SetStartX( ValueFromString( g_UserUnit, msg ) );

    msg = m_Center_StartYCtrl->GetValue();
    m_Item->SetStartY( ValueFromString( g_UserUnit, msg ) );
    m_item->SetStartY( ValueFromString( g_UserUnit, msg ) );

    msg = m_EndX_Radius_Ctrl->GetValue();
    m_Item->SetEndX( ValueFromString( g_UserUnit, msg ) );
    m_item->SetEndX( ValueFromString( g_UserUnit, msg ) );

    msg = m_EndY_Ctrl->GetValue();
    m_Item->SetEndY( ValueFromString( g_UserUnit, msg ) );
    m_item->SetEndY( ValueFromString( g_UserUnit, msg ) );

    msg = m_ThicknessCtrl->GetValue();
    m_Item->SetWidth( ValueFromString( g_UserUnit, msg ) );
    m_item->SetWidth( ValueFromString( g_UserUnit, msg ) );

    msg = m_DefaultThicknessCtrl->GetValue();
    int thickness = ValueFromString( g_UserUnit, msg );

    m_Item->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) );
    m_item->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) );

    if( m_Item->GetLayer() == Edge_Cuts )
    if( m_item->GetLayer() == Edge_Cuts )
        m_brdSettings.m_EdgeSegmentWidth = thickness;
    else
        m_brdSettings.m_DrawSegmentWidth = thickness;

    if( m_Item->GetShape() == S_ARC )
    if( m_item->GetShape() == S_ARC )
    {
        double angle;
        m_Angle_Ctrl->GetValue().ToDouble( &angle );
        NORMALIZE_ANGLE_360( angle );
        m_Item->SetAngle( angle );
        m_item->SetAngle( angle );
    }

    m_parent->OnModify();

    if( m_DC )
        m_Item->Draw( m_parent->GetCanvas(), m_DC, GR_OR );
        m_item->Draw( m_parent->GetCanvas(), m_DC, GR_OR );

    m_parent->SetMsgPanel( m_Item );
    m_parent->SetMsgPanel( m_item );

    m_parent->SetDesignSettings( m_brdSettings );

    Close( true );
}


bool DIALOG_GRAPHIC_ITEM_PROPERTIES::itemValuesOK()
{
    wxArrayString error_msgs;

    // Load the start and end points -- all types use these in the checks.
    int startx = ValueFromString( g_UserUnit, m_Center_StartXCtrl->GetValue() );
    int starty = ValueFromString( g_UserUnit, m_Center_StartYCtrl->GetValue() );
    int endx   = ValueFromString( g_UserUnit, m_EndX_Radius_Ctrl->GetValue() );
    int endy   = ValueFromString( g_UserUnit, m_EndY_Ctrl->GetValue() );

    // Type specific checks.
    switch( m_item->GetShape() )
    {
    case S_ARC:
        // Check angle of arc.
        double angle;
        m_Angle_Ctrl->GetValue().ToDouble( &angle );
        NORMALIZE_ANGLE_360( angle );

        if( angle == 0 )
        {
            error_msgs.Add( _( "The arc angle must be greater than zero." ) );
        }

        // Fall through.
    case S_CIRCLE:

        // Check radius.
        if( (startx == endx) && (starty == endy) )
        {
            error_msgs.Add( _( "The radius must be greater than zero." ) );
        }

        break;

    default:

        // Check start and end are not the same.
        if( (startx == endx) && (starty == endy) )
        {
            error_msgs.Add( _( "The start and end points cannot be the same." ) );
        }

        break;
    }

    // Check the item thickness.
    int thickness = ValueFromString( g_UserUnit, m_ThicknessCtrl->GetValue() );

    if( thickness <= 0 )
        error_msgs.Add( _( "The item thickness must be greater than zero." ) );

    // And the default thickness.
    thickness = ValueFromString( g_UserUnit, m_DefaultThicknessCtrl->GetValue() );

    if( thickness <= 0 )
        error_msgs.Add( _( "The default thickness must be greater than zero." ) );

    if( error_msgs.GetCount() )
    {
        HTML_MESSAGE_BOX dlg( this, _( "Error list" ) );
        dlg.ListSet( error_msgs );
        dlg.ShowModal();
    }

    return error_msgs.GetCount() == 0;
}
+110 −32
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2012-2014 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
 * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
 * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
@@ -23,7 +23,7 @@
 */

/**
 @file dialog_graphic_item_properties_for_Modedit.cpp
 * @file dialog_graphic_item_properties_for_Modedit.cpp
 */

/* Edit parameters values of graphic items in a footprint body:
@@ -49,6 +49,7 @@

#include <dialog_graphic_item_properties_base.h>
#include <class_pcb_layer_box_selector.h>
#include <html_messagebox.h>

class DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES : public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE
{
@@ -68,6 +69,7 @@ private:
    void OnOkClick( wxCommandEvent& event );
    void OnCancelClick( wxCommandEvent& event ){ event.Skip(); }
    void OnLayerChoice( wxCommandEvent& event );
    bool itemValuesOK();
};

DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES(
@@ -85,6 +87,7 @@ DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES(
    Centre();
}


/*
 * Dialog to edit a graphic item of a footprint body.
 */
@@ -137,6 +140,7 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::initDlg()
    switch( m_item->GetShape() )
    {
    case S_CIRCLE:
        SetTitle( _( "Circle Properties" ) );
        m_StartPointXLabel->SetLabel( _( "Center X" ) );
        m_StartPointYLabel->SetLabel( _( "Center Y" ) );
        m_EndPointXLabel->SetLabel( _( "Point X" ) );
@@ -147,6 +151,7 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::initDlg()
        break;

    case S_ARC:
        SetTitle( _( "Arc Properties" ) );
        m_StartPointXLabel->SetLabel( _( "Center X" ) );
        m_StartPointYLabel->SetLabel( _( "Center Y" ) );
        m_EndPointXLabel->SetLabel( _( "Start Point X" ) );
@@ -158,6 +163,10 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::initDlg()
        m_Angle_Ctrl->SetValue( msg );
        break;

    case S_SEGMENT:
        SetTitle( _( "Line Segment Properties" ) );

        // Fall through.
    default:
        m_Angle_Text->Show( false );
        m_Angle_Ctrl->Show( false );
@@ -185,8 +194,8 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::initDlg()

    if( m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() ) < 0 )
    {
        wxMessageBox( _( "This item has an illegal layer id.\n"
                        "Now, forced on the front silk screen layer. Please, fix it" ) );
        wxMessageBox( _( "This item was on an unknown layer.\n"
                         "It has been moved to the front silk screen layer. Please fix it." ) );
        m_LayerSelectionCtrl->SetLayerSelection( F_SilkS );
    }
}
@@ -198,12 +207,16 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::OnLayerChoice( wxCommandEvent& even
{
}


/*******************************************************************/
void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::OnOkClick( wxCommandEvent& event )
/*******************************************************************/
/* Copy values in text control to the item parameters
 */
{
    if( !itemValuesOK() )
        return;

    LAYER_NUM layer = m_LayerSelectionCtrl->GetLayerSelection();

    if( IsCopperLayer( layer ) )
@@ -259,3 +272,68 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::OnOkClick( wxCommandEvent& event )

    Close( true );
}


bool DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::itemValuesOK()
{
    wxArrayString error_msgs;

    // Load the start and end points -- all types use these in the checks.
    int startx = ValueFromString( g_UserUnit, m_Center_StartXCtrl->GetValue() );
    int starty = ValueFromString( g_UserUnit, m_Center_StartYCtrl->GetValue() );
    int endx   = ValueFromString( g_UserUnit, m_EndX_Radius_Ctrl->GetValue() );
    int endy   = ValueFromString( g_UserUnit, m_EndY_Ctrl->GetValue() );

    // Type specific checks.
    switch( m_item->GetShape() )
    {
    case S_ARC:
        // Check angle of arc.
        double angle;
        m_Angle_Ctrl->GetValue().ToDouble( &angle );
        NORMALIZE_ANGLE_360( angle );

        if( angle == 0 )
        {
            error_msgs.Add( _( "The arc angle must be greater than zero." ) );
        }

        // Fall through.
    case S_CIRCLE:

        // Check radius.
        if( (startx == endx) && (starty == endy) )
            error_msgs.Add( _( "The radius must be greater than zero." ) );

        break;

    default:

        // Check start and end are not the same.
        if( (startx == endx) && (starty == endy) )
            error_msgs.Add( _( "The start and end points cannot be the same." ) );

        break;
    }

    // Check the item thickness.
    int thickness = ValueFromString( g_UserUnit, m_ThicknessCtrl->GetValue() );

    if( thickness <= 0 )
        error_msgs.Add( _( "The item thickness must be greater than zero." ) );

    // And the default thickness.
    thickness = ValueFromString( g_UserUnit, m_DefaultThicknessCtrl->GetValue() );

    if( thickness <= 0 )
        error_msgs.Add( _( "The default thickness must be greater than zero." ) );

    if( error_msgs.GetCount() )
    {
        HTML_MESSAGE_BOX dlg( this, _( "Error list" ) );
        dlg.ListSet( error_msgs );
        dlg.ShowModal();
    }

    return error_msgs.GetCount() == 0;
}