← Back to team overview

kicad-developers team mailing list archive

[PATCH] Display more information in component selector

 

Hi,

This patch adds more information to the component selector. In
particular, it adds two things:

1. Display component description even for aliases.
2. Display all fields.

Screenshot: https://misc.c4757p.com/choose-component.png

It should be ready for commit, just pending review.

Upcoming changes:

1. Make datasheet a clickable link
2. Add footprint preview/selection discussed earlier
3. Rearrange dialog to make this all fit

-- 
Chris
>From bd18e1c54e4cdd8ae42d185410eabd42f7c4ef1b Mon Sep 17 00:00:00 2001
From: Chris Pavlina <pavlina.chris@xxxxxxxxx>
Date: Sun, 5 Feb 2017 14:18:29 -0500
Subject: [PATCH] Display more information in component selector

---
 common/string.cpp                                 | 26 ++++++-
 eeschema/dialogs/dialog_choose_component.cpp      | 95 +++++++++++++----------
 eeschema/dialogs/dialog_choose_component_base.cpp | 10 +--
 eeschema/dialogs/dialog_choose_component_base.fbp | 27 +++----
 eeschema/dialogs/dialog_choose_component_base.h   |  5 +-
 eeschema/lib_field.cpp                            |  4 +-
 eeschema/lib_field.h                              |  2 +-
 include/kicad_string.h                            |  5 ++
 8 files changed, 104 insertions(+), 70 deletions(-)

