From 7dadeadbf3f07a228fc30b79a0f1e7f6c2a24344 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 6 Feb 2015 22:01:57 +0100 Subject: [PATCH 1/3] bugfix 1418736: pcbnew crashes if "Interactive Router" was selected from the context menu. --- common/tool/context_menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/tool/context_menu.cpp b/common/tool/context_menu.cpp index 105e283d6b..86c41c301b 100644 --- a/common/tool/context_menu.cpp +++ b/common/tool/context_menu.cpp @@ -132,7 +132,7 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle ) else { InsertSeparator( 0 ); - Insert( 0, new wxMenuItem( this, -1, aTitle, wxEmptyString, wxITEM_NORMAL ) ); + Insert( 0, new wxMenuItem( this, wxID_NONE, aTitle, wxEmptyString, wxITEM_NORMAL ) ); m_titleSet = true; } } From 88ce5920b504bc32ac1196d8b2c499a46fe0c70e Mon Sep 17 00:00:00 2001 From: Adam Wolf Date: Fri, 6 Feb 2015 16:13:35 -0500 Subject: [PATCH 2/3] Fix OSX help search paths. --- common/searchhelpfilefullpath.cpp | 37 ++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/common/searchhelpfilefullpath.cpp b/common/searchhelpfilefullpath.cpp index 79e48fd665..e340a2c08a 100644 --- a/common/searchhelpfilefullpath.cpp +++ b/common/searchhelpfilefullpath.cpp @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2014 CERN - * Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors. + * Copyright (C) 2014-2015 CERN + * Copyright (C) 2014-2015 KiCad Developers, see CHANGELOG.TXT for contributors. * @author Maciej Suminski * * This program is free software; you can redistribute it and/or @@ -31,7 +31,7 @@ * Function FindFileInSearchPaths * looks in "this" for \a aFilename, but first modifies every search * path by appending a list of path fragments from aSubdirs. That modification - * is not rentative. + * is not relative. */ wxString FindFileInSearchPaths( const SEARCH_STACK& aStack, const wxString& aFilename, const wxArrayString* aSubdirs ) @@ -73,7 +73,12 @@ wxString SearchHelpFileFullPath( const SEARCH_STACK& aSStack, const wxString& aB // If there's a KICAD environment variable set, use that guy's path also ss.AddPaths( Pgm().GetKicadEnvVariable(), 0 ); -#if 1 // && defined(__linux__) +#if defined(__WXMAC__) + ss.AddPaths( GetOSXKicadMachineDataDir() ); + ss.AddPaths( Pgm().GetExecutablePath(), 0 ); +#endif + +#if ! defined(__WXMAC__) // && defined(__linux__) // Based on kicad-doc.bzr/CMakeLists.txt, line 20, the help files are // installed into "/share/doc/kicad/help" for linux. // This is ${KICAD_HELP} var in that CMakeLists.txt file. @@ -84,7 +89,7 @@ wxString SearchHelpFileFullPath( const SEARCH_STACK& aSStack, const wxString& aB subdirs.Add( wxT( "help" ) ); #endif -#if 1 // && defined(__WINDOWS__) +#if ! defined(__WXMAC__) // && defined(__WINDOWS__) // Based on kicad-doc.bzr/CMakeLists.txt, line 35, the help files are // installed into "/doc/help" for Windows. // This is ${KICAD_HELP} var in that CMakeLists.txt file. @@ -93,6 +98,18 @@ wxString SearchHelpFileFullPath( const SEARCH_STACK& aSStack, const wxString& aB altsubdirs.Add( wxT( "help" ) ); #endif +#if defined (__WXMAC__) + // OS X packages can have the help files in + // /Library/Application\ Support/kicad/help, + // and in Contents/SharedSupport/help inside the + // bundle. + // Below we account for an international subdirectory. + subdirs.Add( wxT( "help" ) ); + altsubdirs.Add( wxT( "Contents" ) ); + altsubdirs.Add( wxT( "SharedSupport" ) ); + altsubdirs.Add( wxT( "help" ) ); +#endif + /* Search for a help file. * we *must* find a help file. * so help is searched in directories in this order: @@ -110,7 +127,7 @@ wxString SearchHelpFileFullPath( const SEARCH_STACK& aSStack, const wxString& aB locale_name_dirs.Add( i18n->GetCanonicalName() ); // canonical name like fr_FR // wxLocale::GetName() does not return always the short name locale_name_dirs.Add( i18n->GetName().BeforeLast( '_' ) ); // short canonical name like fr - locale_name_dirs.Add( wxT("en") ); // default (en) + locale_name_dirs.Add( wxT( "en" ) ); // default (en) #if defined(DEBUG) && 0 ss.Show( __func__ ); @@ -127,22 +144,22 @@ wxString SearchHelpFileFullPath( const SEARCH_STACK& aSStack, const wxString& aB subdirs.Add( locale_name_dirs[ii] ); altsubdirs.Add( locale_name_dirs[ii] ); - fn = FindFileInSearchPaths( ss, aBaseName + wxT(".html"), &altsubdirs ); + fn = FindFileInSearchPaths( ss, aBaseName + wxT( ".html" ), &altsubdirs ); if( !fn.IsEmpty() ) break; - fn = FindFileInSearchPaths( ss, aBaseName + wxT(".pdf"), &altsubdirs ); + fn = FindFileInSearchPaths( ss, aBaseName + wxT( ".pdf" ), &altsubdirs ); if( !fn.IsEmpty() ) break; - fn = FindFileInSearchPaths( ss, aBaseName + wxT(".html"), &subdirs ); + fn = FindFileInSearchPaths( ss, aBaseName + wxT( ".html" ), &subdirs ); if( !fn.IsEmpty() ) break; - fn = FindFileInSearchPaths( ss, aBaseName + wxT(".pdf"), &subdirs ); + fn = FindFileInSearchPaths( ss, aBaseName + wxT( ".pdf" ), &subdirs ); if( !fn.IsEmpty() ) break; From 07db7c8d2921eeac1fc0f197bdc39f510ded52d9 Mon Sep 17 00:00:00 2001 From: Blair Bonnett Date: Fri, 6 Feb 2015 16:49:40 -0500 Subject: [PATCH 3/3] Prevent Pcbnew edit graphics property dialog from excepting zero length objects. (fixes lp:1392117) --- .../dialog_graphic_item_properties.cpp | 172 +++++++++++++----- ...og_graphic_item_properties_for_Modedit.cpp | 142 +++++++++++---- 2 files changed, 234 insertions(+), 80 deletions(-) diff --git a/pcbnew/dialogs/dialog_graphic_item_properties.cpp b/pcbnew/dialogs/dialog_graphic_item_properties.cpp index fff88b87af..edb27594c1 100644 --- a/pcbnew/dialogs/dialog_graphic_item_properties.cpp +++ b/pcbnew/dialogs/dialog_graphic_item_properties.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2010 Jean-Pierre Charras - * 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,34 +49,36 @@ #include #include +#include -class DIALOG_GRAPHIC_ITEM_PROPERTIES: public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE +class DIALOG_GRAPHIC_ITEM_PROPERTIES : public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE { private: - PCB_EDIT_FRAME* m_parent; - wxDC* m_DC; - DRAWSEGMENT* m_Item; - BOARD_DESIGN_SETTINGS m_brdSettings; + PCB_EDIT_FRAME* m_parent; + wxDC* m_DC; + DRAWSEGMENT* m_item; + BOARD_DESIGN_SETTINGS m_brdSettings; public: - DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_EDIT_FRAME* aParent, DRAWSEGMENT * aItem, wxDC * aDC); + DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_EDIT_FRAME* aParent, DRAWSEGMENT* aItem, wxDC* aDC ); ~DIALOG_GRAPHIC_ITEM_PROPERTIES() {}; private: - void initDlg( ); + void initDlg(); 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, - DRAWSEGMENT * aItem, wxDC * aDC ): + DRAWSEGMENT* aItem, wxDC* aDC ): DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE( aParent ) { 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 ); @@ -101,12 +99,12 @@ void PCB_EDIT_FRAME::InstallGraphicItemPropertiesDialog( DRAWSEGMENT* aItem, wxD } -void DIALOG_GRAPHIC_ITEM_PROPERTIES::initDlg( ) +void DIALOG_GRAPHIC_ITEM_PROPERTIES::initDlg() { m_StandardButtonsSizerOK->SetDefault(); // Set unit symbol - wxStaticText * texts_unit[] = + wxStaticText* texts_unit[] = { m_StartPointXUnit, m_StartPointYUnit, @@ -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,22 +162,22 @@ 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 ) - thickness = m_brdSettings.m_EdgeSegmentWidth; + if( m_item->GetLayer() == Edge_Cuts ) + thickness = m_brdSettings.m_EdgeSegmentWidth; else - thickness = m_brdSettings.m_DrawSegmentWidth; + thickness = m_brdSettings.m_DrawSegmentWidth; PutValueInLocalUnits( *m_DefaultThicknessCtrl, thickness ); @@ -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 ); } } @@ -197,9 +201,9 @@ void DIALOG_GRAPHIC_ITEM_PROPERTIES::OnLayerChoice( wxCommandEvent& event ) int thickness; if( m_LayerSelectionCtrl->GetLayerSelection() == Edge_Cuts ) - thickness = m_brdSettings.m_EdgeSegmentWidth; + thickness = m_brdSettings.m_EdgeSegmentWidth; else - thickness = m_brdSettings.m_DrawSegmentWidth; + thickness = m_brdSettings.m_DrawSegmentWidth; PutValueInLocalUnits( *m_DefaultThicknessCtrl, thickness ); } @@ -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 ) - m_brdSettings.m_EdgeSegmentWidth = thickness; + if( m_item->GetLayer() == Edge_Cuts ) + m_brdSettings.m_EdgeSegmentWidth = thickness; else - m_brdSettings.m_DrawSegmentWidth = thickness; + 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 ); + NORMALIZE_ANGLE_360( 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; +} diff --git a/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp b/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp index 58492f857d..92c8d7caa4 100644 --- a/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp +++ b/pcbnew/dialogs/dialog_graphic_item_properties_for_Modedit.cpp @@ -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,25 +49,27 @@ #include #include +#include -class DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES: public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE +class DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES : public DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE { private: - FOOTPRINT_EDIT_FRAME* m_parent; - EDGE_MODULE* m_item; + FOOTPRINT_EDIT_FRAME* m_parent; + EDGE_MODULE* m_item; BOARD_DESIGN_SETTINGS m_brdSettings; - MODULE * m_module; + MODULE* m_module; public: DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES( FOOTPRINT_EDIT_FRAME* aParent, - EDGE_MODULE * aItem); + EDGE_MODULE* aItem ); ~DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES() {}; private: - void initDlg( ); + void initDlg(); 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,14 +87,15 @@ DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES( Centre(); } + /* * Dialog to edit a graphic item of a footprint body. */ -void FOOTPRINT_EDIT_FRAME::InstallFootprintBodyItemPropertiesDlg(EDGE_MODULE * aItem) +void FOOTPRINT_EDIT_FRAME::InstallFootprintBodyItemPropertiesDlg( EDGE_MODULE* aItem ) { - if ( aItem == NULL ) + if( aItem == NULL ) { - wxMessageBox( wxT("InstallGraphicItemPropertiesDialog() error: NULL item")); + wxMessageBox( wxT( "InstallGraphicItemPropertiesDialog() error: NULL item" ) ); return; } @@ -112,7 +115,7 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::initDlg() m_StandardButtonsSizerOK->SetDefault(); // Set unit symbol - wxStaticText * texts_unit[] = + wxStaticText* texts_unit[] = { m_StartPointXUnit, m_StartPointYUnit, @@ -134,34 +137,40 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::initDlg() wxString msg; // Change texts according to the segment shape: - switch ( m_item->GetShape() ) + switch( m_item->GetShape() ) { case S_CIRCLE: - m_StartPointXLabel->SetLabel(_("Center X")); - m_StartPointYLabel->SetLabel(_("Center Y")); - m_EndPointXLabel->SetLabel(_("Point X")); - m_EndPointYLabel->SetLabel(_("Point Y")); - m_Angle_Text->Show(false); - m_Angle_Ctrl->Show(false); - m_AngleUnit->Show(false); + SetTitle( _( "Circle Properties" ) ); + m_StartPointXLabel->SetLabel( _( "Center X" ) ); + m_StartPointYLabel->SetLabel( _( "Center Y" ) ); + m_EndPointXLabel->SetLabel( _( "Point X" ) ); + m_EndPointYLabel->SetLabel( _( "Point Y" ) ); + m_Angle_Text->Show( false ); + m_Angle_Ctrl->Show( false ); + m_AngleUnit->Show( false ); break; case S_ARC: - m_StartPointXLabel->SetLabel(_("Center X")); - m_StartPointYLabel->SetLabel(_("Center Y")); - m_EndPointXLabel->SetLabel(_("Start Point X")); - m_EndPointYLabel->SetLabel(_("Start Point Y")); + 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() ); - m_Angle_Ctrl->SetValue(msg); + 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); - m_AngleUnit->Show(false); + m_Angle_Text->Show( false ); + m_Angle_Ctrl->Show( false ); + m_AngleUnit->Show( false ); break; } @@ -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 ) ) @@ -250,7 +263,7 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::OnOkClick( wxCommandEvent& event ) { double angle; m_Angle_Ctrl->GetValue().ToDouble( &angle ); - NORMALIZE_ANGLE_360(angle); + NORMALIZE_ANGLE_360( angle ); m_item->SetAngle( angle ); } @@ -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; +}