diff --git a/common/base_screen.cpp b/common/base_screen.cpp index cb025b79c3..5a40558b77 100644 --- a/common/base_screen.cpp +++ b/common/base_screen.cpp @@ -35,13 +35,13 @@ wxString BASE_SCREEN::m_PageLayoutDescrFileName; // the name of the page layou BASE_SCREEN::BASE_SCREEN( EDA_ITEM* aParent, KICAD_T aType ) : EDA_ITEM( aParent, aType ) { - m_Initialized = false; - m_ScreenNumber = 1; - m_NumberOfScreens = 1; // Hierarchy: Root: ScreenNumber = 1 - m_Center = true; + m_Initialized = false; + m_virtualPageNumber = 1; + m_pageCount = 1; // Hierarchy: Root: ScreenNumber = 1 + m_Center = true; - m_FlagModified = false; // Set when any change is made on board. - m_FlagSave = false; // Used in auto save set when an auto save is required. + m_FlagModified = false; // Set when any change is made on board. + m_FlagSave = false; // Used in auto save set when an auto save is required. } @@ -68,6 +68,27 @@ void BASE_SCREEN::InitDataPoints( const wxSize& aPageSizeIU ) } +void BASE_SCREEN::SetPageCount( int aPageCount ) +{ + wxCHECK( aPageCount > 0, /* void */ ); + + m_pageCount = aPageCount; +} + + +const wxString& BASE_SCREEN::GetPageNumber() const +{ + static wxString pageNumber; + + if( m_pageNumber.IsEmpty() ) + pageNumber.Printf( "%d", m_virtualPageNumber ); + else + pageNumber = m_pageNumber; + + return pageNumber; +} + + #if defined(DEBUG) void BASE_SCREEN::Show( int nestLevel, std::ostream& os ) const diff --git a/common/dialogs/dialog_page_settings.cpp b/common/dialogs/dialog_page_settings.cpp index 5e2761d003..6cef34f999 100644 --- a/common/dialogs/dialog_page_settings.cpp +++ b/common/dialogs/dialog_page_settings.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KICAD, a free EDA CAD application. * - * Copyright (C) 1992-2018 Kicad Developers, see AUTHORS.txt for contributors. + * 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 @@ -166,11 +166,11 @@ void DIALOG_PAGES_SETTINGS::initDialog() #ifdef EESCHEMA // Init display value for schematic sub-sheet number wxString format = m_TextSheetCount->GetLabel(); - msg.Printf( format, m_screen->m_NumberOfScreens ); + msg.Printf( format, m_screen->GetPageCount() ); m_TextSheetCount->SetLabel( msg ); format = m_TextSheetNumber->GetLabel(); - msg.Printf( format, m_screen->m_ScreenNumber ); + msg.Printf( format, m_screen->GetVirtualPageNumber() ); m_TextSheetNumber->SetLabel( msg ); #else m_TextSheetCount->Show( false ); @@ -771,7 +771,8 @@ void DIALOG_PAGES_SETTINGS::UpdatePageLayoutExample() GRFilledRect( NULL, &memDC, 0, 0, m_layout_size.x, m_layout_size.y, WHITE, WHITE ); PrintPageLayout( &renderSettings, pageDUMMY, emptyString, emptyString, m_tb, - m_screen->m_NumberOfScreens, m_screen->m_ScreenNumber, 1, &Prj() ); + m_screen->GetPageCount(), m_screen->GetPageNumber(), 1, &Prj(), + wxEmptyString, m_screen->GetVirtualPageNumber() == 1 ); memDC.SelectObject( wxNullBitmap ); m_PageLayoutExampleBitmap->SetBitmap( *m_page_bitmap ); diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp index 3f711ba55e..4593bef462 100644 --- a/common/eda_draw_frame.cpp +++ b/common/eda_draw_frame.cpp @@ -89,7 +89,7 @@ EDA_DRAW_FRAME::EDA_DRAW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame m_gridColor = COLOR4D( DARKGRAY ); // Default grid color m_showPageLimits = false; m_drawBgColor = COLOR4D( BLACK ); // the background color of the draw canvas: - // BLACK for Pcbnew, BLACK or WHITE for eeschema + // BLACK for Pcbnew, BLACK or WHITE for Eeschema m_colorSettings = nullptr; m_MsgFrameHeight = EDA_MSG_PANEL::GetRequiredHeight(); m_userUnits = EDA_UNITS::MILLIMETRES; @@ -819,19 +819,21 @@ static const wxString productName = wxT( "KiCad E.D.A. " ); void PrintPageLayout( RENDER_SETTINGS* aSettings, const PAGE_INFO& aPageInfo, const wxString& aFullSheetName, const wxString& aFileName, - const TITLE_BLOCK& aTitleBlock, int aSheetCount, int aSheetNumber, - double aScalar, const PROJECT* aProject, const wxString& aSheetLayer ) + const TITLE_BLOCK& aTitleBlock, int aSheetCount, const wxString& aPageNumber, + double aScalar, const PROJECT* aProject, const wxString& aSheetLayer, + bool aIsFirstPage ) { WS_DRAW_ITEM_LIST drawList; drawList.SetDefaultPenSize( aSettings->GetDefaultPenWidth() ); drawList.SetMilsToIUfactor( aScalar ); - drawList.SetSheetNumber( aSheetNumber ); + drawList.SetPageNumber( aPageNumber ); drawList.SetSheetCount( aSheetCount ); drawList.SetFileName( aFileName ); drawList.SetSheetName( aFullSheetName ); drawList.SetSheetLayer( aSheetLayer ); drawList.SetProject( aProject ); + drawList.SetIsFirstPage( aIsFirstPage ); drawList.BuildWorkSheetGraphicList( aPageInfo, aTitleBlock ); @@ -857,8 +859,8 @@ void EDA_DRAW_FRAME::PrintWorkSheet( RENDER_SETTINGS* aSettings, BASE_SCREEN* aS } PrintPageLayout( aSettings, GetPageSettings(), GetScreenDesc(), aFilename, GetTitleBlock(), - aScreen->m_NumberOfScreens, aScreen->m_ScreenNumber, aScalar, &Prj(), - aSheetLayer ); + aScreen->GetPageCount(), aScreen->GetPageNumber(), aScalar, &Prj(), + aSheetLayer, aScreen->GetVirtualPageNumber() == 1 ); if( origin.y > 0 ) { @@ -874,6 +876,7 @@ wxString EDA_DRAW_FRAME::GetScreenDesc() const return wxEmptyString; } + bool EDA_DRAW_FRAME::LibraryFileBrowser( bool doOpen, wxFileName& aFilename, const wxString& wildcard, const wxString& ext, bool isDirectory ) diff --git a/common/page_layout/ws_draw_item.cpp b/common/page_layout/ws_draw_item.cpp index 57320bc80d..ec12053002 100644 --- a/common/page_layout/ws_draw_item.cpp +++ b/common/page_layout/ws_draw_item.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 1992-2013 Jean-Pierre Charras . - * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * * * This program is free software; you can redistribute it and/or @@ -253,7 +253,8 @@ bool WS_DRAW_ITEM_POLYPOLYGONS::HitTest( const wxPoint& aPosition, int aAccuracy } -bool WS_DRAW_ITEM_POLYPOLYGONS::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const +bool WS_DRAW_ITEM_POLYPOLYGONS::HitTest( const EDA_RECT& aRect, bool aContained, + int aAccuracy ) const { EDA_RECT sel = aRect; @@ -407,7 +408,7 @@ const EDA_RECT WS_DRAW_ITEM_BITMAP::GetBoundingBox() const auto* bitmap = static_cast( m_peer ); wxSize bm_size = bitmap->m_ImageBitmap->GetSize(); - // bm_size is in Eeschma unit (100nm), convert to iu (0.001 mm) + // bm_size is in Eeschema unit (100nm), convert to iu (0.001 mm) bm_size.x /= 10; bm_size.y /= 10; @@ -450,12 +451,13 @@ const EDA_RECT WS_DRAW_ITEM_PAGE::GetBoundingBox() const { EDA_RECT dummy; - // We want this graphic item alway visible. So gives the max size to the + // We want this graphic item always visible. So gives the max size to the // bounding box to avoid any clamping: dummy.SetSize( wxSize( std::numeric_limits::max(), std::numeric_limits::max() ) ); return dummy; } + // ====================== WS_DRAW_ITEM_LIST ============================== void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList( const PAGE_INFO& aPageInfo, @@ -475,9 +477,9 @@ void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList( const PAGE_INFO& aPageInfo, for( WS_DATA_ITEM* wsItem : model.GetItems() ) { // Generate it only if the page option allows this - if( wsItem->GetPage1Option() == FIRST_PAGE_ONLY && m_sheetNumber != 1 ) + if( wsItem->GetPage1Option() == FIRST_PAGE_ONLY && !m_isFirstPage ) continue; - else if( wsItem->GetPage1Option() == SUBSEQUENT_PAGES && m_sheetNumber == 1 ) + else if( wsItem->GetPage1Option() == SUBSEQUENT_PAGES && m_isFirstPage ) continue; wsItem->SyncDrawItems( this, nullptr ); diff --git a/common/page_layout/ws_painter.cpp b/common/page_layout/ws_painter.cpp index 9b3b44e376..c8b0c63a7f 100644 --- a/common/page_layout/ws_painter.cpp +++ b/common/page_layout/ws_painter.cpp @@ -133,7 +133,7 @@ wxString WS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase ) } else if( token->IsSameAs( wxT( "#" ) ) ) { - *token = wxString::Format( wxT( "%d" ), m_sheetNumber ); + *token = wxString::Format( wxT( "%s" ), m_pageNumber ); tokenUpdated = true; } else if( token->IsSameAs( wxT( "##" ) ) ) @@ -348,7 +348,7 @@ void KIGFX::WS_PAINTER::draw( const WS_DRAW_ITEM_PAGE* aItem, int aLayer ) const m_gal->SetStrokeColor( m_renderSettings.m_pageBorderColor ); VECTOR2D pos = VECTOR2D( aItem->GetMarkerPos().x, aItem->GetMarkerPos().y ); - // Draw a cirle and a X + // Draw a circle and a X m_gal->DrawCircle( pos, marker_size ); m_gal->DrawLine( VECTOR2D( pos.x - marker_size, pos.y - marker_size), VECTOR2D( pos.x + marker_size, pos.y + marker_size ) ); diff --git a/common/page_layout/ws_proxy_view_item.cpp b/common/page_layout/ws_proxy_view_item.cpp index 03ae992393..601053d2d4 100644 --- a/common/page_layout/ws_proxy_view_item.cpp +++ b/common/page_layout/ws_proxy_view_item.cpp @@ -38,7 +38,7 @@ WS_PROXY_VIEW_ITEM::WS_PROXY_VIEW_ITEM( int aMils2IUscalefactor, const PAGE_INFO m_mils2IUscalefactor( aMils2IUscalefactor ), m_titleBlock( aTitleBlock ), m_pageInfo( aPageInfo ), - m_sheetNumber( 1 ), + m_pageNumber( "1" ), m_sheetCount( 1 ), m_project( aProject ), m_colorLayer( LAYER_WORKSHEET ), @@ -77,7 +77,8 @@ void WS_PROXY_VIEW_ITEM::buildDrawList( VIEW* aView, WS_DRAW_ITEM_LIST* aDrawLis // worksheet items coordinates and sizes are stored in mils, // and must be scaled to the same units as the caller aDrawList->SetMilsToIUfactor( m_mils2IUscalefactor ); - aDrawList->SetSheetNumber( m_sheetNumber ); + aDrawList->SetIsFirstPage( m_isFirstPage ); + aDrawList->SetPageNumber( m_pageNumber ); aDrawList->SetSheetCount( m_sheetCount ); aDrawList->SetFileName( fileName ); aDrawList->SetSheetName( sheetName ); diff --git a/common/plotters/common_plot_functions.cpp b/common/plotters/common_plot_functions.cpp index 79fb52c73e..28cf17521d 100644 --- a/common/plotters/common_plot_functions.cpp +++ b/common/plotters/common_plot_functions.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * * * This program is free software; you can redistribute it and/or @@ -55,8 +55,9 @@ wxString GetDefaultPlotExtension( PLOT_FORMAT aFormat ) void PlotWorkSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BLOCK& aTitleBlock, - const PAGE_INFO& aPageInfo, int aSheetNumber, int aNumberOfSheets, - const wxString &aSheetDesc, const wxString &aFilename, COLOR4D aColor ) + const PAGE_INFO& aPageInfo, const wxString& aSheetNumber, int aNumberOfSheets, + const wxString& aSheetDesc, const wxString& aFilename, COLOR4D aColor, + bool aIsFirstPage ) { /* Note: Page sizes values are given in mils */ @@ -76,11 +77,12 @@ void PlotWorkSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BLOCK // Prepare plot parameters drawList.SetDefaultPenSize( PLOTTER::USE_DEFAULT_LINE_WIDTH ); drawList.SetMilsToIUfactor( iusPerMil ); - drawList.SetSheetNumber( aSheetNumber ); + drawList.SetPageNumber( aSheetNumber ); drawList.SetSheetCount( aNumberOfSheets ); drawList.SetFileName( fn.GetFullName() ); // Print only the short filename drawList.SetSheetName( aSheetDesc ); drawList.SetProject( aProject ); + drawList.SetIsFirstPage( aIsFirstPage ); drawList.BuildWorkSheetGraphicList( aPageInfo, aTitleBlock ); diff --git a/eeschema/dialogs/dialog_sheet_properties.cpp b/eeschema/dialogs/dialog_sheet_properties.cpp index 3064631c56..66fcdeb25c 100644 --- a/eeschema/dialogs/dialog_sheet_properties.cpp +++ b/eeschema/dialogs/dialog_sheet_properties.cpp @@ -161,6 +161,18 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataToWindow() m_borderSwatch->SetSwatchBackground( canvas ); m_backgroundSwatch->SetSwatchBackground( canvas ); + SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetFullHierarchy(); + SCH_SHEET_PATH instance = m_frame->GetCurrentSheet(); + + wxString nextPageNumber; + + if( m_sheet->IsNew() ) + nextPageNumber.Printf( "%z", hierarchy.size() + 1 ); + else + nextPageNumber = m_sheet->GetPageNumber( instance ); + + m_pageNumberTextCtrl->ChangeValue( nextPageNumber ); + // set up the read-only fields m_heirarchyPath->SetValue( m_frame->GetCurrentSheet().PathHumanReadable() ); @@ -316,6 +328,17 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow() m_sheet->SetBorderColor( m_borderSwatch->GetSwatchColor() ); m_sheet->SetBackgroundColor( m_backgroundSwatch->GetSwatchColor() ); + SCH_SHEET_LIST hierarchy = m_frame->Schematic().GetFullHierarchy(); + SCH_SHEET_PATH instance = m_frame->GetCurrentSheet(); + + if( m_sheet->IsNew() ) + { + instance.push_back( m_sheet ); + m_sheet->AddInstance( instance.Path() ); + } + + m_sheet->SetPageNumber( instance, m_pageNumberTextCtrl->GetValue() ); + m_frame->TestDanglingEnds(); // Refresh all sheets in case ordering changed. diff --git a/eeschema/dialogs/dialog_sheet_properties_base.cpp b/eeschema/dialogs/dialog_sheet_properties_base.cpp index 2b2f972d7f..dd9c57c58c 100644 --- a/eeschema/dialogs/dialog_sheet_properties_base.cpp +++ b/eeschema/dialogs/dialog_sheet_properties_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.9.0 Jun 18 2020) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -159,29 +159,36 @@ DIALOG_SHEET_PROPERTIES_BASE::DIALOG_SHEET_PROPERTIES_BASE( wxWindow* parent, wx mainSizer->Add( m_longForm, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + wxBoxSizer* bSizer6; + bSizer6 = new wxBoxSizer( wxHORIZONTAL ); + + m_pageNumberStaticText = new wxStaticText( this, wxID_ANY, _("Page number:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_pageNumberStaticText->Wrap( -1 ); + bSizer6->Add( m_pageNumberStaticText, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + m_pageNumberTextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizer6->Add( m_pageNumberTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 ); + + + bSizer6->Add( 0, 0, 3, wxEXPAND, 5 ); + + + mainSizer->Add( bSizer6, 0, wxALL|wxEXPAND, 5 ); + m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); - mainSizer->Add( m_staticline1, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 ); + mainSizer->Add( m_staticline1, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 ); wxBoxSizer* bSizerBottom; bSizerBottom = new wxBoxSizer( wxHORIZONTAL ); - wxFlexGridSizer* fgSizer1; - fgSizer1 = new wxFlexGridSizer( 1, 2, 0, 0 ); - fgSizer1->AddGrowableCol( 1 ); - fgSizer1->SetFlexibleDirection( wxHORIZONTAL ); - fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); - m_hiearchicalPathLabel = new wxStaticText( this, wxID_ANY, _("Hierarchical path:"), wxDefaultPosition, wxDefaultSize, 0 ); m_hiearchicalPathLabel->Wrap( -1 ); - fgSizer1->Add( m_hiearchicalPathLabel, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 10 ); + bSizerBottom->Add( m_hiearchicalPathLabel, 0, wxLEFT|wxALIGN_CENTER_VERTICAL, 10 ); m_heirarchyPath = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY|wxBORDER_NONE ); m_heirarchyPath->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE ) ); - fgSizer1->Add( m_heirarchyPath, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); - - - bSizerBottom->Add( fgSizer1, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + bSizerBottom->Add( m_heirarchyPath, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 5 ); m_stdDialogButtonSizer = new wxStdDialogButtonSizer(); m_stdDialogButtonSizerOK = new wxButton( this, wxID_OK ); @@ -190,10 +197,10 @@ DIALOG_SHEET_PROPERTIES_BASE::DIALOG_SHEET_PROPERTIES_BASE( wxWindow* parent, wx m_stdDialogButtonSizer->AddButton( m_stdDialogButtonSizerCancel ); m_stdDialogButtonSizer->Realize(); - bSizerBottom->Add( m_stdDialogButtonSizer, 0, wxEXPAND|wxALL, 5 ); + bSizerBottom->Add( m_stdDialogButtonSizer, 0, wxEXPAND, 5 ); - mainSizer->Add( bSizerBottom, 0, wxEXPAND|wxLEFT, 5 ); + mainSizer->Add( bSizerBottom, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 ); this->SetSizer( mainSizer ); diff --git a/eeschema/dialogs/dialog_sheet_properties_base.fbp b/eeschema/dialogs/dialog_sheet_properties_base.fbp index d0d0ea2b5e..850c94e6ac 100644 --- a/eeschema/dialogs/dialog_sheet_properties_base.fbp +++ b/eeschema/dialogs/dialog_sheet_properties_base.fbp @@ -14,6 +14,7 @@ dialog_sheet_properties_base 1000 none + 1 dialog_sheet_properties_base @@ -25,6 +26,7 @@ 1 1 UI + 0 0 0 @@ -192,6 +194,7 @@ + 0 @@ -265,6 +268,7 @@ + 0 @@ -338,6 +342,7 @@ + 0 @@ -421,6 +426,7 @@ + 0 @@ -975,8 +981,154 @@ - 10 - wxEXPAND|wxRIGHT|wxLEFT + 5 + wxALL|wxEXPAND + 0 + + + bSizer6 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Page number: + 0 + + 0 + + + 0 + + 1 + m_pageNumberStaticText + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_pageNumberTextCtrl + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxEXPAND + 3 + + 0 + protected + 0 + + + + + + 5 + wxEXPAND|wxLEFT|wxRIGHT|wxTOP 0 1 @@ -1034,7 +1186,7 @@ 5 - wxEXPAND|wxLEFT + wxBOTTOM|wxEXPAND|wxTOP 0 @@ -1042,151 +1194,133 @@ wxHORIZONTAL none - 5 - wxALIGN_CENTER_VERTICAL|wxALL - 1 - - 2 - wxHORIZONTAL - 1 - - 0 + 10 + wxLEFT|wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Hierarchical path: + 0 + + 0 + + + 0 - fgSizer1 - wxFLEX_GROWMODE_SPECIFIED - none - 1 - 0 - - 10 - wxLEFT|wxALIGN_CENTER_VERTICAL - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Hierarchical path: - 0 - - 0 - - - 0 - - 1 - m_hiearchicalPathLabel - 1 - - - protected - 1 - - Resizable - 1 - - - ; ; forward_declare - 0 - - - - - -1 - - - - 5 - wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL - 0 - - 1 - 1 - 1 - 1 - - - - - - wxSYS_COLOUR_BTNFACE - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - - 0 - - - - 0 - - 1 - m_heirarchyPath - 1 - - - protected - 1 - - Resizable - 1 - - wxTE_READONLY - ; ; forward_declare - 0 - - - wxFILTER_NONE - wxDefaultValidator - - - - - wxBORDER_NONE - - + 1 + m_hiearchicalPathLabel + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + wxSYS_COLOUR_BTNFACE + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_heirarchyPath + 1 + + + protected + 1 + + Resizable + 1 + + wxTE_READONLY + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + wxBORDER_NONE 5 - wxEXPAND|wxALL + wxEXPAND 0 0 diff --git a/eeschema/dialogs/dialog_sheet_properties_base.h b/eeschema/dialogs/dialog_sheet_properties_base.h index 06f8c38bd2..6f76159ad8 100644 --- a/eeschema/dialogs/dialog_sheet_properties_base.h +++ b/eeschema/dialogs/dialog_sheet_properties_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.9.0 Jun 18 2020) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -56,6 +56,8 @@ class DIALOG_SHEET_PROPERTIES_BASE : public DIALOG_SHIM COLOR_SWATCH* m_borderSwatch; wxStaticText* m_backgroundColorLabel; COLOR_SWATCH* m_backgroundSwatch; + wxStaticText* m_pageNumberStaticText; + wxTextCtrl* m_pageNumberTextCtrl; wxStaticLine* m_staticline1; wxStaticText* m_hiearchicalPathLabel; wxTextCtrl* m_heirarchyPath; diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp index ec03c81930..8aba610c9a 100644 --- a/eeschema/erc.cpp +++ b/eeschema/erc.cpp @@ -159,7 +159,7 @@ void ERC_TESTER::TestTextVars( KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet ) if( aWorksheet ) { wsItems.SetMilsToIUfactor( IU_PER_MILS ); - wsItems.SetSheetNumber( 1 ); + wsItems.SetPageNumber( "1" ); wsItems.SetSheetCount( 1 ); wsItems.SetFileName( "dummyFilename" ); wsItems.SetSheetName( "dummySheet" ); diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index 5e5cd5c700..01e5dfe65d 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -406,6 +406,9 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in "versions of KiCad." ) ); } + if( sheetList.AllSheetPageNumbersEmpty() ) + sheetList.SetInitialPageNumbers(); + UpdateFileHistory( fullFileName ); SCH_SCREENS schematic( Schematic().Root() ); @@ -494,8 +497,9 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in for( SCH_SCREEN* screen = schematic.GetFirst(); screen; screen = schematic.GetNext() ) screen->UpdateLocalLibSymbolLinks(); - // Restore all of the loaded symbol instances from the root sheet screen. + // Restore all of the loaded symbol and sheet instances from the root sheet. sheetList.UpdateSymbolInstances( Schematic().RootScreen()->GetSymbolInstances() ); + sheetList.UpdateSheetInstances( Schematic().RootScreen()->GetSheetInstances() ); } Schematic().ConnectionGraph()->Reset(); @@ -788,9 +792,9 @@ bool SCH_EDIT_FRAME::SaveProject() std::vector& sheets = screen->GetClientSheetPaths(); if( sheets.size() == 1 ) - screen->m_ScreenNumber = sheets[0].GetPageNumber(); + screen->SetVirtualPageNumber( 1 ); else - screen->m_ScreenNumber = 0; // multiple uses; no way to store the real sheet # + screen->SetVirtualPageNumber( 0 ); // multiple uses; no way to store the real sheet # success &= SaveEEFile( screens.GetSheet( i ) ); } diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 65cfca1e77..e2111538ea 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2009 Wayne Stambaugh - * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2019 CERN * * This program is free software; you can redistribute it and/or @@ -153,7 +153,7 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() editMenu->Add( ACTIONS::deleteTool ); editMenu->Add( EE_ACTIONS::editTextAndGraphics ); editMenu->Add( EE_ACTIONS::changeSymbols ); - + editMenu->Add( EE_ACTIONS::editPageNumber ); //-- View menu ----------------------------------------------------------- // diff --git a/eeschema/plotters/plot_schematic_DXF.cpp b/eeschema/plotters/plot_schematic_DXF.cpp index 83caa2a10c..e9e95d4cea 100644 --- a/eeschema/plotters/plot_schematic_DXF.cpp +++ b/eeschema/plotters/plot_schematic_DXF.cpp @@ -144,11 +144,11 @@ bool DIALOG_PLOT_SCHEMATIC::PlotOneSheetDXF( const wxString& aFileName, if( aPlotFrameRef ) { PlotWorkSheet( plotter, &m_parent->Prj(), m_parent->GetTitleBlock(), pageInfo, - aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, + aScreen->GetPageNumber(), aScreen->GetPageCount(), m_parent->GetScreenDesc(), aScreen->GetFileName(), plotter->GetColorMode() ? plotter->RenderSettings()->GetLayerColor( LAYER_SCHEMATIC_WORKSHEET ) : - COLOR4D::BLACK ); + COLOR4D::BLACK, aScreen->GetVirtualPageNumber() == 1 ); } aScreen->Plot( plotter ); diff --git a/eeschema/plotters/plot_schematic_HPGL.cpp b/eeschema/plotters/plot_schematic_HPGL.cpp index 755a17871c..deba525b2d 100644 --- a/eeschema/plotters/plot_schematic_HPGL.cpp +++ b/eeschema/plotters/plot_schematic_HPGL.cpp @@ -216,8 +216,9 @@ bool DIALOG_PLOT_SCHEMATIC::Plot_1_Page_HPGL( const wxString& aFileName, if( aPlotFrameRef ) { PlotWorkSheet( plotter, &m_parent->Prj(), m_parent->GetTitleBlock(), aPageInfo, - aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, - m_parent->GetScreenDesc(), aScreen->GetFileName(), COLOR4D::BLACK ); + aScreen->GetPageNumber(), aScreen->GetPageCount(), + m_parent->GetScreenDesc(), aScreen->GetFileName(), COLOR4D::BLACK, + aScreen->GetVirtualPageNumber() == 1 ); } aScreen->Plot( plotter ); diff --git a/eeschema/plotters/plot_schematic_PDF.cpp b/eeschema/plotters/plot_schematic_PDF.cpp index bb1da82a6a..1909c23595 100644 --- a/eeschema/plotters/plot_schematic_PDF.cpp +++ b/eeschema/plotters/plot_schematic_PDF.cpp @@ -48,7 +48,7 @@ void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef, /* When printing all pages, the printed page is not the current page. In * complex hierarchies, we must update component references and others - * parameters in the given printed SCH_SCREEN, accordint to the sheet path + * parameters in the given printed SCH_SCREEN, accordant to the sheet path * because in complex hierarchies a SCH_SCREEN (a drawing ) is shared * between many sheets and component references depend on the actual sheet * path used @@ -164,12 +164,12 @@ void DIALOG_PLOT_SCHEMATIC::plotOneSheetPDF( PLOTTER* aPlotter, if( aPlotFrameRef ) { PlotWorkSheet( aPlotter, &aScreen->Schematic()->Prj(), m_parent->GetTitleBlock(), - m_parent->GetPageSettings(), aScreen->m_ScreenNumber, - aScreen->m_NumberOfScreens, m_parent->GetScreenDesc(), + m_parent->GetPageSettings(), aScreen->GetPageNumber(), + aScreen->GetPageCount(), m_parent->GetScreenDesc(), aScreen->GetFileName(), aPlotter->GetColorMode() ? aPlotter->RenderSettings()->GetLayerColor( LAYER_SCHEMATIC_WORKSHEET ) : - COLOR4D::BLACK ); + COLOR4D::BLACK, aScreen->GetVirtualPageNumber() == 1 ); } aScreen->Plot( aPlotter ); diff --git a/eeschema/plotters/plot_schematic_PS.cpp b/eeschema/plotters/plot_schematic_PS.cpp index c1d04d1545..72d496eb56 100644 --- a/eeschema/plotters/plot_schematic_PS.cpp +++ b/eeschema/plotters/plot_schematic_PS.cpp @@ -37,6 +37,7 @@ #include #include + void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef, RENDER_SETTINGS* aRenderSettings ) { @@ -45,7 +46,7 @@ void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef, /* When printing all pages, the printed page is not the current page. * In complex hierarchies, we must update component references - * and others parameters in the given printed SCH_SCREEN, accordint to the sheet path + * and others parameters in the given printed SCH_SCREEN, accordant to the sheet path * because in complex hierarchies a SCH_SCREEN (a drawing ) * is shared between many sheets and component references depend on the actual sheet path used */ @@ -170,11 +171,11 @@ bool DIALOG_PLOT_SCHEMATIC::plotOneSheetPS( const wxString& aFileName, if( aPlotFrameRef ) { PlotWorkSheet( plotter, &aScreen->Schematic()->Prj(), m_parent->GetTitleBlock(), aPageInfo, - aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, + aScreen->GetPageNumber(), aScreen->GetPageCount(), m_parent->GetScreenDesc(), aScreen->GetFileName(), plotter->GetColorMode() ? plotter->RenderSettings()->GetLayerColor( LAYER_SCHEMATIC_WORKSHEET ) : - COLOR4D::BLACK ); + COLOR4D::BLACK, aScreen->GetVirtualPageNumber() == 1 ); } aScreen->Plot( plotter ); diff --git a/eeschema/plotters/plot_schematic_SVG.cpp b/eeschema/plotters/plot_schematic_SVG.cpp index 4969019a97..4b8d302e88 100644 --- a/eeschema/plotters/plot_schematic_SVG.cpp +++ b/eeschema/plotters/plot_schematic_SVG.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2011-2016 Wayne Stambaugh + * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -43,6 +43,7 @@ #include "sch_painter.h" #include + void DIALOG_PLOT_SCHEMATIC::createSVGFile( bool aPrintAll, bool aPrintFrameRef, RENDER_SETTINGS* aRenderSettings ) { @@ -145,11 +146,11 @@ bool DIALOG_PLOT_SCHEMATIC::plotOneSheetSVG( const wxString& aFileName, if( aPlotFrameRef ) { PlotWorkSheet( plotter, &aScreen->Schematic()->Prj(), m_parent->GetTitleBlock(), pageInfo, - aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, + aScreen->GetPageNumber(), aScreen->GetPageCount(), m_parent->GetScreenDesc(), aScreen->GetFileName(), plotter->GetColorMode() ? plotter->RenderSettings()->GetLayerColor( LAYER_SCHEMATIC_WORKSHEET ) : - COLOR4D::BLACK ); + COLOR4D::BLACK, aScreen->GetVirtualPageNumber() == 1 ); } aScreen->Plot( plotter ); diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 8af9cc633f..a689880d49 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -487,22 +487,21 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount() int sheet_number = 1; const KIID_PATH& current_sheetpath = GetCurrentSheet().Path(); - // Examine all sheets path to find the current sheets path, - // and count them from root to the current sheet path: + // @todo Remove all psuedo page number system is left over from prior to real page number + // implementation. for( const SCH_SHEET_PATH& sheet : Schematic().GetSheets() ) { - if( sheet.Path() == current_sheetpath ) // Current sheet path found + if( sheet.Path() == current_sheetpath ) // Current sheet path found break; - sheet_number++; // Not found, increment before this current path + sheet_number++; // Not found, increment before this current path } - GetCurrentSheet().SetPageNumber( sheet_number ); - for( screen = s_list.GetFirst(); screen != NULL; screen = s_list.GetNext() ) - screen->m_NumberOfScreens = sheet_count; + screen->SetPageCount( sheet_count ); - GetScreen()->m_ScreenNumber = sheet_number; + GetScreen()->SetVirtualPageNumber( sheet_number ); + GetScreen()->SetPageNumber( GetCurrentSheet().GetPageNumber() ); } @@ -1231,10 +1230,10 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags ) int SCH_EDIT_FRAME::RecomputeIntersheetsRefs() { - SCHEMATIC_SETTINGS& settings = Schematic().Settings(); - std::vector pagesNumbers; - SCH_GLOBALLABEL* gLabel; - SCH_IREF* iref; + SCHEMATIC_SETTINGS& settings = Schematic().Settings(); + std::vector pagesNumbers; + SCH_GLOBALLABEL* gLabel; + SCH_IREF* iref; m_labelTable.clear(); @@ -1280,10 +1279,10 @@ int SCH_EDIT_FRAME::RecomputeIntersheetsRefs() iref = gLabel->GetIref(); } - iref->GetRefTable()->clear(); - iref->GetRefTable()->insert( iref->GetRefTable()->end(), - pagesNumbers.begin(), - pagesNumbers.end() ); + iref->GetRefTable().clear(); + iref->GetRefTable().insert( iref->GetRefTable().end(), + pagesNumbers.begin(), + pagesNumbers.end() ); } } } @@ -1295,9 +1294,9 @@ int SCH_EDIT_FRAME::RecomputeIntersheetsRefs() { if( iter->GetText().IsSameAs( item->GetText() ) && ( iter != item ) ) { - iter->GetIref()->GetRefTable()->insert( iter->GetIref()->GetRefTable()->end(), - item->GetIref()->GetRefTable()->begin(), - item->GetIref()->GetRefTable()->end() ); + iter->GetIref()->GetRefTable().insert( iter->GetIref()->GetRefTable().end(), + item->GetIref()->GetRefTable().begin(), + item->GetIref()->GetRefTable().end() ); } } } @@ -1309,23 +1308,23 @@ int SCH_EDIT_FRAME::RecomputeIntersheetsRefs() iref = item->GetIref(); - sort( iref->GetRefTable()->begin(), iref->GetRefTable()->end() ); - iref->GetRefTable()->erase( unique( iref->GetRefTable()->begin(), - iref->GetRefTable()->end() ), - iref->GetRefTable()->end() ); + 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( ( settings.m_IntersheetsRefFormatShort ) && ( iref->GetRefTable().size() > 2 ) ) { - tmp.Printf( "%d..%d", iref->GetRefTable()->front(), iref->GetRefTable()->back() ); + tmp.Printf( "%s..%s", iref->GetRefTable().front(), iref->GetRefTable().back() ); text.Append( tmp ); } else { - for( int ref : *( iref->GetRefTable() ) ) + for( wxString ref : iref->GetRefTable() ) { - tmp.Printf( "%d,", ref ); + tmp.Printf( "%s,", ref ); text.Append( tmp ); } diff --git a/eeschema/sch_file_versions.h b/eeschema/sch_file_versions.h index 25d0e4532d..ac4dc825e0 100644 --- a/eeschema/sch_file_versions.h +++ b/eeschema/sch_file_versions.h @@ -56,5 +56,5 @@ //#define SEXPR_SCHEMATIC_FILE_VERSION 20200714 // Add alternate pin definitions. //#define SEXPR_SCHEMATIC_FILE_VERSION 20200820 //#define SEXPR_SCHEMATIC_FILE_VERSION 20200827 // Remove host tag - -#define SEXPR_SCHEMATIC_FILE_VERSION 20200828 // Add footprint to symbol_instances. +//#define SEXPR_SCHEMATIC_FILE_VERSION 20200828 // Add footprint to symbol_instances. +#define SEXPR_SCHEMATIC_FILE_VERSION 20201015 // Add sheet instance properties. diff --git a/eeschema/sch_iref.cpp b/eeschema/sch_iref.cpp index 22d961e97b..1882f7f022 100644 --- a/eeschema/sch_iref.cpp +++ b/eeschema/sch_iref.cpp @@ -57,6 +57,7 @@ void SCH_IREF::PlaceAtDefaultPosition() SetTextPos( m_parentLabel->GetPosition() + offset ); } + wxPoint SCH_IREF::GetSchematicTextOffset( RENDER_SETTINGS* aSettings ) const { return m_parentLabel->GetSchematicTextOffset( aSettings ); @@ -83,6 +84,7 @@ void SCH_IREF::SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle ) pt.y = 0; pt.x = offset; break; + case LABEL_SPIN_STYLE::UP: SetTextAngle( TEXT_ANGLE_VERT ); SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT ); @@ -90,6 +92,7 @@ void SCH_IREF::SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle ) pt.y = -offset; pt.x = 0; break; + case LABEL_SPIN_STYLE::LEFT: SetTextAngle( TEXT_ANGLE_HORIZ ); SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); @@ -97,6 +100,7 @@ void SCH_IREF::SetIrefOrientation( LABEL_SPIN_STYLE aSpinStyle ) pt.y = 0; pt.x = -offset; break; + case LABEL_SPIN_STYLE::BOTTOM: SetTextAngle( TEXT_ANGLE_VERT ); SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); @@ -122,16 +126,19 @@ void SCH_IREF::CopyParentStyle() void SCH_IREF::BuildHypertextMenu( wxMenu* aMenu ) { - std::map sheetNames; + std::map sheetNames; for( const SCH_SHEET_PATH& sheet : Schematic()->GetSheets() ) sheetNames[ sheet.GetPageNumber() ] = sheet.Last()->GetName(); - for( int i : m_refTable ) + int id = ID_HYPERTEXT_BACK; + + for( wxString& i : m_refTable ) { - aMenu->Append( i, wxString::Format( _( "Go to Page %d (%s)" ), - i, - i == 1 ? _( "Root" ) : sheetNames[ i ] ) ); + aMenu->Append( id, wxString::Format( _( "Go to Page %s (%s)" ), + i, + i == "/" ? _( "Root" ) : sheetNames[ i ] ) ); + id++; } aMenu->AppendSeparator(); diff --git a/eeschema/sch_iref.h b/eeschema/sch_iref.h index e1e0dec6a2..810d2b2185 100644 --- a/eeschema/sch_iref.h +++ b/eeschema/sch_iref.h @@ -55,7 +55,7 @@ public: EDA_ITEM* Clone() const override; - std::vector* GetRefTable() { return &m_refTable; } + std::vector& GetRefTable() { return m_refTable; } bool IsDangling() const override { return false; } @@ -81,9 +81,9 @@ private: // the inherited one. using EDA_ITEM::SetParent; - std::vector m_refTable; - SCH_GLOBALLABEL* m_parentLabel; - SCH_SCREEN* m_screen; + std::vector m_refTable; + SCH_GLOBALLABEL* m_parentLabel; + SCH_SCREEN* m_screen; }; #endif diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp index bbefc2c9b1..7100ff4ed0 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp @@ -1799,6 +1799,63 @@ SCH_SHEET_PIN* SCH_SEXPR_PARSER::parseSchSheetPin( SCH_SHEET* aSheet ) } +void SCH_SEXPR_PARSER::parseSchSheetInstances( SCH_SCREEN* aScreen ) +{ + wxCHECK_RET( CurTok() == T_sheet_instances, + wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + + wxT( " as a instances token." ) ); + wxCHECK( aScreen, /* void */ ); + + T token; + + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token != T_LEFT ) + Expecting( T_LEFT ); + + token = NextTok(); + + switch( token ) + { + case T_path: + { + NeedSYMBOL(); + + SCH_SHEET_INSTANCE instance; + + instance.m_Path = KIID_PATH( FromUTF8() ); + + for( token = NextTok(); token != T_RIGHT; token = NextTok() ) + { + if( token != T_LEFT ) + Expecting( T_LEFT ); + + token = NextTok(); + + switch( token ) + { + case T_page: + NeedSYMBOL(); + instance.m_PageNumber = FromUTF8(); + NeedRIGHT(); + break; + + default: + Expecting( "path or page" ); + } + } + + aScreen->m_sheetInstances.emplace_back( instance ); + break; + } + + default: + Expecting( "path" ); + } + } +} + + void SCH_SEXPR_PARSER::parseSchSymbolInstances( SCH_SCREEN* aScreen ) { wxCHECK_RET( CurTok() == T_symbol_instances, @@ -2020,6 +2077,13 @@ void SCH_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopyableOnly, screen->Append( static_cast( parseSchText() ) ); break; + case T_sheet_instances: + if( aIsCopyableOnly ) + Unexpected( T_sheet_instances ); + + parseSchSheetInstances( screen ); + break; + case T_symbol_instances: if( aIsCopyableOnly ) Unexpected( T_symbol_instances ); diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.h b/eeschema/sch_plugins/kicad/sch_sexpr_parser.h index d8cf7f7a60..15e02b0bfc 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.h +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.h @@ -186,6 +186,7 @@ class SCH_SEXPR_PARSER : public SCHEMATIC_LEXER void parsePAGE_INFO( PAGE_INFO& aPageInfo ); void parseTITLE_BLOCK( TITLE_BLOCK& aTitleBlock ); void parseSchSymbolInstances( SCH_SCREEN* aScreen ); + void parseSchSheetInstances( SCH_SCREEN* aScreen ); SCH_SHEET_PIN* parseSchSheetPin( SCH_SHEET* aSheet ); SCH_FIELD* parseSchField( SCH_ITEM* aParent ); diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp index 814e880e00..8e019cad6a 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_plugin.cpp @@ -589,8 +589,8 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet ) // m_out->Print( 1, "(uuid %s)\n\n", m_out->Quotew( aSheet->m_Uuid.AsString() ).c_str() ); m_out->Print( 1, "(page %d %d)\n\n", - screen->m_ScreenNumber, - screen->m_NumberOfScreens ); + screen->GetVirtualPageNumber(), + screen->GetPageCount() ); screen->GetPageSettings().Format( m_out, 1, 0 ); m_out->Print( 0, "\n" ); @@ -696,11 +696,26 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet ) // If this is the root sheet, save all of the sheet paths. if( aSheet->IsRootSheet() ) { + SCH_SHEET_LIST sheetPaths( aSheet, true ); + + m_out->Print( 0, "\n" ); + m_out->Print( 1, "(sheet_instances\n" ); + + for( const SCH_SHEET_PATH& sheetPath : sheetPaths ) + { + SCH_SHEET* sheet = sheetPath.Last(); + + wxCHECK2( sheet, continue ); + + m_out->Print( 2, "(path %s (page %s))\n", + m_out->Quotew( sheetPath.PathAsString() ).c_str(), + m_out->Quotew( sheet->GetPageNumber( sheetPath ) ).c_str() ); + } + + m_out->Print( 1, ")\n" ); // Close sheet instances token. m_out->Print( 0, "\n" ); m_out->Print( 1, "(symbol_instances\n" ); - SCH_SHEET_LIST sheetPaths( aSheet, true ); - for( const SCH_SHEET_PATH& sheetPath : sheetPaths ) { SCH_REFERENCE_LIST instances; @@ -721,22 +736,43 @@ void SCH_SEXPR_PLUGIN::Format( SCH_SHEET* aSheet ) } } - m_out->Print( 1, ")\n" ); // Close instances token. + m_out->Print( 1, ")\n" ); // Close symbol instances token. } - else if( screen->m_symbolInstances.size() ) + else { - m_out->Print( 0, "\n" ); - m_out->Print( 1, "(symbol_instances\n" ); - - for( const COMPONENT_INSTANCE_REFERENCE& instance : screen->m_symbolInstances ) + // Schematic files (SCH_SCREEN objects) can be shared so we have to save and restore + // symbol and sheet instance data even if the file being saved is not the root sheet + // because it is possible that the file is the root sheet of another project. + if( screen->m_sheetInstances.size() ) { - m_out->Print( 2, "(path %s (reference %s) (unit %d))\n", - m_out->Quotew( instance.m_Path.AsString() ).c_str(), - m_out->Quotew( instance.m_Reference ).c_str(), - instance.m_Unit ); + m_out->Print( 0, "\n" ); + m_out->Print( 1, "(sheet_instances\n" ); + + for( const SCH_SHEET_INSTANCE& instance : screen->m_sheetInstances ) + { + m_out->Print( 2, "(path %s (page %s))\n", + m_out->Quotew( instance.m_Path.AsString() ).c_str(), + m_out->Quotew( instance.m_PageNumber ).c_str() ); + } + + m_out->Print( 1, ")\n" ); // Close sheet instances token. } - m_out->Print( 1, ")\n" ); // Close instances token. + if( screen->m_symbolInstances.size() ) + { + m_out->Print( 0, "\n" ); + m_out->Print( 1, "(symbol_instances\n" ); + + for( const COMPONENT_INSTANCE_REFERENCE& instance : screen->m_symbolInstances ) + { + m_out->Print( 2, "(path %s (reference %s) (unit %d))\n", + m_out->Quotew( instance.m_Path.AsString() ).c_str(), + m_out->Quotew( instance.m_Reference ).c_str(), + instance.m_Unit ); + } + + m_out->Print( 1, ")\n" ); // Close instances token. + } } m_out->Print( 0, ")\n" ); diff --git a/eeschema/sch_plugins/legacy/sch_legacy_plugin.cpp b/eeschema/sch_plugins/legacy/sch_legacy_plugin.cpp index 09dbc41af3..596841e701 100644 --- a/eeschema/sch_plugins/legacy/sch_legacy_plugin.cpp +++ b/eeschema/sch_plugins/legacy/sch_legacy_plugin.cpp @@ -888,8 +888,8 @@ void SCH_LEGACY_PLUGIN::loadPageSettings( LINE_READER& aReader, SCH_SCREEN* aScr if( strCompare( "Sheet", line, &line ) ) { - aScreen->m_ScreenNumber = parseInt( aReader, line, &line ); - aScreen->m_NumberOfScreens = parseInt( aReader, line, &line ); + aScreen->SetVirtualPageNumber( parseInt( aReader, line, &line ) ); + aScreen->SetPageCount( parseInt( aReader, line, &line ) ); } else if( strCompare( "Title", line, &line ) ) { @@ -1871,7 +1871,7 @@ void SCH_LEGACY_PLUGIN::Format( SCH_SHEET* aSheet ) page.GetHeightMils(), !page.IsCustom() && page.IsPortrait() ? " portrait" : "" ); m_out->Print( 0, "encoding utf-8\n" ); - m_out->Print( 0, "Sheet %d %d\n", screen->m_ScreenNumber, screen->m_NumberOfScreens ); + m_out->Print( 0, "Sheet %d %d\n", screen->GetVirtualPageNumber(), screen->GetPageCount() ); m_out->Print( 0, "Title %s\n", EscapedUTF8( tb.GetTitle() ).c_str() ); m_out->Print( 0, "Date %s\n", EscapedUTF8( tb.GetDate() ).c_str() ); m_out->Print( 0, "Rev %s\n", EscapedUTF8( tb.GetRevision() ).c_str() ); diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index bf270e56a5..95d2fba83a 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -206,7 +206,7 @@ void SCH_SCREEN::Clear( bool aFree ) } // Clear the project settings - m_ScreenNumber = m_NumberOfScreens = 1; + m_virtualPageNumber = m_pageCount = 1; m_titles.Clear(); } diff --git a/eeschema/sch_screen.h b/eeschema/sch_screen.h index 93d6acc895..ef68f82663 100644 --- a/eeschema/sch_screen.h +++ b/eeschema/sch_screen.h @@ -137,6 +137,7 @@ private: * schematic files. */ std::vector m_symbolInstances; + std::vector m_sheetInstances; friend SCH_EDIT_FRAME; // Only to populate m_symbolInstances. friend SCH_SEXPR_PARSER; // Only to load instance information from schematic file. @@ -497,6 +498,11 @@ public: return m_symbolInstances; } + const std::vector& GetSheetInstances() const + { + return m_sheetInstances; + } + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override; #endif @@ -626,7 +632,6 @@ public: */ void BuildClientSheetPathList(); - /** * Check \a aSchematicFileName for a potential file name case sensitivity issue. * diff --git a/eeschema/sch_sheet.cpp b/eeschema/sch_sheet.cpp index 1c00f628a4..62a78b7244 100644 --- a/eeschema/sch_sheet.cpp +++ b/eeschema/sch_sheet.cpp @@ -116,6 +116,7 @@ SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) : m_borderWidth = aSheet.m_borderWidth; m_borderColor = aSheet.m_borderColor; m_backgroundColor = aSheet.m_backgroundColor; + m_instances = aSheet.m_instances; if( m_screen ) m_screen->IncRefCount(); @@ -225,7 +226,7 @@ bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const { if( sheet.Last() == this ) // Current sheet path found { - *token = wxString::Format( wxT( "%d" ), sheet.GetPageNumber() ); + *token = wxString::Format( "%s", sheet.GetPageNumber() ); return true; } } @@ -271,6 +272,7 @@ void SCH_SHEET::SwapData( SCH_ITEM* aItem ) std::swap( m_borderWidth, sheet->m_borderWidth ); std::swap( m_borderColor, sheet->m_borderColor ); std::swap( m_backgroundColor, sheet->m_backgroundColor ); + std::swap( m_instances, sheet->m_instances ); } @@ -1013,6 +1015,9 @@ SCH_SHEET& SCH_SHEET::operator=( const SCH_ITEM& aItem ) m_pins.emplace_back( new SCH_SHEET_PIN( *pin ) ); m_pins.back()->SetParent( this ); } + + for( const SCH_SHEET_INSTANCE instance : sheet->m_instances ) + m_instances.emplace_back( instance ); } return *this; @@ -1036,6 +1041,63 @@ bool SCH_SHEET::operator <( const SCH_ITEM& aItem ) const } +bool SCH_SHEET::AddInstance( const KIID_PATH& aSheetPath ) +{ + // a empty sheet path is illegal: + wxCHECK( aSheetPath.size() > 0, false ); + + wxString path; + + for( const SCH_SHEET_INSTANCE& instance : m_instances ) + { + // if aSheetPath is found, nothing to do: + if( instance.m_Path == aSheetPath ) + return false; + } + + SCH_SHEET_INSTANCE instance; + + instance.m_Path = aSheetPath; + + // This entry does not exist: add it with an empty page number. + m_instances.emplace_back( instance ); + return true; +} + + +wxString SCH_SHEET::GetPageNumber( const SCH_SHEET_PATH& aInstance ) const +{ + wxString pageNumber; + KIID_PATH path = aInstance.Path(); + + for( const SCH_SHEET_INSTANCE& instance : m_instances ) + { + if( instance.m_Path == path ) + { + pageNumber = instance.m_PageNumber; + break; + } + } + + return pageNumber; +} + + +void SCH_SHEET::SetPageNumber( const SCH_SHEET_PATH& aInstance, const wxString& aPageNumber ) +{ + KIID_PATH path = aInstance.Path(); + + for( SCH_SHEET_INSTANCE& instance : m_instances ) + { + if( instance.m_Path == path ) + { + instance.m_PageNumber = aPageNumber; + break; + } + } +} + + #if defined(DEBUG) void SCH_SHEET::Show( int nestLevel, std::ostream& os ) const diff --git a/eeschema/sch_sheet.h b/eeschema/sch_sheet.h index 01ccae87ac..c6a74e496c 100644 --- a/eeschema/sch_sheet.h +++ b/eeschema/sch_sheet.h @@ -29,6 +29,7 @@ #include #include +class KIID; class LINE_READER; class SCH_SCREEN; class SCH_SHEET; @@ -235,6 +236,8 @@ class SCH_SHEET : public SCH_ITEM KIGFX::COLOR4D m_borderColor; KIGFX::COLOR4D m_backgroundColor; + std::vector m_instances; + public: SCH_SHEET( EDA_ITEM* aParent = nullptr, const wxPoint& pos = wxPoint( 0, 0 ) ); @@ -576,6 +579,38 @@ public: EDA_ITEM* Clone() const override; + /** + * @return the list of #SCH_SHEET_INSTANCE objects for this sheet. + */ + const std::vector GetInstances() const; + + /** + * Add a new instance \a aSheetPath to the instance list. + * + * If \a aSheetPath does not already exist, it is added to the list. If already exists + * in the list, do nothing. Sheet instances allow for the sharing in complex hierarchies + * which allows for per instance data such as page number for sheets to stored. + * + * @param aInstance is the #KIID_PATH of the sheet instanceadd to the instance list. + * @return false if the instance already exists, true if the instance was added. + */ + bool AddInstance( const KIID_PATH& aInstance ); + + /** + * Return the sheet page number for \a aInstance. + * + * @return the page number for the requested sheet instance. + */ + wxString GetPageNumber( const SCH_SHEET_PATH& aInstance ) const; + + /** + * Set the page number for the sheet instance \a aInstance. + * + * @param aInstance is the hierarchical path of the sheet. + * @param aReference is the new page number for the sheet. + */ + void SetPageNumber( const SCH_SHEET_PATH& aInstance, const wxString& aPageNumber ); + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override; #endif diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index 4c2a9ed36a..df9a1a9555 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2011 Wayne Stambaugh - * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. + * 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 @@ -213,6 +213,17 @@ KIID_PATH SCH_SHEET_PATH::Path() const } +KIID_PATH SCH_SHEET_PATH::PathWithoutRootUuid() const +{ + KIID_PATH path; + + for( size_t i = 1; i < size(); i++ ) + path.push_back( at( i )->m_Uuid ); + + return path; +} + + wxString SCH_SHEET_PATH::GetRootPathName( bool aUseShortName ) { // return a PathName for the root sheet (like "/" or "" @@ -396,6 +407,26 @@ bool SCH_SHEET_PATH::TestForRecursion( const wxString& aSrcFileName, const wxStr } +wxString SCH_SHEET_PATH::GetPageNumber() const +{ + SCH_SHEET* sheet = Last(); + + wxCHECK( sheet, wxEmptyString ); + + return sheet->GetPageNumber( *this ); +} + + +void SCH_SHEET_PATH::SetPageNumber( const wxString& aPageNumber ) +{ + SCH_SHEET* sheet = Last(); + + wxCHECK( sheet, /* void */ ); + + sheet->SetPageNumber( *this, aPageNumber ); +} + + SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet, bool aCheckIntegrity ) { if( aSheet != NULL ) @@ -411,12 +442,6 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet, bool aCheckIntegrity ) m_currentSheetPath.push_back( aSheet ); - /** - * @todo: Schematic page number is currently a left over relic and is generated as - * SCH_SHEET_PATH object is pushed to the list. This only has meaning when - * entire hierarchy is created from the root sheet down. - */ - m_currentSheetPath.SetPageNumber( size() + 1 ); push_back( m_currentSheetPath ); if( m_currentSheetPath.LastScreen() ) @@ -804,6 +829,34 @@ void SCH_SHEET_LIST::UpdateSymbolInstances( } +void SCH_SHEET_LIST::UpdateSheetInstances( const std::vector& aSheetInstances ) +{ + + for( const SCH_SHEET_PATH& instance : *this ) + { + auto it = std::find_if( aSheetInstances.begin(), aSheetInstances.end(), + [ instance ]( const SCH_SHEET_INSTANCE& r ) -> bool + { + return instance.PathWithoutRootUuid() == r.m_Path; + } ); + + if( it == aSheetInstances.end() ) + { + wxLogTrace( traceSchSheetPaths, "No sheet instance found for path \"%s\"", + instance.PathWithoutRootUuid().AsString() ); + continue; + } + + SCH_SHEET* sheet = instance.Last(); + + wxCHECK2( sheet, continue ); + + sheet->AddInstance( instance.Path() ); + sheet->SetPageNumber( instance, it->m_PageNumber ); + } +} + + std::vector SCH_SHEET_LIST::GetPaths() const { std::vector paths; @@ -834,3 +887,41 @@ void SCH_SHEET_LIST::ReplaceLegacySheetPaths( const std::vector& aOld } } } + + +bool SCH_SHEET_LIST::AllSheetPageNumbersEmpty() const +{ + for( const SCH_SHEET_PATH& instance : *this ) + { + const SCH_SHEET* sheet = instance.Last(); + + wxCHECK2( sheet, continue ); + + if( !sheet->GetPageNumber( instance ).IsEmpty() ) + return false; + } + + return true; +} + + +void SCH_SHEET_LIST::SetInitialPageNumbers() +{ + // Don't accidently renumber existing sheets. + wxCHECK( AllSheetPageNumbersEmpty(), /* void */ ); + + wxString tmp; + int pageNumber = 1; + + for( const SCH_SHEET_PATH& instance : *this ) + { + SCH_SHEET* sheet = instance.Last(); + + wxCHECK2( sheet, continue ); + + sheet->AddInstance( instance.Path() ); + tmp.Printf( "%d", pageNumber ); + sheet->SetPageNumber( instance, tmp ); + pageNumber += 1; + } +} diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index 9e4932af26..7c01ec4ea0 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -54,7 +54,20 @@ struct COMPONENT_INSTANCE_REFERENCE }; -/** Info about complex hierarchies handling: +/** + * A simple container for sheet instance infromation. + */ +struct SCH_SHEET_INSTANCE +{ + KIID_PATH m_Path; + + wxString m_PageNumber; +}; + + +/** + * Complex hierarchies + * * A hierarchical schematic uses sheets (hierarchical sheets) included in a * given sheet. Each sheet corresponds to a schematic drawing handled by a * SCH_SCREEN structure. A SCH_SCREEN structure contains drawings, and have @@ -106,15 +119,12 @@ class SCH_REFERENCE_LIST; /** - * Type SCH_MULTI_UNIT_REFERENCE_MAP - * is used to create a map of reference designators for multi-unit parts. + * Container to map reference designators for multi-unit parts. */ typedef std::map SCH_MULTI_UNIT_REFERENCE_MAP; /** - * SCH_SHEET_PATH - * - * handles access to a stack of flattened #SCH_SHEET objects by way of a path for + * Handle access to a stack of flattened #SCH_SHEET objects by way of a path for * creating a flattened schematic hierarchy. * *

