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 (C) 2018-2024 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 along
17 * with this program. If not, see <http://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>
28#include <string_utils.h>
29#include <eda_pattern_match.h>
30#include <design_block.h>
32#include <design_block_info.h>
35
36wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>
38{
39 auto* adapter = new DESIGN_BLOCK_TREE_MODEL_ADAPTER( aParent, aLibs );
40 adapter->m_frame = aParent;
41 return wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>( adapter );
42}
43
44
46 LIB_TABLE* aLibs ) :
47 LIB_TREE_MODEL_ADAPTER( aParent, wxT( "pinned_design_block_libs" ),
48 Kiface().KifaceSettings() ),
49 m_libs( (DESIGN_BLOCK_LIB_TABLE*) aLibs )
50{
51}
52
53
55{
57 PROJECT_FILE& project = aParent->Prj().GetProjectFile();
58
59 for( const wxString& libName : m_libs->GetLogicalLibs() )
60 {
61 const DESIGN_BLOCK_LIB_TABLE_ROW* library = nullptr;
62
63 try
64 {
65 library = m_libs->FindRow( libName, true );
66 }
67 catch( ... )
68 {
69 // Skip loading this library, if not exists/ not found
70 continue;
71 }
72 bool pinned = alg::contains( cfg->m_Session.pinned_design_block_libs, libName )
73 || alg::contains( project.m_PinnedDesignBlockLibs, libName );
74
75 DoAddLibrary( libName, library->GetDescr(), getDesignBlocks( aParent, libName ), pinned,
76 true );
77 }
78
80}
81
82
84{
85 m_tree.Clear();
86}
87
88
89std::vector<LIB_TREE_ITEM*>
91 const wxString& aLibName )
92{
93 std::vector<LIB_TREE_ITEM*> libList;
94
95 auto fullListStart = DESIGN_BLOCK_LIB_TABLE::GetGlobalList().GetList().begin();
96 auto fullListEnd = DESIGN_BLOCK_LIB_TABLE::GetGlobalList().GetList().end();
97
98 std::unique_ptr<DESIGN_BLOCK_INFO> dummy =
99 std::make_unique<DESIGN_BLOCK_INFO_IMPL>( aLibName, wxEmptyString );
100
101 // List is sorted, so use a binary search to find the range of footnotes for our library
102 auto libBounds = std::equal_range(
103 fullListStart, fullListEnd, dummy,
104 []( const std::unique_ptr<DESIGN_BLOCK_INFO>& a,
105 const std::unique_ptr<DESIGN_BLOCK_INFO>& b )
106 {
107 return StrNumCmp( a->GetLibNickname(), b->GetLibNickname(), false ) < 0;
108 } );
109
110 for( auto i = libBounds.first; i != libBounds.second; ++i )
111 libList.push_back( i->get() );
112
113 return libList;
114}
115
116
117wxString DESIGN_BLOCK_TREE_MODEL_ADAPTER::GenerateInfo( LIB_ID const& aLibId, int aUnit )
118{
119 const wxString DescriptionFormat = wxT(
120 "<b>__NAME__</b>"
121 "<br>__DESC__"
122 "<hr><table border=0>"
123 "__FIELDS__"
124 "</table>" );
125
126 const wxString KeywordsFormat = wxT(
127 "<tr>"
128 " <td><b>" + _( "Keywords" ) + "</b></td>"
129 " <td>__KEYWORDS__</td>"
130 "</tr>" );
131
132 const wxString DocFormat = wxT(
133 "<tr>"
134 " <td><b>" + _( "Documentation" ) + "</b></td>"
135 " <td><a href=\"__HREF__\">__TEXT__</a></td>"
136 "</tr>" );
137
138
139 if( !aLibId.IsValid() )
140 return wxEmptyString;
141
142 const DESIGN_BLOCK* db = nullptr;
143
144 try
145 {
147 }
148 catch( const IO_ERROR& ioe )
149 {
150 wxLogError( _( "Error loading design block %s from library '%s'." ) + wxS( "\n%s" ),
151 aLibId.GetLibItemName().wx_str(), aLibId.GetLibNickname().wx_str(),
152 ioe.What() );
153
154 return wxEmptyString;
155 }
156
157 wxString html = DescriptionFormat;
158
159 if( db )
160 {
161 wxString name = aLibId.GetLibItemName();
162 wxString desc = db->GetLibDescription();
163 wxString keywords = db->GetKeywords();
164 wxString doc;
165
166 // It is currently common practice to store a documentation link in the description.
167 size_t idx = desc.find( wxT( "http:" ) );
168
169 if( idx == wxString::npos )
170 idx = desc.find( wxT( "https:" ) );
171
172 if( idx != wxString::npos )
173 {
174 int nesting = 0;
175
176 for( auto chit = desc.begin() + idx; chit != desc.end(); ++chit )
177 {
178 int ch = *chit;
179
180 // Break on invalid URI characters
181 if( ch <= 0x20 || ch >= 0x7F || ch == '"' )
182 break;
183
184 // Check for nesting parentheses, e.g. (Body style from: https://this.url/part.pdf)
185 if( ch == '(' )
186 ++nesting;
187 else if( ch == ')' && --nesting < 0 )
188 break;
189
190 doc += ch;
191 }
192
193 // Trim trailing punctuation
194 static wxString punct = wxS( ".,:;" );
195
196 if( punct.find( doc.Last() ) != wxString::npos )
197 doc = doc.Left( doc.Length() - 1 );
198 }
199
200 wxString esc_desc = EscapeHTML( UnescapeString( desc ) );
201
202 // Add line breaks
203 esc_desc.Replace( wxS( "\n" ), wxS( "<br>" ) );
204
205 // Add links
206 esc_desc = LinkifyHTML( esc_desc );
207
208 html.Replace( "__DESC__", esc_desc );
209 html.Replace( "__NAME__", EscapeHTML( name ) );
210
211 wxString keywordsHtml = KeywordsFormat;
212 keywordsHtml.Replace( "__KEYWORDS__", EscapeHTML( keywords ) );
213
214 wxString docHtml = DocFormat;
215 docHtml.Replace( "__HREF__", doc );
216
217 if( doc.Length() > 75 )
218 doc = doc.Left( 72 ) + wxT( "..." );
219
220 docHtml.Replace( "__TEXT__", EscapeHTML( doc ) );
221
222 html.Replace( "__FIELDS__", keywordsHtml + docHtml );
223 }
224
225 return html;
226}
227
228
230{
232}
const char * name
Definition: DXF_plotter.cpp:57
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
Hold a record identifying a library accessed by the appropriate design block library #PLUGIN object i...
const DESIGN_BLOCK * GetEnumeratedDesignBlock(const wxString &aNickname, const wxString &aDesignBlockName)
A version of DesignBlockLoad() for use after DesignBlockEnumerate() for more efficient cache manageme...
static DESIGN_BLOCK_LIST_IMPL & GetGlobalList()
const DESIGN_BLOCK_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an DESIGN_BLOCK_LIB_TABLE_ROW if aNickName is found in this table or in any chained fall back ...
const DBILIST & GetList() const
Was forced to add this by modview_frame.cpp.
std::vector< LIB_TREE_ITEM * > getDesignBlocks(EDA_BASE_FRAME *aParent, const wxString &aLibName)
static wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > Create(EDA_BASE_FRAME *aParent, LIB_TABLE *aLibs)
Factory function: create a model adapter in a reference-counting container.
wxString GenerateInfo(LIB_ID const &aLibId, int aUnit) override
TOOL_INTERACTIVE * GetContextMenuTool() override
DESIGN_BLOCK_TREE_MODEL_ADAPTER(EDA_BASE_FRAME *aParent, LIB_TABLE *aLibs)
Constructor; takes a set of libraries to be included in the search.
const wxString & GetKeywords() const
Definition: design_block.h:38
const wxString & GetLibDescription() const
Definition: design_block.h:35
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.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
bool IsValid() const
Check if this LID_ID is valid.
Definition: lib_id.h:172
const UTF8 & GetLibItemName() const
Definition: lib_id.h:102
const UTF8 & GetLibNickname() const
Return the logical library name portion of a LIB_ID.
Definition: lib_id.h:87
Manage LIB_TABLE_ROW records (rows), and can be searched based on library nickname.
std::vector< wxString > GetLogicalLibs()
Return the logical library names, all of them that are pertinent to a look up done on this LIB_TABLE.
void 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.
void Clear()
Clear the tree.
void AssignIntrinsicRanks(bool presorted=false)
Store intrinsic ranks on all children of this node.
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:679
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:72
virtual PROJECT_FILE & GetProjectFile() const
Definition: project.h:200
Handle schematic design block actions in the schematic editor.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
wxString wx_str() const
Definition: utf8.cpp:45
#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 DocFormat
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
std::vector< FAB_LAYER_COLOR > dummy
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
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