7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-11 09:00:13 +00:00

groups: extract common class methods into EDA_GROUP base class

This commit is contained in:
Mike Williams 2025-04-01 14:20:03 -04:00
parent 8b69ec4761
commit 05e9772d54
45 changed files with 409 additions and 293 deletions

View File

@ -363,6 +363,8 @@ set( COMMON_DLG_SRCS
dialogs/dialog_global_design_block_lib_table_config.cpp
dialogs/dialog_grid_settings.cpp
dialogs/dialog_grid_settings_base.cpp
dialogs/dialog_group_properties.cpp
dialogs/dialog_group_properties_base.cpp
dialogs/dialog_hotkey_list.cpp
dialogs/dialog_HTML_reporter_base.cpp
dialogs/dialog_import_choose_project.cpp
@ -600,6 +602,7 @@ set( COMMON_SRCS
eda_dde.cpp
eda_doc.cpp
eda_draw_frame.cpp
eda_group.cpp
eda_item.cpp
eda_shape.cpp
eda_text.cpp

View File

@ -26,6 +26,7 @@
#include <tools/pcb_picker_tool.h>
#include <pcb_base_edit_frame.h>
#include <pcb_group.h>
#include <eda_group.h>
#include <status_popup.h>
#include <board_commit.h>
#include <bitmaps.h>
@ -33,10 +34,10 @@
#include <dialogs/dialog_group_properties.h>
DIALOG_GROUP_PROPERTIES::DIALOG_GROUP_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent,
PCB_GROUP* aGroup ) :
DIALOG_GROUP_PROPERTIES::DIALOG_GROUP_PROPERTIES( EDA_DRAW_FRAME* aParent,
EDA_GROUP* aGroup ) :
DIALOG_GROUP_PROPERTIES_BASE( aParent ),
m_brdEditor( aParent ),
m_frame( aParent ),
m_toolMgr( aParent->GetToolManager() ),
m_group( aGroup )
{
@ -45,11 +46,19 @@ DIALOG_GROUP_PROPERTIES::DIALOG_GROUP_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent,
m_nameCtrl->SetValue( m_group->GetName() );
m_locked->SetValue( m_group->IsLocked() );
m_locked->Show( dynamic_cast<PCB_EDIT_FRAME*>( aParent ) != nullptr );
if( aGroup->AsEdaItem()->Type() == PCB_GROUP_T )
{
m_locked->SetValue( static_cast<PCB_GROUP*>( aGroup )->IsLocked() );
m_locked->Show( dynamic_cast<PCB_EDIT_FRAME*>( aParent ) != nullptr );
}
else
{
m_locked->SetValue( false );
m_locked->Hide();
}
for( BOARD_ITEM* item : m_group->GetItems() )
m_membersList->Append( item->GetItemDescription( m_brdEditor, true ), item );
for( EDA_ITEM* item : m_group->GetItems() )
m_membersList->Append( item->GetItemDescription( m_frame, true ), item );
SetupStandardButtons();
@ -62,11 +71,11 @@ DIALOG_GROUP_PROPERTIES::DIALOG_GROUP_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent,
DIALOG_GROUP_PROPERTIES::~DIALOG_GROUP_PROPERTIES()
{
if( m_brdEditor->IsBeingDeleted() )
if( m_frame->IsBeingDeleted() )
return;
m_brdEditor->ClearFocus();
m_brdEditor->GetCanvas()->Refresh();
m_frame->ClearFocus();
m_frame->GetCanvas()->Refresh();
}
@ -80,36 +89,40 @@ bool DIALOG_GROUP_PROPERTIES::TransferDataToWindow()
bool DIALOG_GROUP_PROPERTIES::TransferDataFromWindow()
{
BOARD_COMMIT commit( m_brdEditor );
commit.Modify( m_group );
BOARD_COMMIT commit( m_frame );
commit.Modify( m_group->AsEdaItem() );
for( size_t ii = 0; ii < m_membersList->GetCount(); ++ii )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( m_membersList->GetClientData( ii ) );
PCB_GROUP* existingGroup = item->GetParentGroup();
EDA_ITEM* item = static_cast<EDA_ITEM*>( m_membersList->GetClientData( ii ) );
EDA_GROUP* existingGroup = item->GetParentGroup();
if( existingGroup != m_group )
{
commit.Modify( item );
if( existingGroup )
commit.Modify( existingGroup );
commit.Modify( existingGroup->AsEdaItem() );
}
}
m_group->SetName( m_nameCtrl->GetValue() );
m_group->SetLocked( m_locked->GetValue() );
if( m_group->AsEdaItem()->Type() == PCB_GROUP_T )
{
static_cast<PCB_GROUP*>( m_group )->SetLocked( m_locked->GetValue() );
}
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
m_group->RemoveAll();
for( size_t ii = 0; ii < m_membersList->GetCount(); ++ii )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( m_membersList->GetClientData( ii ) );
EDA_ITEM* item = static_cast<EDA_ITEM*>( m_membersList->GetClientData( ii ) );
m_group->AddItem( item );
}
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, m_group );
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, m_group->AsEdaItem() );
commit.Push( _( "Edit Group Properties" ) );
return true;
@ -122,11 +135,11 @@ void DIALOG_GROUP_PROPERTIES::OnMemberSelected( wxCommandEvent& aEvent )
if( selected >= 0 )
{
WINDOW_THAWER thawer( m_brdEditor );
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( m_membersList->GetClientData( selected ) );
WINDOW_THAWER thawer( m_frame );
EDA_ITEM* item = static_cast<EDA_ITEM*>( m_membersList->GetClientData( selected ) );
m_brdEditor->FocusOnItem( item );
m_brdEditor->GetCanvas()->Refresh();
m_frame->FocusOnItem( item );
m_frame->GetCanvas()->Refresh();
}
aEvent.Skip();
@ -144,14 +157,14 @@ void DIALOG_GROUP_PROPERTIES::DoAddMember( EDA_ITEM* aItem )
for( size_t ii = 0; ii < m_membersList->GetCount(); ++ii )
{
if( aItem == static_cast<BOARD_ITEM*>( m_membersList->GetClientData( ii ) ) )
if( aItem == static_cast<EDA_ITEM*>( m_membersList->GetClientData( ii ) ) )
return;
}
if( aItem == m_group )
if( aItem == m_group->AsEdaItem() )
return;
m_membersList->Append( aItem->GetItemDescription( m_brdEditor, true ), aItem );
m_membersList->Append( aItem->GetItemDescription( m_frame, true ), aItem );
}
@ -162,8 +175,8 @@ void DIALOG_GROUP_PROPERTIES::OnRemoveMember( wxCommandEvent& event )
if( selected >= 0 )
m_membersList->Delete( selected );
m_brdEditor->ClearFocus();
m_brdEditor->GetCanvas()->Refresh();
m_frame->ClearFocus();
m_frame->GetCanvas()->Refresh();
}

View File

@ -26,16 +26,17 @@
#include <dialogs/dialog_group_properties_base.h>
class PCB_BASE_EDIT_FRAME;
class EDA_DRAW_FRAME;
class TOOL_MANAGER;
class PCB_GROUP;
class EDA_GROUP;
class EDA_ITEM;
class DIALOG_GROUP_PROPERTIES : public DIALOG_GROUP_PROPERTIES_BASE
{
public:
DIALOG_GROUP_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, PCB_GROUP* aTarget );
~DIALOG_GROUP_PROPERTIES();
DIALOG_GROUP_PROPERTIES( EDA_DRAW_FRAME* aParent, EDA_GROUP* aTarget );
~DIALOG_GROUP_PROPERTIES() override;
void OnMemberSelected( wxCommandEvent& event ) override;
void OnAddMember( wxCommandEvent& event ) override;
@ -47,9 +48,9 @@ private:
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
PCB_BASE_EDIT_FRAME* m_brdEditor;
TOOL_MANAGER* m_toolMgr;
PCB_GROUP* m_group;
EDA_DRAW_FRAME* m_frame;
TOOL_MANAGER* m_toolMgr;
EDA_GROUP* m_group;
};
#endif // DIALOG_GROUP_PROPERTIES_H

6
common/eda_group.cpp Normal file
View File

@ -0,0 +1,6 @@
#include <eda_group.h>
EDA_GROUP::~EDA_GROUP()
{
}

95
common/eda_group.h Normal file
View File

@ -0,0 +1,95 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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
*/
#ifndef EDA_GROUP_H
#define EDA_GROUP_H
#include <eda_item.h>
#include <lset.h>
#include <unordered_set>
namespace KIGFX
{
class VIEW;
}
/**
* A set of EDA_ITEMs (i.e., without duplicates).
*
* The group parent is always board/sheet, not logical parent group. The group is transparent
* container - e.g., its position is derived from the position of its members. A selection
* containing a group implicitly contains its members. However other operations on sets of
* items, like committing, updating the view, etc the set is explicit.
*/
class EDA_GROUP
{
public:
virtual EDA_ITEM* AsEdaItem() = 0;
virtual ~EDA_GROUP();
wxString GetName() const { return m_name; }
void SetName( const wxString& aName ) { m_name = aName; }
std::unordered_set<EDA_ITEM*>& GetItems() { return m_items; }
const std::unordered_set<EDA_ITEM*>& GetItems() const { return m_items; }
/**
* Add item to group. Does not take ownership of item.
*
* @return true if item was added (false if item belongs to a different group).
*/
virtual bool AddItem( EDA_ITEM* aItem ) = 0;
/**
* Remove item from group.
*
* @return true if item was removed (false if item was not in the group).
*/
virtual bool RemoveItem( EDA_ITEM* aItem ) = 0;
virtual void RemoveAll() = 0;
/*
* Clone() this and all descendants
*/
virtual EDA_GROUP* DeepClone() const = 0;
/*
* Duplicate() this and all descendants
*/
virtual EDA_GROUP* DeepDuplicate() const = 0;
/**
* Check if the proposed type can be added to a group
* @param aType KICAD_T type to check
* @return true if the type can belong to a group, false otherwise
*/
//virtual static bool IsGroupableType( KICAD_T aType );
protected:
std::unordered_set<EDA_ITEM*> m_items; // Members of the group
wxString m_name; // Optional group name
};
#endif // CLASS_PCB_GROUP_H_

View File

