Migrate CvPcb project parameters

This commit is contained in:
Jon Evans 2020-05-25 22:27:27 -04:00
parent a4fadfcdf2
commit 0e2f9cb1bd
16 changed files with 255 additions and 162 deletions

View File

@ -29,7 +29,6 @@
#include <wx/wupdlock.h>
#define LIST_COLUMN_WIDTH_KEY wxT( "SelectorColumnWidth" )
#define PINNED_ITEMS_KEY wxT( "PinnedItems" )
static const int kDataViewIndent = 20;
@ -91,9 +90,12 @@ LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent ) :
auto cfg = Kiface().KifaceSettings();
m_colWidths[PART_COL] = cfg->m_LibTree.column_width;
// TODO(JE) PROJECT
#if 0
// Read the pinned entries from the project config
m_parent->Kiway().Prj().ConfigLoad( Kiface().KifaceSearch(), m_parent->GetName(),
GetProjectFileParameters() );
#endif
}
@ -136,8 +138,11 @@ void LIB_TREE_MODEL_ADAPTER::SavePinnedItems()
m_pinnedLibs.push_back( child->m_LibId.GetLibNickname() );
}
// TODO(JE) PROJECT
#if 0
m_parent->Kiway().Prj().ConfigSave( Kiface().KifaceSearch(), m_parent->GetName(),
GetProjectFileParameters() );
#endif
}

View File

@ -186,20 +186,8 @@ const wxString PROJECT::GetSheetName( const KIID& aSheetID )
{
if( m_sheetNames.empty() )
{
std::unique_ptr<wxConfigBase> config( configCreate( SEARCH_STACK(), GROUP_SHEET_NAMES ) );
config->SetPath( GROUP_SHEET_NAMES );
int index = 1;
wxString entry;
while( config->Read( wxString::Format( "%d", index++ ), &entry ) )
{
wxArrayString tokens = wxSplit( entry, ':' );
if( tokens.size() == 2 )
m_sheetNames[ KIID( tokens[0] ) ] = tokens[1];
}
for( auto pair : GetProjectFile().GetSheets() )
m_sheetNames[pair.first] = pair.second;
}
if( m_sheetNames.count( aSheetID ) )

View File

@ -98,6 +98,18 @@ bool JSON_SETTINGS::LoadFromFile( const std::string& aDirectory )
LOCALE_IO locale;
auto migrateFromLegacy = [&] ( wxFileName& aPath ) {
// Backup and restore during migration so that the original can be mutated if convenient
wxFileName temp;
temp.AssignTempFileName( aPath.GetFullPath() );
bool backed_up = true;
if( !wxCopyFile( aPath.GetFullPath(), temp.GetFullPath() ) )
{
wxLogTrace( traceSettings, "%s: could not create temp file for migration", m_filename );
backed_up = false;
}
wxConfigBase::DontCreateOnDemand();
auto cfg = std::make_unique<wxFileConfig>( wxT( "" ), wxT( "" ), aPath.GetFullPath() );
@ -113,6 +125,13 @@ bool JSON_SETTINGS::LoadFromFile( const std::string& aDirectory )
wxLogTrace( traceSettings, "%s: migrated from legacy format", m_filename );
}
if( backed_up )
{
cfg.reset();
wxCopyFile( temp.GetFullPath(), aPath.GetFullPath() );
wxRemoveFile( temp.GetFullPath() );
}
// Either way, we want to clean up the old file afterwards
legacy_migrated = true;
};

View File