diff --git a/common/string.cpp b/common/string.cpp
index d0bfe33ed..8f35b83d6 100644
--- a/common/string.cpp
+++ b/common/string.cpp
@@ -1,7 +1,7 @@
 /*
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
- * Copyright (C) 2004 KiCad Developers, see change_log.txt for contributors.
+ * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -167,6 +167,30 @@ std::string EscapedUTF8( const wxString& aString )
 }
 
 
+wxString EscapedHTML( const wxString& aString )
+{
+    wxString converted;
+
+    for( wxUniChar c: aString )
+    {
+        if( c == '\"' )
+            converted += "&quot;";
+        else if( c == '\'' )
+            converted += "&apos;";
+        else if( c == '&' )
+            converted += "&amp;";
+        else if( c == '<' )
+            converted += "&lt;";
+        else if( c == '>' )
+            converted += "&gt;";
+        else
+            converted += c;
+    }
+
+    return converted;
+}
+
+
 char* StrPurge( char* text )
 {
     static const char whitespace[] = " \t\n\r\f\v";
diff --git a/eeschema/dialogs/dialog_choose_component.cpp b/eeschema/dialogs/dialog_choose_component.cpp
index 04728a0d5..640182713 100644
--- a/eeschema/dialogs/dialog_choose_component.cpp
+++ b/eeschema/dialogs/dialog_choose_component.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2014 Henner Zeller <h.zeller@xxxxxxx>
- * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 2016-2017 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -29,6 +29,7 @@
 #include <class_library.h>
 #include <component_tree_search_container.h>
 #include <sch_base_frame.h>
+#include <kicad_string.h>
 
 // Tree navigation helpers.
 static wxTreeItemId GetPrevItem( const wxTreeCtrl& tree, const wxTreeItemId& item );
@@ -44,7 +45,6 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const
     m_external_browser_requested = false;
     m_received_doubleclick_in_tree = false;
     m_search_container->SetTree( m_libraryComponentTree );
-    m_componentDetails->SetEditable( false );
     m_componentView->SetLayoutDirection( wxLayout_LeftToRight );
 
     m_libraryComponentTree->ScrollTo( m_libraryComponentTree->GetFocusedItem() );
@@ -221,70 +221,83 @@ bool DIALOG_CHOOSE_COMPONENT::updateSelection()
 
     m_componentView->Refresh();
 
-    m_componentDetails->Clear();
+    m_componentDetails->SetPage( wxEmptyString );
 
     if( selection == NULL )
         return false;
 
     m_componentDetails->Freeze();
-    wxFont font_normal = m_componentDetails->GetFont();
-    wxFont font_bold = m_componentDetails->GetFont();
-    font_bold.SetWeight( wxFONTWEIGHT_BOLD );
-
-    wxTextAttr headline_attribute;
-    headline_attribute.SetFont( font_bold );
-    wxTextAttr text_attribute;
-    text_attribute.SetFont( font_normal );
 
     const wxString name = selection->GetName();
+    wxString description = selection->GetDescription();
 
     if ( !name.empty() )
     {
-        m_componentDetails->SetDefaultStyle( headline_attribute );
-        m_componentDetails->AppendText( name );
+        m_componentDetails->AppendToPage( "<b>" );
+        m_componentDetails->AppendToPage( EscapedHTML( name ) );
+        m_componentDetails->AppendToPage( "</b>" );
     }
 
-    const wxString description = selection->GetDescription();
-
-    if( !description.empty() )
+    if( !selection->IsRoot() )
     {
-        if ( !m_componentDetails->IsEmpty() )
-            m_componentDetails->AppendText( wxT( "\n\n" ) );
+        LIB_PART* root_part = selection->GetPart();
+        const wxString root_name( root_part ? root_part->GetName() : _( "Unknown" ) );
+
+        m_componentDetails->AppendToPage(
+                "<br><i>" + _( "Alias of " ) + EscapedHTML( root_name ) + "</i>" );
+
+        // For some reason descriptions are a property of aliases, even though
+        // only the root component's main LIB_ALIAS can actually have a description.
+        // If the description was empty, go through the alias list and find an alias
+        // that actually has one.
 
-        m_componentDetails->SetDefaultStyle( headline_attribute );
-        m_componentDetails->AppendText( _( "Description\n" ) );
-        m_componentDetails->SetDefaultStyle( text_attribute );
-        m_componentDetails->AppendText( description );
+        if( description.empty() )
+        {
+            for( size_t i = 0; i < root_part->GetAliasCount(); ++i )
+            {
+                LIB_ALIAS* alias = root_part->GetAlias( i );
+
+                if( !alias )
+                    continue;
+
+                description = alias->GetDescription();
+
+                if( !description.empty() )
+                    break;
+            }
+        }
     }
 
-    const wxString keywords = selection->GetKeyWords();
+    if( !description.empty() )
+    {
+        m_componentDetails->AppendToPage( "<br>" );
+        m_componentDetails->AppendToPage( EscapedHTML( description ) );
+    }
 
+    wxString keywords = selection->GetKeyWords();
     if( !keywords.empty() )
     {
-        if ( !m_componentDetails->IsEmpty() )
-            m_componentDetails->AppendText( wxT( "\n\n" ) );
-
-        m_componentDetails->SetDefaultStyle( headline_attribute );
-        m_componentDetails->AppendText( _( "Keywords\n" ) );
-        m_componentDetails->SetDefaultStyle( text_attribute );
-        m_componentDetails->AppendText( keywords );
+        m_componentDetails->AppendToPage( "<br>" + _( "Keywords:" ) + " " );
+        m_componentDetails->AppendToPage( EscapedHTML( keywords ) );
     }
 
-    if ( !selection->IsRoot() )
-    {
-        LIB_PART* root_part = selection->GetPart();
-        const wxString root_component_name( root_part ? root_part->GetName() : _( "Unknown" ) );
+    m_componentDetails->AppendToPage( "<hr><table border=0>" );
+
 
-        if ( !m_componentDetails->IsEmpty() )
-            m_componentDetails->AppendText( wxT( "\n\n" ) );
+    LIB_FIELDS fields;
+    selection->GetPart()->GetFields( fields );
 
-        m_componentDetails->SetDefaultStyle( headline_attribute );
-        m_componentDetails->AppendText( _( "Alias of " ) );
-        m_componentDetails->SetDefaultStyle( text_attribute );
-        m_componentDetails->AppendText( root_component_name );
+    for( auto const & field: fields )
+    {
+        wxString name = field.GetName();
+        wxString text = field.GetFullText();
+
+        m_componentDetails->AppendToPage( "<tr><td><b>" + EscapedHTML( name ) + "</b></td>" );
+        m_componentDetails->AppendToPage( "<td>" + EscapedHTML( text ) + "</td></tr>" );
     }
 
-    m_componentDetails->SetInsertionPoint( 0 );  // scroll up.
+    m_componentDetails->AppendToPage( "</table>" );
+
     m_componentDetails->Thaw();
 
     return true;
diff --git a/eeschema/dialogs/dialog_choose_component_base.cpp b/eeschema/dialogs/dialog_choose_component_base.cpp
index 2c332c953..a255497d5 100644
--- a/eeschema/dialogs/dialog_choose_component_base.cpp
+++ b/eeschema/dialogs/dialog_choose_component_base.cpp
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jan 15 2017)
+// C++ code generated with wxFormBuilder (version Jan  5 2017)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -40,12 +40,10 @@ DIALOG_CHOOSE_COMPONENT_BASE::DIALOG_CHOOSE_COMPONENT_BASE( wxWindow* parent, wx
 	m_componentView = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER );
 	m_componentView->SetMinSize( wxSize( 200,200 ) );
 	
-	bSizerView->Add( m_componentView, 4, wxEXPAND | wxALL, 5 );
+	bSizerView->Add( m_componentView, 1, wxEXPAND | wxALL, 5 );
 	
-	m_componentDetails = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), wxTE_MULTILINE );
-	m_componentDetails->SetMinSize( wxSize( 200,200 ) );
-	
-	bSizerView->Add( m_componentDetails, 3, wxALL|wxEXPAND, 5 );
+	m_componentDetails = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO );
+	bSizerView->Add( m_componentDetails, 1, wxALL|wxEXPAND, 5 );
 	
 	
 	bSizerMain->Add( bSizerView, 1, wxEXPAND, 5 );
diff --git a/eeschema/dialogs/dialog_choose_component_base.fbp b/eeschema/dialogs/dialog_choose_component_base.fbp
index a07bd5bca..432f72b40 100644
--- a/eeschema/dialogs/dialog_choose_component_base.fbp
+++ b/eeschema/dialogs/dialog_choose_component_base.fbp
@@ -392,7 +392,7 @@
                         <object class="sizeritem" expanded="1">
                             <property name="border">5</property>
                             <property name="flag">wxEXPAND | wxALL</property>
-                            <property name="proportion">4</property>
+                            <property name="proportion">1</property>
                             <object class="wxPanel" expanded="1">
                                 <property name="BottomDockable">1</property>
                                 <property name="LeftDockable">1</property>
@@ -469,11 +469,11 @@
                                 <event name="OnUpdateUI"></event>
                             </object>
                         </object>
-                        <object class="sizeritem" expanded="0">
+                        <object class="sizeritem" expanded="1">
                             <property name="border">5</property>
                             <property name="flag">wxALL|wxEXPAND</property>
-                            <property name="proportion">3</property>
-                            <object class="wxTextCtrl" expanded="0">
+                            <property name="proportion">1</property>
+                            <object class="wxHtmlWindow" expanded="1">
                                 <property name="BottomDockable">1</property>
                                 <property name="LeftDockable">1</property>
                                 <property name="RightDockable">1</property>
@@ -504,10 +504,9 @@
                                 <property name="max_size"></property>
                                 <property name="maximize_button">0</property>
                                 <property name="maximum_size"></property>
-                                <property name="maxlength"></property>
                                 <property name="min_size"></property>
                                 <property name="minimize_button">0</property>
-                                <property name="minimum_size">200,200</property>
+                                <property name="minimum_size"></property>
                                 <property name="moveable">1</property>
                                 <property name="name">m_componentDetails</property>
                                 <property name="pane_border">1</property>
@@ -518,22 +517,20 @@
                                 <property name="pos"></property>
                                 <property name="resize">Resizable</property>
                                 <property name="show">1</property>
-                                <property name="size">-1,-1</property>
-                                <property name="style">wxTE_MULTILINE</property>
+                                <property name="size"></property>
+                                <property name="style">wxHW_SCROLLBAR_AUTO</property>
                                 <property name="subclass"></property>
                                 <property name="toolbar_pane">0</property>
                                 <property name="tooltip"></property>
-                                <property name="validator_data_type"></property>
-                                <property name="validator_style">wxFILTER_NONE</property>
-                                <property name="validator_type">wxDefaultValidator</property>
-                                <property name="validator_variable"></property>
-                                <property name="value"></property>
                                 <property name="window_extra_style"></property>
                                 <property name="window_name"></property>
                                 <property name="window_style"></property>
                                 <event name="OnChar"></event>
                                 <event name="OnEnterWindow"></event>
                                 <event name="OnEraseBackground"></event>
+                                <event name="OnHtmlCellClicked"></event>
+                                <event name="OnHtmlCellHover"></event>
+                                <event name="OnHtmlLinkClicked"></event>
                                 <event name="OnKeyDown"></event>
                                 <event name="OnKeyUp"></event>
                                 <event name="OnKillFocus"></event>
@@ -553,10 +550,6 @@
                                 <event name="OnRightUp"></event>
                                 <event name="OnSetFocus"></event>
                                 <event name="OnSize"></event>
-                                <event name="OnText"></event>
-                                <event name="OnTextEnter"></event>
-                                <event name="OnTextMaxLen"></event>
-                                <event name="OnTextURL"></event>
                                 <event name="OnUpdateUI"></event>
                             </object>
                         </object>
diff --git a/eeschema/dialogs/dialog_choose_component_base.h b/eeschema/dialogs/dialog_choose_component_base.h
index 4d1fa4077..4a05e0ef9 100644
--- a/eeschema/dialogs/dialog_choose_component_base.h
+++ b/eeschema/dialogs/dialog_choose_component_base.h
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jan 15 2017)
+// C++ code generated with wxFormBuilder (version Jan  5 2017)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -24,6 +24,7 @@ class DIALOG_SHIM;
 #include <wx/sizer.h>
 #include <wx/treectrl.h>
 #include <wx/panel.h>
+#include <wx/html/htmlwin.h>
 #include <wx/button.h>
 #include <wx/dialog.h>
 
@@ -42,7 +43,7 @@ class DIALOG_CHOOSE_COMPONENT_BASE : public DIALOG_SHIM
 		wxTextCtrl* m_searchBox;
 		wxTreeCtrl* m_libraryComponentTree;
 		wxPanel* m_componentView;
-		wxTextCtrl* m_componentDetails;
+		wxHtmlWindow* m_componentDetails;
 		wxStdDialogButtonSizer* m_stdButtons;
 		wxButton* m_stdButtonsOK;
 		wxButton* m_stdButtonsCancel;
diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp
index b6e8cd000..a443203ef 100644
--- a/eeschema/lib_field.cpp
+++ b/eeschema/lib_field.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
- * Copyright (C) 2004-2012 KiCad Developers, see change_log.txt for contributors.
+ * Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -528,7 +528,7 @@ void LIB_FIELD::Plot( PLOTTER* aPlotter, const wxPoint& aOffset, bool aFill,
 }
 
 
-wxString LIB_FIELD::GetFullText( int unit )
+wxString LIB_FIELD::GetFullText( int unit ) const
 {
     if( m_id != REFERENCE )
         return GetText();
diff --git a/eeschema/lib_field.h b/eeschema/lib_field.h
index 9e48a45e9..0715e984c 100644
--- a/eeschema/lib_field.h
+++ b/eeschema/lib_field.h
@@ -189,7 +189,7 @@ public:
      * @param unit - The package unit number.  Only effects reference field.
      * @return Field text.
      */
-    wxString GetFullText( int unit = 1 );
+    wxString GetFullText( int unit = 1 ) const;
 
     EDA_COLOR_T GetDefaultColor() override;
 
diff --git a/include/kicad_string.h b/include/kicad_string.h
index d3136a308..abf6a8200 100644
--- a/include/kicad_string.h
+++ b/include/kicad_string.h
@@ -74,6 +74,11 @@ int ReadDelimitedText( wxString* aDest, const char* aSource );
 std::string EscapedUTF8( const wxString& aString );
 
 /**
+ * Return a new wxString escaped for embedding in HTML.
+ */
+wxString EscapedHTML( const wxString& aString );
+
+/**
  * Function GetLine
  * reads one line line from \a aFile.
  * @return A pointer the first useful line read by eliminating blank lines and comments.
-- 
2.11.1


Follow ups