KiCad PCB EDA Suite
Loading...
Searching...
No Matches
design_block_tree_model_adapter.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <pgm_base.h>
21#include <kiface_base.h>
22#include <eda_base_frame.h>
23#include <core/kicad_algo.h>
26#include <wx/log.h>
27#include <wx/tokenzr.h>
29#include <string_utils.h>
30#include <eda_pattern_match.h>
31#include <design_block.h>
34#include <kiplatform/ui.h>
35
36wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>
38 APP_SETTINGS_BASE::LIB_TREE& aSettings, TOOL_INTERACTIVE* aContextMenuTool )
39{
40 auto* adapter = new DESIGN_BLOCK_TREE_MODEL_ADAPTER( aParent, aLibs, aSettings, aContextMenuTool );
41 return wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>( adapter );
42}
43
44
48 TOOL_INTERACTIVE* aContextMenuTool ) :
49 LIB_TREE_MODEL_ADAPTER( aParent, wxT( "pinned_design_block_libs" ),
50 Kiface().KifaceSettings()->m_DesignBlockChooserPanel.tree ),
51 m_libs( aLibs ),
52 m_frame( aParent ),
53 m_contextMenuTool( aContextMenuTool )
54{
55}
56
57
59{
61 PROJECT_FILE& project = aParent->Prj().GetProjectFile();
63
64 for( const LIBRARY_TABLE_ROW* row : manager.Rows( LIBRARY_TABLE_TYPE::DESIGN_BLOCK ) )
65 {
66 if( row->Hidden() )
67 continue;
68
69 wxString libName = row->Nickname();
70
71 bool pinned = alg::contains( cfg->m_Session.pinned_design_block_libs, libName )
72 || alg::contains( project.m_PinnedDesignBlockLibs, libName );
73
74 DoAddLibrary( libName, row->Description(), getDesignBlocks( aParent, libName ), pinned, true );
75 }
76
77 m_tree.AssignIntrinsicRanks( m_shownColumns );
78}
79
80
82{
83 // A queued GtkTreeView scroll target holds a row reference into the nodes we are about to
84 // free. Unlike UpdateSearchString's reset, this teardown happens out-of-band, so the later
85 // CancelPendingScroll would flush the reference against freed memory. Drop it here while the
86 // rows it points at are still valid (#24757).
88
89 m_tree.Clear();
90}
91
92
94 const wxString& aLibName )
95{
96 std::vector<LIB_TREE_ITEM*> libList;
97
98 DESIGN_BLOCK_LIBRARY_ADAPTER* libs = m_frame->Prj().DesignBlockLibs();
99
100 std::vector<DESIGN_BLOCK*> blocks = libs->GetDesignBlocks( aLibName );
101
102 for( DESIGN_BLOCK* block : blocks )
103 {
104 LIB_ID id = block->GetLIB_ID();
105 id.SetLibNickname( aLibName );
106 block->SetLibId( id );
107 libList.emplace_back( block );
108 }
109
110 return libList;
111}
112
113
114wxString DESIGN_BLOCK_TREE_MODEL_ADAPTER::GenerateInfo( LIB_ID const& aLibId, int aUnit )
115{
116 static const wxString DescriptionFormat = wxT(
117 "<b>__NAME__</b>"
118 "__DESC__"
119 "__KEY__"
120 "<hr><table border=0>"
121 "__FIELDS__"
122 "</table>" );
123
124 static const wxString DescFormat = wxS( "<br>%s" );
125 static const wxString KeywordsFormat = wxS( "<br>" ) + _( "Keywords" ) + wxS( ": %s" );
126
127 static const wxString FieldFormat = wxT(
128 "<tr>"
129 " <td><b>__FIELD_NAME__</b></td>"
130 " <td>__FIELD_VALUE__</td>"
131 "</tr>" );
132
133
134 if( !aLibId.IsValid() )
135 return wxEmptyString;
136
137 const DESIGN_BLOCK* db = nullptr;
138
139 try
140 {
141 db = m_libs->GetEnumeratedDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName() );
142 }
143 catch( const IO_ERROR& ioe )
144 {
145 wxLogError( _( "Error loading design block %s from library '%s'." ) + wxS( "\n%s" ),
146 aLibId.GetLibItemName().wx_str(), aLibId.GetLibNickname().wx_str(), ioe.What() );
147
148 return wxEmptyString;
149 }
150
151 wxString html = DescriptionFormat;
152
153 if( db )
154 {
155 wxString name = aLibId.GetLibItemName();
156 wxString desc = db->GetLibDescription();
157 wxString keywords = db->GetKeywords();
158
159 html.Replace( "__NAME__", EscapeHTML( name ) );
160
161 wxString esc_desc = EscapeHTML( UnescapeString( desc ) );
162
163 // Add line breaks
164 esc_desc.Replace( wxS( "\n" ), wxS( "<br>" ) );
165
166 // Add links
167 esc_desc = LinkifyHTML( esc_desc );
168
169 if( esc_desc.IsEmpty() )
170 html.Replace( "__DESC__", wxEmptyString );
171 else
172 html.Replace( "__DESC__", wxString::Format( DescFormat, esc_desc ) );
173
174 if( keywords.IsEmpty() )
175 html.Replace( "__KEY__", wxEmptyString );
176 else
177 html.Replace( "__KEY__", wxString::Format( KeywordsFormat, EscapeHTML( keywords ) ) );
178
179 wxString fieldTable;
180
181 for( const auto& [key, value] : db->GetFields() )
182 {
183 wxString fieldRow = FieldFormat;
184 fieldRow.Replace( wxS( "__FIELD_NAME__" ), EscapeHTML( key ) );
185 fieldRow.Replace( wxS( "__FIELD_VALUE__" ), EscapeHTML( value ) );
186 fieldTable += fieldRow;
187 }
188
189 html.Replace( "__FIELDS__", fieldTable );
190
191 // Design blocks (unlike symbols and footprints) are not cached. We own the pointer.
192 delete db;
193 }
194 else
195 {
196 html.Printf( _( "Error loading design block %s from library '%s'." ) + wxS( "\n" ),
197 aLibId.GetLibItemName().wx_str(), aLibId.GetLibNickname().wx_str() );
198 }
199
200 return html;
201}
202
203
const char * name
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
std::vector< DESIGN_BLOCK * > GetDesignBlocks(const wxString &aNickname)
std::vector< LIB_TREE_ITEM * > getDesignBlocks(EDA_BASE_FRAME *aParent, const wxString &aLibName)
wxString GenerateInfo(LIB_ID const &aLibId, int aUnit) override
static wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > Create(EDA_BASE_FRAME *aParent, DESIGN_BLOCK_LIBRARY_ADAPTER *aLibs, APP_SETTINGS_BASE::LIB_TREE &aSettings, TOOL_INTERACTIVE *aContextMenuTool)
Factory function: create a model adapter in a reference-counting container.
DESIGN_BLOCK_TREE_MODEL_ADAPTER(EDA_BASE_FRAME *aParent, DESIGN_BLOCK_LIBRARY_ADAPTER *aLibs, APP_SETTINGS_BASE::LIB_TREE &aSettings, TOOL_INTERACTIVE *aContextMenuTool)
Constructor; takes a set of libraries to be included in the search.
const wxString & GetKeywords() const
const wxString & GetLibDescription() const
const nlohmann::ordered_map< wxString, wxString > & GetFields() const
The base frame for deriving all KiCad main window classes.
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()
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
std::vector< LIBRARY_TABLE_ROW * > Rows(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH, bool aIncludeInvalid=false) const
Returns a flattened list of libraries of the given type.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
bool IsValid() const
Check if this LID_ID is valid.
Definition lib_id.h:168
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:113
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition lib_id.h:83
LIB_TREE_MODEL_ADAPTER(EDA_BASE_FRAME *aParent, const wxString &aPinnedKey, APP_SETTINGS_BASE::LIB_TREE &aSettingsStruct)
Create the adapter.
std::vector< wxString > m_shownColumns
LIB_TREE_NODE_LIBRARY & DoAddLibrary(const wxString &aNodeName, const wxString &aDesc, const std::vector< LIB_TREE_ITEM * > &aItemList, bool pinned, bool presorted)
Add the given list of symbols by alias.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition pgm_base.cpp:553
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:126
The backing store for a PROJECT, in JSON format.
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:200
wxString wx_str() const
Definition utf8.cpp:41
#define _(s)
Base window classes and related definitions.
Abstract pattern-matching tool and implementations.
static const wxString KeywordsFormat
static const wxString DescriptionFormat
static const wxString DescFormat
static const wxString FieldFormat
void CancelPendingScroll(wxDataViewCtrl *aCtrl)
Cancel any pending scroll-to-item request on aCtrl.
Definition wxgtk/ui.cpp:457
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition kicad_algo.h:96
PGM_BASE & Pgm()
The global program "get" accessor.
see class PGM_BASE
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
wxString UnescapeString(const wxString &aSource)
wxString LinkifyHTML(wxString aStr)
Wraps links in HTML tags.
std::vector< wxString > pinned_design_block_libs