47#include <wx/srchctrl.h>
49#include <wx/textdlg.h>
54#define COLUMN_MARGIN 3
56#define COLUMN_MARGIN 15
103 wxMenuItem* revertMenu = menu.Append(
MYID_REVERT_ROW,
_(
"Revert symbol" ),
_(
"Revert the symbol to its last saved state" ), wxITEM_NORMAL );
104 wxMenuItem* clearMenu = menu.Append(
MYID_CLEAR_CELL,
_(
"Clear cell" ),
_(
"Clear the cell value" ), wxITEM_NORMAL );
105 menu.AppendSeparator();
106 wxMenuItem* createDerivedSymbolMenu = menu.Append(
MYID_CREATE_DERIVED_SYMBOL,
_(
"Create Derived Symbol" ),
_(
"Create a new symbol derived from the selected one" ), wxITEM_NORMAL );
109 wxPoint mousePos = wxGetMousePosition();
110 wxPoint gridPt =
m_grid->ScreenToClient( mousePos );
113 int headerHeight =
m_grid->GetColLabelSize();
114 gridPt.y -= headerHeight;
118 int row =
m_grid->YToRow( gridPt.y );
119 int col =
m_grid->XToCol( gridPt.x );
120 m_grid->SetGridCursor( row, col );
122 revertMenu->Enable(
m_dataModel->IsCellEdited( row, col ) );
123 clearMenu->Enable( !
m_dataModel->IsCellClear( row, col ) );
124 createDerivedSymbolMenu->Enable(
m_dataModel->IsRowSingleSymbol( row ) );
129 menu.AppendSeparator();
134 menu.AppendSeparator();
142 int row =
m_grid->GetGridCursorRow();
143 int col =
m_grid->GetGridCursorCol();
147 if(
m_grid->CommitPendingChanges(
false ) )
153 m_dlg->ClearModify();
159 if(
m_grid->CommitPendingChanges(
false ) )
165 m_dlg->ClearModify();
176 wxArrayString symbolNames;
180 [&](
const wxString& newName ) ->
bool
182 return symbolNames.Index( newName ) == wxNOT_FOUND;
190 wxString derivedName = dlg.
GetName();
192 m_dataModel->CreateDerivedSymbolImmediate( row, col, derivedName );
202 wxString fpid =
m_grid->GetCellValue( row, col );
206 if( frame->ShowModal( &fpid,
m_dlg ) )
207 m_grid->SetCellValue( row, col, fpid );
214 wxString datasheet_uri =
m_grid->GetCellValue( row, col );
219 if( !
m_grid->CommitPendingChanges(
false ) )
227 m_dlg->ShowHideColumn( col, show );
229 wxString fieldName =
m_dataModel->GetColFieldName( col );
278 wxGridCellAttr* attr =
new wxGridCellAttr;
279 attr->SetReadOnly(
true );
282 attr =
new wxGridCellAttr;
283 attr->SetRenderer(
new wxGridCellBoolRenderer() );
285 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
288 attr =
new wxGridCellAttr;
289 attr->SetRenderer(
new wxGridCellBoolRenderer() );
291 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
297 m_filter->SetDescriptiveText(
_(
"Filter" ) );
301 m_grid->UseNativeColHeader(
true );
305 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
327 if( visible_column.IsEmpty() )
329 visible_column = wxT(
"0" );
333 CallAfter( [
this, cfg]()
367 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
369 if(
m_grid->IsColShown( i ) )
371 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
384 m_grid->PopEventHandler(
true );
392 wxGridCellAttr* attr =
new wxGridCellAttr;
393 attr->SetReadOnly(
false );
399 wxString symbolNetlist;
408 pins.push_back(
pin->GetNumber() +
' ' +
pin->GetShownName() );
410 if( !pins.IsEmpty() )
413 symbolNetlist << wxS(
"\r" );
416 if( !fpFilters.IsEmpty() )
419 symbolNetlist << wxS(
"\r" );
433 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
444 attr->SetEditor(
m_grid->GetDefaultEditor() );
453 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
456 m_grid->AutoSizeColumns(
false );
458 bool sortAscending =
true;
464 if(
m_dataModel->GetSortCol() == 0 && valueCol != -1 )
467 sortAscending =
true;
471 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
497 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
507 int maxWidth = defaultDlgSize.x / 3;
509 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
519 m_grid->SetSortingColumn( sortCol, sortAscending );
527 case SCOPE::SCOPE_LIBRARY:
m_choiceScope->SetSelection( 0 );
break;
528 case SCOPE::SCOPE_RELATED_SYMBOLS:
m_choiceScope->SetSelection( 1 );
break;
542 wxString libName =
m_parent->GetTreeLIBID().GetLibNickname();
544 if( aSymbolNames.IsEmpty() )
547 wxMessageBox( wxString::Format(
_(
"No related symbols found in library '%s'." ), libName ) );
549 wxMessageBox( wxString::Format(
_(
"No symbols found in library '%s'." ), libName ) );
555 for(
const wxString& symbolName : aSymbolNames )
559 if( canvasSymbol && canvasSymbol->
GetLibraryName() == libName && canvasSymbol->
GetName() == symbolName )
573 wxLogWarning( wxString::Format(
_(
"Error loading symbol '%s': %s" ), symbolName, ioe.
What() ) );
581 wxMessageBox(
_(
"No related symbols could be loaded from the library." ) );
583 wxMessageBox(
_(
"No symbols could be loaded from the library." ) );
592 if( !
m_grid->CommitPendingChanges() )
595 if( !wxDialog::TransferDataFromWindow() )
598 bool updateCanvas =
false;
605 if(
m_parent->GetCurSymbol() == symbol )
611 auto createdSymbols =
m_dataModel->GetAndClearCreatedDerivedSymbols();
613 wxLogTrace(
traceLibFieldTable,
"Post-apply handler: found %zu created derived symbols",
614 createdSymbols.size() );
616 for(
const auto& [symbol, libraryName] : createdSymbols )
618 if( !libraryName.IsEmpty() )
623 m_parent->GetLibManager().UpdateSymbol( symbol, libraryName );
628 if( !createdSymbols.empty() )
630 wxLogTrace(
traceLibFieldTable,
"Syncing libraries due to %zu new symbols", createdSymbols.size() );
633 std::vector<LIB_SYMBOL*> symbolsToPreserve;
634 for(
const auto& [symbol, libraryName] : createdSymbols )
636 symbolsToPreserve.push_back( symbol );
648 if( existingSymbol->m_Uuid == symbol->
m_Uuid )
667 wxLogTrace(
traceLibFieldTable,
"About to rebuild grid rows to include new symbols" );
685 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
687 if( dlg.ShowModal() != wxID_OK )
690 wxString fieldName = dlg.GetValue();
692 if( fieldName.IsEmpty() )
698 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
700 if( fieldName ==
m_dataModel->GetColFieldName( i ) )
702 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
720 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
742 if( selectedRows.empty() )
745 int row = selectedRows[0];
749 int col =
m_dataModel->GetFieldNameCol( fieldName );
750 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
752 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
754 if( dlg.ShowModal() != wxID_OK )
757 wxString newFieldName = dlg.GetValue();
759 if( newFieldName == fieldName )
762 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
764 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already exists." ), newFieldName ) );
788 wxPoint pos = aEvent.GetPosition();
789 wxRect ctrlRect =
m_filter->GetScreenRect();
790 int buttonWidth = ctrlRect.GetHeight();
793 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
794 SetCursor( wxCURSOR_ARROW );
795 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
796 SetCursor( wxCURSOR_ARROW );
798 SetCursor( wxCURSOR_IBEAM );
805 wxString targetLib =
m_parent->GetTargetLibId().GetLibNickname();
806 wxString targetSymbol =
m_parent->GetTargetLibId().GetLibItemName();
807 wxArrayString symbolNames;
809 SetTitle( wxString::Format(
_(
"Library Fields Table (%s)" ), targetLib ) );
813 if(
m_scope == SCOPE::SCOPE_RELATED_SYMBOLS )
820 symbolNames.Add( root->
GetName() );
844 switch( aEvent.GetSelection() )
846 case 0:
setScope( SCOPE::SCOPE_LIBRARY );
break;
847 case 1:
setScope( SCOPE::SCOPE_RELATED_SYMBOLS );
break;
867 wxString cellValue =
m_grid->GetCellValue( event.GetRow(), event.GetCol() );
869 if( cellValue.StartsWith( wxS(
"> " ) ) || cellValue.StartsWith( wxS(
"v " ) ) )
873 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
888 wxPoint mousePos = wxGetMousePosition();
889 wxPoint gridPt =
m_grid->ScreenToClient( mousePos );
891 int row =
m_grid->YToRow( gridPt.y );
892 int col =
m_grid->XToCol( gridPt.x );
894 if ( row != -1 && col != -1 )
895 m_grid->SetGridCursor( row, col );
916 int remainingWidth =
m_viewControlsGrid->GetSize().GetX() - showColWidth - groupByColWidth;
968 m_grid->CommitPendingChanges(
true );
980 EndModal( wxID_CANCEL );
993 m_grid->CommitPendingChanges(
true );
1014 auto addMandatoryField =
1015 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
1028 AddField( wxS(
"Keywords" ),
_(
"Keywords" ),
true,
false );
1031 AddField( wxS(
"${EXCLUDE_FROM_BOM}" ),
_(
"Exclude From BOM" ),
true,
false,
false,
true );
1032 AddField( wxS(
"${EXCLUDE_FROM_SIM}" ),
_(
"Exclude From Simulation" ),
true,
false,
false,
true );
1033 AddField( wxS(
"${EXCLUDE_FROM_BOARD}" ),
_(
"Exclude From Board" ),
true,
false,
false,
true );
1035 AddField( wxS(
"Power" ),
_(
"Power Symbol" ),
true,
false,
false,
true );
1036 AddField( wxS(
"LocalPower" ),
_(
"Local Power Symbol" ),
true,
false,
false,
true );
1039 std::set<wxString> userFieldNames;
1043 std::vector< SCH_FIELD* > fields;
1044 symbol->GetFields( fields );
1048 if( !field->IsMandatory() && !field->IsPrivate() )
1049 userFieldNames.insert( field->GetName() );
1053 for(
const wxString& fieldName : userFieldNames )
1059 bool groupBy,
bool addedByUser,
bool aIsCheckbox )
1069 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser, aIsCheckbox );
1071 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
1072 m_grid->ProcessTableMessage( msg );
1075 [&]() -> std::pair<int, int>
1086 int col =
m_dataModel->GetFieldNameCol( fieldName );
1087 wxCHECK_RET( col != -1, wxS(
"Field name not found" ) );
1095 int col =
m_dataModel->GetFieldNameCol( oldName );
1096 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
1111 int sortCol = aEvent.GetCol();
1112 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1117 if(
m_grid->IsSortingBy( sortCol ) )
1120 ascending = !
m_grid->IsSortOrderAscending();
1135 int origPos = aEvent.GetCol();
1140 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1142 if(
m_grid->IsColShown( i ) )
1144 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1152 int newPos =
m_grid->GetColPos( origPos );
1155 if( newPos < origPos )
1188 int row = aEvent.GetRow();
1190 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1192 switch( aEvent.GetCol() )
1198 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1203 m_grid->SetColLabelValue( dataCol, label );
1216 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1228 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
STD_BITMAP_BUTTON * m_renameFieldButton
STD_BITMAP_BUTTON * m_addFieldButton
WX_GRID * m_viewControlsGrid
DIALOG_LIB_FIELDS_TABLE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Library Fields Table (%s)"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER)
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 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()
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.
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.
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.
const wxString GetLibraryName() const
wxString GetName() const override
wxArrayString GetFPFilters() const
wxString GetLibNickname() const override
Sets the Description field text value.
std::vector< SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
LIB_SYMBOL_SPTR GetRootSymbol() const
Get the parent symbol that does not have another parent.
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
std::shared_ptr< LIB_SYMBOL > LIB_SYMBOL_SPTR
shared pointer to LIB_SYMBOL
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:...
wxString view_controls_visible_columns
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.