From 840bcffefb7f9108b72eeba715536c4320fe9bee Mon Sep 17 00:00:00 2001 From: Roberto Fernandez Bautista Date: Sat, 14 May 2022 15:52:53 +0200 Subject: [PATCH] ADDED: Hyperlinks on text items in Schematic Editor --- common/eda_text.cpp | 20 +- eeschema/dialogs/dialog_text_properties.cpp | 35 +- eeschema/dialogs/dialog_text_properties.h | 1 + .../dialogs/dialog_text_properties_base.cpp | 82 ++-- .../dialogs/dialog_text_properties_base.fbp | 421 ++++++++++++++---- .../dialogs/dialog_text_properties_base.h | 21 +- eeschema/sch_field.cpp | 2 +- eeschema/sch_field.h | 4 +- eeschema/sch_file_versions.h | 3 +- eeschema/sch_item.h | 2 +- .../sch_plugins/kicad/sch_sexpr_parser.cpp | 21 +- eeschema/sch_text.cpp | 18 + eeschema/sch_text.h | 4 + eeschema/sch_textbox.cpp | 3 + eeschema/schematic.keywords | 1 + include/eda_text.h | 19 + .../dialogs/dialog_text_properties_base.fbp | 16 +- 17 files changed, 532 insertions(+), 141 deletions(-) diff --git a/common/eda_text.cpp b/common/eda_text.cpp index d6381fdb97..50e7024246 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -56,6 +56,7 @@ #include // for wxASSERT #include #include // for wxPoint, wxSize +#include // for wxURL class OUTPUTFORMATTER; class wxFindReplaceData; @@ -836,11 +837,15 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl aFormatter->Print( 0, ")" ); // (justify } - if( !(aControlBits & CTL_OMIT_HIDE) && !IsVisible() ) + if( !( aControlBits & CTL_OMIT_HIDE ) && !IsVisible() ) aFormatter->Print( 0, " hide" ); - aFormatter->Print( 0, ")\n" ); // (justify + if( HasHyperlink() ) + { + aFormatter->Print( 0, " (href %s)", aFormatter->Quotew( GetHyperlink() ).c_str() ); + } + aFormatter->Print( 0, ")\n" ); // (effects #endif } @@ -974,6 +979,14 @@ void EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( SHAPE_POLY_SET* aCorn } +bool EDA_TEXT::ValidateHyperlink( const wxString& aURL ) +{ + wxURL url; + + return aURL.IsEmpty() || url.SetURL( aURL ) == wxURL_NOERR; +} + + static struct EDA_TEXT_DESC { EDA_TEXT_DESC() @@ -992,6 +1005,9 @@ static struct EDA_TEXT_DESC propMgr.AddProperty( new PROPERTY( _HKI( "Text" ), &EDA_TEXT::SetText, &EDA_TEXT::GetText ) ); + propMgr.AddProperty( new PROPERTY( _HKI( "Hyperlink" ), + &EDA_TEXT::SetHyperlink, + &EDA_TEXT::GetHyperlink ) ); propMgr.AddProperty( new PROPERTY( _HKI( "Thickness" ), &EDA_TEXT::SetTextThickness, &EDA_TEXT::GetTextThickness, diff --git a/eeschema/dialogs/dialog_text_properties.cpp b/eeschema/dialogs/dialog_text_properties.cpp index 1372c8b167..a5224fcb9a 100644 --- a/eeschema/dialogs/dialog_text_properties.cpp +++ b/eeschema/dialogs/dialog_text_properties.cpp @@ -70,7 +70,7 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_ITE if( m_frame->GetColorSettings()->GetOverrideSchItemColors() ) m_infoBar->ShowMessage( _( "Note: individual item colors overridden in Preferences." ) ); - } + } else { m_spin1->Show( false ); @@ -158,6 +158,10 @@ bool DIALOG_TEXT_PROPERTIES::TransferDataToWindow() SCHEMATIC& schematic = m_frame->Schematic(); + m_hyperlinkCb->SetValue( static_cast( m_currentItem )->IsHypertext() ); + m_hyperlinkCtrl->Enable( static_cast( m_currentItem )->IsHypertext() ); + m_hyperlinkCtrl->SetValue( static_cast( m_currentItem )->GetHyperlink() ); + // show text variable cross-references in a human-readable format m_textCtrl->SetValue( schematic.ConvertKIIDsToRefs( m_currentText->GetText() ) ); @@ -260,6 +264,25 @@ void DIALOG_TEXT_PROPERTIES::onFillChecked( wxCommandEvent& event ) } +void DIALOG_TEXT_PROPERTIES::onHyperlinkChecked( wxCommandEvent& aEvent ) +{ + if( aEvent.IsChecked() ) + { + m_hyperlinkCtrl->Enable( true ); + m_hyperlinkDestinationLabel->Enable( true ); + m_hyperlinkCtrl->SetFocus(); + } + else + { + m_hyperlinkCtrl->Enable( false ); + m_hyperlinkDestinationLabel->Enable( false ); + m_hyperlinkCtrl->SetValue( wxEmptyString ); + } + + aEvent.Skip(); +} + + void DIALOG_TEXT_PROPERTIES::onScintillaCharAdded( wxStyledTextEvent &aEvent ) { wxStyledTextCtrl* te = m_textCtrl; @@ -379,6 +402,16 @@ bool DIALOG_TEXT_PROPERTIES::TransferDataFromWindow() return false; } + if( !m_currentText->ValidateHyperlink( m_hyperlinkCtrl->GetValue() ) ) + { + DisplayError( this, _( "Invalid hyperlink destination (URL)." ) ); + return false; + } + else + { + m_currentText->SetHyperlink( m_hyperlinkCtrl->GetValue() ); + } + if( m_currentText->GetTextWidth() != m_textSize.GetValue() ) m_currentText->SetTextSize( wxSize( m_textSize.GetValue(), m_textSize.GetValue() ) ); diff --git a/eeschema/dialogs/dialog_text_properties.h b/eeschema/dialogs/dialog_text_properties.h index eb055bd5d4..81815ac34f 100644 --- a/eeschema/dialogs/dialog_text_properties.h +++ b/eeschema/dialogs/dialog_text_properties.h @@ -46,6 +46,7 @@ private: void onSpinButton( wxCommandEvent &aEvent ); void onBorderChecked( wxCommandEvent& event ) override; void onFillChecked( wxCommandEvent& event ) override; + void onHyperlinkChecked( wxCommandEvent& aEvent ) override; void OnFormattingHelp( wxHyperlinkEvent& aEvent ) override; void onMultiLineTCLostFocus( wxFocusEvent& event ) override; diff --git a/eeschema/dialogs/dialog_text_properties_base.cpp b/eeschema/dialogs/dialog_text_properties_base.cpp index 4f09a86613..9a03a90747 100644 --- a/eeschema/dialogs/dialog_text_properties_base.cpp +++ b/eeschema/dialogs/dialog_text_properties_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -46,6 +46,7 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi m_textCtrl->SetViewWhiteSpace( false ); m_textCtrl->SetMarginWidth( 2, 0 ); m_textCtrl->SetIndentationGuides( false ); + m_textCtrl->SetReadOnly( false ); m_textCtrl->SetMarginWidth( 1, 0 ); m_textCtrl->SetMarginWidth( 0, 0 ); m_textCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS ); @@ -69,15 +70,52 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi m_textEntrySizer->Add( m_textCtrl, wxGBPosition( 0, 1 ), wxGBSpan( 1, 5 ), wxEXPAND, 5 ); + wxBoxSizer* bSizer41; + bSizer41 = new wxBoxSizer( wxVERTICAL ); + + m_syntaxHelp = new wxHyperlinkCtrl( this, wxID_ANY, _("Syntax help"), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + m_syntaxHelp->SetToolTip( _("Show syntax help window") ); + + bSizer41->Add( m_syntaxHelp, 0, wxBOTTOM|wxRIGHT|wxLEFT, 6 ); + + + m_textEntrySizer->Add( bSizer41, wxGBPosition( 1, 5 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_RIGHT|wxLEFT, 80 ); + + wxBoxSizer* bSizer11; + bSizer11 = new wxBoxSizer( wxHORIZONTAL ); + + m_hyperlinkCb = new wxCheckBox( this, wxID_ANY, _("Hyperlink"), wxDefaultPosition, wxDefaultSize, 0 ); + m_hyperlinkCb->SetToolTip( _("Make this text item a clickable hyperlink") ); + + bSizer11->Add( m_hyperlinkCb, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + + bSizer11->Add( 10, 0, 0, wxEXPAND, 5 ); + + m_hyperlinkDestinationLabel = new wxStaticText( this, wxID_ANY, _("Destination (URL):"), wxDefaultPosition, wxDefaultSize, 0 ); + m_hyperlinkDestinationLabel->Wrap( -1 ); + m_hyperlinkDestinationLabel->Enable( false ); + + bSizer11->Add( m_hyperlinkDestinationLabel, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + m_hyperlinkCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); + m_hyperlinkCtrl->Enable( false ); + m_hyperlinkCtrl->SetToolTip( _("Please enter a file:// or http(s):// URL") ); + + bSizer11->Add( m_hyperlinkCtrl, 10, wxALL, 5 ); + + + m_textEntrySizer->Add( bSizer11, wxGBPosition( 2, 0 ), wxGBSpan( 1, 6 ), wxEXPAND, 5 ); + m_fontLabel = new wxStaticText( this, wxID_ANY, _("Font:"), wxDefaultPosition, wxDefaultSize, 0 ); m_fontLabel->Wrap( -1 ); - m_textEntrySizer->Add( m_fontLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxTOP, 5 ); + m_textEntrySizer->Add( m_fontLabel, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxTOP, 5 ); wxString m_fontCtrlChoices[] = { _("Default Font"), _("KiCad Font") }; int m_fontCtrlNChoices = sizeof( m_fontCtrlChoices ) / sizeof( wxString ); m_fontCtrl = new FONT_CHOICE( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_fontCtrlNChoices, m_fontCtrlChoices, 0 ); m_fontCtrl->SetSelection( 0 ); - m_textEntrySizer->Add( m_fontCtrl, wxGBPosition( 1, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP, 5 ); + m_textEntrySizer->Add( m_fontCtrl, wxGBPosition( 3, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP, 5 ); wxBoxSizer* bSizeCtrlSizer; bSizeCtrlSizer = new wxBoxSizer( wxHORIZONTAL ); @@ -138,28 +176,17 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi bSizeCtrlSizer->Add( m_separator3, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_textEntrySizer->Add( bSizeCtrlSizer, wxGBPosition( 1, 3 ), wxGBSpan( 1, 2 ), wxEXPAND|wxTOP, 5 ); - - wxBoxSizer* bSizer41; - bSizer41 = new wxBoxSizer( wxVERTICAL ); - - m_syntaxHelp = new wxHyperlinkCtrl( this, wxID_ANY, _("Syntax help"), wxEmptyString, wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); - m_syntaxHelp->SetToolTip( _("Show syntax help window") ); - - bSizer41->Add( m_syntaxHelp, 0, wxBOTTOM|wxRIGHT|wxLEFT, 6 ); - - - m_textEntrySizer->Add( bSizer41, wxGBPosition( 1, 5 ), wxGBSpan( 1, 1 ), wxEXPAND|wxALIGN_RIGHT|wxLEFT, 80 ); + m_textEntrySizer->Add( bSizeCtrlSizer, wxGBPosition( 3, 3 ), wxGBSpan( 1, 2 ), wxEXPAND|wxTOP, 5 ); m_textSizeLabel = new wxStaticText( this, wxID_ANY, _("Text size:"), wxDefaultPosition, wxDefaultSize, 0 ); m_textSizeLabel->Wrap( -1 ); - m_textEntrySizer->Add( m_textSizeLabel, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); + m_textEntrySizer->Add( m_textSizeLabel, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer71; bSizer71 = new wxBoxSizer( wxHORIZONTAL ); m_textSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer71->Add( m_textSizeCtrl, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer71->Add( m_textSizeCtrl, 0, wxEXPAND, 5 ); m_textSizeUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 ); m_textSizeUnits->Wrap( -1 ); @@ -186,20 +213,20 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi bSizer71->Add( m_panelBorderColor1, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_textEntrySizer->Add( bSizer71, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxEXPAND, 5 ); + m_textEntrySizer->Add( bSizer71, wxGBPosition( 4, 1 ), wxGBSpan( 1, 1 ), wxEXPAND, 5 ); m_borderCheckbox = new wxCheckBox( this, wxID_ANY, _("Border"), wxDefaultPosition, wxDefaultSize, 0 ); - m_textEntrySizer->Add( m_borderCheckbox, wxGBPosition( 4, 0 ), wxGBSpan( 1, 2 ), wxBOTTOM, 2 ); + m_textEntrySizer->Add( m_borderCheckbox, wxGBPosition( 6, 0 ), wxGBSpan( 1, 2 ), wxBOTTOM, 2 ); m_borderWidthLabel = new wxStaticText( this, wxID_ANY, _("Width:"), wxDefaultPosition, wxDefaultSize, 0 ); m_borderWidthLabel->Wrap( -1 ); - m_textEntrySizer->Add( m_borderWidthLabel, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); + m_textEntrySizer->Add( m_borderWidthLabel, wxGBPosition( 7, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); wxBoxSizer* bSizer7; bSizer7 = new wxBoxSizer( wxHORIZONTAL ); m_borderWidthCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 ); - bSizer7->Add( m_borderWidthCtrl, 0, wxALIGN_CENTER_VERTICAL, 5 ); + bSizer7->Add( m_borderWidthCtrl, 0, wxEXPAND, 5 ); m_borderWidthUnits = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 ); m_borderWidthUnits->Wrap( -1 ); @@ -226,19 +253,19 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi bSizer7->Add( m_panelBorderColor, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_textEntrySizer->Add( bSizer7, wxGBPosition( 5, 1 ), wxGBSpan( 1, 2 ), wxEXPAND, 5 ); + m_textEntrySizer->Add( bSizer7, wxGBPosition( 7, 1 ), wxGBSpan( 1, 2 ), wxEXPAND, 5 ); m_borderStyleLabel = new wxStaticText( this, wxID_ANY, _("Style:"), wxDefaultPosition, wxDefaultSize, 0 ); m_borderStyleLabel->Wrap( -1 ); - m_textEntrySizer->Add( m_borderStyleLabel, wxGBPosition( 6, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); + m_textEntrySizer->Add( m_borderStyleLabel, wxGBPosition( 8, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); m_borderStyleCombo = new wxBitmapComboBox( this, wxID_ANY, _("Combo!"), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY ); m_borderStyleCombo->SetMinSize( wxSize( 240,-1 ) ); - m_textEntrySizer->Add( m_borderStyleCombo, wxGBPosition( 6, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + m_textEntrySizer->Add( m_borderStyleCombo, wxGBPosition( 8, 1 ), wxGBSpan( 1, 2 ), wxEXPAND, 5 ); m_filledCtrl = new wxCheckBox( this, wxID_ANY, _("Background fill"), wxDefaultPosition, wxDefaultSize, 0 ); - m_textEntrySizer->Add( m_filledCtrl, wxGBPosition( 4, 4 ), wxGBSpan( 1, 2 ), wxRIGHT, 80 ); + m_textEntrySizer->Add( m_filledCtrl, wxGBPosition( 6, 4 ), wxGBSpan( 1, 2 ), wxRIGHT, 80 ); wxBoxSizer* bSizer8; bSizer8 = new wxBoxSizer( wxHORIZONTAL ); @@ -261,7 +288,7 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi bSizer8->Add( m_panelFillColor, 0, wxALIGN_CENTER_VERTICAL, 5 ); - m_textEntrySizer->Add( bSizer8, wxGBPosition( 5, 4 ), wxGBSpan( 1, 2 ), wxEXPAND, 5 ); + m_textEntrySizer->Add( bSizer8, wxGBPosition( 7, 4 ), wxGBSpan( 1, 2 ), wxEXPAND, 5 ); m_textEntrySizer->AddGrowableCol( 3 ); @@ -289,11 +316,11 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi this->SetSizer( bMainSizer ); this->Layout(); - bMainSizer->Fit( this ); // Connect Events m_textCtrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_TEXT_PROPERTIES_BASE::onMultiLineTCLostFocus ), NULL, this ); m_syntaxHelp->Connect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( DIALOG_TEXT_PROPERTIES_BASE::OnFormattingHelp ), NULL, this ); + m_hyperlinkCb->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEXT_PROPERTIES_BASE::onHyperlinkChecked ), NULL, this ); m_borderCheckbox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEXT_PROPERTIES_BASE::onBorderChecked ), NULL, this ); m_filledCtrl->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEXT_PROPERTIES_BASE::onFillChecked ), NULL, this ); } @@ -303,6 +330,7 @@ DIALOG_TEXT_PROPERTIES_BASE::~DIALOG_TEXT_PROPERTIES_BASE() // Disconnect Events m_textCtrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_TEXT_PROPERTIES_BASE::onMultiLineTCLostFocus ), NULL, this ); m_syntaxHelp->Disconnect( wxEVT_COMMAND_HYPERLINK, wxHyperlinkEventHandler( DIALOG_TEXT_PROPERTIES_BASE::OnFormattingHelp ), NULL, this ); + m_hyperlinkCb->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEXT_PROPERTIES_BASE::onHyperlinkChecked ), NULL, this ); m_borderCheckbox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEXT_PROPERTIES_BASE::onBorderChecked ), NULL, this ); m_filledCtrl->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TEXT_PROPERTIES_BASE::onFillChecked ), NULL, this ); diff --git a/eeschema/dialogs/dialog_text_properties_base.fbp b/eeschema/dialogs/dialog_text_properties_base.fbp index 1304d42e46..0b85592984 100644 --- a/eeschema/dialogs/dialog_text_properties_base.fbp +++ b/eeschema/dialogs/dialog_text_properties_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -14,6 +14,7 @@ dialog_text_properties_base 1000 none + 1 dialog_text_properties_base @@ -25,6 +26,7 @@ 1 1 UI + 0 1 0 @@ -45,11 +47,12 @@ DIALOG_TEXT_PROPERTIES_BASE - -1,-1 + 778,449 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Text Properties + 0 @@ -250,6 +253,7 @@ protected 1 + 0 Resizable 1 @@ -267,12 +271,304 @@ onMultiLineTCLostFocus + + 80 + 1 + 5 + wxEXPAND|wxALIGN_RIGHT|wxLEFT + 1 + 1 + + + bSizer41 + wxVERTICAL + none + + 6 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + + wxID_ANY + Syntax help + + 0 + + + 0 + + 1 + m_syntaxHelp + + 1 + + + protected + 1 + + Resizable + 1 + + wxHL_DEFAULT_STYLE + ; ; forward_declare + 0 + Show syntax help window + + + + + + OnFormattingHelp + + + + + + 5 + 6 + 0 + wxEXPAND + 2 + 1 + + + bSizer11 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Hyperlink + + 0 + + + 0 + + 1 + m_hyperlinkCb + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + Make this text item a clickable hyperlink + + wxFILTER_NONE + wxDefaultValidator + + + + + onHyperlinkChecked + + + + 5 + wxEXPAND + 0 + + 0 + protected + 10 + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + + 1 + + 0 + 0 + wxID_ANY + Destination (URL): + 0 + + 0 + + + 0 + + 1 + m_hyperlinkDestinationLabel + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + wxALL + 10 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + 0 + -1,-1 + 0 + -1,-1 + 1 + m_hyperlinkCtrl + 1 + + + protected + 1 + + Resizable + 1 + -1,-1 + + + 0 + Please enter a file:// or http(s):// URL + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 1 0 wxALIGN_CENTER_VERTICAL|wxTOP - 1 + 3 1 1 @@ -336,7 +632,7 @@ 2 1 wxALIGN_CENTER_VERTICAL|wxEXPAND|wxTOP - 1 + 3 1 1 @@ -403,7 +699,7 @@ 2 3 wxEXPAND|wxTOP - 1 + 3 1 @@ -423,6 +719,7 @@ + 0 @@ -495,6 +792,7 @@ + 0 @@ -567,6 +865,7 @@ + 0 @@ -639,6 +938,7 @@ + 0 @@ -711,6 +1011,7 @@ + 0 @@ -783,6 +1084,7 @@ + 0 @@ -855,6 +1157,7 @@ + 0 @@ -927,6 +1230,7 @@ + 0 @@ -999,6 +1303,7 @@ + 0 @@ -1071,6 +1376,7 @@ + 0 @@ -1143,6 +1449,7 @@ + 0 @@ -1204,90 +1511,12 @@ - - 80 - 1 - 5 - wxEXPAND|wxALIGN_RIGHT|wxLEFT - 1 - 1 - - - bSizer41 - wxVERTICAL - none - - 6 - wxBOTTOM|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - - wxID_ANY - Syntax help - - 0 - - - 0 - - 1 - m_syntaxHelp - - 1 - - - protected - 1 - - Resizable - 1 - - wxHL_DEFAULT_STYLE - ; ; forward_declare - 0 - Show syntax help window - - - - - - OnFormattingHelp - - - - 5 1 0 wxALIGN_CENTER_VERTICAL - 2 + 4 1 1 @@ -1351,7 +1580,7 @@ 1 1 wxEXPAND - 2 + 4 1 @@ -1360,7 +1589,7 @@ none 5 - wxALIGN_CENTER_VERTICAL + wxEXPAND 0 1 @@ -1686,7 +1915,7 @@ 2 0 wxBOTTOM - 4 + 6 1 1 @@ -1754,7 +1983,7 @@ 1 0 wxALIGN_CENTER_VERTICAL - 5 + 7 1 1 @@ -1818,7 +2047,7 @@ 2 1 wxEXPAND - 5 + 7 1 @@ -1827,7 +2056,7 @@ none 5 - wxALIGN_CENTER_VERTICAL + wxEXPAND 0 1 @@ -2076,7 +2305,7 @@ wxBORDER_SIMPLE|wxTAB_TRAVERSAL - + bSizer2 wxVERTICAL @@ -2153,7 +2382,7 @@ 1 0 wxALIGN_CENTER_VERTICAL - 6 + 8 1 1 @@ -2216,8 +2445,8 @@ 5 2 1 - wxALIGN_CENTER_VERTICAL|wxEXPAND - 6 + wxEXPAND + 8 1 1 @@ -2285,7 +2514,7 @@ 2 4 wxRIGHT - 4 + 6 1 1 @@ -2353,7 +2582,7 @@ 2 4 wxEXPAND - 5 + 7 1 diff --git a/eeschema/dialogs/dialog_text_properties_base.h b/eeschema/dialogs/dialog_text_properties_base.h index d9619b2ca9..72e71dbc70 100644 --- a/eeschema/dialogs/dialog_text_properties_base.h +++ b/eeschema/dialogs/dialog_text_properties_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Oct 26 2018) +// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -24,17 +24,17 @@ class WX_INFOBAR; #include #include #include +#include +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include #include -#include #include #include #include @@ -54,6 +54,10 @@ class DIALOG_TEXT_PROPERTIES_BASE : public DIALOG_SHIM wxGridBagSizer* m_textEntrySizer; wxStaticText* m_textLabel; wxStyledTextCtrl* m_textCtrl; + wxHyperlinkCtrl* m_syntaxHelp; + wxCheckBox* m_hyperlinkCb; + wxStaticText* m_hyperlinkDestinationLabel; + wxTextCtrl* m_hyperlinkCtrl; wxStaticText* m_fontLabel; FONT_CHOICE* m_fontCtrl; BITMAP_BUTTON* m_separator1; @@ -67,7 +71,6 @@ class DIALOG_TEXT_PROPERTIES_BASE : public DIALOG_SHIM BITMAP_BUTTON* m_spin4; BITMAP_BUTTON* m_spin5; BITMAP_BUTTON* m_separator3; - wxHyperlinkCtrl* m_syntaxHelp; wxStaticText* m_textSizeLabel; wxTextCtrl* m_textSizeCtrl; wxStaticText* m_textSizeUnits; @@ -92,16 +95,18 @@ class DIALOG_TEXT_PROPERTIES_BASE : public DIALOG_SHIM wxButton* m_sdbSizer1OK; wxButton* m_sdbSizer1Cancel; - // Virtual event handlers, overide them in your derived class + // Virtual event handlers, override them in your derived class virtual void onMultiLineTCLostFocus( wxFocusEvent& event ) { event.Skip(); } virtual void OnFormattingHelp( wxHyperlinkEvent& event ) { event.Skip(); } + virtual void onHyperlinkChecked( wxCommandEvent& event ) { event.Skip(); } virtual void onBorderChecked( wxCommandEvent& event ) { event.Skip(); } virtual void onFillChecked( wxCommandEvent& event ) { event.Skip(); } public: - DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 778,449 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~DIALOG_TEXT_PROPERTIES_BASE(); }; diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index 5d7dfa8e14..b01c71d0eb 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -736,7 +736,7 @@ void SCH_FIELD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vectorType() == SCH_GLOBAL_LABEL_T; } - void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) override; + virtual void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) const override; /** * Return the field name (not translated).. diff --git a/eeschema/sch_file_versions.h b/eeschema/sch_file_versions.h index 2954b56586..9addb21c5c 100644 --- a/eeschema/sch_file_versions.h +++ b/eeschema/sch_file_versions.h @@ -82,4 +82,5 @@ //#define SEXPR_SCHEMATIC_FILE_VERSION 20220331 // Text colors //#define SEXPR_SCHEMATIC_FILE_VERSION 20220404 // Default schematic symbol instance data. //#define SEXPR_SCHEMATIC_FILE_VERSION 20220622 // New simulation model format. -#define SEXPR_SCHEMATIC_FILE_VERSION 20220820 // Fix broken default symbol instance data. +//#define SEXPR_SCHEMATIC_FILE_VERSION 20220820 // Fix broken default symbol instance data. +#define SEXPR_SCHEMATIC_FILE_VERSION 20220822 // Hyperlinks in text objects diff --git a/eeschema/sch_item.h b/eeschema/sch_item.h index f5239c7de6..7e85422a65 100644 --- a/eeschema/sch_item.h +++ b/eeschema/sch_item.h @@ -236,7 +236,7 @@ public: */ virtual bool IsHypertext() const { return false; } - virtual void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) { } + virtual void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) const { } /** * Return the layer this item is on. diff --git a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp index 1c247472b1..db8c1a7a26 100644 --- a/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp +++ b/eeschema/sch_plugins/kicad/sch_sexpr_parser.cpp @@ -628,12 +628,31 @@ void SCH_SEXPR_PARSER::parseEDA_TEXT( EDA_TEXT* aText, bool aConvertOverbarSynta break; + case T_href: + { + NeedSYMBOL(); + wxString hyperlink = FromUTF8(); + + if( !aText->ValidateHyperlink( hyperlink ) ) + { + THROW_PARSE_ERROR( wxString::Format( _( "Invalid hyperlink url '%s'" ), hyperlink ), + CurSource(), CurLine(), CurLineNumber(), CurOffset() ); + } + else + { + aText->SetHyperlink( hyperlink ); + } + + NeedRIGHT(); + } + break; + case T_hide: aText->SetVisible( false ); break; default: - Expecting( "font, justify, or hide" ); + Expecting( "font, justify, hide or href" ); } } } diff --git a/eeschema/sch_text.cpp b/eeschema/sch_text.cpp index c446078a63..44ca96282f 100644 --- a/eeschema/sch_text.cpp +++ b/eeschema/sch_text.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -382,6 +383,20 @@ wxString SCH_TEXT::GetShownText( int aDepth ) const } +void SCH_TEXT::DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) const +{ + wxCHECK_MSG( IsHypertext(), /* void */, + "Calling a hypertext menu on a SCH_TEXT with no hyperlink?" ); + + wxMenu menu; + menu.Append( 1, wxString::Format( _( "Open %s" ), m_hyperlink ) ); + int sel = aFrame->GetPopupMenuSelectionFromUser( menu ); + + if( sel == 1 ) + GetAssociatedDocument( aFrame, m_hyperlink, &aFrame->Prj() ); +} + + wxString SCH_TEXT::GetSelectMenuText( EDA_UNITS aUnits ) const { return wxString::Format( _( "Graphic Text '%s'" ), KIUI::EllipsizeMenuText( GetShownText() ) ); @@ -468,6 +483,9 @@ void SCH_TEXT::Plot( PLOTTER* aPlotter, bool aBackground ) const aPlotter->Text( textpos, color, txt, GetTextAngle(), GetTextSize(), GetHorizJustify(), GetVertJustify(), penWidth, IsItalic(), IsBold(), false, font ); } + + if( HasHyperlink() ) + aPlotter->HyperlinkBoxURL( GetBoundingBox(), GetHyperlink() ); } diff --git a/eeschema/sch_text.h b/eeschema/sch_text.h index c7f930f3bf..a5696c11ab 100644 --- a/eeschema/sch_text.h +++ b/eeschema/sch_text.h @@ -133,6 +133,10 @@ public: wxString GetShownText( int aDepth = 0 ) const override; + virtual bool IsHypertext() const override { return HasHyperlink(); } + + virtual void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) const override; + /** * Set a spin or rotation angle, along with specific horizontal and vertical justification * styles with each angle. diff --git a/eeschema/sch_textbox.cpp b/eeschema/sch_textbox.cpp index ddc3fdcd3d..b89f8f8d67 100644 --- a/eeschema/sch_textbox.cpp +++ b/eeschema/sch_textbox.cpp @@ -383,6 +383,9 @@ void SCH_TEXTBOX::Plot( PLOTTER* aPlotter, bool aBackground ) const GetTextSize(), GetHorizJustify(), GetVertJustify(), penWidth, IsItalic(), IsBold(), false, font ); } + + if( HasHyperlink() ) + aPlotter->HyperlinkBoxURL( GetBoundingBox(), GetHyperlink() ); } diff --git a/eeschema/schematic.keywords b/eeschema/schematic.keywords index 56ca7e46db..40b0afacf7 100644 --- a/eeschema/schematic.keywords +++ b/eeschema/schematic.keywords @@ -44,6 +44,7 @@ hide hierarchical_label hint_alt_swap hint_pin_swap +href id image input diff --git a/include/eda_text.h b/include/eda_text.h index cf2163f3bb..0bf9a3b88b 100644 --- a/include/eda_text.h +++ b/include/eda_text.h @@ -322,6 +322,25 @@ public: int Compare( const EDA_TEXT* aOther ) const; + virtual bool HasHyperlink() const { return !m_hyperlink.IsEmpty(); } + wxString GetHyperlink() const { return m_hyperlink; } + void SetHyperlink( wxString aLink ) { m_hyperlink = aLink; } + void RemoveHyperlink() { m_hyperlink = wxEmptyString; } + + /** + * Check if aURL is a valid hyperlink. + * + * @param aURL String to validate + * @return true if aURL is a valid hyperlink + */ + static bool ValidateHyperlink( const wxString& aURL ); + +protected: + /** + * A hyperlink to a URL or file in the system. If empty, this text object is not a hyperlink + */ + wxString m_hyperlink; + private: void cacheShownText(); diff --git a/pcbnew/dialogs/dialog_text_properties_base.fbp b/pcbnew/dialogs/dialog_text_properties_base.fbp index 99d7bd5649..6dd4e30d14 100644 --- a/pcbnew/dialogs/dialog_text_properties_base.fbp +++ b/pcbnew/dialogs/dialog_text_properties_base.fbp @@ -1,6 +1,6 @@ - + C++ @@ -14,6 +14,7 @@ dialog_text_properties_base 1000 none + 1 DIALOG_TEXT_PROPERTIES_BASE @@ -25,6 +26,7 @@ 1 1 UI + 0 0 0 @@ -50,6 +52,7 @@ DIALOG_SHIM; dialog_shim.h Text Properties + 0 @@ -179,6 +182,7 @@ protected 1 + 0 Resizable 1 @@ -916,6 +920,7 @@ + 0 @@ -988,6 +993,7 @@ + 0 @@ -1061,6 +1067,7 @@ + 0 @@ -1133,6 +1140,7 @@ + 0 @@ -1205,6 +1213,7 @@ + 0 @@ -1278,6 +1287,7 @@ + 0 @@ -1351,6 +1361,7 @@ + 0 @@ -1424,6 +1435,7 @@ + 0 @@ -1496,6 +1508,7 @@ + 0 @@ -1568,6 +1581,7 @@ + 0