← Back to team overview

kicad-developers team mailing list archive

Re: 3D filename resolution

 

The attached patch makes the following changes:

1. Adds a Help button and text to the 3D alias configuration dialog
2. Displays KISYS3DMOD and internally defined KiCad path env vars
3. Adds a button to bring up the "Configure Paths" (env vars) dialog
4. Removes the file name mapping feature from the resolver; this results in
    the resolver always using the current definition rather than a possibly
    outdated cache value.

I'm not too happy with the visual appearance; any feedback would be welcome.

- Cirilo

On Thu, Jun 9, 2016 at 3:58 PM, jp charras <jp.charras@xxxxxxxxxx> wrote:

> Le 30/05/2016 à 10:56, Cirilo Bernardo a écrit :
> > Attached is an updated patch made against r6854.  A patch to fix Bug
> > #1585714 prevented the previous patch from applying cleanly.
> >
> > - Cirilo
> >
> >
>
> Hi, Cirilo,
>
> I committed your patch in rev 6905. Thanks.
>
> After playing with your 3D path config dialog, I am thinking it needs 2
> enhancements:
>
> - A help button to display info about aliases meaning and usage (with an
> example), like the help
> button in path configuration dialog
> - At least display the KISYS3DMOD env variable value, which is used
> (explicitly or implicitly) in 3D
> path resolution
>
> Could you add them?
> Thanks.
>
> --
> Jean-Pierre CHARRAS
>
=== modified file '3d-viewer/3d_cache/3d_filename_resolver.cpp'
--- 3d-viewer/3d_cache/3d_filename_resolver.cpp	2016-06-09 05:48:49 +0000
+++ 3d-viewer/3d_cache/3d_filename_resolver.cpp	2016-06-12 00:47:46 +0000
@@ -109,7 +109,6 @@
         al.m_pathvar = "${KIPRJMOD}";
         al.m_pathexp = m_curProjDir;
         m_Paths.push_back( al );
-        m_NameMap.clear();
 
         if( flgChanged )
             *flgChanged = true;
@@ -120,7 +119,6 @@
         if( m_Paths.front().m_pathexp.Cmp( m_curProjDir ) )
         {
             m_Paths.front().m_pathexp = m_curProjDir;
-            m_NameMap.clear();
 
             if( flgChanged )
                 *flgChanged = true;
@@ -185,85 +183,35 @@
     m_Paths.push_back( lpath );
     wxFileName fndummy;
     wxUniChar psep = fndummy.GetPathSeparator();
-    bool hasKISYS3DMOD = false;
+    std::list< wxString > epaths;
 
-    // iterate over the list of internally defined ENV VARs
-    // and add existing paths to the resolver
-    if( m_pgm )
+    if( GetKicadPaths( epaths ) )
     {
-        ENV_VAR_MAP_CITER mS = m_pgm->GetLocalEnvVariables().begin();
-        ENV_VAR_MAP_CITER mE = m_pgm->GetLocalEnvVariables().end();
-
-        while( mS != mE )
+        for( auto i : epaths )
         {
-            // filter out URLs, template directories, and known system paths
-            if( mS->first == wxString( "KICAD_PTEMPLATES" )
-                || mS->first == wxString( "KIGITHUB" )
-                || mS->first == wxString( "KISYSMOD" ) )
-            {
-                ++mS;
-                continue;
-            }
-
-            if( wxString::npos != mS->second.GetValue().find( wxString( "://" ) ) )
-            {
-                ++mS;
-                continue;
-            }
-
-            // ensure system ENV VARs supercede internally defined vars
-            wxString tmp( "${" );
-            tmp.Append( mS->first );
-            tmp.Append( "}" );
-            wxString pathVal = ExpandEnvVarSubstitutions( tmp );
+            wxString pathVal = ExpandEnvVarSubstitutions( i );
 
             if( pathVal.empty() )
             {
-                pathVal = mS->second.GetValue();
-
-                if( pathVal.StartsWith( "${" ) || pathVal.StartsWith( "$(" ) )
-                    pathVal = ExpandEnvVarSubstitutions( pathVal );
-            }
-
-            fndummy.Assign( pathVal, "" );
-            fndummy.Normalize();
-
-            if( tmp == "${KISYS3DMOD}" )
-                hasKISYS3DMOD = true;
-
-            lpath.m_alias =  tmp;
-            lpath.m_pathvar = tmp;
-            lpath.m_pathexp = fndummy.GetFullPath();
+                lpath.m_pathexp.clear();
+            }
+            else
+            {
+                fndummy.Assign( pathVal, "" );
+                fndummy.Normalize();
+                lpath.m_pathexp = fndummy.GetFullPath();
+            }
+
+            lpath.m_alias =  i;
+            lpath.m_pathvar = i;
 
             if( !lpath.m_pathexp.empty() && psep == *lpath.m_pathexp.rbegin() )
                 lpath.m_pathexp.erase( --lpath.m_pathexp.end() );
 
             m_Paths.push_back( lpath );
-
-            ++mS;
         }
     }
 
