Property popups for symbols, labels, sheets, and footprints in PDF.
Fixes https://gitlab.com/kicad/code/kicad/issues/5521
This commit is contained in:
parent
c337c12410
commit
8afc1db7a6
|
@ -38,10 +38,10 @@
|
|||
#include <ignore.h>
|
||||
#include <macros.h>
|
||||
#include <trigo.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
#include <plotters/plotters_pslike.h>
|
||||
|
||||
|
||||
std::string PDF_PLOTTER::encodeStringForPlotter( const wxString& aText )
|
||||
{
|
||||
// returns a string compatible with PDF string convention from a unicode string.
|
||||
|
@ -709,13 +709,14 @@ void PDF_PLOTTER::ClosePage()
|
|||
const double PTsPERMIL = 0.072;
|
||||
VECTOR2D psPaperSize = VECTOR2D( m_pageInfo.GetSizeMils() ) * PTsPERMIL;
|
||||
|
||||
auto iuToPdfUserSpace = [&]( const VECTOR2I& aCoord ) -> VECTOR2D
|
||||
{
|
||||
VECTOR2D retval = VECTOR2D( aCoord ) * PTsPERMIL / SCH_IU_PER_MILS;
|
||||
// PDF y=0 is at bottom of page, invert coordinate
|
||||
retval.y = psPaperSize.y - retval.y;
|
||||
return retval;
|
||||
};
|
||||
auto iuToPdfUserSpace =
|
||||
[&]( const VECTOR2I& aCoord ) -> VECTOR2D
|
||||
{
|
||||
VECTOR2D retval = VECTOR2D( aCoord ) * PTsPERMIL / ( m_IUsPerDecimil * 10 );
|
||||
// PDF y=0 is at bottom of page, invert coordinate
|
||||
retval.y = psPaperSize.y - retval.y;
|
||||
return retval;
|
||||
};
|
||||
|
||||
// Handle annotations (at the moment only "link" type objects)
|
||||
std::vector<int> hyperlinkHandles;
|
||||
|
@ -955,31 +956,45 @@ bool PDF_PLOTTER::EndPlot()
|
|||
const BOX2D& box = menuPair.first;
|
||||
const std::vector<wxString>& urls = menuPair.second;
|
||||
|
||||
// We currently only support menu links for internal pages. This vector holds the
|
||||
// page names and numbers.
|
||||
std::vector<std::pair<wxString, int>> pages;
|
||||
// We currently only support menu links for internal pages and property lists.
|
||||
// This vector holds the menu titles and (optional) page numbers.
|
||||
std::vector<std::pair<wxString, int>> menuItems;
|
||||
|
||||
for( const wxString& url : urls )
|
||||
{
|
||||
wxString pageNumber;
|
||||
|
||||
if( EDA_TEXT::IsGotoPageHref( url, &pageNumber ) )
|
||||
if( url.StartsWith( "!" ) )
|
||||
{
|
||||
menuItems.push_back( { url.AfterFirst( '!' ), -1 } );
|
||||
}
|
||||
else if( EDA_TEXT::IsGotoPageHref( url, &pageNumber ) )
|
||||
{
|
||||
for( size_t ii = 0; ii < m_pageNumbers.size(); ++ii )
|
||||
{
|
||||
if( m_pageNumbers[ii] == pageNumber )
|
||||
pages.push_back( { pageNumber, ii } );
|
||||
menuItems.push_back( { pageNumber, ii } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxString js = wxT( "var aParams = [ " );
|
||||
|
||||
for( const std::pair<wxString, int>& page : pages )
|
||||
for( const std::pair<wxString, int>& menuItem : menuItems )
|
||||
{
|
||||
js += wxString::Format( wxT( "{ cName: '%s', cReturn: '%d' }, " ),
|
||||
wxString::Format( _( "Show Page %s" ), page.first ),
|
||||
page.second );
|
||||
if( menuItem.second < 0 )
|
||||
{
|
||||
js += wxString::Format( wxT( "{ cName: '%s', cReturn: null }, " ),
|
||||
EscapeString( menuItem.first, CTX_JS_STR ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString menuText = wxString::Format( _( "Show Page %s" ), menuItem.first );
|
||||
|
||||
js += wxString::Format( wxT( "{ cName: '%s', cReturn: '%d' }, " ),
|
||||
EscapeString( menuText, CTX_JS_STR ),
|
||||
menuItem.second );
|
||||
}
|
||||
}
|
||||
|
||||
js += wxT( "]; " );
|
||||
|
|
|
@ -195,6 +195,13 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
|
|||
else
|
||||
converted += c;
|
||||
}
|
||||
else if( aContext == CTX_JS_STR )
|
||||
{
|
||||
if( c == '\'' )
|
||||
converted += wxT( "{quote}" );
|
||||
else
|
||||
converted += c;
|
||||
}
|
||||
else if( aContext == CTX_LINE )
|
||||
{
|
||||
if( c == '\n' || c == '\r' )
|
||||
|
|
|
@ -912,6 +912,20 @@ void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground ) const
|
|||
|
||||
for( const SCH_FIELD& field : m_fields )
|
||||
field.Plot( aPlotter, aBackground );
|
||||
|
||||
if( !m_fields.empty() )
|
||||
{
|
||||
std::vector<wxString> properties;
|
||||
|
||||
for( const SCH_FIELD& field : GetFields() )
|
||||
{
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||
field.GetName(),
|
||||
field.GetShownText() ) );
|
||||
}
|
||||
|
||||
aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1075,14 +1075,19 @@ void SCH_SHEET::Plot( PLOTTER* aPlotter, bool aBackground ) const
|
|||
}
|
||||
|
||||
// Make the sheet object a clickable hyperlink (e.g. for PDF plotter)
|
||||
if( !aBackground )
|
||||
{
|
||||
BOX2I rect( m_pos, m_size );
|
||||
wxString pageNum = GetPageNumber( getSheetPath() );
|
||||
std::vector<wxString> properties;
|
||||
|
||||
aPlotter->HyperlinkBox( rect, EDA_TEXT::GotoPageHref( pageNum ) );
|
||||
properties.emplace_back( EDA_TEXT::GotoPageHref( GetPageNumber( getSheetPath() ) ) );
|
||||
|
||||
for( const SCH_FIELD& field : GetFields() )
|
||||
{
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||
field.GetName(),
|
||||
field.GetShownText() ) );
|
||||
}
|
||||
|
||||
aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
|
||||
|
||||
// Plot sheet pins
|
||||
for( SCH_SHEET_PIN* sheetPin : m_pins )
|
||||
sheetPin->Plot( aPlotter, aBackground );
|
||||
|
|
|
@ -2006,6 +2006,20 @@ void SCH_SYMBOL::Plot( PLOTTER* aPlotter, bool aBackground ) const
|
|||
field.Plot( aPlotter, local_background );
|
||||
}
|
||||
|
||||
std::vector<wxString> properties;
|
||||
|
||||
for( const SCH_FIELD& field : GetFields() )
|
||||
{
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||
field.GetName(),
|
||||
field.GetShownText() ) );
|
||||
}
|
||||
|
||||
properties.emplace_back( _( "!Description = " ) + m_part->GetDescription() );
|
||||
properties.emplace_back( _( "!Keywords = " ) + m_part->GetKeyWords() );
|
||||
|
||||
aPlotter->HyperlinkMenu( GetBoundingBox(), properties );
|
||||
|
||||
aPlotter->EndBlock( nullptr );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ enum ESCAPE_CONTEXT
|
|||
CTX_LIBID,
|
||||
CTX_IPC,
|
||||
CTX_QUOTED_STR,
|
||||
CTX_JS_STR,
|
||||
CTX_LINE,
|
||||
CTX_CSV,
|
||||
CTX_FILENAME,
|
||||
|
|
|
@ -1075,6 +1075,7 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
|
|||
if( plotter )
|
||||
{
|
||||
PlotBoardLayers( board, plotter, plotSequence, m_plotOpts );
|
||||
PlotInteractiveLayer( board, plotter );
|
||||
plotter->EndPlot();
|
||||
delete plotter->RenderSettings();
|
||||
delete plotter;
|
||||
|
|
|
@ -158,6 +158,11 @@ PLOTTER* StartPlotBoard( BOARD* aBoard, const PCB_PLOT_PARAMS* aPlotOpts, int aL
|
|||
void PlotBoardLayers( BOARD* aBoard, PLOTTER* aPlotter, const LSEQ& aLayerSequence,
|
||||
const PCB_PLOT_PARAMS& aPlotOptions );
|
||||
|
||||
/**
|
||||
* Plot interactive items (hypertext links, properties, etc.).
|
||||
*/
|
||||
void PlotInteractiveLayer( BOARD* aBoard, PLOTTER* aPlotter );
|
||||
|
||||
/**
|
||||
* Plot one copper or technical layer.
|
||||
*
|
||||
|
|
|
@ -76,6 +76,40 @@ void PlotBoardLayers( BOARD* aBoard, PLOTTER* aPlotter, const LSEQ& aLayers,
|
|||
}
|
||||
|
||||
|
||||
void PlotInteractiveLayer( BOARD* aBoard, PLOTTER* aPlotter )
|
||||
{
|
||||
for( const FOOTPRINT* fp : aBoard->Footprints() )
|
||||
{
|
||||
std::vector<wxString> properties;
|
||||
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||
_( "Reference designator" ),
|
||||
fp->Reference().GetShownText() ) );
|
||||
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||
_( "Value" ),
|
||||
fp->Value().GetShownText() ) );
|
||||
|
||||
for( const auto& [ name, value ] : fp->GetProperties() )
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), name, value ) );
|
||||
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||
_( "Footprint" ),
|
||||
fp->GetFPIDAsString() ) );
|
||||
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||
_( "Description" ),
|
||||
fp->GetDescription() ) );
|
||||
|
||||
properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
|
||||
_( "Keywords" ),
|
||||
fp->GetKeywords() ) );
|
||||
|
||||
aPlotter->HyperlinkMenu( fp->GetBoundingBox(), properties );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PlotOneBoardLayer( BOARD *aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
|
||||
const PCB_PLOT_PARAMS& aPlotOpt )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue