From 0cf2df51c62646e6c45920c60e2041a84f2922ba Mon Sep 17 00:00:00 2001
From: Wayne Stambaugh <stambaughw@gmail.com>
Date: Sat, 2 Sep 2017 14:12:50 -0400
Subject: [PATCH] Convert symbol library viewer over to symbol library table.

Remove all instances of PART_LIBS and replace them with SYMBOL_LIB_TABLE
except for the CMP_TREE_MODEL_ADAPTER which requires updating as well.

Return the selected symbol using the LIB_NICKNAME:SYMBOL_NAME format when
viewer is launched as modal.

Add code to SYMBOL_LIB_TABLE object to allow enumerating symbol library
power symbols only.

Add a non-const version of LIB_TABLE::findRow().

Remove redundant information from Doxygen comments.
---
 common/lib_table_base.cpp      |  22 ++++++
 eeschema/class_library.cpp     |   2 +-
 eeschema/sch_legacy_plugin.cpp |  17 ++++-
 eeschema/sch_legacy_plugin.h   |   6 +-
 eeschema/symbol_lib_table.cpp  |  16 ++++-
 eeschema/symbol_lib_table.h    |  11 ++-
 eeschema/viewlib_frame.cpp     |  71 ++++++++++----------
 eeschema/viewlib_frame.h       |  33 ++++-----
 eeschema/viewlibs.cpp          |  21 +++---
 include/lib_table_base.h       | 118 +++++++++++----------------------
 10 files changed, 159 insertions(+), 158 deletions(-)

diff --git a/common/lib_table_base.cpp b/common/lib_table_base.cpp
index 7901ec684b..6b7edc188c 100644
--- a/common/lib_table_base.cpp
+++ b/common/lib_table_base.cpp
@@ -281,6 +281,28 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName ) const
 }
 
 
+LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName )
+{
+    LIB_TABLE* cur = (LIB_TABLE*) this;
+
+    do
+    {
+        cur->ensureIndex();
+
+        INDEX_ITER it = cur->nickIndex.find( aNickName );
+
+        if( it != cur->nickIndex.end() )
+        {
+            return &cur->rows[it->second];  // found
+        }
+
+        // not found, search fall back table(s), if any
+    } while( ( cur = cur->fallBack ) != 0 );
+
+    return NULL;   // not found
+}
+
+
 const LIB_TABLE_ROW* LIB_TABLE::FindRowByURI( const wxString& aURI )
 {
     LIB_TABLE* cur = this;
diff --git a/eeschema/class_library.cpp b/eeschema/class_library.cpp
index 1ed21f9d13..db6a20f7a4 100644
--- a/eeschema/class_library.cpp
+++ b/eeschema/class_library.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2004-2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 2008-2017 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2008-2017 Wayne Stambaugh <stambaughw@gmail.com>
  * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp
index 2228dfa264..0e67de29c4 100644
--- a/eeschema/sch_legacy_plugin.cpp
+++ b/eeschema/sch_legacy_plugin.cpp
@@ -57,7 +57,8 @@
 #include <lib_polyline.h>
 #include <lib_rectangle.h>
 #include <lib_text.h>
-#include <eeschema_id.h>    // for MAX_UNIT_COUNT_PER_PACKAGE definition
+#include <eeschema_id.h>       // for MAX_UNIT_COUNT_PER_PACKAGE definition
+#include <symbol_lib_table.h>  // for PropPowerSymsOnly definintion.
 
 
 // Must be the first line of part library document (.dcm) files.
@@ -3456,12 +3457,17 @@ void SCH_LEGACY_PLUGIN::EnumerateSymbolLib( wxArrayString&    aAliasNameList,
 
     m_props = aProperties;
 
+    bool powerSymbolsOnly = ( aProperties &&
+                              aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) != aProperties->end() );
     cacheLib( aLibraryPath );
 
     const LIB_ALIAS_MAP& aliases = m_cache->m_aliases;
 
     for( LIB_ALIAS_MAP::const_iterator it = aliases.begin();  it != aliases.end();  ++it )
-        aAliasNameList.Add( it->first );
+    {
+        if( !powerSymbolsOnly || it->second->GetPart()->IsPower() )
+            aAliasNameList.Add( it->first );
+    }
 }
 
 
@@ -3473,12 +3479,17 @@ void SCH_LEGACY_PLUGIN::EnumerateSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
 
     m_props = aProperties;
 
+    bool powerSymbolsOnly = ( aProperties &&
+                              aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) != aProperties->end() );
     cacheLib( aLibraryPath );
 
     const LIB_ALIAS_MAP& aliases = m_cache->m_aliases;
 
     for( LIB_ALIAS_MAP::const_iterator it = aliases.begin();  it != aliases.end();  ++it )
-        aAliasList.push_back( it->second );
+    {
+        if( !powerSymbolsOnly || it->second->GetPart()->IsPower() )
+            aAliasList.push_back( it->second );
+    }
 }
 
 
diff --git a/eeschema/sch_legacy_plugin.h b/eeschema/sch_legacy_plugin.h
index dfdfac17df..c640f7c235 100644
--- a/eeschema/sch_legacy_plugin.h
+++ b/eeschema/sch_legacy_plugin.h
@@ -46,10 +46,8 @@ class LIB_ALIAS;
 
 
 /**
- * Class SCH_LEGACY_PLUGIN
- *
- * is a #SCH_PLUGIN derivation for loading schematic files created before the new
- * s-expression file format.
+ * A #SCH_PLUGIN derivation for loading schematic files created before the new s-expression
+ * file format.
  *
  * The legacy parser and formatter attempt to be compatible with the legacy file format.
  * The original parser was very forgiving in that it would parse only part of a keyword.
diff --git a/eeschema/symbol_lib_table.cpp b/eeschema/symbol_lib_table.cpp
index 51f9ab93c0..986c934244 100644
--- a/eeschema/symbol_lib_table.cpp
+++ b/eeschema/symbol_lib_table.cpp
@@ -40,6 +40,8 @@ using namespace LIB_TABLE_T;
 static const wxString global_tbl_name( "sym-lib-table" );
 
 
+const char* SYMBOL_LIB_TABLE::PropPowerSymsOnly = "pwr_sym_only";
+const char* SYMBOL_LIB_TABLE::PropNonPowerSymsOnly = "non_pwr_sym_only";
 int SYMBOL_LIB_TABLE::m_modifyHash = 1;     // starts at 1 and goes up
 
 
@@ -243,11 +245,21 @@ int SYMBOL_LIB_TABLE::GetModifyHash()
 }
 
 
-void SYMBOL_LIB_TABLE::EnumerateSymbolLib( const wxString& aNickname, wxArrayString& aAliasNames )
+void SYMBOL_LIB_TABLE::EnumerateSymbolLib( const wxString& aNickname, wxArrayString& aAliasNames,
+                                           bool aPowerSymbolsOnly )
 {
-    const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname );
+    SYMBOL_LIB_TABLE_ROW* row = dynamic_cast< SYMBOL_LIB_TABLE_ROW* >( findRow( aNickname ) );
     wxASSERT( (SCH_PLUGIN*) row->plugin );
+
+    wxString options = row->GetOptions();
+
+    if( aPowerSymbolsOnly )
+        row->SetOptions( row->GetOptions() + " " + PropPowerSymsOnly );
+
     row->plugin->EnumerateSymbolLib( aAliasNames, row->GetFullURI( true ), row->GetProperties() );
+
+    if( aPowerSymbolsOnly )
+        row->SetOptions( options );
 }
 
 
diff --git a/eeschema/symbol_lib_table.h b/eeschema/symbol_lib_table.h
index ef5e2ebaff..d52a24c1e4 100644
--- a/eeschema/symbol_lib_table.h
+++ b/eeschema/symbol_lib_table.h
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2016 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2016 Wayne Stambaugh <stambaughw@gmail.com>
  * Copyright (C) 2016-2017 KiCad Developers, see change_log.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
@@ -104,6 +104,9 @@ class SYMBOL_LIB_TABLE : public LIB_TABLE
     static int m_modifyHash;     ///< helper for GetModifyHash()
 
 public:
+    static const char* PropPowerSymsOnly;
+    static const char* PropNonPowerSymsOnly;
+
     virtual void Parse( LIB_TABLE_LEXER* aLexer ) override;
 
     virtual void Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const override;
@@ -141,11 +144,13 @@ public:
      * Return a list of symbol alias names contained within the library given by @a aNickname.
      *
      * @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW.
-     * @param aAliasNames is a reference to an array for the alias names
+     * @param aAliasNames is a reference to an array for the alias names.
+     * @param aPowerSymbolsOnly is a flag to enumerate only power symbols.
      *
      * @throw IO_ERROR if the library cannot be found or loaded.
      */
