diff --git a/common/properties/pg_editors.cpp b/common/properties/pg_editors.cpp index 90320caac0..0656eeee15 100644 --- a/common/properties/pg_editors.cpp +++ b/common/properties/pg_editors.cpp @@ -24,6 +24,16 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include @@ -31,6 +41,8 @@ const wxString PG_UNIT_EDITOR::EDITOR_NAME = wxS( "KiCadUnitEditor" ); const wxString PG_CHECKBOX_EDITOR::EDITOR_NAME = wxS( "KiCadCheckboxEditor" ); const wxString PG_COLOR_EDITOR::EDITOR_NAME = wxS( "KiCadColorEditor" ); const wxString PG_RATIO_EDITOR::EDITOR_NAME = wxS( "KiCadRatioEditor" ); +const wxString PG_FPID_EDITOR::EDITOR_NAME = wxS( "KiCadFpidEditor" ); +const wxString PG_URL_EDITOR::EDITOR_NAME = wxS( "KiCadUrlEditor" ); PG_UNIT_EDITOR::PG_UNIT_EDITOR( EDA_DRAW_FRAME* aFrame ) : @@ -51,6 +63,9 @@ PG_UNIT_EDITOR::~PG_UNIT_EDITOR() wxString PG_UNIT_EDITOR::BuildEditorName( EDA_DRAW_FRAME* aFrame ) { + if( !aFrame ) + return EDITOR_NAME + "NoFrame"; + return EDITOR_NAME + aFrame->GetName(); } @@ -458,3 +473,164 @@ void PG_RATIO_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) "properties!" ) ); } } + + +PG_FPID_EDITOR::PG_FPID_EDITOR( EDA_DRAW_FRAME* aFrame ) : m_frame( aFrame ) +{ + m_editorName = BuildEditorName( aFrame ); +} + + +void PG_FPID_EDITOR::UpdateFrame( EDA_DRAW_FRAME* aFrame ) +{ + m_frame = aFrame; + m_editorName = BuildEditorName( aFrame ); +} + + +wxString PG_FPID_EDITOR::BuildEditorName( EDA_DRAW_FRAME* aFrame ) +{ + if( !aFrame ) + return EDITOR_NAME + "NoFrame"; + + return EDITOR_NAME + aFrame->GetName(); +} + + +wxPGWindowList PG_FPID_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty, + const wxPoint& aPos, const wxSize& aSize ) const +{ + wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize ); + buttons->Add( KiBitmap( BITMAPS::small_library ) ); + buttons->Finalize( aGrid, aPos ); + wxSize textSize = buttons->GetPrimarySize(); + wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize, + aProperty->GetValueAsString(), nullptr, 0, + aProperty->GetMaxLength() ); + wxPGWindowList ret( textCtrl, buttons ); + return ret; +} + + +bool PG_FPID_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl, + wxEvent& aEvent ) const +{ + if( aEvent.GetEventType() == wxEVT_BUTTON ) + { + wxString fpid = aProperty->GetValue().GetString(); + + if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_frame ) ) + { + if( frame->ShowModal( &fpid, m_frame ) ) + aGrid->ChangePropertyValue( aProperty, fpid ); + + frame->Destroy(); + } + + return true; + } + + return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent ); +} + + +PG_URL_EDITOR::PG_URL_EDITOR( EDA_DRAW_FRAME* aFrame ) : m_frame( aFrame ) +{ + m_editorName = BuildEditorName( aFrame ); +} + + +void PG_URL_EDITOR::UpdateFrame( EDA_DRAW_FRAME* aFrame ) +{ + m_frame = aFrame; + m_editorName = BuildEditorName( aFrame ); +} + + +wxString PG_URL_EDITOR::BuildEditorName( EDA_DRAW_FRAME* aFrame ) +{ + if( !aFrame ) + return EDITOR_NAME + "NoFrame"; + + return EDITOR_NAME + aFrame->GetName(); +} + + +wxPGWindowList PG_URL_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty, + const wxPoint& aPos, const wxSize& aSize ) const +{ + wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize ); + // Use a folder icon when no datasheet is set; otherwise use a globe icon. + wxString urlValue = aProperty->GetValueAsString(); + bool hasUrl = !( urlValue.IsEmpty() || urlValue == wxS( "~" ) ); + buttons->Add( KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder ) ); + buttons->Finalize( aGrid, aPos ); + wxSize textSize = buttons->GetPrimarySize(); + wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize, + aProperty->GetValueAsString(), nullptr, 0, + aProperty->GetMaxLength() ); + wxPGWindowList ret( textCtrl, buttons ); + return ret; +} + + +bool PG_URL_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl, + wxEvent& aEvent ) const +{ + if( aEvent.GetEventType() == wxEVT_BUTTON ) + { + wxString filename = aProperty->GetValue().GetString(); + + if( filename.IsEmpty() || filename == wxS( "~" ) ) + { + wxFileDialog openFileDialog( m_frame, _( "Open file" ), wxS( "" ), wxS( "" ), + _( "All Files" ) + wxS( " (*.*)|*.*" ), + wxFD_OPEN | wxFD_FILE_MUST_EXIST ); + + if( openFileDialog.ShowModal() == wxID_OK ) + { + filename = openFileDialog.GetPath(); + aGrid->ChangePropertyValue( aProperty, wxString::Format( wxS( "file://%s" ), + filename ) ); + } + } + else + { + GetAssociatedDocument( m_frame, filename, &m_frame->Prj() ); + } + + // Update the button icon to reflect presence/absence of URL + if( wxObject* src = aEvent.GetEventObject() ) + { + wxString newUrl = aProperty->GetValueAsString(); + bool hasUrl = !( newUrl.IsEmpty() || newUrl == wxS( "~" ) ); + auto bmp = KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder ); + + if( wxWindow* win = wxDynamicCast( src, wxWindow ) ) + { + if( wxBitmapButton* bb = wxDynamicCast( win, wxBitmapButton ) ) + { + bb->SetBitmap( bmp ); + } + else if( wxButton* b = wxDynamicCast( win, wxButton ) ) + { + b->SetBitmap( bmp ); + } + else if( wxWindow* parent = win->GetParent() ) + { + if( wxPGMultiButton* buttons = wxDynamicCast( parent, wxPGMultiButton ) ) + { + wxWindow* btn0 = buttons->GetButton( 0 ); + if( wxBitmapButton* bb0 = wxDynamicCast( btn0, wxBitmapButton ) ) + bb0->SetBitmap( bmp ); + else if( wxButton* b0 = wxDynamicCast( btn0, wxButton ) ) + b0->SetBitmap( bmp ); + } + } + } + } + return true; + } + + return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent ); +} diff --git a/eeschema/widgets/sch_properties_panel.cpp b/eeschema/widgets/sch_properties_panel.cpp index 621cce5d4f..a30bbd0a18 100644 --- a/eeschema/widgets/sch_properties_panel.cpp +++ b/eeschema/widgets/sch_properties_panel.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -149,6 +150,32 @@ SCH_PROPERTIES_PANEL::SCH_PROPERTIES_PANEL( wxWindow* aParent, SCH_BASE_FRAME* a { m_colorEditorInstance = static_cast( it->second ); } + + it = wxPGGlobalVars->m_mapEditorClasses.find( PG_FPID_EDITOR::BuildEditorName( m_frame ) ); + + if( it != wxPGGlobalVars->m_mapEditorClasses.end() ) + { + m_fpEditorInstance = static_cast( it->second ); + m_fpEditorInstance->UpdateFrame( m_frame ); + } + else + { + PG_FPID_EDITOR* fpEditor = new PG_FPID_EDITOR( m_frame ); + m_fpEditorInstance = static_cast( wxPropertyGrid::RegisterEditorClass( fpEditor ) ); + } + + it = wxPGGlobalVars->m_mapEditorClasses.find( PG_URL_EDITOR::BuildEditorName( m_frame ) ); + + if( it != wxPGGlobalVars->m_mapEditorClasses.end() ) + { + m_urlEditorInstance = static_cast( it->second ); + m_urlEditorInstance->UpdateFrame( m_frame ); + } + else + { + PG_URL_EDITOR* urlEditor = new PG_URL_EDITOR( m_frame ); + m_urlEditorInstance = static_cast( wxPropertyGrid::RegisterEditorClass( urlEditor ) ); + } } @@ -156,6 +183,8 @@ SCH_PROPERTIES_PANEL::SCH_PROPERTIES_PANEL( wxWindow* aParent, SCH_BASE_FRAME* a SCH_PROPERTIES_PANEL::~SCH_PROPERTIES_PANEL() { m_unitEditorInstance->UpdateFrame( nullptr ); + m_fpEditorInstance->UpdateFrame( nullptr ); + m_urlEditorInstance->UpdateFrame( nullptr ); } @@ -226,6 +255,11 @@ wxPGProperty* SCH_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProp colorProp->SetBackgroundColor( bg ); } + if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::FOOTPRINT ) ) + prop->SetEditor( PG_FPID_EDITOR::BuildEditorName( m_frame ) ); + else if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::DATASHEET ) ) + prop->SetEditor( PG_URL_EDITOR::BuildEditorName( m_frame ) ); + return prop; } diff --git a/eeschema/widgets/sch_properties_panel.h b/eeschema/widgets/sch_properties_panel.h index 9b9ce8bb11..5a6ad0bd35 100644 --- a/eeschema/widgets/sch_properties_panel.h +++ b/eeschema/widgets/sch_properties_panel.h @@ -32,6 +32,8 @@ class PROPERTY_MANAGER; class PG_UNIT_EDITOR; class PG_CHECKBOX_EDITOR; class PG_COLOR_EDITOR; +class PG_FPID_EDITOR; +class PG_URL_EDITOR; class SCH_PROPERTIES_PANEL : public PROPERTIES_PANEL { @@ -60,6 +62,8 @@ protected: PG_UNIT_EDITOR* m_unitEditorInstance; PG_CHECKBOX_EDITOR* m_checkboxEditorInstance; PG_COLOR_EDITOR* m_colorEditorInstance; + PG_FPID_EDITOR* m_fpEditorInstance; + PG_URL_EDITOR* m_urlEditorInstance; static std::set m_currentFieldNames; wxPGChoices m_nets; diff --git a/include/properties/pg_editors.h b/include/properties/pg_editors.h index 6cb94fdb73..23a264abaa 100644 --- a/include/properties/pg_editors.h +++ b/include/properties/pg_editors.h @@ -125,4 +125,58 @@ public: }; +class PG_FPID_EDITOR : public wxPGTextCtrlEditor +{ +public: + static const wxString EDITOR_NAME; + + PG_FPID_EDITOR( EDA_DRAW_FRAME* aFrame ); + + virtual ~PG_FPID_EDITOR() {} + + wxString GetName() const override { return m_editorName; } + + void UpdateFrame( EDA_DRAW_FRAME* aFrame ); + + static wxString BuildEditorName( EDA_DRAW_FRAME* aFrame ); + + wxPGWindowList CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty, + const wxPoint& aPos, const wxSize& aSize ) const override; + + bool OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl, + wxEvent& aEvent ) const override; + +private: + EDA_DRAW_FRAME* m_frame; + wxString m_editorName; +}; + + +class PG_URL_EDITOR : public wxPGTextCtrlEditor +{ +public: + static const wxString EDITOR_NAME; + + PG_URL_EDITOR( EDA_DRAW_FRAME* aFrame ); + + virtual ~PG_URL_EDITOR() {} + + wxString GetName() const override { return m_editorName; } + + void UpdateFrame( EDA_DRAW_FRAME* aFrame ); + + static wxString BuildEditorName( EDA_DRAW_FRAME* aFrame ); + + wxPGWindowList CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty, + const wxPoint& aPos, const wxSize& aSize ) const override; + + bool OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl, + wxEvent& aEvent ) const override; + +private: + EDA_DRAW_FRAME* m_frame; + wxString m_editorName; +}; + + #endif //KICAD_PG_EDITORS_H diff --git a/pcbnew/widgets/pcb_properties_panel.cpp b/pcbnew/widgets/pcb_properties_panel.cpp index 574be49cf6..40e32f1f83 100644 --- a/pcbnew/widgets/pcb_properties_panel.cpp +++ b/pcbnew/widgets/pcb_properties_panel.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -244,12 +245,40 @@ PCB_PROPERTIES_PANEL::PCB_PROPERTIES_PANEL( wxWindow* aParent, PCB_BASE_EDIT_FRA { m_netSelectorEditorInstance = static_cast( it->second ); } + + it = wxPGGlobalVars->m_mapEditorClasses.find( PG_FPID_EDITOR::BuildEditorName( m_frame ) ); + + if( it != wxPGGlobalVars->m_mapEditorClasses.end() ) + { + m_fpEditorInstance = static_cast( it->second ); + m_fpEditorInstance->UpdateFrame( m_frame ); + } + else + { + PG_FPID_EDITOR* fpEditor = new PG_FPID_EDITOR( m_frame ); + m_fpEditorInstance = static_cast( wxPropertyGrid::RegisterEditorClass( fpEditor ) ); + } + + it = wxPGGlobalVars->m_mapEditorClasses.find( PG_URL_EDITOR::BuildEditorName( m_frame ) ); + + if( it != wxPGGlobalVars->m_mapEditorClasses.end() ) + { + m_urlEditorInstance = static_cast( it->second ); + m_urlEditorInstance->UpdateFrame( m_frame ); + } + else + { + PG_URL_EDITOR* urlEditor = new PG_URL_EDITOR( m_frame ); + m_urlEditorInstance = static_cast( wxPropertyGrid::RegisterEditorClass( urlEditor ) ); + } } PCB_PROPERTIES_PANEL::~PCB_PROPERTIES_PANEL() { m_unitEditorInstance->UpdateFrame( nullptr ); + m_fpEditorInstance->UpdateFrame( nullptr ); + m_urlEditorInstance->UpdateFrame( nullptr ); } @@ -342,7 +371,14 @@ wxPGProperty* PCB_PROPERTIES_PANEL::createPGProperty( const PROPERTY_BASE* aProp return ret; } - return PGPropertyFactory( aProperty, m_frame ); + wxPGProperty* prop = PGPropertyFactory( aProperty, m_frame ); + + if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::FOOTPRINT ) ) + prop->SetEditor( PG_FPID_EDITOR::BuildEditorName( m_frame ) ); + else if( aProperty->Name() == GetCanonicalFieldName( FIELD_T::DATASHEET ) ) + prop->SetEditor( PG_URL_EDITOR::BuildEditorName( m_frame ) ); + + return prop; } diff --git a/pcbnew/widgets/pcb_properties_panel.h b/pcbnew/widgets/pcb_properties_panel.h index 062f2ebf51..9e2c5fd1e5 100644 --- a/pcbnew/widgets/pcb_properties_panel.h +++ b/pcbnew/widgets/pcb_properties_panel.h @@ -34,6 +34,8 @@ class PG_UNIT_EDITOR; class PG_CHECKBOX_EDITOR; class PG_RATIO_EDITOR; class PG_NET_SELECTOR_EDITOR; +class PG_FPID_EDITOR; +class PG_URL_EDITOR; class PCB_PROPERTIES_PANEL : public PROPERTIES_PANEL { @@ -65,6 +67,8 @@ protected: PG_CHECKBOX_EDITOR* m_checkboxEditorInstance; PG_RATIO_EDITOR* m_ratioEditorInstance; PG_NET_SELECTOR_EDITOR* m_netSelectorEditorInstance; + PG_FPID_EDITOR* m_fpEditorInstance; + PG_URL_EDITOR* m_urlEditorInstance; static std::set m_currentFieldNames; wxPGChoices m_nets;