-    // special case: if KISYSMOD is not internally defined but is defined by
-    // the system, then create an entry here
-    wxString envar = ExpandEnvVarSubstitutions( "${KISYS3DMOD}" );
-
-    if( !hasKISYS3DMOD && !envar.empty() )
-    {
-        lpath.m_alias = "${KISYS3DMOD}";
-        lpath.m_pathvar = "${KISYS3DMOD}";
-        fndummy.Assign( envar, "" );
-        fndummy.Normalize();
-        lpath.m_pathexp = fndummy.GetFullPath();
-
-        if( !lpath.m_pathexp.empty() && psep == *lpath.m_pathexp.rbegin() )
-            lpath.m_pathexp.erase( --lpath.m_pathexp.end() );
-
-        if( !lpath.m_pathexp.empty() )
-            m_Paths.push_back( lpath );
-
-    }
-
     if( !m_ConfigDir.empty() )
         readPathList();
 
@@ -277,7 +225,8 @@
 
     while( sPL != ePL )
     {
-        wxLogTrace( MASK_3D_RESOLVER, "   + '%s'\n", (*sPL).m_pathexp.ToUTF8() );
+        wxLogTrace( MASK_3D_RESOLVER, "   + %s : '%s'\n", (*sPL).m_alias.ToUTF8(),
+            (*sPL).m_pathexp.ToUTF8() );
         ++sPL;
     }
 #endif
@@ -312,13 +261,6 @@
     if( m_Paths.empty() )
         createPathList();
 
-    // look up the filename in the internal filename map
-    std::map< wxString, wxString, S3D::rsort_wxString >::iterator mi;
-    mi = m_NameMap.find( aFileName );
-
-    if( mi != m_NameMap.end() )
-        return mi->second;
-
     // first attempt to use the name as specified:
     wxString tname = aFileName;
 
@@ -332,7 +274,7 @@
     // wxFileName::Normalize() routine to perform expansion then
     // we will have a race condition since wxWidgets does not assure
     // a threadsafe wrapper for getenv().
-    if( tname.StartsWith( wxT( "${" ) ) || tname.StartsWith( wxT( "$(" ) ) )
+    if( tname.StartsWith( "${" ) || tname.StartsWith( "$(" ) )
         tname = ExpandEnvVarSubstitutions( tname );
 
     wxFileName tmpFN( tname );
@@ -356,10 +298,9 @@
     {
         tmpFN.Normalize();
         tname = tmpFN.GetFullPath();
-        m_NameMap.insert( std::pair< wxString, wxString > ( aFileName, tname ) );
 
         // special case: if a path begins with ${ENV_VAR} but is not in the
-        // resolver's path list then add it
+        // resolver's path list then add it.
         if( aFileName.StartsWith( "${" ) || aFileName.StartsWith( "$(" ) )
             checkEnvVarPath( aFileName );
 
@@ -409,8 +350,6 @@
             tmpFN.Assign( fullPath );
             tmpFN.Normalize();
             tname = tmpFN.GetFullPath();
-            m_NameMap.insert( std::pair< wxString, wxString > ( aFileName, tname ) );
-
             return tname;
         }
 
@@ -429,7 +368,6 @@
         if( fpath.Normalize() && fpath.FileExists() )
         {
             tname = fpath.GetFullPath();
-            m_NameMap.insert( std::pair< wxString, wxString > ( aFileName, tname ) );
             return tname;
         }
 
@@ -477,7 +415,6 @@
                 if( tmp.Normalize() )
                     tname = tmp.GetFullPath();
 
-                m_NameMap.insert( std::pair< wxString, wxString > ( aFileName, tname ) );
                 return tname;
             }
         }
@@ -869,7 +806,26 @@
             continue;
         }
 
-        wxFileName fpath( sL->m_pathexp, wxT( "" ) );
+        wxFileName fpath;
+
+        // in the case of aliases, ensure that we use the most recent definition
+        if( sL->m_alias.StartsWith( "${" ) || sL->m_alias.StartsWith( "$(" ) )
+        {
+            wxString tpath = ExpandEnvVarSubstitutions( sL->m_alias );
+
+            if( tpath.empty() )
+            {
+                ++sL;
+                continue;
+            }
+
+            fpath.Assign( tpath, wxT( "" ) );
+        }
+        else
+        {
+            fpath.Assign( sL->m_pathexp, wxT( "" ) );
+        }
+
         wxString fps = fpath.GetPathWithSep();
         wxString tname;
 
@@ -1100,3 +1056,53 @@
 
     return true;
 }
+
+
+bool S3D_FILENAME_RESOLVER::GetKicadPaths( std::list< wxString >& paths )
+{
+    paths.clear();
+
+    if( !m_pgm )
+        return false;
+
+    bool hasKisys3D = false;
+
+
+    // iterate over the list of internally defined ENV VARs
+    // and add them to the paths list
+    ENV_VAR_MAP_CITER mS = m_pgm->GetLocalEnvVariables().begin();
+    ENV_VAR_MAP_CITER mE = m_pgm->GetLocalEnvVariables().end();
+
+    while( mS != mE )
+    {
+        // filter out URLs, template directories, and known system paths
+        if( mS->first == wxString( "KICAD_PTEMPLATES" )
+            || mS->first == wxString( "KIGITHUB" )
+            || mS->first == wxString( "KISYSMOD" ) )
+        {
+            ++mS;
+            continue;
+        }
+
+        if( wxString::npos != mS->second.GetValue().find( wxString( "://" ) ) )
+        {
+            ++mS;
+            continue;
+        }
+
+        wxString tmp( "${" );
+        tmp.Append( mS->first );
+        tmp.Append( "}" );
+        paths.push_back( tmp );
+
+        if( tmp == "${KISYS3DMOD}" )
+            hasKisys3D = true;
+
+        ++mS;
+    }
+
+    if( !hasKisys3D )
+        paths.push_back( "${KISYS3DMOD}" );
+
+    return true;
+}