-    void EnumerateSymbolLib( const wxString& aNickname, wxArrayString& aAliasNames );
+    void EnumerateSymbolLib( const wxString& aNickname, wxArrayString& aAliasNames,
+                             bool aPowerSymbolsOnly = false );
 
     /**
      * Load a #LIB_ALIAS having @a aAliasName from the library given by @a aNickname.
diff --git a/eeschema/viewlib_frame.cpp b/eeschema/viewlib_frame.cpp
index fe5c08d262..2f301dc2c7 100644
--- a/eeschema/viewlib_frame.cpp
+++ b/eeschema/viewlib_frame.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 2008-2016 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
  * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
@@ -30,17 +30,20 @@
 #include <fctsys.h>
 #include <kiface_i.h>
 #include <pgm_base.h>
-#include <eeschema_id.h>
 #include <class_drawpanel.h>
-#include <schframe.h>
 #include <msgpanel.h>
 #include <bitmaps.h>
 
+#include <schframe.h>
+#include <eeschema_id.h>
 #include <general.h>
 #include <viewlib_frame.h>
-#include <class_library.h>
+#include <symbol_lib_table.h>
+#include <sch_legacy_plugin.h>
 #include <hotkeys.h>
 #include <dialog_helpers.h>
+#include <class_libentry.h>
+#include <class_library.h>
 
 
 // Save previous component library viewer state.
@@ -81,7 +84,8 @@ BEGIN_EVENT_TABLE( LIB_VIEW_FRAME, EDA_DRAW_FRAME )
 
     EVT_UPDATE_UI( ID_LIBVIEW_VIEWDOC, LIB_VIEW_FRAME::onUpdateViewDoc )
     EVT_UPDATE_UI( ID_LIBVIEW_DE_MORGAN_NORMAL_BUTT, LIB_VIEW_FRAME::onUpdateNormalBodyStyleButton )
-    EVT_UPDATE_UI( ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT, LIB_VIEW_FRAME::onUpdateAlternateBodyStyleButton )
+    EVT_UPDATE_UI( ID_LIBVIEW_DE_MORGAN_CONVERT_BUTT,
+                   LIB_VIEW_FRAME::onUpdateAlternateBodyStyleButton )
     EVT_UPDATE_UI( ID_LIBVIEW_SHOW_ELECTRICAL_TYPE, LIB_VIEW_FRAME::OnUpdateElectricalType )
 
 END_EVENT_TABLE()
@@ -109,7 +113,7 @@ END_EVENT_TABLE()
 #define LIB_VIEW_FRAME_NAME_MODAL "ViewlibFrameModal"
 
 LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType,
-        PART_LIB* aLibrary ) :
+                                const wxString& aLibraryName ) :
     SCH_BASE_FRAME( aKiway, aParent, aFrameType, _( "Library Browser" ),
             wxDefaultPosition, wxDefaultSize,
             aFrameType == FRAME_SCH_VIEWER_MODAL ?
@@ -157,7 +161,7 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
     ReCreateHToolbar();
     ReCreateVToolbar();
 
-    if( !aLibrary )
+    if( aLibraryName.empty() )
     {
         // Creates the libraries window display
         m_libList = new wxListBox( this, ID_LIBVIEW_LIB_LIST,
@@ -166,7 +170,7 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
     }
     else
     {
-        m_libraryName = aLibrary->GetName();
+        m_libraryName = aLibraryName;
         m_entryName.Clear();
         m_unit = 1;
         m_convert = 1;
@@ -265,10 +269,7 @@ LIB_ALIAS* LIB_VIEW_FRAME::getSelectedAlias()
 
     if( !m_libraryName.IsEmpty() && !m_entryName.IsEmpty() )
     {
-        PART_LIB* lib = Prj().SchLibs()->FindLibrary( m_libraryName );
-
-        if( lib )
-            alias = lib->FindAlias( m_entryName );
+        alias = Prj().SchSymbolLibTable()->LoadSymbol( m_libraryName, m_entryName );
     }
 
     return alias;
@@ -376,10 +377,10 @@ double LIB_VIEW_FRAME::BestZoom()
 
     LIB_PART*   part = NULL;
     double      bestzoom = 16.0;      // default value for bestzoom
-    PART_LIB*   lib = Prj().SchLibs()->FindLibrary( m_libraryName );
+    LIB_ALIAS*  alias = Prj().SchSymbolLibTable()->LoadSymbol( m_libraryName, m_entryName );
 
-    if( lib  )
-        part = lib->FindPart( m_entryName );
+    if( alias )
+        part = alias->GetPart();
 
     if( !part )
     {
@@ -419,15 +420,15 @@ bool LIB_VIEW_FRAME::ReCreateListLib()
 
     m_libList->Clear();
 
-    wxArrayString libs = Prj().SchLibs()->GetLibraryNames();
+    std::vector< wxString > libs = Prj().SchSymbolLibTable()->GetLogicalLibs();
 
     // Remove not allowed libs from main list, if the allowed lib list is not empty
     if( m_allowedLibs.GetCount() )
     {
-        for( unsigned ii = 0; ii < libs.GetCount(); )
+        for( unsigned ii = 0; ii < libs.size(); )
         {
             if( m_allowedLibs.Index( libs[ii] ) == wxNOT_FOUND )
-                libs.RemoveAt( ii );
+                libs.erase( libs.begin() + ii );
             else
                 ii++;
         }
@@ -436,21 +437,28 @@ bool LIB_VIEW_FRAME::ReCreateListLib()
     // Remove libs which have no power components, if this filter is activated
     if( m_listPowerCmpOnly )
     {
-        for( unsigned ii = 0; ii < libs.GetCount(); )
+        for( unsigned ii = 0; ii < libs.size(); )
         {
-            PART_LIB* lib = Prj().SchLibs()->FindLibrary( libs[ii] );
+            wxArrayString aliasNames;
 
-            if( lib && !lib->HasPowerParts() )
-                libs.RemoveAt( ii );
+            Prj().SchSymbolLibTable()->EnumerateSymbolLib( libs[ii], aliasNames, true );
+
+            if( aliasNames.IsEmpty() )
+                libs.erase( libs.begin() + ii );
             else
                 ii++;
         }
     }
 
-    if( libs.IsEmpty() )
+    if( libs.empty() )
         return true;
 
-    m_libList->Append( libs );
+    wxArrayString libNames;
+
+    for( auto name : libs )
+        libNames.Add( name );
+
+    m_libList->Append( libNames );
 
     // Search for a previous selection:
     int index = m_libList->FindString( m_libraryName );
@@ -485,9 +493,11 @@ bool LIB_VIEW_FRAME::ReCreateListCmp()
 
     m_cmpList->Clear();
 
-    PART_LIB* lib = Prj().SchLibs()->FindLibrary( m_libraryName );
+    wxArrayString aliasNames;
 
-    if( !lib || lib->IsEmpty() )
+    Prj().SchSymbolLibTable()->EnumerateSymbolLib( m_libraryName, aliasNames, m_listPowerCmpOnly );
+
+    if( aliasNames.IsEmpty() )
     {
         m_libraryName = wxEmptyString;
         m_entryName = wxEmptyString;
@@ -496,14 +506,7 @@ bool LIB_VIEW_FRAME::ReCreateListCmp()
         return true;
     }
 
-    wxArrayString  nameList;
-
-    if( m_listPowerCmpOnly )
-        lib->GetEntryTypePowerNames( nameList );
-    else
-        lib->GetAliasNames( nameList );
-
-    m_cmpList->Append( nameList );
+    m_cmpList->Append( aliasNames );
 
     int index = m_cmpList->FindString( m_entryName );
     bool changed = false;
diff --git a/eeschema/viewlib_frame.h b/eeschema/viewlib_frame.h
index 73deceb27e..8c1b7a31a3 100644
--- a/eeschema/viewlib_frame.h
+++ b/eeschema/viewlib_frame.h
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 2008-2016 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
  * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
@@ -37,14 +37,14 @@
 #include <class_sch_screen.h>
 
 class wxListBox;
-class PART_LIB;
 class SCHLIB_FILTER;
 class LIB_ALIAS;
 class LIB_PART;
+class SYMBOL_LIB_TABLE_ROW;
 
 
 /**
- * Component library viewer main window.
+ * Symbol library viewer main window.
  */
 class LIB_VIEW_FRAME : public SCH_BASE_FRAME
 {
@@ -59,17 +59,14 @@ public:
      * @param aLibrary = the library to open when starting (default = NULL)
      */
     LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent,
-                    FRAME_T aFrameType, PART_LIB* aLibrary = NULL );
+                    FRAME_T aFrameType, const wxString& aLibraryName = wxEmptyString );
 
     ~LIB_VIEW_FRAME();
 
     void OnSize( wxSizeEvent& event ) override;
 
     /**
-     * Function ReCreateListLib
-     *
-     * Creates or recreates the list of current loaded libraries.
-     * This list is sorted, with the library cache always at end of the list
+     * Creates or recreates a sorted list of currently loaded libraries.
      *
      * @return whether the selection of either library or component was changed (i.e. because the
      * selected library no longer exists)
@@ -105,9 +102,9 @@ public:
     EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const override;
 
     /**
-     * Function OnHotKey
-     * handle hot key events.
-     * <p?
+     * Handle hot key events.
+     *
+     * <p>
      * Some commands are relative to the item under the mouse cursor.  Commands are
      * case insensitive
      * </p>
@@ -119,13 +116,11 @@ public:
     void SaveSettings( wxConfigBase* aCfg ) override;
 
     /**
-     * set a filter to display only libraries and/or components
-     * which match the filter
+     * Set a filter to display only libraries and/or components which match the filter.
      *
-     * @param aFilter is a filter to pass the allowed library name list
-     *          and/or some other filter
-     *  see SCH_BASE_FRAME::SelectComponentFromLibrary() for details.
-     * if aFilter == NULL, remove all filtering
+     * @param aFilter is a filter to pass the allowed library name list and/or some other filter
+     *                see SCH_BASE_FRAME::SelectComponentFromLibrary() for details.
+     *                if aFilter == NULL, remove all filtering
      */
     void SetFilter( const SCHLIB_FILTER* aFilter );
 
