Pcbnew: Work on undo/redo in Pcbnew almost finished.
This commit is contained in:
parent
856b7c790f
commit
cfdb28394e
|
@ -4,6 +4,11 @@ KiCad ChangeLog 2009
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2009-aug-23 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
================================================================================
|
||||
++pcbnew
|
||||
Work on undo/redo in pcbnew almost finished.
|
||||
|
||||
2009-Aug-16 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
++pcbnew
|
||||
|
|
|
@ -479,12 +479,11 @@ public:
|
|||
* The zone outline is a frontier, and can be complex (with holes)
|
||||
* The filling starts from starting points like pads, tracks.
|
||||
* If exists the old filling is removed
|
||||
* @param DC = current Device Context
|
||||
* @param zone_container = zone to fill
|
||||
* @param verbose = true to show error messages
|
||||
* @return error level (0 = no error)
|
||||
*/
|
||||
int Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool verbose = TRUE );
|
||||
int Fill_Zone( ZONE_CONTAINER* zone_container, bool verbose = TRUE );
|
||||
|
||||
/** Function Fill_All_Zones()
|
||||
* Fill all zones on the board
|
||||
|
|
|
@ -149,8 +149,10 @@ set(PCBNEW_SRCS
|
|||
work.cpp
|
||||
xchgmod.cpp
|
||||
zones_by_polygon.cpp
|
||||
zones_by_polygon_fill_functions.cpp
|
||||
zones_convert_brd_items_to_polygons.cpp
|
||||
zone_filling_algorithm.cpp
|
||||
zones_functions_for_undo_redo.cpp
|
||||
zones_polygons_insulated_copper_islands.cpp
|
||||
zones_polygons_test_connections.cpp
|
||||
zones_test_and_combine_areas.cpp
|
||||
|
|
|
@ -424,7 +424,8 @@ void WinEDA_PcbFrame::SaveCopyInUndoList( PICKED_ITEMS_LIST& aItemsList,
|
|||
*/
|
||||
if( commandToUndo->GetPickedItemLink( ii ) == NULL )
|
||||
commandToUndo->SetPickedItemLink( DuplicateStruct( item ), ii );
|
||||
wxASSERT( commandToUndo->GetPickedItemLink( ii ) );
|
||||
if( commandToUndo->GetPickedItemLink( ii ) == NULL )
|
||||
wxMessageBox( wxT( "SaveCopyInUndoList() in UR_CHANGED mode: NULL link" ) );
|
||||
break;
|
||||
|
||||
case UR_MOVED:
|
||||
|
|
|
@ -252,7 +252,14 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
|
|||
|
||||
// other types may use linked list
|
||||
default:
|
||||
wxFAIL_MSG( wxT( "BOARD::Add() needs work: BOARD_ITEM type not handled" ) );
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf(
|
||||
wxT( "BOARD::Add() needs work: BOARD_ITEM type (%d) not handled" ),
|
||||
aBoardItem->Type() );
|
||||
wxFAIL_MSG(msg );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**************************************************************/
|
||||
/*************************************************/
|
||||
/* class_board.h - Class BOARD to handle a board */
|
||||
/**************************************************************/
|
||||
/*************************************************/
|
||||
|
||||
#ifndef CLASS_BOARD_H
|
||||
#define CLASS_BOARD_H
|
||||
|
@ -474,19 +474,18 @@ public:
|
|||
|
||||
/* Functions used in test, merge and cut outlines */
|
||||
|
||||
/**
|
||||
* Function AddArea
|
||||
* add empty copper area to net
|
||||
/** Function AddArea
|
||||
* Add an empty copper area to board areas list
|
||||
* @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful in undo commands)
|
||||
* can be NULL
|
||||
* @param aNetcode = the necode of the copper area (0 = no net)
|
||||
* @param aLayer = the layer of area
|
||||
* @param aStartPointPosition = position of the first point of the polygon outline of this area
|
||||
* @param aHatch = hacth option
|
||||
* @return pointer to the new area
|
||||
*/
|
||||
ZONE_CONTAINER* AddArea( int netcode, int layer, int x, int y, int hatch );
|
||||
|
||||
/**
|
||||
* remove copper area from net
|
||||
* @param area = area to remove
|
||||
* @return 0
|
||||
*/
|
||||
int RemoveArea( ZONE_CONTAINER* area_to_remove );
|
||||
ZONE_CONTAINER* AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
|
||||
int aLayer, wxPoint aStartPointPosition, int aHatch );
|
||||
|
||||
/**
|
||||
* Function InsertArea
|
||||
|
@ -522,15 +521,20 @@ public:
|
|||
* Function ClipAreaPolygon
|
||||
* Process an area that has been modified, by clipping its polygon against itself.
|
||||
* This may change the number and order of copper areas in the net.
|
||||
* @param bMessageBoxInt == TRUE, shows message when clipping occurs.
|
||||
* @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs.
|
||||
* @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful in undo commands)
|
||||
* can be NULL
|
||||
* @param aCurrArea = the zone to process
|
||||
* @param bMessageBoxInt == true, shows message when clipping occurs.
|
||||
* @param bMessageBoxArc == true, shows message when clipping can't be done due to arcs.
|
||||
* @param bRetainArcs = true to handle arcs (not really used in kicad)
|
||||
* @return:
|
||||
* -1 if arcs intersect other sides, so polygon can't be clipped
|
||||
* 0 if no intersecting sides
|
||||
* 1 if intersecting sides
|
||||
* Also sets areas->utility1 flags if areas are modified
|
||||
*/
|
||||
int ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
||||
int ClipAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
|
||||
ZONE_CONTAINER* aCurrArea,
|
||||
bool bMessageBoxArc,
|
||||
bool bMessageBoxInt,
|
||||
bool bRetainArcs = TRUE );
|
||||
|
@ -539,6 +543,8 @@ public:
|
|||
* Process an area that has been modified, by clipping its polygon against
|
||||
* itself and the polygons for any other areas on the same net.
|
||||
* This may change the number and order of copper areas in the net.
|
||||
* @param aModifiedZonesList = a PICKED_ITEMS_LIST * where to store deleted or added areas
|
||||
* (useful in undo commands. Can be NULL
|
||||
* @param modified_area = area to test
|
||||
* @param bMessageBox : if TRUE, shows message boxes when clipping occurs.
|
||||
* @return :
|
||||
|
@ -546,20 +552,31 @@ public:
|
|||
* 0 if no intersecting sides
|
||||
* 1 if intersecting sides, polygon clipped
|
||||
*/
|
||||
int AreaPolygonModified( ZONE_CONTAINER* modified_area,
|
||||
int AreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList,
|
||||
ZONE_CONTAINER* modified_area,
|
||||
bool bMessageBoxArc,
|
||||
bool bMessageBoxInt );
|
||||
|
||||
/**
|
||||
* Function CombineAllAreasInNet
|
||||
* Checks all copper areas in net for intersections, combining them if found
|
||||
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands
|
||||
* can be NULL
|
||||
* @param aNetCode = net to consider
|
||||
* @param bMessageBox : if true display warning message box
|
||||
* @param bUseUtility : if true, don't check areas if both utility flags are 0
|
||||
* Sets utility flag = 1 for any areas modified
|
||||
* If an area has self-intersecting arcs, doesn't try to combine it
|
||||
*/
|
||||
int CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtility );
|
||||
int CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, bool bMessageBox, bool bUseUtility );
|
||||
|
||||
/** Function RemoveArea
|
||||
* remove copper area from net, and put it in a deleted list (if exists)
|
||||
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands
|
||||
* can be NULL
|
||||
* @param area_to_remove = area to delete or put in deleted list
|
||||
*/
|
||||
void RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove );
|
||||
|
||||
/**
|
||||
* Function TestAreaIntersections
|
||||
|
@ -583,13 +600,17 @@ public:
|
|||
/**
|
||||
* Function CombineAreas
|
||||
* If possible, combine 2 copper areas
|
||||
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands
|
||||
* can be NULL
|
||||
* @param area_ref = tje main area (zone)
|
||||
* @param area_to_combine = the zone that can be merged with area_ref
|
||||
* area_ref must be BEFORE area_to_combine
|
||||
* area_to_combine will be deleted, if areas are combined
|
||||
* @return : 0 if no intersection
|
||||
* 1 if intersection
|
||||
* 2 if arcs intersect
|
||||
*/
|
||||
int CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine );
|
||||
int CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine );
|
||||
|
||||
/**
|
||||
* Function Test_Drc_Areas_Outlines_To_Areas_Outlines
|
||||
|
|
|
@ -1133,13 +1133,19 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src )
|
|||
m_Layer = src->m_Layer;
|
||||
SetNet( src->GetNet() );
|
||||
m_TimeStamp = src->m_TimeStamp;
|
||||
m_Poly->RemoveAllContours();
|
||||
m_Poly->Copy( src->m_Poly ); // copy outlines
|
||||
m_CornerSelection = -1; // For corner moving, corner index to drag, or -1 if no selection
|
||||
m_ZoneClearance = src->m_ZoneClearance; // clearance value
|
||||
m_FillMode = src->m_FillMode; // Grid used for filling
|
||||
m_FillMode = src->m_FillMode; // Filling mode (segments/polygons)
|
||||
m_ArcToSegmentsCount = src->m_ArcToSegmentsCount;
|
||||
m_PadOption = src->m_PadOption;
|
||||
m_ThermalReliefGapValue = src->m_ThermalReliefGapValue;
|
||||
m_ThermalReliefCopperBridgeValue = src->m_ThermalReliefCopperBridgeValue;
|
||||
m_Poly->SetHatch( src->m_Poly->GetHatchStyle() );
|
||||
m_FilledPolysList.clear();
|
||||
m_FilledPolysList = src->m_FilledPolysList;
|
||||
m_FillSegmList.clear();
|
||||
m_FillSegmList = src->m_FillSegmList;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
int m_ZoneClearance; // clearance value
|
||||
int m_ZoneMinThickness; // Min thickness value in filled areas
|
||||
int m_FillMode; // How to fillingareas: 0 = use polygonal areas , != 0 fill with segments
|
||||
int m_ArcToSegmentsCount; // number of segments to convert a cirlce to a polygon (uses 16 or 32)
|
||||
int m_ArcToSegmentsCount; // number of segments to convert a circle to a polygon (uses 16 or 32)
|
||||
int m_PadOption; //
|
||||
int m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs
|
||||
int m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs
|
||||
|
@ -369,6 +369,13 @@ public:
|
|||
{
|
||||
return m_Poly->GetHatchStyle();
|
||||
}
|
||||
/** function IsSame()
|
||||
* test is 2 zones are equivalent:
|
||||
* 2 zones are equivalent if they have same parameters and same outlines
|
||||
* info relative to filling is not take in account
|
||||
* @param aZoneToCompare = zone to compare with "this"
|
||||
*/
|
||||
bool IsSame( const ZONE_CONTAINER &aZoneToCompare);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/// Licence: GNU License
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined (__GNUG__) && !defined (NO_GCC_PRAGMA)
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma implementation "zones.h"
|
||||
#endif
|
||||
|
||||
|
@ -33,6 +33,8 @@ dialog_copper_zone::dialog_copper_zone( WinEDA_PcbFrame* parent, ZONE_SETTING* z
|
|||
m_Config = wxGetApp().m_EDA_Config;
|
||||
m_Zone_Setting = zone_setting;
|
||||
m_NetSorting = 1; // 0 = alphabetic sort, 1 = pad count sort, and filtering net names
|
||||
m_OnExitCode = ZONE_ABORT;
|
||||
|
||||
if( m_Config )
|
||||
{
|
||||
m_NetSorting = m_Config->Read( ZONE_NET_SORT_OPTION_KEY, 1l );
|
||||
|
@ -207,7 +209,7 @@ void dialog_copper_zone::OnInitDialog( wxInitDialogEvent& event )
|
|||
void dialog_copper_zone::OnButtonCancelClick( wxCommandEvent& event )
|
||||
/********************************************************************/
|
||||
{
|
||||
EndModal( ZONE_ABORT );
|
||||
EndModal( m_OnExitCode );
|
||||
}
|
||||
|
||||
|
||||
|
@ -270,7 +272,7 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab
|
|||
// Test if this is a reasonnable value for this parameter
|
||||
// A too large value can hang pcbnew
|
||||
#define CLEARANCE_MAX_VALUE 5000 // in 1/10000 inch
|
||||
if ( m_Zone_Setting->m_ZoneClearance > CLEARANCE_MAX_VALUE )
|
||||
if( m_Zone_Setting->m_ZoneClearance > CLEARANCE_MAX_VALUE )
|
||||
{
|
||||
DisplayError( this, _( "Error : Zone clearance is set to an unreasonnable value" ) );
|
||||
return false;
|
||||
|
@ -336,13 +338,13 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( ii == 0 ) // the not connected option was selected: this is not a good practice: warn:
|
||||
if( ii == 0 ) // the not connected option was selected: this is not a good practice: warn:
|
||||
{
|
||||
if( ! IsOK( this, _(
|
||||
"You have chosen the \"not connected\" option. This will create insulated copper islands. Are you sure ?") )
|
||||
if( !IsOK( this, _(
|
||||
"You have chosen the \"not connected\" option. This will create insulated copper islands. Are you sure ?" ) )
|
||||
)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString net_name = m_ListNetNameSelection->GetString( ii );
|
||||
|
||||
|
@ -351,7 +353,7 @@ bool dialog_copper_zone::AcceptOptions( bool aPromptForErrors, bool aUseExportab
|
|||
/* Search net_code for this net, if a net was selected */
|
||||
if( m_ListNetNameSelection->GetSelection() > 0 )
|
||||
{
|
||||
NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet(net_name);
|
||||
NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( net_name );
|
||||
if( net )
|
||||
g_Zone_Default_Setting.m_NetcodeSelection = net->GetNet();
|
||||
}
|
||||
|
@ -435,6 +437,7 @@ void dialog_copper_zone::ExportSetupToOtherCopperZones( wxCommandEvent& event )
|
|||
m_Zone_Setting->ExportSetting( *zone, false ); // false = partiel export
|
||||
m_Parent->GetScreen()->SetModify();
|
||||
}
|
||||
m_OnExitCode = ZONE_EXPORT_VALUES; // values are exported to others zones
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,25 +6,30 @@
|
|||
#include "dialog_copper_zones_base.h"
|
||||
|
||||
/* here is the derivated class from dialog_copper_zone_frame created by wxFormBuilder
|
||||
*/
|
||||
class dialog_copper_zone: public dialog_copper_zone_base
|
||||
*/
|
||||
class dialog_copper_zone : public dialog_copper_zone_base
|
||||
{
|
||||
public:
|
||||
WinEDA_PcbFrame* m_Parent;
|
||||
wxConfig* m_Config; // Current config
|
||||
ZONE_SETTING * m_Zone_Setting;
|
||||
long m_NetSorting;
|
||||
int m_LayerId[LAYER_COUNT]; // Handle the real layer number from layer name position in m_LayerSelectionCtrl
|
||||
wxConfig* m_Config; // Current config
|
||||
int m_OnExitCode; /* exit code: ZONE_ABORT if no change,
|
||||
* ZONE_OK if new values accepted
|
||||
* ZONE_EXPORT_VALUES if values are exported to others zones
|
||||
*/
|
||||
|
||||
ZONE_SETTING* m_Zone_Setting;
|
||||
long m_NetSorting;
|
||||
int m_LayerId[LAYER_COUNT]; // Handle the real layer number from layer name position in m_LayerSelectionCtrl
|
||||
|
||||
public:
|
||||
dialog_copper_zone( WinEDA_PcbFrame* parent, ZONE_SETTING * zone_setting);
|
||||
dialog_copper_zone( WinEDA_PcbFrame* parent, ZONE_SETTING* zone_setting );
|
||||
void OnInitDialog( wxInitDialogEvent& event );
|
||||
void OnButtonOkClick( wxCommandEvent& event );
|
||||
void OnButtonCancelClick( wxCommandEvent& event );
|
||||
bool AcceptOptions(bool aPromptForErrors, bool aUseExportableSetupOnly = false);
|
||||
void OnButtonOkClick( wxCommandEvent& event );
|
||||
void OnButtonCancelClick( wxCommandEvent& event );
|
||||
bool AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly = false );
|
||||
void OnNetSortingOptionSelected( wxCommandEvent& event );
|
||||
void ExportSetupToOtherCopperZones( wxCommandEvent& event );
|
||||
void OnPadsInZoneClick( wxCommandEvent& event );
|
||||
void ExportSetupToOtherCopperZones( wxCommandEvent& event );
|
||||
void OnPadsInZoneClick( wxCommandEvent& event );
|
||||
};
|
||||
|
||||
#endif // #ifndef DIALOG_COPPER_ZONES
|
||||
|
|
|
@ -66,13 +66,14 @@ public:
|
|||
|
||||
public:
|
||||
DialogPadProperties( WinEDA_BasePcbFrame* parent, D_PAD* Pad, wxDC* DC );
|
||||
void InitDialog( wxInitDialogEvent& event );
|
||||
void Init( );
|
||||
void OnPadShapeSelection( wxCommandEvent& event );
|
||||
void OnDrillShapeSelected( wxCommandEvent& event );
|
||||
void PadOrientEvent( wxCommandEvent& event );
|
||||
void PadTypeSelected( wxCommandEvent& event );
|
||||
void PadPropertiesAccept( wxCommandEvent& event );
|
||||
void SetPadLayersList( long layer_mask );
|
||||
void OnCancelButtonClick( wxCommandEvent& event );
|
||||
};
|
||||
|
||||
|
||||
|
@ -90,6 +91,12 @@ DialogPadProperties::DialogPadProperties( WinEDA_BasePcbFrame* parent, D_PAD* Pa
|
|||
Current_PadNetName = m_CurrentPad->GetNetname();
|
||||
g_Current_PadName = m_CurrentPad->ReturnStringPadName();
|
||||
}
|
||||
|
||||
Init( );
|
||||
if( GetSizer() )
|
||||
{
|
||||
GetSizer()->SetSizeHints( this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -104,7 +111,7 @@ void WinEDA_BasePcbFrame::InstallPadOptionsFrame( D_PAD* Pad, wxDC* DC, const wx
|
|||
|
||||
|
||||
/**************************************************************/
|
||||
void DialogPadProperties::InitDialog( wxInitDialogEvent& event )
|
||||
void DialogPadProperties::Init( )
|
||||
/**************************************************************/
|
||||
{
|
||||
int tmp;
|
||||
|
@ -235,11 +242,6 @@ void DialogPadProperties::InitDialog( wxInitDialogEvent& event )
|
|||
cmd_event.SetId( m_PadType->GetSelection() );
|
||||
PadTypeSelected( cmd_event );
|
||||
}
|
||||
|
||||
if( GetSizer() )
|
||||
{
|
||||
GetSizer()->SetSizeHints( this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -475,8 +477,8 @@ void DialogPadProperties::PadPropertiesAccept( wxCommandEvent& event )
|
|||
|
||||
if( m_CurrentPad ) // Set Pad Name & Num
|
||||
{
|
||||
m_Parent->SaveCopyInUndoList( m_Parent->GetBoard()->m_Modules, UR_CHANGED );
|
||||
MODULE* Module = (MODULE*) m_CurrentPad->GetParent();
|
||||
m_Parent->SaveCopyInUndoList( Module, UR_CHANGED );
|
||||
Module->m_LastEdit_Time = time( NULL );
|
||||
|
||||
if( m_DC ) // redraw the area where the pad was, without pad (delete pad on screen)
|
||||
|
@ -580,10 +582,18 @@ void DialogPadProperties::PadPropertiesAccept( wxCommandEvent& event )
|
|||
m_Parent->GetScreen()->SetModify();
|
||||
}
|
||||
|
||||
Close();
|
||||
EndModal(1);
|
||||
|
||||
if( m_DC )
|
||||
m_Parent->DrawPanel->CursorOn( m_DC );
|
||||
if( RastnestIsChanged ) // The net ratsnest must be recalculated
|
||||
m_Parent->GetBoard()->m_Status_Pcb = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
void DialogPadProperties::OnCancelButtonClick( wxCommandEvent& event )
|
||||
/*********************************************************************/
|
||||
{
|
||||
EndModal(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -166,21 +166,21 @@ DialogPadPropertiesBase::DialogPadPropertiesBase( wxWindow* parent, wxWindowID i
|
|||
this->Centre( wxBOTH );
|
||||
|
||||
// Connect Events
|
||||
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DialogPadPropertiesBase::InitDialog ) );
|
||||
m_PadShape->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::OnPadShapeSelection ), NULL, this );
|
||||
m_DrillShapeCtrl->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::OnDrillShapeSelected ), NULL, this );
|
||||
m_PadOrient->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::PadOrientEvent ), NULL, this );
|
||||
m_PadType->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::PadTypeSelected ), NULL, this );
|
||||
m_buttonOk->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogPadPropertiesBase::PadPropertiesAccept ), NULL, this );
|
||||
m_buttonCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogPadPropertiesBase::OnCancelButtonClick ), NULL, this );
|
||||
}
|
||||
|
||||
DialogPadPropertiesBase::~DialogPadPropertiesBase()
|
||||
{
|
||||
// Disconnect Events
|
||||
this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DialogPadPropertiesBase::InitDialog ) );
|
||||
m_PadShape->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::OnPadShapeSelection ), NULL, this );
|
||||
m_DrillShapeCtrl->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::OnDrillShapeSelected ), NULL, this );
|
||||
m_PadOrient->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::PadOrientEvent ), NULL, this );
|
||||
m_PadType->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DialogPadPropertiesBase::PadTypeSelected ), NULL, this );
|
||||
m_buttonOk->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogPadPropertiesBase::PadPropertiesAccept ), NULL, this );
|
||||
m_buttonCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DialogPadPropertiesBase::OnCancelButtonClick ), NULL, this );
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<event name="OnHibernate"></event>
|
||||
<event name="OnIconize"></event>
|
||||
<event name="OnIdle"></event>
|
||||
<event name="OnInitDialog">InitDialog</event>
|
||||
<event name="OnInitDialog"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
|
@ -760,7 +760,7 @@
|
|||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick"></event>
|
||||
<event name="OnButtonClick">OnCancelButtonClick</event>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
|
|
|
@ -78,12 +78,12 @@ class DialogPadPropertiesBase : public wxDialog
|
|||
wxCheckBox* m_PadLayerDraft;
|
||||
|
||||
// Virtual event handlers, overide them in your derived class
|
||||
virtual void InitDialog( wxInitDialogEvent& event ){ event.Skip(); }
|
||||
virtual void OnPadShapeSelection( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnDrillShapeSelected( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void PadOrientEvent( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void PadTypeSelected( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void PadPropertiesAccept( wxCommandEvent& event ){ event.Skip(); }
|
||||
virtual void OnCancelButtonClick( wxCommandEvent& event ){ event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
|
|
@ -609,8 +609,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
|
|||
*/
|
||||
zone_cont->Draw( DrawPanel, &dc, GR_XOR );
|
||||
zone_cont->m_Poly->InsertCorner( zone_cont->m_CornerSelection,
|
||||
pos.x,
|
||||
pos.y );
|
||||
pos.x, pos.y );
|
||||
zone_cont->m_CornerSelection++;
|
||||
zone_cont->Draw( DrawPanel, &dc, GR_XOR );
|
||||
DrawPanel->m_AutoPAN_Request = true;
|
||||
|
@ -669,7 +668,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
|
|||
|
||||
case ID_POPUP_PCB_FILL_ZONE:
|
||||
DrawPanel->MouseToCursorSchema();
|
||||
Fill_Zone( NULL, (ZONE_CONTAINER*) GetCurItem() );
|
||||
Fill_Zone( (ZONE_CONTAINER*) GetCurItem() );
|
||||
test_1_net_connexion( NULL, ( (ZONE_CONTAINER*) GetCurItem() )->GetNet() );
|
||||
GetBoard()->DisplayInfo( this );
|
||||
DrawPanel->Refresh();
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
#define ZONE_THERMAL_RELIEF_GAP_STRING_KEY wxT( "Zone_TH_Gap" )
|
||||
#define ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY wxT( "Zone_TH_Copper_Width" )
|
||||
|
||||
// Exit codes for dialog edit zones
|
||||
enum zone_cmd {
|
||||
ZONE_ABORT,
|
||||
ZONE_OK
|
||||
ZONE_ABORT, // if no change
|
||||
ZONE_OK, // if new values accepted
|
||||
ZONE_EXPORT_VALUES // if values are exported to others zones
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -14,10 +14,9 @@
|
|||
#include "zones.h"
|
||||
#include "id.h"
|
||||
#include "protos.h"
|
||||
#include "zones_functions_for_undo_redo.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool verbose = false; // false if zone outline diags must not be shown
|
||||
bool s_Verbose = false; // false if zone outline diags must not be shown
|
||||
|
||||
// Outline creation:
|
||||
static void Abort_Zone_Create_Outline( WinEDA_DrawPanel* Panel, wxDC* DC );
|
||||
|
@ -30,11 +29,13 @@ static void Show_Zone_Corner_Or_Outline_While_Move_Mouse( WinEDA_DrawPanel* pane
|
|||
bool erase );
|
||||
|
||||
/* Local variables */
|
||||
static wxPoint s_CornerInitialPosition; // Used to abort a move corner command
|
||||
static wxPoint s_CornerInitialPosition; // Used to abort a move corner command
|
||||
static bool s_CornerIsNew; // Used to abort a move corner command (if it is a new corner, it must be deleted)
|
||||
static bool s_AddCutoutToCurrentZone; // if true, the next outline will be addes to s_CurrentZone
|
||||
static ZONE_CONTAINER* s_CurrentZone; // if != NULL, these ZONE_CONTAINER params will be used for the next zone
|
||||
static wxPoint s_CursorLastPosition; // in move zone outline, last cursor position. Used to calculate the move vector
|
||||
static PICKED_ITEMS_LIST s_PickedList; // a picked list to save zones for undo/redo command
|
||||
static PICKED_ITEMS_LIST _AuxiliaryList; // a picked list to store zones that are deleted or added when combined
|
||||
|
||||
#include "dialog_copper_zones.h"
|
||||
|
||||
|
@ -91,59 +92,6 @@ void WinEDA_PcbFrame::Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* zone_container
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
void WinEDA_PcbFrame::Delete_Zone_Fill( SEGZONE* aZone, long aTimestamp )
|
||||
/**********************************************************************************/
|
||||
|
||||
/** Function Delete_Zone_Fill
|
||||
* Remove the zone fillig which include the segment aZone, or the zone which have the given time stamp.
|
||||
* A zone is a group of segments which have the same TimeStamp
|
||||
* @param DC = current Device Context (can be NULL)
|
||||
* @param aZone = zone segment within the zone to delete. Can be NULL
|
||||
* @param aTimestamp = Timestamp for the zone to delete, used if aZone == NULL
|
||||
*/
|
||||
{
|
||||
bool modify = false;
|
||||
unsigned long TimeStamp;
|
||||
|
||||
if( aZone == NULL )
|
||||
TimeStamp = aTimestamp;
|
||||
else
|
||||
TimeStamp = aZone->m_TimeStamp; // Save reference time stamp (aZone will be deleted)
|
||||
|
||||
SEGZONE* next;
|
||||
for( SEGZONE* zone = GetBoard()->m_Zone; zone != NULL; zone = next )
|
||||
{
|
||||
next = zone->Next();
|
||||
if( zone->m_TimeStamp == TimeStamp )
|
||||
{
|
||||
modify = TRUE;
|
||||
/* remove item from linked list and free memory */
|
||||
zone->DeleteStructure();
|
||||
}
|
||||
}
|
||||
|
||||
// Now delete the outlines of the corresponding copper areas (deprecated)
|
||||
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
|
||||
{
|
||||
ZONE_CONTAINER* zone = GetBoard()->GetArea( ii );
|
||||
if( zone->m_TimeStamp == TimeStamp )
|
||||
{
|
||||
modify = TRUE;
|
||||
zone->m_FilledPolysList.clear();
|
||||
zone->m_FillSegmList.clear();
|
||||
zone->m_IsFilled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if( modify )
|
||||
{
|
||||
GetScreen()->SetModify();
|
||||
GetScreen()->SetRefreshReq();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************/
|
||||
int WinEDA_PcbFrame::Delete_LastCreatedCorner( wxDC* DC )
|
||||
/*******************************************************/
|
||||
|
@ -232,6 +180,22 @@ void WinEDA_PcbFrame::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_con
|
|||
Hight_Light( DC );
|
||||
}
|
||||
|
||||
|
||||
// Prepare copy of old zones, for undo/redo.
|
||||
// if the corner is new, remove it from list, save and insert it in list
|
||||
int cx = zone_container->m_Poly->GetX( corner_id );
|
||||
int cy = zone_container->m_Poly->GetY( corner_id );
|
||||
|
||||
if ( IsNewCorner )
|
||||
zone_container->m_Poly->DeleteCorner( corner_id );
|
||||
|
||||
_AuxiliaryList.ClearListAndDeleteItems();
|
||||
s_PickedList.ClearListAndDeleteItems();
|
||||
|
||||
SaveCopyOfZones(s_PickedList, GetBoard(), zone_container->GetNet(), zone_container->GetLayer() );
|
||||
if ( IsNewCorner )
|
||||
zone_container->m_Poly->InsertCorner(corner_id-1, cx, cy );
|
||||
|
||||
zone_container->m_Flags = IN_EDIT;
|
||||
DrawPanel->ManageCurseur = Show_Zone_Corner_Or_Outline_While_Move_Mouse;
|
||||
DrawPanel->ForceCloseManageCurseur = Abort_Zone_Move_Corner_Or_Outlines;
|
||||
|
@ -249,7 +213,7 @@ void WinEDA_PcbFrame::Start_Move_Zone_Drag_Outline_Edge( wxDC* DC,
|
|||
/**************************************************************************************/
|
||||
|
||||
/**
|
||||
* Function Start_Move_Zone_Corner
|
||||
* Function Start_Move_Zone_Drag_Outline_Edge
|
||||
* Prepares a drag edge for an existing zone outline,
|
||||
*/
|
||||
{
|
||||
|
@ -260,6 +224,11 @@ void WinEDA_PcbFrame::Start_Move_Zone_Drag_Outline_Edge( wxDC* DC,
|
|||
s_CursorLastPosition = s_CornerInitialPosition = GetScreen()->m_Curseur;
|
||||
s_AddCutoutToCurrentZone = false;
|
||||
s_CurrentZone = NULL;
|
||||
|
||||
s_PickedList.ClearListAndDeleteItems();
|
||||
_AuxiliaryList.ClearListAndDeleteItems();
|
||||
SaveCopyOfZones(s_PickedList, GetBoard(), zone_container->GetNet(), zone_container->GetLayer() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -284,6 +253,10 @@ void WinEDA_PcbFrame::Start_Move_Zone_Outlines( wxDC* DC, ZONE_CONTAINER* zone_c
|
|||
Hight_Light( DC );
|
||||
}
|
||||
|
||||
s_PickedList.ClearListAndDeleteItems();
|
||||
_AuxiliaryList.ClearListAndDeleteItems();
|
||||
SaveCopyOfZones(s_PickedList, GetBoard(), zone_container->GetNet(), zone_container->GetLayer() );
|
||||
|
||||
zone_container->m_Flags = IS_MOVED;
|
||||
DrawPanel->ManageCurseur = Show_Zone_Corner_Or_Outline_While_Move_Mouse;
|
||||
DrawPanel->ForceCloseManageCurseur = Abort_Zone_Move_Corner_Or_Outlines;
|
||||
|
@ -318,7 +291,7 @@ void WinEDA_PcbFrame::End_Move_Zone_Corner_Or_Outlines( wxDC* DC, ZONE_CONTAINER
|
|||
|
||||
/* Combine zones if possible */
|
||||
wxBusyCursor dummy;
|
||||
GetBoard()->AreaPolygonModified( zone_container, true, verbose );
|
||||
GetBoard()->AreaPolygonModified( &_AuxiliaryList, zone_container, true, s_Verbose );
|
||||
DrawPanel->Refresh();
|
||||
|
||||
|
||||
|
@ -326,6 +299,10 @@ void WinEDA_PcbFrame::End_Move_Zone_Corner_Or_Outlines( wxDC* DC, ZONE_CONTAINER
|
|||
if( ii < 0 )
|
||||
zone_container = NULL; // was removed by combining zones
|
||||
|
||||
UpdateCopyOfZonesList( s_PickedList, _AuxiliaryList, GetBoard() );
|
||||
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
|
||||
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
||||
|
||||
int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( zone_container, true );
|
||||
if( error_count )
|
||||
{
|
||||
|
@ -342,7 +319,7 @@ void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_contain
|
|||
* Function Remove_Zone_Corner
|
||||
* Remove the currently selected corner in a zone outline
|
||||
* the .m_CornerSelection is used as corner selection
|
||||
* @param DC = Current deice context (can be NULL )
|
||||
* @param DC = Current device context (can be NULL )
|
||||
* @param zone_container = the zone that contains the selected corner
|
||||
* the member .m_CornerSelection is used as selected corner
|
||||
*/
|
||||
|
@ -369,16 +346,23 @@ void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_contain
|
|||
GetBoard()->RedrawFilledAreas( DrawPanel, DC, GR_XOR, layer );
|
||||
}
|
||||
|
||||
_AuxiliaryList.ClearListAndDeleteItems();
|
||||
s_PickedList. ClearListAndDeleteItems();
|
||||
SaveCopyOfZones(s_PickedList, GetBoard(), zone_container->GetNet(), zone_container->GetLayer() );
|
||||
zone_container->m_Poly->DeleteCorner( zone_container->m_CornerSelection );
|
||||
|
||||
// modify zones outlines according to the new zone_container shape
|
||||
GetBoard()->AreaPolygonModified( zone_container, true, verbose );
|
||||
GetBoard()->AreaPolygonModified( &_AuxiliaryList, zone_container, true, s_Verbose );
|
||||
if( DC )
|
||||
{
|
||||
GetBoard()->RedrawAreasOutlines( DrawPanel, DC, GR_OR, layer );
|
||||
GetBoard()->RedrawFilledAreas( DrawPanel, DC, GR_OR, layer );
|
||||
}
|
||||
|
||||
UpdateCopyOfZonesList( s_PickedList, _AuxiliaryList, GetBoard() );
|
||||
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
|
||||
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
||||
|
||||
int ii = GetBoard()->GetAreaIndex( zone_container ); // test if zone_container exists
|
||||
if( ii < 0 )
|
||||
zone_container = NULL; // zone_container does not exist anymaore, after combining zones
|
||||
|
@ -402,8 +386,6 @@ void Abort_Zone_Move_Corner_Or_Outlines( WinEDA_DrawPanel* Panel, wxDC* DC )
|
|||
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent;
|
||||
ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) pcbframe->GetCurItem();
|
||||
|
||||
// zone_container->Draw( Panel, DC, GR_XOR );
|
||||
|
||||
if( zone_container->m_Flags == IS_MOVED )
|
||||
{
|
||||
wxPoint offset;
|
||||
|
@ -429,10 +411,10 @@ void Abort_Zone_Move_Corner_Or_Outlines( WinEDA_DrawPanel* Panel, wxDC* DC )
|
|||
}
|
||||
}
|
||||
|
||||
// zone_container->Draw( Panel, DC, GR_XOR );
|
||||
_AuxiliaryList.ClearListAndDeleteItems();
|
||||
s_PickedList. ClearListAndDeleteItems();
|
||||
Panel->Refresh();
|
||||
|
||||
|
||||
Panel->ManageCurseur = NULL;
|
||||
Panel->ForceCloseManageCurseur = NULL;
|
||||
pcbframe->SetCurItem( NULL );
|
||||
|
@ -644,7 +626,7 @@ bool WinEDA_PcbFrame::End_Zone( wxDC* DC )
|
|||
if( zone == NULL )
|
||||
return true;
|
||||
|
||||
// Validate the curren outline:
|
||||
// Validate the current outline:
|
||||
if( zone->GetNumCorners() <= 2 ) // An outline must have 3 corners or more
|
||||
{
|
||||
Abort_Zone_Create_Outline( DrawPanel, DC );
|
||||
|
@ -678,12 +660,20 @@ bool WinEDA_PcbFrame::End_Zone( wxDC* DC )
|
|||
GetBoard()->RedrawAreasOutlines( DrawPanel, DC, GR_XOR, layer );
|
||||
GetBoard()->RedrawFilledAreas( DrawPanel, DC, GR_XOR, layer );
|
||||
|
||||
/* Put edges in list */
|
||||
// Save initial zones configuration, for undo/redo, before adding new zone
|
||||
_AuxiliaryList.ClearListAndDeleteItems();
|
||||
s_PickedList.ClearListAndDeleteItems();
|
||||
SaveCopyOfZones(s_PickedList, GetBoard(), zone->GetNet(), zone->GetLayer() );
|
||||
|
||||
/* Put new zone in list */
|
||||
if( s_CurrentZone == NULL )
|
||||
{
|
||||
zone->m_Poly->Close(); // Close the current corner list
|
||||
GetBoard()->Add( zone );
|
||||
GetBoard()->m_CurrentZoneContour = NULL;
|
||||
// Add this zone in picked list, as new item
|
||||
ITEM_PICKER picker( zone, UR_NEW );
|
||||
s_PickedList.PushItem( picker );
|
||||
}
|
||||
else // Append this outline as a cutout to an existing zone
|
||||
{
|
||||
|
@ -703,7 +693,7 @@ bool WinEDA_PcbFrame::End_Zone( wxDC* DC )
|
|||
GetScreen()->SetCurItem( NULL ); // This outine can be deleted when merging outlines
|
||||
|
||||
// Combine zones if possible :
|
||||
GetBoard()->AreaPolygonModified( zone, true, verbose );
|
||||
GetBoard()->AreaPolygonModified( &_AuxiliaryList, zone, true, s_Verbose );
|
||||
|
||||
// Redraw the real edge zone :
|
||||
GetBoard()->RedrawAreasOutlines( DrawPanel, DC, GR_OR, layer );
|
||||
|
@ -712,12 +702,17 @@ bool WinEDA_PcbFrame::End_Zone( wxDC* DC )
|
|||
int ii = GetBoard()->GetAreaIndex( zone ); // test if zone_container exists
|
||||
if( ii < 0 )
|
||||
zone = NULL; // was removed by combining zones
|
||||
|
||||
int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( zone, true );
|
||||
if( error_count )
|
||||
{
|
||||
DisplayError( this, _( "Area: DRC outline error" ) );
|
||||
}
|
||||
|
||||
UpdateCopyOfZonesList( s_PickedList, _AuxiliaryList, GetBoard() );
|
||||
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
|
||||
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
||||
|
||||
GetScreen()->SetModify();
|
||||
return true;
|
||||
}
|
||||
|
@ -727,7 +722,7 @@ bool WinEDA_PcbFrame::End_Zone( wxDC* DC )
|
|||
static void Show_New_Edge_While_Move_Mouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
|
||||
/******************************************************************************************/
|
||||
|
||||
/* Redraws the edge zone when moving mouse
|
||||
/* Redraws the zone outlines when moving mouse
|
||||
*/
|
||||
{
|
||||
WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) panel->m_Parent;
|
||||
|
@ -772,6 +767,14 @@ void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container
|
|||
{
|
||||
int diag;
|
||||
DrawPanel->m_IgnoreMouseEvents = TRUE;
|
||||
|
||||
/* Save initial zones configuration, for undo/redo, before adding new zone
|
||||
* note the net name and the layer can be changed, so we must save all zones
|
||||
*/
|
||||
_AuxiliaryList.ClearListAndDeleteItems();
|
||||
s_PickedList.ClearListAndDeleteItems();
|
||||
SaveCopyOfZones(s_PickedList, GetBoard(), -1, -1 );
|
||||
|
||||
if( zone_container->GetLayer() < FIRST_NO_COPPER_LAYER )
|
||||
{ // edit a zone on a copper layer
|
||||
g_Zone_Default_Setting.ImportSetting(*zone_container);
|
||||
|
@ -786,7 +789,18 @@ void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container
|
|||
DrawPanel->m_IgnoreMouseEvents = FALSE;
|
||||
|
||||
if( diag == ZONE_ABORT )
|
||||
{
|
||||
_AuxiliaryList.ClearListAndDeleteItems();
|
||||
s_PickedList.ClearListAndDeleteItems();
|
||||
return;
|
||||
}
|
||||
if( diag == ZONE_EXPORT_VALUES )
|
||||
{
|
||||
UpdateCopyOfZonesList( s_PickedList, _AuxiliaryList, GetBoard() );
|
||||
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
|
||||
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
||||
return;
|
||||
}
|
||||
|
||||
// Undraw old zone outlines
|
||||
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
|
||||
|
@ -797,16 +811,19 @@ void WinEDA_PcbFrame::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* zone_container
|
|||
|
||||
g_Zone_Default_Setting.ExportSetting( *zone_container);
|
||||
NETINFO_ITEM* net = GetBoard()->FindNet( g_Zone_Default_Setting.m_NetcodeSelection );
|
||||
if( net ) // net === NULL should not occur
|
||||
if( net ) // net == NULL should not occur
|
||||
zone_container->m_Netname = net->GetNetname();
|
||||
|
||||
|
||||
// Combine zones if possible :
|
||||
GetBoard()->AreaPolygonModified( zone_container, true, verbose );
|
||||
GetBoard()->AreaPolygonModified( &_AuxiliaryList, zone_container, true, s_Verbose );
|
||||
|
||||
// Redraw the real new zone outlines:
|
||||
GetBoard()->RedrawAreasOutlines( DrawPanel, DC, GR_OR, -1 );
|
||||
|
||||
UpdateCopyOfZonesList( s_PickedList, _AuxiliaryList, GetBoard() );
|
||||
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
|
||||
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
||||
|
||||
GetScreen()->SetModify();
|
||||
}
|
||||
|
||||
|
@ -847,106 +864,3 @@ void WinEDA_PcbFrame::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* zone_contai
|
|||
GetScreen()->SetModify();
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool verbose )
|
||||
/***************************************************************************************/
|
||||
|
||||
/** Function Fill_Zone()
|
||||
* Calculate the zone filling for the outline zone_container
|
||||
* The zone outline is a frontier, and can be complex (with holes)
|
||||
* The filling starts from starting points like pads, tracks.
|
||||
* If exists, the old filling is removed
|
||||
* @param DC = current Device Context
|
||||
* @param zone_container = zone to fill
|
||||
* @param verbose = true to show error messages
|
||||
* @return error level (0 = no error)
|
||||
*/
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
MsgPanel->EraseMsgBox();
|
||||
if( GetBoard()->ComputeBoundaryBox() == FALSE )
|
||||
{
|
||||
if( verbose )
|
||||
DisplayError( this, wxT( "Board is empty!" ), 10 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Shows the Net */
|
||||
g_Zone_Default_Setting.m_NetcodeSelection = zone_container->GetNet();
|
||||
if( g_HightLigt_Status && (g_HightLigth_NetCode != g_Zone_Default_Setting.m_NetcodeSelection) && DC )
|
||||
{
|
||||
Hight_Light( DC ); // Remove old highlight selection
|
||||
}
|
||||
|
||||
g_HightLigth_NetCode = g_Zone_Default_Setting.m_NetcodeSelection;
|
||||
if( DC )
|
||||
Hight_Light( DC );
|
||||
|
||||
if( g_HightLigth_NetCode > 0 )
|
||||
{
|
||||
NETINFO_ITEM* net = GetBoard()->FindNet( g_HightLigth_NetCode );
|
||||
if( net == NULL )
|
||||
{
|
||||
if( g_HightLigth_NetCode > 0 )
|
||||
{
|
||||
if( verbose )
|
||||
DisplayError( this, wxT( "Unable to find Net name" ) );
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
else
|
||||
msg = net->GetNetname();
|
||||
}
|
||||
else
|
||||
msg = _( "No Net" );
|
||||
|
||||
Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED );
|
||||
wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor)
|
||||
|
||||
int error_level = 0;
|
||||
zone_container->m_FilledPolysList.clear();
|
||||
Delete_Zone_Fill( NULL, zone_container->m_TimeStamp );
|
||||
zone_container->BuildFilledPolysListData( GetBoard() );
|
||||
|
||||
if ( DC )
|
||||
DrawPanel->Refresh();
|
||||
|
||||
GetScreen()->SetModify();
|
||||
|
||||
return error_level;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************/
|
||||
int WinEDA_PcbFrame::Fill_All_Zones( bool verbose )
|
||||
/************************************************************/
|
||||
|
||||
/** Function Fill_All_Zones()
|
||||
* Fill all zones on the board
|
||||
* The old fillings are removed
|
||||
* @param verbose = true to show error messages
|
||||
* @return error level (0 = no error)
|
||||
*/
|
||||
{
|
||||
ZONE_CONTAINER* zone_container;
|
||||
int error_level = 0;
|
||||
|
||||
// Remove all zones :
|
||||
GetBoard()->m_Zone.DeleteAll();
|
||||
|
||||
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
|
||||
{
|
||||
zone_container = GetBoard()->GetArea( ii );
|
||||
error_level = Fill_Zone( NULL, zone_container, verbose );
|
||||
if( error_level && !verbose )
|
||||
break;
|
||||
}
|
||||
test_connexions( NULL );
|
||||
Tst_Ratsnest( NULL, 0 ); // Recalculate the active ratsnest, i.e. the unconnected links */
|
||||
DrawPanel->Refresh( true );
|
||||
return error_level;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: zones_by_polygon_fill_functions.cpp
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2009 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
* Copyright (C) 2007 Kicad Developers, see change_log.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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "appl_wxstruct.h"
|
||||
#include "common.h"
|
||||
#include "class_drawpanel.h"
|
||||
#include "pcbnew.h"
|
||||
#include "wxPcbStruct.h"
|
||||
#include "zones.h"
|
||||
|
||||
|
||||
/**********************************************************************************/
|
||||
void WinEDA_PcbFrame::Delete_Zone_Fill( SEGZONE* aZone, long aTimestamp )
|
||||
/**********************************************************************************/
|
||||
|
||||
/** Function Delete_Zone_Fill
|
||||
* Remove the zone fillig which include the segment aZone, or the zone which have the given time stamp.
|
||||
* A zone is a group of segments which have the same TimeStamp
|
||||
* @param DC = current Device Context (can be NULL)
|
||||
* @param aZone = zone segment within the zone to delete. Can be NULL
|
||||
* @param aTimestamp = Timestamp for the zone to delete, used if aZone == NULL
|
||||
*/
|
||||
{
|
||||
bool modify = false;
|
||||
unsigned long TimeStamp;
|
||||
|
||||
if( aZone == NULL )
|
||||
TimeStamp = aTimestamp;
|
||||
else
|
||||
TimeStamp = aZone->m_TimeStamp; // Save reference time stamp (aZone will be deleted)
|
||||
|
||||
SEGZONE* next;
|
||||
for( SEGZONE* zone = GetBoard()->m_Zone; zone != NULL; zone = next )
|
||||
{
|
||||
next = zone->Next();
|
||||
if( zone->m_TimeStamp == TimeStamp )
|
||||
{
|
||||
modify = TRUE;
|
||||
/* remove item from linked list and free memory */
|
||||
zone->DeleteStructure();
|
||||
}
|
||||
}
|
||||
|
||||
// Now delete the outlines of the corresponding copper areas (deprecated)
|
||||
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
|
||||
{
|
||||
ZONE_CONTAINER* zone = GetBoard()->GetArea( ii );
|
||||
if( zone->m_TimeStamp == TimeStamp )
|
||||
{
|
||||
modify = TRUE;
|
||||
zone->m_FilledPolysList.clear();
|
||||
zone->m_FillSegmList.clear();
|
||||
zone->m_IsFilled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if( modify )
|
||||
{
|
||||
GetScreen()->SetModify();
|
||||
GetScreen()->SetRefreshReq();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
int WinEDA_PcbFrame::Fill_Zone( ZONE_CONTAINER* zone_container, bool verbose )
|
||||
/***************************************************************************************/
|
||||
|
||||
/** Function Fill_Zone()
|
||||
* Calculate the zone filling for the outline zone_container
|
||||
* The zone outline is a frontier, and can be complex (with holes)
|
||||
* The filling starts from starting points like pads, tracks.
|
||||
* If exists, the old filling is removed
|
||||
* @param zone_container = zone to fill
|
||||
* @param verbose = true to show error messages
|
||||
* @return error level (0 = no error)
|
||||
*/
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
MsgPanel->EraseMsgBox();
|
||||
if( GetBoard()->ComputeBoundaryBox() == false )
|
||||
{
|
||||
if( verbose )
|
||||
wxMessageBox( wxT( "Board is empty!" ) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Shows the Net */
|
||||
g_Zone_Default_Setting.m_NetcodeSelection = zone_container->GetNet();
|
||||
|
||||
if( zone_container->GetNet() > 0 )
|
||||
{
|
||||
NETINFO_ITEM* net = GetBoard()->FindNet( zone_container->GetNet() );
|
||||
if( net == NULL )
|
||||
{
|
||||
if( verbose )
|
||||
wxMessageBox( wxT( "Unable to find Net name" ) );
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
msg = net->GetNetname();
|
||||
}
|
||||
else
|
||||
msg = _( "No Net" );
|
||||
|
||||
Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED );
|
||||
wxBusyCursor dummy; // Shows an hourglass cursor (removed by its destructor)
|
||||
|
||||
zone_container->m_FilledPolysList.clear();
|
||||
Delete_Zone_Fill( NULL, zone_container->m_TimeStamp );
|
||||
zone_container->BuildFilledPolysListData( GetBoard() );
|
||||
|
||||
GetScreen()->SetModify();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************/
|
||||
int WinEDA_PcbFrame::Fill_All_Zones( bool verbose )
|
||||
/************************************************************/
|
||||
|
||||
/** Function Fill_All_Zones()
|
||||
* Fill all zones on the board
|
||||
* The old fillings are removed
|
||||
* @param verbose = true to show error messages
|
||||
* @return error level (0 = no error)
|
||||
*/
|
||||
{
|
||||
ZONE_CONTAINER* zone_container;
|
||||
int error_level = 0;
|
||||
|
||||
// Remove all zones :
|
||||
GetBoard()->m_Zone.DeleteAll();
|
||||
|
||||
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
|
||||
{
|
||||
zone_container = GetBoard()->GetArea( ii );
|
||||
error_level = Fill_Zone( zone_container, verbose );
|
||||
if( error_level && !verbose )
|
||||
break;
|
||||
}
|
||||
test_connexions( NULL );
|
||||
Tst_Ratsnest( NULL, 0 ); // Recalculate the active ratsnest, i.e. the unconnected links */
|
||||
DrawPanel->Refresh( true );
|
||||
return error_level;
|
||||
}
|
||||
|
||||
|
|
@ -356,8 +356,8 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
|||
}
|
||||
|
||||
// Now we remove all unused thermal stubs.
|
||||
//define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations
|
||||
//#ifdef REMOVE_UNUSED_THERMAL_STUBS
|
||||
#define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations
|
||||
#ifdef REMOVE_UNUSED_THERMAL_STUBS
|
||||
|
||||
/* Add the main (corrected) polygon (i.e. the filled area using only one outline)
|
||||
* in GroupA in Bool_Engine to do a BOOL_A_SUB_B operation
|
||||
|
@ -500,7 +500,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
|||
|
||||
delete booleng;
|
||||
|
||||
//#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -807,7 +807,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
|
|||
// this seems a bug in kbool polygon (exists in 1.9 kbool version)
|
||||
// angle = 450 (45.0 degrees orientation) seems work fine.
|
||||
// angle = 0 with thermal shapes without angle < 90 deg has problems in rare circumstances
|
||||
// Note: with the 2 step build ( thermal shpaes after correr areas build), 0 seems work
|
||||
// Note: with the 2 step build ( thermal shapes added after areas are built), 0 seems work
|
||||
angle = 450;
|
||||
int angle_pad = aPad.m_Orient; // Pad orientation
|
||||
for( unsigned ihole = 0; ihole < 4; ihole++ )
|
||||
|
@ -1247,7 +1247,7 @@ void AddTextBoxWithClearancePolygon( Bool_Engine* aBooleng,
|
|||
corners[3].y = corners[2].y;
|
||||
corners[3].x = corners[0].x;
|
||||
|
||||
|
||||
|
||||
if( aBooleng->StartPolygonAdd( GROUP_B ) )
|
||||
{
|
||||
for( int ii = 0; ii < 4; ii ++ )
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Name: zones_functions_for_undo_redo.cpp
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2009 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
* Copyright (C) 2007 Kicad Developers, see change_log.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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
/* These functions are relative to undo redo function, when zones are involved.
|
||||
* When a zone outline is modified (or created) this zone, or others zones on the same layer
|
||||
* and with the same netcode can change or can be deleted
|
||||
* This is due to the fact overlapping zones are merged
|
||||
* Also, when a zone outline is modified by adding a cutout area,
|
||||
* this zone can be converted to more than one area, if the outline is break to 2 or more outlines
|
||||
* and therefore new zones are created
|
||||
*
|
||||
* Due to the complexity of potential changes, and the fact there are only few zones
|
||||
* in a board, and a zone has only few segments outlines, the more easy way to
|
||||
* undo redo changes is to make a copy of all zones that can be changed
|
||||
* and see after zone edition or creation what zones that are really modified,
|
||||
* and ones they are modified (changes, deletion or addition)
|
||||
*/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "appl_wxstruct.h"
|
||||
#include "common.h"
|
||||
#include "class_drawpanel.h"
|
||||
#include "pcbnew.h"
|
||||
#include "wxPcbStruct.h"
|
||||
#include "zones.h"
|
||||
#include "zones_functions_for_undo_redo.h"
|
||||
|
||||
/** function ZONE_CONTAINER::IsSame()
|
||||
* test is 2 zones are equivalent:
|
||||
* 2 zones are equivalent if they have same parameters and same outlines
|
||||
* info relative to filling is not take in account
|
||||
* @param aZoneToCompare = zone to compare with "this"
|
||||
*/
|
||||
bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare )
|
||||
{
|
||||
// compare basic parameters:
|
||||
if( GetLayer() != aZoneToCompare.GetLayer() )
|
||||
return false;
|
||||
if( m_Netname != aZoneToCompare.m_Netname )
|
||||
return false;
|
||||
|
||||
// Compare zone specfic parameters
|
||||
if( m_ZoneClearance != aZoneToCompare.m_ZoneClearance )
|
||||
return false;
|
||||
if( m_ZoneMinThickness != aZoneToCompare.m_ZoneMinThickness )
|
||||
return false;
|
||||
if( m_FillMode != aZoneToCompare.m_FillMode )
|
||||
return false;
|
||||
if( m_ArcToSegmentsCount != aZoneToCompare.m_ArcToSegmentsCount )
|
||||
return false;
|
||||
if( m_PadOption != aZoneToCompare.m_PadOption )
|
||||
return false;
|
||||
if( m_ThermalReliefGapValue != aZoneToCompare.m_ThermalReliefGapValue )
|
||||
return false;
|
||||
if( m_ThermalReliefCopperBridgeValue != aZoneToCompare.m_ThermalReliefCopperBridgeValue )
|
||||
return false;
|
||||
|
||||
// Compare outlines
|
||||
wxASSERT( m_Poly ); // m_Poly == NULL Should never happen
|
||||
wxASSERT( aZoneToCompare.m_Poly );
|
||||
if( m_Poly->corner != aZoneToCompare.m_Poly->corner ) // Compare vector
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** function SaveCopyOfZones()
|
||||
* creates a copy of zones having a given netcode on a given layer,
|
||||
* and fill a pick list with pickers to handle these copies
|
||||
* the UndoRedo status is set to UR_CHANGED for all items in list
|
||||
* Later, UpdateCopyOfZonesList will change and update these pickers after a zone edition
|
||||
* @param aPickList = the pick list
|
||||
* @param aPcb = the Board
|
||||
* @param aNetCode = the reference netcode. if aNetCode < 0 all netcodes are used
|
||||
* @param aLayer = the layer of zones. if aLayer < 0, all layers are used
|
||||
* @return the count of saved copies
|
||||
*/
|
||||
int SaveCopyOfZones( PICKED_ITEMS_LIST& aPickList, BOARD* aPcb, int aNetCode, int aLayer )
|
||||
{
|
||||
int copyCount = 0;
|
||||
|
||||
for( unsigned ii = 0; ; ii++ )
|
||||
{
|
||||
ZONE_CONTAINER* zone = aPcb->GetArea( ii );
|
||||
if( zone == NULL ) // End of list
|
||||
break;
|
||||
if( aNetCode >= 0 && aNetCode != zone->GetNet() )
|
||||
continue;
|
||||
if( aLayer >= 0 && aLayer != zone->GetLayer() )
|
||||
continue;
|
||||
ZONE_CONTAINER* zoneDup = new ZONE_CONTAINER( aPcb );
|
||||
zoneDup->Copy( zone );
|
||||
ITEM_PICKER picker( zone, UR_CHANGED );
|
||||
picker.m_Link = zoneDup;
|
||||
picker.m_PickedItemType = zone->Type();
|
||||
aPickList.PushItem( picker );
|
||||
copyCount++;
|
||||
}
|
||||
|
||||
return copyCount;
|
||||
}
|
||||
|
||||
|
||||
/** function UpdateCopyOfZonesList()
|
||||
* check a pick list to remove zones identical to their copies
|
||||
* and set the type of operation in picker (UR_DELETED, UR_CHANGED)
|
||||
* if an item is deleted, the initial values are retrievered,
|
||||
* because they can have changed in edition
|
||||
* @param aPickList = the main pick list
|
||||
* @param aAuxiliaryList = the list of deleted or added (new created) items after calculations
|
||||
* @param aPcb = the Board
|
||||
*
|
||||
* aAuxiliaryList is a list of pickers updated by zone algorithms:
|
||||
* In this list are put zone taht were added or deleted during the zone combine process
|
||||
* aPickList :is a list of zone that can be modified (changed or deleted, or not modified)
|
||||
* >> if the picked zone is not changed, it is removed from list
|
||||
* >> if the picked zone was deleted (i.e. not found in boad list), the picker is modified:
|
||||
* - its status becomes UR_DELETED
|
||||
* - the aAuxiliaryList corresponding picker is removed (if not found : set an error)
|
||||
* >> if the picked zone was flagged as UR_NEW, and was deleted (i.e. not found in boad list),
|
||||
* - the picker is removed
|
||||
* - the zone itself if really deleted
|
||||
* - the aAuxiliaryList corresponding picker is removed (if not found : set an error)
|
||||
* After aPickList is cleaned, the aAuxiliaryList is read
|
||||
* All pickers flagged UR_NEW are moved to aPickList
|
||||
* (the corresponding zones are zone that were created by the zone combine process, mainly when adding cutaout areas)
|
||||
* At the end of the update process the aAuxiliaryList must be void, because all pickers created by the combine process
|
||||
* must have been removed (removed for new and deleted zones, or moved in aPickList.)
|
||||
* If not an error is set.
|
||||
*/
|
||||
void UpdateCopyOfZonesList( PICKED_ITEMS_LIST& aPickList,
|
||||
PICKED_ITEMS_LIST& aAuxiliaryList,
|
||||
BOARD* aPcb )
|
||||
{
|
||||
for( unsigned kk = 0; kk < aPickList.GetCount(); kk++ )
|
||||
{
|
||||
UndoRedoOpType status = aPickList.GetPickedItemStatus( kk );
|
||||
|
||||
ZONE_CONTAINER* ref = (ZONE_CONTAINER*) aPickList.GetPickedItem( kk );
|
||||
for( unsigned ii = 0; ; ii++ ) // analyse the main picked list
|
||||
{
|
||||
ZONE_CONTAINER* zone = aPcb->GetArea( ii );
|
||||
if( zone == NULL )
|
||||
{
|
||||
/* End of list: the stored item is not found:
|
||||
* it must be in aDeletedList:
|
||||
* search it and restore initial values
|
||||
* or
|
||||
* if flagged UR_NEW: remove it definitively
|
||||
*/
|
||||
if( status == UR_NEW )
|
||||
{
|
||||
delete ref;
|
||||
aPickList.RemovePicker( kk );
|
||||
kk--;
|
||||
}
|
||||
else
|
||||
{
|
||||
ZONE_CONTAINER* zcopy = (ZONE_CONTAINER*) aPickList.GetPickedItemLink( kk );
|
||||
aPickList.SetPickedItemStatus( UR_DELETED, kk );
|
||||
if( zcopy )
|
||||
ref->Copy( zcopy );
|
||||
else
|
||||
wxMessageBox( wxT( "UpdateCopyOfZonesList() error: link = NULL" ) );
|
||||
aPickList.SetPickedItemLink( NULL, kk ); // the copy was deleted; the link does not exists now
|
||||
delete zcopy;
|
||||
}
|
||||
|
||||
// Remove this item from aAuxiliaryList, mainly for tests purpose
|
||||
bool notfound = true;
|
||||
for( unsigned nn = 0; nn < aAuxiliaryList.GetCount(); nn++ )
|
||||
{
|
||||
if( aAuxiliaryList.GetPickedItem( nn ) == ref )
|
||||
{
|
||||
aAuxiliaryList.RemovePicker( nn );
|
||||
notfound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( notfound )
|
||||
wxMessageBox( wxT(
|
||||
"UpdateCopyOfZonesList() error: item not found in aAuxiliaryList" ) );
|
||||
break;
|
||||
}
|
||||
if( zone == ref ) // picked zone found
|
||||
{
|
||||
if( aPickList.GetPickedItemStatus( kk ) != UR_NEW )
|
||||
{
|
||||
ZONE_CONTAINER* zcopy = (ZONE_CONTAINER*) aPickList.GetPickedItemLink( kk );
|
||||
if( zone->IsSame( *zcopy ) ) // Remove picked, because no changes
|
||||
{
|
||||
delete zcopy; // Delete copy
|
||||
aPickList.RemovePicker( kk );
|
||||
kk--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add new zones in main pick list, and remove pickers from Auxiliary List
|
||||
for( unsigned ii = 0; ii < aAuxiliaryList.GetCount(); ii++ )
|
||||
{
|
||||
if( aAuxiliaryList.GetPickedItemStatus( ii ) == UR_NEW )
|
||||
{
|
||||
ITEM_PICKER picker = aAuxiliaryList.GetItemWrapper( ii );
|
||||
aPickList.PushItem( picker );
|
||||
aAuxiliaryList.RemovePicker( ii );
|
||||
ii--;
|
||||
}
|
||||
}
|
||||
|
||||
// Should not occur:
|
||||
if( aAuxiliaryList.GetCount()> 0 )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( wxT(
|
||||
"UpdateCopyOfZonesList() error: aAuxiliaryList not void: %d item left (status %d)" ),
|
||||
aAuxiliaryList.GetCount(), aAuxiliaryList.GetPickedItemStatus( 0 ) );
|
||||
wxMessageBox( msg );
|
||||
while( aAuxiliaryList.GetCount()> 0 )
|
||||
{
|
||||
delete aAuxiliaryList.GetPickedItemLink( 0 );
|
||||
aAuxiliaryList.RemovePicker( 0 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: zones_functions_for_undo_redo.h
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2009 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
* Copyright (C) 2007 Kicad Developers, see change_log.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
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
/* These functions are relative to undo redo function, when zones are involved.
|
||||
* When a zone outline is modified (or created) this zone, or others zones on the same layer
|
||||
* and with the same netcode can change or can be deleted
|
||||
* This is due to the fact overlapping zones are merged
|
||||
* Also, when a zone outline is modified by adding a cutout area,
|
||||
* this zone can be converted to more than one area, if the outline is break to 2 or more outlines
|
||||
* and therefore new zones are created
|
||||
*
|
||||
* Due to the complexity of potential changes, and the fact there are only few zones
|
||||
* in a board, and a zone has only few segments outlines, the more easy way to
|
||||
* undo redo changes is to make a copy of all zones that can be changed
|
||||
* and see after zone edition or creation what zones that are really modified,
|
||||
* and ones they are modified (changes, deletion or addition)
|
||||
*/
|
||||
|
||||
#ifndef ZONES_FUNCTIONS_TO_UNDO_REDO_H
|
||||
#define ZONES_FUNCTIONS_TO_UNDO_REDO_H
|
||||
|
||||
|
||||
/** function SaveCopyOfZones()
|
||||
* creates a copy of zones having a given netcode on a given layer,
|
||||
* and fill a pick list with pickers to handle these copies
|
||||
* @param aPickList = the pick list
|
||||
* @param aPcb = the Board
|
||||
* @param aNetCode = the reference netcode. if aNetCode < 0 all netcodes are used
|
||||
* @param aLayer = the layer of zones. if aLayer < 0, all layers are used
|
||||
* @return the count of saved copies
|
||||
*/
|
||||
int SaveCopyOfZones(PICKED_ITEMS_LIST & aPickList, BOARD* aPcb, int aNetCode, int aLayer );
|
||||
|
||||
|
||||
/** function UpdateCopyOfZonesList()
|
||||
* check a pick list to remove zones identical to their copies
|
||||
* and set the type of operation in picker (UR_DELETED, UR_CHANGED)
|
||||
* @param aPickList = the main pick list
|
||||
* @param aDeletedList = the list of dleted items
|
||||
* @param aPcb = the Board
|
||||
*/
|
||||
void UpdateCopyOfZonesList( PICKED_ITEMS_LIST& aPickList, PICKED_ITEMS_LIST& aDeletedList, BOARD* aPcb );
|
||||
|
||||
#endif // ZONES_FUNCTIONS_TO_UNDO_REDO_H
|
|
@ -18,29 +18,52 @@ bool bDontShowIntersectionArcsWarning;
|
|||
bool bDontShowIntersectionWarning;
|
||||
|
||||
|
||||
/**
|
||||
* Function AddArea
|
||||
* add empty copper area to net
|
||||
/** Function AddArea
|
||||
* Add an empty copper area to board areas list
|
||||
* @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful in undo commands)
|
||||
* can be NULL
|
||||
* @param aNetcode = the necode of the copper area (0 = no net)
|
||||
* @param aLayer = the layer of area
|
||||
* @param aStartPointPosition = position of the first point of the polygon outline of this area
|
||||
* @param aHatch = hacth option
|
||||
* @return pointer to the new area
|
||||
*/
|
||||
ZONE_CONTAINER* BOARD::AddArea( int netcode, int layer, int x, int y, int hatch )
|
||||
ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
|
||||
int aLayer, wxPoint aStartPointPosition, int aHatch )
|
||||
{
|
||||
ZONE_CONTAINER* new_area = InsertArea( netcode, m_ZoneDescriptorList.size(
|
||||
) - 1, layer, x, y, hatch );
|
||||
ZONE_CONTAINER* new_area = InsertArea( aNetcode,
|
||||
m_ZoneDescriptorList.size( ) - 1,
|
||||
aLayer, aStartPointPosition.x, aStartPointPosition.y, aHatch );
|
||||
|
||||
if( aNewZonesList )
|
||||
{
|
||||
ITEM_PICKER picker( new_area, UR_NEW );
|
||||
picker.m_PickedItemType = new_area->Type();
|
||||
aNewZonesList->PushItem( picker );
|
||||
}
|
||||
return new_area;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* remove copper area from net
|
||||
* @param area = area to remove
|
||||
* @return 0
|
||||
/** Function RemoveArea
|
||||
* remove copper area from net, and put it in a deleted list (if exists)
|
||||
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands)
|
||||
* can be NULL
|
||||
* @param area_to_remove = area to delete or put in deleted list
|
||||
*/
|
||||
int BOARD::RemoveArea( ZONE_CONTAINER* area_to_remove )
|
||||
void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove )
|
||||
{
|
||||
Delete( area_to_remove );
|
||||
return 0;
|
||||
if( area_to_remove == NULL )
|
||||
return;
|
||||
if( aDeletedList )
|
||||
{
|
||||
ITEM_PICKER picker( area_to_remove, UR_DELETED );
|
||||
picker.m_PickedItemType = area_to_remove->Type();
|
||||
aDeletedList->PushItem( picker );
|
||||
Remove( area_to_remove ); // remove from zone list, but does not delete it
|
||||
}
|
||||
else
|
||||
Delete( area_to_remove );
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,9 +105,8 @@ int BOARD::CompleteArea( ZONE_CONTAINER* area_to_complete, int style )
|
|||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveArea( area_to_complete );
|
||||
}
|
||||
Delete( area_to_complete );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -206,19 +228,24 @@ int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea )
|
|||
* Function ClipAreaPolygon
|
||||
* Process an area that has been modified, by clipping its polygon against itself.
|
||||
* This may change the number and order of copper areas in the net.
|
||||
* @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful in undo commands)
|
||||
* can be NULL
|
||||
* @param aCurrArea = the zone to process
|
||||
* @param bMessageBoxInt == true, shows message when clipping occurs.
|
||||
* @param bMessageBoxArc == true, shows message when clipping can't be done due to arcs.
|
||||
* @param bRetainArcs = true to handle arcs (not really used in kicad)
|
||||
* @return:
|
||||
* -1 if arcs intersect other sides, so polygon can't be clipped
|
||||
* 0 if no intersecting sides
|
||||
* 1 if intersecting sides
|
||||
* Also sets areas->utility1 flags if areas are modified
|
||||
*/
|
||||
int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
||||
int BOARD::ClipAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
|
||||
ZONE_CONTAINER* aCurrArea,
|
||||
bool bMessageBoxArc, bool bMessageBoxInt, bool bRetainArcs )
|
||||
{
|
||||
CPolyLine* curr_polygon = CurrArea->m_Poly;
|
||||
int test = TestAreaPolygon( CurrArea ); // this sets utility2 flag
|
||||
CPolyLine* curr_polygon = aCurrArea->m_Poly;
|
||||
int test = TestAreaPolygon( aCurrArea ); // this sets utility2 flag
|
||||
|
||||
if( test == -1 && !bRetainArcs )
|
||||
test = 1;
|
||||
|
@ -229,7 +256,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
|||
{
|
||||
wxString str;
|
||||
str.Printf( wxT( "Area %8.8X of net \"%s\" has arcs intersecting other sides.\n" ),
|
||||
CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() );
|
||||
aCurrArea->m_TimeStamp, aCurrArea->m_Netname.GetData() );
|
||||
str += wxT( "This may cause problems with other editing operations,\n" );
|
||||
str += wxT( "such as adding cutouts. It can't be fixed automatically.\n" );
|
||||
str += wxT( "Manual correction is recommended." );
|
||||
|
@ -242,7 +269,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
|||
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
|
||||
m_ZoneDescriptorList[ia]->utility = 0;
|
||||
|
||||
CurrArea->utility = 1;
|
||||
aCurrArea->utility = 1;
|
||||
|
||||
if( test == 1 )
|
||||
{
|
||||
|
@ -252,7 +279,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
|||
wxString str;
|
||||
str.Printf( wxT(
|
||||
"Area %8.8X of net \"%s\" is self-intersecting and will be clipped.\n" ),
|
||||
CurrArea->m_TimeStamp, CurrArea->m_Netname.GetData() );
|
||||
aCurrArea->m_TimeStamp, aCurrArea->m_Netname.GetData() );
|
||||
str += wxT( "This may result in splitting the area.\n" );
|
||||
str += wxT( "If the area is complex, this may take a few seconds." );
|
||||
wxMessageBox( str );
|
||||
|
@ -266,7 +293,7 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
|||
{
|
||||
std::vector<CPolyLine*>* pa = new std::vector<CPolyLine*>;
|
||||
curr_polygon->Undraw();
|
||||
int n_poly = CurrArea->m_Poly->NormalizeAreaOutlines( pa, bRetainArcs );
|
||||
int n_poly = aCurrArea->m_Poly->NormalizeAreaOutlines( pa, bRetainArcs );
|
||||
if( n_poly > 1 ) // i.e if clipping has created some polygons, we must add these new copper areas
|
||||
{
|
||||
ZONE_CONTAINER* NewArea;
|
||||
|
@ -274,7 +301,8 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
|||
{
|
||||
// create new copper area and copy poly into it
|
||||
CPolyLine* new_p = (*pa)[ip - 1];
|
||||
NewArea = AddArea( CurrArea->GetNet(), CurrArea->GetLayer(), 0, 0, 0 );
|
||||
NewArea = AddArea( aNewZonesList, aCurrArea->GetNet(), aCurrArea->GetLayer(),
|
||||
wxPoint(0, 0), CPolyLine::NO_HATCH );
|
||||
|
||||
// remove the poly that was automatically created for the new area
|
||||
// and replace it with a poly from NormalizeWithKbool
|
||||
|
@ -295,6 +323,8 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
|||
* Process an area that has been modified, by clipping its polygon against
|
||||
* itself and the polygons for any other areas on the same net.
|
||||
* This may change the number and order of copper areas in the net.
|
||||
* @param aModifiedZonesList = a PICKED_ITEMS_LIST * where to store deleted or added areas (useful in undo commands
|
||||
* can be NULL
|
||||
* @param modified_area = area to test
|
||||
* @param bMessageBoxInt == true, shows message when clipping occurs.
|
||||
* @param bMessageBoxArc == true, shows message when clipping can't be done due to arcs.
|
||||
|
@ -303,12 +333,13 @@ int BOARD::ClipAreaPolygon( ZONE_CONTAINER* CurrArea,
|
|||
* 0 if no intersecting sides
|
||||
* 1 if intersecting sides, polygon clipped
|
||||
*/
|
||||
int BOARD::AreaPolygonModified( ZONE_CONTAINER* modified_area,
|
||||
int BOARD::AreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList,
|
||||
ZONE_CONTAINER* modified_area,
|
||||
bool bMessageBoxArc,
|
||||
bool bMessageBoxInt )
|
||||
{
|
||||
// clip polygon against itself
|
||||
int test = ClipAreaPolygon( modified_area, bMessageBoxArc, bMessageBoxInt );
|
||||
int test = ClipAreaPolygon( aModifiedZonesList, modified_area, bMessageBoxArc, bMessageBoxInt );
|
||||
|
||||
if( test == -1 )
|
||||
return test;
|
||||
|
@ -321,7 +352,7 @@ int BOARD::AreaPolygonModified( ZONE_CONTAINER* modified_area,
|
|||
else
|
||||
bCheckAllAreas = TestAreaIntersections( modified_area );
|
||||
if( bCheckAllAreas )
|
||||
CombineAllAreasInNet( modified_area->GetNet(), bMessageBoxInt, true );
|
||||
CombineAllAreasInNet( aModifiedZonesList, modified_area->GetNet(), bMessageBoxInt, true );
|
||||
|
||||
if( layer >= FIRST_NO_COPPER_LAYER ) // Refill non copper zones on this layer
|
||||
{
|
||||
|
@ -343,7 +374,7 @@ int BOARD::AreaPolygonModified( ZONE_CONTAINER* modified_area,
|
|||
|
||||
// Remove zone because it is incorrect:
|
||||
else
|
||||
RemoveArea( zone );
|
||||
RemoveArea( aModifiedZonesList, zone );
|
||||
}
|
||||
|
||||
return test;
|
||||
|
@ -353,13 +384,15 @@ int BOARD::AreaPolygonModified( ZONE_CONTAINER* modified_area,
|
|||
/**
|
||||
* Function CombineAllAreasInNet
|
||||
* Checks all copper areas in net for intersections, combining them if found
|
||||
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands
|
||||
* can be NULL
|
||||
* @param aNetCode = net to consider
|
||||
* @param bMessageBox : if true display warning message box
|
||||
* @param bUseUtility : if true, don't check areas if both utility flags are 0
|
||||
* Sets utility flag = 1 for any areas modified
|
||||
* If an area has self-intersecting arcs, doesn't try to combine it
|
||||
*/
|
||||
int BOARD::CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtility )
|
||||
int BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, bool bMessageBox, bool bUseUtility )
|
||||
{
|
||||
if( m_ZoneDescriptorList.size() <= 1 )
|
||||
return 0;
|
||||
|
@ -397,7 +430,7 @@ int BOARD::CombineAllAreasInNet( int aNetCode, bool bMessageBox, bool bUseUtilit
|
|||
{
|
||||
int ret = TestAreaIntersection( curr_area, area2 );
|
||||
if( ret == 1 )
|
||||
ret = CombineAreas( curr_area, area2 );
|
||||
ret = CombineAreas( aDeletedList, curr_area, area2 );
|
||||
if( ret == 1 )
|
||||
{
|
||||
mod_ia1 = true;
|
||||
|
@ -671,13 +704,17 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_
|
|||
/**
|
||||
* Function CombineAreas
|
||||
* If possible, combine 2 copper areas
|
||||
* area_ref must be BEFORE area_to_combine in m_ZoneDescriptorList
|
||||
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo commands
|
||||
* can be NULL
|
||||
* @param area_ref = tje main area (zone)
|
||||
* @param area_to_combine = the zone that can be merged with area_ref
|
||||
* area_ref must be BEFORE area_to_combine
|
||||
* area_to_combine will be deleted, if areas are combined
|
||||
* @return : 0 if no intersection
|
||||
* 1 if intersection
|
||||
* 2 if arcs intersect
|
||||
*/
|
||||
int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine )
|
||||
int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine )
|
||||
{
|
||||
if( area_ref == area_to_combine )
|
||||
{
|
||||
|
@ -780,7 +817,7 @@ int BOARD::CombineAreas( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combi
|
|||
}
|
||||
|
||||
if( !keep_area_to_combine )
|
||||
RemoveArea( area_to_combine );
|
||||
RemoveArea( aDeletedList, area_to_combine );
|
||||
|
||||
area_ref->utility = 1;
|
||||
area_ref->m_Poly->RestoreArcs( &arc_array1 );
|
||||
|
|
|
@ -1489,14 +1489,11 @@ bool CPolyLine::TestPointInsideContour( int icont, int px, int py )
|
|||
void CPolyLine::Copy( CPolyLine* src )
|
||||
{
|
||||
Undraw();
|
||||
|
||||
// copy corners
|
||||
for( unsigned ii = 0; ii < src->corner.size(); ii++ )
|
||||
corner.push_back( src->corner[ii] );
|
||||
|
||||
// copy side styles
|
||||
for( unsigned ii = 0; ii < src->side_style.size(); ii++ )
|
||||
side_style.push_back( src->side_style[ii] );
|
||||
m_HatchStyle = src->m_HatchStyle;
|
||||
// copy corners, using vector copy
|
||||
corner = src->corner;
|
||||
// copy side styles, using vector copy
|
||||
side_style = src->side_style;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -102,6 +102,12 @@ public:
|
|||
int y;
|
||||
bool end_contour;
|
||||
int utility;
|
||||
|
||||
bool operator == (const CPolyPt& cpt2 ) const
|
||||
{ return (x == cpt2.x) && (y == cpt2.y) && (end_contour == cpt2.end_contour); }
|
||||
|
||||
bool operator != (CPolyPt& cpt2 ) const
|
||||
{ return (x != cpt2.x) || (y != cpt2.y) || (end_contour != cpt2.end_contour); }
|
||||
};
|
||||
|
||||
#include "polygon_test_point_inside.h"
|
||||
|
|
Loading…
Reference in New Issue