@@ -176,9 +186,9 @@ public: size_t GetCurrentHash() const { return m_current_hash; } - void SetPageNumber( int aPageNumber ) { m_pageNumber = aPageNumber; } + void SetPageNumber( const wxString& aPageNumber ); - int GetPageNumber() const { return m_pageNumber; } + wxString GetPageNumber() const; const SCH_SHEET* GetSheet( unsigned aIndex ) const { @@ -191,8 +201,8 @@ public: } /** - * Function Cmp * Compare if this is the same sheet path as aSheetPathToTest + * * @param aSheetPathToTest = sheet path to compare * @return 1 if this sheet path has more sheets than aSheetPathToTest, * -1 if this sheet path has fewer sheets than aSheetPathToTest, @@ -201,15 +211,14 @@ public: int Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const; /** - * Function Last - * returns a pointer to the last sheet of the list - * One can see the others sheet as the "path" to reach this last sheet + * Return a pointer to the last #SCH_SHEET of the list. + * + * One can see the others sheet as the "path" to reach this last sheet. */ SCH_SHEET* Last() const; /** - * Function LastScreen - * @return the SCH_SCREEN relative to the last sheet in list + * @return the #SCH_SCREEN relative to the last sheet in list. */ SCH_SCREEN* LastScreen(); @@ -218,52 +227,57 @@ public: SCH_SCREEN* LastScreen() const; /** - * Function PathAsString - * the path uses the time stamps which do not changes even when editing - * sheet parameters - * a path is something like / (root) or /34005677 or /34005677/00AE4523 + * Return the path of time stamps which do not changes even when editing sheet parameters. + * + * A path is something like / (root) or /34005677 or /34005677/00AE4523. */ wxString PathAsString() const; /** - * Get the sheet path as an KIID_PATH. + * Get the sheet path as an #KIID_PATH. + * + * @note This #KIID_PATH includes the root sheet UUID prefixed to the path. * @return */ KIID_PATH Path() const; /** - * Function PathHumanReadable - * returns the sheet path in a human readable form, i.e. as a path made - * from sheet names. The the "normal" path instead uses the time - * stamps in the path. (Time stamps do not change even when editing - * sheet parameters). + * Get the sheet path as an #KIID_PATH without the root sheet UUID prefix. + * + * @note This #KIID_PATH does not include the root sheet UUID prefixed to the path. + * @return + */ + KIID_PATH PathWithoutRootUuid() const; + + /** + * Return the sheet path in a human readable form made from thesheet names. + * + * The the "normal" path instead uses the #KIID objects in the path that do not change + * even when editing sheet parameters. */ wxString PathHumanReadable() const; /** - * @return a PathName for the root sheet (like "/" or "" + * @return a path name for the root sheet (like "/" or "" * @param aUseShortName: true to return "/", false to return a longer name */ static wxString GetRootPathName( bool aUseShortName = true ); /** - * Function UpdateAllScreenReferences - * updates the reference and the m_Multi parameter (part selection) for all - * components on a screen depending on the actual sheet path. - * Mandatory in complex hierarchies because sheets use the same screen - * (basic schematic) - * but with different references and part selections according to the - * displayed sheet + * Update all the symbol references for this sheet path. + * + * Mandatory in complex hierarchies because sheets may use the same screen (basic schematic) + * more than once but with different references and units according to the displayed sheet. */ void UpdateAllScreenReferences(); /** - * Function GetComponents - * adds a SCH_REFERENCE() object to \a aReferences for each component in the sheet. + * Adds #SCH_REFERENCE object to \a aReferences for each component in the sheet. * * @param aReferences List of references to populate. * @param aIncludePowerSymbols : false to only get normal components. - * @param aForceIncludeOrphanComponents : true to include components having no symbol found in lib. + * @param aForceIncludeOrphanComponents : true to include components having no symbol found + * in lib. * ( orphan components) * The normal option is false, and set to true only to build the full list of components. */ @@ -271,10 +285,10 @@ public: bool aForceIncludeOrphanComponents = false ) const; /** - * Function GetMultiUnitComponents - * adds a SCH_REFERENCE_LIST object to \a aRefList for each same-reference set of - * multi-unit parts in the sheet. The map key for each element will be the - * reference designator. + * Add a #SCH_REFERENCE_LIST object to \a aRefList for each same-reference set of + * multi-unit parts in the sheet. + * + * The map key for each element will be the reference designator. * * @param aRefList Map of reference designators to reference lists * @param aIncludePowerSymbols : false to only get normal components. @@ -283,9 +297,7 @@ public: bool aIncludePowerSymbols = true ) const; /** - * Function TestForRecursion - * - * test the SCH_SHEET_PATH file names to check adding the sheet stored in the file + * Test the SCH_SHEET_PATH file names to check adding the sheet stored in the file * \a aSrcFileName to the sheet stored in file \a aDestFileName will cause a sheet * path recursion. * @@ -321,9 +333,7 @@ typedef SCH_SHEET_PATHS::iterator SCH_SHEET_PATHS_ITER; /** - * SCH_SHEET_LIST - * - * handles a list of #SCH_SHEET_PATH objects in a flattened hierarchy. + * A container for handling #SCH_SHEET_PATH objects in a flattened hierarchy. * * #SCH_SHEET objects are not unique, there can be many sheets with the same filename and * that share the same #SCH_SCREEN reference. Each The schematic file (#SCH_SCREEN) may @@ -338,8 +348,7 @@ private: public: /** - * Constructor - * build a flattened list of SCH_SHEET_PATH objects from \a aSheet. + * Construct a flattened list of SCH_SHEET_PATH objects from \a aSheet. * * If aSheet == NULL, then this is an empty hierarchy which the user can populate. */ @@ -348,8 +357,8 @@ public: ~SCH_SHEET_LIST() {} /** - * Function IsModified - * checks the entire hierarchy for any modifications. + * Check the entire hierarchy for any modifications. + * * @return True if the hierarchy is modified otherwise false. */ bool IsModified(); @@ -367,9 +376,9 @@ public: void FillItemMap( std::map& aMap ); /** - * Function AnnotatePowerSymbols - * Silently annotates the not yet annotated power symbols of the entire hierarchy - * of the sheet path list. + * Silently annotate the not yet annotated power symbols of the entire hierarchy of the + * sheet path list. + * * It is called before creating a netlist, to annotate power symbols, without prompting * the user about not annotated or duplicate for these symbols, if only these symbols * need annotation ( a very frequent case ). @@ -377,13 +386,13 @@ public: void AnnotatePowerSymbols(); /** - * Function GetComponents - * adds a SCH_REFERENCE() object to \a aReferences for each component in the list + * Add a #SCH_REFERENCE object to \a aReferences for each component in the list * of sheets. * * @param aReferences List of references to populate. * @param aIncludePowerSymbols Set to false to only get normal components. - * @param aForceIncludeOrphanComponents : true to include components having no symbol found in lib. + * @param aForceIncludeOrphanComponents : true to include components having no symbol found + * in lib. * ( orphan components) * The normal option is false, and set to true only to build the full list of components. */ @@ -391,8 +400,7 @@ public: bool aForceIncludeOrphanComponents = false ) const; /** - * Function GetMultiUnitComponents - * adds a SCH_REFERENCE_LIST object to \a aRefList for each same-reference set of + * Add a #SCH_REFERENCE_LIST object to \a aRefList for each same-reference set of * multi-unit parts in the list of sheets. The map key for each element will be the * reference designator. * @@ -403,9 +411,7 @@ public: bool aIncludePowerSymbols = true ) const; /** - * Function TestForRecursion - * - * test every SCH_SHEET_PATH in the SCH_SHEET_LIST to verify if adding the sheets stored + * Test every #SCH_SHEET_PATH in this #SCH_SHEET_LIST to verify if adding the sheets stored * in \a aSrcSheetHierarchy to the sheet stored in \a aDestFileName will cause recursion. * * @param aSrcSheetHierarchy is the SCH_SHEET_LIST of the source sheet add to \a aDestFileName. @@ -416,15 +422,14 @@ public: const wxString& aDestFileName ); /** - * Function FindSheetForScreen - * - * returns the first sheetPath (not necessarily the only one) using a particular screen + * Return a pointer to the first #SCH_SHEET_PATH object (not necessarily the only one) using + * a particular screen. */ SCH_SHEET_PATH* FindSheetForScreen( SCH_SCREEN* aScreen ); /** - * Function BuildSheetList - * builds the list of sheets and their sheet path from \a aSheet. + * Build the list of sheets and their sheet path from \a aSheet. + * * If \a aSheet is the root sheet, the full sheet path and sheet list are built. * * @param aSheet is the starting sheet from which the list is built, or NULL @@ -442,6 +447,15 @@ public: */ void UpdateSymbolInstances( const std::vector& aSymbolInstances ); + /** + * Update all of the sheet instance information using \a aSheetInstances. + * + * @warning Do not call this on anything other than the full hierarchy. + * + * @param aSymbolInstances is the symbol path information loaded from the root schematic. + */ + void UpdateSheetInstances( const std::vector& aSheetInstances ); + std::vector GetPaths() const; /** @@ -457,6 +471,24 @@ public: * @param aOldSheetPaths is the #SHEET_PATH_LIST to update from. */ void ReplaceLegacySheetPaths( const std::vector& aOldSheetPaths ); + + /** + * Check all of the sheet instance for empty page numbers. + * + * @note This should only return true when loading a legacy schematic or an s-expression + * schematic before version 20201005. + * + * @return true if all sheet instance page numbers are not defined. Otherwise false. + */ + bool AllSheetPageNumbersEmpty() const; + + /** + * Set initial sheet page numbers. + * + * The number scheme is base on the old psuedo sheet numbering algorithm prior to + * the implementation of user defineable sheet page numbers. + */ + void SetInitialPageNumbers(); }; #endif // CLASS_DRAWSHEET_PATH_H diff --git a/eeschema/sch_view.cpp b/eeschema/sch_view.cpp index cd86029dd2..cc224d4551 100644 --- a/eeschema/sch_view.cpp +++ b/eeschema/sch_view.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013-2018 CERN - * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors. * * @author Tomasz Wlostowski * @author Maciej Suminski @@ -63,6 +63,7 @@ SCH_VIEW::~SCH_VIEW() { } + void SCH_VIEW::Cleanup() { Clear(); @@ -100,11 +101,12 @@ void SCH_VIEW::DisplaySheet( SCH_SCREEN *aScreen ) &aScreen->GetPageSettings(), &aScreen->Schematic()->Prj(), &aScreen->GetTitleBlock() ) ); - m_worksheet->SetSheetNumber( aScreen->m_ScreenNumber ); - m_worksheet->SetSheetCount( aScreen->m_NumberOfScreens ); + m_worksheet->SetPageNumber( TO_UTF8( aScreen->GetPageNumber() ) ); + m_worksheet->SetSheetCount( aScreen->GetPageCount() ); m_worksheet->SetFileName( TO_UTF8( aScreen->GetFileName() ) ); m_worksheet->SetColorLayer( LAYER_SCHEMATIC_WORKSHEET ); m_worksheet->SetPageBorderColorLayer( LAYER_SCHEMATIC_GRID ); + m_worksheet->SetIsFirstPage( aScreen->GetVirtualPageNumber() == 1 ); if( m_frame && m_frame->IsType( FRAME_SCH ) ) m_worksheet->SetSheetName( TO_UTF8( m_frame->GetScreenDesc() ) ); diff --git a/eeschema/schematic.cpp b/eeschema/schematic.cpp index 47f6e6a261..a286291290 100644 --- a/eeschema/schematic.cpp +++ b/eeschema/schematic.cpp @@ -311,3 +311,12 @@ wxString SCHEMATIC::ConvertKIIDsToRefs( const wxString& aSource ) const } +SCH_SHEET_LIST& SCHEMATIC::GetFullHierarchy() const +{ + static SCH_SHEET_LIST hierarchy; + + hierarchy.clear(); + hierarchy.BuildSheetList( m_rootSheet, false ); + + return hierarchy; +} diff --git a/eeschema/schematic.h b/eeschema/schematic.h index f02014150e..5dd1137d4f 100644 --- a/eeschema/schematic.h +++ b/eeschema/schematic.h @@ -32,6 +32,8 @@ class ERC_SETTINGS; class PROJECT; class SCH_SCREEN; class SCH_SHEET; +class SCH_SHEET_LIST; + /** * Holds all the data relating to one schematic @@ -158,6 +160,11 @@ public: wxString ConvertRefsToKIIDs( const wxString& aSource ) const; wxString ConvertKIIDsToRefs( const wxString& aSource ) const; + /** + * Return the full schematic flattened hiearchical sheet list. + */ + SCH_SHEET_LIST& GetFullHierarchy() const; + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override {} diff --git a/eeschema/schematic.keywords b/eeschema/schematic.keywords index d91382b078..dc69e9d71f 100644 --- a/eeschema/schematic.keywords +++ b/eeschema/schematic.keywords @@ -47,6 +47,7 @@ input_low inverted inverted_clock in_bom +iref italic junction justify @@ -102,8 +103,8 @@ rev right scale shape -iref sheet +sheet_instances size solid start diff --git a/eeschema/schematic_undo_redo.cpp b/eeschema/schematic_undo_redo.cpp index ce4dda7152..dd7c1433f9 100644 --- a/eeschema/schematic_undo_redo.cpp +++ b/eeschema/schematic_undo_redo.cpp @@ -2,7 +2,7 @@ * 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) 2004-2019 KiCad Developers, see change_log.txt for contributors. + * Copyright (C) 2004-2020 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 @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include + /* Functions to undo and redo edit commands. * * m_UndoList and m_RedoList handle a std::vector of PICKED_ITEMS_LIST @@ -95,14 +97,13 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, SCH_ITEM* aItem, - UNDO_REDO aCommandType, + UNDO_REDO aCommandType, bool aAppend, const wxPoint& aTransformPoint ) { PICKED_ITEMS_LIST* commandToUndo = nullptr; - if( !aItem ) - return; + wxCHECK( aItem, /* void */ ); // Connectivity may change aItem->SetConnectivityDirty(); @@ -155,7 +156,7 @@ void SCH_EDIT_FRAME::SaveCopyInUndoList( SCH_SCREEN* aScreen, void SCH_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, - UNDO_REDO aTypeCommand, + UNDO_REDO aTypeCommand, bool aAppend, const wxPoint& aTransformPoint ) { @@ -286,11 +287,14 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed } else if( dynamic_cast( eda_item ) ) { - // everthing else is modified in place - + // everything else is modified in place SCH_ITEM* item = (SCH_ITEM*) eda_item; SCH_ITEM* alt_item = (SCH_ITEM*) aList->GetPickedItemLink( (unsigned) ii ); - RemoveFromScreen( item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) ); + + // The root sheet is a pseudo object that owns the root screen object but is not on + // the root screen so do not attempt to remove it from the screen it owns. + if( item != &Schematic().Root() ) + RemoveFromScreen( item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) ); switch( status ) { @@ -334,7 +338,8 @@ void SCH_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool aRed break; } - AddToScreen( item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) ); + if( item != &Schematic().Root() ) + AddToScreen( item, (SCH_SCREEN*) aList->GetScreenForItem( (unsigned) ii ) ); } } diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index 3da19c3ff7..5b6810a087 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -560,6 +560,12 @@ TOOL_ACTION EE_ACTIONS::schematicSetup( "eeschema.EditorControl.schematicSetup", _( "Edit schematic setup including annotation styles and electrical rules" ), options_schematic_xpm ); +TOOL_ACTION EE_ACTIONS::editPageNumber( "eeschema.EditorControl.editPageNumber", + AS_GLOBAL, 0, "", + _( "Edit Page Number..." ), + _( "Edit the page number of the current or selected sheet" ), + nullptr ); + TOOL_ACTION EE_ACTIONS::rescueSymbols( "eeschema.EditorControl.rescueSymbols", AS_GLOBAL, 0, "", _( "Rescue Symbols..." ), diff --git a/eeschema/tools/ee_actions.h b/eeschema/tools/ee_actions.h index b2875e1929..ff2f0afbc7 100644 --- a/eeschema/tools/ee_actions.h +++ b/eeschema/tools/ee_actions.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2019 CERN - * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors. + * 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 @@ -152,6 +152,7 @@ public: static TOOL_ACTION assignNetclass; static TOOL_ACTION showBusManager; static TOOL_ACTION schematicSetup; + static TOOL_ACTION editPageNumber; static TOOL_ACTION rescueSymbols; static TOOL_ACTION remapSymbols; diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 6097aa9e89..c944dcbfbf 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -122,8 +122,10 @@ EE_SELECTION_TOOL::~EE_SELECTION_TOOL() getView()->Remove( &m_selection ); } + using E_C = EE_CONDITIONS; + bool EE_SELECTION_TOOL::Init() { m_frame = getEditFrame(); @@ -201,6 +203,7 @@ bool EE_SELECTION_TOOL::Init() menu.AddItem( EE_ACTIONS::breakBus, busSelection && EE_CONDITIONS::Idle, 250 ); menu.AddItem( EE_ACTIONS::importSheetPin, sheetSelection && EE_CONDITIONS::Idle, 250 ); menu.AddItem( EE_ACTIONS::assignNetclass, connectedSelection && EE_CONDITIONS::Idle, 250 ); + menu.AddItem( EE_ACTIONS::editPageNumber, E_C::Empty || sheetSelection, 250 ); menu.AddSeparator( 400 ); menu.AddItem( EE_ACTIONS::symbolProperties, havePartCondition && EE_CONDITIONS::Empty, 400 ); @@ -966,7 +969,7 @@ void EE_SELECTION_TOOL::updateReferencePoint() bool EE_SELECTION_TOOL::selectMultiple() { - bool cancelled = false; // Was the tool cancelled while it was running? + bool cancelled = false; // Was the tool canceled while it was running? m_multiple = true; // Multiple selection mode is active KIGFX::VIEW* view = getView(); @@ -1493,7 +1496,7 @@ bool EE_SELECTION_TOOL::doSelectionMenu( EE_COLLECTOR* aCollector ) bool EE_SELECTION_TOOL::Selectable( const EDA_ITEM* aItem, bool checkVisibilityOnly ) const { - // NOTE: in the future this is where eeschema layer/itemtype visibility will be handled + // NOTE: in the future this is where Eeschema layer/itemtype visibility will be handled LIB_EDIT_FRAME* symbeditFrame = dynamic_cast< LIB_EDIT_FRAME* >( m_frame ); switch( aItem->Type() ) diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index ac6f5a69d0..8ab828518f 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -1731,6 +1732,75 @@ int SCH_EDIT_TOOL::CleanupSheetPins( const TOOL_EVENT& aEvent ) } +int SCH_EDIT_TOOL::EditPageNumber( const TOOL_EVENT& aEvent ) +{ + EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::SheetsOnly ); + + if( selection.GetSize() > 1 ) + return 0; + + SCH_SHEET* sheet = (SCH_SHEET*) selection.Front(); + + SCH_SHEET_PATH instance = m_frame->GetCurrentSheet(); + + SCH_SCREEN* screen; + + if( sheet ) + { + // When changing the page number of a selected sheet, the current screen owns the sheet. + screen = m_frame->GetScreen(); + + instance.push_back( sheet ); + } + else + { + SCH_SHEET_PATH prevInstance = instance; + + // When change the page number in the screen, the previous screen owns the sheet. + if( prevInstance.size() ) + { + prevInstance.pop_back(); + screen = prevInstance.LastScreen(); + } + else + { + // The root sheet and root screen are effectively the same thing. + screen = m_frame->GetScreen(); + } + + sheet = m_frame->GetCurrentSheet().Last(); + } + + wxString msg; + wxString sheetPath = instance.PathAsString(); + wxString pageNumber = instance.GetPageNumber(); + + msg.Printf( _( "Enter page number for sheet path%s" ), + ( sheetPath.Length() > 20 ) ? "\n" + sheetPath : " " + sheetPath ); + + wxTextEntryDialog dlg( m_frame, msg, _( "Edit Page Number" ), pageNumber ); + + dlg.SetTextValidator( wxFILTER_ALPHANUMERIC ); // No white space. + + if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue() == instance.GetPageNumber() ) + return 0; + + m_frame->SaveCopyInUndoList( screen, sheet, UNDO_REDO::CHANGED, false ); + + instance.SetPageNumber( dlg.GetValue() ); + + if( instance == m_frame->GetCurrentSheet() ) + { + m_frame->GetScreen()->SetPageNumber( dlg.GetValue() ); + m_frame->OnPageSettingsChange(); + } + + m_frame->OnModify(); + + return 0; +} + + void SCH_EDIT_TOOL::setTransitions() { Go( &SCH_EDIT_TOOL::Duplicate, ACTIONS::duplicate.MakeEvent() ); @@ -1764,4 +1834,5 @@ void SCH_EDIT_TOOL::setTransitions() Go( &SCH_EDIT_TOOL::CleanupSheetPins, EE_ACTIONS::cleanupSheetPins.MakeEvent() ); Go( &SCH_EDIT_TOOL::GlobalEdit, EE_ACTIONS::editTextAndGraphics.MakeEvent() ); + Go( &SCH_EDIT_TOOL::EditPageNumber, EE_ACTIONS::editPageNumber.MakeEvent() ); } diff --git a/eeschema/tools/sch_edit_tool.h b/eeschema/tools/sch_edit_tool.h index 9a6d49937a..75677a8136 100644 --- a/eeschema/tools/sch_edit_tool.h +++ b/eeschema/tools/sch_edit_tool.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2019 CERN - * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors. + * 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 @@ -53,6 +53,7 @@ public: int AutoplaceFields( const TOOL_EVENT& aEvent ); int ChangeSymbols( const TOOL_EVENT& aEvent ); int ConvertDeMorgan( const TOOL_EVENT& aEvent ); + int EditPageNumber( const TOOL_EVENT& aEvent ); /** * Change a text type to another one. diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index a6af162a39..87b8c89176 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -223,7 +223,7 @@ int SCH_EDITOR_CONTROL::Quit( const TOOL_EVENT& aEvent ) } -// A dummy wxFindReplaceData signalling any marker should be found +// A dummy wxFindReplaceData signaling any marker should be found static wxFindReplaceData g_markersOnly; @@ -458,7 +458,7 @@ int SCH_EDITOR_CONTROL::FindNext( const TOOL_EVENT& aEvent ) wxString msg = searchAllSheets ? _( "Reached end of schematic." ) : _( "Reached end of sheet." ); - // Show the popup during the timeperiod the user can wrap the search + // Show the popup during the time period the user can wrap the search m_frame->ShowFindReplaceStatus( msg + _( " Find again to wrap around to the start." ), 4000 ); wrapAroundTimer.StartOnce( 4000 ); @@ -915,7 +915,7 @@ int SCH_EDITOR_CONTROL::AssignNetclass( const TOOL_EVENT& aEvent ) // Ensure the netlist data is up to date: m_frame->RecalculateConnections( NO_CLEANUP ); - // Remove selection in favour of highlighting so the whole net is highlighted + // Remove selection in favor of highlighting so the whole net is highlighted selectionTool->ClearSelection(); highlightNet( m_toolMgr, cursorPos ); @@ -926,7 +926,7 @@ int SCH_EDITOR_CONTROL::AssignNetclass( const TOOL_EVENT& aEvent ) if( !conn->Driver() || CONNECTION_SUBGRAPH::GetDriverPriority( conn->Driver() ) < CONNECTION_SUBGRAPH::PRIORITY::SHEET_PIN ) { - m_frame->ShowInfoBarError( _( "Net must be labelled to assign a netclass." ) ); + m_frame->ShowInfoBarError( _( "Net must be labeled to assign a netclass." ) ); highlightNet( m_toolMgr, CLEAR ); return 0; } @@ -1182,6 +1182,7 @@ int SCH_EDITOR_CONTROL::Undo( const TOOL_EVENT& aEvent ) m_frame->SetSheetNumberAndCount(); m_frame->TestDanglingEnds(); + m_frame->OnPageSettingsChange(); m_frame->SyncView(); m_frame->GetCanvas()->Refresh(); m_frame->OnModify(); @@ -1214,6 +1215,7 @@ int SCH_EDITOR_CONTROL::Redo( const TOOL_EVENT& aEvent ) m_frame->SetSheetNumberAndCount(); m_frame->TestDanglingEnds(); + m_frame->OnPageSettingsChange(); m_frame->SyncView(); m_frame->GetCanvas()->Refresh(); m_frame->OnModify(); diff --git a/eeschema/tools/sch_navigate_tool.cpp b/eeschema/tools/sch_navigate_tool.cpp index a12c1f5a1e..f538845a95 100644 --- a/eeschema/tools/sch_navigate_tool.cpp +++ b/eeschema/tools/sch_navigate_tool.cpp @@ -36,14 +36,16 @@ int SCH_NAVIGATE_TOOL::NavigateHierarchy( const TOOL_EVENT& aEvent ) int SCH_NAVIGATE_TOOL::HypertextCommand( const TOOL_EVENT& aEvent ) { - intptr_t target = aEvent.Parameter(); + wxString* page = aEvent.Parameter(); + + wxCHECK( page, 0 ); auto goToPage = - [&]( intptr_t aPage ) + [&]( wxString* aPage ) { for( const SCH_SHEET_PATH& sheet : m_frame->Schematic().GetSheets() ) { - if( sheet.GetPageNumber() == aPage ) + if( sheet.GetPageNumber() == *aPage ) { m_frame->GetToolManager()->RunAction( ACTIONS::cancelInteractive, true ); m_frame->GetToolManager()->RunAction( EE_ACTIONS::clearSelection, true ); @@ -56,18 +58,18 @@ int SCH_NAVIGATE_TOOL::HypertextCommand( const TOOL_EVENT& aEvent ) } }; - if( target == ID_HYPERTEXT_BACK ) + if( aEvent.GetCommandId() == ID_HYPERTEXT_BACK ) { if( m_hypertextStack.size() > 0 ) { - goToPage( m_hypertextStack.top() ); + goToPage( &m_hypertextStack.top() ); m_hypertextStack.pop(); } } else { m_hypertextStack.push( m_frame->GetCurrentSheet().GetPageNumber() ); - goToPage( target ); + goToPage( page ); } return 0; diff --git a/eeschema/tools/sch_navigate_tool.h b/eeschema/tools/sch_navigate_tool.h index bf4a56b4cf..35e81f7339 100644 --- a/eeschema/tools/sch_navigate_tool.h +++ b/eeschema/tools/sch_navigate_tool.h @@ -58,7 +58,7 @@ private: void setTransitions() override; private: - std::stack m_hypertextStack; + std::stack m_hypertextStack; }; diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp index 73449551c5..6d34eb44b2 100644 --- a/gerbview/gerbview_frame.cpp +++ b/gerbview/gerbview_frame.cpp @@ -61,6 +61,7 @@ #include #include + GERBVIEW_FRAME::GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent ) : EDA_DRAW_FRAME( aKiway, aParent, FRAME_GERBER, wxT( "GerbView" ), wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, GERBVIEW_FRAME_NAME ), @@ -875,7 +876,7 @@ void GERBVIEW_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings ) if( GetScreen() ) { - worksheet->SetSheetNumber( 1 ); + worksheet->SetPageNumber( "1" ); worksheet->SetSheetCount( 1 ); } diff --git a/include/base_screen.h b/include/base_screen.h index 4c494418d8..8dd8146a06 100644 --- a/include/base_screen.h +++ b/include/base_screen.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 2011 Wayne Stambaugh + * Copyright (C) 2011 Wayne Stambaugh * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -52,6 +52,35 @@ private: */ wxPoint m_crossHairPosition; +protected: + /** + * The number of #BASE_SCREEN objects in this design. + * + * This currently only has meaning for #SCH_SCREEN objects because #PCB_SCREEN object + * are limited to a single file. The count is virtual because #SCH_SCREEN objects can be + * used more than once so the screen (page) count can be more than the number of screen + * objects. + */ + int m_pageCount; + + /** + * An integer based page number used for printing a range of pages. + * + * This page number is set before printing and plotting because page numbering does not + * reflect the actual page number in complex hiearachies in #SCH_SCREEN objects. + */ + int m_virtualPageNumber; + + /** + * A user defined string page number used for printing and plotting. + * + * This currently only has meaning for #SCH_SCREEN objects because #PCB_SCREEN object + * are limited to a single file. This must be set before displaying, printing, or + * plotting the current sheet. If empty, the #m_virtualPageNumber value is converted + * to a string. + */ + wxString m_pageNumber; + public: static wxString m_PageLayoutDescrFileName; ///< the name of the page layout descr file, ///< or emty to used the default pagelayout @@ -75,9 +104,6 @@ public: bool m_Initialized; - int m_ScreenNumber; - int m_NumberOfScreens; - public: BASE_SCREEN( EDA_ITEM* aParent, KICAD_T aType = SCREEN_T ); @@ -95,7 +121,6 @@ public: void InitDataPoints( const wxSize& aPageSizeInternalUnits ); - void SetModify() { m_FlagModified = true; } void ClrModify() { m_FlagModified = false; } void SetSave() { m_FlagSave = true; } @@ -104,8 +129,8 @@ public: bool IsSave() const { return m_FlagSave; } /** - * Function GetClass - * returns the class name. + * Return the class name. + * * @return wxString */ virtual wxString GetClass() const override @@ -113,6 +138,14 @@ public: return wxT( "BASE_SCREEN" ); } + int GetPageCount() const { return m_pageCount; } + void SetPageCount( int aPageCount ); + + int GetVirtualPageNumber() const { return m_virtualPageNumber; } + void SetVirtualPageNumber( int aPageNumber ) { m_virtualPageNumber = aPageNumber; } + + const wxString& GetPageNumber() const; + void SetPageNumber( const wxString& aPageNumber ) { m_pageNumber = aPageNumber; } #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override; #endif diff --git a/include/page_layout/ws_draw_item.h b/include/page_layout/ws_draw_item.h index 64e5d76d2a..dd68881590 100644 --- a/include/page_layout/ws_draw_item.h +++ b/include/page_layout/ws_draw_item.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. + * 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 @@ -41,7 +41,7 @@ class PAGE_INFO; class EDA_ITEM; class EDA_DRAW_FRAME; -/* +/** * Helper classes to handle basic graphic items used to draw/plot * title blocks and frame references * segments @@ -150,6 +150,7 @@ public: #endif }; + // This class draws a polygon class WS_DRAW_ITEM_POLYPOLYGONS : public WS_DRAW_ITEM_BASE { @@ -159,7 +160,7 @@ class WS_DRAW_ITEM_POLYPOLYGONS : public WS_DRAW_ITEM_BASE public: /** The list of polygons. Because these polygons are only for drawing purposes, - * each polygon is expected having no holes, jusst a main outline + * each polygon is expected having no holes, just a main outline */ SHAPE_POLY_SET m_Polygons; @@ -191,6 +192,7 @@ public: #endif }; + // This class draws a not filled rectangle with thick segment class WS_DRAW_ITEM_RECT : public WS_DRAW_ITEM_BASE { @@ -272,8 +274,9 @@ public: #endif }; + // This class draws a graphic text. -// it is derived from an EDA_TEXT, so it handle all caracteristics +// it is derived from an EDA_TEXT, so it handle all characteristics // of this graphic text (justification, rotation ... ) class WS_DRAW_ITEM_TEXT : public WS_DRAW_ITEM_BASE, public EDA_TEXT { @@ -311,6 +314,7 @@ public: #endif }; + // This class draws a bitmap. class WS_DRAW_ITEM_BITMAP : public WS_DRAW_ITEM_BASE { @@ -343,8 +347,9 @@ public: #endif }; -/* - * this class stores the list of graphic items: + +/** + * Store the list of graphic items: * rect, lines, polygons and texts to draw/plot * the title block and frame references, and parameters to * draw/plot them @@ -358,13 +363,14 @@ protected: // to draw/plot units. int m_penSize; // The default line width for drawings. // used when an item has a pen size = 0 - int m_sheetNumber; // the value of the sheet number, for basic inscriptions - int m_sheetCount; // the value of the number of sheets, in schematic + bool m_isFirstPage; ///< Is this the first page or not. + int m_sheetCount; ///< The number of sheets // for basic inscriptions, in schematic const TITLE_BLOCK* m_titleBlock; // for basic inscriptions const wxString* m_paperFormat; // for basic inscriptions wxString m_fileName; // for basic inscriptions wxString m_sheetFullName; // for basic inscriptions + wxString m_pageNumber; ///< The actual page number displayed in the title block. const wxString* m_sheetLayer; // for basic inscriptions const PROJECT* m_project; // for project-based variable substitutions @@ -374,12 +380,13 @@ public: m_idx = 0; m_milsToIu = 1.0; m_penSize = 1; - m_sheetNumber = 1; + m_pageNumber = "1"; m_sheetCount = 1; m_sheetLayer = nullptr; m_titleBlock = nullptr; m_paperFormat = nullptr; m_project = nullptr; + m_isFirstPage = true; } ~WS_DRAW_ITEM_LIST() @@ -429,7 +436,6 @@ public: int GetDefaultPenSize() const { return m_penSize; } /** - * Function SetMilsToIUfactor * Set the scalar to convert pages units (mils) to draw/plot units */ void SetMilsToIUfactor( double aScale ) @@ -438,16 +444,19 @@ public: } /** - * Function SetSheetNumber - * Set the value of the sheet number, for basic inscriptions + * Set the value of the sheet number. */ - void SetSheetNumber( int aSheetNumber ) + void SetPageNumber( const wxString& aPageNumber ) { - m_sheetNumber = aSheetNumber; + m_pageNumber = aPageNumber; } /** - * Function SetSheetCount + * Set if the page is the first page. + */ + void SetIsFirstPage( bool aIsFirstPage ) { m_isFirstPage = aIsFirstPage; } + + /** * Set the value of the count of sheets, for basic inscriptions */ void SetSheetCount( int aSheetCount ) @@ -497,8 +506,7 @@ public: void Print( RENDER_SETTINGS* aSettings ); /** - * Function BuildWorkSheetGraphicList is a core function for drawing or plotting the - * page layout with the frame and the basic inscriptions. + * Drawing or plot the page layout. * * Before calling this function, some parameters should be initialized by calling: * SetPenSize( aPenWidth ); @@ -518,8 +526,7 @@ public: static void GetTextVars( wxArrayString* aVars ); /** - * Function BuildFullText - * returns the full text corresponding to the aTextbase, + * Return the full text corresponding to the aTextbase, * after replacing format symbols by the corresponding value * * Basic texts in Ki_WorkSheetData struct use format notation diff --git a/include/page_layout/ws_painter.h b/include/page_layout/ws_painter.h index b94eaa7cb2..62d1230677 100644 --- a/include/page_layout/ws_painter.h +++ b/include/page_layout/ws_painter.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. + * 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 @@ -41,10 +41,9 @@ namespace KIGFX { /** - * WS_RENDER_SETTINGS - * Stores page-layout-specific render settings. + * Store page-layout-specific render settings. */ -class WS_RENDER_SETTINGS : public RENDER_SETTINGS +class WS_RENDER_SETTINGS : public RENDER_SETTINGS { public: friend class WS_PAINTER; @@ -94,8 +93,7 @@ private: /** - * WS_PAINTER - * Contains methods for drawing worksheet items. + * Methods for drawing worksheet items. */ class WS_PAINTER : public PAINTER { @@ -134,17 +132,18 @@ private: /** - * Function PrintPageLayout is a core function to print the page layout with the frame and the - * basic inscriptions. + * Print the border and title block. + * * @param aDC The device context. * @param aPageInfo for margins and page size (in mils). * @param aFullSheetName The sheetpath (full sheet name), for basic inscriptions. * @param aFileName The file name, for basic inscriptions. * @param aTitleBlock The sheet title block, for basic inscriptions. * @param aSheetCount The number of sheets (for basic inscriptions). - * @param aSheetNumber The sheet number (for basic inscriptions). + * @param aPageNumber The page number. * @param aScalar the scale factor to convert from mils to internal units. - * @param aSheetLayer The layer from pcbnew. + * @param aSheetLayer The layer from Pcbnew. + * @param aIsFirstPage True when this is the first page. This only has meaning for schematics. * * Parameters used in aPageInfo * - the size of the page layout. @@ -153,8 +152,8 @@ private: */ void PrintPageLayout( RENDER_SETTINGS* aSettings, const PAGE_INFO& aPageInfo, const wxString& aFullSheetName, const wxString& aFileName, - const TITLE_BLOCK& aTitleBlock, int aSheetCount, int aSheetNumber, + const TITLE_BLOCK& aTitleBlock, int aSheetCount, const wxString& aPageNumber, double aScalar, const PROJECT* aProject, - const wxString& aSheetLayer = wxEmptyString ); + const wxString& aSheetLayer = wxEmptyString, bool aIsFirstPage = true ); #endif // WS_PAINTER_H diff --git a/include/page_layout/ws_proxy_view_item.h b/include/page_layout/ws_proxy_view_item.h index b6e65a6eff..bb58594dc9 100644 --- a/include/page_layout/ws_proxy_view_item.h +++ b/include/page_layout/ws_proxy_view_item.h @@ -2,6 +2,7 @@ * This program source code file is part of KICAD, a free EDA CAD application. * * Copyright (C) 2013 CERN + * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. * @author Maciej Suminski * * This program is free software; you can redistribute it and/or @@ -48,29 +49,33 @@ public: const TITLE_BLOCK* aTitleBlock ); /** - * Function SetFileName() - * Sets the file name displayed in the title block. + * Set the file name displayed in the title block. */ void SetFileName( const std::string& aFileName ) { m_fileName = aFileName; } /** - * Function SetSheetName() - * Sets the sheet name displayed in the title block. + * Set the sheet name displayed in the title block. */ void SetSheetName( const std::string& aSheetName ) { m_sheetName = aSheetName; } /** - * Function SetSheetNumber() - * Changes the sheet number displayed in the title block. + * Changes the page number displayed in the title block. */ - void SetSheetNumber( int aSheetNumber ) { m_sheetNumber = aSheetNumber; } + void SetPageNumber( const std::string& aPageNumber ) { m_pageNumber = aPageNumber; } /** - * Function SetSheetCount() - * Changes the sheets count number displayed in the title block. + * Change the sheets count number displayed in the title block. */ void SetSheetCount( int aSheetCount ) { m_sheetCount = aSheetCount; } + /** + * Change if this is first page. + * + * Title blocks have an option to allow all subsequent pages to not display a title + * block. This needs to be set to false when displaying any page but the first page. + */ + void SetIsFirstPage( bool aIsFirstPage ) { m_isFirstPage = aIsFirstPage; } + /** * Can be used to override which layer ID is used for worksheet item colors * @param aLayerId is the color to use (will default to LAYER_WORKSHEET if this is not called) @@ -127,8 +132,9 @@ protected: std::string m_sheetName; const TITLE_BLOCK* m_titleBlock; const PAGE_INFO* m_pageInfo; - int m_sheetNumber; + std::string m_pageNumber; int m_sheetCount; + bool m_isFirstPage; const PROJECT* m_project; /// Layer that is used for worksheet color (LAYER_WORKSHEET is always used for visibility) diff --git a/include/plotter.h b/include/plotter.h index 2b89afd0ea..2f057cebe7 100644 --- a/include/plotter.h +++ b/include/plotter.h @@ -23,7 +23,6 @@ */ /** - * Common plot library \n * Plot settings, and plotting engines (Postscript, Gerber, HPGL and DXF) * * @file plotter.h @@ -50,9 +49,9 @@ class GBR_NETLIST_METADATA; using KIGFX::RENDER_SETTINGS; /** - * Enum PlotFormat - * is the set of supported output plot formats. They should be kept in order - * of the radio buttons in the plot panel/windows. + * The set of supported output plot formats. + * + They should be kept in order of the radio buttons in the plot panel/windows. */ enum class PLOT_FORMAT { @@ -68,8 +67,9 @@ enum class PLOT_FORMAT }; /** - * Enum for choosing which kind of text to output with the PSLIKE - * plotters. You can: + * Which kind of text to output with the PSLIKE plotters. + * + * You can: * 1) only use the internal vector font * 2) only use native postscript fonts * 3) use the internal vector font and add 'phantom' text to aid @@ -88,7 +88,7 @@ enum class PLOT_TEXT_MODE }; /** - * Enum for choosing dashed line type + * Dashed line types. */ enum class PLOT_DASH_TYPE { @@ -143,7 +143,8 @@ public: negativeMode = aNegative; } - /** Plot in B/W or color. + /** + * Plot in B/W or color. * @param aColorMode = true to plot in color, false to plot in black and white */ virtual void SetColorMode( bool aColorMode ) { colorMode = aColorMode; } @@ -178,7 +179,6 @@ public: } /** - * Function AddLineToHeader * Add a line to the list of free lines to print at the beginning of the file * @param aExtraString is the string to print */ @@ -188,8 +188,7 @@ public: } /** - * Function ClearHeaderLinesList - * remove all lines from the list of free lines to print at the beginning of the file + * Remove all lines from the list of free lines to print at the beginning of the file */ void ClearHeaderLinesList() { @@ -242,7 +241,7 @@ public: /** * Generic fallback: Cubic Bezier curve rendered as a polyline - * In Kicad the bezier curves have 4 control points: + * In KiCad the bezier curves have 4 control points: * start ctrl1 ctrl2 end */ virtual void BezierCurve( const wxPoint& aStart, const wxPoint& aControl1, @@ -283,8 +282,7 @@ public: } /** - * Function PlotPoly - * @brief Draw a polygon ( filled or not ) + * Draw a polygon ( filled or not ) * @param aCornerList = corners list (a std::vector< wxPoint >) * @param aFill = type of fill * @param aWidth = line width @@ -294,8 +292,7 @@ public: int aWidth = USE_DEFAULT_LINE_WIDTH, void * aData = NULL ) = 0; /** - * Function PlotPoly - * @brief Draw a polygon ( filled or not ) + * Draw a polygon ( filled or not ) * @param aCornerList = corners list (a SHAPE_LINE_CHAIN). * must be closed (IsClosed() == true) for a polygon. Otherwise this is a polyline * @param aFill = type of fill @@ -306,9 +303,10 @@ public: int aWidth = USE_DEFAULT_LINE_WIDTH, void * aData = NULL ); /** - * Function PlotImage - * Only Postscript plotters can plot bitmaps - * for plotters that cannot plot a bitmap, a rectangle is plotted + * Only Postscript plotters can plot bitmaps. + * + * A rectangle is plotted for plotters that cannot plot a bitmap. + * * @brief Draw an image bitmap * @param aImage = the bitmap * @param aPos = position of the center of the bitmap @@ -334,7 +332,6 @@ public: // Flash primitives /** - * virtual function FlashPadCircle * @param aPadPos Position of the shape (center of the rectangle * @param aDiameter diameter of round pad * @param aTraceMode FILLED or SKETCH @@ -344,7 +341,6 @@ public: OUTLINE_MODE aTraceMode, void* aData ) = 0; /** - * virtual function FlashPadOval * @param aPadPos Position of the shape (center of the rectangle * @param aSize = size of oblong shape * @param aPadOrient The rotation of the shape @@ -355,18 +351,16 @@ public: OUTLINE_MODE aTraceMode, void* aData ) = 0; /** - * virtual function FlashPadRect * @param aPadPos Position of the shape (center of the rectangle * @param aSize = size of rounded rect * @param aPadOrient The rotation of the shape * @param aTraceMode FILLED or SKETCH - * @param aData an auxuliary info (mainly for gerber format attributes) + * @param aData an auxiliary info (mainly for gerber format attributes) */ virtual void FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize, double aPadOrient, OUTLINE_MODE aTraceMode, void* aData ) = 0; /** - * virtual function FlashPadRoundRect * @param aPadPos Position of the shape (center of the rectangle * @param aSize = size of rounded rect * @param aCornerRadius Radius of the rounded corners @@ -379,7 +373,6 @@ public: OUTLINE_MODE aTraceMode, void* aData ) = 0; /** - * virtual function FlashPadCustom * @param aPadPos Position of the shape (center of the rectangle * @param aSize = size of round reference pad * @param aPolygons the shape as polygon set @@ -390,8 +383,8 @@ public: SHAPE_POLY_SET* aPolygons, OUTLINE_MODE aTraceMode, void* aData ) = 0; - /** virtual function FlashPadTrapez - * flash a trapezoidal pad + /** + * Flash a trapezoidal pad * @param aPadPos = the position of the shape * @param aCorners = the list of 4 corners positions, * relative to the shape position, pad orientation 0 @@ -403,7 +396,8 @@ public: double aPadOrient, OUTLINE_MODE aTraceMode, void* aData ) = 0; - /** Flash a regular polygon. Usefull only in Gerber files to flash a regular polygon + /** + * Flash a regular polygon. Useful only in Gerber files to flash a regular polygon * @param aShapePos is the center of the circle containing the polygon * @param aRadius is the radius of the circle containing the polygon * @param aCornerCount is the number of vertices @@ -444,8 +438,7 @@ public: void Marker( const wxPoint& position, int diametre, unsigned aShapeId ); /** - * Function SetLayerPolarity - * sets current Gerber layer polarity to positive or negative + * Set the current Gerber layer polarity to positive or negative * by writing \%LPD*\% or \%LPC*\% to the Gerber file, respectively. * (obviously starts a new Gerber layer, too) * @param aPositive is the layer polarity and true for positive. @@ -535,7 +528,7 @@ protected: // Helper function for sketched filler segment /** - * Cdonvert a thick segment and plot it as an oval + * Convert a thick segment and plot it as an oval */ void segmentAsOval( const wxPoint& start, const wxPoint& end, int width, OUTLINE_MODE tracemode ); @@ -574,8 +567,8 @@ protected: // variables used in most of plotters: double plotScale; /* Caller scale (how many IUs in a decimil - always); it's a double - * because in eeschema there are 0.1 IUs in a decimil (eeschema - * always works in mils internally) while pcbnew can work in decimil + * because in Eeschema there are 0.1 IUs in a decimil (Eeschema + * always works in mils internally) while PcbNew can work in decimil * or nanometers, so this value would be >= 1 */ double m_IUsPerDecimil; @@ -616,9 +609,9 @@ protected: // variables used in most of plotters: class TITLE_BLOCK; void PlotWorkSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BLOCK& aTitleBlock, - const PAGE_INFO& aPageInfo, int aSheetNumber, int aNumberOfSheets, - const wxString &aSheetDesc, const wxString &aFilename, - COLOR4D aColor = COLOR4D::UNSPECIFIED ); + const PAGE_INFO& aPageInfo, const wxString& aSheetNumber, int aNumberOfSheets, + const wxString& aSheetDesc, const wxString& aFilename, + COLOR4D aColor = COLOR4D::UNSPECIFIED, bool aIsFirstPage = true ); /** Returns the default plot extension for a format */ diff --git a/pagelayout_editor/dialogs/dialogs_for_printing.cpp b/pagelayout_editor/dialogs/dialogs_for_printing.cpp index 559ea000b4..7536536c6a 100644 --- a/pagelayout_editor/dialogs/dialogs_for_printing.cpp +++ b/pagelayout_editor/dialogs/dialogs_for_printing.cpp @@ -6,6 +6,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 CERN + * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors. + * * @author Jean-Pierre Charras, jp.charras at wanadoo.fr * * This program is free software; you can redistribute it and/or @@ -64,6 +66,7 @@ public: void PrintPage( int aPageNum ); }; + /** * Custom print preview frame. */ @@ -123,11 +126,14 @@ private: DECLARE_NO_COPY_CLASS( PLEDITOR_PREVIEW_FRAME ) }; + wxPoint PLEDITOR_PREVIEW_FRAME::s_pos; wxSize PLEDITOR_PREVIEW_FRAME::s_size; + IMPLEMENT_CLASS( PLEDITOR_PREVIEW_FRAME, wxPreviewFrame ) + BEGIN_EVENT_TABLE( PLEDITOR_PREVIEW_FRAME, wxPreviewFrame ) EVT_CLOSE( PLEDITOR_PREVIEW_FRAME::OnCloseWindow ) END_EVENT_TABLE() @@ -180,7 +186,7 @@ void PLEDITOR_PRINTOUT::PrintPage( int aPageNum ) COLOR4D bg_color = m_parent->GetDrawBgColor(); m_parent->SetDrawBgColor( WHITE ); - screen->m_ScreenNumber = aPageNum; + screen->SetVirtualPageNumber( aPageNum ); KIGFX::WS_RENDER_SETTINGS renderSettings; renderSettings.SetDefaultPenWidth( 1 ); @@ -242,6 +248,7 @@ int InvokeDialogPrint( PL_EDITOR_FRAME* aCaller, wxPrintData* aPrintData, return 1; } + int InvokeDialogPrintPreview( PL_EDITOR_FRAME* aCaller, wxPrintData* aPrintData ) { // Pass two printout objects: for preview, and possible printing. diff --git a/pagelayout_editor/pl_editor_frame.cpp b/pagelayout_editor/pl_editor_frame.cpp index 0908069c55..71e4b838df 100644 --- a/pagelayout_editor/pl_editor_frame.cpp +++ b/pagelayout_editor/pl_editor_frame.cpp @@ -62,6 +62,7 @@ #include "invoke_pl_editor_dialog.h" #include "tools/pl_editor_control.h" + BEGIN_EVENT_TABLE( PL_EDITOR_FRAME, EDA_DRAW_FRAME ) EVT_MENU( wxID_CLOSE, PL_EDITOR_FRAME::OnExit ) EVT_MENU( wxID_EXIT, PL_EDITOR_FRAME::OnExit ) @@ -211,6 +212,7 @@ PL_EDITOR_FRAME::~PL_EDITOR_FRAME() m_toolManager->ShutdownAllTools(); } + void PL_EDITOR_FRAME::setupTools() { // Create the manager and dispatcher & route draw panel events to the dispatcher @@ -766,7 +768,7 @@ void PL_EDITOR_FRAME::UpdateStatusBar() void PL_EDITOR_FRAME::PrintPage( RENDER_SETTINGS* aSettings ) { - GetScreen()->m_ScreenNumber = GetPageNumberOption() ? 1 : 2; + GetScreen()->SetVirtualPageNumber( GetPageNumberOption() ? 1 : 2 ); WS_DATA_MODEL& model = WS_DATA_MODEL::GetTheInstance(); for( WS_DATA_ITEM* dataItem : model.GetItems() ) diff --git a/pcbnew/drc/drc_test_provider_misc.cpp b/pcbnew/drc/drc_test_provider_misc.cpp index 6e1cea54b6..d2ce05b764 100644 --- a/pcbnew/drc/drc_test_provider_misc.cpp +++ b/pcbnew/drc/drc_test_provider_misc.cpp @@ -160,7 +160,7 @@ void DRC_TEST_PROVIDER_MISC::testTextVars() return; wsItems.SetMilsToIUfactor( IU_PER_MILS ); - wsItems.SetSheetNumber( 1 ); + wsItems.SetPageNumber( "1" ); wsItems.SetSheetCount( 1 ); wsItems.SetFileName( "dummyFilename" ); wsItems.SetSheetName( "dummySheet" ); diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index f012a092f9..23ede676e2 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -441,8 +441,8 @@ void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings ) if( screen != NULL ) { - worksheet->SetSheetNumber( screen->m_ScreenNumber ); - worksheet->SetSheetCount( screen->m_NumberOfScreens ); + worksheet->SetPageNumber( TO_UTF8( screen->GetPageNumber() ) ); + worksheet->SetSheetCount( screen->GetPageCount() ); } if( auto board = GetBoard() ) @@ -812,6 +812,7 @@ bool PCB_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent ) return true; } + void PCB_EDIT_FRAME::doCloseWindow() { // On Windows 7 / 32 bits, on OpenGL mode only, Pcbnew crashes diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index cf1999de51..dae00943f6 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -847,7 +847,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask, // Remove initial shapes: each shape will be added later, as flashed item or region // with a suitable attribute. - // Do not merge pads is mandatory in Gerber files: They must be indentified as pads + // Do not merge pads is mandatory in Gerber files: They must be identified as pads // we deflate areas in polygons, to avoid after subtracting initial shapes // having small artifacts due to approximations during polygon transforms @@ -1108,7 +1108,7 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, int aLayer, if( aPlotOpts->GetPlotFrameRef() ) { PlotWorkSheet( plotter, aBoard->GetProject(), aBoard->GetTitleBlock(), - aBoard->GetPageSettings(), 1, 1, aSheetDesc, aBoard->GetFileName() ); + aBoard->GetPageSettings(), "1", 1, aSheetDesc, aBoard->GetFileName() ); if( aPlotOpts->GetMirror() ) initializePlotter( plotter, aBoard, aPlotOpts ); diff --git a/qa/eeschema/CMakeLists.txt b/qa/eeschema/CMakeLists.txt index e58a26200f..daa3632a83 100644 --- a/qa/eeschema/CMakeLists.txt +++ b/qa/eeschema/CMakeLists.txt @@ -56,6 +56,7 @@ set( QA_EESCHEMA_SRCS test_sch_rtree.cpp test_sch_sheet.cpp test_sch_sheet_path.cpp + test_sch_sheet_list.cpp test_sch_symbol.cpp ) diff --git a/qa/eeschema/eeschema_test_utils.cpp b/qa/eeschema/eeschema_test_utils.cpp index 5a9c4c67b4..5bfbe6e5b7 100644 --- a/qa/eeschema/eeschema_test_utils.cpp +++ b/qa/eeschema/eeschema_test_utils.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors. + * Copyright (C) 2019-2020 KiCad Developers, see CHANGELOG.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 @@ -59,11 +59,12 @@ wxFileName KI_TEST::GetEeschemaTestDataDir() return wxFileName{ fn }; } + std::unique_ptr ReadSchematicFromFile( const std::string& aFilename ) { auto pi = SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ); std::unique_ptr schematic( new SCHEMATIC ( nullptr ) ); - + schematic->Reset(); schematic->SetRoot( pi->Load( aFilename, schematic.get() ) ); schematic->CurrentSheet().push_back( &schematic->Root() ); @@ -91,4 +92,4 @@ std::unique_ptr ReadSchematicFromFile( const std::string& aFilename ) schematic->ConnectionGraph()->Recalculate( sheets, true ); return schematic; -} \ No newline at end of file +} diff --git a/qa/eeschema/test_sch_sheet_list.cpp b/qa/eeschema/test_sch_sheet_list.cpp new file mode 100644 index 0000000000..67320e9903 --- /dev/null +++ b/qa/eeschema/test_sch_sheet_list.cpp @@ -0,0 +1,121 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 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 3 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, see . + */ + +#include +#include "eeschema_test_utils.h" + +#include +#include +#include +#include +#include +#include + + +class TEST_SCH_SHEET_LIST_FIXTURE +{ +public: + TEST_SCH_SHEET_LIST_FIXTURE() : + m_schematic( nullptr ) + { + m_pi = SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ); + } + + virtual ~TEST_SCH_SHEET_LIST_FIXTURE() + { + delete m_pi; + } + + void loadSchematic( const wxString& aBaseName ); + + ///> Schematic to load + SCHEMATIC m_schematic; + + SCH_PLUGIN* m_pi; + + SETTINGS_MANAGER m_manager; +}; + + +void TEST_SCH_SHEET_LIST_FIXTURE::loadSchematic( const wxString& aBaseName ) +{ + wxFileName fn = KI_TEST::GetEeschemaTestDataDir(); + + fn.AppendDir( "netlists" ); + fn.AppendDir( aBaseName ); + fn.SetName( aBaseName ); + fn.SetExt( KiCadSchematicFileExtension ); + + BOOST_TEST_MESSAGE( fn.GetFullPath() ); + + wxFileName pro( fn ); + pro.SetExt( ProjectFileExtension ); + + m_manager.LoadProject( pro.GetFullPath() ); + + m_manager.Prj().SetElem( PROJECT::ELEM_SCH_PART_LIBS, nullptr ); + + m_schematic.Reset(); + m_schematic.SetProject( &m_manager.Prj() ); + m_schematic.SetRoot( m_pi->Load( fn.GetFullPath(), &m_schematic ) ); + + BOOST_REQUIRE_EQUAL( m_pi->GetError().IsEmpty(), true ); + + m_schematic.CurrentSheet().push_back( &m_schematic.Root() ); + + SCH_SCREENS screens( m_schematic.Root() ); + + for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() ) + screen->UpdateLocalLibSymbolLinks(); + + SCH_SHEET_LIST sheets = m_schematic.GetSheets(); + + // Restore all of the loaded symbol instances from the root sheet screen. + sheets.UpdateSymbolInstances( m_schematic.RootScreen()->GetSymbolInstances() ); + + sheets.AnnotatePowerSymbols(); + + // NOTE: This is required for multi-unit symbols to be correct + // Normally called from SCH_EDIT_FRAME::FixupJunctions() but could be refactored + for( SCH_SHEET_PATH& sheet : sheets ) + sheet.UpdateAllScreenReferences(); +} + + +BOOST_FIXTURE_TEST_SUITE( SchSheetList, TEST_SCH_SHEET_LIST_FIXTURE ) + + +BOOST_AUTO_TEST_CASE( TestSheetListPageProperties ) +{ + loadSchematic( "complex_hierarchy" ); + + SCH_SHEET_LIST sheets = m_schematic.GetSheets(); + + BOOST_CHECK( sheets.AllSheetPageNumbersEmpty() ); + + sheets.SetInitialPageNumbers(); + + // The root sheet should now be page 1. + BOOST_CHECK_EQUAL( sheets.at( 0 ).GetPageNumber(), "1" ); + BOOST_CHECK_EQUAL( sheets.at( 1 ).GetPageNumber(), "2" ); + BOOST_CHECK_EQUAL( sheets.at( 2 ).GetPageNumber(), "3" ); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/qa/eeschema/test_sch_sheet_path.cpp b/qa/eeschema/test_sch_sheet_path.cpp index 006e1ee566..110403c3a5 100644 --- a/qa/eeschema/test_sch_sheet_path.cpp +++ b/qa/eeschema/test_sch_sheet_path.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2019 KiCad Developers, see CHANGELOG.TXT for contributors. + * Copyright (C) 2019-2020 KiCad Developers, see CHANGELOG.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 @@ -23,7 +23,7 @@ /** * @file - * Test suite for SCH_SHEET_PATH + * Test suite for #SCH_SHEET_PATH and #SCH_SHEET_LIST */ #include @@ -85,7 +85,8 @@ BOOST_AUTO_TEST_CASE( Empty ) BOOST_CHECK_THROW( m_empty_path.at( 0 ), std::out_of_range ); - BOOST_CHECK_EQUAL( m_empty_path.GetPageNumber(), 0 ); + // Sheet paths with no SCH_SCHEET object are illegal. + CHECK_WX_ASSERT( m_empty_path.GetPageNumber() ); // These accessors return nullptr when empty (i.e. they don't crash) BOOST_CHECK_EQUAL( m_empty_path.Last(), nullptr ); @@ -107,8 +108,6 @@ BOOST_AUTO_TEST_CASE( NonEmpty ) BOOST_CHECK_EQUAL( m_linear.at( 1 ), &m_sheets[1] ); BOOST_CHECK_EQUAL( m_linear.at( 2 ), &m_sheets[2] ); - BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), 0 ); - BOOST_CHECK_EQUAL( m_linear.Last(), &m_sheets[2] ); BOOST_CHECK_EQUAL( m_linear.LastScreen(), nullptr ); @@ -130,4 +129,21 @@ BOOST_AUTO_TEST_CASE( Compare ) BOOST_CHECK( m_empty_path != m_linear ); } + +/** + * Test sheet path page number properties. + */ +BOOST_AUTO_TEST_CASE( SheetPathPageProperties ) +{ + BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), wxEmptyString ); + + // Add new instance to sheet object. + BOOST_CHECK( m_linear.Last()->AddInstance( m_linear.Path() ) ); + m_linear.SetPageNumber( "1" ); + BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), "1" ); + m_linear.SetPageNumber( "i" ); + BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), "i" ); +} + + BOOST_AUTO_TEST_SUITE_END()