@ -42,6 +42,15 @@ PROJECT_FILE::PROJECT_FILE( const std::string& aFullPath ) :
m_params.emplace_back( new PARAM_LIST<FILE_INFO_PAIR>( "sheets", &m_sheets, {} ) );
m_params.emplace_back( new PARAM_LIST<FILE_INFO_PAIR>( "boards", &m_boards, {} ) );
m_params.emplace_back(
new PARAM_LIST<wxString>( "libraries.pinned_symbol_libs", &m_PinnedSymbolLibs, {} ) );
m_params.emplace_back( new PARAM_LIST<wxString>(
"libraries.pinned_footprint_libs", &m_PinnedFootprintLibs, {} ) );
m_params.emplace_back(
new PARAM_PATH_LIST( "cvpcb.equivalence_files", &m_EquivalenceFiles, {} ) );
}
@ -51,9 +60,67 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aLegacyFile )
wxString str;
long index = 0;
std::set<wxString> group_blacklist;
// Legacy files don't store board info; they assume board matches project name
// We will leave m_boards empty here so it can be populated with other code
// First handle migration of data that will be stored locally in this object
auto loadPinnedLibs =
[&]( const std::string& aDest )
{
int libIndex = 1;
wxString libKey = wxT( "PinnedItems" );
libKey << libIndex;
nlohmann::json libs = nlohmann::json::array();
while( aLegacyFile->Read( libKey, &str ) )
{
libs.push_back( str );
aLegacyFile->DeleteEntry( libKey, true );
libKey = wxT( "PinnedItems" );
libKey << ++libIndex;
}
( *this )[PointerFromString( aDest )] = libs;
};
aLegacyFile->SetPath( wxT( "/LibeditFrame" ) );
loadPinnedLibs( "libraries.pinned_symbol_libs" );
aLegacyFile->SetPath( wxT( "/ModEditFrame" ) );
loadPinnedLibs( "libraries.pinned_footprint_libs" );
aLegacyFile->SetPath( wxT( "/cvpcb/equfiles" ) );
{
int eqIdx = 1;
wxString eqKey = wxT( "EquName" );
eqKey << eqIdx;
nlohmann::json eqs = nlohmann::json::array();
while( aLegacyFile->Read( eqKey, &str ) )
{
eqs.push_back( str );
eqKey = wxT( "EquName" );
eqKey << ++eqIdx;
}
( *this )[PointerFromString( "cvpcb.equivalence_files" )] = eqs;
}
// No other cvpcb params are currently used
group_blacklist.insert( "/cvpcb" );
// Next load sheet names and put all other legacy data in the legacy dict
aLegacyFile->SetPath( "/" );
auto loadSheetNames =
[&]() -> bool
{
@ -63,7 +130,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aLegacyFile )
wxLogTrace( traceSettings, "Migrating sheet names" );
aLegacyFile->SetPath( GROUP_SHEET_NAMES );
aLegacyFile->SetPath( wxT( "/sheetnames" ) );
while( aLegacyFile->Read( wxString::Format( "%d", sheet++ ), &entry ) )
{
@ -76,7 +143,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aLegacyFile )
}
}
( *this )[PointerFromString( "sheets" )] = arr;
( *this )[PointerFromString( "sheets" )] = arr;
aLegacyFile->SetPath( "/" );
@ -86,13 +153,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aLegacyFile )
std::vector<wxString> groups;
while( aLegacyFile->GetNextGroup( str, index ) )
{
if( str == wxString( GROUP_SHEET_NAMES ).Mid( 1 ) )
ret |= loadSheetNames();
else
groups.emplace_back( "/" + str );
}
groups.emplace_back( "" );
auto loadLegacyPairs =
[&]( const std::string& aGroup ) -> bool
@ -127,18 +188,31 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aLegacyFile )
return success;
};
ret &= loadLegacyPairs( "" );
for( size_t i = 0; i < groups.size(); i++ )
{
aLegacyFile->SetPath( groups[i] );
if( groups[i] == wxT( "/sheetnames" ) )
{
ret |= loadSheetNames();
continue;
}
aLegacyFile->DeleteEntry( wxT( "last_client" ), true );
aLegacyFile->DeleteEntry( wxT( "update" ), true );
aLegacyFile->DeleteEntry( wxT( "version" ), true );
ret &= loadLegacyPairs( groups[i].ToStdString() );
index = 0;
while( aLegacyFile->GetNextGroup( str, index ) )
groups.emplace_back( groups[i] + "/" + str );
{
wxString group = groups[i] + "/" + str;
if( !group_blacklist.count( group ) )
groups.emplace_back( group );
}
aLegacyFile->SetPath( "/" );
}

View File

