void SCH_SCREEN::addConnectedItemsToBlock( const wxPoint& position ) { SCH_ITEM* item; ITEM_PICKER picker; bool addinlist = true; for( item = m_drawList.begin(); item; item = item->Next() ) { picker.SetItem( item ); if( !item->IsConnectable() || !item->IsConnected( position ) || (item->GetFlags() & SKIP_STRUCT) ) continue; if( item->IsSelected() && item->Type() != SCH_LINE_T ) continue; // A line having 2 ends, it can be tested twice: one time per end if( item->Type() == SCH_LINE_T ) { if( ! item->IsSelected() ) // First time this line is tested item->SetFlags( SELECTED | STARTPOINT | ENDPOINT ); else // second time (or more) this line is tested addinlist = false; SCH_LINE* line = (SCH_LINE*) item; if( line->GetStartPoint() == position ) item->ClearFlags( STARTPOINT ); else if( line->GetEndPoint() == position ) item->ClearFlags( ENDPOINT ); } else item->SetFlags( SELECTED ); if( addinlist ) { picker.SetFlags( item->GetFlags() ); m_BlockLocate.GetItems().PushItem( picker ); } } }
/** * When the component table dialog is closed, * work out if we need to save any changed. * If so, capture those changes and push them to the undo stack. */ bool DIALOG_BOM_EDITOR::TransferDataFromWindow() { if( m_bom->HaveFieldsChanged() ) { /** * As we may be saving changes across multiple sheets, * we need to first determine which changes need to be made to which sheet. * To this end, we perform the following: * 1. Save the "path" of the currently displayed sheet * 2. Create a MAP of <SheetPath:ChangeList> changes that need to be made * 3. Push UNDO actions to appropriate sheets * 4. Perform all the update actions * 5. Reset the view to the current sheet */ auto currentSheet = m_parent->GetCurrentSheet(); //! Create a map of changes required for each sheet std::map<wxString, SheetUndoList> undoSheetMap; // List of components that have changed auto changed = m_bom->GetChangedComponents(); ITEM_PICKER picker; // Iterate through each of the components that were changed for( auto ref : changed ) { // Extract the SCH_COMPONENT* object auto cmp = ref.GetComp(); wxString path = ref.GetSheetPath().Path(); // Push the component into the picker list picker = ITEM_PICKER( cmp, UR_CHANGED ); picker.SetFlags( cmp->GetFlags() ); /* * If there is not currently an undo list for the given sheet, * create an empty one */ if( undoSheetMap.count( path ) == 0 ) { SheetUndoList newList; newList.path = ref.GetSheetPath(); undoSheetMap[path] = newList; } auto& pickerList = undoSheetMap[path]; pickerList.items.PushItem( picker ); } // Iterate through each sheet that needs updating for( auto it = undoSheetMap.begin(); it != undoSheetMap.end(); ++it ) { auto undo = it->second; m_parent->SetCurrentSheet( undo.path ); m_parent->SaveCopyInUndoList( undo.items, UR_CHANGED ); m_parent->OnModify(); } // Make all component changes m_bom->ApplyFieldChanges(); // Redraw the current sheet and mark as dirty m_parent->Refresh(); m_parent->OnModify(); // Reset the view to where we left the user m_parent->SetCurrentSheet(currentSheet); } return true; }
void SCH_SCREEN::addConnectedItemsToBlock( const SCH_ITEM* aItem, const wxPoint& position ) { SCH_ITEM* item; ITEM_PICKER picker; for( item = m_drawList.begin(); item; item = item->Next() ) { if( !item->IsConnectable() || ( item->GetFlags() & SKIP_STRUCT ) || !item->CanConnect( aItem ) || item == aItem ) continue; // A line having 2 ends, it can be tested twice: one time per end if( item->Type() == SCH_LINE_T ) { SCH_LINE* line = (SCH_LINE*) item; if( !item->HitTest( position ) ) continue; // First time through. Flags set to denote an end that is not moving if( !item->IsSelected() ) item->SetFlags( CANDIDATE | STARTPOINT | ENDPOINT ); if( line->GetStartPoint() == position ) item->ClearFlags( STARTPOINT ); else if( line->GetEndPoint() == position ) item->ClearFlags( ENDPOINT ); else // This picks up items such as labels that can connect to the middle of a line item->ClearFlags( STARTPOINT | ENDPOINT ); } // We want to move a mid-connected label or bus entry when the full line is being moved else if( !item->IsSelected() && aItem->Type() == SCH_LINE_T && !( aItem->GetFlags() & ( ENDPOINT | STARTPOINT ) ) ) { std::vector< wxPoint > connections; item->GetConnectionPoints( connections ); for( auto conn : connections ) { if( aItem->HitTest( conn ) ) { item->SetFlags( CANDIDATE ); break; } } } if( item->IsSelected() ) continue; if( ( item->GetFlags() & CANDIDATE ) || item->IsConnected( position ) ) // Deal with all non-line items { item->ClearFlags( CANDIDATE ); item->SetFlags( SELECTED ); picker.SetItem( item ); picker.SetFlags( item->GetFlags() ); m_BlockLocate.GetItems().PushItem( picker ); } } }