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" ),
_(
"Revert the symbol to its last saved state" ), wxITEM_NORMAL );
105 wxMenuItem* clearMenu = menu.Append(
MYID_CLEAR_CELL,
_(
"Clear cell" ),
_(
"Clear the cell value" ), wxITEM_NORMAL );
106 menu.AppendSeparator();
107 wxMenuItem* createDerivedSymbolMenu = menu.Append(
MYID_CREATE_DERIVED_SYMBOL,
_(
"Create Derived Symbol" ),
_(
"Create a new symbol derived from the selected one" ), wxITEM_NORMAL );
110 wxPoint mousePos = wxGetMousePosition();
111 wxPoint gridPt =
m_grid->ScreenToClient( mousePos );
114 int headerHeight =
m_grid->GetColLabelSize();
115 gridPt.y -= headerHeight;
119 int row =
m_grid->YToRow( gridPt.y );
120 int col =
m_grid->XToCol( gridPt.x );
121 m_grid->SetGridCursor( row, col );
123 revertMenu->Enable(
m_dataModel->IsCellEdited( row, col ) );
124 clearMenu->Enable( !
m_dataModel->IsCellClear( row, col ) );
125 createDerivedSymbolMenu->Enable(
m_dataModel->IsRowSingleSymbol( row ) );
130 menu.AppendSeparator();
135 menu.AppendSeparator();
143 int row =
m_grid->GetGridCursorRow();
144 int col =
m_grid->GetGridCursorCol();
148 if(
m_grid->CommitPendingChanges(
false ) )
154 m_dlg->ClearModify();
160 if(
m_grid->CommitPendingChanges(
false ) )
166 m_dlg->ClearModify();
177 wxArrayString symbolNames;
181 [&](
const wxString& newName ) ->
bool
183 return symbolNames.Index( newName ) == wxNOT_FOUND;
191 wxString derivedName = dlg.
GetName();
193 m_dataModel->CreateDerivedSymbolImmediate( row, col, derivedName );
203 wxString fpid =
m_grid->GetCellValue( row, col );
207 if( frame->ShowModal( &fpid,
m_dlg ) )
208 m_grid->SetCellValue( row, col, fpid );
215 wxString datasheet_uri =
m_grid->GetCellValue( row, col );
220 if( !
m_grid->CommitPendingChanges(
false ) )
228 m_dlg->ShowHideColumn( col, show );
230 wxString fieldName =
m_dataModel->GetColFieldName( col );
279 wxGridCellAttr* attr =
new wxGridCellAttr;
280 attr->SetReadOnly(
true );
283 attr =
new wxGridCellAttr;
284 attr->SetRenderer(
new wxGridCellBoolRenderer() );
286 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
289 attr =
new wxGridCellAttr;
290 attr->SetRenderer(
new wxGridCellBoolRenderer() );
292 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
298 m_filter->SetDescriptiveText(
_(
"Filter" ) );
302 m_grid->UseNativeColHeader(
true );
306 m_grid->SetSelectionMode( wxGrid::wxGridSelectCells );
328 if( visible_column.IsEmpty() )
330 visible_column = wxT(
"0" );
334 CallAfter( [
this, cfg]()
363 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
365 if(
m_grid->IsColShown( i ) )
367 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
380 m_grid->PopEventHandler(
true );
390 if( aIsLeftPanelCollapsed )
405 wxGridCellAttr* attr =
new wxGridCellAttr;
406 attr->SetReadOnly(
false );
412 wxString symbolNetlist;
421 pins.push_back(
pin->GetNumber() +
' ' +
pin->GetShownName() );
423 if( !pins.IsEmpty() )
426 symbolNetlist << wxS(
"\r" );
429 if( !fpFilters.IsEmpty() )
432 symbolNetlist << wxS(
"\r" );
446 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
458 attr->SetEditor(
m_grid->GetDefaultEditor() );
467 wxSize defaultDlgSize = ConvertDialogToPixels( wxSize( 600, 300 ) );
470 m_grid->AutoSizeColumns(
false );
472 bool sortAscending =
true;
478 if(
m_dataModel->GetSortCol() == 0 && nameCol != -1 )
481 sortAscending =
true;
485 for(
int col = 0; col <
m_grid->GetNumberCols(); ++col )
511 std::string key(
m_dataModel->GetColFieldName( col ).ToUTF8() );
521 int maxWidth = defaultDlgSize.x / 3;
523 m_grid->SetColSize( col, std::clamp( textWidth, 100, maxWidth ) );
533 m_grid->SetSortingColumn( sortCol, sortAscending );
543 case SCOPE::SCOPE_LIBRARY:
m_choiceScope->SetSelection( 0 );
break;
544 case SCOPE::SCOPE_RELATED_SYMBOLS:
m_choiceScope->SetSelection( 1 );
break;
558 wxString libName =
m_parent->GetTreeLIBID().GetLibNickname();
560 if( aSymbolNames.IsEmpty() )
563 wxMessageBox( wxString::Format(
_(
"No related symbols found in library '%s'." ), libName ) );
565 wxMessageBox( wxString::Format(
_(
"No symbols found in library '%s'." ), libName ) );
571 for(
const wxString& symbolName : aSymbolNames )
575 if( canvasSymbol && canvasSymbol->
GetLibraryName() == libName && canvasSymbol->
GetName() == symbolName )
589 wxLogWarning( wxString::Format(
_(
"Error loading symbol '%s': %s" ), symbolName, ioe.
What() ) );
597 wxMessageBox(
_(
"No related symbols could be loaded from the library." ) );
599 wxMessageBox(
_(
"No symbols could be loaded from the library." ) );
608 if( !
m_grid->CommitPendingChanges() )
611 if( !wxDialog::TransferDataFromWindow() )
614 bool updateCanvas =
false;
621 if(
m_parent->GetCurSymbol() == symbol )
627 auto createdSymbols =
m_dataModel->GetAndClearCreatedDerivedSymbols();
629 wxLogTrace(
traceLibFieldTable,
"Post-apply handler: found %zu created derived symbols",
630 createdSymbols.size() );
632 for(
const auto& [symbol, libraryName] : createdSymbols )
634 if( !libraryName.IsEmpty() )
639 m_parent->GetLibManager().UpdateSymbol( symbol, libraryName );
644 if( !createdSymbols.empty() )
646 wxLogTrace(
traceLibFieldTable,
"Syncing libraries due to %zu new symbols", createdSymbols.size() );
649 std::vector<LIB_SYMBOL*> symbolsToPreserve;
650 for(
const auto& [symbol, libraryName] : createdSymbols )
652 symbolsToPreserve.push_back( symbol );
664 if( existingSymbol->m_Uuid == symbol->
m_Uuid )
683 wxLogTrace(
traceLibFieldTable,
"About to rebuild grid rows to include new symbols" );
701 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Add Field" ) );
703 if( dlg.ShowModal() != wxID_OK )
706 wxString fieldName = dlg.GetValue();
708 if( fieldName.IsEmpty() )
714 for(
int i = 0; i <
m_dataModel->GetNumberCols(); ++i )
716 if( fieldName ==
m_dataModel->GetColFieldName( i ) )
718 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already in use." ), fieldName ) );
736 return IsOK(
this, wxString::Format(
_(
"Are you sure you want to remove the field '%s'?" ),
758 if( selectedRows.empty() )
761 int row = selectedRows[0];
765 int col =
m_dataModel->GetFieldNameCol( fieldName );
766 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
768 wxTextEntryDialog dlg(
this,
_(
"New field name:" ),
_(
"Rename Field" ), fieldName );
770 if( dlg.ShowModal() != wxID_OK )
773 wxString newFieldName = dlg.GetValue();
775 if( newFieldName == fieldName )
778 if(
m_dataModel->GetFieldNameCol( newFieldName ) != -1 )
780 DisplayError(
this, wxString::Format(
_(
"Field name '%s' already exists." ), newFieldName ) );
804 wxPoint pos = aEvent.GetPosition();
805 wxRect ctrlRect =
m_filter->GetScreenRect();
806 int buttonWidth = ctrlRect.GetHeight();
809 if(
m_filter->IsSearchButtonVisible() && pos.x < buttonWidth )
810 SetCursor( wxCURSOR_ARROW );
811 else if(
m_filter->IsCancelButtonVisible() && pos.x > ctrlRect.GetWidth() - buttonWidth )
812 SetCursor( wxCURSOR_ARROW );
814 SetCursor( wxCURSOR_IBEAM );
821 wxString targetLib =
m_parent->GetTargetLibId().GetLibNickname();
822 wxString targetSymbol =
m_parent->GetTargetLibId().GetLibItemName();
823 wxArrayString symbolNames;
825 SetTitle( wxString::Format(
_(
"Library Fields Table (%s)" ), targetLib ) );
829 if(
m_scope == SCOPE::SCOPE_RELATED_SYMBOLS )
836 symbolNames.Add( root->
GetName() );
860 switch( aEvent.GetSelection() )
862 case 0:
setScope( SCOPE::SCOPE_LIBRARY );
break;
863 case 1:
setScope( SCOPE::SCOPE_RELATED_SYMBOLS );
break;
883 if(
m_dataModel->IsExpanderColumn( event.GetCol() ) )
887 m_grid->SetGridCursor( event.GetRow(), event.GetCol() );
902 wxPoint mousePos = wxGetMousePosition();
903 wxPoint gridPt =
m_grid->ScreenToClient( mousePos );
905 int row =
m_grid->YToRow( gridPt.y );
906 int col =
m_grid->XToCol( gridPt.x );
908 if ( row != -1 && col != -1 )
909 m_grid->SetGridCursor( row, col );
938 int remainingWidth =
m_viewControlsGrid->GetSize().GetX() - showColWidth - groupByColWidth;
989 m_grid->CommitPendingChanges(
true );
1001 EndModal( wxID_CANCEL );
1008 EndModal( wxID_OK );
1014 m_grid->CommitPendingChanges(
true );
1035 auto addMandatoryField =
1036 [&](
FIELD_T fieldId,
bool show,
bool groupBy )
1051 AddField( wxS(
"Keywords" ),
_(
"Keywords" ),
true,
false );
1054 AddField( wxS(
"${EXCLUDE_FROM_BOM}" ),
_(
"Exclude From BOM" ),
true,
false,
false,
true );
1055 AddField( wxS(
"${EXCLUDE_FROM_SIM}" ),
_(
"Exclude From Simulation" ),
true,
false,
false,
true );
1056 AddField( wxS(
"${EXCLUDE_FROM_BOARD}" ),
_(
"Exclude From Board" ),
true,
false,
false,
true );
1058 AddField( wxS(
"Power" ),
_(
"Power Symbol" ),
true,
false,
false,
true );
1059 AddField( wxS(
"LocalPower" ),
_(
"Local Power Symbol" ),
true,
false,
false,
true );
1062 std::set<wxString> userFieldNames;
1066 std::vector< SCH_FIELD* > fields;
1067 symbol->GetFields( fields );
1071 if( !field->IsMandatory() && !field->IsPrivate() )
1072 userFieldNames.insert( field->GetName() );
1076 for(
const wxString& fieldName : userFieldNames )
1082 bool groupBy,
bool addedByUser,
bool aIsCheckbox )
1092 m_dataModel->AddColumn( aFieldName, aLabelValue, addedByUser, aIsCheckbox );
1094 wxGridTableMessage msg(
m_dataModel, wxGRIDTABLE_NOTIFY_COLS_APPENDED, 1 );
1095 m_grid->ProcessTableMessage( msg );
1098 [&]() -> std::pair<int, int>
1109 int col =
m_dataModel->GetFieldNameCol( fieldName );
1110 wxCHECK_RET( col != -1, wxS(
"Field name not found" ) );
1118 int col =
m_dataModel->GetFieldNameCol( oldName );
1119 wxCHECK_RET( col != -1, wxS(
"Existing field name missing from data model" ) );
1134 int sortCol = aEvent.GetCol();
1135 std::string key(
m_dataModel->GetColFieldName( sortCol ).ToUTF8() );
1140 if(
m_grid->IsSortingBy( sortCol ) )
1143 ascending = !
m_grid->IsSortOrderAscending();
1158 int origPos = aEvent.GetCol();
1163 for(
int i = 0; i <
m_grid->GetNumberCols(); i++ )
1165 if(
m_grid->IsColShown( i ) )
1167 std::string fieldName(
m_dataModel->GetColFieldName( i ).ToUTF8() );
1175 int newPos =
m_grid->GetColPos( origPos );
1178 if( newPos < origPos )
1211 int row = aEvent.GetRow();
1213 wxCHECK( row < m_viewControlsGrid->GetNumberRows(), );
1215 switch( aEvent.GetCol() )
1221 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1226 m_grid->SetColLabelValue( dataCol, label );
1239 int dataCol =
m_dataModel->GetFieldNameCol( fieldName );
1251 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
wxCheckBox * m_groupSymbolsBox
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 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.
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.