kicad/eeschema/sch_item.h

481 lines
16 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2004-2020 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
*/
#ifndef SCH_ITEM_H
#define SCH_ITEM_H
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <base_struct.h>
#include <general.h>
#include <sch_sheet_path.h>
class SCH_CONNECTION;
class SCH_SHEET_PATH;
class LINE_READER;
class SCH_EDIT_FRAME;
class wxFindReplaceData;
class PLOTTER;
class NETLIST_OBJECT;
class NETLIST_OBJECT_LIST;
enum FIELDS_AUTOPLACED
{
FIELDS_AUTOPLACED_NO = 0,
FIELDS_AUTOPLACED_AUTO,
FIELDS_AUTOPLACED_MANUAL
};
enum DANGLING_END_T
{
UNKNOWN = 0,
WIRE_START_END,
WIRE_END_END,
BUS_START_END,
BUS_END_END,
JUNCTION_END,
PIN_END,
LABEL_END,
BUS_ENTRY_END,
WIRE_ENTRY_END,
SHEET_LABEL_END,
NO_CONNECT_END,
};
/**
* DANGLING_END_ITEM
* is a helper class used to store the state of schematic items that can be connected to
* other schematic items.
*/
class DANGLING_END_ITEM
{
private:
/// A pointer to the connectable object.
EDA_ITEM* m_item;
/// The position of the connection point.
wxPoint m_pos;
/// The type of connection of #m_item.
DANGLING_END_T m_type;
/// A pointer to the parent object (in the case of pins)
const EDA_ITEM* m_parent;
public:
DANGLING_END_ITEM( DANGLING_END_T aType, EDA_ITEM* aItem, const wxPoint& aPosition )
{
m_item = aItem;
m_type = aType;
m_pos = aPosition;
m_parent = aItem;
}
DANGLING_END_ITEM( DANGLING_END_T aType, EDA_ITEM* aItem,
const wxPoint& aPosition, const EDA_ITEM* aParent )
{
m_item = aItem;
m_type = aType;
m_pos = aPosition;
m_parent = aParent;
}
bool operator==( const DANGLING_END_ITEM& aB )
{
return GetItem() == aB.GetItem()
&& GetPosition() == aB.GetPosition()
&& GetType() == aB.GetType()
&& GetParent() == aB.GetParent();
}
bool operator!=( const DANGLING_END_ITEM& aB )
{
return GetItem() != aB.GetItem()
|| GetPosition() != aB.GetPosition()
|| GetType() != aB.GetType()
|| GetParent() != aB.GetParent();;
}
bool operator<( const DANGLING_END_ITEM& rhs ) const
{
return( m_pos.x < rhs.m_pos.x || ( m_pos.x == rhs.m_pos.x && m_pos.y < rhs.m_pos.y )
|| ( m_pos == rhs.m_pos && m_item < rhs.m_item ) );
}
wxPoint GetPosition() const { return m_pos; }
EDA_ITEM* GetItem() const { return m_item; }
const EDA_ITEM* GetParent() const { return m_parent; }
DANGLING_END_T GetType() const { return m_type; }
};
typedef std::unordered_set<SCH_ITEM*> ITEM_SET;
/**
* SCH_ITEM
* is a base class for any item which can be embedded within the SCHEMATIC
* container class, and therefore instances of derived classes should only be
* found in EESCHEMA or other programs that use class SCHEMATIC and its contents.
* The corresponding class in Pcbnew is BOARD_ITEM.
*/
class SCH_ITEM : public EDA_ITEM
{
friend class CONNECTION_GRAPH;
protected:
SCH_LAYER_ID m_Layer;
EDA_ITEMS m_connections; // List of items connected to this item.
FIELDS_AUTOPLACED m_fieldsAutoplaced; // indicates status of field autoplacement
wxPoint m_storedPos; // a temporary variable used in some move commands
// to store a initial pos of the item or mouse cursor
/// Stores pointers to other items that are connected to this one, per sheet
std::unordered_map<SCH_SHEET_PATH, ITEM_SET> m_connected_items;
/// Stores connectivity information, per sheet
std::unordered_map<SCH_SHEET_PATH, SCH_CONNECTION*> m_connection_map;
/// True if connectivity info might be out of date
bool m_connectivity_dirty;
public:
SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType );
SCH_ITEM( const SCH_ITEM& aItem );
~SCH_ITEM();
virtual wxString GetClass() const override
{
return wxT( "SCH_ITEM" );
}
/**
* Function SwapData
* swap the internal data structures \a aItem with the schematic item.
* Obviously, aItem must have the same type than me
* @param aItem The item to swap the data structures with.
*/
virtual void SwapData( SCH_ITEM* aItem );
/**
* Routine to create a new copy of given item.
* The new object is not put in draw list (not linked).
*
* @param doClone (default = false) indicates unique values (such as timestamp and
* sheet name) should be duplicated. Use only for undo/redo operations.
*/
SCH_ITEM* Duplicate( bool doClone = false ) const;
/**
* Virtual function IsMovableFromAnchorPoint
* @return true for items which are moved with the anchor point at mouse cursor
* and false for items moved with no reference to anchor
* Usually return true for small items (labels, junctions) and false for
* items which can be large (hierarchical sheets, compoments)
*/
virtual bool IsMovableFromAnchorPoint() { return true; }
wxPoint& GetStoredPos() { return m_storedPos; }
void SetStoredPos( wxPoint aPos ) { m_storedPos = aPos; }
/**
* Function IsLocked
* @return bool - true if the object is locked, else false
*/
virtual bool IsLocked() const { return false; }
/**
* Function SetLocked
* modifies 'lock' status for of the item.
*/
virtual void SetLocked( bool aLocked ) {}
/**
* Function GetLayer
* returns the layer this item is on.
*/
SCH_LAYER_ID GetLayer() const { return m_Layer; }
/**
* Function SetLayer
* sets the layer this item is on.
* @param aLayer The layer number.
*/
void SetLayer( SCH_LAYER_ID aLayer ) { m_Layer = aLayer; }
/**
* Function ViewGetLayers
* returns the layers the item is drawn on (which may be more than its "home" layer)
*/
void ViewGetLayers( int aLayers[], int& aCount ) const override;
/**
* Function GetPenSize virtual pure
* @return the size of the "pen" that be used to draw or plot this item
*/
virtual int GetPenSize() const { return 0; }
/**
* Function Print
* Print a schematic item. Each schematic item should have its own method
* @param aDC Device Context (can be null)
* @param aOffset drawing Offset (usually wxPoint(0,0),
* but can be different when moving an object)
*/
virtual void Print( wxDC* aDC, const wxPoint& aOffset ) = 0;
/**
* Function Move
* moves the item by \a aMoveVector to a new position.
* @param aMoveVector = the displacement vector
*/
virtual void Move( const wxPoint& aMoveVector ) = 0;
/**
* Function MirrorY
* mirrors item relative to the Y axis about \a aYaxis_position.
* @param aYaxis_position The Y axis position to mirror around.
*/
virtual void MirrorY( int aYaxis_position ) = 0;
/**
* Function MirrorX
* mirrors item relative to the X axis about \a aXaxis_position.
* @param aXaxis_position The X axis position to mirror around.
*/
virtual void MirrorX( int aXaxis_position ) = 0;
/**
* Function Rotate
* rotates the item around \a aPosition 90 degrees in the clockwise direction.
* @param aPosition A reference to a wxPoint object containing the coordinates to
* rotate around.
*/
virtual void Rotate( wxPoint aPosition ) = 0;
/**
* Function Load
* reads a schematic item from \a aLine in a .sch file.
*
* @param aLine - Essentially this is file to read the object from.
* @param aErrorMsg - Description of the error if an error occurs while loading the object.
* @return True if the object loaded successfully.
*/
virtual bool Load( LINE_READER& aLine, wxString& aErrorMsg ) { return false; }
/**
* Function GetEndPoints
* adds the schematic item end points to \a aItemList if the item has end points.
*
* The default version doesn't do anything since many of the schematic object cannot
* be tested for dangling ends. If you add a new schematic item that can have a
* dangling end ( no connect ), override this method to provide the correct end
* points.
*
* @param aItemList - List of DANGLING_END_ITEMS to add to.
*/
virtual void GetEndPoints( std::vector< DANGLING_END_ITEM >& aItemList ) {}
/**
* Function IsDanglingStateChanged
* tests the schematic item to \a aItemList to check if it's dangling state has changed.
*
* Note that the return value only true when the state of the test has changed. Use
* the IsDangling() method to get the current dangling state of the item. Some of
* the schematic objects cannot be tested for a dangling state, the default method
* always returns false. Only override the method if the item can be tested for a
* dangling state.
*
* If aSheet is passed a non-null pointer to a SCH_SHEET_PATH, the overrided method can
* optionally use it to update sheet-local connectivity information
*
* @param aItemList - List of items to test item against.
* @param aSheet - Sheet path to update connections for
* @return True if the dangling state has changed from it's current setting.
*/
virtual bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
const SCH_SHEET_PATH* aPath = nullptr )
{
return false;
}
virtual bool IsDangling() const { return false; }
virtual bool CanConnect( const SCH_ITEM* aItem ) const { return m_Layer == aItem->GetLayer(); }
/**
* Function IsConnectable
* returns true if the schematic item can connect to another schematic item.
*/
virtual bool IsConnectable() const { return false; }
/**
* Function GetConnectionPoints
* add all the connection points for this item to \a aPoints.
*
* Not all schematic items have connection points so the default method does nothing.
*
* @param aPoints List of connection points to add to.
*/
virtual void GetConnectionPoints( std::vector< wxPoint >& aPoints ) const { }
/**
* Function ClearConnections
* clears all of the connection items from the list.
*
* The vector release method is used to prevent the item pointers from being deleted.
* Do not use the vector erase method on the connection list.
*/
void ClearConnections() { m_connections.clear(); }
/**
* Function IsConnected
* tests the item to see if it is connected to \a aPoint.
*
* @param aPoint A reference to a wxPoint object containing the coordinates to test.
* @return True if connection to \a aPoint exists.
*/
bool IsConnected( const wxPoint& aPoint ) const;
/**
* Retrieves the connection associated with this object in the given sheet
* Note: the returned value can be nullptr.
*/
SCH_CONNECTION* Connection( const SCH_SHEET_PATH& aPath ) const;
/**
* Retrieves the set of items connected to this item on the given sheet
*/
ITEM_SET& ConnectedItems( const SCH_SHEET_PATH& aPath );
/**
* Adds a connection link between this item and another
*/
void AddConnectionTo( const SCH_SHEET_PATH& aPath, SCH_ITEM* aItem );
/**
* Creates a new connection object associated with this object
*
* @param aPath is the sheet path to initialize
*/
SCH_CONNECTION* InitializeConnection( const SCH_SHEET_PATH& aPath );
/**
* Returns true if this item should propagate connection info to aItem
*/
virtual bool ConnectionPropagatesTo( const EDA_ITEM* aItem ) const { return true; }
bool IsConnectivityDirty() { return m_connectivity_dirty; }
void SetConnectivityDirty( bool aDirty = true ) { m_connectivity_dirty = aDirty; }
/**
* Return whether the fields have been automatically placed.
*/
FIELDS_AUTOPLACED GetFieldsAutoplaced() const { return m_fieldsAutoplaced; }
/**
* Set fields automatically placed flag false.
*/
void ClearFieldsAutoplaced() { m_fieldsAutoplaced = FIELDS_AUTOPLACED_NO; }
/**
* Autoplace fields only if correct to do so automatically.
*
* Fields that have been moved by hand are not automatically placed.
*
* @param aScreen is the SCH_SCREEN associated with the current instance of the
* component.
*/
void AutoAutoplaceFields( SCH_SCREEN* aScreen )
{
if( GetFieldsAutoplaced() )
AutoplaceFields( aScreen, GetFieldsAutoplaced() == FIELDS_AUTOPLACED_MANUAL );
}
virtual void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) { }
/**
* Function Plot
* plots the schematic item to \a aPlotter.
*
* @param aPlotter A pointer to a #PLOTTER object.
*/
virtual void Plot( PLOTTER* aPlotter );
/**
* Function GetNetListItem
* creates a new #NETLIST_OBJECT for the schematic object and adds it to
* \a aNetListItems.
* <p>
* Not all schematic objects have net list items associated with them. This
* method only needs to be overridden for those schematic objects that have
* net list objects associated with them.
* </p>
*/
virtual void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath ) { }
/**
* Function GetPosition
* @return A wxPoint object containing the schematic item position.
*/
virtual wxPoint GetPosition() const = 0;
/**
* Function SetPosition
* set the schematic item position to \a aPosition.
*
* @param aPosition A reference to a wxPoint object containing the new position.
*/
virtual void SetPosition( const wxPoint& aPosition ) = 0;
virtual bool operator <( const SCH_ITEM& aItem ) const;
private:
/**
* Function doIsConnected
* provides the object specific test to see if it is connected to \a aPosition.
*
* @note Override this function if the derived object can be connect to another
* object such as a wire, bus, or junction. Do not override this function
* for objects that cannot have connections. The default will always return
* false. This functions is call through the public function IsConnected()
* which performs tests common to all schematic items before calling the
* item specific connection testing.
*
* @param aPosition A reference to a wxPoint object containing the test position.
* @return True if connection to \a aPosition exists.
*/
virtual bool doIsConnected( const wxPoint& aPosition ) const { return false; }
};
#endif /* SCH_ITEM_H */