*) Implement "Copy On Write" (COW) support in GITHUB_PLUGIN. See class header
comment for GITHUB_PLUGIN which should flow into Doxygen output. *) Rewrote: PCB_BASE_FRAME::Save_Module_In_Library(): now uses fp-lib-table and PROPERTIES. PCB_EDIT_FRAME::ArchiveModulesOnBoard(): now can archive to any writable library type. PCB_BASE_FRAME::SelectLibrary(): is now generic for selecting a library, not just the active library.
This commit is contained in:
parent
56615d1653
commit
b0c739e7ee
4
TODO.txt
4
TODO.txt
|
@ -62,10 +62,6 @@ PCBNew
|
|||
|
||||
Dick's Final TODO List:
|
||||
======================
|
||||
*) Rewrite
|
||||
PCB_BASE_FRAME::Save_Module_In_Library
|
||||
PCB_EDIT_FRAME::ArchiveModulesOnBoard
|
||||
to use FP_LIB_TABLE mechanisms.
|
||||
*) Apply Fabrizio and Alexander's linux desktop patches after unifying them.
|
||||
*) Get licensing cleaned up.
|
||||
*) Re-arrange the repo architecture.
|
||||
|
|
|
@ -179,11 +179,27 @@ MODULE* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname, const wxString&
|
|||
}
|
||||
|
||||
|
||||
void FP_LIB_TABLE::FootprintSave( const wxString& aNickname, const MODULE* aFootprint )
|
||||
FP_LIB_TABLE::SAVE_T FP_LIB_TABLE::FootprintSave( const wxString& aNickname, const MODULE* aFootprint, bool aOverwrite )
|
||||
{
|
||||
const ROW* row = FindRow( aNickname );
|
||||
wxASSERT( (PLUGIN*) row->plugin );
|
||||
return row->plugin->FootprintSave( row->GetFullURI( true ), aFootprint, row->GetProperties() );
|
||||
|
||||
if( !aOverwrite )
|
||||
{
|
||||
// Try loading the footprint to see if it already exists, caller wants overwrite
|
||||
// protection, which is atypical, not the default.
|
||||
|
||||
wxString fpname = FROM_UTF8( aFootprint->GetFPID().GetFootprintName().c_str() );
|
||||
|
||||
std::auto_ptr<MODULE> m( row->plugin->FootprintLoad( row->GetFullURI( true ), fpname, row->GetProperties() ) );
|
||||
|
||||
if( m.get() )
|
||||
return SAVE_SKIPPED;
|
||||
}
|
||||
|
||||
row->plugin->FootprintSave( row->GetFullURI( true ), aFootprint, row->GetProperties() );
|
||||
|
||||
return SAVE_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -203,6 +219,22 @@ bool FP_LIB_TABLE::IsFootprintLibWritable( const wxString& aNickname )
|
|||
}
|
||||
|
||||
|
||||
void FP_LIB_TABLE::FootprintLibDelete( const wxString& aNickname )
|
||||
{
|
||||
const ROW* row = FindRow( aNickname );
|
||||
wxASSERT( (PLUGIN*) row->plugin );
|
||||
row->plugin->FootprintLibDelete( row->GetFullURI( true ), row->GetProperties() );
|
||||
}
|
||||
|
||||
|
||||
void FP_LIB_TABLE::FootprintLibCreate( const wxString& aNickname )
|
||||
{
|
||||
const ROW* row = FindRow( aNickname );
|
||||
wxASSERT( (PLUGIN*) row->plugin );
|
||||
row->plugin->FootprintLibCreate( row->GetFullURI( true ), row->GetProperties() );
|
||||
}
|
||||
|
||||
|
||||
const wxString FP_LIB_TABLE::GetDescription( const wxString& aNickname )
|
||||
{
|
||||
// use "no exception" form of find row:
|
||||
|
|
|
@ -394,6 +394,16 @@ public:
|
|||
*/
|
||||
MODULE* FootprintLoad( const wxString& aNickname, const wxString& aFootprintName );
|
||||
|
||||
/**
|
||||
* Enum SAVE_T
|
||||
* is the set of return values from FootprintSave() below.
|
||||
*/
|
||||
enum SAVE_T
|
||||
{
|
||||
SAVE_OK,
|
||||
SAVE_SKIPPED,
|
||||
};
|
||||
|
||||
/**
|
||||
* Function FootprintSave
|
||||
* will write @a aFootprint to an existing library given by @a aNickname.
|
||||
|
@ -405,9 +415,14 @@ public:
|
|||
* @param aFootprint is what to store in the library. The caller continues
|
||||
* to own the footprint after this call.
|
||||
*
|
||||
* @param aOverwrite when true means overwrite any existing footprint by the
|
||||
* same name, else if false means skip the write and return SAVE_SKIPPED.
|
||||
*
|
||||
* @return SAVE_T - SAVE_OK or SAVE_SKIPPED. If error saving, then IO_ERROR is thrown.
|
||||
*
|
||||
* @throw IO_ERROR if there is a problem saving.
|
||||
*/
|
||||
void FootprintSave( const wxString& aNickname, const MODULE* aFootprint );
|
||||
SAVE_T FootprintSave( const wxString& aNickname, const MODULE* aFootprint, bool aOverwrite = true );
|
||||
|
||||
/**
|
||||
* Function FootprintDelete
|
||||
|
@ -431,6 +446,10 @@ public:
|
|||
*/
|
||||
bool IsFootprintLibWritable( const wxString& aNickname );
|
||||
|
||||
void FootprintLibDelete( const wxString& aNickname );
|
||||
|
||||
void FootprintLibCreate( const wxString& aNickname );
|
||||
|
||||
//-----</PLUGIN API SUBSET, REBASED ON aNickname>---------------------------
|
||||
|
||||
/**
|
||||
|
|
|
@ -295,7 +295,7 @@ public:
|
|||
* @param aLibName = name of the library to use
|
||||
* @param aModule = the given footprint
|
||||
* @param aOverwrite = true to overwrite an existing footprint, false to
|
||||
* abort an existing footprint is found
|
||||
* abort if an existing footprint with same name is found
|
||||
* @param aDisplayDialog = true to display a dialog to enter or confirm the
|
||||
* footprint name
|
||||
* @return : true if OK, false if abort
|
||||
|
@ -305,6 +305,16 @@ public:
|
|||
bool aOverwrite,
|
||||
bool aDisplayDialog );
|
||||
|
||||
/**
|
||||
* Function SelectLibrary
|
||||
* puts up a dialog and allows the user to pick a library, for unspecified use.
|
||||
*
|
||||
* @param aNicknameExisting is the current choice to highlight
|
||||
*
|
||||
* @return wxString - the library or wxEmptyString on abort.
|
||||
*/
|
||||
wxString SelectLibrary( const wxString& aNicknameExisting );
|
||||
|
||||
MODULE* GetModuleByName();
|
||||
|
||||
/**
|
||||
|
|
|
@ -119,7 +119,7 @@ protected:
|
|||
|
||||
void setupTools();
|
||||
void destroyTools();
|
||||
void onGenericCommand( wxCommandEvent& aEvent );
|
||||
void onGenericCommand( wxCommandEvent& aEvent );
|
||||
|
||||
// we'll use lower case function names for private member functions.
|
||||
void createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu* aPopMenu );
|
||||
|
@ -906,12 +906,11 @@ public:
|
|||
/**
|
||||
* Function ArchiveModulesOnBoard
|
||||
* Save modules in a library:
|
||||
* @param aLibName: the full filename of the library to create or modify
|
||||
* @param aNewModulesOnly:
|
||||
* true : save modules not already existing in this lib
|
||||
* false: save all modules
|
||||
*/
|
||||
void ArchiveModulesOnBoard( const wxString& aLibName, bool aNewModulesOnly );
|
||||
void ArchiveModulesOnBoard( bool aNewModulesOnly );
|
||||
|
||||
/**
|
||||
* Function RecreateBOMFileFromBoard
|
||||
|
|
|
@ -1106,17 +1106,15 @@ EAGLE_PLUGIN::~EAGLE_PLUGIN()
|
|||
}
|
||||
|
||||
|
||||
const wxString& EAGLE_PLUGIN::PluginName() const
|
||||
const wxString EAGLE_PLUGIN::PluginName() const
|
||||
{
|
||||
static const wxString name = wxT( "Eagle" );
|
||||
return name;
|
||||
return wxT( "Eagle" );
|
||||
}
|
||||
|
||||
|
||||
const wxString& EAGLE_PLUGIN::GetFileExtension() const
|
||||
const wxString EAGLE_PLUGIN::GetFileExtension() const
|
||||
{
|
||||
static const wxString extension = wxT( "brd" );
|
||||
return extension;
|
||||
return wxT( "brd" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -80,11 +80,11 @@ class EAGLE_PLUGIN : public PLUGIN
|
|||
public:
|
||||
|
||||
//-----<PUBLIC PLUGIN API>--------------------------------------------------
|
||||
const wxString& PluginName() const;
|
||||
const wxString PluginName() const;
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties = NULL );
|
||||
|
||||
const wxString& GetFileExtension() const;
|
||||
const wxString GetFileExtension() const;
|
||||
|
||||
wxArrayString FootprintEnumerate( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL);
|
||||
|
||||
|
|
|
@ -1177,11 +1177,11 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||
break;
|
||||
|
||||
case ID_MENU_ARCHIVE_NEW_MODULES:
|
||||
ArchiveModulesOnBoard( wxEmptyString, true );
|
||||
ArchiveModulesOnBoard( true );
|
||||
break;
|
||||
|
||||
case ID_MENU_ARCHIVE_ALL_MODULES:
|
||||
ArchiveModulesOnBoard( wxEmptyString, false );
|
||||
ArchiveModulesOnBoard( false );
|
||||
break;
|
||||
|
||||
case ID_GEN_IMPORT_DXF_FILE:
|
||||
|
|
|
@ -24,22 +24,6 @@
|
|||
|
||||
|
||||
/*
|
||||
This is a pcbnew PLUGIN which supports some of the PLUGIN::Footprint*() functions
|
||||
in the PLUGIN interface, and could do so by utilizing the version 3 github.com
|
||||
API documented here:
|
||||
|
||||
http://developer.github.com
|
||||
https://help.github.com/articles/creating-an-access-token-for-command-line-use
|
||||
|
||||
but it does not. Rather it simply reads in a zip file of the repo and unzips it
|
||||
from RAM as needed. Therefore the PLUGIN is read only for accessing
|
||||
remote pretty libraries. If you want to support writing to the repo, then you
|
||||
could use the above API.
|
||||
|
||||
@todo:
|
||||
Derive this PLUGIN from KICAD_PLUGIN so we can use its FootprintSave().
|
||||
Support local footprints if they are present in an optional directory.
|
||||
Possibly cache the zip file locally. Use HTTP's "have changed" or whatever it is called.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -76,9 +60,14 @@
|
|||
#include <github_plugin.h>
|
||||
#include <class_module.h>
|
||||
#include <macros.h>
|
||||
#include <fp_lib_table.h> // ExpandSubstitutions()
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
static const char* PRETTY_DIR = "allow_pretty_writing_to_this_dir";
|
||||
|
||||
|
||||
typedef boost::ptr_map<string, wxZipEntry> MODULE_MAP;
|
||||
typedef MODULE_MAP::iterator MODULE_ITER;
|
||||
typedef MODULE_MAP::const_iterator MODULE_CITER;
|
||||
|
@ -95,28 +84,27 @@ struct GH_CACHE : public MODULE_MAP
|
|||
|
||||
|
||||
GITHUB_PLUGIN::GITHUB_PLUGIN() :
|
||||
m_cache( 0 )
|
||||
PCB_IO(),
|
||||
m_gh_cache( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
GITHUB_PLUGIN::~GITHUB_PLUGIN()
|
||||
{
|
||||
delete m_cache;
|
||||
delete m_gh_cache;
|
||||
}
|
||||
|
||||
|
||||
const wxString& GITHUB_PLUGIN::PluginName() const
|
||||
const wxString GITHUB_PLUGIN::PluginName() const
|
||||
{
|
||||
static wxString name( wxT( "Github" ) );
|
||||
return name;
|
||||
return wxT( "Github" );
|
||||
}
|
||||
|
||||
|
||||
const wxString& GITHUB_PLUGIN::GetFileExtension() const
|
||||
const wxString GITHUB_PLUGIN::GetFileExtension() const
|
||||
{
|
||||
static wxString empty_ext;
|
||||
return empty_ext;
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,12 +112,14 @@ wxArrayString GITHUB_PLUGIN::FootprintEnumerate(
|
|||
const wxString& aLibraryPath, const PROPERTIES* aProperties )
|
||||
{
|
||||
//D(printf("%s: this:%p aLibraryPath:'%s'\n", __func__, this, TO_UTF8(aLibraryPath) );)
|
||||
|
||||
cacheLib( aLibraryPath );
|
||||
cacheLib( aLibraryPath, aProperties );
|
||||
|
||||
wxArrayString ret;
|
||||
|
||||
for( MODULE_ITER it = m_cache->begin(); it!=m_cache->end(); ++it )
|
||||
if( m_pretty_dir.size() )
|
||||
ret = PCB_IO::FootprintEnumerate( m_pretty_dir );
|
||||
|
||||
for( MODULE_ITER it = m_gh_cache->begin(); it!=m_gh_cache->end(); ++it )
|
||||
{
|
||||
ret.Add( FROM_UTF8( it->first.c_str() ) );
|
||||
}
|
||||
|
@ -143,13 +133,24 @@ MODULE* GITHUB_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
|
|||
{
|
||||
// D(printf("%s: this:%p aLibraryPath:'%s'\n", __func__, this, TO_UTF8(aLibraryPath) );)
|
||||
|
||||
cacheLib( aLibraryPath );
|
||||
// clear or set to valid the variable m_pretty_dir
|
||||
cacheLib( aLibraryPath, aProperties );
|
||||
|
||||
if( m_pretty_dir.size() )
|
||||
{
|
||||
// API has FootprintLoad() *not* throwing an exception if footprint not found.
|
||||
MODULE* local = PCB_IO::FootprintLoad( m_pretty_dir, aFootprintName, aProperties );
|
||||
|
||||
if( local )
|
||||
return local;
|
||||
}
|
||||
|
||||
|
||||
string fp_name = TO_UTF8( aFootprintName );
|
||||
|
||||
MODULE_CITER it = m_cache->find( fp_name );
|
||||
MODULE_CITER it = m_gh_cache->find( fp_name );
|
||||
|
||||
if( it != m_cache->end() ) // fp_name is present
|
||||
if( it != m_gh_cache->end() ) // fp_name is present
|
||||
{
|
||||
wxMemoryInputStream mis( &m_zip_image[0], m_zip_image.size() );
|
||||
|
||||
|
@ -181,7 +182,109 @@ MODULE* GITHUB_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
|
|||
|
||||
bool GITHUB_PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
|
||||
{
|
||||
return false;
|
||||
if( m_pretty_dir.size() )
|
||||
return PCB_IO::IsFootprintLibWritable( m_pretty_dir );
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void GITHUB_PLUGIN::FootprintSave( const wxString& aLibraryPath,
|
||||
const MODULE* aFootprint, const PROPERTIES* aProperties )
|
||||
{
|
||||
// set m_pretty_dir to either empty or something in aProperties
|
||||
cacheLib( aLibraryPath, aProperties );
|
||||
|
||||
if( GITHUB_PLUGIN::IsFootprintLibWritable( aLibraryPath ) )
|
||||
{
|
||||
PCB_IO::FootprintSave( m_pretty_dir, aFootprint, aProperties );
|
||||
}
|
||||
else
|
||||
{
|
||||
// This typically will not happen if the caller first properly calls
|
||||
// IsFootprintLibWritable() to determine if calling FootprintSave() is
|
||||
// even legal, so I spend no time on internationalization here:
|
||||
|
||||
string msg = StrPrintf( "Github library\n'%s'\nis only writable if you set option '%s' in Library Tables dialog.",
|
||||
(const char*) TO_UTF8( aLibraryPath ), PRETTY_DIR );
|
||||
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GITHUB_PLUGIN::FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName,
|
||||
const PROPERTIES* aProperties )
|
||||
{
|
||||
// set m_pretty_dir to either empty or something in aProperties
|
||||
cacheLib( aLibraryPath, aProperties );
|
||||
|
||||
if( GITHUB_PLUGIN::IsFootprintLibWritable( aLibraryPath ) )
|
||||
{
|
||||
// Does the PCB_IO base class have this footprint?
|
||||
// We cannot write to github.
|
||||
|
||||
wxArrayString pretties = PCB_IO::FootprintEnumerate( m_pretty_dir, aProperties );
|
||||
|
||||
if( pretties.Index( aFootprintName ) != wxNOT_FOUND )
|
||||
{
|
||||
PCB_IO::FootprintDelete( m_pretty_dir, aFootprintName, aProperties );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "Footprint\n'%s'\nis not in the writable portion of this Github library\n'%s'" ),
|
||||
GetChars( aFootprintName ),
|
||||
GetChars( aLibraryPath )
|
||||
);
|
||||
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This typically will not happen if the caller first properly calls
|
||||
// IsFootprintLibWritable() to determine if calling FootprintSave() is
|
||||
// even legal, so I spend no time on internationalization here:
|
||||
|
||||
string msg = StrPrintf( "Github library\n'%s'\nis only writable if you set option '%s' in Library Tables dialog.",
|
||||
(const char*) TO_UTF8( aLibraryPath ), PRETTY_DIR );
|
||||
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GITHUB_PLUGIN::FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties )
|
||||
{
|
||||
// set m_pretty_dir to either empty or something in aProperties
|
||||
cacheLib( aLibraryPath, aProperties );
|
||||
|
||||
if( m_pretty_dir.size() )
|
||||
{
|
||||
PCB_IO::FootprintLibCreate( m_pretty_dir, aProperties );
|
||||
}
|
||||
else
|
||||
{
|
||||
// THROW_IO_ERROR() @todo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GITHUB_PLUGIN::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties )
|
||||
{
|
||||
// set m_pretty_dir to either empty or something in aProperties
|
||||
cacheLib( aLibraryPath, aProperties );
|
||||
|
||||
if( m_pretty_dir.size() )
|
||||
{
|
||||
return PCB_IO::FootprintLibDelete( m_pretty_dir, aProperties );
|
||||
}
|
||||
else
|
||||
{
|
||||
// THROW_IO_ERROR() @todo
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -190,32 +293,74 @@ void GITHUB_PLUGIN::FootprintLibOptions( PROPERTIES* aListToAppendTo ) const
|
|||
// inherit options supported by all PLUGINs.
|
||||
PLUGIN::FootprintLibOptions( aListToAppendTo );
|
||||
|
||||
(*aListToAppendTo)["allow_pretty_writing_to_this_dir"] = wxString( _(
|
||||
(*aListToAppendTo)[ PRETTY_DIR ] = wxString( _(
|
||||
"Set this property to a directory where footprints are to be written as pretty "
|
||||
"footprints when saving to this library. Anything saved will take precedence over "
|
||||
"footprints by the same name in the github repo. These saved footprints can then "
|
||||
"be sent to the library maintainer as updates. "
|
||||
"<p>The directory should have a <b>.pretty</b> file extension because the "
|
||||
"Kicad plugin is used to do the saving.</p>"
|
||||
"<p>The directory <b>must</b> have a <b>.pretty</b> file extension because the "
|
||||
"format of the save is pretty.</p>"
|
||||
)).utf8_str();
|
||||
|
||||
/*
|
||||
(*aListToAppendTo)["cache_github_zip_in_this_dir"] = wxString( _(
|
||||
"Set this property to a directory where the github *.zip file will be cached. "
|
||||
"This should speed up subsequent visits to this library."
|
||||
)).utf8_str();
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void GITHUB_PLUGIN::cacheLib( const wxString& aLibraryPath ) throw( IO_ERROR )
|
||||
void GITHUB_PLUGIN::cacheLib( const wxString& aLibraryPath, const PROPERTIES* aProperties ) throw( IO_ERROR )
|
||||
{
|
||||
if( !m_cache || m_lib_path != aLibraryPath )
|
||||
// This is edge triggered based on a change in 'aLibraryPath',
|
||||
// usually it does nothing. When the edge fires, m_pretty_dir is set
|
||||
// to either:
|
||||
// 1) empty or
|
||||
// 2) a verified and validated, writable, *.pretty directory.
|
||||
|
||||
if( !m_gh_cache || m_lib_path != aLibraryPath )
|
||||
{
|
||||
delete m_gh_cache;
|
||||
m_gh_cache = 0;
|
||||
|
||||
m_pretty_dir.clear();
|
||||
|
||||
if( aProperties )
|
||||
{
|
||||
string pretty_dir;
|
||||
|
||||
if( aProperties->Value( PRETTY_DIR, &pretty_dir ) )
|
||||
{
|
||||
wxString wx_pretty_dir = FROM_UTF8( pretty_dir.c_str() );
|
||||
|
||||
wx_pretty_dir = FP_LIB_TABLE::ExpandSubstitutions( wx_pretty_dir );
|
||||
|
||||
wxFileName wx_pretty_fn = wx_pretty_dir;
|
||||
|
||||
if( !wx_pretty_fn.IsOk() ||
|
||||
!wx_pretty_fn.IsDirWritable() ||
|
||||
wx_pretty_fn.GetExt() != wxT( "pretty" )
|
||||
)
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "option '%s' for Github library '%s' must point to a writable directory ending with '.pretty'." ),
|
||||
GetChars( FROM_UTF8( PRETTY_DIR ) ),
|
||||
GetChars( aLibraryPath )
|
||||
);
|
||||
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
|
||||
m_pretty_dir = wx_pretty_dir;
|
||||
}
|
||||
}
|
||||
|
||||
// operator==( wxString, wxChar* ) does not exist, construct wxString once here.
|
||||
const wxString kicad_mod( wxT( "kicad_mod" ) );
|
||||
|
||||
//D(printf("%s: this:%p m_lib_path:'%s' aLibraryPath:'%s'\n", __func__, this, TO_UTF8( m_lib_path), TO_UTF8(aLibraryPath) );)
|
||||
delete m_cache;
|
||||
m_cache = new GH_CACHE();
|
||||
m_gh_cache = new GH_CACHE();
|
||||
|
||||
// INIT_LOGGER( "/tmp", "test.log" );
|
||||
remote_get_zip( aLibraryPath );
|
||||
|
@ -238,7 +383,7 @@ void GITHUB_PLUGIN::cacheLib( const wxString& aLibraryPath ) throw( IO_ERROR )
|
|||
{
|
||||
string fp_name = TO_UTF8( fn.GetName() ); // omit extension & path
|
||||
|
||||
m_cache->insert( fp_name, entry );
|
||||
m_gh_cache->insert( fp_name, entry );
|
||||
}
|
||||
else
|
||||
delete entry;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#ifndef GITHUB_PLUGIN_H_
|
||||
#define GITHUB_PLUGIN_H_
|
||||
|
||||
#include <kicad_plugin.h>
|
||||
|
||||
struct GH_CACHE;
|
||||
|
||||
|
@ -32,38 +33,98 @@ struct GH_CACHE;
|
|||
/**
|
||||
* Class GITHUB_PLUGIN
|
||||
* implements a portion of pcbnew PLUGIN to provide read only access to a github
|
||||
* repo consisting of pretty footprints
|
||||
* repo consisting of pretty footprints. It could have used version 3 of the
|
||||
github.com API documented here:
|
||||
<code>
|
||||
http://developer.github.com
|
||||
https://help.github.com/articles/creating-an-access-token-for-command-line-use
|
||||
</code>
|
||||
but it does not. Rather it simply reads in a zip file of the repo and unzips it
|
||||
from RAM as needed. Therefore the PLUGIN is read only for accessing
|
||||
remote pretty libraries. The "Library Path" in the fp-lib-table should be set
|
||||
to the full https:// URL. For example:
|
||||
<code>
|
||||
https://github.com/liftoff-sr/pretty_footprints
|
||||
</code>
|
||||
|
||||
This is typically https://github.com/user_name/repo_name
|
||||
|
||||
<p>
|
||||
This PLUGIN also supports "Copy On Write", a.k.a "COW". So a library defined
|
||||
in the fp-lib-table will take an optional option called
|
||||
<b>allow_pretty_writing_to_this_dir</b> which is essentially the lib_path for
|
||||
a local Kicad (pretty) library which is combined to make up the Github library.
|
||||
If the option is missing, then the Github library is read only. If it is present,
|
||||
then any writes will go to the local *.pretty directory. Any reads will always
|
||||
give precedence to the local footprints. So once you have written to the local
|
||||
directory, no github updates will travel down on any footprints for which you've
|
||||
written locally. Always keep a separate local *.pretty directory for each Github
|
||||
library, never combine them you will likely create a mess. You must manually
|
||||
create the local directory in advance, and the directory name must end with ".pretty".
|
||||
The option <b>allow_pretty_writing_to_this_dir</b> will be path substituted with
|
||||
any environment variable strings embedded in the option's value, just like the
|
||||
"Library Path" is.
|
||||
<p>
|
||||
What's the point of COW? It is to turbo charge the sharing of footprints. If you
|
||||
periodically email your COW pretty footprints to the Github repo maintainer,
|
||||
you can help update the Github copy. The idea should be to keep the COW file
|
||||
set as small as possible. After you've received confirmation that your changes
|
||||
have been committed up at github.com, you can safely delete your COW file(s)
|
||||
and those from github.com will flow down.
|
||||
<p>
|
||||
Note that if you use the module editor to delete a footprint and it is present
|
||||
in the COW local dir, it will get deleted from there. However, it may not
|
||||
be deleted from the library as a whole if the footprint of the same name also
|
||||
existed in the github repo. In this case deleting the local copy will simply
|
||||
unmask the one at the github repo. Remember, it is masked out if there is
|
||||
a local COW copy, since the local copy always takes precedence.
|
||||
|
||||
*
|
||||
* @author Dick Hollenbeck
|
||||
* @date Original date: 10-Sep-2013
|
||||
*/
|
||||
class GITHUB_PLUGIN : public PLUGIN
|
||||
class GITHUB_PLUGIN : public PCB_IO
|
||||
{
|
||||
public:
|
||||
//-----<PLUGIN API>----------------------------------------------------------
|
||||
// ("read-only" subset)
|
||||
const wxString PluginName() const;
|
||||
|
||||
const wxString& PluginName() const;
|
||||
const wxString GetFileExtension() const;
|
||||
|
||||
const wxString& GetFileExtension() const;
|
||||
|
||||
wxArrayString FootprintEnumerate( const wxString& aLibraryPath, const PROPERTIES* aProperties );
|
||||
wxArrayString FootprintEnumerate( const wxString& aLibraryPath,
|
||||
const PROPERTIES* aProperties = NULL );
|
||||
|
||||
MODULE* FootprintLoad( const wxString& aLibraryPath,
|
||||
const wxString& aFootprintName, const PROPERTIES* aProperties );
|
||||
|
||||
void FootprintSave( const wxString& aLibraryPath, const MODULE* aFootprint,
|
||||
const PROPERTIES* aProperties = NULL );
|
||||
|
||||
void FootprintDelete( const wxString& aLibraryPath, const wxString& aFootprintName,
|
||||
const PROPERTIES* aProperties = NULL );
|
||||
|
||||
bool IsFootprintLibWritable( const wxString& aLibraryPath );
|
||||
|
||||
void FootprintLibOptions( PROPERTIES* aListToAppendTo ) const;
|
||||
|
||||
// Since I derive from PCB_IO, I have to implement this, else I'd inherit his, which is bad since
|
||||
// my lib_path is not his. Note: it is impossible to create a Github library, but can the C.O.W. portion.
|
||||
void FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES* aProperties );
|
||||
|
||||
// Since I derive from PCB_IO, I have to implement this, else I'd inherit his, which is bad since
|
||||
// my lib_path is not his. Note: it is impossible to delete a Github library, but can the C.O.W portion.
|
||||
bool FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES* aProperties );
|
||||
|
||||
//-----</PLUGIN API>---------------------------------------------------------
|
||||
|
||||
GITHUB_PLUGIN(); // constructor, if any, must be zero arg
|
||||
~GITHUB_PLUGIN();
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
void cacheLib( const wxString& aLibraryPath ) throw( IO_ERROR );
|
||||
void init( const PROPERTIES* aProperties );
|
||||
|
||||
void cacheLib( const wxString& aLibraryPath, const PROPERTIES* aProperties ) throw( IO_ERROR );
|
||||
|
||||
/**
|
||||
* Function repoURL_zipURL
|
||||
|
@ -84,7 +145,9 @@ private:
|
|||
|
||||
wxString m_lib_path; ///< from aLibraryPath, something like https://github.com/liftoff-sr/pretty_footprints
|
||||
std::string m_zip_image; ///< byte image of the zip file in its entirety.
|
||||
GH_CACHE* m_cache;
|
||||
GH_CACHE* m_gh_cache;
|
||||
wxString m_pretty_dir;
|
||||
};
|
||||
|
||||
|
||||
#endif // GITHUB_PLUGIN_H_
|
||||
|
|
|
@ -52,16 +52,14 @@ public:
|
|||
|
||||
//-----<PLUGIN API>---------------------------------------------------------
|
||||
|
||||
const wxString& PluginName() const
|
||||
const wxString PluginName() const
|
||||
{
|
||||
static const wxString name = wxT( "Geda PCB" );
|
||||
return name;
|
||||
return wxT( "Geda PCB" );
|
||||
}
|
||||
|
||||
const wxString& GetFileExtension() const
|
||||
const wxString GetFileExtension() const
|
||||
{
|
||||
static const wxString extension = wxT( "fp" );
|
||||
return extension;
|
||||
return wxT( "fp" );
|
||||
}
|
||||
|
||||
wxArrayString FootprintEnumerate( const wxString& aLibraryPath, const PROPERTIES* aProperties = NULL);
|
||||
|
|
|
@ -220,13 +220,13 @@ public:
|
|||
* Function PluginName
|
||||
* returns a brief hard coded name for this PLUGIN.
|
||||
*/
|
||||
virtual const wxString& PluginName() const = 0;
|
||||
virtual const wxString PluginName() const = 0;
|
||||
|
||||
/**
|
||||
* Function GetFileExtension
|
||||
* returns the file extension for the PLUGIN.
|
||||
*/
|
||||
virtual const wxString& GetFileExtension() const = 0;
|
||||
virtual const wxString GetFileExtension() const = 0;
|
||||
|
||||
/**
|
||||
* Function Load
|
||||
|
|
|
@ -85,7 +85,10 @@ public:
|
|||
|
||||
wxString GetName() const { return m_file_name.GetDirs().Last(); }
|
||||
wxFileName GetFileName() const { return m_file_name; }
|
||||
|
||||
/// Tell if the disk content or the lib_path has changed.
|
||||
bool IsModified() const;
|
||||
|
||||
MODULE* GetModule() const { return m_module.get(); }
|
||||
void UpdateModificationTime() { m_mod_time = m_file_name.GetModificationTime(); }
|
||||
};
|
||||
|
@ -339,6 +342,7 @@ bool FP_CACHE::IsModified( const wxString& aLibPath, const wxString& aFootprintN
|
|||
for( MODULE_CITER it = m_modules.begin(); it != m_modules.end(); ++it )
|
||||
{
|
||||
wxFileName fn = m_lib_path;
|
||||
|
||||
fn.SetName( it->second->GetFileName().GetName() );
|
||||
fn.SetExt( KiCadFootprintFileExtension );
|
||||
|
||||
|
@ -1804,7 +1808,7 @@ void PCB_IO::FootprintDelete( const wxString& aLibraryPath, const wxString& aFoo
|
|||
{
|
||||
LOCALE_IO toggle; // toggles on, then off, the C locale.
|
||||
|
||||
init( NULL );
|
||||
init( aProperties );
|
||||
|
||||
cacheLib( aLibraryPath );
|
||||
|
||||
|
|
|
@ -83,20 +83,18 @@ public:
|
|||
|
||||
//-----<PLUGIN API>---------------------------------------------------------
|
||||
|
||||
const wxString& PluginName() const
|
||||
const wxString PluginName() const
|
||||
{
|
||||
static const wxString name = wxT( "KiCad" );
|
||||
return name;
|
||||
return wxT( "KiCad" );
|
||||
}
|
||||
|
||||
const wxString& GetFileExtension() const
|
||||
const wxString GetFileExtension() const
|
||||
{
|
||||
// Would have used wildcards_and_files_ext.cpp's KiCadPcbFileExtension,
|
||||
// but to be pure, a plugin should not assume that it will always be linked
|
||||
// with the core of the pcbnew code. (Might someday be a DLL/DSO.) Besides,
|
||||
// file extension policy should be controlled by the plugin.
|
||||
static const wxString extension = wxT( "kicad_pcb" );
|
||||
return extension;
|
||||
return wxT( "kicad_pcb" );
|
||||
}
|
||||
|
||||
void Save( const wxString& aFileName, BOARD* aBoard,
|
||||
|
@ -172,6 +170,10 @@ protected:
|
|||
int m_ctl;
|
||||
PCB_PARSER* m_parser;
|
||||
|
||||
/// we only cache one footprint library, this determines which one.
|
||||
void cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName = wxEmptyString );
|
||||
|
||||
void init( const PROPERTIES* aProperties );
|
||||
|
||||
private:
|
||||
void format( BOARD* aBoard, int aNestLevel = 0 ) const
|
||||
|
@ -211,11 +213,6 @@ private:
|
|||
|
||||
void formatLayers( LAYER_MSK aLayerMask, int aNestLevel = 0 ) const
|
||||
throw( IO_ERROR );
|
||||
|
||||
/// we only cache one footprint library for now, this determines which one.
|
||||
void cacheLib( const wxString& aLibraryPath, const wxString& aFootprintName = wxEmptyString );
|
||||
|
||||
void init( const PROPERTIES* aProperties );
|
||||
};
|
||||
|
||||
#endif // KICAD_PLUGIN_H_
|
||||
|
|
|
@ -64,16 +64,14 @@ public:
|
|||
|
||||
//-----<PLUGIN IMPLEMENTATION>----------------------------------------------
|
||||
|
||||
const wxString& PluginName() const
|
||||
const wxString PluginName() const
|
||||
{
|
||||
static const wxString name = wxT( "KiCad-Legacy" );
|
||||
return name;
|
||||
return wxT( "KiCad-Legacy" );
|
||||
}
|
||||
|
||||
const wxString& GetFileExtension() const
|
||||
const wxString GetFileExtension() const
|
||||
{
|
||||
static const wxString extension = wxT( "brd" );
|
||||
return extension;
|
||||
return wxT( "brd" );
|
||||
}
|
||||
|
||||
BOARD* Load( const wxString& aFileName, BOARD* aAppendToMe, const PROPERTIES* aProperties = NULL );
|
||||
|
|
|
@ -53,29 +53,29 @@
|
|||
|
||||
// unique, "file local" translations:
|
||||
|
||||
#define FMT_OK_OVERWRITE _( "Library <%s> exists, OK to replace ?" )
|
||||
#define FMT_OK_OVERWRITE _( "Library '%s' exists, OK to replace ?" )
|
||||
#define FMT_CREATE_LIB _( "Create New Library" )
|
||||
#define FMT_OK_DELETE _( "OK to delete module %s in library <%s>" )
|
||||
#define FMT_OK_DELETE _( "OK to delete module %s in library '%s'" )
|
||||
#define FMT_IMPORT_MODULE _( "Import Footprint Module" )
|
||||
#define FMT_FILE_NOT_FOUND _( "File <%s> not found" )
|
||||
#define FMT_FILE_NOT_FOUND _( "File '%s' not found" )
|
||||
#define FMT_NOT_MODULE _( "Not a module file" )
|
||||
#define FMT_MOD_NOT_FOUND _( "Unable to find or load footprint %s from lib path <%s>" )
|
||||
#define FMT_BAD_PATH _( "Unable to find or load footprint from path <%s>" )
|
||||
#define FMT_BAD_PATHS _( "The footprint library <%s> could not be found in any of the search paths." )
|
||||
#define FMT_LIB_READ_ONLY _( "Library <%s> is read only, not writable" )
|
||||
#define FMT_MOD_NOT_FOUND _( "Unable to find or load footprint %s from lib path '%s'" )
|
||||
#define FMT_BAD_PATH _( "Unable to find or load footprint from path '%s'" )
|
||||
#define FMT_BAD_PATHS _( "The footprint library '%s' could not be found in any of the search paths." )
|
||||
#define FMT_LIB_READ_ONLY _( "Library '%s' is read only, not writable" )
|
||||
|
||||
#define FMT_EXPORT_MODULE _( "Export Module" )
|
||||
#define FMT_SAVE_MODULE _( "Save Module" )
|
||||
#define FMT_MOD_REF _( "Module Reference:" )
|
||||
#define FMT_EXPORTED _( "Module exported to file <%s>" )
|
||||
#define FMT_MOD_DELETED _( "Module %s deleted from library <%s>" )
|
||||
#define FMT_EXPORTED _( "Module exported to file '%s'" )
|
||||
#define FMT_MOD_DELETED _( "Module %s deleted from library '%s'" )
|
||||
#define FMT_MOD_CREATE _( "Module Creation" )
|
||||
|
||||
#define FMT_NO_MODULES _( "No modules to archive!" )
|
||||
#define FMT_LIBRARY _( "Library" ) // window title
|
||||
#define FMT_MOD_EXISTS _( "Module %s already exists in library <%s>" )
|
||||
#define FMT_MOD_EXISTS _( "Module %s already exists in library '%s'" )
|
||||
#define FMT_NO_REF_ABORTED _( "No reference, aborted" )
|
||||
#define FMT_SELECT_LIB _( "Select Active Library" )
|
||||
#define FMT_SELECT_LIB _( "Select Library" )
|
||||
|
||||
|
||||
static const wxString ModExportFileWildcard( _( "KiCad foot print export files (*.emp)|*.emp" ) );
|
||||
|
@ -463,6 +463,53 @@ wxString FOOTPRINT_EDIT_FRAME::CreateNewLibrary()
|
|||
|
||||
bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
|
||||
{
|
||||
#if defined(USE_FP_LIB_TABLE)
|
||||
|
||||
wxString nickname = getLibNickName();
|
||||
|
||||
if( !m_footprintLibTable->IsFootprintLibWritable( nickname ) )
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "Library '%s' is read only" ),
|
||||
GetChars( nickname )
|
||||
);
|
||||
|
||||
DisplayError( this, msg );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString fpid_txt = PCB_BASE_FRAME::SelectFootprint( this, nickname,
|
||||
wxEmptyString, wxEmptyString, m_footprintLibTable );
|
||||
|
||||
if( !fpid_txt )
|
||||
return false;
|
||||
|
||||
FPID fpid( fpid_txt );
|
||||
wxString fpname = FROM_UTF8( fpid.GetFootprintName().c_str() );
|
||||
|
||||
// Confirmation
|
||||
wxString msg = wxString::Format( FMT_OK_DELETE, fpname.GetData(), nickname.GetData() );
|
||||
|
||||
if( !IsOK( this, msg ) )
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
m_footprintLibTable->FootprintDelete( nickname, fpname );
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
{
|
||||
DisplayError( this, ioe.errorText );
|
||||
return false;
|
||||
}
|
||||
|
||||
msg.Printf( FMT_MOD_DELETED, fpname.GetData(), nickname.GetData() );
|
||||
|
||||
SetStatusText( msg );
|
||||
|
||||
return true;
|
||||
|
||||
#else
|
||||
PCB_EDIT_FRAME* parent = (PCB_EDIT_FRAME*) GetParent();
|
||||
wxString libPath = getLibPath();
|
||||
wxString footprintName = PCB_BASE_FRAME::SelectFootprint( this, libPath,
|
||||
|
@ -497,17 +544,73 @@ bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromCurrentLibrary()
|
|||
SetStatusText( msg );
|
||||
|
||||
return true;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Save modules in a library:
|
||||
* param aNewModulesOnly:
|
||||
* true : save modules not already existing in this lib
|
||||
* false: save all modules
|
||||
*/
|
||||
void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewModulesOnly )
|
||||
#if defined(USE_FP_LIB_TABLE)
|
||||
void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aNewModulesOnly )
|
||||
{
|
||||
wxString fileName = aLibName;
|
||||
if( GetBoard()->m_Modules == NULL )
|
||||
{
|
||||
DisplayInfoMessage( this, FMT_NO_MODULES );
|
||||
return;
|
||||
}
|
||||
|
||||
wxString last_nickname = wxGetApp().ReturnLastVisitedLibraryPath();
|
||||
|
||||
wxString nickname = SelectLibrary( last_nickname );
|
||||
|
||||
if( !nickname )
|
||||
return;
|
||||
|
||||
wxGetApp().SaveLastVisitedLibraryPath( nickname );
|
||||
|
||||
if( !aNewModulesOnly )
|
||||
{
|
||||
wxString msg = wxString::Format( FMT_OK_OVERWRITE, GetChars( nickname ) );
|
||||
|
||||
if( !IsOK( this, msg ) )
|
||||
return;
|
||||
}
|
||||
|
||||
m_canvas->SetAbortRequest( false );
|
||||
|
||||
try
|
||||
{
|
||||
// Delete old library if we're replacing it entirely.
|
||||
if( !aNewModulesOnly )
|
||||
{
|
||||
m_footprintLibTable->FootprintLibDelete( nickname );
|
||||
m_footprintLibTable->FootprintLibCreate( nickname );
|
||||
|
||||
for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() )
|
||||
{
|
||||
m_footprintLibTable->FootprintSave( nickname, m, true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( MODULE* m = GetBoard()->m_Modules; m; m = m->Next() )
|
||||
{
|
||||
m_footprintLibTable->FootprintSave( nickname, m, false );
|
||||
|
||||
// Check for request to stop backup (ESCAPE key actuated)
|
||||
if( m_canvas->GetAbortRequest() )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
{
|
||||
DisplayError( this, ioe.errorText );
|
||||
}
|
||||
}
|
||||
#else
|
||||
void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aNewModulesOnly )
|
||||
{
|
||||
wxString fileName;
|
||||
wxString path;
|
||||
|
||||
if( GetBoard()->m_Modules == NULL )
|
||||
|
@ -518,7 +621,6 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
|
|||
|
||||
path = wxGetApp().ReturnLastVisitedLibraryPath();
|
||||
|
||||
if( !aLibName )
|
||||
{
|
||||
wxFileDialog dlg( this, FMT_LIBRARY, path,
|
||||
wxEmptyString,
|
||||
|
@ -532,7 +634,9 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
|
|||
}
|
||||
|
||||
wxFileName fn( fileName );
|
||||
|
||||
wxGetApp().SaveLastVisitedLibraryPath( fn.GetPath() );
|
||||
|
||||
bool lib_exists = wxFileExists( fileName );
|
||||
|
||||
if( !aNewModulesOnly && lib_exists )
|
||||
|
@ -584,12 +688,12 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( const wxString& aLibName, bool aNewM
|
|||
catch( IO_ERROR ioe )
|
||||
{
|
||||
DisplayError( this, ioe.errorText );
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibPath,
|
||||
bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibrary,
|
||||
MODULE* aModule,
|
||||
bool aOverwrite,
|
||||
bool aDisplayDialog )
|
||||
|
@ -618,10 +722,10 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibPath,
|
|||
|
||||
if( ! MODULE::IsLibNameValid( footprintName ) )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _("Error:\none of invalid chars '%s' found\nin '%s'" ),
|
||||
MODULE::ReturnStringLibNameInvalidChars( true ),
|
||||
GetChars( footprintName ) );
|
||||
wxString msg = wxString::Format(
|
||||
_("Error:\none of invalid chars '%s' found\nin '%s'" ),
|
||||
MODULE::ReturnStringLibNameInvalidChars( true ),
|
||||
GetChars( footprintName ) );
|
||||
|
||||
DisplayError( NULL, msg );
|
||||
return false;
|
||||
|
@ -637,25 +741,24 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibPath,
|
|||
aModule->SetFPID( footprintName );
|
||||
}
|
||||
|
||||
IO_MGR::PCB_FILE_T pluginType = IO_MGR::GuessPluginTypeFromLibPath( aLibPath );
|
||||
|
||||
MODULE* module_exists = NULL;
|
||||
bool module_exists = false;
|
||||
|
||||
#if defined(USE_FP_LIB_TABLE)
|
||||
try
|
||||
{
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
|
||||
MODULE* m = m_footprintLibTable->FootprintLoad( aLibrary, footprintName );
|
||||
|
||||
module_exists = pi->FootprintLoad( aLibPath, footprintName );
|
||||
|
||||
if( module_exists )
|
||||
if( m )
|
||||
{
|
||||
delete module_exists;
|
||||
delete m;
|
||||
|
||||
module_exists = true;
|
||||
|
||||
// an existing footprint is found in current lib
|
||||
if( aDisplayDialog )
|
||||
{
|
||||
wxString msg = wxString::Format( FMT_MOD_EXISTS,
|
||||
footprintName.GetData(), aLibPath.GetData() );
|
||||
footprintName.GetData(), aLibrary.GetData() );
|
||||
|
||||
SetStatusText( msg );
|
||||
}
|
||||
|
@ -669,7 +772,46 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibPath,
|
|||
|
||||
// this always overwrites any existing footprint, but should yell on its
|
||||
// own if the library or footprint is not writable.
|
||||
pi->FootprintSave( aLibPath, aModule );
|
||||
m_footprintLibTable->FootprintSave( aLibrary, aModule );
|
||||
|
||||
#else
|
||||
|
||||
|
||||
IO_MGR::PCB_FILE_T pluginType = IO_MGR::GuessPluginTypeFromLibPath( aLibrary );
|
||||
|
||||
try
|
||||
{
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
|
||||
|
||||
MODULE* m = pi->FootprintLoad( aLibrary, footprintName );
|
||||
|
||||
if( m )
|
||||
{
|
||||
delete m;
|
||||
|
||||
module_exists = true;
|
||||
|
||||
// an existing footprint is found in current lib
|
||||
if( aDisplayDialog )
|
||||
{
|
||||
wxString msg = wxString::Format( FMT_MOD_EXISTS,
|
||||
footprintName.GetData(), aLibrary.GetData() );
|
||||
|
||||
SetStatusText( msg );
|
||||
}
|
||||
|
||||
if( !aOverwrite )
|
||||
{
|
||||
// Do not save the given footprint: an old one exists
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// this always overwrites any existing footprint, but should yell on its
|
||||
// own if the library or footprint is not writable.
|
||||
pi->FootprintSave( aLibrary, aModule );
|
||||
#endif
|
||||
|
||||
}
|
||||
catch( IO_ERROR ioe )
|
||||
{
|
||||
|
@ -680,10 +822,10 @@ bool PCB_BASE_FRAME::Save_Module_In_Library( const wxString& aLibPath,
|
|||
if( aDisplayDialog )
|
||||
{
|
||||
wxString fmt = module_exists ?
|
||||
_( "Component [%s] replaced in <%s>" ) :
|
||||
_( "Component [%s] added in <%s>" );
|
||||
_( "Component [%s] replaced in '%s'" ) :
|
||||
_( "Component [%s] added in '%s'" );
|
||||
|
||||
wxString msg = wxString::Format( fmt, footprintName.GetData(), aLibPath.GetData() );
|
||||
wxString msg = wxString::Format( fmt, footprintName.GetData(), aLibrary.GetData() );
|
||||
SetStatusText( msg );
|
||||
}
|
||||
|
||||
|
@ -750,10 +892,10 @@ MODULE* PCB_BASE_FRAME::Create_1_Module( const wxString& aModuleName )
|
|||
|
||||
#if !defined( USE_FP_LIB_TABLE )
|
||||
|
||||
void FOOTPRINT_EDIT_FRAME::Select_Active_Library()
|
||||
wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting )
|
||||
{
|
||||
if( g_LibraryNames.GetCount() == 0 )
|
||||
return;
|
||||
return wxEmptyString;
|
||||
|
||||
wxArrayString headers;
|
||||
headers.Add( _( "Library" ) );
|
||||
|
@ -768,37 +910,31 @@ void FOOTPRINT_EDIT_FRAME::Select_Active_Library()
|
|||
itemsToDisplay.push_back( item );
|
||||
}
|
||||
|
||||
EDA_LIST_DIALOG dlg( this, FMT_SELECT_LIB, headers, itemsToDisplay, getLibNickName() );
|
||||
EDA_LIST_DIALOG dlg( this, FMT_SELECT_LIB, headers, itemsToDisplay, aNicknameExisting );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
return;
|
||||
return wxEmptyString;
|
||||
|
||||
wxFileName fileName = wxFileName( wxEmptyString, dlg.GetTextSelection(),
|
||||
LegacyFootprintLibPathExtension );
|
||||
|
||||
fileName = wxGetApp().FindLibraryPath( fileName );
|
||||
|
||||
if( fileName.IsOk() && fileName.FileExists() )
|
||||
{
|
||||
setLibNickName( fileName.GetName() );
|
||||
setLibPath( fileName.GetFullPath() );
|
||||
}
|
||||
else
|
||||
if( !fileName.IsOk() || !fileName.FileExists() )
|
||||
{
|
||||
wxString msg = wxString::Format( FMT_BAD_PATHS, GetChars( dlg.GetTextSelection() ) );
|
||||
|
||||
DisplayError( this, msg );
|
||||
|
||||
setLibNickName( wxEmptyString );
|
||||
setLibPath( wxEmptyString );
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
updateTitle();
|
||||
return fileName.GetFullPath();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void FOOTPRINT_EDIT_FRAME::Select_Active_Library()
|
||||
wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting )
|
||||
{
|
||||
wxArrayString headers;
|
||||
|
||||
|
@ -818,18 +954,16 @@ void FOOTPRINT_EDIT_FRAME::Select_Active_Library()
|
|||
itemsToDisplay.push_back( item );
|
||||
}
|
||||
|
||||
EDA_LIST_DIALOG dlg( this, FMT_SELECT_LIB, headers, itemsToDisplay, getLibNickName() );
|
||||
EDA_LIST_DIALOG dlg( this, FMT_SELECT_LIB, headers, itemsToDisplay, aNicknameExisting );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
return;
|
||||
return wxEmptyString;
|
||||
|
||||
wxString nickname = dlg.GetTextSelection();
|
||||
|
||||
setLibNickName( nickname );
|
||||
wxLogDebug( wxT( "Chose footprint library '%s'." ), GetChars( nickname ) );
|
||||
|
||||
wxLogDebug( wxT( "Chose footprint library <%s>." ), GetChars( nickname ) );
|
||||
|
||||
updateTitle();
|
||||
return nickname;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -249,7 +249,22 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||
break;
|
||||
|
||||
case ID_MODEDIT_SELECT_CURRENT_LIB:
|
||||
Select_Active_Library();
|
||||
{
|
||||
wxString library = SelectLibrary( getLibNickName() );
|
||||
|
||||
if( library.size() )
|
||||
{
|
||||
#if defined(USE_FP_LIB_TABLE)
|
||||
setLibNickName( library );
|
||||
#else
|
||||
wxFileName fileName( library );
|
||||
|
||||
setLibNickName( fileName.GetName() );
|
||||
setLibPath( fileName.GetFullPath() );
|
||||
#endif
|
||||
updateTitle();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_OPEN_MODULE_VIEWER:
|
||||
|
@ -349,11 +364,19 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||
break;
|
||||
|
||||
case ID_MODEDIT_SAVE_LIBMODULE:
|
||||
#if defined(USE_FP_LIB_TABLE)
|
||||
if( GetBoard()->m_Modules && getLibNickName().size() )
|
||||
{
|
||||
Save_Module_In_Library( getLibNickName(), GetBoard()->m_Modules, true, true );
|
||||
GetScreen()->ClrModify();
|
||||
}
|
||||
#else
|
||||
if( GetBoard()->m_Modules && getLibPath() != wxEmptyString )
|
||||
{
|
||||
Save_Module_In_Library( getLibPath(), GetBoard()->m_Modules, true, true );
|
||||
GetScreen()->ClrModify();
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ID_MODEDIT_INSERT_MODULE_IN_BOARD:
|
||||
|
|
|
@ -401,8 +401,6 @@ public:
|
|||
*/
|
||||
bool DeleteModuleFromCurrentLibrary();
|
||||
|
||||
void Select_Active_Library();
|
||||
|
||||
virtual EDA_COLOR_T GetGridColor( void ) const;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
|
|
@ -363,9 +363,15 @@ void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
|||
case wxID_YES:
|
||||
// code from FOOTPRINT_EDIT_FRAME::Process_Special_Functions,
|
||||
// at case ID_MODEDIT_SAVE_LIBMODULE
|
||||
#if defined(USE_FP_LIB_TABLE)
|
||||
if( GetBoard()->m_Modules && getLibNickName().size() )
|
||||
{
|
||||
if( Save_Module_In_Library( getLibNickName(), GetBoard()->m_Modules, true, true ) )
|
||||
#else
|
||||
if( GetBoard()->m_Modules && getLibPath() != wxEmptyString )
|
||||
{
|
||||
if( Save_Module_In_Library( getLibPath(), GetBoard()->m_Modules, true, true ) )
|
||||
#endif
|
||||
{
|
||||
// save was correct
|
||||
GetScreen()->ClrModify();
|
||||
|
|
|
@ -55,19 +55,15 @@ PCAD_PLUGIN::~PCAD_PLUGIN()
|
|||
}
|
||||
|
||||
|
||||
const wxString& PCAD_PLUGIN::PluginName() const
|
||||
const wxString PCAD_PLUGIN::PluginName() const
|
||||
{
|
||||
static const wxString name = wxT( "P-Cad" );
|
||||
|
||||
return name;
|
||||
return wxT( "P-Cad" );
|
||||
}
|
||||
|
||||
|
||||
const wxString& PCAD_PLUGIN::GetFileExtension() const
|
||||
const wxString PCAD_PLUGIN::GetFileExtension() const
|
||||
{
|
||||
static const wxString extension = wxT( "pcb" );
|
||||
|
||||
return extension;
|
||||
return wxT( "pcb" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,18 +39,19 @@ public:
|
|||
|
||||
// -----<PUBLIC PLUGIN API>--------------------------------------------------
|
||||
|
||||
const wxString& PluginName() const;
|
||||
const wxString PluginName() const;
|
||||
|
||||
BOARD* Load( const wxString& aFileName,
|
||||
BOARD* aAppendToMe,
|
||||
const PROPERTIES* aProperties = NULL );
|
||||
|
||||
const wxString& GetFileExtension() const;
|
||||
const wxString GetFileExtension() const;
|
||||
|
||||
// -----</PUBLIC PLUGIN API>-------------------------------------------------
|
||||
|
||||
PCAD_PLUGIN();
|
||||
~PCAD_PLUGIN();
|
||||
|
||||
private:
|
||||
const PROPERTIES* m_props;
|
||||
BOARD* m_board;
|
||||
|
|
Loading…
Reference in New Issue