=== modified file '3d-viewer/3d_cache/3d_filename_resolver.h'
--- 3d-viewer/3d_cache/3d_filename_resolver.h	2016-06-09 05:48:49 +0000
+++ 3d-viewer/3d_cache/3d_filename_resolver.h	2016-06-11 23:47:05 +0000
@@ -54,8 +54,6 @@
 private:
     wxString m_ConfigDir;           // 3D configuration directory
     std::list< S3D_ALIAS > m_Paths; // list of base paths to search from
-    // mapping of (short) file names to resolved names
-    std::map< wxString, wxString, S3D::rsort_wxString > m_NameMap;
     int m_errflags;
     PGM_BASE* m_pgm;
     wxString m_curProjDir;
@@ -192,6 +190,14 @@
      * If the path contains an alias then hasAlias is set true.
      */
     bool ValidateFileName( const wxString& aFileName, bool& hasAlias );
+
+    /**
+     * Function GetKicadPaths
+     * returns a list of path environment variables local to Kicad;
+     * this list always includes KISYS3DMOD even if it is not
+     * defined locally.
+     */
+    bool GetKicadPaths( std::list< wxString >& paths );
 };
 
 #endif  // FILENAME_RESOLVER_3D_H

=== modified file '3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig.cpp'
--- 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig.cpp	2016-06-09 05:48:49 +0000
+++ 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig.cpp	2016-06-12 02:19:18 +0000
@@ -23,6 +23,8 @@
 
 
 #include <wx/msgdlg.h>
+#include <pgm_base.h>
+#include <html_messagebox.h>
 #include "3d_cache/dialogs/dlg_3d_pathconfig.h"
 #include "3d_cache/3d_filename_resolver.h"
 
@@ -42,8 +44,16 @@
 	m_Aliases->SetColSize( 1, 300 );
 	m_Aliases->SetColSize( 2, 120 );
 
+    m_EnvVars->SetColMinimalWidth( 0, 80 );
+    m_EnvVars->SetColMinimalWidth( 1, 300 );
+    m_EnvVars->SetColMinimalAcceptableWidth( 80 );
+    m_EnvVars->SetColSize( 0, 80 );
+    m_EnvVars->SetColSize( 1, 300 );
+
     if( m_resolver )
     {
+        updateEnvVars();
+
         // prohibit these characters in the alias names: []{}()%~<>"='`;:.,&?/\|$
         m_aliasValidator.SetStyle( wxFILTER_EXCLUDE_CHAR_LIST );
         m_aliasValidator.SetCharExcludes( wxT( "{}[]()%~<>\"='`;:.,&?/\\|$" ) );
@@ -290,3 +300,73 @@
 
     event.Skip();
 }
+
+
+void DLG_3D_PATH_CONFIG::OnConfigEnvVar( wxCommandEvent& event )
+{
+    Pgm().ConfigurePaths( this );
+    updateEnvVars();
+    event.Skip();
+}
+
+
+void DLG_3D_PATH_CONFIG::updateEnvVars( void )
+{
+    if( !m_resolver )
+        return;
+
+    std::list< wxString > epaths;
+
+    m_resolver->GetKicadPaths( epaths );
+    size_t nitems = epaths.size();
+    size_t nrows = m_EnvVars->GetNumberRows();
+
+    if( nrows > nitems )
+    {
+        size_t ni = nrows - nitems;
+        m_EnvVars->DeleteRows( 0, ni );
+    }
+    else if( nrows < nitems )
+    {
+        size_t ni = nitems - nrows;
+        m_EnvVars->InsertRows( 0, ni );
+    }
+
+    int j = 0;
+
+    for( auto i : epaths )
+    {
+        wxString val = ExpandEnvVarSubstitutions( i );
+        m_EnvVars->SetCellValue( j, 0, i );
+        m_EnvVars->SetCellValue( j, 1, val );
+        m_EnvVars->SetReadOnly( j, 0, true );
+        m_EnvVars->SetReadOnly( j, 1, true );
+        wxGridCellAttr* ap = m_EnvVars->GetOrCreateCellAttr( j, 0 );
+        ap->SetReadOnly( true );
+        ap->SetBackgroundColour( *wxLIGHT_GREY );
+        m_EnvVars->SetRowAttr( j, ap );
+        ++j;
+    }
+
+    m_EnvVars->AutoSize();
+
+    return;
+}
+
+
+void DLG_3D_PATH_CONFIG::OnHelp( wxCommandEvent& event )
+{
+    wxString msg = _( "Enter the name and path for each 3D alias variable.  KiCad "
+                      "environment variables and their values are shown for "
+                      "reference only and cannot be edited. " );
+    msg << "<br><br><b>";
+    msg << _( "Alias names may not contain any of the characters " );
+    msg << "{}[]()%~<>\"='`;:.,&?/\\|$";
+    msg << "</b>";
+
+    HTML_MESSAGE_BOX dlg( GetParent(), _( "Environment Variable Help" ) );
+    dlg.AddHTML_Text( msg );
+    dlg.ShowModal();
+
+    event.Skip();
+}

=== modified file '3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig.h'
--- 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig.h	2016-01-18 05:59:06 +0000
+++ 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig.h	2016-06-12 02:14:16 +0000
@@ -41,10 +41,15 @@
     void OnDelAlias( wxCommandEvent& event );
     void OnAliasMoveUp( wxCommandEvent& event );
     void OnAliasMoveDown( wxCommandEvent& event );
+    void OnConfigEnvVar( wxCommandEvent& event );
+    void OnHelp( wxCommandEvent& event );
 
 public:
     DLG_3D_PATH_CONFIG( wxWindow* aParent, S3D_FILENAME_RESOLVER* aResolver );
     bool TransferDataFromWindow();
+
+private:
+    void updateEnvVars( void );
 };
 
 #endif  // DLG_3D_PATHCONFIG_H

=== modified file '3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig_base.cpp'
--- 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig_base.cpp	2016-05-28 09:33:20 +0000
+++ 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig_base.cpp	2016-06-12 02:00:36 +0000
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version May 21 2016)
+// C++ code generated with wxFormBuilder (version Mar  2 2016)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -12,22 +12,56 @@
 DLG_3D_PATH_CONFIG_BASE::DLG_3D_PATH_CONFIG_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
 {
 	this->SetSizeHints( wxSize( 600,150 ), wxDefaultSize );
-
+	
 	wxBoxSizer* bSizerMain;
 	bSizerMain = new wxBoxSizer( wxVERTICAL );
-
+	
+	wxBoxSizer* bSizer5;
+	bSizer5 = new wxBoxSizer( wxHORIZONTAL );
+	
+	m_EnvVars = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
+	
+	// Grid
+	m_EnvVars->CreateGrid( 0, 2 );
+	m_EnvVars->EnableEditing( true );
+	m_EnvVars->EnableGridLines( true );
+	m_EnvVars->EnableDragGridSize( false );
+	m_EnvVars->SetMargins( 0, 0 );
+	
+	// Columns
+	m_EnvVars->EnableDragColMove( false );
+	m_EnvVars->EnableDragColSize( true );
+	m_EnvVars->SetColLabelSize( 30 );
+	m_EnvVars->SetColLabelValue( 0, _("Env Var") );
+	m_EnvVars->SetColLabelValue( 1, _("Path") );
+	m_EnvVars->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+	
+	// Rows
+	m_EnvVars->EnableDragRowSize( true );
+	m_EnvVars->SetRowLabelSize( 80 );
+	m_EnvVars->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
+	
+	// Label Appearance
+	
+	// Cell Defaults
+	m_EnvVars->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
+	bSizer5->Add( m_EnvVars, 0, wxALL, 5 );
+	
+	
+	bSizerMain->Add( bSizer5, 1, wxEXPAND, 5 );
+	
 	wxBoxSizer* bSizerGrid;
 	bSizerGrid = new wxBoxSizer( wxHORIZONTAL );
-
+	
 	m_Aliases = new wxGrid( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
-
+	
 	// Grid
 	m_Aliases->CreateGrid( 1, 3 );
 	m_Aliases->EnableEditing( true );
 	m_Aliases->EnableGridLines( true );
 	m_Aliases->EnableDragGridSize( false );
 	m_Aliases->SetMargins( 0, 0 );
-
+	
 	// Columns
 	m_Aliases->SetColSize( 0, 80 );
 	m_Aliases->SetColSize( 1, 300 );
@@ -39,60 +73,70 @@
 	m_Aliases->SetColLabelValue( 1, _("Path") );
 	m_Aliases->SetColLabelValue( 2, _("Description") );
 	m_Aliases->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
-
+	
 	// Rows
 	m_Aliases->AutoSizeRows();
 	m_Aliases->EnableDragRowSize( false );
 	m_Aliases->SetRowLabelSize( 80 );
 	m_Aliases->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
-
+	
 	// Label Appearance
-
+	
 	// Cell Defaults
 	m_Aliases->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
 	bSizerGrid->Add( m_Aliases, 1, wxALL|wxEXPAND, 5 );
-
-
+	
+	
 	bSizerMain->Add( bSizerGrid, 1, wxEXPAND, 5 );
-
+	
 	m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
 	bSizerMain->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
-
+	
 	wxBoxSizer* bSizerButtons;
 	bSizerButtons = new wxBoxSizer( wxHORIZONTAL );
-
+	
 	m_btnAddAlias = new wxButton( this, wxID_ANY, _("Add Alias"), wxDefaultPosition, wxDefaultSize, 0 );
 	bSizerButtons->Add( m_btnAddAlias, 0, wxALL, 5 );
-
+	
 	m_btnDelAlias = new wxButton( this, wxID_ANY, _("Remove Alias"), wxDefaultPosition, wxDefaultSize, 0 );
 	bSizerButtons->Add( m_btnDelAlias, 0, wxALL, 5 );
-
+	
 	m_btnMoveUp = new wxButton( this, wxID_ANY, _("Move Up"), wxDefaultPosition, wxDefaultSize, 0 );
 	bSizerButtons->Add( m_btnMoveUp, 0, wxALL, 5 );
-
+	
 	m_btnMoveDown = new wxButton( this, wxID_ANY, _("Move Down"), wxDefaultPosition, wxDefaultSize, 0 );
 	bSizerButtons->Add( m_btnMoveDown, 0, wxALL, 5 );
-
-	m_btnOK = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 );
-	bSizerButtons->Add( m_btnOK, 0, wxALL, 5 );
-
-	m_btnCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
-	bSizerButtons->Add( m_btnCancel, 0, wxALL, 5 );
-
-
-	bSizerMain->Add( bSizerButtons, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 );
-
-
+	
+	m_btnEnvCfg = new wxButton( this, wxID_ANY, _("Config Env"), wxDefaultPosition, wxDefaultSize, 0 );
+	bSizerButtons->Add( m_btnEnvCfg, 0, wxALL, 5 );
+	
+	
+	bSizerMain->Add( bSizerButtons, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
+	
+	m_sdbSizer2 = new wxStdDialogButtonSizer();
+	m_sdbSizer2OK = new wxButton( this, wxID_OK );
+	m_sdbSizer2->AddButton( m_sdbSizer2OK );
+	m_sdbSizer2Cancel = new wxButton( this, wxID_CANCEL );
+	m_sdbSizer2->AddButton( m_sdbSizer2Cancel );
+	m_sdbSizer2Help = new wxButton( this, wxID_HELP );
+	m_sdbSizer2->AddButton( m_sdbSizer2Help );
+	m_sdbSizer2->Realize();
+	
+	bSizerMain->Add( m_sdbSizer2, 1, wxALIGN_CENTER, 5 );
+	
+	
 	this->SetSizer( bSizerMain );
 	this->Layout();
-
+	
 	this->Centre( wxBOTH );
-
+	
 	// Connect Events
 	m_btnAddAlias->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAddAlias ), NULL, this );
 	m_btnDelAlias->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnDelAlias ), NULL, this );
 	m_btnMoveUp->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAliasMoveUp ), NULL, this );
 	m_btnMoveDown->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAliasMoveDown ), NULL, this );
