kicad/eeschema/schedit.cpp

201 lines
6.6 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008-2017 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-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
* 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
*/
#include <fctsys.h>
#include <kiway.h>
#include <gr_basic.h>
#include <sch_draw_panel.h>
#include <confirm.h>
#include <sch_edit_frame.h>
#include <hotkeys_basic.h>
#include <general.h>
#include <eeschema_id.h>
#include <list_operations.h>
#include <class_library.h>
#include <sch_bus_entry.h>
#include <sch_marker.h>
#include <sch_component.h>
#include <sch_junction.h>
#include <sch_line.h>
#include <sch_sheet.h>
#include <sch_sheet_path.h>
#include <sch_view.h>
#include <tool/tool_manager.h>
#include <tools/sch_actions.h>
#include <tools/sch_selection_tool.h>
void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
int id = event.GetId();
wxPoint pos;
SCH_SCREEN* screen = GetScreen();
SCH_ITEM* item = screen->GetCurItem();
pos = wxGetMousePosition();
pos.y += 20;
switch( id )
{
case ID_HIERARCHY:
SetNoToolSelected();
InstallHierarchyFrame( pos );
SetRepeatItem( NULL );
break;
case ID_POPUP_SCH_CLEANUP_SHEET:
if( item != NULL && item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = (SCH_SHEET*) item;
if( !sheet->HasUndefinedPins() )
{
DisplayInfoMessage( this, _( "There are no undefined labels in this sheet to clean up." ) );
return;
}
if( !IsOK( this, _( "Do you wish to cleanup this sheet?" ) ) )
return;
/* Save sheet in undo list before cleaning up unreferenced hierarchical labels. */
SaveCopyInUndoList( sheet, UR_CHANGED );
sheet->CleanupSheet();
SyncView();
GetCanvas()->Refresh();
OnModify();
}
break;
default: // Log error:
wxFAIL_MSG( wxString::Format( "Cannot process command event ID %d", event.GetId() ) );
break;
}
}
void SCH_EDIT_FRAME::OnUnfoldBus( wxCommandEvent& event )
{
wxMenuItem* item = static_cast<wxMenuItem*>( event.GetEventUserData() );
wxString net = item->GetItemLabelText();
GetToolManager()->RunAction( SCH_ACTIONS::unfoldBus, true, &net );
// Now that we have handled the chosen bus unfold, disconnect all the events so they can be
// recreated with updated data on the next unfold
Unbind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus, this );
}
void SCH_EDIT_FRAME::OnUnfoldBusHotkey( wxCommandEvent& aEvent )
{
SCH_SELECTION_TOOL* selTool = GetToolManager()->GetTool<SCH_SELECTION_TOOL>();
EDA_HOTKEY_CLIENT_DATA* data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
SCH_ITEM* item = GetScreen()->GetCurItem();
wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
if( item == NULL )
{
// If we didn't get here by a hot key, then something has gone wrong.
if( aEvent.GetInt() == 0 )
return;
item = selTool->SelectPoint( data->GetPosition(), SCH_COLLECTOR::EditableItems );
// Exit if no item found at the current location or the item is already being edited.
if( item == NULL || item->GetEditFlags() != 0 )
return;
}
if( item->Type() != SCH_LINE_T )
return;
wxMenu* bus_unfold_menu = GetUnfoldBusMenu( static_cast<SCH_LINE*>( item ) );
if( bus_unfold_menu )
{
auto controls = GetCanvas()->GetViewControls();
auto vmp = controls->GetMousePosition( false );
wxPoint mouse_pos( (int) vmp.x, (int) vmp.y );
GetGalCanvas()->PopupMenu( bus_unfold_menu, mouse_pos );
}
}
wxMenu* SCH_EDIT_FRAME::GetUnfoldBusMenu( SCH_LINE* aBus )
{
auto connection = aBus->Connection( *g_CurrentSheet );
if( !connection || !connection->IsBus() || connection->Members().empty() )
return nullptr;
int idx = 0;
wxMenu* bus_unfolding_menu = new wxMenu;
for( const auto& member : connection->Members() )
{
int id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
wxString name = member->Name( true );
if( member->Type() == CONNECTION_BUS )
{
wxMenu* submenu = new wxMenu;
bus_unfolding_menu->AppendSubMenu( submenu, _( name ) );
for( const auto& sub_member : member->Members() )
{
id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
submenu->Append( id, sub_member->Name( true ), wxEmptyString );
// See comment in else clause below
auto sub_item_clone = new wxMenuItem();
sub_item_clone->SetItemLabel( sub_member->Name( true ) );
Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus, this, id, id,
sub_item_clone );
}
}
else
{
bus_unfolding_menu->Append( id, name, wxEmptyString );
// Because Bind() takes ownership of the user data item, we
// make a new menu item here and set its label. Why create a
// menu item instead of just a wxString or something? Because
// Bind() requires a pointer to wxObject rather than a void
// pointer. Maybe at some point I'll think of a better way...
auto item_clone = new wxMenuItem();
item_clone->SetItemLabel( name );
Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus, this, id, id,
item_clone );
}
}
return bus_unfolding_menu;
}