48#include <wx/srchctrl.h>
50#include <wx/textdlg.h>
55#define COLUMN_MARGIN 3
57#define COLUMN_MARGIN 15
104 wxMenuItem* revertMenu = menu.Append(
MYID_REVERT_ROW,
_(
"Revert symbol" ),
105 _(
"Revert the symbol to its last saved state" ), wxITEM_NORMAL );
107 _(
"Clear the cell value" ), wxITEM_NORMAL );
108 menu.AppendSeparator();
110 _(
"Create a new symbol derived from the selected one" ),
114 wxPoint mousePos = wxGetMousePosition();
115 wxPoint gridPt =
m_grid->ScreenToClient( mousePos );
118 int headerHeight =
m_grid->GetColLabelSize();
119 gridPt.y -= headerHeight;
123 int row =
m_grid->YToRow( gridPt.y );
124 int col =
m_grid->XToCol( gridPt.x );
125 m_grid->SetGridCursor( row, col );
127 revertMenu->Enable(
m_dataModel->IsCellEdited( row, col ) );
128 clearMenu->Enable( !
m_dataModel->IsCellClear( row, col ) );
129 deriveMenu->Enable(
m_dataModel->IsRowSingleSymbol( row ) );
134 menu.AppendSeparator();
139 menu.AppendSeparator();
147 int row =
m_grid->GetGridCursorRow();
148 int col =
m_grid->GetGridCursorCol();
152 if(
m_grid->CommitPendingChanges(
false ) )
158 m_dlg->ClearModify();
164 if(
m_grid->CommitPendingChanges(
false ) )
170 m_dlg->ClearModify();
181 wxArrayString symbolNames;
185 [&](
const wxString& newName ) ->
bool
187 return symbolNames.Index( newName ) == wxNOT_FOUND;
195 wxString derivedName = dlg.
GetName();
197 m_dataModel->CreateDerivedSymbolImmediate( row, col, derivedName );
207 wxString fpid =
m_grid->GetCellValue( row, col );
211 if( frame->ShowModal( &fpid,
m_dlg ) )
212 m_grid->SetCellValue( row, col, fpid );
219 wxString datasheet_uri =
m_grid->GetCellValue( row, col );
224 if( !
m_grid->CommitPendingChanges(
false ) )
232 m_dlg->ShowHideColumn( col, show );
234 wxString fieldName =
m_dataModel->GetColFieldName( col );
283 wxGridCellAttr* attr =
new wxGridCellAttr;
284 attr->SetReadOnly(
true );
287 attr =
new wxGridCellAttr;
288 attr->SetRenderer(
new wxGridCellBoolRenderer() );
290 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
293 attr =
new wxGridCellAttr;
294 attr->SetRenderer(
new wxGridCellBoolRenderer() );
296 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
302 m_filter->SetDescriptiveText(
_(
"Filter" ) );
306 m_grid->UseNativeColHeader(
true );
310 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
329 CallAfter( [
this, cfg]()
356 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
358 if(
m_grid->IsColShown( i ) )
360 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
373 m_grid->PopEventHandler(
true );
383 if( aIsLeftPanelCollapsed )
398 wxGridCellAttr* attr =
new wxGridCellAttr;
399 attr->SetReadOnly(
false );
405 wxString symbolNetlist;
414 pins.push_back(
pin->GetNumber() +
' ' +
pin->GetShownName() );
416 if( !pins.IsEmpty() )
419 symbolNetlist << wxS(
"\r" );
422 if( !fpFilters.IsEmpty() )
425 symbolNetlist << wxS(
"\r" );
439 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
451 attr->SetEditor(
m_grid->GetDefaultEditor() );
460 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
463 m_grid->AutoSizeColumns(
false );
465 bool sortAscending =
true;
471 if(
m_dataModel->GetSortCol() == 0 && nameCol != -1 )
474 sortAscending =
true;
478 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
504 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
514 int maxWidth = defaultDlgSize.x / 3;
516 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
526 m_grid->SetSortingColumn( sortCol, sortAscending );
536 case SCOPE::SCOPE_LIBRARY:
m_choiceScope->SetSelection( 0 );
break;
537 case SCOPE::SCOPE_RELATED_SYMBOLS:
m_choiceScope->SetSelection( 1 );
break;
551 wxString libName =
m_parent->GetTreeLIBID().GetLibNickname();
553 if( aSymbolNames.IsEmpty() )
556 wxMessageBox( wxString::Format(
_(
"No related symbols found in library '%s'." ), libName ) );
558 wxMessageBox( wxString::Format(
_(
"No symbols found in library '%s'." ), libName ) );
564 for(
const wxString& symbolName : aSymbolNames )
568 if( canvasSymbol && canvasSymbol->
GetLibraryName() == libName && canvasSymbol->
GetName() == symbolName )
582 wxLogWarning( wxString::Format(
_(
"Error loading symbol '%s': %s" ), symbolName, ioe.
What() ) );
590 wxMessageBox(
_(
"No related symbols could be loaded from the library." ) );
592 wxMessageBox(
_(
"No symbols could be loaded from the library." ) );
601 if( !
m_grid->CommitPendingChanges() )
604 if( !wxDialog::TransferDataFromWindow() )
607 bool updateCanvas =
false;
614 if(
m_parent->GetCurSymbol() == symbol )
620 auto createdSymbols =
m_dataModel->GetAndClearCreatedDerivedSymbols();
622 wxLogTrace(
traceLibFieldTable,
"Post-apply handler: found %zu created derived symbols",
623 createdSymbols.size() );
625 for(
const auto& [symbol, libraryName] : createdSymbols )
627 if( !libraryName.IsEmpty() )
632 m_parent->GetLibManager().UpdateSymbol( symbol, libraryName );
637 if( !createdSymbols.empty() )
639 wxLogTrace(
traceLibFieldTable,
"Syncing libraries due to %zu new symbols", createdSymbols.size() );
642 std::vector<LIB_SYMBOL*> symbolsToPreserve;
643 for(
const auto& [symbol, libraryName] : createdSymbols )
645 symbolsToPreserve.push_back( symbol );
657 if( existingSymbol->m_Uuid == symbol->
m_Uuid )
676 wxLogTrace(
traceLibFieldTable,
"About to rebuild grid rows to include new symbols" );
694 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
696 if( dlg.ShowModal() != wxID_OK )
699 wxString fieldName = dlg.GetValue();
701 if( fieldName.IsEmpty() )
707 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
709 if( fieldName ==
m_dataModel->GetColFieldName( i ) )
711 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
729 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
751 if( selectedRows.empty() )
754 int row = selectedRows[0];
758 int col =
m_dataModel->GetFieldNameCol( fieldName );
759 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
761 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
763 if( dlg.ShowModal() != wxID_OK )
766 wxString newFieldName = dlg.GetValue();
768 if( newFieldName == fieldName )
771 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
773 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already exists." ), newFieldName ) );
797#if defined( __WXOSX__ )
798 wxPoint pos = aEvent.GetPosition();
799 wxRect ctrlRect =
m_filter->GetScreenRect();
800 int buttonWidth = ctrlRect.GetHeight();
803 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
804 SetCursor( wxCURSOR_ARROW );
805 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
806 SetCursor( wxCURSOR_ARROW );
808 SetCursor( wxCURSOR_IBEAM );
816 wxString targetLib =
m_parent->GetTargetLibId().GetLibNickname();
817 wxString targetSymbol =
m_parent->GetTargetLibId().GetLibItemName();
818 wxArrayString symbolNames;
820 SetTitle( wxString::Format(
_(
"Symbol Fields Table ('%s' Library)" ), targetLib ) );
824 if(
m_scope == SCOPE::SCOPE_RELATED_SYMBOLS )
827 std::shared_ptr<LIB_SYMBOL> root = symbol ? symbol->
GetRootSymbol() :
nullptr;
831 symbolNames.Add( root->GetName() );
855 switch( aEvent.GetSelection() )
857 case 0:
setScope( SCOPE::SCOPE_LIBRARY );
break;
858 case 1:
setScope( SCOPE::SCOPE_RELATED_SYMBOLS );
break;
878 if(
m_dataModel->IsExpanderColumn( event.GetCol() ) )
882 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
897 wxPoint mousePos = wxGetMousePosition();
898 wxPoint gridPt =
m_grid->ScreenToClient( mousePos );
900 int row =
m_grid->YToRow( gridPt.y );
901 int col =
m_grid->XToCol( gridPt.x );
903 if ( row != -1 && col != -1 )
904 m_grid->SetGridCursor( row, col );
933 int remainingWidth =
m_viewControlsGrid->GetSize().GetX() - showColWidth - groupByColWidth;
984 m_grid->CommitPendingChanges(
true );
996 EndModal( wxID_CANCEL );
1003 EndModal( wxID_OK );
1009 m_grid->CommitPendingChanges(
true );
1030 auto addMandatoryField =
1031 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
1046 AddField( wxS(
"Keywords" ),
_(
"Keywords" ),
true,
false );
1049 AddField( wxS(
"${EXCLUDE_FROM_BOM}" ),
_(
"Exclude From BOM" ),
true,
false,
false,
true );
1050 AddField( wxS(
"${EXCLUDE_FROM_SIM}" ),
_(
"Exclude From Simulation" ),
true,
false,
false,
true );
1051 AddField( wxS(
"${EXCLUDE_FROM_BOARD}" ),
_(
"Exclude From Board" ),
true,
false,
false,
true );
1053 AddField( wxS(
"Power" ),
_(
"Power Symbol" ),
true,
false,
false,
true );
1054 AddField( wxS(
"LocalPower" ),
_(
"Local Power Symbol" ),
true,
false,
false,
true );
1057 std::set<wxString> userFieldNames;
1061 std::vector< SCH_FIELD* > fields;
1062 symbol->GetFields( fields );
1066 if( !field->IsMandatory() && !field->IsPrivate() )
1067 userFieldNames.insert( field->GetName() );
1071 for(
const wxString& fieldName : userFieldNames )
1077 bool groupBy,
bool addedByUser,
bool aIsCheckbox )
1087 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser, aIsCheckbox );
1089 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
1090 m_grid->ProcessTableMessage( msg );
1093 [&]() -> std::pair<int, int>
1104 int col =
m_dataModel->GetFieldNameCol( fieldName );
1105 wxCHECK_RET( col != -1, wxS(
"Field name not found" ) );
1113 int col =
m_dataModel->GetFieldNameCol( oldName );
1114 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
1129 int sortCol = aEvent.GetCol();
1130 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1135 if(
m_grid->IsSortingBy( sortCol ) )
1138 ascending = !
m_grid->IsSortOrderAscending();
1153 int origPos = aEvent.GetCol();
1158 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1160 if(
m_grid->IsColShown( i ) )
1162 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1170 int newPos =
m_grid->GetColPos( origPos );
1173 if( newPos < origPos )
1206 int row = aEvent.GetRow();
1208 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1210 switch( aEvent.GetCol() )
1216 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1221 m_grid->SetColLabelValue( dataCol, label );
1234 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1246 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
STD_BITMAP_BUTTON * m_bRefresh
STD_BITMAP_BUTTON * m_sidebarButton
wxSplitterWindow * m_splitterMainWindow
DIALOG_LIB_FIELDS_TABLE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Symbol Fields Table ('%s' Library)"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER)
STD_BITMAP_BUTTON * m_renameFieldButton
wxCheckBox * m_groupSymbolsBox
STD_BITMAP_BUTTON * m_addFieldButton
WX_GRID * m_viewControlsGrid
STD_BITMAP_BUTTON * m_removeFieldButton
bool TransferDataToWindow() override
void OnTableColSize(wxGridSizeEvent &event) override
void OnFilterMouseMoved(wxMouseEvent &event) override
void OnScope(wxCommandEvent &event) override
void OnTableItemContextMenu(wxGridEvent &event) override
void OnGroupSymbolsToggled(wxCommandEvent &event) override
void setScope(SCOPE aScope)
void SetupColumnProperties(int aCol)
void OnSidebarToggle(wxCommandEvent &event) override
void OnAddField(wxCommandEvent &event) override
void ShowHideColumn(int aCol, bool aShow)
~DIALOG_LIB_FIELDS_TABLE() override
LIB_FIELDS_EDITOR_GRID_DATA_MODEL * m_dataModel
void OnTableCellClick(wxGridEvent &event) override
void OnViewControlsCellChanged(wxGridEvent &aEvent) override
void RenameField(const wxString &oldName, const wxString &newName)
void OnClose(wxCloseEvent &event) override
void OnOk(wxCommandEvent &event) override
void OnTableValueChanged(wxGridEvent &event) override
void AddField(const wxString &aFieldName, const wxString &aLabelValue, bool show, bool groupBy, bool addedByUser=false, bool aIsCheckbox=false)
void OnApply(wxCommandEvent &event) override
SYMBOL_EDIT_FRAME * m_parent
std::vector< LIB_SYMBOL * > m_symbolsList
void OnRegroupSymbols(wxCommandEvent &event) override
void OnSizeViewControlsGrid(wxSizeEvent &event) override
void OnCancel(wxCommandEvent &event) override
void OnRenameField(wxCommandEvent &event) override
void RemoveField(const wxString &fieldName)
DIALOG_LIB_FIELDS_TABLE(SYMBOL_EDIT_FRAME *parent, DIALOG_LIB_FIELDS_TABLE::SCOPE aScope)
void OnColSort(wxGridEvent &aEvent)
VIEW_CONTROLS_GRID_DATA_MODEL * m_viewControlsDataModel
void OnColMove(wxGridEvent &aEvent)
void SetupAllColumnProperties()
void setSideBarButtonLook(bool aIsLeftPanelCollapsed)
bool TransferDataFromWindow() override
void loadSymbols(const wxArrayString &aSymbolNames)
void OnFilterText(wxCommandEvent &event) override
void OnRemoveField(wxCommandEvent &event) override
wxString GetName() const override
int vertPixelsFromDU(int y) const
Convert an integer number of dialog units to pixels, vertically.
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int horizPixelsFromDU(int x) const
Convert an integer number of dialog units to pixels, horizontally.
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
The base class for create windows for drawing purpose.
A general-purpose text renderer for WX_GRIDs backed by WX_GRID_TABLE_BASE tables that can handle draw...
GRID_TRICKS(WX_GRID *aGrid)
virtual void doPopupSelection(wxCommandEvent &event)
virtual void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent)
WX_GRID * m_grid
I don't own the grid, but he owns me.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
wxString AsString() const
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
static const wxString SYMBOL_NAME
LIB_FIELDS_EDITOR_GRID_DATA_MODEL * m_dataModel
LIB_FIELDS_EDITOR_GRID_TRICKS(DIALOG_LIB_FIELDS_TABLE *aParent, WX_GRID *aGrid, VIEW_CONTROLS_GRID_DATA_MODEL *aViewFieldsData, LIB_FIELDS_EDITOR_GRID_DATA_MODEL *aDataModel)
VIEW_CONTROLS_GRID_DATA_MODEL * m_viewControlsDataModel
DIALOG_LIB_FIELDS_TABLE * m_dlg
void doPopupSelection(wxCommandEvent &event) override
void showPopupMenu(wxMenu &menu, wxGridEvent &aEvent) override
Symbol library management helper that is specific to the symbol library editor frame.
Define a library symbol object.
std::vector< const SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
const wxString GetLibraryName() const
std::shared_ptr< LIB_SYMBOL > GetRootSymbol() const
Get the parent symbol that does not have another parent.
wxString GetName() const override
wxArrayString GetFPFilters() const
wxString GetLibNickname() const override
Sets the Description field text value.
static SEARCH_STACK * SchSearchS(PROJECT *aProject)
Accessor for Eeschema search stack.
PANEL_LIB_FIELDS_TABLE m_LibFieldEditor
The symbol library editor main window.
LIB_SYMBOL * GetBufferedSymbol(const wxString &aSymbolName, const wxString &aLibrary)
Return the symbol copy from the buffer.
void GetSymbolNames(const wxString &aLibName, wxArrayString &aSymbolNames, SYMBOL_NAME_FILTER aFilter=SYMBOL_NAME_FILTER::ALL)
size_t GetDerivedSymbolNames(const wxString &aSymbolName, const wxString &aLibraryName, wxArrayString &aList)
Fetch all of the symbols derived from a aSymbolName into aList.
VIEW_CONTROLS_GRID_TRICKS(WX_GRID *aGrid)
void doPopupSelection(wxCommandEvent &event) override
wxString GetGeneratedFieldDisplayName(const wxString &aSource)
Returns any variables unexpanded, e.g.
bool IsGeneratedField(const wxString &aSource)
Returns true if the string is generated, e.g contains a single text var reference.
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
This file is part of the common library.
DIALOG_LIB_NEW_SYMBOL DIALOG_NEW_SYMBOL
@ MYID_CREATE_DERIVED_SYMBOL
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, PROJECT *aProject, SEARCH_STACK *aPaths, std::vector< EMBEDDED_FILES * > aFilesStack)
Open a document (file) with the suitable browser.
This file is part of the common library.
#define DISPLAY_NAME_COLUMN
#define SHOW_FIELD_COLUMN
@ FRAME_FOOTPRINT_CHOOSER
@ GRIDTRICKS_FIRST_SHOWHIDE
@ GRIDTRICKS_FIRST_CLIENT_ID
const wxChar *const traceLibFieldTable
KICOMMON_API wxSize GetTextSize(const wxString &aSingleLine, wxWindow *aWindow)
Return the size of aSingleLine of text when it is rendered in aWindow using whatever font is currentl...
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
std::map< std::string, int > field_widths
wxString GetDefaultFieldName(FIELD_T aFieldId, bool aTranslateForHI)
Return a default symbol field name for a mandatory field type.
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ DESCRIPTION
Field Description of part, i.e. "1/4W 1% Metal Film Resistor".
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ DATASHEET
name of datasheet
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
wxString GetCanonicalFieldName(FIELD_T aFieldType)
wxLogTrace helper definitions.