+	m_btnEnvCfg->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnConfigEnvVar ), NULL, this );
+	m_sdbSizer2Help->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnHelp ), NULL, this );
 }
 
 DLG_3D_PATH_CONFIG_BASE::~DLG_3D_PATH_CONFIG_BASE()
@@ -102,5 +146,7 @@
 	m_btnDelAlias->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnDelAlias ), NULL, this );
 	m_btnMoveUp->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAliasMoveUp ), NULL, this );
 	m_btnMoveDown->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnAliasMoveDown ), NULL, this );
-
+	m_btnEnvCfg->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnConfigEnvVar ), NULL, this );
+	m_sdbSizer2Help->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DLG_3D_PATH_CONFIG_BASE::OnHelp ), NULL, this );
+	
 }

=== modified file '3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig_base.fbp'
--- 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig_base.fbp	2016-05-28 09:33:20 +0000
+++ 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig_base.fbp	2016-06-12 02:00:36 +0000
@@ -44,7 +44,7 @@
             <property name="minimum_size">600,150</property>
             <property name="name">DLG_3D_PATH_CONFIG_BASE</property>
             <property name="pos"></property>
-            <property name="size">619,160</property>
+            <property name="size">619,319</property>
             <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
             <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
             <property name="title">3D Search Path Configuration</property>
@@ -98,6 +98,160 @@
                     <property name="flag">wxEXPAND</property>
                     <property name="proportion">1</property>
                     <object class="wxBoxSizer" expanded="1">