@ -40,6 +40,7 @@ EDA_ITEM::EDA_ITEM( EDA_ITEM* parent, KICAD_T idType, bool isSCH_ITEM, bool isBO
m_structType( idType ),
m_flags( 0 ),
m_parent( parent ),
m_group( nullptr ),
m_forceVisible( false ),
m_isRollover( false )
{ }
@ -50,6 +51,7 @@ EDA_ITEM::EDA_ITEM( KICAD_T idType, bool isSCH_ITEM, bool isBOARD_ITEM ) :
m_structType( idType ),
m_flags( 0 ),
m_parent( nullptr ),
m_group( nullptr ),
m_forceVisible( false ),
m_isRollover( false )
{ }
@ -61,6 +63,7 @@ EDA_ITEM::EDA_ITEM( const EDA_ITEM& base ) :
m_structType( base.m_structType ),
m_flags( base.m_flags ),
m_parent( base.m_parent ),
m_group( base.m_group ),
m_forceVisible( base.m_forceVisible ),
m_isRollover( false )
{

View File

@ -22,6 +22,7 @@
*/
#include <bitmaps.h>
#include <eda_draw_frame.h>
#include <eda_group.h>
#include <geometry/shape_compound.h>
#include <sch_item.h>
#include <sch_group.h>
@ -74,8 +75,10 @@ bool SCH_GROUP::IsGroupableType( KICAD_T aType )
}
bool SCH_GROUP::AddItem( SCH_ITEM* aItem )
bool SCH_GROUP::AddItem( EDA_ITEM* aItem )
{
wxCHECK_MSG( aItem, false, wxT( "Nullptr added to group." ) );
wxCHECK_MSG( IsGroupableType( aItem->Type() ), false,
wxT( "Invalid item type added to group: " ) + aItem->GetTypeDesc() );
@ -89,8 +92,10 @@ bool SCH_GROUP::AddItem( SCH_ITEM* aItem )
}
bool SCH_GROUP::RemoveItem( SCH_ITEM* aItem )
bool SCH_GROUP::RemoveItem( EDA_ITEM* aItem )
{
wxCHECK_MSG( aItem, false, wxT( "Nullptr removed from group." ) );
// Only clear the item's group field if it was inside this group
if( m_items.erase( aItem ) == 1 )
{
@ -104,18 +109,36 @@ bool SCH_GROUP::RemoveItem( SCH_ITEM* aItem )
void SCH_GROUP::RemoveAll()
{
for( SCH_ITEM* item : m_items )
for( EDA_ITEM* item : m_items )
item->SetParentGroup( nullptr );
m_items.clear();
}
std::unordered_set<SCH_ITEM*> SCH_GROUP::GetSchItems() const
{
std::unordered_set<SCH_ITEM*> items;
for( EDA_ITEM* item : m_items )
{
SCH_ITEM* sch_item = dynamic_cast<SCH_ITEM*>( item );
if( sch_item )
{
items.insert( sch_item );
}
}
return items;
}
/*
* @return if not in the symbol editor and aItem is in a symbol, returns the
* symbol's parent group. Otherwise, returns the aItem's parent group.
*/
SCH_GROUP* getClosestGroup( SCH_ITEM* aItem, bool isSymbolEditor )
EDA_GROUP* getClosestGroup( SCH_ITEM* aItem, bool isSymbolEditor )
{
if( !isSymbolEditor && aItem->GetParent() && aItem->GetParent()->Type() == SCH_SYMBOL_T )
return static_cast<SCH_SYMBOL*>( aItem->GetParent() )->GetParentGroup();
@ -125,26 +148,26 @@ SCH_GROUP* getClosestGroup( SCH_ITEM* aItem, bool isSymbolEditor )
/// Returns the top level group inside the aScope group, or nullptr
SCH_GROUP* getNestedGroup( SCH_ITEM* aItem, SCH_GROUP* aScope, bool isSymbolEditor )
EDA_GROUP* getNestedGroup( SCH_ITEM* aItem, EDA_GROUP* aScope, bool isSymbolEditor )
{
SCH_GROUP* group = getClosestGroup( aItem, isSymbolEditor );
EDA_GROUP* group = getClosestGroup( aItem, isSymbolEditor );
if( group == aScope )
return nullptr;
while( group && group->GetParentGroup() && group->GetParentGroup() != aScope )
while( group && group->AsEdaItem()->GetParentGroup() && group->AsEdaItem()->GetParentGroup() != aScope )
{
if( group->GetParent()->Type() == LIB_SYMBOL_T && isSymbolEditor )
if( group->AsEdaItem()->GetParent()->Type() == LIB_SYMBOL_T && isSymbolEditor )
break;
group = group->GetParentGroup();
group = group->AsEdaItem()->GetParentGroup();
}
return group;
}
SCH_GROUP* SCH_GROUP::TopLevelGroup( SCH_ITEM* aItem, SCH_GROUP* aScope, bool isSymbolEditor )
EDA_GROUP* SCH_GROUP::TopLevelGroup( SCH_ITEM* aItem, EDA_GROUP* aScope, bool isSymbolEditor )
{
return getNestedGroup( aItem, aScope, isSymbolEditor );
}
@ -152,14 +175,14 @@ SCH_GROUP* SCH_GROUP::TopLevelGroup( SCH_ITEM* aItem, SCH_GROUP* aScope, bool is
bool SCH_GROUP::WithinScope( SCH_ITEM* aItem, SCH_GROUP* aScope, bool isSymbolEditor )
{
SCH_GROUP* group = getClosestGroup( aItem, isSymbolEditor );
EDA_GROUP* group = getClosestGroup( aItem, isSymbolEditor );
if( group && group == aScope )
return true;
SCH_GROUP* nested = getNestedGroup( aItem, aScope, isSymbolEditor );
EDA_GROUP* nested = getNestedGroup( aItem, aScope, isSymbolEditor );
return nested && nested->GetParentGroup() && nested->GetParentGroup() == aScope;
return nested && nested->AsEdaItem()->GetParentGroup() && nested->AsEdaItem()->GetParentGroup() == aScope;
}
@ -191,7 +214,7 @@ SCH_GROUP* SCH_GROUP::DeepClone() const
SCH_GROUP* newGroup = new SCH_GROUP( *this );
newGroup->m_items.clear();
for( SCH_ITEM* member : m_items )
for( EDA_ITEM* member : m_items )
{
if( member->Type() == SCH_GROUP_T )
newGroup->AddItem( static_cast<SCH_GROUP*>( member )->DeepClone() );
@ -208,12 +231,12 @@ SCH_GROUP* SCH_GROUP::DeepDuplicate() const
SCH_GROUP* newGroup = static_cast<SCH_GROUP*>( Duplicate() );
newGroup->m_items.clear();
for( SCH_ITEM* member : m_items )
for( EDA_ITEM* member : m_items )
{
if( member->Type() == SCH_GROUP_T )
newGroup->AddItem( static_cast<SCH_GROUP*>( member )->DeepDuplicate() );
else
newGroup->AddItem( static_cast<SCH_ITEM*>( member->Duplicate() ) );
newGroup->AddItem( static_cast<SCH_ITEM*>( member )->Duplicate() );
}
return newGroup;
@ -246,7 +269,7 @@ const BOX2I SCH_GROUP::GetBoundingBox() const
{
BOX2I bbox;
for( SCH_ITEM* item : m_items )
for( EDA_ITEM* item : m_items )
{
if( item->Type() == SCH_SYMBOL_T || item->Type() == LIB_SYMBOL_T )
bbox.Merge( static_cast<SYMBOL*>( item )->GetBoundingBox() );
@ -293,29 +316,29 @@ double SCH_GROUP::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
void SCH_GROUP::Move( const VECTOR2I& aMoveVector )
{
for( SCH_ITEM* member : m_items )
member->Move( aMoveVector );
for( EDA_ITEM* member : m_items )
static_cast<SCH_ITEM*>( member )->Move( aMoveVector );
}
void SCH_GROUP::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
{
for( SCH_ITEM* member : m_items )
member->Rotate( aCenter, aRotateCCW );
for( EDA_ITEM* member : m_items )
static_cast<SCH_ITEM*>( member )->Rotate( aCenter, aRotateCCW );
}
void SCH_GROUP::MirrorHorizontally( int aCenter )
{
for( SCH_ITEM* item : m_items )
item->MirrorHorizontally( aCenter );
for( EDA_ITEM* item : m_items )
static_cast<SCH_ITEM*>( item )->MirrorHorizontally( aCenter );
}
void SCH_GROUP::MirrorVertically( int aCenter )
{
for( SCH_ITEM* item : m_items )
item->MirrorVertically( aCenter );
for( EDA_ITEM* item : m_items )
static_cast<SCH_ITEM*>( item )->MirrorVertically( aCenter );
}
@ -345,12 +368,12 @@ void SCH_GROUP::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction
{
try
{
for( SCH_ITEM* item : m_items )
for( EDA_ITEM* item : m_items )
{
aFunction( item );
aFunction( static_cast<SCH_ITEM*>( item ) );
if( item->Type() == SCH_GROUP_T )
item->RunOnChildren( aFunction, RECURSE_MODE::RECURSE );
static_cast<SCH_ITEM*>( item )->RunOnChildren( aFunction, RECURSE_MODE::RECURSE );
}
}
catch( std::bad_function_call& )
@ -402,11 +425,11 @@ double SCH_GROUP::Similarity( const SCH_ITEM& aOther ) const
double similarity = 0.0;
for( SCH_ITEM* item : m_items )
for( EDA_ITEM* item : m_items )
{
for( SCH_ITEM* otherItem : other.m_items )
for( EDA_ITEM* otherItem : other.m_items )
{
similarity += item->Similarity( *otherItem );
similarity += static_cast<SCH_ITEM*>( item )->Similarity( *static_cast<SCH_ITEM*>( otherItem ) );
}
}
@ -421,7 +444,9 @@ static struct SCH_GROUP_DESC
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( SCH_GROUP );
propMgr.AddTypeCast( new TYPE_CAST<SCH_GROUP, SCH_ITEM> );
propMgr.AddTypeCast( new TYPE_CAST<SCH_GROUP, EDA_GROUP> );
propMgr.InheritsAfter( TYPE_HASH( SCH_GROUP ), TYPE_HASH( SCH_ITEM ) );
propMgr.InheritsAfter( TYPE_HASH( SCH_GROUP ), TYPE_HASH( EDA_GROUP ) );
propMgr.Mask( TYPE_HASH( SCH_GROUP ), TYPE_HASH( SCH_ITEM ), _HKI( "Position X" ) );
propMgr.Mask( TYPE_HASH( SCH_GROUP ), TYPE_HASH( SCH_ITEM ), _HKI( "Position Y" ) );
@ -429,7 +454,7 @@ static struct SCH_GROUP_DESC
const wxString groupTab = _HKI( "Group Properties" );
propMgr.AddProperty(
new PROPERTY<SCH_GROUP, wxString>( _HKI( "Name" ), &SCH_GROUP::SetName, &SCH_GROUP::GetName ),
new PROPERTY<EDA_GROUP, wxString>( _HKI( "Name" ), &SCH_GROUP::SetName, &SCH_GROUP::GetName ),
groupTab );
}
} _SCH_GROUP_DESC;

View File

@ -29,6 +29,7 @@
#ifndef CLASS_SCH_GROUP_H_
#define CLASS_SCH_GROUP_H_
#include <eda_group.h>
#include <sch_commit.h>
#include <sch_item.h>
#include <lset.h>
@ -47,39 +48,36 @@ class VIEW;
* containing a group implicitly contains its members. However other operations on sets of
* items, like committing, updating the view, etc the set is explicit.
*/
class SCH_GROUP : public SCH_ITEM
class SCH_GROUP : public SCH_ITEM, public EDA_GROUP
{
public:
SCH_GROUP();
SCH_GROUP( SCH_ITEM* aParent );
EDA_ITEM* AsEdaItem() override { return this; }
static inline bool ClassOf( const EDA_ITEM* aItem ) { return aItem && SCH_GROUP_T == aItem->Type(); }
wxString GetClass() const override { return wxT( "SCH_GROUP" ); }
wxString GetName() const { return m_name; }
void SetName( const wxString& aName ) { m_name = aName; }
std::unordered_set<SCH_ITEM*>& GetItems() { return m_items; }
const std::unordered_set<SCH_ITEM*>& GetItems() const { return m_items; }
/**
* Add item to group. Does not take ownership of item.
*
* @return true if item was added (false if item belongs to a different group).
*/
virtual bool AddItem( SCH_ITEM* aItem );
bool AddItem( EDA_ITEM* aItem ) override;
/**
* Remove item from group.
*
* @return true if item was removed (false if item was not in the group).
*/
virtual bool RemoveItem( SCH_ITEM* aItem );
bool RemoveItem( EDA_ITEM* aItem ) override;
void RemoveAll();
void RemoveAll() override;
std::unordered_set<SCH_ITEM*> GetSchItems() const;
/*
* Search for highest level group inside of aScope, containing item.
@ -88,7 +86,7 @@ public:
* @param isSymbolEditor true if we should stop promoting at the symbol level
* @return group inside of aScope, containing item, if exists, otherwise, nullptr
*/
static SCH_GROUP* TopLevelGroup( SCH_ITEM* aItem, SCH_GROUP* aScope, bool isSymbolEditor );
static EDA_GROUP* TopLevelGroup( SCH_ITEM* aItem, EDA_GROUP* aScope, bool isSymbolEditor );
static bool WithinScope( SCH_ITEM* aItem, SCH_GROUP* aScope, bool isSymbolEditor );
@ -113,12 +111,12 @@ public:
/*
* Clone() this and all descendants
*/
SCH_GROUP* DeepClone() const;
SCH_GROUP* DeepClone() const override;
/*
* Duplicate() this and all descendants
*/
SCH_GROUP* DeepDuplicate() const;
SCH_GROUP* DeepDuplicate() const override;
/// @copydoc EDA_ITEM::HitTest
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
@ -172,10 +170,6 @@ public:
/// @copydoc SCH_ITEM::swapData
void swapData( SCH_ITEM* aImage ) override;
protected:
std::unordered_set<SCH_ITEM*> m_items; // Members of the group
wxString m_name; // Optional group name
};
#endif

View File

@ -78,8 +78,7 @@ SCH_ITEM::SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType, int aUnit, int aBodyStyle
EDA_ITEM( aParent, aType, true, false ),
m_unit( aUnit ),
m_bodyStyle( aBodyStyle ),
m_private( false ),
m_group( nullptr )
m_private( false )
{
m_layer = LAYER_WIRE; // It's only a default, in fact
m_fieldsAutoplaced = AUTOPLACE_NONE;
@ -95,7 +94,6 @@ SCH_ITEM::SCH_ITEM( const SCH_ITEM& aItem ) :
m_bodyStyle = aItem.m_bodyStyle;
m_private = aItem.m_private;
m_fieldsAutoplaced = aItem.m_fieldsAutoplaced;
m_group = aItem.m_group;
m_connectivity_dirty = aItem.m_connectivity_dirty;
}
@ -107,7 +105,6 @@ SCH_ITEM& SCH_ITEM::operator=( const SCH_ITEM& aItem )
m_bodyStyle = aItem.m_bodyStyle;
m_private = aItem.m_private;
m_fieldsAutoplaced = aItem.m_fieldsAutoplaced;
m_group = aItem.m_group;
m_connectivity_dirty = aItem.m_connectivity_dirty;
return *this;
@ -116,8 +113,6 @@ SCH_ITEM& SCH_ITEM::operator=( const SCH_ITEM& aItem )
SCH_ITEM::~SCH_ITEM()
{
wxASSERT( m_group == nullptr );
for( const auto& it : m_connection_map )
delete it.second;
@ -361,7 +356,7 @@ void SCH_ITEM::SwapItemData( SCH_ITEM* aImage )
return;
EDA_ITEM* parent = GetParent();
SCH_GROUP* group = GetParentGroup();
EDA_GROUP* group = GetParentGroup();
SetParentGroup( nullptr );
aImage->SetParentGroup( nullptr );

View File

@ -40,7 +40,6 @@
class CONNECTION_GRAPH;
class SCH_CONNECTION;
class SCH_GROUP;
class SCH_SHEET_PATH;
class SCHEMATIC;
class SYMBOL;
@ -175,9 +174,6 @@ public:
virtual ~SCH_ITEM();
void SetParentGroup( SCH_GROUP* aGroup ) { m_group = aGroup; }
SCH_GROUP* GetParentGroup() const { return m_group; }
wxString GetClass() const override
{
return wxT( "SCH_ITEM" );
@ -714,7 +710,6 @@ protected:
AUTOPLACE_ALGO m_fieldsAutoplaced; // indicates status of field autoplacement
VECTOR2I m_storedPos; // temp variable used in some move commands to store
// an initial position of the item or mouse cursor
SCH_GROUP* m_group; // The group this item belongs to
/// Store pointers to other items that are connected to this one, per sheet.
std::map<SCH_SHEET_PATH, SCH_ITEM_VEC, SHEET_PATH_CMP> m_connected_items;

View File

@ -81,18 +81,12 @@ public:
EDA_ITEM( aParent, idtype, false, true ),
m_layer( aLayer ),
m_isKnockout( false ),
m_isLocked( false ),
m_group( nullptr )
m_isLocked( false )
{
}
~BOARD_ITEM();
virtual void CopyFrom( const BOARD_ITEM* aOther );
void SetParentGroup( PCB_GROUP* aGroup ) { m_group = aGroup; }
PCB_GROUP* GetParentGroup() const { return m_group; }
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
int GetX() const
@ -452,8 +446,6 @@ protected:
bool m_isKnockout;
bool m_isLocked;
PCB_GROUP* m_group;
};
#ifndef SWIG

View File

@ -57,6 +57,7 @@ enum RECURSE_MODE
*/
class UNITS_PROVIDER;
class EDA_DRAW_FRAME;
class EDA_GROUP;
class MSG_PANEL_ITEM;
class EMBEDDED_FILES;
@ -94,7 +95,7 @@ typedef const INSPECTOR_FUNC& INSPECTOR;
class EDA_ITEM : public KIGFX::VIEW_ITEM, public SERIALIZABLE
{
public:
virtual ~EDA_ITEM() { };
virtual ~EDA_ITEM() { wxASSERT( m_group == nullptr ); };
/**
* Returns the type of object.
@ -109,6 +110,9 @@ public:
EDA_ITEM* GetParent() const { return m_parent; }
virtual void SetParent( EDA_ITEM* aParent ) { m_parent = aParent; }
virtual void SetParentGroup( EDA_GROUP* aGroup ) { m_group = aGroup; }
EDA_GROUP* GetParentGroup() const { return m_group; }
inline bool IsModified() const { return m_flags & IS_CHANGED; }
inline bool IsNew() const { return m_flags & IS_NEW; }
inline bool IsMoving() const { return m_flags & IS_MOVING; }
@ -504,6 +508,7 @@ private:
protected:
EDA_ITEM_FLAGS m_flags;
EDA_ITEM* m_parent; ///< Linked list: Link (parent struct).
EDA_GROUP* m_group; ///< The group this item belongs to
bool m_forceVisible;
bool m_isRollover;
};

View File

@ -97,8 +97,6 @@ set( PCBNEW_DIALOGS
dialogs/dialog_global_edit_text_and_graphics.cpp
dialogs/dialog_global_edit_text_and_graphics_base.cpp
dialogs/dialog_global_fp_lib_table_config.cpp
dialogs/dialog_group_properties.cpp
dialogs/dialog_group_properties_base.cpp
dialogs/dialog_push_pad_properties.cpp
dialogs/dialog_push_pad_properties_base.cpp
dialogs/dialog_shape_properties.cpp

View File

@ -141,13 +141,13 @@ BOARD::~BOARD()
// Untangle group parents before doing any deleting
for( PCB_GROUP* group : m_groups )
{
for( BOARD_ITEM* item : group->GetItems() )
for( EDA_ITEM* item : group->GetItems() )
item->SetParentGroup( nullptr );
}
for( PCB_GENERATOR* generator : m_generators )
{
for( BOARD_ITEM* item : generator->GetItems() )
for( EDA_ITEM* item : generator->GetItems() )
item->SetParentGroup( nullptr );
}
@ -1311,9 +1311,9 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
aBoardItem->SetFlags( STRUCT_DELETED );
PCB_GROUP* parentGroup = aBoardItem->GetParentGroup();
EDA_GROUP* parentGroup = aBoardItem->GetParentGroup();
if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
if( parentGroup && !( parentGroup->AsEdaItem()->GetFlags() & STRUCT_DELETED ) )
parentGroup->RemoveItem( aBoardItem );
m_connectivity->Remove( aBoardItem );
@ -2818,11 +2818,11 @@ wxString BOARD::GroupsSanityCheckInternal( bool repair )
// There may be extra time taken due to the container access calls and iterators.
//
// Groups we know are cycle free
std::unordered_set<PCB_GROUP*> knownCycleFreeGroups;
std::unordered_set<EDA_GROUP*> knownCycleFreeGroups;
// Groups in the current chain we're exploring.
std::unordered_set<PCB_GROUP*> currentChainGroups;
std::unordered_set<EDA_GROUP*> currentChainGroups;
// Groups we haven't checked yet.
std::unordered_set<PCB_GROUP*> toCheckGroups;
std::unordered_set<EDA_GROUP*> toCheckGroups;
// Initialize set of groups and generators to check that could participate in a cycle.
for( PCB_GROUP* group : Groups() )
@ -2834,14 +2834,14 @@ wxString BOARD::GroupsSanityCheckInternal( bool repair )
while( !toCheckGroups.empty() )
{
currentChainGroups.clear();
PCB_GROUP* group = *toCheckGroups.begin();
EDA_GROUP* group = *toCheckGroups.begin();
while( true )
{
if( currentChainGroups.find( group ) != currentChainGroups.end() )
{
if( repair )
Remove( group );
Remove( static_cast<BOARD_ITEM*>( group->AsEdaItem() ) );
return "Cycle detected in group membership";
}
@ -2855,7 +2855,7 @@ wxString BOARD::GroupsSanityCheckInternal( bool repair )
// We haven't visited currIdx yet, so it must be in toCheckGroups
toCheckGroups.erase( group );
group = group->GetParentGroup();
group = group->AsEdaItem()->GetParentGroup();
if( !group )
{

View File

@ -387,7 +387,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
case CHT_REMOVE:
{
FOOTPRINT* parentFP = boardItem->GetParentFootprint();
PCB_GROUP* parentGroup = boardItem->GetParentGroup();
EDA_GROUP* parentGroup = boardItem->GetParentGroup();
if( !( aCommitFlags & SKIP_UNDO ) )
undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::DELETED ) );
@ -400,7 +400,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
itemsDeselected = true;
}
if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
if( parentGroup && !( parentGroup->AsEdaItem()->GetFlags() & STRUCT_DELETED ) )
parentGroup->RemoveItem( boardItem );
if( parentFP && !( parentFP->GetFlags() & STRUCT_DELETED ) )
@ -471,12 +471,12 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
}
case CHT_UNGROUP:
if( PCB_GROUP* group = boardItem->GetParentGroup() )
if( EDA_GROUP* group = boardItem->GetParentGroup() )
{
if( !( aCommitFlags & SKIP_UNDO ) )
{
ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::UNGROUP );
itemWrapper.SetGroupId( group->m_Uuid );
itemWrapper.SetGroupId( group->AsEdaItem()->m_Uuid );
undoList.PushItem( itemWrapper );
}
@ -751,9 +751,9 @@ void BOARD_COMMIT::Revert()
case CHT_ADD:
// Items are auto-added to the parent group by BOARD_ITEM::Duplicate(), not when
// the commit is pushed.
if( PCB_GROUP* parentGroup = boardItem->GetParentGroup() )
if( EDA_GROUP* parentGroup = boardItem->GetParentGroup() )
{
if( GetStatus( parentGroup ) == 0 )
if( GetStatus( parentGroup->AsEdaItem() ) == 0 )
parentGroup->RemoveItem( boardItem );
}

View File

@ -38,12 +38,6 @@
#include <font/font.h>
BOARD_ITEM::~BOARD_ITEM()
{
wxASSERT( m_group == nullptr );
}
void BOARD_ITEM::CopyFrom( const BOARD_ITEM* aOther )
{
wxCHECK( aOther, /* void */ );
@ -81,7 +75,7 @@ BOARD* BOARD_ITEM::GetBoard()
bool BOARD_ITEM::IsLocked() const
{
if( GetParentGroup() && GetParentGroup()->IsLocked() )
if( GetParentGroup() && static_cast<PCB_GROUP*>( GetParentGroup() )->IsLocked() )
return true;
const BOARD* board = GetBoard();
@ -235,7 +229,7 @@ void BOARD_ITEM::SwapItemData( BOARD_ITEM* aImage )
return;
EDA_ITEM* parent = GetParent();
PCB_GROUP* group = GetParentGroup();
EDA_GROUP* group = GetParentGroup();
SetParentGroup( nullptr );
aImage->SetParentGroup( nullptr );

View File

@ -214,10 +214,10 @@ void DIALOG_CLEANUP_TRACKS_AND_VIAS::doCleanup( bool aDryRun )
{
if( !aItem->IsSelected() )
{
PCB_GROUP* group = aItem->GetParentGroup();
EDA_GROUP* group = aItem->GetParentGroup();
while( group && !group->IsSelected() )
group = group->GetParentGroup();
while( group && !group->AsEdaItem()->IsSelected() )
group = group->AsEdaItem()->GetParentGroup();
if( !group )
return true;

View File

@ -387,10 +387,10 @@ void DIALOG_GLOBAL_EDIT_TEARDROPS::visitItem( BOARD_COMMIT* aCommit,
{
if( !aItem->IsSelected() )
{
PCB_GROUP* group = aItem->GetParentGroup();
EDA_GROUP* group = aItem->GetParentGroup();
while( group && !group->IsSelected() )
group = group->GetParentGroup();
while( group && !group->AsEdaItem()->IsSelected() )
group = group->AsEdaItem()->GetParentGroup();
if( !group )
return;

View File

@ -480,7 +480,7 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( BOARD_COMMIT& aCommit, BOA
{
if( m_selectedItemsFilter->GetValue() )
{
BOARD_ITEM* candidate = aItem;
EDA_ITEM* candidate = aItem;
if( !candidate->IsSelected() )
{
@ -490,10 +490,10 @@ void DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::visitItem( BOARD_COMMIT& aCommit, BOA
if( !candidate->IsSelected() )
{
candidate = candidate->GetParentGroup();
candidate = ( candidate->GetParentGroup() ? candidate->GetParentGroup()->AsEdaItem() : nullptr );
while( candidate && !candidate->IsSelected() )
candidate = candidate->GetParentGroup();
candidate = candidate->GetParentGroup()->AsEdaItem();
if( !candidate )
return;

View File

@ -352,10 +352,10 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::visitItem( PICKED_ITEMS_LIST* aUndoList
{
if( !aItem->IsSelected() )
{
PCB_GROUP* group = aItem->GetParentGroup();
EDA_GROUP* group = aItem->GetParentGroup();
while( group && !group->IsSelected() )
group = group->GetParentGroup();
while( group && !group->AsEdaItem()->IsSelected() )
group = group->AsEdaItem()->GetParentGroup();
if( !group )
return;

View File

@ -136,7 +136,7 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
std::ranges::copy( aFootprint.m_jumperPadGroups,
std::inserter( m_jumperPadGroups, m_jumperPadGroups.end() ) );
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
// Copy fields
for( PCB_FIELD* field : aFootprint.m_fields )
@ -201,7 +201,7 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
newGroup->GetItems().clear();
for( BOARD_ITEM* member : group->GetItems() )
for( EDA_ITEM* member : group->GetItems() )
{
if( ptrMap.count( member ) )
newGroup->AddItem( ptrMap[ member ] );
@ -236,7 +236,7 @@ FOOTPRINT::~FOOTPRINT()
// Untangle group parents before doing any deleting
for( PCB_GROUP* group : m_groups )
{
for( BOARD_ITEM* item : group->GetItems() )
for( EDA_ITEM* item : group->GetItems() )
item->SetParentGroup( nullptr );
}
@ -871,7 +871,7 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
m_zoneConnection = aOther.m_zoneConnection;
m_netTiePadGroups = aOther.m_netTiePadGroups;
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
std::map<EDA_ITEM*, EDA_ITEM*> ptrMap;
// Copy fields
m_fields.clear();
@ -927,7 +927,7 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
PCB_GROUP* newGroup = static_cast<PCB_GROUP*>( group->Clone() );
newGroup->GetItems().clear();
for( BOARD_ITEM* member : group->GetItems() )
for( EDA_ITEM* member : group->GetItems() )
newGroup->AddItem( ptrMap[ member ] );
Add( newGroup );
@ -1211,9 +1211,9 @@ void FOOTPRINT::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aMode )
aBoardItem->SetFlags( STRUCT_DELETED );
PCB_GROUP* parentGroup = aBoardItem->GetParentGroup();
EDA_GROUP* parentGroup = aBoardItem->GetParentGroup();
if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
if( parentGroup && !( parentGroup->AsEdaItem()->GetFlags() & STRUCT_DELETED ) )
parentGroup->RemoveItem( aBoardItem );
}
@ -2808,7 +2808,7 @@ double FOOTPRINT::GetCoverageArea( const BOARD_ITEM* aItem, const GENERAL_COLLEC
{
double combinedArea = 0.0;
for( BOARD_ITEM* member : static_cast<const PCB_GROUP*>( aItem )->GetItems() )
for( BOARD_ITEM* member : static_cast<const PCB_GROUP*>( aItem )->GetBoardItems() )
combinedArea += GetCoverageArea( member, aCollector );
return combinedArea;

View File

@ -602,7 +602,7 @@ void PCB_EDIT_FRAME::ExportFootprintsToLibrary( bool aStoreInNewLib, const wxStr
auto resetGroup =
[]( FOOTPRINT* aFootprint )
{
if( PCB_GROUP* parentGroup = aFootprint->GetParentGroup() )
if( EDA_GROUP* parentGroup = aFootprint->GetParentGroup() )
parentGroup->RemoveItem( aFootprint );
};

View File

@ -1137,7 +1137,7 @@ void PCB_TUNING_PATTERN::Remove( GENERATOR_TOOL* aTool, BOARD* aBoard, BOARD_COM
{
PCB_GENERATOR* group = this;
for( BOARD_ITEM* member : group->GetItems() )
for( EDA_ITEM* member : group->GetItems() )
aCommit->Stage( member, CHT_UNGROUP );
group->GetItems().clear();
@ -2004,7 +2004,7 @@ void PCB_TUNING_PATTERN::ShowPropertiesDialog( PCB_BASE_EDIT_FRAME* aEditFrame )
if( !m_items.empty() )
{
BOARD_ITEM* startItem = *m_items.begin();
BOARD_ITEM* startItem = static_cast<BOARD_ITEM*>( *m_items.begin() );
std::shared_ptr<DRC_ENGINE>& drcEngine = GetBoard()->GetDesignSettings().m_DRCEngine;
constraint = drcEngine->EvalRules( LENGTH_CONSTRAINT, startItem, nullptr, GetLayer() );
@ -2094,7 +2094,7 @@ void PCB_TUNING_PATTERN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame,
aList.emplace_back( _( "Type" ), GetFriendlyName() );
for( BOARD_ITEM* member : GetItems() )
for( EDA_ITEM* member : GetItems() )
{
if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( member ) )
{
@ -2539,7 +2539,7 @@ int DRAWING_TOOL::PlaceTuningPattern( const TOOL_EVENT& aEvent )
{
if( !m_tuningPattern->GetItems().empty() )
{
BOARD_ITEM* startItem = *m_tuningPattern->GetItems().begin();
BOARD_ITEM* startItem = *m_tuningPattern->GetBoardItems().begin();
constraint = drcEngine->EvalRules( LENGTH_CONSTRAINT, startItem, nullptr,
startItem->GetLayer() );

View File

@ -2170,7 +2170,7 @@ std::vector<PCB_SHAPE*> PAD::Recombine( bool aIsDryRun, int maxError )
// If the editor was inside a group when the pad was exploded, the added exploded shapes
// will be part of the group. Remove them here before duplicating; we don't want the
// primitives to wind up in a group.
if( PCB_GROUP* group = fpShape->GetParentGroup(); group )
if( EDA_GROUP* group = fpShape->GetParentGroup(); group )
group->RemoveItem( fpShape );
PCB_SHAPE* primitive = static_cast<PCB_SHAPE*>( fpShape->Duplicate() );

View File

@ -2419,7 +2419,7 @@ void PCB_EDIT_FRAME::ExchangeFootprint( FOOTPRINT* aExisting, FOOTPRINT* aNew,
bool resetTextContent, bool resetFabricationAttrs,
bool reset3DModels, bool* aUpdated )
{
PCB_GROUP* parentGroup = aExisting->GetParentGroup();
EDA_GROUP* parentGroup = aExisting->GetParentGroup();
bool dummyBool = false;
if( !aUpdated )

Some files were not shown because too many files have changed in this diff Show More