Implement DeMorgan conversions in modern toolset.

This commit is contained in:
Jeff Young 2019-05-01 22:50:11 +01:00
parent 7c54fc9c46
commit 1e5334f5d4
13 changed files with 89 additions and 67 deletions

View File

@ -23,11 +23,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file getpart.cpp
* @brief functions to get and place library components.
*/
#include <algorithm>
#include <fctsys.h>
#include <pgm_base.h>
@ -38,7 +33,8 @@
#include <sch_edit_frame.h>
#include <kicad_device_context.h>
#include <msgpanel.h>
#include <tool/tool_manager.h>
#include <tools/sch_actions.h>
#include <general.h>
#include <class_library.h>
#include <sch_component.h>
@ -272,7 +268,7 @@ void SCH_EDIT_FRAME::ConvertPart( SCH_COMPONENT* aComponent )
return;
}
STATUS_FLAGS flags = aComponent->GetFlags();
STATUS_FLAGS savedFlags = aComponent->GetFlags();
aComponent->SetConvert( aComponent->GetConvert() + 1 );
@ -290,7 +286,11 @@ void SCH_EDIT_FRAME::ConvertPart( SCH_COMPONENT* aComponent )
aComponent->UpdatePins();
TestDanglingEnds();
aComponent->ClearFlags();
aComponent->SetFlags( flags ); // Restore m_Flag (modified by SetConvert())
aComponent->SetFlags( savedFlags ); // Restore m_Flags (modified by SetConvert())
// If selected make sure all the now-included pins are selected
if( aComponent->IsSelected() )
m_toolManager->RunAction( SCH_ACTIONS::addItemToSel, true, aComponent );
RefreshItem( aComponent );
OnModify();

View File

@ -115,10 +115,6 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, SYMBOL_LIB
wxMenu* editmenu = new wxMenu;
if( part && part->HasConversion() )
AddMenuItem( editmenu, ID_POPUP_SCH_EDIT_CONVERT_CMP, _( "Convert" ),
KiBitmap( component_select_alternate_shape_xpm ) );
if( part && part->GetUnitCount() >= 2 )
{
wxMenu* sel_unit_menu = new wxMenu; int ii;

View File

@ -740,6 +740,13 @@ void SCH_EDIT_FRAME::OnModify()
}
void SCH_EDIT_FRAME::OnUpdateSelectTool( wxUpdateUIEvent& aEvent )
{
if( aEvent.GetEventObject() == m_drawToolBar || aEvent.GetEventObject() == m_mainToolBar )
aEvent.Check( GetToolId() == aEvent.GetId() );
}
void SCH_EDIT_FRAME::OnUpdatePaste( wxUpdateUIEvent& event )
{
event.Enable( m_blockItems.GetCount() > 0 );

View File

@ -1026,9 +1026,10 @@ public:
*/
void EditComponentFieldText( SCH_FIELD* aField );
void ConvertPart( SCH_COMPONENT* aComponent );
private:
void OnSelectUnit( wxCommandEvent& aEvent );
void ConvertPart( SCH_COMPONENT* DrawComponent );
/* Undo - redo */
public:

View File

@ -57,27 +57,10 @@
pos.y += 20;
// If needed, stop the current command and deselect current tool
switch( id )
{
case ID_POPUP_SCH_CLEANUP_SHEET:
case ID_POPUP_IMPORT_HLABEL_TO_SHEETPIN:
case ID_POPUP_SCH_EDIT_CONVERT_CMP:
/* At this point: Do nothing. these commands do not need to stop the
* current command (mainly a block command) or reset the current state
* They will be executed later, in next switch structure.
*/
break;
default:
// Stop the current command and deselect the current tool
SetNoToolSelected();
break;
}
switch( id )
{
case ID_HIERARCHY:
SetNoToolSelected();
InstallHierarchyFrame( pos );
SetRepeatItem( NULL );
break;
@ -105,22 +88,10 @@
}
break;
case ID_POPUP_SCH_EDIT_CONVERT_CMP:
// Ensure the struct is a component (could be a struct of a component, like Field, text..)
if( item && item->Type() == SCH_COMPONENT_T )
{
m_canvas->MoveCursorToCrossHair();
ConvertPart( (SCH_COMPONENT*) item );
}
break;
default: // Log error:
wxFAIL_MSG( wxString::Format( "Cannot process command event ID %d", event.GetId() ) );
break;
}
if( GetToolId() == ID_NO_TOOL_SELECTED )
SetRepeatItem( NULL );
}
@ -137,13 +108,6 @@ void SCH_EDIT_FRAME::OnUnfoldBus( wxCommandEvent& event )
}
void SCH_EDIT_FRAME::OnUpdateSelectTool( wxUpdateUIEvent& aEvent )
{
if( aEvent.GetEventObject() == m_drawToolBar || aEvent.GetEventObject() == m_mainToolBar )
aEvent.Check( GetToolId() == aEvent.GetId() );
}
void SCH_EDIT_FRAME::OnUnfoldBusHotkey( wxCommandEvent& aEvent )
{
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();

View File

@ -248,6 +248,9 @@ OPT<TOOL_EVENT> SCH_ACTIONS::TranslateLegacyId( int aId )
case ID_AUTOPLACE_FIELDS:
return SCH_ACTIONS::autoplaceFields.MakeEvent();
case ID_POPUP_SCH_EDIT_CONVERT_CMP:
return SCH_ACTIONS::convertDeMorgan.MakeEvent();
case ID_POPUP_SCH_DISPLAYDOC_CMP:
return SCH_ACTIONS::showDatasheet.MakeEvent();

View File

@ -117,6 +117,7 @@ public:
static TOOL_ACTION editValue;
static TOOL_ACTION editFootprint;
static TOOL_ACTION autoplaceFields;
static TOOL_ACTION convertDeMorgan;
static TOOL_ACTION doDelete;
static TOOL_ACTION addJunction;
static TOOL_ACTION addLabel;

View File

@ -391,7 +391,7 @@ int SCH_DRAWING_TOOL::doPlaceComponent( SCH_COMPONENT* aComponent, SCHLIB_FILTER
aComponent->SetFlags( IS_NEW | IS_MOVED );
m_toolMgr->RunAction( SCH_ACTIONS::clearSelection, true );
m_toolMgr->RunAction( SCH_ACTIONS::addItemToSel, true, aComponent );
m_selectionTool->AddItemToSel( aComponent );
// Queue up a refresh event so we don't have to wait for the next mouse-moved event
m_toolMgr->RunAction( SCH_ACTIONS::refreshPreview );
@ -854,7 +854,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType )
if( selection.GetSize() == 1 )
{
item = (SCH_ITEM*) selection.GetItem( 0 );
item = (SCH_ITEM*) selection.Front();
m_view->ClearPreview();
m_view->AddToPreview( item->Clone() );
}

View File

@ -112,6 +112,11 @@ TOOL_ACTION SCH_ACTIONS::autoplaceFields( "eeschema.InteractiveEdit.autoplaceFie
_( "Autoplace Fields" ), _( "Runs the automatic placement algorithm on the symbol's fields" ),
autoplace_fields_xpm );
TOOL_ACTION SCH_ACTIONS::convertDeMorgan( "eeschema.InteractiveEdit.convertDeMorgan",
AS_GLOBAL, 0,
_( "DeMorgan Conversion" ), _( "Switch between DeMorgan representations" ),
nullptr );
TOOL_ACTION SCH_ACTIONS::toShapeSlash( "eeschema.InteractiveEdit.toShapeSlash",
AS_GLOBAL, 0,
_( "Set Bus Entry Shape /" ), _( "Change the bus entry shape to /" ),
@ -205,7 +210,7 @@ bool SCH_EDIT_TOOL::Init()
if( aSel.GetSize() > 1 )
return true;
switch( static_cast<EDA_ITEM*>( aSel.GetItem( 0 ) )->Type() )
switch( static_cast<EDA_ITEM*>( aSel.Front() )->Type() )
{
case SCH_MARKER_T:
case SCH_JUNCTION_T:
@ -225,7 +230,7 @@ bool SCH_EDIT_TOOL::Init()
if( aSel.GetSize() != 1 )
return false;
switch( static_cast<EDA_ITEM*>( aSel.GetItem( 0 ) )->Type() )
switch( static_cast<EDA_ITEM*>( aSel.Front() )->Type() )
{
case SCH_MARKER_T:
case SCH_JUNCTION_T:
@ -273,7 +278,7 @@ bool SCH_EDIT_TOOL::Init()
auto singleSymbolCondition = [] ( const SELECTION& aSel ) {
if( aSel.GetSize() == 1 )
{
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.GetItem( 0 ) );
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
if( comp )
{
@ -285,6 +290,21 @@ bool SCH_EDIT_TOOL::Init()
return false;
};
auto singleDeMorganSymbolCondition = [] ( const SELECTION& aSel ) {
if( aSel.GetSize() == 1 )
{
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
if( comp )
{
auto partRef = comp->GetPartRef().lock();
return partRef && partRef->HasConversion();
}
}
return false;
};
auto wireTool = [ this ] ( const SELECTION& aSel ) {
return ( m_frame->GetToolId() == ID_WIRE_BUTT
|| m_frame->GetToolId() == ID_JUNCTION_BUTT );
@ -323,6 +343,7 @@ bool SCH_EDIT_TOOL::Init()
ctxMenu.AddItem( SCH_ACTIONS::editReference, singleComponentCondition );
ctxMenu.AddItem( SCH_ACTIONS::editValue, singleComponentCondition );
ctxMenu.AddItem( SCH_ACTIONS::editFootprint, singleComponentCondition );
ctxMenu.AddItem( SCH_ACTIONS::convertDeMorgan, singleDeMorganSymbolCondition );
ctxMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty );
ctxMenu.AddItem( SCH_ACTIONS::cut, SELECTION_CONDITIONS::NotEmpty );
@ -345,6 +366,7 @@ bool SCH_EDIT_TOOL::Init()
drawingMenu.AddItem( SCH_ACTIONS::editReference, singleComponentCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::editValue, singleComponentCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::editFootprint, singleComponentCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::convertDeMorgan, singleDeMorganSymbolCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::toShapeSlash, entryCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::toShapeBackslash, entryCondition, 200 );
drawingMenu.AddItem( SCH_ACTIONS::toLabel, toLabelCondition, 200 );
@ -374,6 +396,7 @@ bool SCH_EDIT_TOOL::Init()
selToolMenu.AddItem( SCH_ACTIONS::editValue, singleSymbolCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::editFootprint, singleSymbolCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::autoplaceFields, singleComponentCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::convertDeMorgan, singleDeMorganSymbolCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::showDatasheet, singleSymbolCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::toShapeSlash, entryCondition, 200 );
selToolMenu.AddItem( SCH_ACTIONS::toShapeBackslash, entryCondition, 200 );
@ -845,7 +868,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
wxPoint rotPoint;
bool clockwise = ( aEvent.Matches( SCH_ACTIONS::rotateCW.MakeEvent() ) );
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( 0 ) );
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
bool connections = false;
bool moving = item->IsMoving();
@ -970,7 +993,7 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
wxPoint mirrorPoint;
bool xAxis = ( aEvent.Matches( SCH_ACTIONS::mirrorX.MakeEvent() ) );
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.GetItem( 0 ) );
SCH_ITEM* item = static_cast<SCH_ITEM*>( selection.Front() );
bool connections = false;
bool moving = item->IsMoving();
@ -1360,7 +1383,7 @@ int SCH_EDIT_TOOL::EditField( const TOOL_EVENT& aEvent )
if( selection.Empty() )
return 0;
SCH_ITEM* item = (SCH_ITEM*) selection.GetItem( 0 );
SCH_ITEM* item = (SCH_ITEM*) selection.Front();
if( item->Type() == SCH_COMPONENT_T )
{
@ -1389,7 +1412,7 @@ int SCH_EDIT_TOOL::AutoplaceFields( const TOOL_EVENT& aEvent )
if( selection.Empty() )
return 0;
SCH_COMPONENT* component = (SCH_COMPONENT*) selection.GetItem( 0 );
SCH_COMPONENT* component = (SCH_COMPONENT*) selection.Front();
if( !component->IsNew() )
m_frame->SaveCopyInUndoList( component, UR_CHANGED );
@ -1403,6 +1426,26 @@ int SCH_EDIT_TOOL::AutoplaceFields( const TOOL_EVENT& aEvent )
}
int SCH_EDIT_TOOL::ConvertDeMorgan( const TOOL_EVENT& aEvent )
{
SELECTION& selection = m_selectionTool->RequestSelection( SCH_COLLECTOR::ComponentsOnly );
if( selection.Empty() )
return 0;
SCH_COMPONENT* component = (SCH_COMPONENT*) selection.Front();
if( component->IsNew() )
m_toolMgr->RunAction( SCH_ACTIONS::refreshPreview );
else
m_frame->SaveCopyInUndoList( component, UR_CHANGED );
m_frame->ConvertPart( component );
return 0;
}
int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
{
SELECTION& selection = m_selectionTool->RequestSelection( SCH_COLLECTOR::EditableItems );
@ -1410,7 +1453,7 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
if( selection.Empty() )
return 0;
SCH_ITEM* item = (SCH_ITEM*) selection.GetItem( 0 );
SCH_ITEM* item = (SCH_ITEM*) selection.Front();
switch( item->Type() )
{
@ -1606,6 +1649,7 @@ void SCH_EDIT_TOOL::setTransitions()
Go( &SCH_EDIT_TOOL::EditField, SCH_ACTIONS::editValue.MakeEvent() );
Go( &SCH_EDIT_TOOL::EditField, SCH_ACTIONS::editFootprint.MakeEvent() );
Go( &SCH_EDIT_TOOL::AutoplaceFields, SCH_ACTIONS::autoplaceFields.MakeEvent() );
Go( &SCH_EDIT_TOOL::ConvertDeMorgan, SCH_ACTIONS::convertDeMorgan.MakeEvent() );
Go( &SCH_EDIT_TOOL::ChangeShape, SCH_ACTIONS::toShapeSlash.MakeEvent() );
Go( &SCH_EDIT_TOOL::ChangeShape, SCH_ACTIONS::toShapeBackslash.MakeEvent() );

View File

@ -64,6 +64,7 @@ public:
int Properties( const TOOL_EVENT& aEvent );
int EditField( const TOOL_EVENT& aEvent );
int AutoplaceFields( const TOOL_EVENT& aEvent );
int ConvertDeMorgan( const TOOL_EVENT& aEvent );
int ChangeShape( const TOOL_EVENT& aEvent );
int ChangeTextType( const TOOL_EVENT& aEvent );

View File

@ -693,7 +693,7 @@ int SCH_EDITOR_CONTROL::EditWithSymbolEditor( const TOOL_EVENT& aEvent )
wxString msg;
if( selection.GetSize() >= 1 )
comp = (SCH_COMPONENT*) selection.GetItem( 0 );
comp = (SCH_COMPONENT*) selection.Front();
if( !comp || comp->GetEditFlags() != 0 )
return 0;
@ -720,7 +720,7 @@ int SCH_EDITOR_CONTROL::EnterSheet( const TOOL_EVENT& aEvent )
if( selection.GetSize() == 1 )
{
g_CurrentSheet->push_back( (SCH_SHEET*) selection.GetItem( 0 ) );
g_CurrentSheet->push_back( (SCH_SHEET*) selection.Front() );
m_frame->DisplayCurrentSheet();
}

View File

@ -72,7 +72,7 @@ bool SCH_INSPECTION_TOOL::Init()
auto singleSymbolCondition = [] (const SELECTION& aSel ) {
if( aSel.GetSize() == 1 )
{
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.GetItem( 0 ) );
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( aSel.Front() );
if( comp )
{
@ -110,7 +110,7 @@ int SCH_INSPECTION_TOOL::ShowDatasheet( const TOOL_EVENT& aEvent )
if( selection.Empty() )
return 0;
SCH_COMPONENT* component = (SCH_COMPONENT*) selection.GetItem( 0 );
SCH_COMPONENT* component = (SCH_COMPONENT*) selection.Front();
wxString datasheet = component->GetField( DATASHEET )->GetText();
if( !datasheet.IsEmpty() )
@ -127,7 +127,7 @@ int SCH_INSPECTION_TOOL::ShowMarkerInfo( const TOOL_EVENT& aEvent )
if( selection.Empty() )
return 0;
SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( selection.GetItem( 0 ) );
SCH_MARKER* marker = dynamic_cast<SCH_MARKER*>( selection.Front() );
if( marker )
marker->DisplayMarkerInfo( m_frame );
@ -143,7 +143,7 @@ int SCH_INSPECTION_TOOL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
if( selection.GetSize() == 1 )
{
SCH_ITEM* item = (SCH_ITEM*) selection.GetItem( 0 );
SCH_ITEM* item = (SCH_ITEM*) selection.Front();
MSG_PANEL_ITEMS msgItems;
item->GetMsgPanelInfo( m_frame->GetUserUnits(), msgItems );

View File

@ -154,6 +154,11 @@ int SCH_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
// Single click? Select single object
if( evt->IsClick( BUT_LEFT ) )
{
// JEY TODO: this is a hack, but I can't figure out why it's needed to
// keep from getting the first click when running the Place Symbol tool.
if( m_frame->GetToolId() != ID_NO_TOOL_SELECTED )
continue;
if( evt->Modifier( MD_CTRL ) && dynamic_cast<SCH_EDIT_FRAME*>( m_frame ) )
{
m_toolMgr->RunAction( SCH_ACTIONS::highlightNet, true );
@ -529,7 +534,7 @@ int SCH_SELECTION_TOOL::SelectConnection( const TOOL_EVENT& aEvent )
if( m_selection.Empty() )
return 0;
SCH_LINE* line = (SCH_LINE*) m_selection.GetItem( 0 );
SCH_LINE* line = (SCH_LINE*) m_selection.Front();
EDA_ITEMS items;
m_frame->GetScreen()->ClearDrawingState();