31#include <wx/filename.h>
33#include <wx/dataview.h>
40constexpr wxUIntPtr ROW_DATA_DERIVED = 1;
43constexpr unsigned int SYMBOL_COLUMN = 1;
53class IMPORT_SYMBOL_LIST_STORE :
public wxDataViewListStore
56 bool GetAttrByRow(
unsigned int aRow,
unsigned int aCol,
57 wxDataViewItemAttr& aAttr )
const override
59 if( aCol == SYMBOL_COLUMN && GetItemData( GetItem( aRow ) ) == ROW_DATA_DERIVED )
61 aAttr.SetItalic(
true );
73 const wxString& aFilePath,
74 const wxString& aDestLibrary,
75 SCH_IO_MGR::SCH_FILE_T aPluginType ) :
87 wxFileName fn( aFilePath );
88 SetTitle( wxString::Format(
_(
"Import Symbols from %s" ), fn.GetFullName() ) );
92 IMPORT_SYMBOL_LIST_STORE* store =
new IMPORT_SYMBOL_LIST_STORE();
96 m_symbolList->AppendToggleColumn( wxEmptyString, wxDATAVIEW_CELL_ACTIVATABLE, 30 );
97 m_symbolList->AppendIconTextColumn(
_(
"Symbol" ), wxDATAVIEW_CELL_INERT, 250 );
99 m_symbolList->Connect( wxEVT_DATAVIEW_ITEM_VALUE_CHANGED,
119 m_symbolList->Disconnect( wxEVT_DATAVIEW_ITEM_VALUE_CHANGED,
148 DisplayError(
this,
_(
"Unable to find a plugin to read this library." ) );
152 wxArrayString symbolNames;
161 wxString::Format(
_(
"Cannot read symbol library '%s'." ),
m_filePath ),
166 if( symbolNames.empty() )
176 for(
const wxString&
name : symbolNames )
179 bool isPower =
false;
203 [&libMgr,
this](
const wxString&
name ) {
233 wxVector<wxVariant> data;
237 bool isChecked =
info->m_checked ||
info->m_autoSelected;
238 data.push_back( wxVariant( isChecked ) );
240 if(
info->m_isPower )
243 icon.CopyFromBitmap( bmp );
245 else if(
info->m_existsInDest )
248 icon.CopyFromBitmap( bmp );
253 wxDataViewIconText iconText(
name, icon );
254 data.push_back( wxVariant( iconText ) );
258 wxUIntPtr rowData =
info->m_parentName.IsEmpty() ? 0 : ROW_DATA_DERIVED;
304 for(
int ii = 0; ii < unitCount; ii++ )
310 int selectedUnit = (
m_unitChoice->GetSelection() != wxNOT_FOUND )
315 std::unique_ptr<LIB_SYMBOL> flattenedSym;
322 m_preview->DisplayPart( flattenedSym.get(), selectedUnit );
327 m_preview->DisplayPart( sym, selectedUnit );
332 m_preview->DisplayPart( sym, selectedUnit );
339 int manualCount =
m_manager.GetManualSelectionCount();
340 int autoCount =
m_manager.GetAutoSelectionCount();
346 status = wxString::Format(
_(
"%d symbols selected, %d parents auto-included" ),
347 manualCount, autoCount );
351 status = wxString::Format(
_(
"%d symbols selected" ), manualCount );
360 bool hasSelection = !
m_manager.GetSymbolsToImport().empty();
376 if( row == wxNOT_FOUND )
385 if( listIndex == row )
402 if( row == wxNOT_FOUND )
407 if( listIndex == row )
411 bool newState = value.GetBool();
424 std::vector<wxString> changed =
m_manager.SetSymbolSelected( aSymbolName,
true );
426 for(
const wxString& changedName : changed )
438 m_manager.DeselectWithDescendants( aSymbolName );
450 bool shouldBeChecked =
info->m_checked ||
info->m_autoSelected;
494 int selectedUnit = (
m_unitChoice->GetSelection() != wxNOT_FOUND )
514 std::unique_ptr<LIB_SYMBOL> flattenedSym;
521 m_preview->DisplayPart( flattenedSym.get(), selectedUnit );
525 m_preview->DisplayPart( sym, selectedUnit );
530 m_preview->DisplayPart( sym, selectedUnit );
545 std::vector<wxString> conflicts =
m_manager.GetConflicts();
547 if( conflicts.empty() )
550 wxDialog dlg(
this, wxID_ANY,
_(
"Resolve Import Conflicts" ),
551 wxDefaultPosition, wxSize( 500, 400 ),
552 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
554 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
556 wxStaticText* label =
new wxStaticText( &dlg, wxID_ANY,
557 _(
"The following symbols already exist in the destination library. "
558 "Choose how to handle each conflict:" ) );
560 mainSizer->Add( label, 0, wxALL | wxEXPAND, 10 );
562 wxDataViewListCtrl* conflictList =
new wxDataViewListCtrl( &dlg, wxID_ANY );
563 conflictList->AppendTextColumn(
_(
"Symbol" ), wxDATAVIEW_CELL_INERT, 200 );
564 conflictList->AppendTextColumn(
_(
"Action" ), wxDATAVIEW_CELL_EDITABLE, 100 );
566 for(
const wxString&
name : conflicts )
568 wxVector<wxVariant> data;
569 data.push_back( wxVariant(
name ) );
570 data.push_back( wxVariant(
_(
"Overwrite" ) ) );
571 conflictList->AppendItem( data );
576 mainSizer->Add( conflictList, 1, wxALL | wxEXPAND, 10 );
578 wxBoxSizer* actionSizer =
new wxBoxSizer( wxHORIZONTAL );
579 wxButton* skipAllBtn =
new wxButton( &dlg, wxID_ANY,
_(
"Skip All" ) );
580 wxButton* overwriteAllBtn =
new wxButton( &dlg, wxID_ANY,
_(
"Overwrite All" ) );
581 actionSizer->Add( skipAllBtn, 0, wxRIGHT, 5 );
582 actionSizer->Add( overwriteAllBtn, 0 );
583 mainSizer->Add( actionSizer, 0, wxLEFT | wxRIGHT | wxBOTTOM, 10 );
585 wxStdDialogButtonSizer* btnSizer =
new wxStdDialogButtonSizer();
586 btnSizer->AddButton(
new wxButton( &dlg, wxID_OK,
_(
"Import" ) ) );
587 btnSizer->AddButton(
new wxButton( &dlg, wxID_CANCEL ) );
589 mainSizer->Add( btnSizer, 0, wxALL | wxEXPAND, 10 );
591 dlg.SetSizer( mainSizer );
593 skipAllBtn->Bind( wxEVT_BUTTON, [&]( wxCommandEvent& ) {
594 for(
size_t i = 0; i < conflicts.size(); i++ )
596 conflictList->SetTextValue(
_(
"Skip" ), i, 1 );
601 overwriteAllBtn->Bind( wxEVT_BUTTON, [&]( wxCommandEvent& ) {
602 for(
size_t i = 0; i < conflicts.size(); i++ )
604 conflictList->SetTextValue(
_(
"Overwrite" ), i, 1 );
609 conflictList->Bind( wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [&]( wxDataViewEvent& evt ) {
610 int row = conflictList->ItemToRow( evt.GetItem() );
612 if( row >= 0 && row < (
int) conflicts.size() )
614 wxString action = conflictList->GetTextValue( row, 1 );
621 return dlg.ShowModal() == wxID_OK;
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
wxStaticText * m_statusLine
wxSearchCtrl * m_searchCtrl
wxBoxSizer * m_previewSizer
DIALOG_IMPORT_SYMBOL_SELECT_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Import Symbols from %s"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(900, 650), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
wxDataViewListCtrl * m_symbolList
~DIALOG_IMPORT_SYMBOL_SELECT() override
bool loadSymbols()
Load symbols from the source file and populate the manager.
SYMBOL_IMPORT_MANAGER m_manager
Manager for symbol selection logic.
void refreshList()
Refresh the list control based on current filter and selections.
std::vector< wxString > GetSelectedSymbols() const
Get the list of symbols selected for import.
bool toggleSymbolSelection(const wxString &aSymbolName, bool aChecked)
Toggle selection state for a symbol.
wxString m_filterString
Current filter string.
wxString m_selectedSymbol
Currently selected symbol for preview.
bool matchesFilter(const wxString &aSymbolName) const
Check if a symbol matches the current filter.
std::map< wxString, CONFLICT_RESOLUTION > m_conflictResolutions
Conflict resolutions chosen by user.
void OnSymbolSelected(wxDataViewEvent &event) override
bool resolveConflicts()
Show conflict resolution dialog.
void updateImportButton()
Update import button enabled state based on selection.
void updateStatusLine()
Update the status line with selection counts.
void OnFilterTextChanged(wxCommandEvent &event) override
bool TransferDataToWindow() override
void OnSelectAll(wxCommandEvent &event) override
std::map< wxString, int > m_listIndices
Map from symbol name to list index (UI-only, -1 if filtered out)
bool TransferDataFromWindow() override
SYMBOL_PREVIEW_WIDGET * m_preview
SYMBOL_EDIT_FRAME * m_frame
void OnSelectNone(wxCommandEvent &event) override
void onItemChecked(wxDataViewEvent &event)
Handle checkbox toggle in the list.
void OnUnitChanged(wxCommandEvent &event) override
DIALOG_IMPORT_SYMBOL_SELECT(SYMBOL_EDIT_FRAME *aParent, const wxString &aFilePath, const wxString &aDestLibrary, SCH_IO_MGR::SCH_FILE_T aPluginType)
void updatePreview()
Update the preview for the currently selected symbol.
IO_RELEASER< SCH_IO > m_plugin
Plugin kept alive for symbol access during dialog lifetime.
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={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
@ GAL_TYPE_OPENGL
OpenGL implementation.
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()
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Symbol library management helper that is specific to the symbol library editor frame.
Define a library symbol object.
bool IsPower() const override
const wxString & GetParentName() const
int GetUnitCount() const override
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
wxString GetUnitDisplayName(int aUnit, bool aLabel) const override
Return the user-defined display name for aUnit for symbols with units.
A factory which returns an instance of a SCH_IO.
The symbol library editor main window.
static bool MatchesFilter(const wxString &aSymbolName, const wxString &aFilter)
Check if a symbol name matches a filter string (case-insensitive contains).
bool SymbolExists(const wxString &aSymbolName, const wxString &aLibrary) const
Return true if symbol with a specific alias exists in library (either original one or buffered).
static REPORTER & GetInstance()
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
This file is part of the common library.
Information about a symbol available for import.
@ OVERWRITE
Overwrite existing symbol.
@ SKIP
Don't import this symbol.