1 /*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
5 * Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <generate_alias_info.h>
22 #include <string_utils.h>
23 #include <template_fieldnames.h>
24 #include <lib_symbol.h>
25 #include <symbol_lib_table.h>
26 #include <wx/log.h>
27
28 static const wxString DescriptionFormat =
29 "<b>__NAME__</b>"
30 "__ALIASOF__"
31 "__DESC__"
32 "__KEY__"
33 "<hr><table border=0>"
34 "__FIELDS__"
35 "</table>";
36
37 static const wxString AliasOfFormat = "<br><i>" + _( "Alias of" ) + " %s (%s)</i>";
38 static const wxString DescFormat = "<br>%s";
39 static const wxString KeywordsFormat = "<br>" + _( "Keywords" ) + ": %s";
40 static const wxString FieldFormat =
41 "<tr>"
42 " <td><b>__NAME__</b></td>"
43 " <td>__VALUE__</td>"
44 "</tr>";
45 static const wxString DatasheetLinkFormat = "<a href=\"__HREF__\">__TEXT__</a>";
46
47
48 class FOOTPRINT_INFO_GENERATOR
49 {
50 wxString m_html;
51 SYMBOL_LIB_TABLE* m_sym_lib_table;
52 LIB_ID const m_lib_id;
53 LIB_SYMBOL* m_symbol;
54 int m_unit;
55
56 public:
FOOTPRINT_INFO_GENERATOR(SYMBOL_LIB_TABLE * aSymbolLibTable,LIB_ID const & aLibId,int aUnit)57 FOOTPRINT_INFO_GENERATOR( SYMBOL_LIB_TABLE* aSymbolLibTable, LIB_ID const& aLibId, int aUnit )
58 : m_html( DescriptionFormat ),
59 m_sym_lib_table( aSymbolLibTable ),
60 m_lib_id( aLibId ),
61 m_symbol( nullptr ),
62 m_unit( aUnit )
63 { }
64
65 /**
66 * Generate the HTML internally.
67 */
GenerateHtml()68 void GenerateHtml()
69 {
70 wxCHECK_RET( m_sym_lib_table, "Symbol library table pointer is not valid" );
71
72 if( !m_lib_id.IsValid() )
73 return;
74
75 try
76 {
77 m_symbol = m_sym_lib_table->LoadSymbol( m_lib_id );
78 }
79 catch( const IO_ERROR& ioe )
80 {
81 wxLogError( _( "Error loading symbol %s from library '%s'." ) + wxS( "\n%s" ),
82 m_lib_id.GetLibItemName().wx_str(),
83 m_lib_id.GetLibNickname().wx_str(),
84 ioe.What() );
85 return;
86 }
87
88 if( m_symbol )
89 {
90 SetHtmlName();
91 SetHtmlAliasOf();
92 SetHtmlDesc();
93 SetHtmlKeywords();
94 SetHtmlFieldTable();
95 }
96 }
97
98 /**
99 * Return the generated HTML.
100 */
GetHtml() const101 wxString GetHtml() const
102 {
103 return m_html;
104 }
105
106 protected:
SetHtmlName()107 void SetHtmlName()
108 {
109 m_html.Replace( "__NAME__", EscapeHTML( UnescapeString( m_symbol->GetName() ) ) );
110 }
111
112
SetHtmlAliasOf()113 void SetHtmlAliasOf()
114 {
115 if( m_symbol->IsRoot() )
116 {
117 m_html.Replace( "__ALIASOF__", wxEmptyString );
118 }
119 else
120 {
121 wxString root_name = _( "Unknown" );
122 wxString root_desc = "";
123
124 std::shared_ptr< LIB_SYMBOL > parent = m_symbol->GetParent().lock();
125
126 if( parent )
127 {
128 root_name = parent->GetName();
129 root_desc = parent->GetDescription();
130 }
131
132 m_html.Replace( "__ALIASOF__", wxString::Format( AliasOfFormat,
133 EscapeHTML( UnescapeString( root_name ) ),
134 EscapeHTML( root_desc ) ) );
135 }
136 }
137
138
SetHtmlDesc()139 void SetHtmlDesc()
140 {
141 wxString raw_desc = m_symbol->GetDescription();
142
143 m_html.Replace( "__DESC__", wxString::Format( DescFormat, EscapeHTML( raw_desc ) ) );
144 }
145
146
SetHtmlKeywords()147 void SetHtmlKeywords()
148 {
149 wxString keywords = m_symbol->GetKeyWords();
150
151 if( keywords.empty() )
152 m_html.Replace( "__KEY__", wxEmptyString );
153 else
154 m_html.Replace( "__KEY__", wxString::Format( KeywordsFormat, EscapeHTML( keywords ) ) );
155 }
156
157
GetHtmlFieldRow(const LIB_FIELD & aField) const158 wxString GetHtmlFieldRow( const LIB_FIELD& aField ) const
159 {
160 wxString name = aField.GetCanonicalName();
161 wxString text = aField.GetFullText( m_unit > 0 ? m_unit : 1 );
162 wxString fieldhtml = FieldFormat;
163
164 fieldhtml.Replace( "__NAME__", EscapeHTML( name ) );
165
166 switch( aField.GetId() )
167 {
168 case DATASHEET_FIELD:
169 text = m_symbol->GetDatasheetField().GetText();
170
171 if( text.IsEmpty() || text == wxT( "~" ) )
172 {
173 fieldhtml.Replace( "__VALUE__", text );
174 }
175 else
176 {
177 wxString datasheetlink = DatasheetLinkFormat;
178 datasheetlink.Replace( "__HREF__", EscapeHTML( text ) );
179
180 if( text.Length() > 75 )
181 text = text.Left( 72 ) + wxT( "..." );
182
183 datasheetlink.Replace( "__TEXT__", EscapeHTML( text ) );
184
185 fieldhtml.Replace( "__VALUE__", datasheetlink );
186 }
187
188 break;
189
190 case VALUE_FIELD:
191 // showing the value just repeats the name, so that's not much use...
192 return wxEmptyString;
193
194 default:
195 fieldhtml.Replace( "__VALUE__", EscapeHTML( text ) );
196 }
197
198 return fieldhtml;
199 }
200
201
SetHtmlFieldTable()202 void SetHtmlFieldTable()
203 {
204 wxString fieldtable;
205 std::vector<LIB_FIELD*> fields;
206
207 m_symbol->GetFields( fields );
208
209 for( const LIB_FIELD* field: fields )
210 fieldtable += GetHtmlFieldRow( *field );
211
212 if( m_symbol->IsAlias() )
213 {
214 std::shared_ptr<LIB_SYMBOL> parent = m_symbol->GetParent().lock();
215
216 // Append all of the unique parent fields if this is an alias.
217 if( parent )
218 {
219 std::vector<LIB_FIELD*> parentFields;
220
221 parent->GetFields( parentFields );
222
223 for( const LIB_FIELD* parentField : parentFields )
224 {
225 if( m_symbol->FindField( parentField->GetCanonicalName() ) )
226 continue;
227
228 fieldtable += GetHtmlFieldRow( *parentField );
229 }
230 }
231 }
232
233 m_html.Replace( "__FIELDS__", fieldtable );
234 }
235 };
236
237
GenerateAliasInfo(SYMBOL_LIB_TABLE * aSymLibTable,LIB_ID const & aLibId,int aUnit)238 wxString GenerateAliasInfo( SYMBOL_LIB_TABLE* aSymLibTable, LIB_ID const& aLibId, int aUnit )
239 {
240 FOOTPRINT_INFO_GENERATOR gen( aSymLibTable, aLibId, aUnit );
241 gen.GenerateHtml();
242 return gen.GetHtml();
243 }
244