From 9e609acae39913cd078dd237284f46fb03db8998 Mon Sep 17 00:00:00 2001 From: Tomasz Wlostowski Date: Fri, 29 Jan 2016 11:21:13 +0100 Subject: [PATCH] made netlist entries and netlist update undoable --- include/core/typeinfo.h | 1 + include/wxPcbStruct.h | 30 +++++++++++++-------- pcbnew/board_undo_redo.cpp | 50 ++++++++++++++++++++++++++--------- pcbnew/class_board.cpp | 9 +++++++ pcbnew/class_board.h | 5 ++++ pcbnew/class_netinfo.h | 44 +++++++++++++++++++++++++++--- pcbnew/class_netinfo_item.cpp | 3 ++- pcbnew/netlist.cpp | 4 +-- pcbnew/pcbframe.cpp | 1 + 9 files changed, 118 insertions(+), 29 deletions(-) diff --git a/include/core/typeinfo.h b/include/core/typeinfo.h index 8c89e4c75b..b6f1ce626c 100644 --- a/include/core/typeinfo.h +++ b/include/core/typeinfo.h @@ -60,6 +60,7 @@ enum KICAD_T PCB_TARGET_T, ///< class PCB_TARGET, a target (graphic item) PCB_ZONE_AREA_T, ///< class ZONE_CONTAINER, a zone area PCB_ITEM_LIST_T, ///< class BOARD_ITEM_LIST, a list of board items + PCB_NETINFO_T, ///< class NETINFO_ITEM, a description of a net // Schematic draw Items. The order of these items effects the sort order. // It is currently ordered to mimic the old Eeschema locate behavior where diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 1cb2d7a1ca..c13fc2e714 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -89,19 +89,10 @@ class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME /// The auxiliary right vertical tool bar used to access the microwave tools. wxAuiToolBar* m_microWaveToolBar; - /** - * Function loadFootprints - * loads the footprints for each #COMPONENT in \a aNetlist from the list of libraries. - * - * @param aNetlist is the netlist of components to load the footprints into. - * @param aReporter is the #REPORTER object to report to. - * @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error - * occurs while reading footprint library files. - */ - void loadFootprints( NETLIST& aNetlist, REPORTER* aReporter ) - throw( IO_ERROR, PARSE_ERROR ); protected: + bool m_undoDisabled; + PCB_LAYER_WIDGET* m_Layers; DRC* m_drc; ///< the DRC controller, see drc.cpp @@ -225,6 +216,23 @@ public: virtual ~PCB_EDIT_FRAME(); + /** + * Function loadFootprints + * loads the footprints for each #COMPONENT in \a aNetlist from the list of libraries. + * + * @param aNetlist is the netlist of components to load the footprints into. + * @param aReporter is the #REPORTER object to report to. + * @throw IO_ERROR if an I/O error occurs or a #PARSE_ERROR if a file parsing error + * occurs while reading footprint library files. + */ + void LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter ) + throw( IO_ERROR, PARSE_ERROR ); + + void DisableUndo( bool aDisable = true ) + { + m_undoDisabled = aDisable; + } + void OnQuit( wxCommandEvent& event ); /** diff --git a/pcbnew/board_undo_redo.cpp b/pcbnew/board_undo_redo.cpp index 48bf7eb84e..6cfa415ba0 100644 --- a/pcbnew/board_undo_redo.cpp +++ b/pcbnew/board_undo_redo.cpp @@ -145,6 +145,10 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem ) for( item = aPcb->m_Zone; item != NULL; item = item->Next() ) icnt++; + NETINFO_LIST& netInfo = aPcb->GetNetInfo(); + + icnt += netInfo.GetNetCount(); + // Build candidate list: itemsList.clear(); itemsList.reserve(icnt); @@ -170,6 +174,9 @@ static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem ) for( item = aPcb->m_Zone; item != NULL; item = item->Next() ) itemsList.push_back( item ); + for( NETINFO_LIST::iterator i = netInfo.begin(); i != netInfo.end(); ++i ) + itemsList.push_back( *i ); + // Sort list std::sort( itemsList.begin(), itemsList.end() ); return false; @@ -310,12 +317,11 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem, if( aItem->Type() == PCB_MODULE_TEXT_T ) { aItem = aItem->GetParent(); + wxASSERT( aItem->Type() == PCB_MODULE_T ); + aCommandType = UR_CHANGED; if( aItem == NULL ) return; - - wxASSERT( aItem->Type() == PCB_MODULE_T ); - aCommandType = UR_CHANGED; } PICKED_ITEMS_LIST* commandToUndo = new PICKED_ITEMS_LIST(); @@ -380,27 +386,48 @@ void PCB_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, commandToUndo->m_TransformPoint = aTransformPoint; - // Copy picker list: - commandToUndo->CopyList( aItemsList ); + // First, filter unnecessary stuff from the list (i.e. for multiple pads / labels modified), + // take the first occurence of the module. - // Verify list, and creates data if needed - for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ ) + for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ ) { - BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii ); + BOARD_ITEM* item = (BOARD_ITEM*) aItemsList.GetPickedItem( ii ); + UNDO_REDO_T status = aItemsList.GetPickedItemStatus( ii ); // For texts belonging to modules, we need to save state of the parent module if( item->Type() == PCB_MODULE_TEXT_T || item->Type() == PCB_PAD_T ) { item = item->GetParent(); + wxASSERT( item->Type() == PCB_MODULE_T ); if( item == NULL ) continue; - wxASSERT( item->Type() == PCB_MODULE_T ); + bool found = false; - commandToUndo->SetPickedItem( item, ii ); - commandToUndo->SetPickedItemStatus( UR_CHANGED, ii ); + for( int j = 0; j < commandToUndo->GetCount(); j++ ) + { + if( commandToUndo->GetPickedItem( j ) == item && commandToUndo->GetPickedItemStatus( j ) == UR_CHANGED ) + { + found = true; + break; + } + } + + if( !found ) + commandToUndo->PushItem( ITEM_PICKER(item, UR_CHANGED ) ); + else + continue; + + } else { + commandToUndo->PushItem( ITEM_PICKER( item, status ) ); } + } + + for( unsigned ii = 0; ii < commandToUndo->GetCount(); ii++ ) + { + BOARD_ITEM* item = (BOARD_ITEM*) commandToUndo->GetPickedItem( ii ); + UNDO_REDO_T status = commandToUndo->GetPickedItemStatus( ii ); UNDO_REDO_T command = commandToUndo->GetPickedItemStatus( ii ); @@ -649,7 +676,6 @@ void PCB_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent ) /* Get the old list */ PICKED_ITEMS_LIST* List = GetScreen()->PopCommandFromUndoList(); - /* Undo the command */ PutDataInPreviousState( List, false ); diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index bfca85d1a8..a0563821d1 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -737,6 +737,10 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl ) aBoardItem->SetParent( this ); break; + case PCB_NETINFO_T: + m_NetInfo.AppendNet( (NETINFO_ITEM *) aBoardItem ); + break; + // other types may use linked list default: { @@ -807,6 +811,11 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) m_Drawings.Remove( aBoardItem ); break; + case PCB_NETINFO_T: + printf( "Unimpl! remove netinfo!\n" ); + assert( false ); + break; + // other types may use linked list default: wxFAIL_MSG( wxT( "BOARD::Remove() needs more ::Type() support" ) ); diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index bd9a78dab4..ba5241f7ed 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -821,6 +821,11 @@ public: m_NetInfo.AppendNet( aNewNet ); } + NETINFO_LIST& GetNetInfo() + { + return m_NetInfo; + } + #ifndef SWIG /** * Function BeginNets diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index 8fb74d50e4..3f0a5fba39 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -422,6 +423,11 @@ public: } #endif + BOARD* GetParent() const + { + return m_Parent; + } + private: /** * Function clear @@ -468,7 +474,7 @@ private: * Class NETINFO_ITEM * handles the data for a net */ -class NETINFO_ITEM +class NETINFO_ITEM : public BOARD_ITEM { friend class NETINFO_LIST; @@ -485,7 +491,7 @@ private: // item of the net classes list NETCLASSPTR m_NetClass; - BOARD_ITEM* m_parent; ///< The parent board item object the net belongs to. + BOARD* m_parent; ///< The parent board the net belongs to. public: std::vector m_PadInNetList; ///< List of pads connected to this net @@ -498,9 +504,33 @@ public: unsigned m_RatsnestEndIdx; // Ending point of ratsnests of this net // (excluded) in this buffer - NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName = wxEmptyString, int aNetCode = -1 ); + NETINFO_ITEM( BOARD* aParent, const wxString& aNetName = wxEmptyString, int aNetCode = -1 ); ~NETINFO_ITEM(); + static inline bool ClassOf( const EDA_ITEM* aItem ) + { + return aItem && PCB_T == aItem->Type(); + } + + wxString GetClass() const + { + return wxT( "NETINFO_ITEM" ); + } + + void Show( int nestLevel, std::ostream& os ) const + { + } + + const wxPoint& GetPosition() const + { + static wxPoint dummy(0, 0); + return dummy; + } + + void SetPosition( const wxPoint& aPos ) + { + } + /** * Function SetClass * sets \a aNetclass into this NET @@ -622,6 +652,8 @@ public: */ int GetNet() const { return m_NetCode; } + void SetNetCode( int aNetCode ) { m_NetCode = aNetCode; } + /** * Function GetNodesCount * @return int - number of nodes in the net @@ -663,6 +695,12 @@ public: SetClass( NETCLASSPTR() ); } + + BOARD* GetParent() const + { + return m_parent; + } + }; diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp index 1f1f2672e3..46c60fe046 100644 --- a/pcbnew/class_netinfo_item.cpp +++ b/pcbnew/class_netinfo_item.cpp @@ -49,7 +49,8 @@ /* class NETINFO_ITEM: handle data relative to a given net */ /*********************************************************/ -NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent, const wxString& aNetName, int aNetCode ) : +NETINFO_ITEM::NETINFO_ITEM( BOARD* aParent, const wxString& aNetName, int aNetCode ) : + BOARD_ITEM( aParent, PCB_NETINFO_T ), m_NetCode( aNetCode ), m_Netname( aNetName ), m_ShortNetname( m_Netname.AfterLast( '/' ) ) { m_parent = aParent; diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index bbd31bf750..99e7632c15 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -87,7 +87,7 @@ void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName, SetLastNetListRead( aNetlistFileName ); netlistReader->LoadNetlist(); - loadFootprints( netlist, aReporter ); + LoadFootprints( netlist, aReporter ); } catch( const IO_ERROR& ioe ) { @@ -205,7 +205,7 @@ MODULE* PCB_EDIT_FRAME::ListAndSelectModuleName() #define ALLOW_PARTIAL_FPID 1 -void PCB_EDIT_FRAME::loadFootprints( NETLIST& aNetlist, REPORTER* aReporter ) +void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER* aReporter ) throw( IO_ERROR, PARSE_ERROR ) { wxString msg; diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 7c72766c05..adc68a70bc 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -309,6 +309,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB, wxT( "Pcbnew" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME ) { + m_undoDisabled = false; m_showBorderAndTitleBlock = true; // true to display sheet references m_showAxis = false; // true to display X and Y axis m_showOriginAxis = true;