@ -28,7 +28,6 @@ set( CVPCB_SRCS
${CMAKE_SOURCE_DIR}/common/base_units.cpp
${CMAKE_SOURCE_DIR}/pcbnew/board_stackup_manager/stackup_predefined_prms.cpp
auto_associate.cpp
cfg.cpp
components_listbox.cpp
display_footprints_frame.cpp
footprints_listbox.cpp

View File

@ -39,6 +39,7 @@
#include <cvpcb_association.h>
#include <cvpcb_mainframe.h>
#include <listboxes.h>
#include <settings/project_file.h>
#define QUOTE '\''
@ -83,13 +84,14 @@ int CVPCB_MAINFRAME::buildEquivalenceList( FOOTPRINT_EQUIVALENCE_LIST& aList, wx
wxFileName fn;
wxString tmp, error_msg;
SEARCH_STACK& search = Kiface().KifaceSearch();
SEARCH_STACK& search = Kiface().KifaceSearch();
PROJECT_FILE& project = Prj().GetProjectFile();
// Find equivalences in all available files, and populates the
// equiv_List with all equivalences found in .equ files
for( unsigned ii = 0; ii < m_EquFilesNames.GetCount(); ii++ )
for( const auto& equfile : project.m_EquivalenceFiles )
{
fn = wxExpandEnvVars( m_EquFilesNames[ii] );
fn = wxExpandEnvVars( equfile );
tmp = search.FindValidPath( fn.GetFullPath() );

View File

@ -1,76 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2011 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
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file cfg.cpp
*/
#include <config_params.h>
#include <kiface_i.h>
#include <project.h>
#include <cvpcb_mainframe.h>
std::vector<PARAM_CFG*>& CVPCB_MAINFRAME::GetProjectFileParameters()
{
if( !m_projectFileParams.empty() )
return m_projectFileParams;
m_projectFileParams.push_back( new PARAM_CFG( GROUP_PCB_LIBS, PARAM_COMMAND_ERASE ) );
m_projectFileParams.push_back( new PARAM_CFG_LIBNAME_LIST(
wxT( "EquName" ), &m_EquFilesNames, GROUP_CVP_EQU ) );
return m_projectFileParams;
}
void CVPCB_MAINFRAME::LoadProjectFile()
{
PROJECT& prj = Prj();
m_ModuleLibNames.Clear();
m_EquFilesNames.Clear();
prj.ConfigLoad( Kiface().KifaceSearch(), GROUP_CVP, GetProjectFileParameters() );
}
void CVPCB_MAINFRAME::SaveProjectFile()
{
PROJECT& prj = Prj();
wxFileName fn = prj.GetProjectFullName();
if( !IsWritable( fn ) )
{
wxMessageBox( _( "Project file \"%s\" is not writable" ), fn.GetFullPath() );
return;
}
wxString pro_name = fn.GetFullPath();
prj.ConfigSave( Kiface().KifaceSearch(), GROUP_CVP, GetProjectFileParameters(), pro_name );
}

View File

@ -75,9 +75,6 @@ class CVPCB_MAINFRAME : public KIWAY_PLAYER
wxButton* m_saveAndContinue;
public:
wxArrayString m_ModuleLibNames;
wxArrayString m_EquFilesNames;
FOOTPRINT_LIST* m_FootprintsList;
protected:
@ -85,7 +82,6 @@ protected:
bool m_skipComponentSelect; // skip component selection event during
// automatic selection/deletion of
// associations
std::vector<PARAM_CFG*> m_projectFileParams;
bool m_initialized;
@ -283,18 +279,6 @@ public:
*/
int ReadSchematicNetlist( const std::string& aNetlist );
/**
* Function LoadProjectFile
* reads the CvPcb configuration parameter from the project (.pro) file \a aFileName
*/
void LoadProjectFile();
/**
* Function SaveProjectFile
* Saves the CvPcb configuration parameter from the project (.pro) file \a aFileName
*/
void SaveProjectFile();
void LoadSettings( APP_SETTINGS_BASE* aCfg ) override;
void SaveSettings( APP_SETTINGS_BASE* aCfg ) override;
@ -326,21 +310,6 @@ public:
*/
bool LoadFootprintFiles();
/**
* Function GetProjectFileParameters
* return project file parameter list for CvPcb.
* <p>
* Populate the project file parameter array specific to CvPcb if it hasn't
* already been populated and return a reference to the array to the caller.
* Creating the parameter list at run time has the advantage of being able
* to define local variables. The old method of statically building the array
* at compile time requiring global variable definitions.
* </p>
*
* @return reference to a std::vector<PARAM_CFG*> contain the project settings for CvPcb.
*/
std::vector<PARAM_CFG*>& GetProjectFileParameters( void );
/**
* Function SendMessageToEESCHEMA
* Send a remote command to Eeschema via a socket,

View File

@ -35,6 +35,8 @@
#include <cvpcb_mainframe.h>
#include <dialog_config_equfiles.h>
#include <settings/project_file.h>
#include <settings/settings_manager.h>
#include <wildcards_and_files_ext.h>
@ -59,8 +61,17 @@ void DIALOG_CONFIG_EQUFILES::Init()
m_sdbSizerOK->SetDefault();
m_ListChanged = false;
if( !m_Parent->m_EquFilesNames.IsEmpty() )
m_ListEquiv->InsertItems( m_Parent->m_EquFilesNames, 0 );
PROJECT_FILE& project = Prj().GetProjectFile();
if( !project.m_EquivalenceFiles.empty() )
{
wxArrayString arr;
for( const auto& entry : project.m_EquivalenceFiles )
arr.Add( entry );
m_ListEquiv->InsertItems( arr, 0 );
}
if( getEnvVarCount() < 2 )
m_gridEnvVars->AppendRows(2 - getEnvVarCount() );
@ -113,14 +124,16 @@ void DIALOG_CONFIG_EQUFILES::OnOkClick( wxCommandEvent& event )
// Save new equ file list if the files list was modified
if( m_ListChanged )
{
PROJECT_FILE& project = Prj().GetProjectFile();
// Recreate equ list
m_Parent->m_EquFilesNames.Clear();
project.m_EquivalenceFiles.clear();
for( unsigned ii = 0; ii < m_ListEquiv->GetCount(); ii++ )
m_Parent->m_EquFilesNames.Add( m_ListEquiv->GetString( ii ) );
project.m_EquivalenceFiles.emplace_back( m_ListEquiv->GetString( ii ) );
wxCommandEvent evt( ID_SAVE_PROJECT );
m_Parent->SaveProjectFile();
Pgm().GetSettingsManager().SaveProject();
}
EndModal( wxID_OK );

View File

@ -88,8 +88,6 @@ bool CVPCB_MAINFRAME::ReadNetListAndFpFiles( const std::string& aNetlist )
if( m_compListBox == NULL )
return false;
LoadProjectFile();
wxSafeYield();
LoadFootprintFiles();

View File

@ -54,6 +54,7 @@
#include <connection_graph.h>
#include <tool/actions.h>
#include <tools/sch_editor_control.h>
#include <settings/project_file.h>
#include <settings/settings_manager.h>
#include <netlist.h>
#include <widgets/infobar.h>
@ -716,22 +717,16 @@ bool SCH_EDIT_FRAME::SaveProject()
UpdateFileHistory( Schematic().RootScreen()->GetFileName() );
// Save the sheet name map to the project file
wxString configFile = Prj().GetProjectFullName();
wxConfigBase* config = new wxFileConfig( wxEmptyString, wxEmptyString, configFile );
int index = 1;
config->DeleteGroup( GROUP_SHEET_NAMES );
config->SetPath( GROUP_SHEET_NAMES );
std::vector<FILE_INFO_PAIR>& sheets = Prj().GetProjectFile().GetSheets();
sheets.clear();
for( SCH_SHEET_PATH& sheetPath : Schematic().GetSheets() )
{
SCH_SHEET* sheet = sheetPath.Last();
config->Write( wxString::Format( "%d", index++ ),
wxString::Format( "%s:%s", sheet->m_Uuid.AsString(), sheet->GetName() ) );
sheets.emplace_back( std::make_pair( sheet->m_Uuid, sheet->GetName() ) );
}
config->Flush();
delete config;
Pgm().GetSettingsManager().SaveProject();
UpdateTitle();

View File

@ -46,10 +46,6 @@ using KIGFX::COLOR4D;
/// (Now in fp lib tables)
#define GROUP_SCH_LIBS wxT( "/eeschema/libraries" ) /// library list section
#define GROUP_CVP wxT( "/cvpcb" )
#define GROUP_CVP_EQU wxT( "/cvpcb/equfiles" )
#define GROUP_SHEET_NAMES wxT( "/sheetnames" )
#define GROUP_TEXT_VARS wxT( "/text_variables" )
#define CONFIG_VERSION 1

View File

@ -126,6 +126,12 @@ public:
*/
VTBL_ENTRY const wxString SymbolLibTableName() const;
VTBL_ENTRY PROJECT_FILE& GetProjectFile() const
{
wxASSERT( m_projectFile );
return *m_projectFile;
}
/**
* Function ConfigSave
* saves the current "project" parameters into the wxConfigBase* derivative.

View File

@ -422,12 +422,85 @@ public:
return false;
}
private:
protected:
std::vector<Type>* m_ptr;
std::vector<Type> m_default;
};
/**
* Represents a list of strings holding directory paths.
* Normalizes paths to unix directory separator style in the file.
*/
class PARAM_PATH_LIST : public PARAM_LIST<wxString>
{
public:
PARAM_PATH_LIST( const std::string& aJsonPath, std::vector<wxString>* aPtr,
std::initializer_list<wxString> aDefault, bool aReadOnly = false ) :
PARAM_LIST( aJsonPath, aPtr, aDefault, aReadOnly )
{ }
PARAM_PATH_LIST( const std::string& aJsonPath, std::vector<wxString>* aPtr,
std::vector<wxString> aDefault, bool aReadOnly = false ) :
PARAM_LIST( aJsonPath, aPtr, aDefault, aReadOnly )
{ }
void Load( JSON_SETTINGS* aSettings ) const override
{
if( m_readOnly )
return;
PARAM_LIST::Load( aSettings );
for( size_t i = 0; i < m_ptr->size(); i++ )
( *m_ptr )[i] = fromFileFormat( ( *m_ptr )[i] );
}
void Store( JSON_SETTINGS* aSettings) const override
{
nlohmann::json js = nlohmann::json::array();
for( const auto& el : *m_ptr )
js.push_back( toFileFormat( el ) );
aSettings->Set<nlohmann::json>( m_path, js );
}
bool MatchesFile( JSON_SETTINGS* aSettings ) const override
{
if( OPT<nlohmann::json> js = aSettings->GetJson( m_path ) )
{
if( js->is_array() )
{
std::vector<wxString> val;
for( const auto& el : js->items() )
val.emplace_back( fromFileFormat( el.value().get<wxString>() ) );
return val == *m_ptr;
}
}
return false;
}
private:
wxString toFileFormat( const wxString& aString ) const
{
wxString ret = aString;
ret.Replace( wxT( "\\" ), wxT( "/" ) );
return ret;
}
wxString fromFileFormat( const wxString& aString ) const
{
wxString ret = aString;
#ifdef __WINDOWS__
ret.Replace( wxT( "/" ), wxT( "\\" ) );
#endif
return ret;
}
};
/**
* Represents a map of <std::string, Value>. The key parameter has to be a string in JSON.

View File

@ -51,6 +51,16 @@ public:
virtual bool MigrateFromLegacy( wxConfigBase* aLegacyFile ) override;
std::vector<FILE_INFO_PAIR>& GetSheets()
{
return m_sheets;
}
std::vector<FILE_INFO_PAIR>& GetBoards()
{
return m_boards;
}
protected:
wxString getFileExt() const override;
@ -63,6 +73,28 @@ private:
/// A list of board files in this project
std::vector<FILE_INFO_PAIR> m_boards;
/**
* Below are project-level settings that have not been moved to a dedicated file
*/
public:
/**
* Shared params, used by more than one application
*/
/// The list of pinned symbol libraries
std::vector<wxString> m_PinnedSymbolLibs;
/// The list of pinned footprint libraries
std::vector<wxString> m_PinnedFootprintLibs;
/**
* CvPcb params
*/
/// List of equivalence (equ) files used in the project
std::vector<wxString> m_EquivalenceFiles;
};
// Specializations to allow directly reading/writing FILE_INFO_PAIRs from JSON

View File

@ -292,8 +292,8 @@ int KICAD_MANAGER_CONTROL::NewFromTemplate( const TOOL_EVENT& aEvent )
int KICAD_MANAGER_CONTROL::OpenProject( const TOOL_EVENT& aEvent )
{
wxString wildcard = ProjectFileWildcard() + "|" + LegacyProjectFileWildcard() + "|"
+ AllProjectFilesWildcard();
wxString wildcard = AllProjectFilesWildcard() + "|" + ProjectFileWildcard() + "|"
+ LegacyProjectFileWildcard();
wxString default_dir = m_frame->GetMruPath();
wxFileDialog dlg( m_frame, _( "Open Existing Project" ), default_dir, wxEmptyString,