+                        <property name="minimum_size"></property>
+                        <property name="name">bSizer5</property>
+                        <property name="orient">wxHORIZONTAL</property>
+                        <property name="permission">none</property>
+                        <object class="sizeritem" expanded="1">
+                            <property name="border">5</property>
+                            <property name="flag">wxALL</property>
+                            <property name="proportion">0</property>
+                            <object class="wxGrid" expanded="1">
+                                <property name="BottomDockable">1</property>
+                                <property name="LeftDockable">1</property>
+                                <property name="RightDockable">1</property>
+                                <property name="TopDockable">1</property>
+                                <property name="aui_layer"></property>
+                                <property name="aui_name"></property>
+                                <property name="aui_position"></property>
+                                <property name="aui_row"></property>
+                                <property name="autosize_cols">0</property>
+                                <property name="autosize_rows">0</property>
+                                <property name="best_size"></property>
+                                <property name="bg"></property>
+                                <property name="caption"></property>
+                                <property name="caption_visible">1</property>
+                                <property name="cell_bg"></property>
+                                <property name="cell_font"></property>
+                                <property name="cell_horiz_alignment">wxALIGN_LEFT</property>
+                                <property name="cell_text"></property>
+                                <property name="cell_vert_alignment">wxALIGN_TOP</property>
+                                <property name="center_pane">0</property>
+                                <property name="close_button">1</property>
+                                <property name="col_label_horiz_alignment">wxALIGN_CENTRE</property>
+                                <property name="col_label_size">30</property>
+                                <property name="col_label_values">&quot;Env Var&quot; &quot;Path&quot;</property>
+                                <property name="col_label_vert_alignment">wxALIGN_CENTRE</property>
+                                <property name="cols">2</property>
+                                <property name="column_sizes"></property>
+                                <property name="context_help"></property>
+                                <property name="context_menu">1</property>
+                                <property name="default_pane">0</property>
+                                <property name="dock">Dock</property>
+                                <property name="dock_fixed">0</property>
+                                <property name="docking">Left</property>
+                                <property name="drag_col_move">0</property>
+                                <property name="drag_col_size">1</property>
+                                <property name="drag_grid_size">0</property>
+                                <property name="drag_row_size">1</property>
+                                <property name="editing">1</property>
+                                <property name="enabled">1</property>
+                                <property name="fg"></property>
+                                <property name="floatable">1</property>
+                                <property name="font"></property>
+                                <property name="grid_line_color"></property>
+                                <property name="grid_lines">1</property>
+                                <property name="gripper">0</property>
+                                <property name="hidden">0</property>
+                                <property name="id">wxID_ANY</property>
+                                <property name="label_bg"></property>
+                                <property name="label_font"></property>
+                                <property name="label_text"></property>
+                                <property name="margin_height">0</property>
+                                <property name="margin_width">0</property>
+                                <property name="max_size"></property>
+                                <property name="maximize_button">0</property>
+                                <property name="maximum_size"></property>
+                                <property name="min_size"></property>
+                                <property name="minimize_button">0</property>
+                                <property name="minimum_size"></property>
+                                <property name="moveable">1</property>
+                                <property name="name">m_EnvVars</property>
+                                <property name="pane_border">1</property>
+                                <property name="pane_position"></property>
+                                <property name="pane_size"></property>
+                                <property name="permission">protected</property>
+                                <property name="pin_button">1</property>
+                                <property name="pos"></property>
+                                <property name="resize">Resizable</property>
+                                <property name="row_label_horiz_alignment">wxALIGN_CENTRE</property>
+                                <property name="row_label_size">80</property>
+                                <property name="row_label_values"></property>
+                                <property name="row_label_vert_alignment">wxALIGN_CENTRE</property>
+                                <property name="row_sizes"></property>
+                                <property name="rows">0</property>
+                                <property name="show">1</property>
+                                <property name="size"></property>
+                                <property name="subclass"></property>
+                                <property name="toolbar_pane">0</property>
+                                <property name="tooltip"></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="OnGridCellChange"></event>
+                                <event name="OnGridCellLeftClick"></event>
+                                <event name="OnGridCellLeftDClick"></event>
+                                <event name="OnGridCellRightClick"></event>
+                                <event name="OnGridCellRightDClick"></event>
+                                <event name="OnGridCmdCellChange"></event>
+                                <event name="OnGridCmdCellLeftClick"></event>
+                                <event name="OnGridCmdCellLeftDClick"></event>
+                                <event name="OnGridCmdCellRightClick"></event>
+                                <event name="OnGridCmdCellRightDClick"></event>
+                                <event name="OnGridCmdColSize"></event>
+                                <event name="OnGridCmdEditorCreated"></event>
+                                <event name="OnGridCmdEditorHidden"></event>
+                                <event name="OnGridCmdEditorShown"></event>
+                                <event name="OnGridCmdLabelLeftClick"></event>
+                                <event name="OnGridCmdLabelLeftDClick"></event>
+                                <event name="OnGridCmdLabelRightClick"></event>
+                                <event name="OnGridCmdLabelRightDClick"></event>
+                                <event name="OnGridCmdRangeSelect"></event>
+                                <event name="OnGridCmdRowSize"></event>
+                                <event name="OnGridCmdSelectCell"></event>
+                                <event name="OnGridColSize"></event>
+                                <event name="OnGridEditorCreated"></event>
+                                <event name="OnGridEditorHidden"></event>
+                                <event name="OnGridEditorShown"></event>
+                                <event name="OnGridLabelLeftClick"></event>
+                                <event name="OnGridLabelLeftDClick"></event>
+                                <event name="OnGridLabelRightClick"></event>
+                                <event name="OnGridLabelRightDClick"></event>
+                                <event name="OnGridRangeSelect"></event>
+                                <event name="OnGridRowSize"></event>
+                                <event name="OnGridSelectCell"></event>
+                                <event name="OnKeyDown"></event>
+                                <event name="OnKeyUp"></event>
+                                <event name="OnKillFocus"></event>
+                                <event name="OnLeaveWindow"></event>
+                                <event name="OnLeftDClick"></event>
+                                <event name="OnLeftDown"></event>
+                                <event name="OnLeftUp"></event>
+                                <event name="OnMiddleDClick"></event>
+                                <event name="OnMiddleDown"></event>
+                                <event name="OnMiddleUp"></event>
+                                <event name="OnMotion"></event>
+                                <event name="OnMouseEvents"></event>
+                                <event name="OnMouseWheel"></event>
+                                <event name="OnPaint"></event>
+                                <event name="OnRightDClick"></event>
+                                <event name="OnRightDown"></event>
+                                <event name="OnRightUp"></event>
+                                <event name="OnSetFocus"></event>
+                                <event name="OnSize"></event>
+                                <event name="OnUpdateUI"></event>
+                            </object>
+                        </object>
+                    </object>
+                </object>
+                <object class="sizeritem" expanded="1">
+                    <property name="border">5</property>
+                    <property name="flag">wxEXPAND</property>
+                    <property name="proportion">1</property>
+                    <object class="wxBoxSizer" expanded="1">
                         <property name="minimum_size">-1,-1</property>
                         <property name="name">bSizerGrid</property>
                         <property name="orient">wxHORIZONTAL</property>
@@ -330,7 +484,7 @@
                 </object>
                 <object class="sizeritem" expanded="1">
                     <property name="border">5</property>
-                    <property name="flag">wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT</property>
+                    <property name="flag">wxALIGN_CENTER_HORIZONTAL</property>
                     <property name="proportion">0</property>
                     <object class="wxBoxSizer" expanded="1">
                         <property name="minimum_size"></property>