@@ -146,6 +141,7 @@ public:
     // Accessors:
     /**
      * Set unit and convert, and set flag preventing them from automatically resetting to 1
+     *
      * @param aUnit - unit; if invalid will be set to 1
      * @param aConvert - convert; if invalid will be set to 1
      */
@@ -158,8 +154,7 @@ public:
 
 private:
     /**
-     * Function OnActivate
-     * is called when the frame frame is activate to reload the libraries and component lists
+     * Called when the frame is activated to reload the libraries and component lists
      * that can be changed by the schematic editor or the library editor.
      */
     virtual void OnActivate( wxActivateEvent& event ) override;
diff --git a/eeschema/viewlibs.cpp b/eeschema/viewlibs.cpp
index 4badd6b3a8..2a10a9d391 100644
--- a/eeschema/viewlibs.cpp
+++ b/eeschema/viewlibs.cpp
@@ -33,8 +33,8 @@
 #include <class_drawpanel.h>
 #include <confirm.h>
 #include <eda_doc.h>
-#include <class_sch_screen.h>
 
+#include <class_sch_screen.h>
 #include <general.h>
 #include <viewlib_frame.h>
 #include <eeschema_id.h>
@@ -42,6 +42,7 @@
 #include <dialog_helpers.h>
 #include <dialog_choose_component.h>
 #include <cmp_tree_model_adapter.h>
