mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-21 20:53:45 +00:00
Push most of DIALOG_CHOOSE_SYMBOL down into PANEL_SYMBOL_CHOOSER.
Includes a dialog wrapper (DIALOG_SYMBOL_CHOOSER) and a frame wrapper (SYMBOL_CHOOSER_FRAME).
This commit is contained in:
parent
23033451b1
commit
974da4ea7c
common
eeschema
CMakeLists.txt
dialogs
dialog_change_symbols.cppdialog_choose_symbol.hdialog_edit_symbols_libid.cppdialog_symbol_chooser.cppdialog_symbol_chooser.h
eeschema.cppeeschema_id.hpicksymbol.cppsch_base_frame.cppsch_base_frame.hsch_edit_frame.cppsymbol_chooser_frame.cppsymbol_chooser_frame.hsymbol_viewer_frame.cppsymbol_viewer_frame.htoolbars_symbol_viewer.cpptools
widgets
include
pcbnew
@ -666,8 +666,7 @@ void DIALOG_PAGES_SETTINGS::UpdateDrawingSheetExample()
|
||||
|
||||
if( m_parent->IsType( FRAME_SCH )
|
||||
|| m_parent->IsType( FRAME_SCH_SYMBOL_EDITOR )
|
||||
|| m_parent->IsType( FRAME_SCH_VIEWER )
|
||||
|| m_parent->IsType( FRAME_SCH_VIEWER_MODAL ) )
|
||||
|| m_parent->IsType( FRAME_SCH_VIEWER ) )
|
||||
{
|
||||
COLOR4D color = renderSettings.GetLayerColor( LAYER_SCHEMATIC_DRAWINGSHEET );
|
||||
renderSettings.SetLayerColor( LAYER_DRAWINGSHEET, color );
|
||||
|
@ -60,7 +60,6 @@ PANEL_GRID_SETTINGS::PANEL_GRID_SETTINGS( wxWindow* aParent, UNITS_PROVIDER* aUn
|
||||
if( m_frameType != FRAME_SCH
|
||||
&& m_frameType != FRAME_SCH_SYMBOL_EDITOR
|
||||
&& m_frameType != FRAME_SCH_VIEWER
|
||||
&& m_frameType != FRAME_SCH_VIEWER_MODAL
|
||||
&& m_frameType != FRAME_SIMULATOR )
|
||||
{
|
||||
m_checkGridOverrideConnected->Show( false );
|
||||
|
@ -374,7 +374,7 @@ KIWAY::FACE_T KIWAY::KifaceType( FRAME_T aFrameType )
|
||||
case FRAME_SCH:
|
||||
case FRAME_SCH_SYMBOL_EDITOR:
|
||||
case FRAME_SCH_VIEWER:
|
||||
case FRAME_SCH_VIEWER_MODAL:
|
||||
case FRAME_SYMBOL_CHOOSER:
|
||||
case FRAME_SIMULATOR:
|
||||
return FACE_SCH;
|
||||
|
||||
|
@ -355,8 +355,7 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
|
||||
// Leave a bigger margin for library editors & viewers
|
||||
|
||||
if( frame->IsType( FRAME_FOOTPRINT_VIEWER )
|
||||
|| frame->IsType( FRAME_SCH_VIEWER )
|
||||
|| frame->IsType( FRAME_SCH_VIEWER_MODAL ) )
|
||||
|| frame->IsType( FRAME_SCH_VIEWER ) )
|
||||
{
|
||||
margin_scale_factor = 1.30;
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ protected:
|
||||
rawValue = m_preselect;
|
||||
|
||||
wxString symbolId = escapeLibId( rawValue );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_SCH_VIEWER_MODAL, true, m_dlg );
|
||||
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_SYMBOL_CHOOSER, true, m_dlg );
|
||||
|
||||
if( frame->ShowModal( &symbolId, m_dlg ) )
|
||||
SetValue( UnescapeString( symbolId ) );
|
||||
|
@ -149,9 +149,6 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, const wxString& aRecentSearchesKey, LIB_T
|
||||
m_tree_ctrl = new WX_DATAVIEWCTRL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, dvFlags );
|
||||
m_adapter->AttachTo( m_tree_ctrl );
|
||||
|
||||
if( aFlags & DETAILS )
|
||||
sizer->AddSpacer( 5 );
|
||||
|
||||
sizer->Add( m_tree_ctrl, 5, wxRIGHT | wxBOTTOM | wxEXPAND, 1 );
|
||||
|
||||
// Description panel
|
||||
@ -162,8 +159,7 @@ LIB_TREE::LIB_TREE( wxWindow* aParent, const wxString& aRecentSearchesKey, LIB_T
|
||||
wxPoint html_size = ConvertDialogToPixels( wxPoint( 80, 80 ) );
|
||||
|
||||
m_details_ctrl = new HTML_WINDOW( this, wxID_ANY, wxDefaultPosition,
|
||||
wxSize( html_size.x, html_size.y ),
|
||||
wxHW_SCROLLBAR_AUTO );
|
||||
wxSize( html_size.x, html_size.y ) );
|
||||
|
||||
sizer->Add( m_details_ctrl, 2, wxTOP | wxEXPAND, 5 );
|
||||
}
|
||||
|
@ -77,7 +77,6 @@ set( EESCHEMA_DLGS
|
||||
dialogs/dialog_bom_base.cpp
|
||||
dialogs/dialog_change_symbols.cpp
|
||||
dialogs/dialog_change_symbols_base.cpp
|
||||
dialogs/dialog_choose_symbol.cpp
|
||||
dialogs/dialog_database_lib_settings_base.cpp
|
||||
dialogs/dialog_database_lib_settings.cpp
|
||||
dialogs/dialog_edit_symbols_libid.cpp
|
||||
@ -135,6 +134,7 @@ set( EESCHEMA_DLGS
|
||||
dialogs/dialog_sheet_pin_properties_base.cpp
|
||||
dialogs/dialog_sheet_properties.cpp
|
||||
dialogs/dialog_sheet_properties_base.cpp
|
||||
dialogs/dialog_symbol_chooser.cpp
|
||||
dialogs/dialog_symbol_fields_table.cpp
|
||||
dialogs/dialog_symbol_fields_table_base.cpp
|
||||
dialogs/dialog_symbol_properties.cpp
|
||||
@ -256,6 +256,7 @@ set( EESCHEMA_SIM_SRCS
|
||||
|
||||
set( EESCHEMA_WIDGETS
|
||||
widgets/hierarchy_pane.cpp
|
||||
widgets/panel_symbol_chooser.cpp
|
||||
widgets/pin_shape_combobox.cpp
|
||||
widgets/pin_type_combobox.cpp
|
||||
widgets/symbol_diff_widget.cpp
|
||||
@ -368,6 +369,7 @@ set( EESCHEMA_SRCS
|
||||
sheet.cpp
|
||||
symbol_async_loader.cpp
|
||||
symbol_checker.cpp
|
||||
symbol_chooser_frame.cpp
|
||||
symbol_lib_table.cpp
|
||||
symbol_library.cpp
|
||||
symbol_library_manager.cpp
|
||||
|
@ -244,7 +244,7 @@ void DIALOG_CHANGE_SYMBOLS::launchMatchIdSymbolBrowser( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxString newName = getLibIdValue( m_specifiedId );
|
||||
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH_VIEWER_MODAL, true, this );
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this );
|
||||
|
||||
if( frame->ShowModal( &newName, this ) )
|
||||
{
|
||||
@ -260,7 +260,7 @@ void DIALOG_CHANGE_SYMBOLS::launchNewIdSymbolBrowser( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxString newName = getLibIdValue( m_newId );
|
||||
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH_VIEWER_MODAL, true, this );
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this );
|
||||
|
||||
if( frame->ShowModal( &newName, this ) )
|
||||
{
|
||||
|
@ -1,233 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
|
||||
* Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#ifndef DIALOG_CHOOSE_SYMBOL_H
|
||||
#define DIALOG_CHOOSE_SYMBOL_H
|
||||
|
||||
#include "dialog_shim.h"
|
||||
#include <symbol_tree_model_adapter.h>
|
||||
#include <footprint_info.h>
|
||||
#include <widgets/html_window.h>
|
||||
|
||||
class wxCheckBox;
|
||||
class wxStaticBitmap;
|
||||
class wxTextCtrl;
|
||||
class wxStdDialogButtonSizer;
|
||||
class wxDataViewCtrl;
|
||||
class wxHtmlLinkEvent;
|
||||
class wxPanel;
|
||||
class wxChoice;
|
||||
class wxButton;
|
||||
class wxTimer;
|
||||
class wxSplitterWindow;
|
||||
|
||||
class LIB_TREE;
|
||||
class SYMBOL_PREVIEW_WIDGET;
|
||||
class FOOTPRINT_PREVIEW_WIDGET;
|
||||
class FOOTPRINT_SELECT_WIDGET;
|
||||
class LIB_ALIAS;
|
||||
class SCH_BASE_FRAME;
|
||||
class SCH_DRAW_PANEL;
|
||||
|
||||
|
||||
/**
|
||||
* Dialog class to select a symbol from the libraries. This is the master View class in a
|
||||
* Model-View-Adapter (mediated MVC) architecture. The other pieces are in:
|
||||
*
|
||||
* - Adapter: SYM_TREE_MODEL_ADAPTER in common/cmp_tree_model_adapter.h
|
||||
* - Model: SYM_TREE_NODE and descendants in common/cmp_tree_model.h
|
||||
*
|
||||
* Because everything is tied together in the adapter class, see that file
|
||||
* for thorough documentation. A simple example usage follows:
|
||||
*
|
||||
* // Create the adapter class
|
||||
* auto adapter( SYMBOL_TREE_MODEL_ADAPTER::Create( PROJECT_SCH::SchSymbolLibTable( &Prj() ) );
|
||||
*
|
||||
* // Perform any configuration of adapter properties here
|
||||
* adapter->SetPreselectNode( "LIB_NICKNAME", "SYMBO_NAME", 2 );
|
||||
*
|
||||
* // Initialize model from #SYMBOL_LIB_TABLE
|
||||
* libNicknames = libs->GetLogicalLibs();
|
||||
*
|
||||
* for( auto nickname : libNicknames )
|
||||
* adapter->AddLibrary( nickname );
|
||||
*
|
||||
* // Create and display dialog
|
||||
* DIALOG_CHOOSE_SYMBOL dlg( this, title, adapter, 1 );
|
||||
* bool selected = ( dlg.ShowModal() != wxID_CANCEL );
|
||||
*
|
||||
* // Receive part
|
||||
* if( selected )
|
||||
* {
|
||||
* int unit;
|
||||
* #LIB_ID id = dlg.GetSelectedAlias( &unit );
|
||||
* do_something( id, unit );
|
||||
* }
|
||||
*
|
||||
*/
|
||||
class DIALOG_CHOOSE_SYMBOL : public DIALOG_SHIM
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create dialog to choose symbol.
|
||||
*
|
||||
* @param aParent a SCH_BASE_FRAME parent window.
|
||||
* @param aTitle Dialog title.
|
||||
* @param aAdapter SYMBOL_TREE_MODEL_ADAPTER::PTR. See SYM_TREE_MODEL_ADAPTER
|
||||
* for documentation.
|
||||
* @param aDeMorganConvert preferred deMorgan conversion.
|
||||
* (TODO: should happen in dialog)
|
||||
* @param aAllowFieldEdits if false, all functions that allow the user to edit fields
|
||||
* (currently just footprint selection) will not be available.
|
||||
* @param aShowFootprints if false, all footprint preview and selection features are
|
||||
* disabled. This forces aAllowFieldEdits false too.
|
||||
* @param aAllowBrowser show a Select with Browser button.
|
||||
*/
|
||||
DIALOG_CHOOSE_SYMBOL( SCH_BASE_FRAME* aParent, const wxString& aTitle,
|
||||
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>& aAdapter,
|
||||
int aDeMorganConvert, bool aAllowFieldEdits, bool aShowFootprints,
|
||||
bool aAllowBrowser );
|
||||
|
||||
~DIALOG_CHOOSE_SYMBOL();
|
||||
|
||||
/**
|
||||
* To be called after this dialog returns from ShowModal().
|
||||
*
|
||||
* For multi-unit symbols, if the user selects the symbol itself rather than picking
|
||||
* an individual unit, 0 will be returned in aUnit.
|
||||
* Beware that this is an invalid unit number - this should be replaced with whatever
|
||||
* default is desired (usually 1).
|
||||
*
|
||||
* @param aUnit if not NULL, the selected unit is filled in here.
|
||||
* @return the #LIB_ID of the symbol that has been selected.
|
||||
*/
|
||||
LIB_ID GetSelectedLibId( int* aUnit = nullptr ) const;
|
||||
|
||||
/**
|
||||
* To be called after this dialog returns from ShowModal()
|
||||
*
|
||||
* In the case of multi-unit symbols, this preferences asks to iterate through
|
||||
* all units of the symbol, one per click.
|
||||
*
|
||||
* @return The value of the dialog preference checkbox.
|
||||
*/
|
||||
bool GetUseAllUnits() const;
|
||||
|
||||
/**
|
||||
* To be called after this dialog returns from ShowModal()
|
||||
*
|
||||
* Keeps a new copy of the symbol on the mouse cursor, allowing the user to rapidly
|
||||
* place multiple copies of the same symbol on their schematic.
|
||||
*
|
||||
* @return The value of the keep symbol preference checkbox.
|
||||
*/
|
||||
bool GetKeepSymbol() const;
|
||||
|
||||
/**
|
||||
* Get a list of fields edited by the user.
|
||||
*
|
||||
* @return vector of pairs; each.first = field ID, each.second = new value.
|
||||
*/
|
||||
std::vector<std::pair<int, wxString>> GetFields() const
|
||||
{
|
||||
return m_field_edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the user requested the symbol browser.
|
||||
*/
|
||||
bool IsExternalBrowserSelected() const
|
||||
{
|
||||
return m_external_browser_requested;
|
||||
}
|
||||
|
||||
protected:
|
||||
static constexpr int DblClickDelay = 100; // milliseconds
|
||||
|
||||
wxPanel* ConstructRightPanel( wxWindow* aParent );
|
||||
|
||||
void OnInitDialog( wxInitDialogEvent& aEvent );
|
||||
void OnCharHook( wxKeyEvent& aEvt ) override;
|
||||
void OnCloseTimer( wxTimerEvent& aEvent );
|
||||
void OnUseBrowser( wxCommandEvent& aEvent );
|
||||
|
||||
void OnFootprintSelected( wxCommandEvent& aEvent );
|
||||
void OnComponentPreselected( wxCommandEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Handle the selection of an item. This is called when either the search box or the tree
|
||||
* receive an Enter, or the tree receives a double click.
|
||||
* If the item selected is a category, it is expanded or collapsed; if it is a symbol, the
|
||||
* symbol is picked.
|
||||
*/
|
||||
void OnComponentSelected( wxCommandEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Look up the footprint for a given symbol specified in the #LIB_ID and display it.
|
||||
*/
|
||||
void ShowFootprintFor( const LIB_ID& aLibId );
|
||||
|
||||
/**
|
||||
* Display the given footprint by name.
|
||||
*/
|
||||
void ShowFootprint( const wxString& aFootprint );
|
||||
|
||||
/**
|
||||
* Populate the footprint selector for a given alias.
|
||||
*
|
||||
* @param aLibId the #LIB_ID of the selection or invalid to clear.
|
||||
*/
|
||||
void PopulateFootprintSelector( const LIB_ID& aLibId );
|
||||
|
||||
public:
|
||||
static std::mutex g_Mutex;
|
||||
|
||||
protected:
|
||||
static wxString g_symbolSearchString;
|
||||
static wxString g_powerSearchString;
|
||||
|
||||
wxTimer* m_dbl_click_timer;
|
||||
SYMBOL_PREVIEW_WIDGET* m_symbol_preview;
|
||||
wxButton* m_browser_button;
|
||||
wxSplitterWindow* m_hsplitter;
|
||||
wxSplitterWindow* m_vsplitter;
|
||||
|
||||
FOOTPRINT_SELECT_WIDGET* m_fp_sel_ctrl;
|
||||
FOOTPRINT_PREVIEW_WIDGET* m_fp_preview;
|
||||
wxCheckBox* m_keepSymbol;
|
||||
wxCheckBox* m_useUnits;
|
||||
LIB_TREE* m_tree;
|
||||
HTML_WINDOW* m_details;
|
||||
|
||||
SCH_BASE_FRAME* m_parent;
|
||||
bool m_showPower;
|
||||
int m_deMorganConvert;
|
||||
bool m_allow_field_edits;
|
||||
bool m_show_footprints;
|
||||
bool m_external_browser_requested;
|
||||
wxString m_fp_override;
|
||||
|
||||
std::vector<std::pair<int, wxString>> m_field_edits;
|
||||
};
|
||||
|
||||
#endif /* DIALOG_CHOOSE_SYMBOL_H */
|
@ -347,8 +347,8 @@ private:
|
||||
};
|
||||
|
||||
|
||||
DIALOG_EDIT_SYMBOLS_LIBID::DIALOG_EDIT_SYMBOLS_LIBID( SCH_EDIT_FRAME* aParent )
|
||||
:DIALOG_EDIT_SYMBOLS_LIBID_BASE( aParent )
|
||||
DIALOG_EDIT_SYMBOLS_LIBID::DIALOG_EDIT_SYMBOLS_LIBID( SCH_EDIT_FRAME* aParent ) :
|
||||
DIALOG_EDIT_SYMBOLS_LIBID_BASE( aParent )
|
||||
{
|
||||
m_autoWrapRenderer = new GRIDCELL_AUTOWRAP_STRINGRENDERER;
|
||||
|
||||
@ -668,15 +668,10 @@ void DIALOG_EDIT_SYMBOLS_LIBID::onClickOrphansButton( wxCommandEvent& event )
|
||||
|
||||
bool DIALOG_EDIT_SYMBOLS_LIBID::setLibIdByBrowser( int aRow )
|
||||
{
|
||||
#if 0
|
||||
// Use dialog symbol selector to choose a symbol
|
||||
SCH_BASE_FRAME::HISTORY_LIST dummy;
|
||||
SCH_BASE_FRAME::PICKED_SYMBOL sel = m_frame->SelectComponentFromLibrary( nullptr, dummy, true,
|
||||
0, 0, false );
|
||||
#else
|
||||
// Use library viewer to choose a symbol
|
||||
LIB_ID preselected;
|
||||
wxString current = getLibIdValue( m_grid, aRow, COL_NEW_LIBID );
|
||||
std::vector<PICKED_SYMBOL> dummyHistory;
|
||||
LIB_ID preselected;
|
||||
wxString current = getLibIdValue( m_grid, aRow, COL_NEW_LIBID );
|
||||
|
||||
if( current.IsEmpty() )
|
||||
current = getLibIdValue( m_grid, aRow, COL_CURR_LIBID );
|
||||
@ -684,8 +679,8 @@ bool DIALOG_EDIT_SYMBOLS_LIBID::setLibIdByBrowser( int aRow )
|
||||
if( !current.IsEmpty() )
|
||||
preselected.Parse( current, true );
|
||||
|
||||
PICKED_SYMBOL sel = GetParent()->PickSymbolFromLibBrowser( this, nullptr, preselected, 0, 0 );
|
||||
#endif
|
||||
PICKED_SYMBOL sel = GetParent()->PickSymbolFromLibrary( nullptr, dummyHistory, false,
|
||||
&preselected, false );
|
||||
|
||||
if( sel.LibId.empty() ) // command aborted
|
||||
return false;
|
||||
|
126
eeschema/dialogs/dialog_symbol_chooser.cpp
Normal file
126
eeschema/dialogs/dialog_symbol_chooser.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <symbol_library.h>
|
||||
#include <dialog_symbol_chooser.h>
|
||||
#include <widgets/panel_symbol_chooser.h>
|
||||
#include <eeschema_settings.h>
|
||||
#include <kiface_base.h>
|
||||
#include <sch_base_frame.h>
|
||||
#include <core/kicad_algo.h>
|
||||
#include <template_fieldnames.h>
|
||||
#include <widgets/footprint_preview_widget.h>
|
||||
#include <widgets/footprint_select_widget.h>
|
||||
#include <widgets/symbol_preview_widget.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/sizer.h>
|
||||
|
||||
std::mutex DIALOG_SYMBOL_CHOOSER::g_Mutex;
|
||||
|
||||
DIALOG_SYMBOL_CHOOSER::DIALOG_SYMBOL_CHOOSER( SCH_BASE_FRAME* aParent, const LIB_ID* aPreselect,
|
||||
const SYMBOL_LIBRARY_FILTER* aFilter,
|
||||
std::vector<PICKED_SYMBOL>& aHistoryList,
|
||||
bool aAllowFieldEdits, bool aShowFootprints ) :
|
||||
DIALOG_SHIM( aParent, wxID_ANY, _( "Choose Symbol" ), wxDefaultPosition, wxDefaultSize,
|
||||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER )
|
||||
{
|
||||
wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_chooserPanel = new PANEL_SYMBOL_CHOOSER( aParent, this, aFilter, aHistoryList,
|
||||
aAllowFieldEdits, aShowFootprints,
|
||||
[this]()
|
||||
{
|
||||
EndModal( wxID_OK );
|
||||
} );
|
||||
|
||||
sizer->Add( m_chooserPanel, 1, wxEXPAND, 5 );
|
||||
|
||||
if( aPreselect && aPreselect->IsValid() )
|
||||
m_chooserPanel->SetPreselect( *aPreselect );
|
||||
|
||||
if( aFilter->GetFilterPowerSymbols() )
|
||||
SetTitle( _( "Choose Power Symbol" ) );
|
||||
|
||||
SetTitle( GetTitle() + wxString::Format( _( " (%d items loaded)" ),
|
||||
m_chooserPanel->GetItemCount() ) );
|
||||
|
||||
wxBoxSizer* buttonsSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_keepSymbol = new wxCheckBox( this, wxID_ANY, _( "Place repeated copies" ) );
|
||||
m_keepSymbol->SetToolTip( _( "Keep the symbol selected for subsequent clicks." ) );
|
||||
|
||||
m_useUnits = new wxCheckBox( this, wxID_ANY, _( "Place all units" ) );
|
||||
m_useUnits->SetToolTip( _( "Sequentially place all units of the symbol." ) );
|
||||
|
||||
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
|
||||
{
|
||||
m_keepSymbol->SetValue( cfg->m_SymChooserPanel.keep_symbol );
|
||||
m_useUnits->SetValue( cfg->m_SymChooserPanel.place_all_units );
|
||||
}
|
||||
|
||||
buttonsSizer->Add( m_keepSymbol, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 5 );
|
||||
buttonsSizer->Add( m_useUnits, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 30 );
|
||||
|
||||
wxStdDialogButtonSizer* sdbSizer = new wxStdDialogButtonSizer();
|
||||
wxButton* okButton = new wxButton( this, wxID_OK );
|
||||
wxButton* cancelButton = new wxButton( this, wxID_CANCEL );
|
||||
|
||||
sdbSizer->AddButton( okButton );
|
||||
sdbSizer->AddButton( cancelButton );
|
||||
sdbSizer->Realize();
|
||||
|
||||
buttonsSizer->Add( sdbSizer, 1, wxALL, 5 );
|
||||
|
||||
sizer->Add( buttonsSizer, 0, wxEXPAND | wxLEFT, 5 );
|
||||
SetSizer( sizer );
|
||||
|
||||
SetInitialFocus( m_chooserPanel->GetFocusTarget() );
|
||||
SetupStandardButtons();
|
||||
|
||||
m_chooserPanel->FinishSetup();
|
||||
Layout();
|
||||
}
|
||||
|
||||
|
||||
DIALOG_SYMBOL_CHOOSER::~DIALOG_SYMBOL_CHOOSER()
|
||||
{
|
||||
if( EESCHEMA_SETTINGS* cfg = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() ) )
|
||||
{
|
||||
cfg->m_SymChooserPanel.keep_symbol = m_keepSymbol->GetValue();
|
||||
cfg->m_SymChooserPanel.place_all_units = m_useUnits->GetValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LIB_ID DIALOG_SYMBOL_CHOOSER::GetSelectedLibId( int* aUnit ) const
|
||||
{
|
||||
return m_chooserPanel->GetSelectedLibId( aUnit );
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::pair<int, wxString>> DIALOG_SYMBOL_CHOOSER::GetFields() const
|
||||
{
|
||||
return m_chooserPanel->GetFields();
|
||||
}
|
||||
|
||||
|
86
eeschema/dialogs/dialog_symbol_chooser.h
Normal file
86
eeschema/dialogs/dialog_symbol_chooser.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#ifndef DIALOG_SYMBOL_CHOOSER_H
|
||||
#define DIALOG_SYMBOL_CHOOSER_H
|
||||
|
||||
#include "dialog_shim.h"
|
||||
#include <symbol_tree_model_adapter.h>
|
||||
#include <footprint_info.h>
|
||||
#include <widgets/html_window.h>
|
||||
#include <wx/checkbox.h>
|
||||
|
||||
|
||||
class SCH_BASE_FRAME;
|
||||
class PANEL_SYMBOL_CHOOSER;
|
||||
struct PICKED_SYMBOL;
|
||||
|
||||
|
||||
class DIALOG_SYMBOL_CHOOSER : public DIALOG_SHIM
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create dialog to choose symbol.
|
||||
*
|
||||
* @param aParent a SCH_BASE_FRAME parent window.
|
||||
* @param aAllowFieldEdits if false, all functions that allow the user to edit fields
|
||||
* (currently just footprint selection) will not be available.
|
||||
* @param aShowFootprints if false, all footprint preview and selection features are
|
||||
* disabled. This forces aAllowFieldEdits false too.
|
||||
*/
|
||||
DIALOG_SYMBOL_CHOOSER( SCH_BASE_FRAME* aParent, const LIB_ID* aPreselect,
|
||||
const SYMBOL_LIBRARY_FILTER* aFilter,
|
||||
std::vector<PICKED_SYMBOL>& aHistoryList,
|
||||
bool aAllowFieldEdits, bool aShowFootprints );
|
||||
|
||||
~DIALOG_SYMBOL_CHOOSER();
|
||||
|
||||
/**
|
||||
* To be called after this dialog returns from ShowModal().
|
||||
*
|
||||
* For multi-unit symbols, if the user selects the symbol itself rather than picking
|
||||
* an individual unit, 0 will be returned in aUnit.
|
||||
* Beware that this is an invalid unit number - this should be replaced with whatever
|
||||
* default is desired (usually 1).
|
||||
*
|
||||
* @param aUnit if not NULL, the selected unit is filled in here.
|
||||
* @return the #LIB_ID of the symbol that has been selected.
|
||||
*/
|
||||
LIB_ID GetSelectedLibId( int* aUnit = nullptr ) const;
|
||||
|
||||
/**
|
||||
* Get a list of fields edited by the user.
|
||||
*
|
||||
* @return vector of pairs; each.first = field ID, each.second = new value.
|
||||
*/
|
||||
std::vector<std::pair<int, wxString>> GetFields() const;
|
||||
|
||||
public:
|
||||
static std::mutex g_Mutex;
|
||||
|
||||
protected:
|
||||
PANEL_SYMBOL_CHOOSER* m_chooserPanel;
|
||||
wxCheckBox* m_keepSymbol;
|
||||
wxCheckBox* m_useUnits;
|
||||
};
|
||||
|
||||
#endif /* DIALOG_SYMBOL_CHOOSER_H */
|
@ -35,7 +35,7 @@
|
||||
#include <sch_edit_frame.h>
|
||||
#include <symbol_edit_frame.h>
|
||||
#include <symbol_viewer_frame.h>
|
||||
#include <transform.h>
|
||||
#include <symbol_chooser_frame.h>
|
||||
#include <symbol_lib_table.h>
|
||||
#include <dialogs/dialog_global_sym_lib_table_config.h>
|
||||
#include <dialogs/panel_grid_settings.h>
|
||||
@ -178,10 +178,14 @@ static struct IFACE : public KIFACE_BASE, public UNITS_PROVIDER
|
||||
}
|
||||
|
||||
case FRAME_SCH_VIEWER:
|
||||
case FRAME_SCH_VIEWER_MODAL:
|
||||
{
|
||||
SYMBOL_VIEWER_FRAME* frame = new SYMBOL_VIEWER_FRAME( aKiway, aParent,
|
||||
FRAME_T( aClassId ) );
|
||||
SYMBOL_VIEWER_FRAME* frame = new SYMBOL_VIEWER_FRAME( aKiway, aParent );
|
||||
return frame;
|
||||
}
|
||||
|
||||
case FRAME_SYMBOL_CHOOSER:
|
||||
{
|
||||
SYMBOL_CHOOSER_FRAME* frame = new SYMBOL_CHOOSER_FRAME( aKiway, aParent );
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,6 @@ enum id_eeschema_frm
|
||||
ID_LIBEDIT_SELECT_UNIT_NUMBER,
|
||||
|
||||
/* Library viewer horizontal toolbar IDs */
|
||||
ID_LIBVIEW_SELECT_PART,
|
||||
ID_LIBVIEW_NEXT,
|
||||
ID_LIBVIEW_PREVIOUS,
|
||||
ID_LIBVIEW_SELECT_UNIT_NUMBER,
|
||||
|
@ -43,180 +43,29 @@
|
||||
#include <tools/ee_actions.h>
|
||||
#include <project_sch.h>
|
||||
|
||||
#include <dialog_choose_symbol.h>
|
||||
#include <dialog_symbol_chooser.h>
|
||||
|
||||
PICKED_SYMBOL SCH_BASE_FRAME::PickSymbolFromLibBrowser( wxTopLevelWindow* aParent,
|
||||
const SYMBOL_LIBRARY_FILTER* aFilter,
|
||||
const LIB_ID& aPreselectedLibId,
|
||||
int aUnit, int aConvert )
|
||||
{
|
||||
// Close any open non-modal Lib browser, and open a new one, in "modal" mode:
|
||||
SYMBOL_VIEWER_FRAME* viewer = (SYMBOL_VIEWER_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false );
|
||||
|
||||
if( viewer )
|
||||
viewer->Destroy();
|
||||
|
||||
viewer = (SYMBOL_VIEWER_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, true, aParent );
|
||||
|
||||
if( aFilter )
|
||||
viewer->SetFilter( aFilter );
|
||||
|
||||
if( aPreselectedLibId.IsValid() )
|
||||
{
|
||||
viewer->SetSelectedLibrary( aPreselectedLibId.GetLibNickname() );
|
||||
viewer->SetSelectedSymbol( aPreselectedLibId.GetLibItemName());
|
||||
}
|
||||
|
||||
viewer->SetUnitAndConvert( aUnit, aConvert );
|
||||
|
||||
viewer->Refresh();
|
||||
|
||||
PICKED_SYMBOL sel;
|
||||
wxString symbol;
|
||||
|
||||
if( viewer->ShowModal( &symbol, aParent ) )
|
||||
{
|
||||
LIB_ID id;
|
||||
|
||||
if( id.Parse( symbol ) == -1 )
|
||||
sel.LibId = id;
|
||||
|
||||
sel.Unit = viewer->GetUnit();
|
||||
sel.Convert = viewer->GetConvert();
|
||||
}
|
||||
|
||||
viewer->Destroy();
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
|
||||
PICKED_SYMBOL SCH_BASE_FRAME::PickSymbolFromLibTree( const SYMBOL_LIBRARY_FILTER* aFilter,
|
||||
PICKED_SYMBOL SCH_BASE_FRAME::PickSymbolFromLibrary( const SYMBOL_LIBRARY_FILTER* aFilter,
|
||||
std::vector<PICKED_SYMBOL>& aHistoryList,
|
||||
bool aUseLibBrowser, int aUnit, int aConvert,
|
||||
bool aShowFootprints, const LIB_ID* aHighlight,
|
||||
bool aAllowFields )
|
||||
{
|
||||
std::unique_lock<std::mutex> dialogLock( DIALOG_CHOOSE_SYMBOL::g_Mutex, std::defer_lock );
|
||||
SYMBOL_LIB_TABLE* libs = PROJECT_SCH::SchSymbolLibTable( &Prj() );
|
||||
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
|
||||
PROJECT_FILE& project = Prj().GetProjectFile();
|
||||
std::unique_lock<std::mutex> dialogLock( DIALOG_SYMBOL_CHOOSER::g_Mutex, std::defer_lock );
|
||||
|
||||
// One DIALOG_CHOOSE_SYMBOL dialog at a time. User probably can't handle more anyway.
|
||||
// One DIALOG_SYMBOL_CHOOSER dialog at a time. User probably can't handle more anyway.
|
||||
if( !dialogLock.try_lock() )
|
||||
return PICKED_SYMBOL();
|
||||
|
||||
// Make sure settings are loaded before we start running multi-threaded symbol loaders
|
||||
Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
|
||||
Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
|
||||
DIALOG_SYMBOL_CHOOSER dlg( this, aHighlight, aFilter, aHistoryList, aAllowFields,
|
||||
aShowFootprints );
|
||||
|
||||
|
||||
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> dataPtr
|
||||
= SYMBOL_TREE_MODEL_ADAPTER::Create( this, libs );
|
||||
SYMBOL_TREE_MODEL_ADAPTER* modelAdapter
|
||||
= static_cast<SYMBOL_TREE_MODEL_ADAPTER*>( dataPtr.get() );
|
||||
bool loaded = false;
|
||||
|
||||
if( aFilter )
|
||||
{
|
||||
const wxArrayString& liblist = aFilter->GetAllowedLibList();
|
||||
|
||||
for( const wxString& nickname : liblist )
|
||||
{
|
||||
if( libs->HasLibrary( nickname, true ) )
|
||||
{
|
||||
loaded = true;
|
||||
|
||||
bool pinned = alg::contains( cfg->m_Session.pinned_symbol_libs, nickname )
|
||||
|| alg::contains( project.m_PinnedSymbolLibs, nickname );
|
||||
|
||||
if( libs->FindRow( nickname )->GetIsVisible() )
|
||||
modelAdapter->AddLibrary( nickname, pinned );
|
||||
}
|
||||
}
|
||||
|
||||
modelAdapter->AssignIntrinsicRanks();
|
||||
|
||||
if( aFilter->GetFilterPowerSymbols() )
|
||||
modelAdapter->SetFilter( SYMBOL_TREE_MODEL_ADAPTER::SYM_FILTER_POWER );
|
||||
}
|
||||
|
||||
std::vector<LIB_SYMBOL> history_list_storage;
|
||||
std::vector<LIB_TREE_ITEM*> history_list;
|
||||
|
||||
history_list_storage.reserve( aHistoryList.size() );
|
||||
|
||||
for( const PICKED_SYMBOL& i : aHistoryList )
|
||||
{
|
||||
LIB_SYMBOL* symbol = GetLibSymbol( i.LibId );
|
||||
|
||||
// This can be null, for example when a symbol has been deleted from a library
|
||||
if( symbol )
|
||||
{
|
||||
history_list_storage.emplace_back( *symbol );
|
||||
|
||||
for( const std::pair<int, wxString>& fieldDef : i.Fields )
|
||||
{
|
||||
LIB_FIELD* field = history_list_storage.back().GetFieldById( fieldDef.first );
|
||||
|
||||
if( field )
|
||||
field->SetText( fieldDef.second );
|
||||
}
|
||||
|
||||
history_list.push_back( &history_list_storage.back() );
|
||||
}
|
||||
}
|
||||
|
||||
modelAdapter->DoAddLibrary( wxT( "-- " ) + _( "Recently Used" ) + wxT( " --" ), wxEmptyString,
|
||||
history_list, false, true );
|
||||
|
||||
if( !aHistoryList.empty() )
|
||||
modelAdapter->SetPreselectNode( aHistoryList[0].LibId, aHistoryList[0].Unit );
|
||||
|
||||
const std::vector< wxString > libNicknames = libs->GetLogicalLibs();
|
||||
|
||||
if( !loaded )
|
||||
{
|
||||
if( !modelAdapter->AddLibraries( libNicknames, this ) )
|
||||
{
|
||||
// loading cancelled by user
|
||||
return PICKED_SYMBOL();
|
||||
}
|
||||
}
|
||||
|
||||
if( aHighlight && aHighlight->IsValid() )
|
||||
modelAdapter->SetPreselectNode( *aHighlight, /* aUnit */ 0 );
|
||||
|
||||
wxString dialogTitle;
|
||||
|
||||
if( modelAdapter->GetFilter() == SYMBOL_TREE_MODEL_ADAPTER::SYM_FILTER_POWER )
|
||||
dialogTitle.Printf( _( "Choose Power Symbol (%d items loaded)" ), dataPtr->GetItemCount() );
|
||||
else
|
||||
dialogTitle.Printf( _( "Choose Symbol (%d items loaded)" ), dataPtr->GetItemCount() );
|
||||
|
||||
DIALOG_CHOOSE_SYMBOL dlg( this, dialogTitle, dataPtr, aConvert, aAllowFields, aShowFootprints,
|
||||
aUseLibBrowser );
|
||||
|
||||
int ret = dlg.ShowModal();
|
||||
|
||||
// Save any changes to column widths, etc.
|
||||
modelAdapter->SaveSettings();
|
||||
|
||||
if( ret == wxID_CANCEL )
|
||||
if( dlg.ShowModal() == wxID_CANCEL )
|
||||
return PICKED_SYMBOL();
|
||||
|
||||
PICKED_SYMBOL sel;
|
||||
LIB_ID id = dlg.GetSelectedLibId( &sel.Unit );
|
||||
|
||||
if( dlg.IsExternalBrowserSelected() ) // User requested symbol browser.
|
||||
{
|
||||
sel = PickSymbolFromLibBrowser( this, aFilter, id, sel.Unit, sel.Convert );
|
||||
id = sel.LibId;
|
||||
}
|
||||
|
||||
if( !id.IsValid() ) // Dialog closed by OK button,
|
||||
// or the selection by lib browser was requested,
|
||||
// but no symbol selected
|
||||
if( !id.IsValid() )
|
||||
return PICKED_SYMBOL();
|
||||
|
||||
if( sel.Unit == 0 )
|
||||
|
@ -94,7 +94,8 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindo
|
||||
aFrameName, schIUScale ),
|
||||
m_base_frame_defaults( nullptr, "base_Frame_defaults" ), m_spaceMouse( nullptr )
|
||||
{
|
||||
createCanvas();
|
||||
if( ( aStyle & wxFRAME_NO_TASKBAR ) == 0 )
|
||||
createCanvas();
|
||||
|
||||
Bind( wxEVT_IDLE,
|
||||
[this]( wxIdleEvent& aEvent )
|
||||
|
@ -146,9 +146,6 @@ public:
|
||||
* @param aFilter is an optional #SYMBOL_LIBRARY_FILTER filter to pass the allowed library names
|
||||
* and/or the library name to load the symbol from and/or some other filter
|
||||
* @param aHistoryList is the list of previously loaded symbols - will be edited
|
||||
* @param aUseLibBrowser is the flag to call the library viewer to select the symbol
|
||||
* @param aUnit is the preselected unit.
|
||||
* @param aConvert is the preselected De Morgan shape.
|
||||
* @param aHighlight is the name of symbol to highlight in the list.
|
||||
* highlights none if there isn't one by that name.
|
||||
* @param aShowFootprints is the whether to show footprints in the dialog.
|
||||
@ -156,13 +153,9 @@ public:
|
||||
*
|
||||
* @return the selected symbol
|
||||
*/
|
||||
PICKED_SYMBOL PickSymbolFromLibTree( const SYMBOL_LIBRARY_FILTER* aFilter,
|
||||
PICKED_SYMBOL PickSymbolFromLibrary( const SYMBOL_LIBRARY_FILTER* aFilter,
|
||||
std::vector<PICKED_SYMBOL>& aHistoryList,
|
||||
bool aUseLibBrowser,
|
||||
int aUnit,
|
||||
int aConvert,
|
||||
bool aShowFootprints,
|
||||
const LIB_ID* aHighlight = nullptr,
|
||||
bool aShowFootprints, const LIB_ID* aHighlight = nullptr,
|
||||
bool aAllowFields = true );
|
||||
|
||||
/**
|
||||
@ -177,23 +170,6 @@ public:
|
||||
LIB_SYMBOL* GetLibSymbol( const LIB_ID& aLibId, bool aUseCacheLib = false,
|
||||
bool aShowErrorMsg = false );
|
||||
|
||||
/**
|
||||
* Call the library viewer to select symbol to import into schematic.
|
||||
* If the library viewer is currently running, it is closed and reopened in modal mode.
|
||||
*
|
||||
* @param aParent is the caller.
|
||||
* @param aFilter is a filter to pass the allowed library names
|
||||
* and/or some other filter.
|
||||
* @param aPreselectedLibId is the preselected symbol's #LIB_ID. Not valid if none selected.
|
||||
* @param aUnit is the preselected unit.
|
||||
* @param aConvert is the preselected deMorgan conversion.
|
||||
* @return the selected symbol.
|
||||
*/
|
||||
PICKED_SYMBOL PickSymbolFromLibBrowser( wxTopLevelWindow* aParent,
|
||||
const SYMBOL_LIBRARY_FILTER* aFilter,
|
||||
const LIB_ID& aPreselectedLibId,
|
||||
int aUnit, int aConvert );
|
||||
|
||||
/**
|
||||
* Display a list of loaded libraries and allows the user to select a library.
|
||||
*
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <project/net_settings.h>
|
||||
#include <python_scripting.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <symbol_chooser_frame.h>
|
||||
#include <sch_painter.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_marker.h>
|
||||
@ -903,9 +904,11 @@ bool SCH_EDIT_FRAME::canCloseWindow( wxCloseEvent& aEvent )
|
||||
if( symbolViewer && !symbolViewer->Close() ) // Can close symbol viewer?
|
||||
return false;
|
||||
|
||||
symbolViewer = (SYMBOL_VIEWER_FRAME*) Kiway().Player( FRAME_SCH_VIEWER_MODAL, false );
|
||||
// SYMBOL_CHOOSER_FRAME is always modal so this shouldn't come up, but better safe than
|
||||
// sorry.
|
||||
auto* chooser = (SYMBOL_CHOOSER_FRAME*) Kiway().Player( FRAME_SYMBOL_CHOOSER, false );
|
||||
|
||||
if( symbolViewer && !symbolViewer->Close() ) // Can close modal symbol viewer?
|
||||
if( chooser && !chooser->Close() ) // Can close symbol chooser?
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
174
eeschema/symbol_chooser_frame.cpp
Normal file
174
eeschema/symbol_chooser_frame.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <pgm_base.h>
|
||||
#include <kiplatform/ui.h>
|
||||
#include <wx/button.h>
|
||||
#include <sch_base_frame.h>
|
||||
#include <eeschema_settings.h>
|
||||
#include <widgets/panel_symbol_chooser.h>
|
||||
#include <symbol_chooser_frame.h>
|
||||
|
||||
|
||||
static std::vector<PICKED_SYMBOL> s_SymbolHistoryList;
|
||||
static unsigned s_SymbolHistoryMaxCount = 8;
|
||||
|
||||
static void AddSymbolToHistory( const PICKED_SYMBOL& aSymbol )
|
||||
{
|
||||
// Remove duplicates
|
||||
alg::delete_if( s_SymbolHistoryList,
|
||||
[&]( const PICKED_SYMBOL& candidate ) -> bool
|
||||
{
|
||||
return candidate.LibId == aSymbol.LibId
|
||||
&& candidate.Unit == aSymbol.Unit
|
||||
&& candidate.Convert == aSymbol.Convert;
|
||||
} );
|
||||
|
||||
// Add the new name at the beginning of the history list
|
||||
s_SymbolHistoryList.insert( s_SymbolHistoryList.begin(), aSymbol );
|
||||
|
||||
// Remove extra names
|
||||
while( s_SymbolHistoryList.size() > s_SymbolHistoryMaxCount )
|
||||
s_SymbolHistoryList.resize( s_SymbolHistoryMaxCount );
|
||||
}
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( SYMBOL_CHOOSER_FRAME, SCH_BASE_FRAME )
|
||||
// Menu (and/or hotkey) events
|
||||
EVT_MENU( wxID_CLOSE, SYMBOL_CHOOSER_FRAME::CloseSymbolChooser )
|
||||
EVT_BUTTON( wxID_OK, SYMBOL_CHOOSER_FRAME::OnOK )
|
||||
EVT_BUTTON( wxID_CANCEL, SYMBOL_CHOOSER_FRAME::CloseSymbolChooser )
|
||||
EVT_PAINT( SYMBOL_CHOOSER_FRAME::OnPaint )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
#define PARENT_STYLE ( wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | wxCLIP_CHILDREN \
|
||||
| wxWANTS_CHARS | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT )
|
||||
|
||||
SYMBOL_CHOOSER_FRAME::SYMBOL_CHOOSER_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
SCH_BASE_FRAME( aKiway, aParent, FRAME_SYMBOL_CHOOSER, _( "Symbol Chooser" ),
|
||||
wxDefaultPosition, wxDefaultSize, PARENT_STYLE, SYMBOL_CHOOSER_FRAME_NAME )
|
||||
{
|
||||
SetModal( true );
|
||||
|
||||
wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
|
||||
m_chooserPanel = new PANEL_SYMBOL_CHOOSER( this, this, nullptr /* no filter */,
|
||||
s_SymbolHistoryList, false, false,
|
||||
[this]()
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
OnOK( dummy );
|
||||
} );
|
||||
|
||||
sizer->Add( m_chooserPanel, 1, wxEXPAND, 5 );
|
||||
|
||||
wxStdDialogButtonSizer* sdbSizer = new wxStdDialogButtonSizer();
|
||||
wxButton* okButton = new wxButton( this, wxID_OK );
|
||||
wxButton* cancelButton = new wxButton( this, wxID_CANCEL );
|
||||
sdbSizer->AddButton( okButton );
|
||||
sdbSizer->AddButton( cancelButton );
|
||||
sdbSizer->Realize();
|
||||
|
||||
sizer->Add( sdbSizer, 0, wxEXPAND | wxALL, 5 );
|
||||
SetSizer( sizer );
|
||||
|
||||
SetTitle( GetTitle() + wxString::Format( _( " (%d items loaded)" ),
|
||||
m_chooserPanel->GetItemCount() ) );
|
||||
|
||||
Layout();
|
||||
m_chooserPanel->FinishSetup();
|
||||
}
|
||||
|
||||
|
||||
bool SYMBOL_CHOOSER_FRAME::ShowModal( wxString* aSymbol, wxWindow* aParent )
|
||||
{
|
||||
if( aSymbol && !aSymbol->IsEmpty() )
|
||||
{
|
||||
LIB_ID libid;
|
||||
|
||||
libid.Parse( *aSymbol, true );
|
||||
|
||||
if( libid.IsValid() )
|
||||
m_chooserPanel->SetPreselect( libid );
|
||||
}
|
||||
|
||||
return KIWAY_PLAYER::ShowModal( aSymbol, aParent );
|
||||
}
|
||||
|
||||
|
||||
void SYMBOL_CHOOSER_FRAME::doCloseWindow()
|
||||
{
|
||||
// Only dismiss a modal frame once, so that the return values set by
|
||||
// the prior DismissModal() are not bashed for ShowModal().
|
||||
if( !IsDismissed() )
|
||||
DismissModal( false );
|
||||
|
||||
// window to be destroyed by the caller of KIWAY_PLAYER::ShowModal()
|
||||
}
|
||||
|
||||
|
||||
void SYMBOL_CHOOSER_FRAME::OnPaint( wxPaintEvent& aEvent )
|
||||
{
|
||||
if( m_firstPaintEvent )
|
||||
{
|
||||
KIPLATFORM::UI::FixupCancelButtonCmdKeyCollision( this );
|
||||
KIPLATFORM::UI::ForceFocus( m_chooserPanel->GetFocusTarget() );
|
||||
|
||||
m_firstPaintEvent = false;
|
||||
}
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void SYMBOL_CHOOSER_FRAME::OnOK( wxCommandEvent& aEvent )
|
||||
{
|
||||
LIB_ID libId = m_chooserPanel->GetSelectedLibId();
|
||||
|
||||
if( libId.IsValid() )
|
||||
{
|
||||
PICKED_SYMBOL symbol;
|
||||
symbol.LibId = libId;
|
||||
|
||||
AddSymbolToHistory( symbol );
|
||||
DismissModal( true, libId.Format() );
|
||||
}
|
||||
else
|
||||
{
|
||||
DismissModal( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WINDOW_SETTINGS* SYMBOL_CHOOSER_FRAME::GetWindowSettings( APP_SETTINGS_BASE* aCfg )
|
||||
{
|
||||
auto cfg = dynamic_cast<EESCHEMA_SETTINGS*>( aCfg );
|
||||
wxASSERT( cfg );
|
||||
return &cfg->m_LibViewPanel.window;
|
||||
}
|
||||
|
||||
|
||||
void SYMBOL_CHOOSER_FRAME::CloseSymbolChooser( wxCommandEvent& event )
|
||||
{
|
||||
Close( false );
|
||||
}
|
87
eeschema/symbol_chooser_frame.h
Normal file
87
eeschema/symbol_chooser_frame.h
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SYMBOL_CHOOSER_FRAME_H
|
||||
#define SYMBOL_CHOOSER_FRAME_H
|
||||
|
||||
#include <sch_base_frame.h>
|
||||
|
||||
class PANEL_SYMBOL_CHOOSER;
|
||||
|
||||
|
||||
/**
|
||||
* Symbol library viewer main window.
|
||||
*/
|
||||
class SYMBOL_CHOOSER_FRAME : public SCH_BASE_FRAME
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @param aKiway
|
||||
* @param aParent is the parent frame of the viewer.
|
||||
* @param aFrameType must be either #FRAME_SCH_LIB_VIEWER or #FRAME_SCH_LIB_VIEWER_MODAL.
|
||||
* @param aLibrary is the library to open when starting (default = NULL).
|
||||
*/
|
||||
SYMBOL_CHOOSER_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||
|
||||
~SYMBOL_CHOOSER_FRAME() {};
|
||||
|
||||
/**
|
||||
* Runs the symbol viewer as a modal dialog.
|
||||
*
|
||||
* @param aSymbol an optional FPID string to initialize the viewer with and to
|
||||
* return a selected footprint through.
|
||||
*/
|
||||
bool ShowModal( wxString* aSymbol, wxWindow* aParent ) override;
|
||||
|
||||
/**
|
||||
* Set a filter to display only libraries and/or symbols which match the filter.
|
||||
*
|
||||
* @param aFilter is a filter to pass the allowed library name list and/or some other filter
|
||||
* see SCH_BASE_FRAME::SelectSymbolFromLibrary() for details.
|
||||
* if aFilter == NULL, remove all filtering.
|
||||
*/
|
||||
void SetFilter( const SYMBOL_LIBRARY_FILTER* aFilter );
|
||||
|
||||
private:
|
||||
void OnPaint( wxPaintEvent& aEvent );
|
||||
void OnOK( wxCommandEvent& aEvent );
|
||||
|
||||
void doCloseWindow() override;
|
||||
void CloseSymbolChooser( wxCommandEvent& aEvent );
|
||||
|
||||
WINDOW_SETTINGS* GetWindowSettings( APP_SETTINGS_BASE* aCfg ) override;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
private:
|
||||
PANEL_SYMBOL_CHOOSER* m_chooserPanel;
|
||||
|
||||
// On MacOS (at least) SetFocus() calls made in the constructor will fail because a
|
||||
// window that isn't yet visible will return false to AcceptsFocus(). So we must delay
|
||||
// the initial-focus SetFocus() call to the first paint event.
|
||||
bool m_firstPaintEvent;
|
||||
};
|
||||
|
||||
#endif // SYMBOL_CHOOSER_FRAME_H
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <bitmaps.h>
|
||||
#include <symbol_library_common.h>
|
||||
#include <confirm.h>
|
||||
#include <dialog_choose_symbol.h>
|
||||
#include <dialogs/html_message_box.h>
|
||||
#include <eeschema_id.h>
|
||||
#include <eeschema_settings.h>
|
||||
@ -81,7 +80,6 @@ BEGIN_EVENT_TABLE( SYMBOL_VIEWER_FRAME, SCH_BASE_FRAME )
|
||||
EVT_ACTIVATE( SYMBOL_VIEWER_FRAME::OnActivate )
|
||||
|
||||
// Toolbar events
|
||||
EVT_TOOL( ID_LIBVIEW_SELECT_PART, SYMBOL_VIEWER_FRAME::OnSelectSymbol )
|
||||
EVT_TOOL( ID_LIBVIEW_NEXT, SYMBOL_VIEWER_FRAME::onSelectNextSymbol )
|
||||
EVT_TOOL( ID_LIBVIEW_PREVIOUS, SYMBOL_VIEWER_FRAME::onSelectPreviousSymbol )
|
||||
EVT_CHOICE( ID_LIBVIEW_SELECT_UNIT_NUMBER, SYMBOL_VIEWER_FRAME::onSelectSymbolUnit )
|
||||
@ -101,34 +99,20 @@ BEGIN_EVENT_TABLE( SYMBOL_VIEWER_FRAME, SCH_BASE_FRAME )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
#define LIB_VIEW_NAME "ViewlibFrame"
|
||||
#define LIB_VIEW_NAME_MODAL "ViewlibFrameModal"
|
||||
|
||||
#define LIB_VIEW_STYLE ( KICAD_DEFAULT_DRAWFRAME_STYLE )
|
||||
#define LIB_VIEW_STYLE_MODAL ( KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT )
|
||||
|
||||
|
||||
SYMBOL_VIEWER_FRAME::SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
|
||||
const wxString& aLibraryName ) :
|
||||
SCH_BASE_FRAME( aKiway, aParent, aFrameType, _( "Symbol Library Browser" ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
aFrameType == FRAME_SCH_VIEWER_MODAL ? LIB_VIEW_STYLE_MODAL : LIB_VIEW_STYLE,
|
||||
aFrameType == FRAME_SCH_VIEWER_MODAL ? LIB_VIEW_NAME_MODAL : LIB_VIEW_NAME ),
|
||||
SYMBOL_VIEWER_FRAME::SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH_VIEWER, _( "Symbol Library Browser" ),
|
||||
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
|
||||
LIB_VIEW_FRAME_NAME ),
|
||||
m_unitChoice( nullptr ),
|
||||
m_libList( nullptr ),
|
||||
m_symbolList( nullptr )
|
||||
{
|
||||
wxASSERT( aFrameType == FRAME_SCH_VIEWER || aFrameType == FRAME_SCH_VIEWER_MODAL );
|
||||
|
||||
if( aFrameType == FRAME_SCH_VIEWER_MODAL )
|
||||
SetModal( true );
|
||||
|
||||
m_aboutTitle = _HKI( "KiCad Symbol Library Viewer" );
|
||||
m_aboutTitle = _HKI( "KiCad Symbol Library Browser" );
|
||||
|
||||
// Force the frame name used in config. the lib viewer frame has a name
|
||||
// depending on aFrameType (needed to identify the frame by wxWidgets),
|
||||
// but only one configuration is preferable.
|
||||
m_configName = LIB_VIEW_NAME;
|
||||
m_configName = LIB_VIEW_FRAME_NAME;
|
||||
|
||||
// Give an icon
|
||||
wxIcon icon;
|
||||
@ -204,18 +188,7 @@ SYMBOL_VIEWER_FRAME::SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAM
|
||||
|
||||
// Preload libraries
|
||||
loadAllLibraries();
|
||||
|
||||
if( aLibraryName.empty() )
|
||||
{
|
||||
ReCreateLibList();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentSymbol.SetLibNickname( aLibraryName );
|
||||
m_currentSymbol.SetLibItemName( "" );
|
||||
m_unit = 1;
|
||||
m_convert = 1;
|
||||
}
|
||||
ReCreateLibList();
|
||||
|
||||
m_selection_changed = false;
|
||||
|
||||
@ -236,8 +209,6 @@ SYMBOL_VIEWER_FRAME::SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAM
|
||||
|
||||
m_auimgr.AddPane( GetCanvas(), EDA_PANE().Canvas().Name( "DrawFrame" ).Center() );
|
||||
|
||||
m_auimgr.GetPane( libPanel ).Show( aLibraryName.empty() );
|
||||
|
||||
m_auimgr.Update();
|
||||
|
||||
if( m_libListWidth > 0 )
|
||||
@ -1072,59 +1043,6 @@ void SYMBOL_VIEWER_FRAME::FinishModal()
|
||||
}
|
||||
|
||||
|
||||
void SYMBOL_VIEWER_FRAME::OnSelectSymbol( wxCommandEvent& aEvent )
|
||||
{
|
||||
std::unique_lock<std::mutex> dialogLock( DIALOG_CHOOSE_SYMBOL::g_Mutex, std::defer_lock );
|
||||
|
||||
// One CHOOSE_SYMBOL dialog at a time. User probably can't handle more anyway.
|
||||
if( !dialogLock.try_lock() )
|
||||
return;
|
||||
|
||||
// Container doing search-as-you-type.
|
||||
SYMBOL_LIB_TABLE* libs = PROJECT_SCH::SchSymbolLibTable( &Prj() );
|
||||
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> dataPtr
|
||||
= SYMBOL_TREE_MODEL_ADAPTER::Create( this, libs );
|
||||
SYMBOL_TREE_MODEL_ADAPTER* modelAdapter
|
||||
= static_cast<SYMBOL_TREE_MODEL_ADAPTER*>( dataPtr.get() );
|
||||
|
||||
if( !modelAdapter->AddLibraries( libs->GetLogicalLibs(), this ) )
|
||||
{
|
||||
// loading cancelled by user
|
||||
return;
|
||||
}
|
||||
|
||||
LIB_SYMBOL* current = GetSelectedSymbol();
|
||||
LIB_ID id;
|
||||
int unit = 0;
|
||||
|
||||
if( current )
|
||||
{
|
||||
id = current->GetLibId();
|
||||
modelAdapter->SetPreselectNode( id, unit );
|
||||
}
|
||||
|
||||
wxString dialogTitle;
|
||||
dialogTitle.Printf( _( "Choose Symbol (%d items loaded)" ), modelAdapter->GetItemCount() );
|
||||
|
||||
DIALOG_CHOOSE_SYMBOL dlg( this, dialogTitle, dataPtr, m_convert, false, false, false );
|
||||
|
||||
if( dlg.ShowQuasiModal() == wxID_CANCEL )
|
||||
return;
|
||||
|
||||
// Save any changes to column widths, etc.
|
||||
modelAdapter->SaveSettings();
|
||||
|
||||
id = dlg.GetSelectedLibId( &unit );
|
||||
|
||||
if( !id.IsValid() )
|
||||
return;
|
||||
|
||||
SetSelectedLibrary( id.GetLibNickname(), id.GetSubLibraryName() );
|
||||
SetSelectedSymbol( id.GetLibItemName() );
|
||||
SetUnitAndConvert( unit, 1 );
|
||||
}
|
||||
|
||||
|
||||
void SYMBOL_VIEWER_FRAME::OnLibFilter( wxCommandEvent& aEvent )
|
||||
{
|
||||
ReCreateLibList();
|
||||
|
@ -51,8 +51,7 @@ public:
|
||||
* @param aFrameType must be either #FRAME_SCH_LIB_VIEWER or #FRAME_SCH_LIB_VIEWER_MODAL.
|
||||
* @param aLibrary is the library to open when starting (default = NULL).
|
||||
*/
|
||||
SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
|
||||
const wxString& aLibraryName = wxEmptyString );
|
||||
SYMBOL_VIEWER_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||
|
||||
~SYMBOL_VIEWER_FRAME();
|
||||
|
||||
@ -95,7 +94,6 @@ public:
|
||||
|
||||
void ClickOnLibList( wxCommandEvent& event );
|
||||
void ClickOnSymbolList( wxCommandEvent& event );
|
||||
void OnSelectSymbol( wxCommandEvent& aEvent );
|
||||
|
||||
void LoadSettings( APP_SETTINGS_BASE* aCfg ) override;
|
||||
void SaveSettings( APP_SETTINGS_BASE* aCfg ) override;
|
||||
|
@ -46,10 +46,6 @@ void SYMBOL_VIEWER_FRAME::ReCreateHToolbar()
|
||||
m_mainToolBar->SetAuiManager( &m_auimgr );
|
||||
}
|
||||
|
||||
m_mainToolBar->AddTool( ID_LIBVIEW_SELECT_PART, wxEmptyString,
|
||||
KiScaledBitmap( BITMAPS::library_browser, this ),
|
||||
_( "Choose symbol" ) );
|
||||
|
||||
m_mainToolBar->AddTool( ID_LIBVIEW_PREVIOUS, wxEmptyString,
|
||||
KiScaledBitmap( BITMAPS::lib_previous, this ),
|
||||
_( "Display previous symbol" ) );
|
||||
|
@ -404,7 +404,7 @@ int EE_INSPECTION_TOOL::ShowDatasheet( const TOOL_EVENT& aEvent )
|
||||
|
||||
datasheet = symbol->GetDatasheetField().GetText();
|
||||
}
|
||||
else if( m_frame->IsType( FRAME_SCH_VIEWER ) || m_frame->IsType( FRAME_SCH_VIEWER_MODAL ) )
|
||||
else if( m_frame->IsType( FRAME_SCH_VIEWER ) )
|
||||
{
|
||||
LIB_SYMBOL* entry = static_cast<SYMBOL_VIEWER_FRAME*>( m_frame )->GetSelectedSymbol();
|
||||
|
||||
|
@ -305,8 +305,8 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
||||
|
||||
// Pick the symbol to be placed
|
||||
bool footprintPreviews = m_frame->eeconfig()->m_Appearance.footprint_preview;
|
||||
PICKED_SYMBOL sel = m_frame->PickSymbolFromLibTree( &filter, *historyList, true,
|
||||
1, 1, footprintPreviews );
|
||||
PICKED_SYMBOL sel = m_frame->PickSymbolFromLibrary( &filter, *historyList,
|
||||
footprintPreviews );
|
||||
|
||||
LIB_SYMBOL* libSymbol = sel.LibId.IsValid() ? m_frame->GetLibSymbol( sel.LibId )
|
||||
: nullptr;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user