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 // Design blocks come back in filesystem enumeration order, so they are not presorted;
75 // let AssignIntrinsicRanks() sort them by name.
76 DoAddLibrary( libName, row->Description(), getDesignBlocks( aParent, libName ), pinned, false );
77 }
78
79 m_tree.AssignIntrinsicRanks( m_shownColumns );
80}
81
82
84{
85 // A queued GtkTreeView scroll target holds a row reference into the nodes we are about to
86 // free. Unlike UpdateSearchString's reset, this teardown happens out-of-band, so the later
87 // CancelPendingScroll would flush the reference against freed memory. Drop it here while the
88 // rows it points at are still valid (#24757).
90
91 m_tree.Clear();
92}
93
94
96 const wxString& aLibName )
97{
98 std::vector<LIB_TREE_ITEM*> libList;
99
100 DESIGN_BLOCK_LIBRARY_ADAPTER* libs = m_frame->Prj().DesignBlockLibs();
101
102 std::vector<DESIGN_BLOCK*> blocks = libs->GetDesignBlocks( aLibName );
103
104 for( DESIGN_BLOCK* block : blocks )
105 {
106 LIB_ID id = block->GetLIB_ID();
107 id.SetLibNickname( aLibName );
108 block->SetLibId( id );
109 libList.emplace_back( block );
110 }
111
112 return libList;
113}
114
115
116wxString DESIGN_BLOCK_TREE_MODEL_ADAPTER::GenerateInfo( LIB_ID const& aLibId, int aUnit )
117{
118 static const wxString DescriptionFormat = wxT(
119 "<b>__NAME__</b>"
120 "__DESC__"
121 "__KEY__"
122 "<hr><table border=0>"
123 "__FIELDS__"
124 "</table>" );
125
126 static const wxString DescFormat = wxS( "<br>%s" );
127 static const wxString KeywordsFormat = wxS( "<br>" ) + _( "Keywords" ) + wxS( ": %s" );
128
129 static const wxString FieldFormat = wxT(
130 "<tr>"
131 " <td><b>__FIELD_NAME__</b></td>"
132 " <td>__FIELD_VALUE__</td>"
133 "</tr>" );
134
135
136 if( !aLibId.IsValid() )
137 return wxEmptyString;
138
139 const DESIGN_BLOCK* db = nullptr;
140
141 try
142 {
143 db = m_libs->GetEnumeratedDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName() );
144 }
145 catch( const IO_ERROR& ioe )
146 {
147 wxLogError( _( "Error loading design block %s from library '%s'." ) + wxS( "\n%s" ),
148 aLibId.GetLibItemName().wx_str(), aLibId.GetLibNickname().wx_str(), ioe.What() );
149
150 return wxEmptyString;
151 }
152
153 wxString html = DescriptionFormat;
154
155 if( db )
156 {
157 wxString name = aLibId.GetLibItemName();
158 wxString desc = db->GetLibDescription();
159 wxString keywords = db->GetKeywords();
160
161 html.Replace( "__NAME__", EscapeHTML( name ) );
162
163 wxString esc_desc = EscapeHTML( UnescapeString( desc ) );
164
165 // Add line breaks
166 esc_desc.Replace( wxS( "\n" ), wxS( "<br>" ) );
167
168 // Add links
169 esc_desc = LinkifyHTML( esc_desc );
170
171 if( esc_desc.IsEmpty() )
172 html.Replace( "__DESC__", wxEmptyString );
173 else
174 html.Replace( "__DESC__", wxString::Format( DescFormat, esc_desc ) );
175
176 if( keywords.IsEmpty() )
177 html.Replace( "__KEY__", wxEmptyString );
178 else
179 html.Replace( "__KEY__", wxString::Format( KeywordsFormat, EscapeHTML( keywords ) ) );
180
181 wxString fieldTable;
182
183 for( const auto& [key, value] : db->GetFields() )
184 {
185 wxString fieldRow = FieldFormat;
186 fieldRow.Replace( wxS( "__FIELD_NAME__" ), EscapeHTML( key ) );
187 fieldRow.Replace( wxS( "__FIELD_VALUE__" ), EscapeHTML( value ) );
188 fieldTable += fieldRow;
189 }
190
191 html.Replace( "__FIELDS__", fieldTable );
192
193 // Design blocks (unlike symbols and footprints) are not cached. We own the pointer.
194 delete db;
195 }
196 else
197 {
198 html.Printf( _( "Error loading design block %s from library '%s'." ) + wxS( "\n" ),
199 aLibId.GetLibItemName().wx_str(), aLibId.GetLibNickname().wx_str() );
200 }
201
202 return html;
203}
204
205
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:546
virtual LIBRARY_MANAGER & GetLibraryManager() const
Definition pgm_base.h:125
The backing store for a PROJECT, in JSON format.
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:201
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:530
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