From 902be18a048d2228989923985821521b42c7e840 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 29 Apr 2019 18:50:46 +0100 Subject: [PATCH] More modern toolset context menu work. Text/label type changes and bus entry shape changes. And some context menu bug fixing. --- common/tool/tool_event.cpp | 20 ++- common/tool/tool_menu.cpp | 7 +- eeschema/CMakeLists.txt | 1 - eeschema/bus-wire-junction.cpp | 20 --- eeschema/busentry.cpp | 82 ------------ eeschema/edit_label.cpp | 179 +++++++------------------ eeschema/eeschema_id.h | 9 -- eeschema/onrightclick.cpp | 118 ----------------- eeschema/sch_edit_frame.cpp | 2 - eeschema/sch_edit_frame.h | 23 ++-- eeschema/sch_screen.h | 1 + eeschema/schedit.cpp | 12 -- eeschema/tools/sch_actions.cpp | 5 + eeschema/tools/sch_actions.h | 8 ++ eeschema/tools/sch_drawing_tool.cpp | 110 +++++++++++----- eeschema/tools/sch_drawing_tool.h | 11 +- eeschema/tools/sch_edit_tool.cpp | 196 +++++++++++++++++++++++++--- eeschema/tools/sch_edit_tool.h | 3 + eeschema/tools/sch_picker_tool.cpp | 2 +- include/tool/tool_event.h | 32 +++++ pcbnew/tools/tool_event_utils.cpp | 10 +- pcbnew/tools/tool_event_utils.h | 9 -- 22 files changed, 382 insertions(+), 478 deletions(-) delete mode 100644 eeschema/busentry.cpp diff --git a/common/tool/tool_event.cpp b/common/tool/tool_event.cpp index 6bc2763062..a23161c59c 100644 --- a/common/tool/tool_event.cpp +++ b/common/tool/tool_event.cpp @@ -28,7 +28,7 @@ #include #include #include - +#include struct FlagString { @@ -160,3 +160,21 @@ const std::string TOOL_EVENT_LIST::Format() const return s; } + + +bool TOOL_EVT_UTILS::IsCancelInteractive( const TOOL_EVENT& aEvt ) +{ + return aEvt.IsAction( &ACTIONS::cancelInteractive ) + || aEvt.IsActivate() + || aEvt.IsCancel(); +} + + +bool TOOL_EVT_UTILS::IsSelectionEvent( const TOOL_EVENT& aEvt ) +{ + return aEvt.Matches( EVENTS::ClearedEvent ) + || aEvt.Matches( EVENTS::UnselectedEvent ) + || aEvt.Matches( EVENTS::SelectedEvent ); +} + + diff --git a/common/tool/tool_menu.cpp b/common/tool/tool_menu.cpp index fd76fae516..fd3c4e73d6 100644 --- a/common/tool/tool_menu.cpp +++ b/common/tool/tool_menu.cpp @@ -61,13 +61,10 @@ void TOOL_MENU::AddSubMenu( std::shared_ptr aSubMenu ) void TOOL_MENU::ShowContextMenu( SELECTION& aSelection ) { - m_contextMenu = std::unique_ptr( - m_menu.Generate( aSelection ) ); + m_contextMenu = std::unique_ptr( m_menu.Generate( aSelection ) ); if( m_contextMenu->GetMenuItemCount() > 0 ) - { m_tool.SetContextMenu( m_contextMenu.get(), CMENU_NOW ); - } } @@ -83,9 +80,7 @@ void TOOL_MENU::CloseContextMenu( OPT_TOOL_EVENT& evt ) { // m_contextMenu can be null here, that's OK if( evt->Parameter() == m_contextMenu.get() ) - { m_contextMenu = nullptr; - } } diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 324f46262d..2e8626b37a 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -142,7 +142,6 @@ set( EESCHEMA_SRCS block.cpp bus_alias.cpp bus-wire-junction.cpp - busentry.cpp class_libentry.cpp class_library.cpp cmp_library_keywords.cpp diff --git a/eeschema/bus-wire-junction.cpp b/eeschema/bus-wire-junction.cpp index b84a250bd9..6304c8927c 100644 --- a/eeschema/bus-wire-junction.cpp +++ b/eeschema/bus-wire-junction.cpp @@ -452,23 +452,3 @@ SCH_JUNCTION* SCH_EDIT_FRAME::AddJunction( const wxPoint& aPosition, bool aAppen } -SCH_NO_CONNECT* SCH_EDIT_FRAME::AddNoConnect( const wxPoint& aPosition ) -{ - SCH_NO_CONNECT* no_connect = new SCH_NO_CONNECT( aPosition ); - - SetRepeatItem( no_connect ); - AddToScreen( no_connect ); - SchematicCleanUp(); - TestDanglingEnds(); - OnModify(); - - auto view = GetCanvas()->GetView(); - view->ClearPreview(); - view->ShowPreview( false ); - view->ClearHiddenFlags(); - - SaveCopyInUndoList( no_connect, UR_NEW ); - return no_connect; -} - - diff --git a/eeschema/busentry.cpp b/eeschema/busentry.cpp deleted file mode 100644 index a5966eeb16..0000000000 --- a/eeschema/busentry.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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) 2008-2011 Wayne Stambaugh - * Copyright (C) 2004-2011 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 - */ - -/** - * @file busentry.cpp - * @brief Code to handle manipulation of bus entry objects. - */ - -#include -#include -#include -#include - -#include - - -static int s_LastShape = '\\'; - - -SCH_BUS_BUS_ENTRY* SCH_EDIT_FRAME::CreateBusBusEntry() -{ - // Create and place a new bus entry at cursor position - SCH_BUS_BUS_ENTRY* busEntry = new SCH_BUS_BUS_ENTRY( GetCrossHairPosition(), s_LastShape ); - - busEntry->SetFlags( IS_NEW ); - GetScreen()->SetCurItem( busEntry ); - AddItemToScreen( busEntry ); - return busEntry; -} - -SCH_BUS_WIRE_ENTRY* SCH_EDIT_FRAME::CreateBusWireEntry() -{ - // Create and place a new bus entry at cursor position - SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( GetCrossHairPosition(), s_LastShape ); - - busEntry->SetFlags( IS_NEW ); - GetScreen()->SetCurItem( busEntry ); - AddItemToScreen( busEntry ); - return busEntry; -} - -/* set the shape of BusEntry (shape = / or \ ) - */ -void SCH_EDIT_FRAME::SetBusEntryShape( wxDC* DC, SCH_BUS_ENTRY_BASE* BusEntry, char entry_shape ) -{ - if( BusEntry == NULL ) - return; - - /* Put old item in undo list if it is not currently in edit */ - if( BusEntry->GetEditFlags() == 0 ) - SaveCopyInUndoList( BusEntry, UR_CHANGED ); - - s_LastShape = entry_shape == '/' ? '/' : '\\'; - - BusEntry->SetBusEntryShape( s_LastShape ); - TestDanglingEnds(); - - RefreshItem( BusEntry ); - OnModify( ); -} diff --git a/eeschema/edit_label.cpp b/eeschema/edit_label.cpp index 8500de75b2..faadf04397 100644 --- a/eeschema/edit_label.cpp +++ b/eeschema/edit_label.cpp @@ -22,11 +22,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -/** - * @file edit_label.cpp - * @brief Label, global label and text creation and editing. - */ - #include #include #include @@ -35,10 +30,12 @@ #include #include #include - +#include +#include #include #include #include +#include static PINSHEETLABEL_SHAPE lastGlobalLabelShape = NET_INPUT; @@ -104,163 +101,77 @@ SCH_TEXT* SCH_EDIT_FRAME::CreateNewText( int aType ) /* - * OnConvertTextType is a command event handler to change a text type to another one. - * The new text, label, hierarchical label, or global label is created from the old text - * The old text is deleted. - * A tricky case is when the 'old" text is being edited (i.e. moving) - * because we must create a new text, and prepare the undo/redo command data for this - * change and the current move/edit command + * ConvertTextType changes a text from one type to another. It creates a new text of the + * appropriate type and deletes the old one. */ -void SCH_EDIT_FRAME::OnConvertTextType( wxCommandEvent& aEvent ) +void SCH_EDIT_FRAME::ConvertTextType( SCH_TEXT* aText, KICAD_T aType ) { SCH_SCREEN* screen = GetScreen(); - SCH_TEXT* text = (SCH_TEXT*) screen->GetCurItem(); + bool selected = aText->IsSelected(); - wxCHECK_RET( (text != NULL) && text->CanIncrementLabel(), "Cannot convert text type." ); + wxCHECK_RET( aText->CanIncrementLabel(), "Cannot convert text type." ); - KICAD_T type; - - switch( aEvent.GetId() ) - { - case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL: - type = SCH_LABEL_T; - break; - - case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL: - type = SCH_GLOBAL_LABEL_T; - break; - - case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL: - type = SCH_HIER_LABEL_T; - break; - - case ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT: - type = SCH_TEXT_T; - break; - - default: - wxFAIL_MSG( wxString::Format( "Invalid text type command ID %d.", aEvent.GetId() ) ); - return; - } - - if( text->Type() == type ) + if( aText->Type() == aType ) return; SCH_TEXT* newtext = nullptr; - const wxPoint& position = text->GetPosition(); - const wxString txt = text->GetText(); + const wxPoint& position = aText->GetPosition(); + const wxString txt = aText->GetText(); - switch( type ) + switch( aType ) { - case SCH_LABEL_T: - newtext = new SCH_LABEL( position, txt ); - break; - - case SCH_GLOBAL_LABEL_T: - newtext = new SCH_GLOBALLABEL( position, txt ); - break; - - case SCH_HIER_LABEL_T: - newtext = new SCH_HIERLABEL( position, txt ); - break; - - case SCH_TEXT_T: - newtext = new SCH_TEXT( position, txt ); - break; + case SCH_LABEL_T: newtext = new SCH_LABEL( position, txt ); break; + case SCH_GLOBAL_LABEL_T: newtext = new SCH_GLOBALLABEL( position, txt ); break; + case SCH_HIER_LABEL_T: newtext = new SCH_HIERLABEL( position, txt ); break; + case SCH_TEXT_T: newtext = new SCH_TEXT( position, txt ); break; default: - wxASSERT_MSG( false, wxString::Format( "Invalid text type: %d.", type ) ); + wxASSERT_MSG( false, wxString::Format( "Invalid text type: %d.", aType ) ); return; } - /* Copy the old text item settings to the new one. Justifications are not copied because - * they are not used in labels. Justifications will be set to default value in the new - * text item type. - */ - newtext->SetFlags( text->GetFlags() ); - newtext->SetShape( text->GetShape() ); - newtext->SetLabelSpinStyle( text->GetLabelSpinStyle() ); - newtext->SetTextSize( text->GetTextSize() ); - newtext->SetThickness( text->GetThickness() ); - newtext->SetItalic( text->IsItalic() ); - newtext->SetBold( text->IsBold() ); - newtext->SetIsDangling( text->IsDangling() ); + // Copy the old text item settings to the new one. Justifications are not copied + // because they are not used in labels. Justifications will be set to default value + // in the new text item type. + // + newtext->SetFlags( aText->GetEditFlags() ); + newtext->SetShape( aText->GetShape() ); + newtext->SetLabelSpinStyle( aText->GetLabelSpinStyle() ); + newtext->SetTextSize( aText->GetTextSize() ); + newtext->SetThickness( aText->GetThickness() ); + newtext->SetItalic( aText->IsItalic() ); + newtext->SetBold( aText->IsBold() ); + newtext->SetIsDangling( aText->IsDangling() ); - /* Save the new text in undo list if the old text was not itself a "new created text" - * In this case, the old text is already in undo list as a deleted item. - * Of course if the old text was a "new created text" the new text will be - * put in undo list later, at the end of the current command (if not aborted) - */ + if( selected ) + m_toolManager->RunAction( SCH_ACTIONS::unselectItem, true, aText ); - m_canvas->CrossHairOff(); // Erase schematic cursor - - // For an exiting item (i.e. already in list): - // replace the existing item by the new text in list - for( SCH_ITEM* item = screen->GetDrawItems(); item != NULL; item = item->Next() ) + if( !aText->IsNew() ) { - if( item == text ) - { - RemoveFromScreen( text ); - AddToScreen( newtext ); - break; - } + SaveCopyInUndoList( aText, UR_DELETED ); + SaveCopyInUndoList( newtext, UR_NEW, true ); + + RemoveFromScreen( aText ); + AddToScreen( newtext ); } - SetRepeatItem( NULL ); - OnModify(); - m_canvas->CrossHairOn( ); // redraw schematic cursor + if( selected ) + m_toolManager->RunAction( SCH_ACTIONS::selectItem, true, newtext ); // if the old item is the current schematic item, replace it by the new text: - if( screen->GetCurItem() == text ) + if( screen->GetCurItem() == aText ) screen->SetCurItem( newtext ); - if( text->IsNew() ) - { - // if the previous text is new, no undo command to prepare here - // just delete this previous text. - delete text; - return; - } + SetRepeatItem( nullptr ); - // previous text is not new and we replace text by new text. - // So this is equivalent to delete text and add newtext - // If text if being currently edited (i.e. moved) - // we also save the initial copy of text, and prepare undo command for new text modifications. - // we must save it as modified text,if it is currently edited, then save as deleted text, - // and replace text with newtext - PICKED_ITEMS_LIST pickList; - ITEM_PICKER picker( text, UR_CHANGED ); + delete aText; - if( text->GetEditFlags() ) - { - // text is being edited, save initial text for undo command - picker.SetLink( GetUndoItem() ); - pickList.PushItem( picker ); - - // the owner of undoItem is no more "this", it is now "picker": - SetUndoItem( NULL ); - - // save current newtext copy for undo/abort current command - SetUndoItem( newtext ); - } - - // Prepare undo command for delete old text - picker.SetStatus( UR_DELETED ); - picker.SetLink( NULL ); - pickList.PushItem( picker ); - - // Prepare undo command for new text - picker.SetStatus( UR_NEW ); - picker.SetItem(newtext); - pickList.PushItem( picker ); - - SaveCopyInUndoList( pickList, UR_UNSPECIFIED ); + OnModify(); } -/* Function to increment bus label members numbers, - * i.e. when a text is ending with a number, adds - * aIncrement to this number +/* + * Function to increment bus label numbers. Adds aIncrement to labels which end in numbers. */ void IncrementLabelMember( wxString& name, int aIncrement ) { diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h index 3983728fea..2aba0e51e6 100644 --- a/eeschema/eeschema_id.h +++ b/eeschema/eeschema_id.h @@ -135,8 +135,6 @@ enum id_eeschema_frm ID_POPUP_SCH_BEGIN_LINES, ID_POPUP_SCH_DELETE_CONNECTION, ID_POPUP_SCH_DELETE_NODE, - ID_POPUP_SCH_ENTRY_SELECT_SLASH, - ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH, ID_POPUP_SCH_INIT_CMP, @@ -171,13 +169,6 @@ enum id_eeschema_frm ID_POPUP_SCH_SELECT_UNIT_CMP_MAX = ID_POPUP_SCH_SELECT_UNIT1 + MAX_UNIT_COUNT_PER_PACKAGE, - // Change text type context menu command IDs. - ID_POPUP_SCH_CHANGE_TYPE_TEXT, - ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL, - ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL, - ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL, - ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT, - ID_SELECT_ITEM_START, ID_SELECT_ITEM_END = ID_SELECT_ITEM_START + MAX_SELECT_ITEM_IDS, diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp index ac4f4f2d18..260151f6d3 100644 --- a/eeschema/onrightclick.cpp +++ b/eeschema/onrightclick.cpp @@ -58,16 +58,9 @@ static void AddMenusForWire( wxMenu* PopMenu, SCH_LINE* Wire, SCH_EDIT_FRAME* frame ); static void AddMenusForBus( wxMenu* PopMenu, SCH_LINE* Bus, SCH_EDIT_FRAME* frame ); static void AddMenusForHierchicalSheet( wxMenu* PopMenu, SCH_SHEET* Sheet ); -static void AddMenusForText( wxMenu* PopMenu, SCH_TEXT* Text ); -static void AddMenusForLabel( wxMenu* PopMenu, SCH_LABEL* Label ); -static void AddMenusForGLabel( wxMenu* PopMenu, SCH_GLOBALLABEL* GLabel ); -static void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* GLabel ); -static void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, - SYMBOL_LIB_TABLE* aLibs ); static void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, SYMBOL_LIB_TABLE* aLibs ); static void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_FRAME* aFrame ); -static void AddMenusForBusEntry( wxMenu* aPopMenu, SCH_BUS_ENTRY_BASE * aBusEntry ); bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) @@ -134,31 +127,10 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) addJunctionMenuEntries( PopMenu, (SCH_JUNCTION*) item ); break; - case SCH_BUS_BUS_ENTRY_T: - case SCH_BUS_WIRE_ENTRY_T: - AddMenusForBusEntry( PopMenu, static_cast( item ) ); - break; - case SCH_MARKER_T: AddMenusForMarkers( PopMenu, (SCH_MARKER*) item, this ); break; - case SCH_TEXT_T: - AddMenusForText( PopMenu, (SCH_TEXT*) item ); - break; - - case SCH_LABEL_T: - AddMenusForLabel( PopMenu, (SCH_LABEL*) item ); - break; - - case SCH_GLOBAL_LABEL_T: - AddMenusForGLabel( PopMenu, (SCH_GLOBALLABEL*) item ); - break; - - case SCH_HIER_LABEL_T: - AddMenusForHLabel( PopMenu, (SCH_HIERLABEL*) item ); - break; - case SCH_COMPONENT_T: AddMenusForComponent( PopMenu, (SCH_COMPONENT*) item, Prj().SchSymbolLibTable() ); break; @@ -187,12 +159,6 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu ) void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, SYMBOL_LIB_TABLE* aLibs ) -{ - AddMenusForEditComponent( PopMenu, Component, aLibs ); -} - - -void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, SYMBOL_LIB_TABLE* aLibs ) { wxString msg; LIB_PART* part = NULL; @@ -250,79 +216,6 @@ void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, SYMBOL } -void AddMenusForGLabel( wxMenu* PopMenu, SCH_GLOBALLABEL* GLabel ) -{ - wxMenu* menu_change_type = new wxMenu; - wxString msg; - - // add menu change type text (to label, glabel, text): - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL, - _( "Change to Hierarchical Label" ), KiBitmap( label2glabel_xpm ) ); - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL, - _( "Change to Label" ), KiBitmap( glabel2label_xpm ) ); - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT, - _( "Change to Text" ), KiBitmap( glabel2text_xpm ) ); - AddMenuItem( PopMenu, menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT, - _( "Change Type" ), KiBitmap( gl_change_xpm ) ); -} - - -void AddMenusForHLabel( wxMenu* PopMenu, SCH_HIERLABEL* HLabel ) -{ - wxMenu* menu_change_type = new wxMenu; - wxString msg; - - // add menu change type text (to label, glabel, text): - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL, - _( "Change to Label" ), KiBitmap( glabel2label_xpm ) ); - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT, - _( "Change to Text" ), KiBitmap( glabel2text_xpm ) ); - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL, - _( "Change to Global Label" ), KiBitmap( label2glabel_xpm ) ); - AddMenuItem( PopMenu, menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT, - _( "Change Type" ), KiBitmap( gl_change_xpm ) ); -} - - -void AddMenusForLabel( wxMenu* PopMenu, SCH_LABEL* Label ) -{ - wxMenu* menu_change_type = new wxMenu; - wxString msg; - - // add menu change type text (to label, glabel, text): - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL, - _( "Change to Hierarchical Label" ), KiBitmap( label2glabel_xpm ) ); - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT, - _( "Change to Text" ), KiBitmap( label2text_xpm ) ); - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL, - _( "Change to Global Label" ), KiBitmap( label2glabel_xpm ) ); - AddMenuItem( PopMenu, menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT, - _( "Change Type" ), KiBitmap( gl_change_xpm ) ); -} - - -void AddMenusForText( wxMenu* PopMenu, SCH_TEXT* Text ) -{ - wxString msg; - wxMenu* menu_change_type = new wxMenu; - - /* add menu change type text (to label, glabel, text), - * but only if this is a single line text - */ - if( Text->GetText().Find( wxT( "\n" ) ) == wxNOT_FOUND ) - { - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_LABEL, - _( "Change to Label" ), KiBitmap( label2text_xpm ) ); - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_HLABEL, - _( "Change to Hierarchical Label" ), KiBitmap( label2glabel_xpm ) ); - AddMenuItem( menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_GLABEL, - _( "Change to Global Label" ), KiBitmap( label2glabel_xpm ) ); - AddMenuItem( PopMenu, menu_change_type, ID_POPUP_SCH_CHANGE_TYPE_TEXT, - _( "Change Type" ), KiBitmap( gl_change_xpm ) ); - } -} - - void SCH_EDIT_FRAME::addJunctionMenuEntries( wxMenu* aMenu, SCH_JUNCTION* aJunction ) { wxString msg; @@ -455,14 +348,3 @@ void AddMenusForMarkers( wxMenu* aPopMenu, SCH_MARKER* aMarker, SCH_EDIT_FRAME* } -void AddMenusForBusEntry( wxMenu* aPopMenu, SCH_BUS_ENTRY_BASE* aBusEntry ) -{ - wxString msg; - - if( aBusEntry->GetBusEntryShape() == '\\' ) - AddMenuItem( aPopMenu, ID_POPUP_SCH_ENTRY_SELECT_SLASH, - _( "Set Bus Entry Shape /" ), KiBitmap( change_entry_orient_xpm ) ); - else - AddMenuItem( aPopMenu, ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH, - _( "Set Bus Entry Shape \\" ), KiBitmap( change_entry_orient_xpm ) ); -} diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 426e83323d..eef859d945 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -288,8 +288,6 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME ) SCH_EDIT_FRAME::Process_Special_Functions ) EVT_MENU_RANGE( ID_POPUP_SCH_SELECT_UNIT1, ID_POPUP_SCH_SELECT_UNIT_CMP_MAX, SCH_EDIT_FRAME::OnSelectUnit ) - EVT_MENU_RANGE( ID_POPUP_SCH_CHANGE_TYPE_TEXT, ID_POPUP_SCH_CHANGE_TYPE_TEXT_TO_COMMENT, - SCH_EDIT_FRAME::OnConvertTextType ) /* Handle user interface update events. */ EVT_UPDATE_UI( wxID_PASTE, SCH_EDIT_FRAME::OnUpdatePaste ) diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index e5227bc3e3..2f57754ba5 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -741,13 +741,9 @@ public: */ bool AskToSaveChanges(); - SCH_NO_CONNECT* AddNoConnect( const wxPoint& aPosition ); SCH_JUNCTION* AddJunction( const wxPoint& aPosition, bool aAppendToUndo = false, bool aFinal = true ); - SCH_BUS_WIRE_ENTRY* CreateBusWireEntry(); - SCH_BUS_BUS_ENTRY* CreateBusBusEntry(); - SCH_TEXT* CreateNewText( int aType ); /** @@ -872,9 +868,6 @@ private: */ void UpdateTitle(); - // Bus Entry - void SetBusEntryShape( wxDC* DC, SCH_BUS_ENTRY_BASE* BusEntry, char entry_shape ); - /** * Checks all wires and adds any junctions that are missing * (Intended to be called only on file load) @@ -887,14 +880,6 @@ private: */ void NormalizeSchematicOnFirstLoad(); - /** - * Command event handler to change a text type to another one. - * - * The new text, label, hierarchical label, or global label is created from the old text - * and the old text object is deleted. - */ - void OnConvertTextType( wxCommandEvent& aEvent ); - /** * Erase the last segment at the current mouse position. */ @@ -904,6 +889,14 @@ private: void InstallHierarchyFrame( wxPoint& pos ); public: + /** + * Change a text type to another one. + * + * The new text, label, hierarchical label, or global label is created from the old text + * and the old text object is deleted. + */ + void ConvertTextType( SCH_TEXT* aText, KICAD_T aType ); + /** * Launches the "Edit Text/Label" dialog */ diff --git a/eeschema/sch_screen.h b/eeschema/sch_screen.h index 165e37a6b6..9b0e22ddfc 100644 --- a/eeschema/sch_screen.h +++ b/eeschema/sch_screen.h @@ -188,6 +188,7 @@ public: * * @return SCH_ITEM* - the one selected, or NULL. */ + // JEY TODO: these should go away: if the selection contains one item then it's the curItem... SCH_ITEM* GetCurItem() const { return (SCH_ITEM*) BASE_SCREEN::GetCurItem(); } LIB_ITEM* GetCurLibItem() const { return (LIB_ITEM*) BASE_SCREEN::GetCurItem(); } diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp index 332db340e1..b9e1f6aade 100644 --- a/eeschema/schedit.cpp +++ b/eeschema/schedit.cpp @@ -63,8 +63,6 @@ switch( id ) { case ID_POPUP_CANCEL_CURRENT_COMMAND: - case ID_POPUP_SCH_ENTRY_SELECT_SLASH: - case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH: case ID_POPUP_SCH_CLEANUP_SHEET: case ID_POPUP_SCH_RESIZE_SHEET: case ID_POPUP_IMPORT_HLABEL_TO_SHEETPIN: @@ -98,16 +96,6 @@ SetRepeatItem( NULL ); break; - case ID_POPUP_SCH_ENTRY_SELECT_SLASH: - m_canvas->MoveCursorToCrossHair(); - SetBusEntryShape( nullptr, dynamic_cast( item ), '/' ); - break; - - case ID_POPUP_SCH_ENTRY_SELECT_ANTISLASH: - m_canvas->MoveCursorToCrossHair(); - SetBusEntryShape( nullptr, dynamic_cast( item ), '\\' ); - break; - case ID_POPUP_CANCEL_CURRENT_COMMAND: if( m_canvas->IsMouseCaptured() ) { diff --git a/eeschema/tools/sch_actions.cpp b/eeschema/tools/sch_actions.cpp index 883a0b42e8..fb43459c71 100644 --- a/eeschema/tools/sch_actions.cpp +++ b/eeschema/tools/sch_actions.cpp @@ -33,6 +33,11 @@ #include #include + +char g_lastBusEntryShape = '/'; + + +// JEY TODO: IDs that only appear in popup menus don't need to be here.... OPT SCH_ACTIONS::TranslateLegacyId( int aId ) { switch( aId ) diff --git a/eeschema/tools/sch_actions.h b/eeschema/tools/sch_actions.h index 968c287084..ca7fdf125c 100644 --- a/eeschema/tools/sch_actions.h +++ b/eeschema/tools/sch_actions.h @@ -31,6 +31,8 @@ class TOOL_EVENT; class TOOL_MANAGER; +extern char g_lastBusEntryShape; + /** * Class SCH_ACTIONS * @@ -135,6 +137,12 @@ public: static TOOL_ACTION addJunction; static TOOL_ACTION addLabel; static TOOL_ACTION addGlobalLabel; + static TOOL_ACTION toShapeSlash; + static TOOL_ACTION toShapeBackslash; + static TOOL_ACTION toLabel; + static TOOL_ACTION toHLabel; + static TOOL_ACTION toGLabel; + static TOOL_ACTION toText; /// Clipboard static TOOL_ACTION cut; diff --git a/eeschema/tools/sch_drawing_tool.cpp b/eeschema/tools/sch_drawing_tool.cpp index e5278c7672..04d0656604 100644 --- a/eeschema/tools/sch_drawing_tool.cpp +++ b/eeschema/tools/sch_drawing_tool.cpp @@ -188,6 +188,7 @@ TOOL_ACTION SCH_ACTIONS::addGlobalLabel( "eeschema.InteractiveEditing.addGlobalL SCH_DRAWING_TOOL::SCH_DRAWING_TOOL() : TOOL_INTERACTIVE( "eeschema.InteractiveDrawing" ), + m_selectionTool( nullptr ), m_view( nullptr ), m_controls( nullptr ), m_frame( nullptr ), @@ -205,6 +206,7 @@ SCH_DRAWING_TOOL::~SCH_DRAWING_TOOL() bool SCH_DRAWING_TOOL::Init() { m_frame = getEditFrame(); + m_selectionTool = m_toolMgr->GetTool(); auto activeToolCondition = [ this ] ( const SELECTION& aSel ) { return ( m_frame->GetToolId() != ID_NO_TOOL_SELECTED ); @@ -362,7 +364,7 @@ int SCH_DRAWING_TOOL::doPlaceComponent( SCH_COMPONENT* aComponent, SCHLIB_FILTER { cursorPos = m_controls->GetCursorPosition( !evt->Modifier( MD_ALT ) ); - if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsActivate() || evt->IsCancel() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( evt.get() ) ) { if( aComponent ) { @@ -430,6 +432,8 @@ int SCH_DRAWING_TOOL::doPlaceComponent( SCH_COMPONENT* aComponent, SCHLIB_FILTER m_view->ClearPreview(); m_view->AddToPreview( aComponent->Clone() ); + m_toolMgr->RunAction( SCH_ACTIONS::selectItem, true, aComponent ); + m_controls->SetCursorPosition( cursorPos, false ); } else @@ -443,12 +447,11 @@ int SCH_DRAWING_TOOL::doPlaceComponent( SCH_COMPONENT* aComponent, SCHLIB_FILTER } else if( evt->IsClick( BUT_RIGHT ) ) { - SELECTION selection; + // Warp after context menu only if dragging... + if( !aComponent ) + m_toolMgr->VetoContextMenuMouseWarp(); - if( aComponent ) - selection.Add( aComponent ); - - m_menu.ShowContextMenu( selection ); + m_menu.ShowContextMenu( m_selectionTool->GetSelection() ); } else if( aComponent && ( evt->IsAction( &SCH_ACTIONS::refreshPreview ) || evt->IsMotion() ) ) { @@ -474,7 +477,7 @@ int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent ) m_frame->SetToolID( ID_ADD_IMAGE_BUTT, wxCURSOR_PENCIL, _( "Add image" ) ); - VECTOR2I cursorPos = m_controls->GetCursorPosition(); + VECTOR2I cursorPos = m_controls->GetCursorPosition(); m_toolMgr->RunAction( SCH_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); @@ -495,7 +498,7 @@ int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent ) { cursorPos = m_controls->GetCursorPosition( !evt->Modifier( MD_ALT ) ); - if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsActivate() || evt->IsCancel() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( evt.get() ) ) { if( image ) { @@ -569,12 +572,11 @@ int SCH_DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent ) } else if( evt->IsClick( BUT_RIGHT ) ) { - SELECTION selection; + // Warp after context menu only if dragging... + if( !image ) + m_toolMgr->VetoContextMenuMouseWarp(); - if( image ) - selection.Add( image ); - - m_menu.ShowContextMenu( selection ); + m_menu.ShowContextMenu( m_selectionTool->GetSelection() ); } else if( image && ( evt->IsAction( &SCH_ACTIONS::refreshPreview ) || evt->IsMotion() ) ) { @@ -635,7 +637,7 @@ int SCH_DRAWING_TOOL::doSingleClickPlace( KICAD_T aType ) { wxPoint cursorPos = (wxPoint)m_controls->GetCursorPosition( !evt->Modifier( MD_ALT ) ); - if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsActivate() || evt->IsCancel() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( evt.get() ) ) { break; } @@ -647,18 +649,35 @@ int SCH_DRAWING_TOOL::doSingleClickPlace( KICAD_T aType ) { switch( aType ) { - case SCH_NO_CONNECT_T: item = m_frame->AddNoConnect( cursorPos ); break; - case SCH_JUNCTION_T: item = m_frame->AddJunction( cursorPos ); break; - case SCH_BUS_WIRE_ENTRY_T: item = m_frame->CreateBusWireEntry(); break; - case SCH_BUS_BUS_ENTRY_T: item = m_frame->CreateBusBusEntry(); break; - default: wxFAIL_MSG( "doSingleClickPlace(): unknown type" ); + case SCH_NO_CONNECT_T: + item = new SCH_NO_CONNECT( cursorPos ); + break; + case SCH_JUNCTION_T: + item = m_frame->AddJunction( cursorPos ); + break; + case SCH_BUS_WIRE_ENTRY_T: + item = new SCH_BUS_WIRE_ENTRY( cursorPos, g_lastBusEntryShape ); + break; + case SCH_BUS_BUS_ENTRY_T: + item = new SCH_BUS_BUS_ENTRY( cursorPos, g_lastBusEntryShape ); + break; + default: + wxFAIL_MSG( "doSingleClickPlace(): unknown type" ); } } if( item ) { + item->SetFlags( IS_NEW ); + m_frame->AddItemToScreen( item ); + m_frame->SaveCopyInUndoList( item, UR_NEW ); + m_frame->SetRepeatItem( item ); m_frame->GetScreen()->SetCurItem( item ); + + m_frame->SchematicCleanUp(); + m_frame->TestDanglingEnds(); + m_frame->OnModify(); } } else if( evt->IsClick( BUT_RIGHT ) ) @@ -719,7 +738,6 @@ int SCH_DRAWING_TOOL::PlaceSchematicText( const TOOL_EVENT& aEvent ) int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) { - SCH_SELECTION_TOOL* selTool = m_toolMgr->GetTool(); VECTOR2I cursorPos = m_controls->GetCursorPosition(); SCH_ITEM* item = nullptr; @@ -734,7 +752,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) { cursorPos = m_controls->GetCursorPosition( !evt->Modifier( MD_ALT ) ); - if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsActivate() || evt->IsCancel() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( evt.get() ) ) { if( item ) { @@ -753,6 +771,7 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) } else if( evt->IsClick( BUT_LEFT ) ) { + // First click creates... if( !item ) { m_frame->SetRepeatItem( NULL ); @@ -773,7 +792,8 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) item = m_frame->CreateNewText( LAYER_NOTES ); break; case SCH_SHEET_PIN_T: - item = selTool->SelectPoint( cursorPos, SCH_COLLECTOR::SheetsAndSheetLabels ); + item = m_selectionTool->SelectPoint( cursorPos, SCH_COLLECTOR::SheetsAndSheetLabels ); + if( item ) { if( m_frame->GetToolId() == ID_IMPORT_HLABEL_BUTT ) @@ -792,6 +812,9 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) if( item ) { + m_toolMgr->RunAction( SCH_ACTIONS::selectItem, true, item ); + + // JEY TODO: this should be handled by selection event.... MSG_PANEL_ITEMS items; item->GetMsgPanelInfo( m_frame->GetUserUnits(), items ); m_frame->SetMsgPanel( items ); @@ -803,6 +826,8 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) m_controls->SetCursorPosition( cursorPos, false ); } + + // ... and second click places: else { m_view->ClearPreview(); @@ -814,12 +839,25 @@ int SCH_DRAWING_TOOL::doTwoClickPlace( KICAD_T aType ) } else if( evt->IsClick( BUT_RIGHT ) ) { - SELECTION selection; + // Warp after context menu only if dragging... + if( !item ) + m_toolMgr->VetoContextMenuMouseWarp(); - if( item ) - selection.Add( item ); + m_menu.ShowContextMenu( m_selectionTool->GetSelection() ); + } + else if( TOOL_EVT_UTILS::IsSelectionEvent( evt.get() ) ) + { + // This happens if our text was replaced out from under us by CovertTextType() + SELECTION& selection = m_selectionTool->GetSelection(); - m_menu.ShowContextMenu( selection ); + if( selection.GetSize() == 1 ) + { + item = (SCH_ITEM*) selection.GetItem( 0 ); + m_view->ClearPreview(); + m_view->AddToPreview( item->Clone() ); + } + else + item = nullptr; } else if( item && ( evt->IsAction( &SCH_ACTIONS::refreshPreview ) || evt->IsMotion() ) ) { @@ -1116,7 +1154,7 @@ int SCH_DRAWING_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment ) { wxPoint cursorPos = (wxPoint)m_controls->GetCursorPosition( !evt->Modifier( MD_ALT ) ); - if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsActivate() || evt->IsCancel() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( evt.get() ) ) { if( aSegment || m_busUnfold.in_progress ) { @@ -1167,12 +1205,11 @@ int SCH_DRAWING_TOOL::doDrawSegments( int aType, SCH_LINE* aSegment ) } else if( evt->IsClick( BUT_RIGHT ) ) { - SELECTION selection; + // Warp after context menu only if dragging... + if( !aSegment ) + m_toolMgr->VetoContextMenuMouseWarp(); - if( aSegment ) - selection.Add( aSegment ); - - m_menu.ShowContextMenu( selection ); + m_menu.ShowContextMenu( m_selectionTool->GetSelection() ); } else if( evt->IsClick( BUT_LEFT ) || ( aSegment && evt->IsDblClick( BUT_LEFT ) ) ) { @@ -1451,7 +1488,7 @@ int SCH_DRAWING_TOOL::doDrawSheet( SCH_SHEET *aSheet ) { wxPoint cursorPos = (wxPoint)m_controls->GetCursorPosition( !evt->Modifier( MD_ALT ) ); - if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsActivate() || evt->IsCancel() ) + if( TOOL_EVT_UTILS::IsCancelInteractive( evt.get() ) ) { m_view->ClearPreview(); @@ -1560,8 +1597,11 @@ int SCH_DRAWING_TOOL::doDrawSheet( SCH_SHEET *aSheet ) } else if( evt->IsClick( BUT_RIGHT ) ) { - // JEY TODO - // m_menu.ShowContextMenu(); + // Warp after context menu only if dragging... + if( !aSheet ) + m_toolMgr->VetoContextMenuMouseWarp(); + + m_menu.ShowContextMenu( m_selectionTool->GetSelection() ); } // Enable autopanning and cursor capture only when there is a sheet to be placed diff --git a/eeschema/tools/sch_drawing_tool.h b/eeschema/tools/sch_drawing_tool.h index 23748783ba..8d3c49fc33 100644 --- a/eeschema/tools/sch_drawing_tool.h +++ b/eeschema/tools/sch_drawing_tool.h @@ -35,6 +35,7 @@ class SCH_BUS_WIRE_ENTRY; class SCH_LABEL; class SCHLIB_FILTER; class SCH_EDIT_FRAME; +class SCH_SELECTION_TOOL; /// Collection of data related to the bus unfolding tool @@ -121,15 +122,15 @@ private: void setTransitions() override; private: - KIGFX::SCH_VIEW* m_view; + SCH_SELECTION_TOOL* m_selectionTool; + KIGFX::SCH_VIEW* m_view; KIGFX::VIEW_CONTROLS* m_controls; - SCH_EDIT_FRAME* m_frame; + SCH_EDIT_FRAME* m_frame; /// Data related to bus unfolding tool. - BUS_UNFOLDING_T m_busUnfold; + BUS_UNFOLDING_T m_busUnfold; - /// Menu model displayed by the tool. - TOOL_MENU m_menu; + TOOL_MENU m_menu; }; #endif /* SCH_DRAWING_TOOL_H */ diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index e577704dfe..c3d4935252 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -115,6 +116,36 @@ TOOL_ACTION SCH_ACTIONS::showDatasheet( "eeschema.InteractiveEdit.showDatasheet" _( "Show Datasheet" ), _( "Opens the datasheet in a browser" ), datasheet_xpm ); +TOOL_ACTION SCH_ACTIONS::toShapeSlash( "eeschema.InteractiveEdit.toShapeSlash", + AS_GLOBAL, 0, + _( "Set Bus Entry Shape /" ), _( "Change the bus entry shape to /" ), + change_entry_orient_xpm ); + +TOOL_ACTION SCH_ACTIONS::toShapeBackslash( "eeschema.InteractiveEdit.toShapeBackslash", + AS_GLOBAL, 0, + _( "Set Bus Entry Shape \\" ), _( "Change the bus entry shape to \\" ), + change_entry_orient_xpm ); + +TOOL_ACTION SCH_ACTIONS::toLabel( "eeschema.InteractiveEdit.toLabel", + AS_GLOBAL, 0, + _( "Change to Label" ), _( "Change existing item to a label" ), + add_line_label_xpm ); + +TOOL_ACTION SCH_ACTIONS::toHLabel( "eeschema.InteractiveEdit.toHLabel", + AS_GLOBAL, 0, + _( "Change to Hierarchical Label" ), _( "Change existing item to a hierarchical label" ), + add_hierarchical_label_xpm ); + +TOOL_ACTION SCH_ACTIONS::toGLabel( "eeschema.InteractiveEdit.toGLabel", + AS_GLOBAL, 0, + _( "Change to Global Label" ), _( "Change existing item to a global label" ), + add_glabel_xpm ); + +TOOL_ACTION SCH_ACTIONS::toText( "eeschema.InteractiveEdit.toText", + AS_GLOBAL, 0, + _( "Change to Text" ), _( "Change existing item to a text comment" ), + text_xpm ); + TOOL_ACTION SCH_ACTIONS::doDelete( "eeschema.InteractiveEdit.doDelete", AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_DELETE ), _( "Delete" ), _( "Deletes selected item(s)" ), @@ -169,8 +200,54 @@ bool SCH_EDIT_TOOL::Init() return ( m_frame->GetToolId() == ID_NO_TOOL_SELECTED ); }; + auto orientatableCondition = [] ( const SELECTION& aSel ) { + if( aSel.Empty() ) + return false; + + if( aSel.GetSize() > 1 ) + return true; + + switch( static_cast( aSel.GetItem( 0 ) )->Type() ) + { + case SCH_MARKER_T: + case SCH_JUNCTION_T: + case SCH_NO_CONNECT_T: + case SCH_BUS_WIRE_ENTRY_T: + case SCH_BUS_BUS_ENTRY_T: + case SCH_LINE_T: + case SCH_SHEET_PIN_T: + case SCH_PIN_T: + return false; + default: + return true; + } + }; + + auto toLabelCondition = SELECTION_CONDITIONS::Count( 1 ) + && ( SELECTION_CONDITIONS::HasType( SCH_GLOBAL_LABEL_T ) + || SELECTION_CONDITIONS::HasType( SCH_HIER_LABEL_T ) + || SELECTION_CONDITIONS::HasType( SCH_TEXT_T ) ); + + auto toHLabelCondition = SELECTION_CONDITIONS::Count( 1 ) + && ( SELECTION_CONDITIONS::HasType( SCH_LABEL_T ) + || SELECTION_CONDITIONS::HasType( SCH_GLOBAL_LABEL_T ) + || SELECTION_CONDITIONS::HasType( SCH_TEXT_T ) ); + + auto toGLabelCondition = SELECTION_CONDITIONS::Count( 1 ) + && ( SELECTION_CONDITIONS::HasType( SCH_LABEL_T ) + || SELECTION_CONDITIONS::HasType( SCH_HIER_LABEL_T ) + || SELECTION_CONDITIONS::HasType( SCH_TEXT_T ) ); + + auto toTextlCondition = SELECTION_CONDITIONS::Count( 1 ) + && ( SELECTION_CONDITIONS::HasType( SCH_LABEL_T ) + || SELECTION_CONDITIONS::HasType( SCH_GLOBAL_LABEL_T ) + || SELECTION_CONDITIONS::HasType( SCH_HIER_LABEL_T ) ); + + auto entryCondition = SELECTION_CONDITIONS::HasType( SCH_BUS_WIRE_ENTRY_T ) + || SELECTION_CONDITIONS::HasType( SCH_BUS_BUS_ENTRY_T ); + auto singleComponentCondition = SELECTION_CONDITIONS::OnlyType( SCH_COMPONENT_T ) - && SELECTION_CONDITIONS::Count( 1 ); + && SELECTION_CONDITIONS::Count( 1 ); auto singleSymbolCondition = [] (const SELECTION& aSel ) { if( aSel.GetSize() == 1 ) @@ -194,17 +271,17 @@ bool SCH_EDIT_TOOL::Init() ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 ); ctxMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty ); - ctxMenu.AddItem( SCH_ACTIONS::rotateCCW, SELECTION_CONDITIONS::NotEmpty ); - ctxMenu.AddItem( SCH_ACTIONS::rotateCW, SELECTION_CONDITIONS::NotEmpty ); - ctxMenu.AddItem( SCH_ACTIONS::mirrorX, SELECTION_CONDITIONS::NotEmpty ); - ctxMenu.AddItem( SCH_ACTIONS::mirrorY, SELECTION_CONDITIONS::NotEmpty ); + ctxMenu.AddItem( SCH_ACTIONS::rotateCCW, orientatableCondition ); + ctxMenu.AddItem( SCH_ACTIONS::rotateCW, orientatableCondition ); + ctxMenu.AddItem( SCH_ACTIONS::mirrorX, orientatableCondition ); + ctxMenu.AddItem( SCH_ACTIONS::mirrorY, orientatableCondition ); ctxMenu.AddItem( SCH_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty ); ctxMenu.AddItem( SCH_ACTIONS::doDelete, SELECTION_CONDITIONS::NotEmpty ); ctxMenu.AddItem( SCH_ACTIONS::properties, SELECTION_CONDITIONS::Count( 1 ) ); ctxMenu.AddItem( SCH_ACTIONS::editReference, singleComponentCondition ); ctxMenu.AddItem( SCH_ACTIONS::editValue, singleComponentCondition ); - ctxMenu.AddItem( SCH_ACTIONS::editReference, singleComponentCondition ); + ctxMenu.AddItem( SCH_ACTIONS::editFootprint, singleComponentCondition ); ctxMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty ); ctxMenu.AddItem( SCH_ACTIONS::cut, SELECTION_CONDITIONS::NotEmpty ); @@ -218,15 +295,21 @@ bool SCH_EDIT_TOOL::Init() CONDITIONAL_MENU& drawingMenu = drawingTool->GetToolMenu().GetMenu(); ctxMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 200 ); - drawingMenu.AddItem( SCH_ACTIONS::rotateCCW, SELECTION_CONDITIONS::NotEmpty, 200 ); - drawingMenu.AddItem( SCH_ACTIONS::rotateCW, SELECTION_CONDITIONS::NotEmpty, 200 ); - drawingMenu.AddItem( SCH_ACTIONS::mirrorX, SELECTION_CONDITIONS::NotEmpty, 200 ); - drawingMenu.AddItem( SCH_ACTIONS::mirrorY, SELECTION_CONDITIONS::NotEmpty, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::rotateCCW, orientatableCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::rotateCW, orientatableCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::mirrorX, orientatableCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::mirrorY, orientatableCondition, 200 ); drawingMenu.AddItem( SCH_ACTIONS::properties, SELECTION_CONDITIONS::Count( 1 ), 200 ); drawingMenu.AddItem( SCH_ACTIONS::editReference, singleComponentCondition, 200 ); drawingMenu.AddItem( SCH_ACTIONS::editValue, singleComponentCondition, 200 ); - drawingMenu.AddItem( SCH_ACTIONS::editReference, singleComponentCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::editFootprint, singleComponentCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::toShapeSlash, entryCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::toShapeBackslash, entryCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::toLabel, toLabelCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::toHLabel, toHLabelCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::toGLabel, toGLabelCondition, 200 ); + drawingMenu.AddItem( SCH_ACTIONS::toText, toTextlCondition, 200 ); // Add editing actions to the selection tool menu // @@ -234,19 +317,25 @@ bool SCH_EDIT_TOOL::Init() selToolMenu.AddItem( SCH_ACTIONS::move, SELECTION_CONDITIONS::NotEmpty, 200 ); selToolMenu.AddItem( SCH_ACTIONS::drag, SELECTION_CONDITIONS::NotEmpty, 200 ); - selToolMenu.AddItem( SCH_ACTIONS::rotateCCW, SELECTION_CONDITIONS::NotEmpty, 200 ); - selToolMenu.AddItem( SCH_ACTIONS::rotateCW, SELECTION_CONDITIONS::NotEmpty, 200 ); - selToolMenu.AddItem( SCH_ACTIONS::mirrorX, SELECTION_CONDITIONS::NotEmpty, 200 ); - selToolMenu.AddItem( SCH_ACTIONS::mirrorY, SELECTION_CONDITIONS::NotEmpty, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::rotateCCW, orientatableCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::rotateCW, orientatableCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::mirrorX, orientatableCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::mirrorY, orientatableCondition, 200 ); selToolMenu.AddItem( SCH_ACTIONS::duplicate, SELECTION_CONDITIONS::NotEmpty, 200 ); selToolMenu.AddItem( SCH_ACTIONS::doDelete, SELECTION_CONDITIONS::NotEmpty, 200 ); selToolMenu.AddItem( SCH_ACTIONS::properties, SELECTION_CONDITIONS::Count( 1 ), 200 ); selToolMenu.AddItem( SCH_ACTIONS::editReference, singleSymbolCondition, 200 ); selToolMenu.AddItem( SCH_ACTIONS::editValue, singleSymbolCondition, 200 ); - selToolMenu.AddItem( SCH_ACTIONS::editReference, singleSymbolCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::editFootprint, singleSymbolCondition, 200 ); selToolMenu.AddItem( SCH_ACTIONS::autoplaceFields, singleComponentCondition, 200 ); selToolMenu.AddItem( SCH_ACTIONS::showDatasheet, singleSymbolCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::toShapeSlash, entryCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::toShapeBackslash, entryCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::toLabel, toLabelCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::toHLabel, toHLabelCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::toGLabel, toGLabelCondition, 200 ); + selToolMenu.AddItem( SCH_ACTIONS::toText, toTextlCondition, 200 ); selToolMenu.AddSeparator( SELECTION_CONDITIONS::NotEmpty, 200 ); selToolMenu.AddItem( SCH_ACTIONS::cut, SELECTION_CONDITIONS::NotEmpty, 200 ); @@ -435,7 +524,7 @@ int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) } } - else if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsCancel() || evt->IsActivate() ) + else if( TOOL_EVT_UTILS::IsCancelInteractive( evt.get() ) ) { if( m_moveInProgress ) restore_state = true; @@ -449,7 +538,7 @@ int SCH_EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) break; } - // Dispatch TOOL_ACTIONs + // Handle TOOL_ACTION special cases else if( evt->Category() == TC_COMMAND ) { if( evt->IsAction( &SCH_ACTIONS::doDelete ) ) @@ -1308,6 +1397,69 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent ) } +int SCH_EDIT_TOOL::ChangeShape( const TOOL_EVENT& aEvent ) +{ + SELECTION selection = m_selectionTool->GetSelection(); + char shape; + + if( aEvent.IsAction( &SCH_ACTIONS::toShapeSlash ) ) + shape = '/'; + else if( aEvent.IsAction( &SCH_ACTIONS::toShapeBackslash ) ) + shape = '\\'; + else + return 0; + + for( int i = 0; i < selection.GetSize(); ++i ) + { + SCH_BUS_ENTRY_BASE* entry = dynamic_cast( selection.GetItem( i ) ); + + if( entry ) + { + if( entry->GetEditFlags() == 0 ) + m_frame->SaveCopyInUndoList( entry, UR_CHANGED ); + + entry->SetBusEntryShape( shape ); + m_frame->TestDanglingEnds(); + + updateView( entry ); + m_frame->OnModify( ); + } + } + + g_lastBusEntryShape = shape; + + return 0; +} + + +int SCH_EDIT_TOOL::ChangeTextType( const TOOL_EVENT& aEvent ) +{ + SELECTION selection = m_selectionTool->GetSelection(); + KICAD_T type; + + if( aEvent.IsAction( &SCH_ACTIONS::toLabel ) ) + type = SCH_LABEL_T; + else if( aEvent.IsAction( &SCH_ACTIONS::toHLabel ) ) + type = SCH_HIER_LABEL_T; + else if( aEvent.IsAction( &SCH_ACTIONS::toGLabel ) ) + type = SCH_GLOBAL_LABEL_T; + else if( aEvent.IsAction( &SCH_ACTIONS::toText ) ) + type = SCH_TEXT_T; + else + return 0; + + for( int i = 0; i < selection.GetSize(); ++i ) + { + SCH_TEXT* text = dynamic_cast( selection.GetItem( i ) ); + + if( text ) + m_frame->ConvertTextType( text, type ); + } + + return 0; +} + + void SCH_EDIT_TOOL::updateView( EDA_ITEM* aItem ) { KICAD_T itemType = aItem->Type(); @@ -1340,7 +1492,7 @@ void SCH_EDIT_TOOL::setTransitions() Go( &SCH_EDIT_TOOL::Rotate, SCH_ACTIONS::rotateCCW.MakeEvent() ); Go( &SCH_EDIT_TOOL::Mirror, SCH_ACTIONS::mirrorX.MakeEvent() ); Go( &SCH_EDIT_TOOL::Mirror, SCH_ACTIONS::mirrorY.MakeEvent() ); - Go( &SCH_EDIT_TOOL::DoDelete, SCH_ACTIONS::doDelete.MakeEvent() ); + Go( &SCH_EDIT_TOOL::DoDelete, SCH_ACTIONS::doDelete.MakeEvent() ); Go( &SCH_EDIT_TOOL::DeleteItemCursor, SCH_ACTIONS::deleteItemCursor.MakeEvent() ); Go( &SCH_EDIT_TOOL::Properties, SCH_ACTIONS::properties.MakeEvent() ); @@ -1350,4 +1502,10 @@ void SCH_EDIT_TOOL::setTransitions() Go( &SCH_EDIT_TOOL::AutoplaceFields, SCH_ACTIONS::autoplaceFields.MakeEvent() ); Go( &SCH_EDIT_TOOL::ShowDatasheet, SCH_ACTIONS::showDatasheet.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeShape, SCH_ACTIONS::toShapeSlash.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeShape, SCH_ACTIONS::toShapeBackslash.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeTextType, SCH_ACTIONS::toLabel.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeTextType, SCH_ACTIONS::toHLabel.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeTextType, SCH_ACTIONS::toGLabel.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeTextType, SCH_ACTIONS::toText.MakeEvent() ); } diff --git a/eeschema/tools/sch_edit_tool.h b/eeschema/tools/sch_edit_tool.h index 30d7e23ec1..f084144f06 100644 --- a/eeschema/tools/sch_edit_tool.h +++ b/eeschema/tools/sch_edit_tool.h @@ -69,6 +69,9 @@ public: int AutoplaceFields( const TOOL_EVENT& aEvent ); int ShowDatasheet( const TOOL_EVENT& aEvent ); + int ChangeShape( const TOOL_EVENT& aEvent ); + int ChangeTextType( const TOOL_EVENT& aEvent ); + /** * Function DoDelete() * diff --git a/eeschema/tools/sch_picker_tool.cpp b/eeschema/tools/sch_picker_tool.cpp index 6e3c54303e..e791d07aba 100644 --- a/eeschema/tools/sch_picker_tool.cpp +++ b/eeschema/tools/sch_picker_tool.cpp @@ -77,7 +77,7 @@ int SCH_PICKER_TOOL::Main( const TOOL_EVENT& aEvent ) setControls(); } - else if( evt->IsAction( &ACTIONS::cancelInteractive ) || evt->IsActivate() || evt->IsCancel() ) + else if( TOOL_EVT_UTILS::IsCancelInteractive( evt.get() ) ) { if( m_cancelHandler ) { diff --git a/include/tool/tool_event.h b/include/tool/tool_event.h index 191336a66c..7b47c3af1c 100644 --- a/include/tool/tool_event.h +++ b/include/tool/tool_event.h @@ -610,6 +610,7 @@ private: std::deque m_events; }; + inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEventA, const TOOL_EVENT& aEventB ) { TOOL_EVENT_LIST l; @@ -620,6 +621,7 @@ inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEventA, const TOOL_E return l; } + inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEvent, const TOOL_EVENT_LIST& aEventList ) { @@ -629,4 +631,34 @@ inline const TOOL_EVENT_LIST operator||( const TOOL_EVENT& aEvent, return l; } + +/** + * Namespace TOOL_EVT_UTILS + * + * Utility functions for dealing with various tool events. These are + * free functions, so they interface with any classes exclusively via + * the public interfaces, so they don't need to be subsumed into the + * "helped" classes. + */ +namespace TOOL_EVT_UTILS +{ + /** + * Function IsCancelInteractive() + * + * @return true if this event should restart/end an ongoing interactive + * tool's event loop (eg esc key, click cancel, start different + * tool) + */ + bool IsCancelInteractive( const TOOL_EVENT& aEvt ); + + /** + * Function IsSelectionEvent() + * + * Indicates an selection-changed notification event. + */ + bool IsSelectionEvent( const TOOL_EVENT& aEvt ); + +} + + #endif diff --git a/pcbnew/tools/tool_event_utils.cpp b/pcbnew/tools/tool_event_utils.cpp index 7abe83a989..03d3364ac7 100644 --- a/pcbnew/tools/tool_event_utils.cpp +++ b/pcbnew/tools/tool_event_utils.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. - * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2019 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 @@ -22,17 +22,9 @@ */ #include - #include - #include -bool TOOL_EVT_UTILS::IsCancelInteractive( const TOOL_EVENT& aEvt ) -{ - return aEvt.IsAction( &ACTIONS::cancelInteractive ) - || aEvt.IsActivate() - || aEvt.IsCancel(); -} bool TOOL_EVT_UTILS::IsRotateToolEvt( const TOOL_EVENT& aEvt ) { diff --git a/pcbnew/tools/tool_event_utils.h b/pcbnew/tools/tool_event_utils.h index c8331625c1..5f104829c9 100644 --- a/pcbnew/tools/tool_event_utils.h +++ b/pcbnew/tools/tool_event_utils.h @@ -40,15 +40,6 @@ class PCB_BASE_EDIT_FRAME; */ namespace TOOL_EVT_UTILS { - /** - * Function IsCancelInteractive() - * - * @return true if this event should restart/end an ongoing interactive - * tool's event loop (eg esc key, click cancel, start different - * tool) - */ - bool IsCancelInteractive( const TOOL_EVENT& aEvt ); - /** * Function isRotateToolEvt() *