@@ -721,150 +875,88 @@
                                 <property name="font"></property>
                                 <property name="gripper">0</property>
                                 <property name="hidden">0</property>
-                                <property name="id">wxID_OK</property>
-                                <property name="label">OK</property>
-                                <property name="max_size"></property>
-                                <property name="maximize_button">0</property>
-                                <property name="maximum_size"></property>
-                                <property name="min_size"></property>
-                                <property name="minimize_button">0</property>
-                                <property name="minimum_size"></property>
-                                <property name="moveable">1</property>
-                                <property name="name">m_btnOK</property>
-                                <property name="pane_border">1</property>
-                                <property name="pane_position"></property>
-                                <property name="pane_size"></property>
-                                <property name="permission">protected</property>
-                                <property name="pin_button">1</property>
-                                <property name="pos"></property>
-                                <property name="resize">Resizable</property>
-                                <property name="show">1</property>
-                                <property name="size"></property>
-                                <property name="style"></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="window_extra_style"></property>
-                                <property name="window_name"></property>
-                                <property name="window_style"></property>
-                                <event name="OnButtonClick"></event>
-                                <event name="OnChar"></event>
-                                <event name="OnEnterWindow"></event>
-                                <event name="OnEraseBackground"></event>
-                                <event name="OnKeyDown"></event>
-                                <event name="OnKeyUp"></event>
-                                <event name="OnKillFocus"></event>
-                                <event name="OnLeaveWindow"></event>
-                                <event name="OnLeftDClick"></event>
-                                <event name="OnLeftDown"></event>
-                                <event name="OnLeftUp"></event>
-                                <event name="OnMiddleDClick"></event>
-                                <event name="OnMiddleDown"></event>
-                                <event name="OnMiddleUp"></event>
-                                <event name="OnMotion"></event>
-                                <event name="OnMouseEvents"></event>
-                                <event name="OnMouseWheel"></event>
-                                <event name="OnPaint"></event>
-                                <event name="OnRightDClick"></event>
-                                <event name="OnRightDown"></event>
-                                <event name="OnRightUp"></event>
-                                <event name="OnSetFocus"></event>
-                                <event name="OnSize"></event>
-                                <event name="OnUpdateUI"></event>
-                            </object>
-                        </object>
-                        <object class="sizeritem" expanded="1">
-                            <property name="border">5</property>
-                            <property name="flag">wxALL</property>
-                            <property name="proportion">0</property>
-                            <object class="wxButton" expanded="1">
-                                <property name="BottomDockable">1</property>
-                                <property name="LeftDockable">1</property>
-                                <property name="RightDockable">1</property>
-                                <property name="TopDockable">1</property>
-                                <property name="aui_layer"></property>
-                                <property name="aui_name"></property>
-                                <property name="aui_position"></property>
-                                <property name="aui_row"></property>
-                                <property name="best_size"></property>
-                                <property name="bg"></property>
-                                <property name="caption"></property>
-                                <property name="caption_visible">1</property>
-                                <property name="center_pane">0</property>
-                                <property name="close_button">1</property>
-                                <property name="context_help"></property>
-                                <property name="context_menu">1</property>
-                                <property name="default">0</property>
-                                <property name="default_pane">0</property>
-                                <property name="dock">Dock</property>
-                                <property name="dock_fixed">0</property>
-                                <property name="docking">Left</property>
-                                <property name="enabled">1</property>
-                                <property name="fg"></property>
-                                <property name="floatable">1</property>
-                                <property name="font"></property>
-                                <property name="gripper">0</property>
-                                <property name="hidden">0</property>
-                                <property name="id">wxID_CANCEL</property>
-                                <property name="label">Cancel</property>
-                                <property name="max_size"></property>
-                                <property name="maximize_button">0</property>
-                                <property name="maximum_size"></property>
-                                <property name="min_size"></property>
-                                <property name="minimize_button">0</property>
-                                <property name="minimum_size"></property>
-                                <property name="moveable">1</property>
-                                <property name="name">m_btnCancel</property>
-                                <property name="pane_border">1</property>
-                                <property name="pane_position"></property>
-                                <property name="pane_size"></property>
-                                <property name="permission">protected</property>
-                                <property name="pin_button">1</property>
-                                <property name="pos"></property>
-                                <property name="resize">Resizable</property>
-                                <property name="show">1</property>
-                                <property name="size"></property>
-                                <property name="style"></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="window_extra_style"></property>
-                                <property name="window_name"></property>
-                                <property name="window_style"></property>
-                                <event name="OnButtonClick"></event>
-                                <event name="OnChar"></event>
-                                <event name="OnEnterWindow"></event>
-                                <event name="OnEraseBackground"></event>
-                                <event name="OnKeyDown"></event>
-                                <event name="OnKeyUp"></event>
-                                <event name="OnKillFocus"></event>
-                                <event name="OnLeaveWindow"></event>
-                                <event name="OnLeftDClick"></event>
-                                <event name="OnLeftDown"></event>
-                                <event name="OnLeftUp"></event>
-                                <event name="OnMiddleDClick"></event>
-                                <event name="OnMiddleDown"></event>
-                                <event name="OnMiddleUp"></event>
-                                <event name="OnMotion"></event>
-                                <event name="OnMouseEvents"></event>
-                                <event name="OnMouseWheel"></event>
-                                <event name="OnPaint"></event>
-                                <event name="OnRightDClick"></event>
-                                <event name="OnRightDown"></event>
-                                <event name="OnRightUp"></event>
-                                <event name="OnSetFocus"></event>
-                                <event name="OnSize"></event>
-                                <event name="OnUpdateUI"></event>
-                            </object>
-                        </object>
+                                <property name="id">wxID_ANY</property>
+                                <property name="label">Config Env</property>
+                                <property name="max_size"></property>
+                                <property name="maximize_button">0</property>
+                                <property name="maximum_size"></property>
+                                <property name="min_size"></property>
+                                <property name="minimize_button">0</property>
+                                <property name="minimum_size"></property>
+                                <property name="moveable">1</property>
+                                <property name="name">m_btnEnvCfg</property>
+                                <property name="pane_border">1</property>
+                                <property name="pane_position"></property>
+                                <property name="pane_size"></property>
+                                <property name="permission">protected</property>
+                                <property name="pin_button">1</property>
+                                <property name="pos"></property>
+                                <property name="resize">Resizable</property>
+                                <property name="show">1</property>
+                                <property name="size"></property>
+                                <property name="style"></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="window_extra_style"></property>
+                                <property name="window_name"></property>
+                                <property name="window_style"></property>
+                                <event name="OnButtonClick">OnConfigEnvVar</event>
+                                <event name="OnChar"></event>
+                                <event name="OnEnterWindow"></event>
+                                <event name="OnEraseBackground"></event>
+                                <event name="OnKeyDown"></event>
+                                <event name="OnKeyUp"></event>
+                                <event name="OnKillFocus"></event>
+                                <event name="OnLeaveWindow"></event>
+                                <event name="OnLeftDClick"></event>
+                                <event name="OnLeftDown"></event>
+                                <event name="OnLeftUp"></event>
+                                <event name="OnMiddleDClick"></event>
+                                <event name="OnMiddleDown"></event>
+                                <event name="OnMiddleUp"></event>
+                                <event name="OnMotion"></event>
+                                <event name="OnMouseEvents"></event>
+                                <event name="OnMouseWheel"></event>
+                                <event name="OnPaint"></event>
+                                <event name="OnRightDClick"></event>
+                                <event name="OnRightDown"></event>
+                                <event name="OnRightUp"></event>
+                                <event name="OnSetFocus"></event>
+                                <event name="OnSize"></event>
+                                <event name="OnUpdateUI"></event>
+                            </object>
+                        </object>
+                    </object>
+                </object>
+                <object class="sizeritem" expanded="1">
+                    <property name="border">5</property>
+                    <property name="flag">wxALIGN_CENTER</property>
+                    <property name="proportion">1</property>
+                    <object class="wxStdDialogButtonSizer" expanded="1">
+                        <property name="Apply">0</property>
+                        <property name="Cancel">1</property>
+                        <property name="ContextHelp">0</property>
+                        <property name="Help">1</property>
+                        <property name="No">0</property>
+                        <property name="OK">1</property>
+                        <property name="Save">0</property>
+                        <property name="Yes">0</property>
+                        <property name="minimum_size"></property>
+                        <property name="name">m_sdbSizer2</property>
+                        <property name="permission">protected</property>
+                        <event name="OnApplyButtonClick"></event>
+                        <event name="OnCancelButtonClick"></event>
+                        <event name="OnContextHelpButtonClick"></event>
+                        <event name="OnHelpButtonClick">OnHelp</event>
+                        <event name="OnNoButtonClick"></event>
+                        <event name="OnOKButtonClick"></event>
+                        <event name="OnSaveButtonClick"></event>
+                        <event name="OnYesButtonClick"></event>
                     </object>
                 </object>
             </object>

=== modified file '3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig_base.h'
--- 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig_base.h	2016-05-28 09:33:20 +0000
+++ 3d-viewer/3d_cache/dialogs/dlg_3d_pathconfig_base.h	2016-06-12 02:00:36 +0000
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version May 21 2016)
+// C++ code generated with wxFormBuilder (version Mar  2 2016)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -36,25 +36,31 @@
 	private:
 	
 	protected:
+		wxGrid* m_EnvVars;
 		wxGrid* m_Aliases;
 		wxStaticLine* m_staticline1;
 		wxButton* m_btnAddAlias;
 		wxButton* m_btnDelAlias;
 		wxButton* m_btnMoveUp;
 		wxButton* m_btnMoveDown;
-		wxButton* m_btnOK;
-		wxButton* m_btnCancel;
+		wxButton* m_btnEnvCfg;
+		wxStdDialogButtonSizer* m_sdbSizer2;
+		wxButton* m_sdbSizer2OK;
+		wxButton* m_sdbSizer2Cancel;
+		wxButton* m_sdbSizer2Help;
 		
 		// Virtual event handlers, overide them in your derived class
 		virtual void OnAddAlias( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnDelAlias( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnAliasMoveUp( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnAliasMoveDown( wxCommandEvent& event ) { event.Skip(); }
+		virtual void OnConfigEnvVar( wxCommandEvent& event ) { event.Skip(); }
+		virtual void OnHelp( wxCommandEvent& event ) { event.Skip(); }
 		
 	
 	public:
 		
-		DLG_3D_PATH_CONFIG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("3D Search Path Configuration"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 619,160 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); 
+		DLG_3D_PATH_CONFIG_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("3D Search Path Configuration"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 619,319 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); 
 		~DLG_3D_PATH_CONFIG_BASE();
 	
 };


Follow ups

References