+#include <symbol_lib_table.h>
 
 
 void LIB_VIEW_FRAME::OnSelectSymbol( wxCommandEvent& aEvent )
@@ -114,8 +115,8 @@ void LIB_VIEW_FRAME::onSelectPreviousSymbol( wxCommandEvent& aEvent )
 
 void LIB_VIEW_FRAME::onViewSymbolDocument( wxCommandEvent& aEvent )
 {
-    LIB_ID id( wxEmptyString, m_entryName );
-    LIB_ALIAS* entry = Prj().SchLibs()->FindLibraryAlias( id, m_libraryName );
+    LIB_ID id( m_libraryName, m_entryName );
+    LIB_ALIAS* entry = Prj().SchSymbolLibTable()->LoadSymbol( id );
 
     if( entry && !entry->GetDocFileName().IsEmpty() )
     {
@@ -171,14 +172,12 @@ bool LIB_VIEW_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu )
 
 void LIB_VIEW_FRAME::DisplayLibInfos()
 {
-    PART_LIBS*  libs = Prj().SchLibs();
-
-    if( libs )
+    if( m_libList && !m_libList->IsEmpty() && !m_libraryName.IsEmpty() )
     {
-        PART_LIB* lib = libs->FindLibrary( m_libraryName );
+        const SYMBOL_LIB_TABLE_ROW* row = Prj().SchSymbolLibTable()->FindRow( m_libraryName );
 
-        wxString title = wxString::Format( L"Library Browser \u2014 %s",
-            lib ? lib->GetFullFileName() : "no library selected" );
+        wxString title = wxString::Format( L"Symbol Library Browser \u2014 %s",
+            row ? row->GetFullURI() : "no library selected" );
         SetTitle( title );
     }
 }
@@ -186,8 +185,8 @@ void LIB_VIEW_FRAME::DisplayLibInfos()
 
 void LIB_VIEW_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
 {
-    LIB_ID id( wxEmptyString, m_entryName );
-    LIB_ALIAS* entry = Prj().SchLibs()->FindLibraryAlias( id, m_libraryName );
+    LIB_ID id( m_libraryName, m_entryName );
+    LIB_ALIAS* entry = Prj().SchSymbolLibTable()->LoadSymbol( id );
 
     if( !entry )
         return;
diff --git a/include/lib_table_base.h b/include/lib_table_base.h
index 2945fb5f09..eba6dbc0f0 100644
--- a/include/lib_table_base.h
+++ b/include/lib_table_base.h
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2010-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
- * Copyright (C) 2012-2017 Wayne Stambaugh <stambaughw@verizon.net>
+ * Copyright (C) 2012 Wayne Stambaugh <stambaughw@gmail.com>
  * Copyright (C) 2012-2017 KiCad Developers, see change_log.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
@@ -53,8 +53,6 @@ typedef LIB_TABLE_ROWS::const_iterator     LIB_TABLE_ROWS_CITER;
 
 
 /**
- * Function new_clone
- *
  * Allows boost pointer containers to make clones of the data stored in them.  Since they
  * store pointers the data is cloned.  Copying and assigning pointers would cause ownership
  * issues if the standard C++ containers were used.
@@ -63,9 +61,7 @@ LIB_TABLE_ROW* new_clone( const LIB_TABLE_ROW& aRow );
 
 
 /**
- * Class LIB_TABLE_ROW
- *
- * holds a record identifying a library accessed by the appropriate plug in object in the
+ * Hold a record identifying a library accessed by the appropriate plug in object in the
  * #LIB_TABLE.  This is an abstract base class from which to derive library specific rows.
  */
 class LIB_TABLE_ROW : boost::noncopyable
@@ -94,90 +90,68 @@ public:
     bool operator!=( const LIB_TABLE_ROW& r ) const   { return !( *this == r ); }
 
     /**
-     * Function GetNickName
-     *
      * @return the logical name of this library table row.
      */
     const wxString& GetNickName() const         { return nickName; }
 
     /**
-     * Function SetNickName
-     *
-     * changes the logical name of this library, useful for an editor.
+     * Change the logical name of this library, useful for an editor.
      */
     void SetNickName( const wxString& aNickName ) { nickName = aNickName; }
 
     /**
-     * Function GetType
-     *
-     * is a pure virtual function that returns the type of LIB represented by this row.
+     * Return the type of library represented by this row.
      */
     virtual const wxString GetType() const = 0;
 
     /**
-     * Function SetType
-     *
-     * is a pure virtual function changes the type represented by this row that must
-     * be implemented in the derived object to provide the library table row type.
+     * Change the type of library represented by this row that must be implemented in the
+     * derived object to provide the library table row type.
      */
     virtual void SetType( const wxString& aType ) = 0;
 
     /**
-     * Function GetFullURI
-     *
-     * returns the full location specifying URI for the LIB, either in original
-     * UI form or in environment variable expanded form.
+     * Return the full location specifying URI for the LIB, either in original UI form or
+     * in environment variable expanded form.
      *
      * @param aSubstituted Tells if caller wanted the substituted form, else not.
      */
     const wxString GetFullURI( bool aSubstituted = false ) const;
 
     /**
-     * Function SetFullURI
-     *
-     * changes the full URI for the library.
+     * Change the full URI for the library.
      */
     void SetFullURI( const wxString& aFullURI );
 
     /**
-     * Function GetOptions
-     *
-     * returns the options string, which may hold a password or anything else needed to
-     * instantiate the underlying LIB_SOURCE.
+     * Return the options string, which may hold a password or anything else needed to
+     * instantiate the underlying library plugin.
      */
     const wxString& GetOptions() const          { return options; }
 
     /**
-     * Function SetOptions
+     * Change the library options strings.
      */
     void SetOptions( const wxString& aOptions );
 
     /**
-     * Function GetDescr
-     *
-     * returns the description of the library referenced by this row.
+     * Return the description of the library referenced by this row.
      */
     const wxString& GetDescr() const            { return description; }
 
     /**
-     * Function SetDescr
-     *
-     * changes the description of the library referenced by this row.
+     * Change the description of the library referenced by this row.
      */
     void SetDescr( const wxString& aDescr )     { description = aDescr; }
 
     /**
-     * Function GetProperties
-     *
-     * returns the constant PROPERTIES for this library (LIB_TABLE_ROW).  These are
+     * Return the constant #PROPERTIES for this library (#LIB_TABLE_ROW).  These are
      * the "options" in a table.
      */
     const PROPERTIES* GetProperties() const     { return properties.get(); }
 
     /**
-     * Function Format
-     *
-     * serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
+     * Serialize this object as utf8 text to an #OUTPUTFORMATTER, and tries to
      * make it look good using multiple lines and indentation.
      *
      * @param out is an #OUTPUTFORMATTER
@@ -231,9 +205,8 @@ private:
 
 
 /**
- * Class LIB_TABLE
+ * Manage #LIB_TABLE_ROW records (rows), and can be searched based on library nickname.
  *
- * holds #LIB_TABLE_ROW records (rows), and can be searched based on library nickname.
  * <p>
  * This class owns the <b>library table</b>, which is like fstab in concept and maps
  * logical library name to the library URI, type, and options. It is heavily based on
@@ -284,9 +257,7 @@ class LIB_TABLE : public PROJECT::_ELEM
 public:
 
     /**
-     * Function Parse
-     *
-     * Parses the \a #LIB_TABLE_LEXER s-expression library table format into the appropriate
+     * Parse the #LIB_TABLE_LEXER s-expression library table format into the appropriate
      * #LIB_TABLE_ROW objects.
      *
      * @param aLexer is the lexer to parse.
@@ -312,9 +283,8 @@ public:
     virtual void Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const = 0;
 
     /**
-     * Constructor LIB_TABLE
-     * builds a library table by pre-pending this table fragment in front of
-     * @a aFallBackTable.  Loading of this table fragment is done by using Parse().
+     * Build a library table by pre-pending this table fragment in front of \a aFallBackTable.
+     * Loading of this table fragment is done by using Parse().
      *
      * @param aFallBackTable is another LIB_TABLE which is searched only when
      *                       a row is not found in this table.  No ownership is
@@ -354,7 +324,7 @@ public:
     LIB_TABLE_ROW* At( int aIndex ) { return &rows[aIndex]; }
 
     /**
-     * Function IsEmpty
+     * Return true if the table is empty.
      *
      * @param aIncludeFallback is used to determine if the fallback table should be
      *                         included in the test.
@@ -364,8 +334,6 @@ public:
     bool IsEmpty( bool aIncludeFallback = true );
 
     /**
-     * Function GetDescription
-     *
      * @return the library description from @a aNickname, or an empty string
      *         if @a aNickname does not exist.
      */
@@ -379,17 +347,13 @@ public:
     bool HasLibrary( const wxString& aNickname ) const;
 
     /**
-     * Function GetLogicalLibs
-     *
-     * returns the logical library names, all of them that are pertinent to
+     * Return the logical library names, all of them that are pertinent to
      * a look up done on this LIB_TABLE.
      */
     std::vector<wxString> GetLogicalLibs();
 
     /**
-     * Function InsertRow
-     *
-     * adds aRow if it does not already exist or if doReplace is true.  If doReplace
+     * Adds \a aRow if it does not already exist or if doReplace is true.  If doReplace
      * is not true and the key for aRow already exists, the function fails and returns false.
      *
      * The key for the table is the nickName, and all in this table must be unique.
@@ -403,17 +367,13 @@ public:
     bool InsertRow( LIB_TABLE_ROW* aRow, bool doReplace = false );
 
     /**
-     * Function FindRowByURI
-     *
      * @return a #LIB_TABLE_ROW pointer if \a aURI is found in this table or in any chained
      *         fallBack table fragments, else NULL.
      */
     const LIB_TABLE_ROW* FindRowByURI( const wxString& aURI );
 
     /**
-     * Function Load
-     *
-     * loads the library table using the path defined by \a aFileName aFallBackTable.
+     * Load the library table using the path defined by \a aFileName aFallBackTable.
      *
      * @param aFileName contains the full path to the s-expression file.
      *
@@ -423,9 +383,7 @@ public:
     void Load( const wxString& aFileName );
 
     /**
-     * Function Save
-     *
-     * writes this library table to \a aFileName in s-expression form.
+     * Write this library table to \a aFileName in s-expression form.
      *
      * @param aFileName is the name of the file to write to.
      */
@@ -444,11 +402,10 @@ public:
     size_t GetEnvVars( wxArrayString& aEnvVars ) const;
 
     /**
-     * Function ParseOptions
-     *
-     * parses @a aOptionsList and places the result into a PROPERTIES object which is
+     * Parses \a aOptionsList and places the result into a #PROPERTIES object which is
      * returned.  If the options field is empty, then the returned PROPERTIES will be
      * a NULL pointer.
+     *
      * <p>
      * Typically aOptionsList comes from the "options" field within a LIB_TABLE_ROW and
      * the format is simply a comma separated list of name value pairs. e.g.:
@@ -459,11 +416,10 @@ public:
     static PROPERTIES* ParseOptions( const std::string& aOptionsList );
 
     /**
-     * Function FormatOptions
+     * Returns a list of options from the aProperties parameter.
      *
-     * returns a list of options from the aProperties parameter.  The name=value
-     * pairs will be separated with the '|' character.  The =value portion may not
-     * be present.  You might expect something like "name1=value1|name2=value2|flag_me".
+     * The name=value pairs will be separated with the '|' character.  The =value portion may
+     * not be present.  You might expect something like "name1=value1|name2=value2|flag_me".
      * Notice that flag_me does not have a value.  This is ok.
      *
      * @param aProperties is the PROPERTIES to format or NULL.  If NULL the returned
@@ -472,24 +428,24 @@ public:
     static UTF8 FormatOptions( const PROPERTIES* aProperties );
 
     /**
-     * Function ExpandSubstitutions
+     * Replaces any environment variable references with their values and is here to fully
+     * embellish the TABLE_ROW::uri in a platform independent way.
      *
-     * replaces any environment variable references with their values and is here to fully
-     * embellish the TABLE_ROW::uri in a platform independent way.  This enables library
-     * tables to have platform dependent environment variables in them, allowing for a
-     * uniform table across platforms.
+     * This enables library tables to have platform dependent environment variables in them,
+     * allowing for a uniform table across platforms.
      */
     static const wxString ExpandSubstitutions( const wxString& aString );
 
 protected:
 
     /**
-     * Function findRow
-     * returns a LIB_TABLE_ROW if aNickname is found in this table or in any chained
+     * Return a #LIB_TABLE_ROW if \a aNickname is found in this table or in any chained
      * fallBack table fragment, else NULL.
      */
     LIB_TABLE_ROW* findRow( const wxString& aNickname ) const;
 
+    LIB_TABLE_ROW* findRow( const wxString& aNickname );
+
     void reindex()
     {
         nickIndex.clear();