24 changed files with 809 additions and 286 deletions
-
5CHANGELOG.txt
-
3include/wxPcbStruct.h
-
2pcbnew/CMakeLists.txt
-
3pcbnew/board_undo_redo.cpp
-
9pcbnew/class_board.cpp
-
59pcbnew/class_board.h
-
8pcbnew/class_zone.cpp
-
9pcbnew/class_zone.h
-
21pcbnew/dialog_copper_zones.cpp
-
29pcbnew/dialog_copper_zones.h
-
28pcbnew/dialog_pad_properties.cpp
-
4pcbnew/dialog_pad_properties_base.cpp
-
4pcbnew/dialog_pad_properties_base.fbp
-
2pcbnew/dialog_pad_properties_base.h
-
5pcbnew/edit.cpp
-
6pcbnew/zones.h
-
264pcbnew/zones_by_polygon.cpp
-
175pcbnew/zones_by_polygon_fill_functions.cpp
-
10pcbnew/zones_convert_brd_items_to_polygons.cpp
-
258pcbnew/zones_functions_for_undo_redo.cpp
-
69pcbnew/zones_functions_for_undo_redo.h
-
103pcbnew/zones_test_and_combine_areas.cpp
-
13polygon/PolyLine.cpp
-
6polygon/PolyLine.h
@ -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; |
|||
} |
|||
|
|||
|
@ -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 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue