Re-write IntersheetRefs on top of SCH_FIELDs and textVars.

1) Generalize SCH_ITEM owners (SCH_COMPONENT, SCH_SHEET, and now
SCH_GLOBALLABEL)
2) Generalize hypertext items
3) Use SCH_FIELD autoplace infrastructure for placing intersheet
references
4) Use textVar infrastructure for buildin intersheet references.

As an important side-effect this also fixes the undo issues with
intersheet refs.
This commit is contained in:
Jeff Young 2020-11-17 16:02:47 +00:00
parent d616d5ad1f
commit 8c5c902fa3
37 changed files with 557 additions and 801 deletions

View File

@ -235,7 +235,6 @@ set( EESCHEMA_SRCS
toolbars_lib_view.cpp
toolbars_sch_editor.cpp
transform.cpp
sch_iref.cpp
netlist_exporters/netlist_exporter_base.cpp
netlist_exporters/netlist_exporter_cadstar.cpp

View File

@ -63,6 +63,9 @@
///< The default text size in mils. (can be changed in preference menu)
#define DEFAULT_TEXT_SIZE 50
///< Ratio of the font height to the baseline of the text above the wire.
#define DEFAULT_TEXT_OFFSET_RATIO 0.08
///< The offset of the pin name string from the end of the pin in mils.
#define DEFAULT_PIN_NAME_OFFSET 20

View File

@ -33,13 +33,11 @@
#include <sch_component.h>
#include <sch_reference_list.h>
#include <schematic.h>
#include <widgets/unit_binder.h>
#include <dialogs/html_messagebox.h>
#include <dialog_edit_label.h>
#include <kicad_string.h>
#include <tool/actions.h>
#include <scintilla_tricks.h>
#include <sch_iref.h>
class SCH_EDIT_FRAME;
class SCH_TEXT;
@ -348,14 +346,7 @@ bool DIALOG_LABEL_EDITOR::TransferDataFromWindow()
if( m_CurrentText->Type() == SCH_GLOBAL_LABEL_T )
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( m_CurrentText );
SCH_IREF* iref = label->GetIref();
if( iref )
{
if( iref->GetBoundingBox().Intersects( label->GetBoundingBox() ) )
iref->PlaceAtDefaultPosition();
iref->CopyParentStyle();
}
label->UpdateIntersheetRefProps();
}
return true;

View File

@ -70,11 +70,11 @@ bool PANEL_SETUP_FORMATTING::TransferDataToWindow()
m_pinSymbolSize.SetValue( settings.m_PinSymbolSize );
m_choiceJunctionDotSize->SetSelection( settings.m_JunctionSizeChoice );
m_showIntersheetsReferences->SetValue( settings.m_IntersheetsRefShow );
m_radioFormatStandard->SetValue( !settings.m_IntersheetsRefFormatShort );
m_radioFormatAbbreviated->SetValue( settings.m_IntersheetsRefFormatShort );
m_prefixCtrl->ChangeValue( settings.m_IntersheetsRefPrefix );
m_suffixCtrl->ChangeValue( settings.m_IntersheetsRefSuffix );
m_showIntersheetsReferences->SetValue( settings.m_IntersheetRefsShow );
m_radioFormatStandard->SetValue( !settings.m_IntersheetRefsFormatShort );
m_radioFormatAbbreviated->SetValue( settings.m_IntersheetRefsFormatShort );
m_prefixCtrl->ChangeValue( settings.m_IntersheetRefsPrefix );
m_suffixCtrl->ChangeValue( settings.m_IntersheetRefsSuffix );
wxString offsetRatio = wxString::Format( "%f", settings.m_TextOffsetRatio * 100.0 );
m_textOffsetRatioCtrl->SetValue( offsetRatio );
@ -142,10 +142,10 @@ bool PANEL_SETUP_FORMATTING::TransferDataFromWindow()
settings.m_JunctionSize = currJunctionDotSize;
settings.m_IntersheetsRefShow = m_showIntersheetsReferences->GetValue();
settings.m_IntersheetsRefFormatShort = !m_radioFormatStandard->GetValue();
settings.m_IntersheetsRefPrefix = m_prefixCtrl->GetValue();
settings.m_IntersheetsRefSuffix = m_suffixCtrl->GetValue();
settings.m_IntersheetRefsShow = m_showIntersheetsReferences->GetValue();
settings.m_IntersheetRefsFormatShort = !m_radioFormatStandard->GetValue();
settings.m_IntersheetRefsPrefix = m_prefixCtrl->GetValue();
settings.m_IntersheetRefsSuffix = m_suffixCtrl->GetValue();
double dtmp = 0.0;
wxString msg = m_textOffsetRatioCtrl->GetValue();
@ -171,11 +171,11 @@ void PANEL_SETUP_FORMATTING::ImportSettingsFrom( SCHEMATIC_SETTINGS& aSettings )
m_lineWidth.SetValue( aSettings.m_DefaultLineWidth );
m_pinSymbolSize.SetValue( aSettings.m_PinSymbolSize );
m_showIntersheetsReferences->SetValue( aSettings.m_IntersheetsRefShow );
m_radioFormatStandard->SetValue( aSettings.m_IntersheetsRefFormatShort );
m_radioFormatAbbreviated->SetValue( !aSettings.m_IntersheetsRefFormatShort );
m_prefixCtrl->ChangeValue( aSettings.m_IntersheetsRefPrefix );
m_suffixCtrl->ChangeValue( aSettings.m_IntersheetsRefSuffix );
m_showIntersheetsReferences->SetValue( aSettings.m_IntersheetRefsShow );
m_radioFormatStandard->SetValue( aSettings.m_IntersheetRefsFormatShort );
m_radioFormatAbbreviated->SetValue( !aSettings.m_IntersheetRefsFormatShort );
m_prefixCtrl->ChangeValue( aSettings.m_IntersheetRefsPrefix );
m_suffixCtrl->ChangeValue( aSettings.m_IntersheetRefsSuffix );
wxString offsetRatio = wxString::Format( "%f", aSettings.m_TextOffsetRatio * 100.0 );
m_textOffsetRatioCtrl->SetValue( offsetRatio );

View File

@ -71,9 +71,10 @@ const KICAD_T EE_COLLECTOR::SheetsOnly[] = {
};
const KICAD_T EE_COLLECTOR::ComponentsOrSheets[] = {
const KICAD_T EE_COLLECTOR::FieldOwners[] = {
SCH_COMPONENT_T,
SCH_SHEET_T,
SCH_GLOBAL_LABEL_T,
EOT
};
@ -122,6 +123,7 @@ void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], co
// they're not in the filter list
bool componentsVisited = false;
bool sheetsVisited = false;
bool globalLabelsVisited = false;
for( const KICAD_T* filter = aFilterList; *filter != EOT; ++filter )
{
@ -133,6 +135,9 @@ void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], co
if( *filter == SCH_SHEET_T || *filter == SCH_LOCATE_ANY_T )
sheetsVisited = true;
if( *filter == SCH_GLOBAL_LABEL_T || *filter == SCH_LOCATE_ANY_T )
globalLabelsVisited = true;
item->Visit( m_inspector, nullptr, m_scanTypes );
}
}
@ -148,6 +153,12 @@ void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], co
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_SHEET_T ) )
item->Visit( m_inspector, nullptr, m_scanTypes );
}
if( !globalLabelsVisited )
{
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_GLOBAL_LABEL_T ) )
item->Visit( m_inspector, nullptr, m_scanTypes );
}
}
}
@ -164,7 +175,7 @@ void EE_COLLECTOR::Collect( LIB_ITEMS_CONTAINER& aItems, const KICAD_T aFilterLi
// remember where the snapshot was taken from and pass refPos to the Inspect() function.
SetRefPos( aPos );
for( auto& item : aItems )
for( LIB_ITEM& item : aItems )
{
if( item.Visit( m_inspector, nullptr, m_scanTypes ) == SEARCH_RESULT::QUIT )
break;

View File

@ -46,7 +46,7 @@ public:
static const KICAD_T EditableItems[];
static const KICAD_T ComponentsOnly[];
static const KICAD_T SheetsOnly[];
static const KICAD_T ComponentsOrSheets[];
static const KICAD_T FieldOwners[];
EE_COLLECTOR( const KICAD_T* aScanTypes = EE_COLLECTOR::AllItems ) :
m_Unit( 0 ),

View File

@ -301,10 +301,10 @@ void SCH_BASE_FRAME::UpdateItem( EDA_ITEM* aItem, bool isAddOrDelete )
if( !isAddOrDelete )
GetCanvas()->GetView()->Update( aItem );
// Component children are drawn from their parents. Mark them for re-paint.
if( parent && parent->Type() == SCH_COMPONENT_T )
GetCanvas()->GetView()->Update( parent, KIGFX::REPAINT );
else if( parent && parent->Type() == SCH_SHEET_T )
// Some children are drawn from their parents. Mark them for re-paint.
static KICAD_T parentTypes[] = { SCH_COMPONENT_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT };
if( parent && parent->IsType( parentTypes ) )
GetCanvas()->GetView()->Update( parent, KIGFX::REPAINT );
}

View File

@ -793,6 +793,16 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
}
void SCH_COMPONENT::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
{
for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
aFunction( pin.get() );
for( SCH_FIELD& field : m_fields )
aFunction( &field );
}
SCH_PIN* SCH_COMPONENT::GetPin( const wxString& aNumber )
{
for( const std::unique_ptr<SCH_PIN>& pin : m_pins )

View File

@ -454,6 +454,8 @@ public:
*/
void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override;
void RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction ) override;
//-----</Fields>----------------------------------------------------------

View File

@ -45,9 +45,7 @@
#include <project/project_file.h>
#include <project/net_settings.h>
#include <sch_edit_frame.h>
#include <sch_iref.h>
#include <sch_painter.h>
#include <sch_view.h>
#include <sch_sheet.h>
#include <schematic.h>
#include <settings/settings_manager.h>
@ -1234,182 +1232,99 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
timer.Stop();
wxLogTrace( "CONN_PROFILE", "SchematicCleanUp() %0.4f ms", timer.msecs() );
if( settings.m_IntersheetsRefShow == true )
if( settings.m_IntersheetRefsShow == true )
RecomputeIntersheetsRefs();
Schematic().ConnectionGraph()->Recalculate( list, true );
}
int SCH_EDIT_FRAME::RecomputeIntersheetsRefs()
{
SCHEMATIC_SETTINGS& settings = Schematic().Settings();
std::vector<wxString> pagesNumbers;
SCH_GLOBALLABEL* gLabel;
SCH_IREF* iref;
std::map<wxString, std::set<wxString>>& pageRefsMap = Schematic().GetPageRefsMap();
m_labelTable.clear();
pageRefsMap.clear();
SCH_SCREENS screens( Schematic().Root() );
std::vector<wxString> pageNumbers;
/* Iterate over screens */
for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
{
pagesNumbers.clear();
pageNumbers.clear();
/* Find in which sheets this screen is used */
for( const SCH_SHEET_PATH& sheet : Schematic().GetSheets() )
{
if( sheet.LastScreen() == screen )
pagesNumbers.push_back( sheet.GetPageNumber() );
pageNumbers.push_back( sheet.GetPageNumber() );
}
for( SCH_ITEM* item : screen->Items() )
{
if( item->Type() == SCH_GLOBAL_LABEL_T )
{
gLabel = static_cast<SCH_GLOBALLABEL*>( item );
m_labelTable.push_back( gLabel );
SCH_GLOBALLABEL* globalLabel = static_cast<SCH_GLOBALLABEL*>( item );
std::set<wxString>& pageList = pageRefsMap[ globalLabel->GetText() ];
if( gLabel->GetIref() == nullptr )
{
iref = new SCH_IREF();
gLabel->SetIref( iref );
iref->SetParentLabel( gLabel );
iref->SetFlags( IS_NEW );
iref->SetScreen( screen );
if( gLabel->GetIrefSavedPosition() != wxDefaultPosition )
iref->SetPosition( gLabel->GetIrefSavedPosition() );
else
iref->PlaceAtDefaultPosition();
iref->CopyParentStyle();
}
else
{
iref = gLabel->GetIref();
wxCHECK2( iref, continue );
}
iref->GetRefTable().clear();
iref->GetRefTable().insert( iref->GetRefTable().end(),
pagesNumbers.begin(),
pagesNumbers.end() );
for( const wxString& pageNo : pageNumbers )
pageList.insert( pageNo );
}
}
}
/* Fill intersheets references for each global label */
for( SCH_GLOBALLABEL* item : m_labelTable )
{
for( SCH_GLOBALLABEL* iter : m_labelTable )
{
if( iter->GetText().IsSameAs( item->GetText() ) && ( iter != item ) )
{
iter->GetIref()->GetRefTable().insert( iter->GetIref()->GetRefTable().end(),
item->GetIref()->GetRefTable().begin(),
item->GetIref()->GetRefTable().end() );
}
}
}
bool show = Schematic().Settings().m_IntersheetRefsShow;
/* Refresh all global labels */
for( SCH_GLOBALLABEL* item : m_labelTable )
for( EDA_ITEM* item : GetScreen()->Items() )
{
wxString text, tmp;
iref = item->GetIref();
wxCHECK2( iref, continue );
std::sort( iref->GetRefTable().begin(), iref->GetRefTable().end() );
iref->GetRefTable().erase( std::unique( iref->GetRefTable().begin(),
iref->GetRefTable().end() ),
iref->GetRefTable().end() );
text.Printf( "%s", settings.m_IntersheetsRefPrefix );
if( ( settings.m_IntersheetsRefFormatShort ) && ( iref->GetRefTable().size() > 2 ) )
if( item->Type() == SCH_GLOBAL_LABEL_T )
{
tmp.Printf( "%s..%s", iref->GetRefTable().front(), iref->GetRefTable().back() );
text.Append( tmp );
SCH_GLOBALLABEL* global = static_cast<SCH_GLOBALLABEL*>( item );
global->GetIntersheetRefs()->SetVisible( show );
if( show )
GetCanvas()->GetView()->Update( global );
}
else
{
for( wxString ref : iref->GetRefTable() )
{
tmp.Printf( "%s,", ref );
text.Append( tmp );
}
if( text.Last() == ',' )
text.RemoveLast();
}
text.Append( settings.m_IntersheetsRefSuffix );
iref->SetText( text );
SCH_SCREEN* screen = iref->GetScreen();
if( !screen->CheckIfOnDrawList( iref ) )
AddToScreen( iref, screen );
iref->ClearFlags( IS_NEW );
screen->SetModify();
Refresh( iref );
iref->ClearEditFlags();
GetCanvas()->Refresh();
}
return 0;
}
void SCH_EDIT_FRAME::RemoveAllIntersheetsRefs()
{
SCH_SHEET_LIST sheets = Schematic().GetSheets();
std::vector<SCH_IREF*> irefList;
SCH_GLOBALLABEL* gLabel;
void SCH_EDIT_FRAME::ShowAllIntersheetRefs( bool aShow )
{
SCH_SCREENS screens( Schematic().Root() );
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
{
for( SCH_ITEM* item : screen->Items() )
{
if( item->Type() == SCH_GLOBAL_LABEL_T )
{
gLabel = (SCH_GLOBALLABEL*)( item );
SCH_IREF* iref = gLabel->GetIref();
SCH_GLOBALLABEL* gLabel = (SCH_GLOBALLABEL*)( item );
SCH_FIELD* intersheetRef = gLabel->GetIntersheetRefs();
if( iref )
{
gLabel->SetIref( nullptr );
gLabel->SetIrefSavedPosition( wxDefaultPosition );
irefList.push_back( iref );
}
}
}
}
intersheetRef->SetVisible( aShow );
for( SCH_IREF* iref : irefList )
RemoveFromScreen( iref, iref->GetScreen() );
if( aShow )
AddToScreen( intersheetRef, screen );
else
RemoveFromScreen( intersheetRef, screen );
}
}
}
}
void SCH_EDIT_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
{
SCHEMATIC_SETTINGS& settings = Schematic().Settings();
SCH_BASE_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
if( settings.m_IntersheetsRefShow == false )
RemoveAllIntersheetsRefs();
else
RecomputeIntersheetsRefs();
ShowAllIntersheetRefs( settings.m_IntersheetRefsShow );
GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL );
GetCanvas()->Refresh();

View File

@ -133,10 +133,6 @@ private:
DIALOG_SCH_FIND* m_findReplaceDialog;
static PINSHEETLABEL_SHAPE m_lastSheetPinType; ///< Last sheet pin type.
std::vector<SCH_GLOBALLABEL*> m_labelTable;
protected:
/**
* Save the schematic files that have been modified and not yet saved.
@ -923,7 +919,7 @@ public:
int RecomputeIntersheetsRefs();
void RemoveAllIntersheetsRefs();
void ShowAllIntersheetRefs( bool aShow );
DECLARE_EVENT_TABLE()
};

View File

@ -22,7 +22,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* Fields are texts attached to a component, having a special meaning
/*
* Fields are texts attached to a component, having a special meaning
* Fields 0 and 1 are very important: reference and value
* Field 2 is used as default footprint name.
* Field 3 is reserved (not currently used
@ -30,6 +31,7 @@
* They can be renamed and can appear in reports
*/
#include <wx/menu.h>
#include <eda_item.h>
#include <gr_text.h>
#include <sch_edit_frame.h>
@ -45,7 +47,9 @@
#include <kicad_string.h>
#include <trace_helpers.h>
#include <trigo.h>
#include <eeschema_id.h>
#include <tool/tool_manager.h>
#include <tools/ee_actions.h>
SCH_FIELD::SCH_FIELD( const wxPoint& aPos, int aFieldId, SCH_ITEM* aParent,
const wxString& aName ) :
@ -93,7 +97,6 @@ void SCH_FIELD::SetId( int aId )
default: SetLayer( LAYER_FIELDS ); break;
}
}
}
@ -131,6 +134,13 @@ wxString SCH_FIELD::GetShownText( int aDepth ) const
return sheet->ResolveTextVar( token, aDepth + 1 );
};
std::function<bool( wxString* )> globalLabelResolver =
[&]( wxString* token ) -> bool
{
SCH_GLOBALLABEL* globalLabel = static_cast<SCH_GLOBALLABEL*>( m_parent );
return globalLabel->ResolveTextVar( token, aDepth + 1 );
};
PROJECT* project = nullptr;
bool processTextVars = false;
wxString text = EDA_TEXT::GetShownText( &processTextVars );
@ -146,6 +156,8 @@ wxString SCH_FIELD::GetShownText( int aDepth ) const
text = ExpandTextVars( text, &symbolResolver, project );
else if( m_parent && m_parent->Type() == SCH_SHEET_T )
text = ExpandTextVars( text, &sheetResolver, project );
else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
text = ExpandTextVars( text, &globalLabelResolver, project );
else
text = ExpandTextVars( text, nullptr, project );
}
@ -371,6 +383,10 @@ bool SCH_FIELD::IsReplaceable() const
if( m_id == SHEETFILENAME )
return false;
}
else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
{
return false;
}
return true;
}
@ -436,6 +452,54 @@ wxString SCH_FIELD::GetSelectMenuText( EDA_UNITS aUnits ) const
}
void SCH_FIELD::DoHypertextMenu( EDA_DRAW_FRAME* aFrame )
{
static wxString back = "HYPERTEXT_BACK";
wxMenu menu;
SCH_TEXT* label = dynamic_cast<SCH_TEXT*>( m_parent );
if( label && Schematic() )
{
auto it = Schematic()->GetPageRefsMap().find( label->GetText() );
if( it != Schematic()->GetPageRefsMap().end() )
{
std::map<wxString, wxString> sheetNames;
std::vector<wxString> pageListCopy;
pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
std::sort( pageListCopy.begin(), pageListCopy.end() );
for( const SCH_SHEET_PATH& sheet : Schematic()->GetSheets() )
sheetNames[ sheet.GetPageNumber() ] = sheet.Last()->GetName();
for( const wxString& pageNo : pageListCopy )
{
wxString pageName = pageNo == "/" ? _( "Root" ) : sheetNames[ pageNo ];
menu.Append( -1, wxString::Format( _( "Go to Page %s (%s)" ),
pageNo,
pageName ) );
}
menu.AppendSeparator();
menu.Append( -1, _( "Back" ) );
int sel = aFrame->GetPopupMenuSelectionFromUser( menu );
void* param = nullptr;
if( sel >= 1 && sel <= (int) pageListCopy.size() )
param = (void*) &pageListCopy[ sel - 1 ];
else if( sel == (int) pageListCopy.size() )
param = (void*) &back;
if( param )
aFrame->GetToolManager()->RunAction( EE_ACTIONS::hypertextCommand, true, param );
}
}
}
wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
{
if( !m_name.IsEmpty() )
@ -446,6 +510,8 @@ wxString SCH_FIELD::GetName( bool aUseDefaultName ) const
return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id );
else if( m_parent && m_parent->Type() == SCH_SHEET_T )
return SCH_SHEET::GetDefaultFieldName( m_id );
else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
return _( "Intersheet References" );
}
return wxEmptyString;
@ -472,6 +538,10 @@ wxString SCH_FIELD::GetCanonicalName() const
case SHEETFILENAME: return wxT( "Sheetfile" );
}
}
else if( m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T )
{
return wxT( "Intersheet References" );
}
return m_name;
}

View File

@ -31,7 +31,6 @@
#include <template_fieldnames.h>
#include <general.h>
class SCH_EDIT_FRAME;
class SCH_COMPONENT;
class LIB_FIELD;
@ -93,6 +92,13 @@ public:
return false;
}
bool IsHypertext() const override
{
return m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T;
}
void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) override;
/**
* Function GetName
* returns the field name.

View File

@ -1,146 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019-2020 Franck Jullien, franck.jullien at gmail.com
* Copyright (C) 2019-2020 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 <sch_text.h>
#include <sch_iref.h>
#include <schematic.h>
#include <tool/tool_manager.h>
#include <tools/sch_editor_control.h>
#include <tools/sch_navigate_tool.h>
SCH_IREF::SCH_IREF( const wxPoint& pos, const wxString& text, SCH_GLOBALLABEL* aParent ) :
SCH_TEXT( pos, text, SCH_IREF_T )
{
m_layer = LAYER_GLOBLABEL;
m_parentLabel = aParent;
SetMultilineAllowed( false );
m_screen = nullptr;
}
void SCH_IREF::PlaceAtDefaultPosition()
{
wxPoint offset;
int labelLen = m_parentLabel->GetBoundingBox().GetSizeMax();
switch( m_parentLabel->GetLabelSpinStyle() )
{
default:
case LABEL_SPIN_STYLE::LEFT: offset.x -= labelLen; break;
case LABEL_SPIN_STYLE::UP: offset.y -= labelLen; break;
case LABEL_SPIN_STYLE::RIGHT: offset.x += labelLen; break;
case LABEL_SPIN_STYLE::BOTTOM: offset.y += labelLen; break;
}
SetTextPos( m_parentLabel->GetPosition() + offset );
}
wxPoint SCH_IREF::GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const
{
return m_parentLabel->GetSchematicTextOffset( aSettings );
}
EDA_ITEM* SCH_IREF::Clone() const
{
return new SCH_IREF( *this );
}
void SCH_IREF::SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle )
{
wxPoint pt = GetTextPos() - m_parentLabel->GetPosition();
int offset = std::max( abs( pt.x ), abs( pt.y ) );
switch( aSpinStyle )
{
case LABEL_SPIN_STYLE::RIGHT:
SetTextAngle( TEXT_ANGLE_HORIZ );
SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
pt.y = 0;
pt.x = offset;
break;
case LABEL_SPIN_STYLE::UP:
SetTextAngle( TEXT_ANGLE_VERT );
SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
pt.y = -offset;
pt.x = 0;
break;
case LABEL_SPIN_STYLE::LEFT:
SetTextAngle( TEXT_ANGLE_HORIZ );
SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
pt.y = 0;
pt.x = -offset;
break;
case LABEL_SPIN_STYLE::BOTTOM:
SetTextAngle( TEXT_ANGLE_VERT );
SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
pt.y = offset;
pt.x = 0;
break;
}
SetPosition( m_parentLabel->GetPosition() + pt );
}
void SCH_IREF::CopyParentStyle()
{
SetTextSize( m_parentLabel->GetTextSize() );
SetItalic( m_parentLabel->IsItalic() );
SetBold( m_parentLabel->IsBold() );
SetTextThickness( m_parentLabel->GetTextThickness() );
SetIrefOrientation( m_parentLabel->GetLabelSpinStyle() );
}
void SCH_IREF::BuildHypertextMenu( wxMenu* aMenu )
{
std::map<wxString, wxString> sheetNames;
for( const SCH_SHEET_PATH& sheet : Schematic()->GetSheets() )
sheetNames[ sheet.GetPageNumber() ] = sheet.Last()->GetName();
int id = ID_HYPERTEXT_BACK;
for( wxString& i : m_refTable )
{
aMenu->Append( id, wxString::Format( _( "Go to Page %s (%s)" ),
i,
i == "/" ? _( "Root" ) : sheetNames[ i ] ) );
id++;
}
aMenu->AppendSeparator();
aMenu->Append( ID_HYPERTEXT_BACK, _( "Back" ) );
}

View File

@ -1,88 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2020 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
*/
/**
* @file sch_iref.h
* @brief Definitions of the SCH_IREF class and derivatives for Eeschema.
*/
#ifndef CLASS_IREF_H
#define CLASS_IREF_H
#include <sch_text.h>
class SCH_GLOBALLABEL;
class SCH_IREF : public SCH_TEXT
{
public:
SCH_IREF( const wxPoint& pos = wxPoint( 0, 0 ), const wxString& text = wxEmptyString,
SCH_GLOBALLABEL* aParent = nullptr );
~SCH_IREF() { }
static inline bool ClassOf( const EDA_ITEM* aItem )
{
return aItem && SCH_IREF_T == aItem->Type();
}
wxString GetClass() const override
{
return wxT( "SCH_IREF" );
}
EDA_ITEM* Clone() const override;
std::vector<wxString>& GetRefTable() { return m_refTable; }
bool IsDangling() const override { return false; }
void CopyParentStyle();
void PlaceAtDefaultPosition();
wxPoint GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const override;
SCH_GLOBALLABEL* GetParentLabel() { return m_parentLabel; }
void SetParentLabel( SCH_GLOBALLABEL* parent ) { m_parentLabel = parent; }
SCH_SCREEN* GetScreen() { return m_screen; }
void SetScreen( SCH_SCREEN* screen ) { m_screen = screen; }
void BuildHypertextMenu( wxMenu* aMenu );
private:
void SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle );
// We create a different set parent function for this class, so we hide
// the inherited one.
using EDA_ITEM::SetParent;
std::vector<wxString> m_refTable;
SCH_GLOBALLABEL* m_parentLabel;
SCH_SCREEN* m_screen;
};
#endif

View File

@ -84,27 +84,11 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) const
newItem->ClearFlags( SELECTED | BRIGHTENED );
if( newItem->Type() == SCH_COMPONENT_T )
newItem->RunOnChildren(
[]( SCH_ITEM* aChild )
{
SCH_COMPONENT* symbol = (SCH_COMPONENT*) newItem;
for( SCH_PIN* pin : symbol->GetPins() )
pin->ClearFlags( SELECTED | BRIGHTENED );
for( SCH_FIELD& field : symbol->GetFields() )
field.ClearFlags( SELECTED | BRIGHTENED );
}
if( newItem->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = (SCH_SHEET*) newItem;
for( SCH_FIELD& field : sheet->GetFields() )
field.ClearFlags( SELECTED | BRIGHTENED );
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
pin->ClearFlags( SELECTED | BRIGHTENED );
}
aChild->ClearFlags( SELECTED | BRIGHTENED );
} );
return newItem;
}

View File

@ -208,7 +208,6 @@ protected:
/// Stores connectivity information, per sheet
std::unordered_map<SCH_SHEET_PATH, SCH_CONNECTION*> m_connection_map;
/// True if connectivity info might be out of date
bool m_connectivity_dirty;
public:
@ -273,6 +272,13 @@ public:
*/
virtual void SetLocked( bool aLocked ) {}
/**
* Allows items to support hypertext actions when hovered/clicked.
*/
virtual bool IsHypertext() const { return false; }
virtual void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) { }
/**
* Return the layer this item is on.
*/
@ -466,6 +472,8 @@ public:
virtual void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) { }
virtual void RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction ) { }
/**
* Check if this schematic item has line stoke properties.
*

View File

@ -51,7 +51,6 @@
#include <sch_component.h>
#include <sch_edit_frame.h>
#include <sch_field.h>
#include <sch_iref.h>
#include <sch_junction.h>
#include <sch_line.h>
#include <sch_marker.h>
@ -221,7 +220,6 @@ bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
HANDLE_ITEM( SCH_BUS_BUS_ENTRY_T, SCH_BUS_ENTRY_BASE );
HANDLE_ITEM( SCH_BITMAP_T, SCH_BITMAP );
HANDLE_ITEM( SCH_MARKER_T, SCH_MARKER );
HANDLE_ITEM( SCH_IREF_T, SCH_TEXT );
default: return false;
}
@ -1160,7 +1158,7 @@ void SCH_PAINTER::draw( LIB_BEZIER *aCurve, int aLayer )
std::deque<VECTOR2D> pts_xformed;
poly.GetPoly( pts );
for( const auto &p : pts )
for( const wxPoint &p : pts )
pts_xformed.push_back( mapCoords( p ) );
m_gal->DrawPolygon( pts_xformed );
@ -1273,12 +1271,16 @@ void SCH_PAINTER::draw( SCH_LINE *aLine, int aLayer )
}
if( aLine->IsStartDangling() )
{
drawDanglingSymbol( aLine->GetStartPoint(), getLineWidth( aLine, drawingShadows ),
drawingShadows );
}
if( aLine->IsEndDangling() )
{
drawDanglingSymbol( aLine->GetEndPoint(), getLineWidth( aLine, drawingShadows ),
drawingShadows );
}
}
@ -1294,19 +1296,11 @@ void SCH_PAINTER::draw( SCH_TEXT *aText, int aLayer )
case SCH_SHEET_PIN_T: aLayer = LAYER_SHEETLABEL; break;
case SCH_HIER_LABEL_T: aLayer = LAYER_HIERLABEL; break;
case SCH_GLOBAL_LABEL_T: aLayer = LAYER_GLOBLABEL; break;
case SCH_IREF_T: aLayer = LAYER_GLOBLABEL; break;
case SCH_LABEL_T: aLayer = LAYER_LOCLABEL; break;
default: aLayer = LAYER_NOTES; break;
}
COLOR4D color = getRenderColor( aText, aLayer, drawingShadows );
bool underline = false;
if( aText->Type() == SCH_IREF_T && ( aText->GetFlags() & IS_ROLLOVER ) > 0 )
{
color = BLUE;
underline = true;
}
if( m_schematic )
{
@ -1329,7 +1323,7 @@ void SCH_PAINTER::draw( SCH_TEXT *aText, int aLayer )
m_gal->SetLineWidth( getTextThickness( aText, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->SetTextAttributes( aText );
m_gal->SetFontUnderlined( underline );
m_gal->SetFontUnderlined( false );
VECTOR2D text_offset = aText->GetTextPos() + aText->GetSchematicTextOffset( &m_schSettings );
wxString shownText( aText->GetShownText() );
@ -1500,6 +1494,14 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer )
return;
}
bool underline = false;
if( aField->IsHypertext() && ( aField->GetFlags() & IS_ROLLOVER ) > 0 )
{
color = PUREBLUE;
underline = true;
}
// Calculate the text orientation according to the parent orientation.
int orient = (int) aField->GetTextAngle();
@ -1549,7 +1551,7 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer )
m_gal->SetGlyphSize( VECTOR2D( aField->GetTextSize() ) );
m_gal->SetFontBold( aField->IsBold() );
m_gal->SetFontItalic( aField->IsItalic() );
m_gal->SetFontUnderlined( false );
m_gal->SetFontUnderlined( underline );
m_gal->SetTextMirrored( aField->IsMirrored() );
m_gal->SetLineWidth( getTextThickness( aField, drawingShadows ) );
@ -1601,6 +1603,8 @@ void SCH_PAINTER::draw( SCH_GLOBALLABEL *aLabel, int aLayer )
m_gal->DrawPolyline( pts2 );
draw( static_cast<SCH_TEXT*>( aLabel ), aLayer );
draw( aLabel->GetIntersheetRefs(), aLayer );
}

View File

@ -2231,7 +2231,6 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
break;
case T_property:
{
// The field parent symbol must be set and it's orientation must be set before
// the field positions are set.
field = parseSchField( symbol.get() );
@ -2282,7 +2281,6 @@ SCH_COMPONENT* SCH_SEXPR_PARSER::parseSchematicSymbol()
delete field;
break;
}
case T_pin:
{
@ -2703,8 +2701,7 @@ SCH_TEXT* SCH_SEXPR_PARSER::parseSchText()
case T_global_label: text = std::make_unique<SCH_GLOBALLABEL>(); break;
case T_hierarchical_label: text = std::make_unique<SCH_HIERLABEL>(); break;
default:
wxCHECK_MSG( false, nullptr,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as text." ) );
wxCHECK_MSG( false, nullptr, "Cannot parse " + GetTokenString( CurTok() ) + " as text." );
}
NeedSYMBOL();
@ -2721,7 +2718,6 @@ SCH_TEXT* SCH_SEXPR_PARSER::parseSchText()
switch( token )
{
case T_at:
{
text->SetPosition( parseXY() );
switch( static_cast<int>( parseDouble( "text angle" ) ) )
@ -2738,10 +2734,8 @@ SCH_TEXT* SCH_SEXPR_PARSER::parseSchText()
NeedRIGHT();
break;
}
case T_shape:
{
if( text->Type() == SCH_TEXT_T || text->Type() == SCH_LABEL_T )
Unexpected( T_shape );
@ -2760,22 +2754,36 @@ SCH_TEXT* SCH_SEXPR_PARSER::parseSchText()
NeedRIGHT();
break;
}
case T_effects:
parseEDA_TEXT( static_cast<EDA_TEXT*>( text.get() ) );
break;
case T_iref:
{
case T_iref: // legacy format; current is a T_property (aka SCH_FIELD)
if( text->Type() == SCH_GLOBAL_LABEL_T )
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( text.get() );
label->SetIrefSavedPosition( parseXY() );
SCH_FIELD* field = label->GetIntersheetRefs();
field->SetTextPos( parseXY() );
NeedRIGHT();
field->SetVisible( true );
}
break;
case T_property:
if( text->Type() == SCH_GLOBAL_LABEL_T )
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( text.get() );
SCH_FIELD* field = parseSchField( label );
field->SetLayer( LAYER_GLOBLABEL );
label->SetIntersheetRefs( *field );
delete field;
}
break;
default:
Expecting( "at, shape, iref or effects" );

View File

@ -38,7 +38,6 @@
#include <sch_line.h>
#include <sch_no_connect.h>
#include <sch_text.h>
#include <sch_iref.h>
#include <sch_sheet.h>
#include <schematic.h>
#include <sch_plugins/kicad/sch_sexpr_plugin.h>
@ -1233,18 +1232,6 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel )
if( ( aText->Type() == SCH_GLOBAL_LABEL_T ) || ( aText->Type() == SCH_HIER_LABEL_T ) )
m_out->Print( 0, " (shape %s)", getSheetPinShapeToken( aText->GetShape() ) );
if( ( aText->Type() == SCH_GLOBAL_LABEL_T ) )
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( aText );
if( label->GetIref() != nullptr )
{
SCH_IREF* iref = label->GetIref();
m_out->Print( 0, " (iref %s %s)", FormatInternalUnits( iref->GetPosition().x ).c_str(),
FormatInternalUnits( iref->GetPosition().y ).c_str() );
}
}
if( aText->GetText().Length() < 50 )
{
m_out->Print( 0, " (at %s %s %s)",
@ -1261,6 +1248,12 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel )
FormatAngle( aText->GetTextAngle() ).c_str() );
}
if( ( aText->Type() == SCH_GLOBAL_LABEL_T ) )
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( aText );
saveField( label->GetIntersheetRefs(), aNestLevel + 1 );
}
m_out->Print( 0, "\n" );
aText->Format( m_out, aNestLevel, 0 );
m_out->Print( aNestLevel, ")\n" ); // Closes text token.
@ -1584,7 +1577,7 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
aSymbol->GetFields( fields );
for( auto field : fields )
for( LIB_FIELD& field : fields )
saveField( &field, aFormatter, aNestLevel + 1 );
lastFieldId = fields.back().GetId() + 1;
@ -1630,7 +1623,7 @@ void SCH_SEXPR_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFo
aSymbol->GetFields( fields );
for( auto field : fields )
for( LIB_FIELD& field : fields )
saveField( &field, aFormatter, aNestLevel + 1 );
lastFieldId = fields.back().GetId() + 1;

View File

@ -949,9 +949,11 @@ void SCH_SCREEN::EnsureAlternateReferencesExist()
void SCH_SCREEN::GetHierarchicalItems( std::vector<SCH_ITEM*>* aItems )
{
static KICAD_T hierarchicalTypes[] = { SCH_COMPONENT_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT };
for( SCH_ITEM* item : Items() )
{
if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) )
if( item->IsType( hierarchicalTypes ) )
aItems->push_back( item );
}
}

View File

@ -900,6 +900,16 @@ SEARCH_RESULT SCH_SHEET::Visit( INSPECTOR aInspector, void* testData, const KICA
}
void SCH_SHEET::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
{
for( SCH_FIELD& field : m_fields )
aFunction( &field );
for( SCH_SHEET_PIN* pin : m_pins )
aFunction( pin );
}
wxString SCH_SHEET::GetSelectMenuText( EDA_UNITS aUnits ) const
{
return wxString::Format( _( "Hierarchical Sheet %s" ),

View File

@ -556,6 +556,8 @@ public:
SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
void RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction ) override;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
BITMAP_DEF GetMenuImage() const override;

View File

@ -526,56 +526,22 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut )
return aItem;
}
else if( aItem->Type() == SCH_COMPONENT_T )
{
SCH_COMPONENT* comp = static_cast<SCH_COMPONENT*>( aItem );
for( SCH_FIELD& field : comp->GetFields() )
SCH_ITEM* childMatch = nullptr;
aItem->RunOnChildren(
[&]( SCH_ITEM* aChild )
{
if( field.m_Uuid == aID )
if( aChild->m_Uuid == aID )
childMatch = aChild;
} );
if( childMatch )
{
if( aPathOut )
*aPathOut = sheet;
return &field;
}
}
for( SCH_PIN* pin : comp->GetPins() )
{
if( pin->m_Uuid == aID )
{
if( aPathOut )
*aPathOut = sheet;
return pin;
}
}
}
else if( aItem->Type() == SCH_SHEET_T )
{
SCH_SHEET* sch_sheet = static_cast<SCH_SHEET*>( aItem );
for( SCH_FIELD& field : sch_sheet->GetFields() )
{
if( field.m_Uuid == aID )
{
if( aPathOut )
*aPathOut = sheet;
return &field;
}
}
for( SCH_SHEET_PIN* pin : sch_sheet->GetPins() )
{
if( pin->m_Uuid == aID )
{
if( aPathOut )
*aPathOut = sheet;
return pin;
}
}
return childMatch;
}
}
}
@ -595,26 +561,11 @@ void SCH_SHEET_LIST::FillItemMap( std::map<KIID, EDA_ITEM*>& aMap )
{
aMap[ aItem->m_Uuid ] = aItem;
if( aItem->Type() == SCH_COMPONENT_T )
aItem->RunOnChildren(
[&]( SCH_ITEM* aChild )
{
SCH_COMPONENT* comp = static_cast<SCH_COMPONENT*>( aItem );
for( SCH_FIELD& field : comp->GetFields() )
aMap[ field.m_Uuid ] = &field;
for( SCH_PIN* pin : comp->GetPins() )
aMap[ pin->m_Uuid ] = pin;
}
else if( aItem->Type() == SCH_SHEET_T )
{
SCH_SHEET* sch_sheet = static_cast<SCH_SHEET*>( aItem );
for( SCH_FIELD& field : sch_sheet->GetFields() )
aMap[ field.m_Uuid ] = &field;
for( SCH_SHEET_PIN* pin : sch_sheet->GetPins() )
aMap[ pin->m_Uuid ] = pin;
}
aMap[ aChild->m_Uuid ] = aChild;
} );
}
}
}

View File

@ -44,7 +44,6 @@
#include <dialogs/html_messagebox.h>
#include <project/project_file.h>
#include <project/net_settings.h>
#include <sch_iref.h>
#include <dialog_helpers.h>
#include <trigo.h>
@ -307,10 +306,16 @@ bool SCH_TEXT::operator<( const SCH_ITEM& aItem ) const
int SCH_TEXT::GetTextOffset( RENDER_SETTINGS* aSettings ) const
{
SCH_RENDER_SETTINGS* renderSettings = static_cast<SCH_RENDER_SETTINGS*>( aSettings );
double ratio;
if( renderSettings )
return KiROUND( renderSettings->m_TextOffsetRatio * GetTextSize().y );
if( aSettings )
ratio = static_cast<SCH_RENDER_SETTINGS*>( aSettings )->m_TextOffsetRatio;
else if( Schematic() )
ratio = Schematic()->Settings().m_TextOffsetRatio;
else
ratio = DEFAULT_TEXT_OFFSET_RATIO; // For previews (such as in Preferences), etc.
return KiROUND( ratio * GetTextSize().y );
return 0;
}
@ -767,10 +772,7 @@ bool SCH_LABEL::IsType( const KICAD_T aScanTypes[] ) const
const EDA_RECT SCH_LABEL::GetBoundingBox() const
{
EDA_RECT rect = GetTextBox();
// In practice this is controlled by the current TextOffsetRatio, but the default is
// close enough for hit-testing, etc.
int margin = Mils2iu( TXT_MARGIN );
int margin = GetTextOffset();
rect.Inflate( margin );
@ -805,15 +807,31 @@ BITMAP_DEF SCH_LABEL::GetMenuImage() const
}
SCH_GLOBALLABEL::SCH_GLOBALLABEL( const wxPoint& pos, const wxString& text )
: SCH_TEXT( pos, text, SCH_GLOBAL_LABEL_T )
SCH_GLOBALLABEL::SCH_GLOBALLABEL( const wxPoint& pos, const wxString& text ) :
SCH_TEXT( pos, text, SCH_GLOBAL_LABEL_T ),
m_intersheetRefsField( { 0, 0 }, 0, this )
{
m_layer = LAYER_GLOBLABEL;
m_shape = PINSHEETLABEL_SHAPE::PS_BIDI;
m_isDangling = true;
m_iref = nullptr;
SetMultilineAllowed( false );
m_savedIrefPos = wxDefaultPosition;
m_intersheetRefsField.SetText( wxT( "${INTERSHEET_REFS}" ) );
m_intersheetRefsField.SetLayer( LAYER_GLOBLABEL );
m_fieldsAutoplaced = FIELDS_AUTOPLACED_AUTO;
}
SCH_GLOBALLABEL::SCH_GLOBALLABEL( const SCH_GLOBALLABEL& aGlobalLabel ) :
SCH_TEXT( aGlobalLabel ),
m_intersheetRefsField( { 0, 0 }, 0, this )
{
m_intersheetRefsField = aGlobalLabel.m_intersheetRefsField;
// Re-parent the fields, which before this had aGlobalLabel as parent
m_intersheetRefsField.SetParent( this );
m_fieldsAutoplaced = aGlobalLabel.m_fieldsAutoplaced;
}
@ -823,6 +841,52 @@ EDA_ITEM* SCH_GLOBALLABEL::Clone() const
}
void SCH_GLOBALLABEL::SwapData( SCH_ITEM* aItem )
{
SCH_TEXT::SwapData( aItem );
SCH_GLOBALLABEL* globalLabel = static_cast<SCH_GLOBALLABEL*>( aItem );
// Swap field data wholesale...
std::swap( m_intersheetRefsField, globalLabel->m_intersheetRefsField );
// ...and then reset parent pointers.
globalLabel->m_intersheetRefsField.SetParent( globalLabel );
m_intersheetRefsField.SetParent( this );
}
SEARCH_RESULT SCH_GLOBALLABEL::Visit( INSPECTOR aInspector, void* testData,
const KICAD_T aFilterTypes[] )
{
KICAD_T stype;
for( const KICAD_T* p = aFilterTypes; (stype = *p) != EOT; ++p )
{
// If caller wants to inspect my type
if( stype == SCH_LOCATE_ANY_T || stype == Type() )
{
if( SEARCH_RESULT::QUIT == aInspector( this, NULL ) )
return SEARCH_RESULT::QUIT;
}
if( stype == SCH_LOCATE_ANY_T || stype == SCH_FIELD_T )
{
if( SEARCH_RESULT::QUIT == aInspector( GetIntersheetRefs(), this ) )
return SEARCH_RESULT::QUIT;
}
}
return SEARCH_RESULT::CONTINUE;
}
void SCH_GLOBALLABEL::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
{
aFunction( &m_intersheetRefsField );
}
wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const
{
wxPoint text_offset;
@ -894,6 +958,106 @@ void SCH_GLOBALLABEL::SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle )
}
void SCH_GLOBALLABEL::UpdateIntersheetRefProps()
{
m_intersheetRefsField.SetTextSize( GetTextSize() );
m_intersheetRefsField.SetItalic( IsItalic() );
m_intersheetRefsField.SetBold( IsBold() );
m_intersheetRefsField.SetTextThickness( GetTextThickness() );
if( m_fieldsAutoplaced == FIELDS_AUTOPLACED_AUTO )
AutoplaceFields( nullptr, false );
}
void SCH_GLOBALLABEL::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual )
{
int margin = GetTextOffset();
int labelLen = GetBoundingBox().GetSizeMax();
int penOffset = GetPenWidth() / 2;
// Set both axes to penOffset; we're going to overwrite the text axis below
wxPoint offset( -penOffset, -penOffset );
switch( GetLabelSpinStyle() )
{
default:
case LABEL_SPIN_STYLE::LEFT:
m_intersheetRefsField.SetTextAngle( TEXT_ANGLE_HORIZ );
m_intersheetRefsField.SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
m_intersheetRefsField.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
offset.x = - ( labelLen + margin / 2 );
break;
case LABEL_SPIN_STYLE::UP:
m_intersheetRefsField.SetTextAngle( TEXT_ANGLE_VERT );
m_intersheetRefsField.SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
m_intersheetRefsField.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
offset.y = - ( labelLen + margin / 2 );
break;
case LABEL_SPIN_STYLE::RIGHT:
m_intersheetRefsField.SetTextAngle( TEXT_ANGLE_HORIZ );
m_intersheetRefsField.SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
m_intersheetRefsField.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
offset.x = labelLen + margin /2 ;
break;
case LABEL_SPIN_STYLE::BOTTOM:
m_intersheetRefsField.SetTextAngle( TEXT_ANGLE_VERT );
m_intersheetRefsField.SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
m_intersheetRefsField.SetVertJustify( GR_TEXT_VJUSTIFY_CENTER );
offset.y = labelLen + margin / 2;
break;
}
m_intersheetRefsField.SetTextPos( GetPosition() + offset );
m_fieldsAutoplaced = FIELDS_AUTOPLACED_AUTO;
}
bool SCH_GLOBALLABEL::ResolveTextVar( wxString* token, int aDepth ) const
{
if( token->IsSameAs( wxT( "INTERSHEET_REFS" ) ) && Schematic() )
{
auto it = Schematic()->GetPageRefsMap().find( GetText() );
if( it != Schematic()->GetPageRefsMap().end() )
{
SCHEMATIC_SETTINGS& settings = Schematic()->Settings();
std::vector<wxString> pageListCopy;
pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
std::sort( pageListCopy.begin(), pageListCopy.end() );
token->Printf( "%s", settings.m_IntersheetRefsPrefix );
if( ( settings.m_IntersheetRefsFormatShort ) && ( pageListCopy.size() > 2 ) )
{
token->Append( wxString::Format( wxT( "%s..%s" ),
pageListCopy.front(),
pageListCopy.back() ) );
}
else
{
for( const wxString& pageNo : pageListCopy )
token->Append( wxString::Format( wxT( "%s," ), pageNo ) );
if( token->Last() == ',' )
token->RemoveLast();
}
token->Append( settings.m_IntersheetRefsSuffix );
}
return true;
}
return false;
}
void SCH_GLOBALLABEL::Print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
{
static std::vector <wxPoint> Poly;
@ -987,11 +1151,7 @@ const EDA_RECT SCH_GLOBALLABEL::GetBoundingBox() const
int x = GetTextPos().x;
int y = GetTextPos().y;
int penWidth = GetEffectiveTextPenWidth();
// In practice this is controlled by the current TextOffsetRatio, but the default is
// close enough for hit-testing, etc.
int margin = Mils2iu( TXT_MARGIN );
int margin = GetTextOffset();
int height = ( (GetTextHeight() * 15) / 10 ) + penWidth + 2 * margin;
int length = LenSize( GetShownText(), penWidth )
+ height // add height for triangular shapes
@ -1153,10 +1313,7 @@ void SCH_HIERLABEL::CreateGraphicShape( RENDER_SETTINGS* aRenderSettings,
const EDA_RECT SCH_HIERLABEL::GetBoundingBox() const
{
int penWidth = GetEffectiveTextPenWidth();
// In practice this is controlled by the current TextOffsetRatio, but the default is
// close enough for hit-testing, etc.
int margin = Mils2iu( TXT_MARGIN );
int margin = GetTextOffset();
int x = GetTextPos().x;
int y = GetTextPos().y;

View File

@ -28,12 +28,12 @@
#include <eda_text.h>
#include <sch_item.h>
#include <sch_field.h>
#include <sch_connection.h> // for CONNECTION_TYPE
class NETLIST_OBJECT_LIST;
class HTML_MESSAGE_BOX;
class SCH_IREF;
/*
* Spin style for text items of all kinds on schematics
@ -265,7 +265,7 @@ public:
bool operator<( const SCH_ITEM& aItem ) const override;
int GetTextOffset( RENDER_SETTINGS* aSettings ) const;
int GetTextOffset( RENDER_SETTINGS* aSettings = nullptr ) const;
int GetPenWidth() const override;
@ -377,7 +377,7 @@ class SCH_GLOBALLABEL : public SCH_TEXT
public:
SCH_GLOBALLABEL( const wxPoint& aPos = wxPoint( 0, 0 ), const wxString& aText = wxEmptyString );
// Do not create a copy constructor. The one generated by the compiler is adequate.
SCH_GLOBALLABEL( const SCH_GLOBALLABEL& aGlobalLabel );
~SCH_GLOBALLABEL() { }
@ -393,6 +393,12 @@ public:
EDA_ITEM* Clone() const override;
void SwapData( SCH_ITEM* aItem ) override;
SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
void RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction ) override;
void SetLabelSpinStyle( LABEL_SPIN_STYLE aSpinStyle ) override;
wxPoint GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const override;
@ -402,6 +408,11 @@ public:
void CreateGraphicShape( RENDER_SETTINGS* aRenderSettings,
std::vector<wxPoint>& aPoints, const wxPoint& aPos ) override;
void UpdateIntersheetRefProps();
void AutoplaceFields( SCH_SCREEN* aScreen, bool aManual ) override;
bool ResolveTextVar( wxString* token, int aDepth ) const;
bool IsConnectable() const override { return true; }
bool CanConnect( const SCH_ITEM* aItem ) const override
@ -416,25 +427,27 @@ public:
void Print( RENDER_SETTINGS* aSettings, const wxPoint& offset ) override;
SCH_IREF* GetIref() { return m_iref; }
void SetIref( SCH_IREF* iref ) { m_iref = iref; }
wxPoint GetIrefSavedPosition() { return m_savedIrefPos; }
void SetIrefSavedPosition( wxPoint pos ) { m_savedIrefPos = pos; }
SCH_FIELD* GetIntersheetRefs() { return &m_intersheetRefsField; }
void SetIntersheetRefs( const SCH_FIELD& aField ) { m_intersheetRefsField = aField; }
bool IsPointClickableAnchor( const wxPoint& aPos ) const override
{
return m_isDangling && GetPosition() == aPos;
}
void Move( const wxPoint& aMoveVector ) override
{
SCH_TEXT::Move( aMoveVector );
m_intersheetRefsField.Move( aMoveVector );
}
private:
bool doIsConnected( const wxPoint& aPosition ) const override
{
return EDA_TEXT::GetTextPos() == aPosition;
}
SCH_IREF* m_iref;
wxPoint m_savedIrefPos;
SCH_FIELD m_intersheetRefsField;
};

View File

@ -62,6 +62,12 @@ private:
/// Holds and calculates connectivity information of this schematic
CONNECTION_GRAPH* m_connectionGraph;
/**
* Holds a map of labels to the page numbers that they appear on. Used to update global
* label intersheet references.
*/
std::map<wxString, std::set<wxString>> m_labelToPageRefsMap;
public:
SCHEMATIC( PROJECT* aPrj );
@ -157,6 +163,8 @@ public:
*/
bool ResolveCrossReference( wxString* token, int aDepth ) const;
std::map<wxString, std::set<wxString>>& GetPageRefsMap() { return m_labelToPageRefsMap; }
wxString ConvertRefsToKIIDs( const wxString& aSource ) const;
wxString ConvertKIIDsToRefs( const wxString& aSource ) const;

View File

@ -38,14 +38,14 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin
m_DefaultWireThickness( DEFAULT_WIRE_THICKNESS * IU_PER_MILS ),
m_DefaultBusThickness( DEFAULT_BUS_THICKNESS * IU_PER_MILS ),
m_DefaultTextSize( DEFAULT_TEXT_SIZE * IU_PER_MILS ),
m_TextOffsetRatio( 0.08 ),
m_TextOffsetRatio( DEFAULT_TEXT_OFFSET_RATIO ),
m_PinSymbolSize( DEFAULT_TEXT_SIZE * IU_PER_MILS / 2 ),
m_JunctionSize( DEFAULT_JUNCTION_DIAM * IU_PER_MILS ),
m_JunctionSizeChoice( 3 ),
m_IntersheetsRefShow( false ),
m_IntersheetsRefFormatShort( false ),
m_IntersheetsRefPrefix( DEFAULT_IREF_PREFIX ),
m_IntersheetsRefSuffix( DEFAULT_IREF_SUFFIX ),
m_IntersheetRefsShow( false ),
m_IntersheetRefsFormatShort( false ),
m_IntersheetRefsPrefix( DEFAULT_IREF_PREFIX ),
m_IntersheetRefsSuffix( DEFAULT_IREF_SUFFIX ),
m_SpiceAdjustPassiveValues( false )
{
EESCHEMA_SETTINGS* appSettings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
@ -74,16 +74,16 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin
appSettings ? appSettings->m_Drawing.intersheets_ref_suffix : DEFAULT_IREF_SUFFIX;
m_params.emplace_back( new PARAM<bool>( "drawing.intersheets_ref_show",
&m_IntersheetsRefShow, defaultIntersheetsRefShow ) );
&m_IntersheetRefsShow, defaultIntersheetsRefShow ) );
m_params.emplace_back( new PARAM<bool>( "drawing.intersheets_ref_short",
&m_IntersheetsRefFormatShort, defaultIntersheetsRefFormatShort ) );
&m_IntersheetRefsFormatShort, defaultIntersheetsRefFormatShort ) );
m_params.emplace_back( new PARAM<wxString>( "drawing.intersheets_ref_prefix",
&m_IntersheetsRefPrefix, defaultIntersheetsRefPrefix ) );
&m_IntersheetRefsPrefix, defaultIntersheetsRefPrefix ) );
m_params.emplace_back( new PARAM<wxString>( "drawing.intersheets_ref_suffix",
&m_IntersheetsRefSuffix, defaultIntersheetsRefSuffix ) );
&m_IntersheetRefsSuffix, defaultIntersheetsRefSuffix ) );
m_params.emplace_back( new PARAM_SCALED<int>( "drawing.default_line_thickness",
&m_DefaultLineWidth, Mils2iu( defaultLineThickness ),

View File

@ -52,10 +52,10 @@ public:
// User choice for junction dot size ( e.g. none = 0, smallest = 1, small = 2, etc )
int m_JunctionSizeChoice;
bool m_IntersheetsRefShow;
bool m_IntersheetsRefFormatShort;
wxString m_IntersheetsRefPrefix;
wxString m_IntersheetsRefSuffix;
bool m_IntersheetRefsShow;
bool m_IntersheetRefsFormatShort;
wxString m_IntersheetRefsPrefix;
wxString m_IntersheetRefsSuffix;
wxString m_PageLayoutDescrFile;

View File

@ -39,11 +39,9 @@
#include <sch_base_frame.h>
#include <sch_component.h>
#include <sch_edit_frame.h>
#include <sch_field.h>
#include <sch_item.h>
#include <sch_line.h>
#include <sch_sheet.h>
#include <sch_iref.h>
#include <schematic.h>
#include <tool/tool_event.h>
#include <tool/tool_manager.h>
@ -360,14 +358,9 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
m_toolMgr->ProcessEvent( *newEvt );
continueSelect = false;
}
else if( collector[0]->Type() == SCH_IREF_T )
else if( collector[0]->IsHypertext() )
{
wxMenu menu;
static_cast<SCH_IREF*>( collector[0] )->BuildHypertextMenu( &menu );
intptr_t sel = m_frame->GetPopupMenuSelectionFromUser( menu );
m_toolMgr->RunAction( EE_ACTIONS::hypertextCommand, true, (void*) sel );
collector[0]->DoHypertextMenu( m_frame );
continueSelect = false;
}
}
@ -518,8 +511,8 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
displayWireCursor = true;
}
else if( collector[0]->Type() == SCH_IREF_T && !m_additive && !m_subtractive
&& !m_exclusive_or )
else if( collector[0]->IsHypertext()
&& ( !m_additive && !m_subtractive && !m_exclusive_or ) )
{
rolloverItem = collector[0]->m_Uuid;
}
@ -538,6 +531,10 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
item->ClearFlags( IS_ROLLOVER );
lastRolloverItem = niluuid;
if( item->Type() == SCH_FIELD_T )
m_frame->GetCanvas()->GetView()->Update( item->GetParent() );
else
m_frame->GetCanvas()->GetView()->Update( item );
}
@ -547,6 +544,10 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
item->SetFlags( IS_ROLLOVER );
lastRolloverItem = rolloverItem;
if( item->Type() == SCH_FIELD_T )
m_frame->GetCanvas()->GetView()->Update( item->GetParent() );
else
m_frame->GetCanvas()->GetView()->Update( item );
}
}
@ -659,12 +660,12 @@ bool EE_SELECTION_TOOL::selectPoint( EE_COLLECTOR& aCollector, EDA_ITEM** aItem,
{
m_selection.ClearReferencePoint();
// Unmodified clicking of SCH_IREFs results in hypertext links rather than selection.
// Unmodified clicking of hypertext items results in hypertext actions rather than selection.
if( !aAdd && !aSubtract && !aExclusiveOr )
{
for( int i = aCollector.GetCount() - 1; i >= 0; --i )
{
if( aCollector[i]->Type() == SCH_IREF_T )
if( aCollector[i]->IsHypertext() )
aCollector.Remove( i );
}
}
@ -1302,7 +1303,7 @@ void EE_SELECTION_TOOL::RebuildSelection()
}
else
{
for( auto item : m_frame->GetScreen()->Items() )
for( SCH_ITEM* item : m_frame->GetScreen()->Items() )
{
// If the field and component are selected, only use the component
if( item->IsSelected() )
@ -1311,30 +1312,12 @@ void EE_SELECTION_TOOL::RebuildSelection()
}
else
{
if( item->Type() == SCH_COMPONENT_T )
item->RunOnChildren(
[&]( SCH_ITEM* aChild )
{
for( SCH_FIELD& field : static_cast<SCH_COMPONENT*>( item )->GetFields() )
{
if( field.IsSelected() )
select( &field );
}
}
if( item->Type() == SCH_SHEET_T )
{
for( SCH_FIELD& field : static_cast<SCH_SHEET*>( item )->GetFields() )
{
if( field.IsSelected() )
select( &field );
}
for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( item )->GetPins() )
{
if( pin->IsSelected() )
select( pin );
}
}
if( aChild->IsSelected() )
select( aChild );
} );
}
}
}
@ -1595,42 +1578,14 @@ void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGr
// Highlight pins and fields. (All the other component children are currently only
// represented in the LIB_PART and will inherit the settings of the parent component.)
if( itemType == SCH_COMPONENT_T )
{
for( SCH_PIN* pin : static_cast<SCH_COMPONENT*>( aItem )->GetPins() )
static_cast<SCH_ITEM*>( aItem )->RunOnChildren(
[&]( SCH_ITEM* aChild )
{
if( aMode == SELECTED )
pin->SetSelected();
aChild->SetSelected();
else if( aMode == BRIGHTENED )
pin->SetBrightened();
}
for( SCH_FIELD& field : static_cast<SCH_COMPONENT*>( aItem )->GetFields() )
{
if( aMode == SELECTED )
field.SetSelected();
else if( aMode == BRIGHTENED )
field.SetBrightened();
}
}
else if( itemType == SCH_SHEET_T )
{
for( SCH_FIELD& field : static_cast<SCH_SHEET*>( aItem )->GetFields() )
{
if( aMode == SELECTED )
field.SetSelected();
else if( aMode == BRIGHTENED )
field.SetBrightened();
}
for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( aItem )->GetPins() )
{
if( aMode == SELECTED )
pin->SetSelected();
else if( aMode == BRIGHTENED )
pin->SetBrightened();
}
}
aChild->SetSelected();
} );
if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
getView()->Update( aItem->GetParent() );
@ -1653,42 +1608,14 @@ void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* a
// Unhighlight pins and fields. (All the other component children are currently only
// represented in the LIB_PART.)
if( itemType == SCH_COMPONENT_T )
{
for( SCH_PIN* pin : static_cast<SCH_COMPONENT*>( aItem )->GetPins() )
static_cast<SCH_ITEM*>( aItem )->RunOnChildren(
[&]( SCH_ITEM* aChild )
{
if( aMode == SELECTED )
pin->ClearSelected();
aChild->ClearSelected();
else if( aMode == BRIGHTENED )
pin->ClearBrightened();
}
for( SCH_FIELD& field : static_cast<SCH_COMPONENT*>( aItem )->GetFields() )
{
if( aMode == SELECTED )
field.ClearSelected();
else if( aMode == BRIGHTENED )
field.ClearBrightened();
}
}
else if( itemType == SCH_SHEET_T )
{
for( SCH_FIELD& field : static_cast<SCH_SHEET*>( aItem )->GetFields() )
{
if( aMode == SELECTED )
field.ClearSelected();
else if( aMode == BRIGHTENED )
field.ClearBrightened();
}
for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( aItem )->GetPins() )
{
if( aMode == SELECTED )
pin->ClearSelected();
else if( aMode == BRIGHTENED )
pin->ClearBrightened();
}
}
aChild->ClearBrightened();
} );
if( itemType == SCH_PIN_T || itemType == SCH_FIELD_T || itemType == SCH_SHEET_PIN_T )
getView()->Update( aItem->GetParent() );

View File

@ -779,7 +779,7 @@ SCH_SHEET_PIN* SCH_DRAWING_TOOLS::createSheetPin( SCH_SHEET* aSheet, SCH_HIERLAB
int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
{
EDA_ITEM* item = nullptr;
SCH_ITEM* item = nullptr;
bool isImportMode = aEvent.IsAction( &EE_ACTIONS::importSheetPin );
bool isText = aEvent.IsAction( &EE_ACTIONS::placeSchematicText );
bool isGlobalLabel = aEvent.IsAction( &EE_ACTIONS::placeGlobalLabel );
@ -885,11 +885,12 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
break;
case SCH_SHEET_PIN_T:
{
EDA_ITEM* i;
SCH_HIERLABEL* label = nullptr;
SCH_SHEET* sheet = nullptr;
if( m_selectionTool->SelectPoint( cursorPos, EE_COLLECTOR::SheetsOnly, &item ) )
sheet = dynamic_cast<SCH_SHEET*>( item );
if( m_selectionTool->SelectPoint( cursorPos, EE_COLLECTOR::SheetsOnly, &i ) )
sheet = dynamic_cast<SCH_SHEET*>( i );
item = nullptr;
@ -944,6 +945,8 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
else
{
item->ClearFlags( IS_MOVED );
item->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), (SCH_ITEM*) item, false );
item = nullptr;

View File

@ -42,7 +42,6 @@
#include <sch_bitmap.h>
#include <sch_view.h>
#include <sch_line.h>
#include <sch_iref.h>
#include <sch_bus_entry.h>
#include <sch_junction.h>
#include <sch_edit_frame.h>
@ -276,7 +275,11 @@ bool SCH_EDIT_TOOL::Init()
static KICAD_T entryTypes[] = { SCH_BUS_WIRE_ENTRY_T, SCH_BUS_BUS_ENTRY_T, EOT };
auto entryCondition = E_C::MoreThan( 0 ) && E_C::OnlyTypes( entryTypes );
auto singleComponentCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_COMPONENT_T );
static KICAD_T fieldParentTypes[] = { SCH_COMPONENT_T, SCH_SHEET_T, SCH_GLOBAL_LABEL_T, EOT };
auto singleFieldParentCondition = E_C::Count( 1 ) && E_C::OnlyTypes( fieldParentTypes );
auto singleSymbolCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_COMPONENT_T );
auto singleSheetCondition = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
//
// Add edit actions to the move tool menu
@ -293,9 +296,9 @@ bool SCH_EDIT_TOOL::Init()
moveMenu.AddItem( ACTIONS::doDelete, E_C::NotEmpty );
moveMenu.AddItem( EE_ACTIONS::properties, propertiesCondition );
moveMenu.AddItem( EE_ACTIONS::editReference, singleComponentCondition );
moveMenu.AddItem( EE_ACTIONS::editValue, singleComponentCondition );
moveMenu.AddItem( EE_ACTIONS::editFootprint, singleComponentCondition );
moveMenu.AddItem( EE_ACTIONS::editReference, singleSymbolCondition );
moveMenu.AddItem( EE_ACTIONS::editValue, singleSymbolCondition );
moveMenu.AddItem( EE_ACTIONS::editFootprint, singleSymbolCondition );
moveMenu.AddItem( EE_ACTIONS::toggleDeMorgan, E_C::SingleDeMorganSymbol );
std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu = std::make_shared<SYMBOL_UNIT_MENU>();
@ -323,10 +326,10 @@ bool SCH_EDIT_TOOL::Init()
drawMenu.AddItem( EE_ACTIONS::mirrorY, orientCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::properties, propertiesCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::editReference, singleComponentCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::editValue, singleComponentCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::editFootprint, singleComponentCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::autoplaceFields, singleComponentCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::editReference, singleSymbolCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::editValue, singleSymbolCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::editFootprint, singleSymbolCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::autoplaceFields, singleFieldParentCondition, 200 );
drawMenu.AddItem( EE_ACTIONS::toggleDeMorgan, E_C::SingleDeMorganSymbol, 200 );
std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu2 = std::make_shared<SYMBOL_UNIT_MENU>();
@ -334,7 +337,7 @@ bool SCH_EDIT_TOOL::Init()
drawingTools->GetToolMenu().AddSubMenu( symUnitMenu2 );
drawMenu.AddMenu( symUnitMenu2.get(), E_C::SingleMultiUnitSymbol, 1 );
drawMenu.AddItem( EE_ACTIONS::editWithLibEdit, singleComponentCondition && E_C::Idle, 200 );
drawMenu.AddItem( EE_ACTIONS::editWithLibEdit, singleSymbolCondition && E_C::Idle, 200 );
drawMenu.AddItem( EE_ACTIONS::toLabel, anyTextTool && E_C::Idle, 200 );
drawMenu.AddItem( EE_ACTIONS::toHLabel, anyTextTool && E_C::Idle, 200 );
@ -357,8 +360,7 @@ bool SCH_EDIT_TOOL::Init()
selToolMenu.AddItem( EE_ACTIONS::editReference, E_C::SingleSymbol, 200 );
selToolMenu.AddItem( EE_ACTIONS::editValue, E_C::SingleSymbol, 200 );
selToolMenu.AddItem( EE_ACTIONS::editFootprint, E_C::SingleSymbol, 200 );
selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, singleComponentCondition
|| singleSheetCondition, 200 );
selToolMenu.AddItem( EE_ACTIONS::autoplaceFields, singleFieldParentCondition, 200 );
selToolMenu.AddItem( EE_ACTIONS::toggleDeMorgan, E_C::SingleSymbol, 200 );
std::shared_ptr<SYMBOL_UNIT_MENU> symUnitMenu3 = std::make_shared<SYMBOL_UNIT_MENU>();
@ -366,7 +368,7 @@ bool SCH_EDIT_TOOL::Init()
m_selectionTool->GetToolMenu().AddSubMenu( symUnitMenu3 );
selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 );
selToolMenu.AddItem( EE_ACTIONS::editWithLibEdit, singleComponentCondition && E_C::Idle, 200 );
selToolMenu.AddItem( EE_ACTIONS::editWithLibEdit, singleSymbolCondition && E_C::Idle, 200 );
selToolMenu.AddItem( EE_ACTIONS::changeSymbol, E_C::SingleSymbol, 200 );
selToolMenu.AddItem( EE_ACTIONS::updateSymbol, E_C::SingleSymbol, 200 );
@ -460,10 +462,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
if( item->Type() == SCH_GLOBAL_LABEL_T )
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( item );
SCH_IREF* iref = label->GetIref();
if( iref )
iref->CopyParentStyle();
label->UpdateIntersheetRefProps();
}
break;
@ -653,10 +652,7 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
if( item->Type() == SCH_GLOBAL_LABEL_T )
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( item );
SCH_IREF* iref = label->GetIref();
if( iref )
iref->CopyParentStyle();
label->UpdateIntersheetRefProps();
}
break;
@ -846,14 +842,6 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
case SCH_NO_CONNECT_T:
newItem->SetParent( m_frame->GetScreen() );
m_frame->AddToScreen( newItem, m_frame->GetScreen() );
if( newItem->Type() == SCH_GLOBAL_LABEL_T )
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( newItem );
label->SetIref( nullptr );
label->SetIrefSavedPosition( wxDefaultPosition );
}
break;
case SCH_SHEET_T:
@ -1062,16 +1050,6 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
sheet->RemovePin( pin );
}
else if( sch_item->Type() == SCH_GLOBAL_LABEL_T )
{
SCH_GLOBALLABEL* label = (SCH_GLOBALLABEL*) sch_item;
SCH_IREF* iref = label->GetIref();
m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() );
if( iref )
m_frame->RemoveFromScreen( iref, m_frame->GetScreen() );
}
else
{
m_frame->RemoveFromScreen( sch_item, m_frame->GetScreen() );
@ -1259,7 +1237,7 @@ int SCH_EDIT_TOOL::EditField( const TOOL_EVENT& aEvent )
int SCH_EDIT_TOOL::AutoplaceFields( const TOOL_EVENT& aEvent )
{
EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::ComponentsOrSheets );
EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::FieldOwners );
if( selection.Empty() )
return 0;
@ -1269,16 +1247,7 @@ int SCH_EDIT_TOOL::AutoplaceFields( const TOOL_EVENT& aEvent )
if( !item->IsNew() )
saveCopyInUndoList( item, UNDO_REDO::CHANGED );
if( item->Type() == SCH_COMPONENT_T )
{
SCH_COMPONENT* component = static_cast<SCH_COMPONENT*>( item );
component->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
}
else if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
sheet->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
}
item->AutoplaceFields( m_frame->GetScreen(), /* aManual */ true );
updateItem( item, true );
m_frame->OnModify();
@ -1302,7 +1271,9 @@ int SCH_EDIT_TOOL::ChangeSymbols( const TOOL_EVENT& aEvent )
if( aEvent.IsAction( &EE_ACTIONS::changeSymbol )
|| aEvent.IsAction( &EE_ACTIONS::changeSymbols ) )
{
mode = DIALOG_CHANGE_SYMBOLS::MODE::CHANGE;
}
DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode );
@ -1323,11 +1294,15 @@ int SCH_EDIT_TOOL::ConvertDeMorgan( const TOOL_EVENT& aEvent )
if( aEvent.IsAction( &EE_ACTIONS::showDeMorganStandard )
&& component->GetConvert() == LIB_ITEM::LIB_CONVERT::BASE )
{
return 0;
}
if( aEvent.IsAction( &EE_ACTIONS::showDeMorganAlternate )
&& component->GetConvert() != LIB_ITEM::LIB_CONVERT::DEMORGAN )
{
return 0;
}
if( !component->IsNew() )
saveCopyInUndoList( component, UNDO_REDO::CHANGED );

View File

@ -268,27 +268,11 @@ int SCH_EDITOR_CONTROL::UpdateFind( const TOOL_EVENT& aEvent )
{
visit( item, &m_frame->GetCurrentSheet() );
if( item->Type() == SCH_COMPONENT_T )
item->RunOnChildren(
[&]( SCH_ITEM* aChild )
{
SCH_COMPONENT* cmp = static_cast<SCH_COMPONENT*>( item );
for( SCH_FIELD& field : cmp->GetFields() )
visit( &field, &m_frame->GetCurrentSheet() );
for( SCH_PIN* pin : cmp->GetPins() )
visit( pin, &m_frame->GetCurrentSheet() );
}
else if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
for( SCH_FIELD& field : sheet->GetFields() )
visit( &field, &m_frame->GetCurrentSheet() );
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
visit( pin, &m_frame->GetCurrentSheet() );
}
visit( aChild, &m_frame->GetCurrentSheet() );
} );
}
}
else if( aEvent.Matches( EVENTS::SelectedItemsModified ) )
@ -1542,13 +1526,6 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
updatePastedInstances( pastePath, clipPath, sheet, forceKeepAnnotations );
}
if( item->Type() == SCH_GLOBAL_LABEL_T )
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( item );
label->SetIref( nullptr );
label->SetIrefSavedPosition( wxDefaultPosition );
}
item->SetFlags( IS_NEW | IS_PASTED | IS_MOVED );
m_frame->AddItemToScreenAndUndoList( m_frame->GetScreen(), (SCH_ITEM*) item, i > 0 );

View File

@ -29,11 +29,9 @@
#include <ee_actions.h>
#include <bitmaps.h>
#include <eda_item.h>
#include <sch_iref.h>
#include <sch_item.h>
#include <sch_component.h>
#include <sch_sheet.h>
#include <sch_view.h>
#include <sch_line.h>
#include <sch_edit_frame.h>
#include <eeschema_id.h>
@ -98,7 +96,6 @@ static const KICAD_T movableItems[] =
SCH_COMPONENT_T,
SCH_SHEET_PIN_T,
SCH_SHEET_T,
SCH_IREF_T,
EOT
};
@ -710,36 +707,6 @@ void SCH_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
break;
}
case SCH_GLOBAL_LABEL_T:
{
SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( aItem );
EDA_ITEM* iref = (EDA_ITEM*) ( label->GetIref() );
static_cast<SCH_ITEM*>( aItem )->Move( (wxPoint) aDelta );
if( iref )
static_cast<SCH_ITEM*>( iref )->Move( (wxPoint) aDelta );
break;
}
case SCH_IREF_T:
{
SCH_IREF* iref = static_cast<SCH_IREF*>( aItem );
wxPoint pt = (wxPoint) aDelta;
int style = iref->GetParentLabel()->GetLabelSpinStyle();
if( iref->GetParentLabel()->IsSelected() )
break;
if( ( style == LABEL_SPIN_STYLE::RIGHT ) || ( style == LABEL_SPIN_STYLE::LEFT ) )
pt.y = 0;
if( ( style == LABEL_SPIN_STYLE::UP ) || ( style == LABEL_SPIN_STYLE::BOTTOM ) )
pt.x = 0;
iref->Move( pt );
break;
}
default:
static_cast<SCH_ITEM*>( aItem )->Move( (wxPoint) aDelta );
break;

View File

@ -23,6 +23,7 @@
*/
#include <schematic.h>
#include <eeschema_id.h>
#include <tools/ee_actions.h>
#include <tools/sch_navigate_tool.h>
@ -58,7 +59,7 @@ int SCH_NAVIGATE_TOOL::HypertextCommand( const TOOL_EVENT& aEvent )
}
};
if( aEvent.GetCommandId() == ID_HYPERTEXT_BACK )
if( *page == "HYPERTEXT_BACK" )
{
if( m_hypertextStack.size() > 0 )
{

View File

@ -32,8 +32,6 @@
class SCH_EDIT_FRAME;
#define ID_HYPERTEXT_BACK 999
/**
* SCH_NAVIGATE_TOOL
*

View File

@ -137,7 +137,6 @@ enum KICAD_T
SCH_SHEET_PIN_T,
SCH_SHEET_T,
SCH_PIN_T,
SCH_IREF_T,
// Be prudent with these types:
// they should be used only to locate a specific field type among SCH_FIELD_Ts