KiCad PCB EDA Suite
symbol_library_manager.h
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) 2017 CERN
5  * Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Maciej Suminski <maciej.suminski@cern.ch>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 3
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * https://www.gnu.org/licenses/gpl-3.0.html
22  * or you may search the http://www.gnu.org website for the version 3 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #ifndef SYMBOL_LIBRARY_MANAGER_H
28 #define SYMBOL_LIBRARY_MANAGER_H
29 
30 #include <map>
31 #include <list>
32 #include <deque>
33 #include <set>
34 #include <memory>
35 #include <wx/arrstr.h>
37 #include <sch_io_mgr.h>
38 #include <sch_screen.h>
39 
40 class LIB_PART;
41 class PART_LIB;
42 class PROGRESS_REPORTER;
43 class SCH_PLUGIN;
44 class SYMBOL_EDIT_FRAME;
45 class SYMBOL_LIB_TABLE;
47 
48 
49 class LIB_LOGGER : public wxLogGui
50 {
51 public:
53  m_previousLogger( nullptr ),
54  m_activated( false )
55  { }
56 
57  ~LIB_LOGGER() override
58  {
59  Deactivate();
60  }
61 
62  void Activate()
63  {
64  if( !m_activated )
65  {
66  m_previousLogger = wxLog::GetActiveTarget();
67  wxLog::SetActiveTarget( this );
68  m_activated = true;
69  }
70  }
71 
72  void Deactivate()
73  {
74  if( m_activated )
75  {
76  Flush();
77  m_activated = false;
78  wxLog::SetActiveTarget( m_previousLogger );
79  }
80  }
81 
82  void Flush() override
83  {
84  if( m_bHasMessages )
85  {
86  wxLogMessage( _( "Not all symbol libraries could be loaded. Use the Manage Symbol\n"
87  "Libraries dialog to adjust paths and add or remove libraries." ) );
88  wxLogGui::Flush();
89  }
90  }
91 
92 private:
95 };
96 
97 
102 {
103 public:
105 
109  void Sync( const wxString& aForceRefresh,
110  std::function<void( int, int, const wxString& )> aProgressCallback );
111 
117  void Preload( PROGRESS_REPORTER& aReporter );
118 
119  int GetHash() const;
120 
121  bool HasModifications() const;
122 
130  int GetLibraryHash( const wxString& aLibrary ) const;
131 
135  wxArrayString GetLibraryNames() const;
136 
140  SYMBOL_LIB_TABLE_ROW* GetLibrary( const wxString& aLibrary ) const;
141 
142  std::list<LIB_PART*> GetAliases( const wxString& aLibrary ) const;
143 
147  bool CreateLibrary( const wxString& aFilePath, SYMBOL_LIB_TABLE* aTable )
148  {
149  return addLibrary( aFilePath, true, aTable );
150  }
151 
155  bool AddLibrary( const wxString& aFilePath, SYMBOL_LIB_TABLE* aTable )
156  {
157  return addLibrary( aFilePath, false, aTable );
158  }
159 
165  bool UpdatePart( LIB_PART* aPart, const wxString& aLibrary );
166 
171  bool UpdatePartAfterRename( LIB_PART* aPart, const wxString& oldAlias,
172  const wxString& aLibrary );
173 
178  bool RemovePart( const wxString& aName, const wxString& aLibrary );
179 
184  LIB_PART* GetAlias( const wxString& aAlias, const wxString& aLibrary ) const;
185 
190  LIB_PART* GetBufferedPart( const wxString& aAlias, const wxString& aLibrary );
191 
196  SCH_SCREEN* GetScreen( const wxString& aAlias, const wxString& aLibrary );
197 
202  bool PartExists( const wxString& aAlias, const wxString& aLibrary ) const;
203 
208  bool LibraryExists( const wxString& aLibrary, bool aCheckEnabled = false ) const;
209 
213  bool IsLibraryLoaded( const wxString& aLibrary ) const;
214 
218  bool IsLibraryModified( const wxString& aLibrary ) const;
219 
223  bool IsPartModified( const wxString& aAlias, const wxString& aLibrary ) const;
224 
228  bool ClearLibraryModified( const wxString& aLibrary ) const;
229 
233  bool ClearPartModified( const wxString& aAlias, const wxString& aLibrary ) const;
234 
240  bool IsLibraryReadOnly( const wxString& aLibrary ) const;
241 
248  bool FlushPart( const wxString& aAlias, const wxString& aLibrary );
249 
257  bool SaveLibrary( const wxString& aLibrary, const wxString& aFileName,
258  SCH_IO_MGR::SCH_FILE_T aFileType = SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY );
259 
266  LIB_ID RevertPart( const wxString& aAlias, const wxString& aLibrary );
267 
273  bool RevertLibrary( const wxString& aLibrary );
274 
280  bool RevertAll();
281 
286  wxString GetUniqueLibraryName() const;
287 
291  wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>& GetAdapter() { return m_adapter; }
292 
293  void GetRootSymbolNames( const wxString& aLibName, wxArrayString& aRootSymbolNames );
294 
301  bool HasDerivedSymbols( const wxString& aSymbolName, const wxString& aLibraryName );
302 
303  size_t GetLibraryCount() const;
304 
305 private:
307  static wxString getLibraryName( const wxString& aFilePath );
308 
310  bool addLibrary( const wxString& aFilePath, bool aCreate, SYMBOL_LIB_TABLE* aTable );
311 
313  SYMBOL_LIB_TABLE* symTable() const;
314 
316  {
317  return static_cast<SYMBOL_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
318  }
319 
322  {
323  public:
324  PART_BUFFER( LIB_PART* aPart = nullptr, std::unique_ptr<SCH_SCREEN> aScreen = nullptr );
325  ~PART_BUFFER();
326 
327  LIB_PART* GetPart() const { return m_part; }
328  void SetPart( LIB_PART* aPart );
329 
330  LIB_PART* GetOriginal() const { return m_original; }
331  void SetOriginal( LIB_PART* aPart );
332 
333  bool IsModified() const;
334  SCH_SCREEN* GetScreen() const { return m_screen.get(); }
335 
337  std::unique_ptr<SCH_SCREEN> RemoveScreen()
338  {
339  return std::move( m_screen );
340  }
341 
342  bool SetScreen( std::unique_ptr<SCH_SCREEN> aScreen )
343  {
344  bool ret = !!m_screen;
345  m_screen = std::move( aScreen );
346  return ret;
347  }
348 
349  typedef std::shared_ptr<PART_BUFFER> PTR;
350  typedef std::weak_ptr<PART_BUFFER> WEAK_PTR;
351 
352  private:
353  std::unique_ptr<SCH_SCREEN> m_screen;
354 
355  LIB_PART* m_part; // Working copy
356  LIB_PART* m_original; // Initial state of the part
357  };
358 
359 
362  {
363  public:
364  LIB_BUFFER( const wxString& aLibrary ) :
365  m_libName( aLibrary ),
366  m_hash( 1 )
367  { }
368 
369  bool IsModified() const
370  {
371  if( !m_deleted.empty() )
372  return true;
373 
374  for( const auto& partBuf : m_parts )
375  {
376  if( partBuf->IsModified() )
377  return true;
378  }
379 
380  return false;
381  }
382 
383  int GetHash() const { return m_hash; }
384 
386  LIB_PART* GetPart( const wxString& aAlias ) const;
387 
389  bool CreateBuffer( LIB_PART* aCopy, SCH_SCREEN* aScreen );
390 
392  bool UpdateBuffer( PART_BUFFER::PTR aPartBuf, LIB_PART* aCopy );
393 
394  bool DeleteBuffer( PART_BUFFER::PTR aPartBuf );
395 
397  {
398  m_deleted.clear();
399  }
400 
403  bool SaveBuffer( PART_BUFFER::PTR aPartBuf, SYMBOL_LIB_TABLE* aLibTable );
404 
407  bool SaveBuffer( PART_BUFFER::PTR aPartBuf, const wxString& aFileName,
408  SCH_PLUGIN* aPlugin, bool aBuffer );
409 
411  PART_BUFFER::PTR GetBuffer( const wxString& aAlias ) const;
412 
414  const std::deque<PART_BUFFER::PTR>& GetBuffers() const { return m_parts; }
415 
423  bool HasDerivedSymbols( const wxString& aParentName ) const;
424 
430  void GetRootSymbolNames( wxArrayString& aRootSymbolNames );
431 
440  size_t GetDerivedSymbolNames( const wxString& aSymbolName, wxArrayString& aList );
441 
442  private:
449  int removeChildSymbols( PART_BUFFER::PTR aPartBuf );
450 
451  std::deque<PART_BUFFER::PTR> m_parts;
452  std::deque<PART_BUFFER::PTR> m_deleted; // Buffer for deleted parts until library is saved
453  const wxString m_libName; // Buffered library name
454  int m_hash;
455  };
456 
460  std::set<LIB_PART*> getOriginalParts( const wxString& aLibrary );
461 
466  LIB_BUFFER& getLibraryBuffer( const wxString& aLibrary );
467 
469  std::map<wxString, LIB_BUFFER> m_libs;
470 
474 
475  wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> m_adapter;
476 };
477 
478 #endif /* SYMBOL_LIBRARY_MANAGER_H */
bool ClearPartModified(const wxString &aAlias, const wxString &aLibrary) const
Clear the modified flag for a part.
bool UpdatePartAfterRename(LIB_PART *aPart, const wxString &oldAlias, const wxString &aLibrary)
Update the part buffer with a new version of the part when the name has changed.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
LIB_PART * GetAlias(const wxString &aAlias, const wxString &aLibrary) const
Return either an alias of a working LIB_PART copy, or alias of the original part if there is no worki...
void GetRootSymbolNames(const wxString &aLibName, wxArrayString &aRootSymbolNames)
bool RemovePart(const wxString &aName, const wxString &aLibrary)
Remove the part from the part buffer.
SCH_SCREEN * GetScreen() const
Transfer the screen ownership.
bool ClearLibraryModified(const wxString &aLibrary) const
Clear the modified flag for all parts in a library.
bool AddLibrary(const wxString &aFilePath, SYMBOL_LIB_TABLE *aTable)
Add an existing library.
A progress reporter for use in multi-threaded environments.
bool PartExists(const wxString &aAlias, const wxString &aLibrary) const
Return true if part with a specific alias exists in library (either original one or buffered).
SYMBOL_LIBRARY_MANAGER(SYMBOL_EDIT_FRAME &aFrame)
std::unique_ptr< SCH_SCREEN > m_screen
bool SaveLibrary(const wxString &aLibrary, const wxString &aFileName, SCH_IO_MGR::SCH_FILE_T aFileType=SCH_IO_MGR::SCH_FILE_T::SCH_LEGACY)
Save library to a file, including unsaved changes.
bool CreateBuffer(LIB_PART *aCopy, SCH_SCREEN *aScreen)
Update the buffered part with the contents of aCopy.
static wxString getLibraryName(const wxString &aFilePath)
< Extract library name basing on the file name.
SYMBOL_LIB_TABLE * symTable() const
int GetHash() const
Return the working copy of a LIB_PART root object with specified alias.
PART_BUFFER(LIB_PART *aPart=nullptr, std::unique_ptr< SCH_SCREEN > aScreen=nullptr)
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
std::deque< PART_BUFFER::PTR > m_parts
SYMBOL_EDIT_FRAME & m_frame
Parent frame.
std::weak_ptr< PART_BUFFER > WEAK_PTR
bool UpdatePart(LIB_PART *aPart, const wxString &aLibrary)
Update the part buffer with a new version of the part.
bool RevertLibrary(const wxString &aLibrary)
Revert unsaved changes for a particular library.
LIB_BUFFER & getLibraryBuffer(const wxString &aLibrary)
Return an existing library buffer or creates one to using Symbol Library Table to get the original da...
~LIB_LOGGER() override
LIB_PART * GetPart(const wxString &aAlias) const
Create a new buffer to store a part. LIB_BUFFER takes ownership of aCopy.
std::deque< PART_BUFFER::PTR > m_deleted
bool addLibrary(const wxString &aFilePath, bool aCreate, SYMBOL_LIB_TABLE *aTable)
Return the current Symbol Library Table.
std::unique_ptr< SCH_SCREEN > RemoveScreen()
bool FlushPart(const wxString &aAlias, const wxString &aLibrary)
Save part changes to the library copy used by the schematic editor.
LIB_PART * GetBufferedPart(const wxString &aAlias, const wxString &aLibrary)
Return the part copy from the buffer.
Store a working copy of a library.
Base class that schematic file and library loading and saving plugins should derive from.
Definition: sch_io_mgr.h:151
wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > m_adapter
bool UpdateBuffer(PART_BUFFER::PTR aPartBuf, LIB_PART *aCopy)
bool RevertAll()
Revert all pending changes.
wxString GetUniqueLibraryName() const
Return a library name that is not currently in use.
SYMBOL_LIB_TABLE_ROW * GetLibrary(const wxString &aLibrary) const
Find a single library within the (aggregate) library table.
int GetLibraryHash(const wxString &aLibrary) const
Return a library hash value to determine if it has changed.
Class to handle modifications to the symbol libraries.
void ClearDeletedBuffer()
Save stored modifications to Symbol Lib Table.
bool IsLibraryReadOnly(const wxString &aLibrary) const
Return true if the library is stored in a read-only file.
Define a library symbol object.
Definition: lib_symbol.h:93
std::map< wxString, LIB_BUFFER > m_libs
bool DeleteBuffer(PART_BUFFER::PTR aPartBuf)
SYMBOL_TREE_SYNCHRONIZING_ADAPTER * getAdapter()
Class to store a working copy of a LIB_PART object and editor context.
bool HasDerivedSymbols(const wxString &aSymbolName, const wxString &aLibraryName)
Check if symbol aSymbolName in library aLibraryName is a root symbol that has derived symbols.
void Sync(const wxString &aForceRefresh, std::function< void(int, int, const wxString &)> aProgressCallback)
Updates the SYMBOL_LIBRARY_MANAGER data to synchronize with Symbol Library Table.
void Preload(PROGRESS_REPORTER &aReporter)
Preloads all symbol libraries in the symbol library table using SYMBOL_ASYNC_LOADER.
void Flush() override
const std::deque< PART_BUFFER::PTR > & GetBuffers() const
void GetRootSymbolNames(wxArrayString &aRootSymbolNames)
Fetch a list of root symbols names from the library buffer.
int removeChildSymbols(PART_BUFFER::PTR aPartBuf)
Remove all symbols derived from aParent from the library buffer.
wxArrayString GetLibraryNames() const
Return the array of library names.
std::set< LIB_PART * > getOriginalParts(const wxString &aLibrary)
Return a set of LIB_PART objects belonging to the original library.
LIB_ID RevertPart(const wxString &aAlias, const wxString &aLibrary)
Revert unsaved changes for a particular part.
bool IsLibraryModified(const wxString &aLibrary) const
Return true if library has unsaved modifications.
bool LibraryExists(const wxString &aLibrary, bool aCheckEnabled=false) const
Return true if library exists.
wxObjectDataPtr< LIB_TREE_MODEL_ADAPTER > & GetAdapter()
Return the adapter object that provides the stored data.
#define _(s)
Definition: 3d_actions.cpp:33
bool IsLibraryLoaded(const wxString &aLibrary) const
Return true if the library was successfully loaded.
size_t GetDerivedSymbolNames(const wxString &aSymbolName, wxArrayString &aList)
Fetch all of the symbols derived from a aSymbolName into aList.
int m_syncHash
Symbol lib table hash value from last synchronization.
PART_BUFFER::PTR GetBuffer(const wxString &aAlias) const
Return all buffered parts.
SCH_SCREEN * GetScreen(const wxString &aAlias, const wxString &aLibrary)
Return the screen used to edit a specific part.
bool CreateLibrary(const wxString &aFilePath, SYMBOL_LIB_TABLE *aTable)
Create an empty library and adds it to the library table.
bool SetScreen(std::unique_ptr< SCH_SCREEN > aScreen)
std::list< LIB_PART * > GetAliases(const wxString &aLibrary) const
bool SaveBuffer(PART_BUFFER::PTR aPartBuf, SYMBOL_LIB_TABLE *aLibTable)
Save stored modifications using a plugin.
bool HasDerivedSymbols(const wxString &aParentName) const
Check to see any parts in the buffer are derived from a parent named aParentName.
Object used to load, save, search, and otherwise manipulate symbol library files.
std::shared_ptr< PART_BUFFER > PTR
The symbol library editor main window.
bool IsPartModified(const wxString &aAlias, const wxString &aLibrary) const
Return true if part has unsaved modifications.