Commit 5f65d0da authored by Dick Hollenbeck's avatar Dick Hollenbeck

*) Add KIFACE_I::StartFlags() and IsSingle() so a KIFACE implementation can know

    if it is running under single_top.cpp or under a project manager.

*)  Test Kiface().IsSingle() when adding menus, some operations are not permitted
    when running under a project manager and the KIWAY_PLAYER is pegged to a
    specific project.

*)  Implemented KIWAY::KiFACE() so it loads *.kiface files.  They still have to be
    in the same directory as the main *.exe launcher, so this presents some difficulty
    when the binaries are not yet installed but rather the *.kiface files are still
    in their original build directories.  For today, I simply copied _pcbnew.kiface
    to build/kicad/.

*)  Add a test case to kicad/mainframe.cpp just to get an early peek at loading
    _pcbnew.kiface under the C++ project manager.  Got that working for one
    specific invocation just for proof of concept.  Surprise, it works.
parent e52d9342
......@@ -639,7 +639,7 @@ namespace BMP2CMP {
static struct IFACE : public KIFACE_I
{
bool OnKifaceStart( PGM_BASE* aProgram );
bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
wxWindow* CreateWindow( wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 )
{
......@@ -706,8 +706,8 @@ PGM_BASE& Pgm()
#endif
bool IFACE::OnKifaceStart( PGM_BASE* aProgram )
bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
{
return start_common();
return start_common( aCtlBits );
}
......@@ -186,6 +186,7 @@ set( COMMON_SRCS
msgpanel.cpp
netlist_keywords.cpp
newstroke_font.cpp
prependpath.cpp
project.cpp
ptree.cpp
reporter.cpp
......
......@@ -94,8 +94,10 @@ static void setSearchPaths( SEARCH_STACK* aDst, KIWAY::FACE_T aId )
}
bool KIFACE_I::start_common()
bool KIFACE_I::start_common( int aCtlBits )
{
m_start_flags = aCtlBits;
m_bm.Init();
m_bm.m_config->Read( showPageLimitsKey, &g_ShowPageLimits );
......
......@@ -22,15 +22,12 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <string.h>
#include <kiway.h>
#include <config.h>
#include <wx/debug.h>
#include <string.h>
// one for each FACE_T
wxDynamicLibrary KIWAY::s_sch_dso;
wxDynamicLibrary KIWAY::s_pcb_dso;
#include <wx/stdpaths.h>
KIWAY::KIWAY()
......@@ -39,20 +36,30 @@ KIWAY::KIWAY()
}
/*
const wxString KIWAY::dso_name( FACE_T aFaceId )
const wxString KIWAY::dso_full_path( FACE_T aFaceId )
{
const wxChar* name = wxT("");
switch( aFaceId )
{
case FACE_SCH: return KIFACE_PREFIX wxT( "eeschema" ) KIFACE_SUFFIX;
case FACE_PCB: return KIFACE_PREFIX wxT( "pcbnew" ) KIFACE_SUFFIX;
case FACE_SCH: name = KIFACE_PREFIX wxT( "eeschema" ); break;
case FACE_PCB: name = KIFACE_PREFIX wxT( "pcbnew" ); break;
default:
wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
return wxEmptyString;
}
wxFileName fn = wxStandardPaths::Get().GetExecutablePath();
fn.SetName( name );
// Here a "suffix" == an extension with a preceding '.',
// so skip the preceding '.' to get an extension
fn.SetExt( KIFACE_SUFFIX + 1 ); // + 1 => &KIFACE_SUFFIX[1]
return fn.GetFullPath();
}
*/
PROJECT& KIWAY::Prj() const
......@@ -61,14 +68,15 @@ PROJECT& KIWAY::Prj() const
}
KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
KIFACE* KIWAY::KiFACE( PGM_BASE* aProgram, FACE_T aFaceId, bool doLoad )
{
switch( aFaceId )
{
case FACE_SCH:
// case FACE_SCH:
case FACE_PCB:
if( m_kiface[aFaceId] )
return m_kiface[aFaceId];
break;
default:
wxASSERT_MSG( 0, wxT( "caller has a bug, passed a bad aFaceId" ) );
......@@ -78,17 +86,47 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
// DSO with KIFACE has not been loaded yet, does user want to load it?
if( doLoad )
{
switch( aFaceId )
wxString dname = dso_full_path( aFaceId );
wxDynamicLibrary dso;
void* addr = NULL;
if( !dso.Load( dname, wxDL_VERBATIM | wxDL_NOW ) )
{
case FACE_SCH:
break;
// Failure: error reporting UI was done via wxLogSysError().
// No further reporting required here.
}
case FACE_PCB:
break;
else if( ( addr = dso.GetSymbol( wxT( KIFACE_INSTANCE_NAME_AND_VERSION ) ) ) == NULL )
{
// Failure: error reporting UI was done via wxLogSysError().
// No further reporting required here.
}
default:
;
else
{
KIFACE_GETTER_FUNC* getter = (KIFACE_GETTER_FUNC*) addr;
KIFACE* kiface = getter( &m_kiface_version[aFaceId], KIFACE_VERSION, aProgram );
// KIFACE_GETTER_FUNC function comment (API) says the non-NULL is unconditional.
wxASSERT_MSG( kiface,
wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) );
// Give the DSO a single chance to do its "process level" initialization.
// "Process level" specifically means stay away from any projects in there.
if( kiface->OnKifaceStart( aProgram, KFCTL_PROJECT_SUITE ) )
{
// Tell dso's wxDynamicLibrary destructor not to Unload() the program image.
(void) dso.Detach();
return m_kiface[aFaceId] = kiface;
}
}
// In any of the failure cases above, dso.Unload() should be called here
// by dso destructor.
}
return NULL;
......
#include <macros.h>
#include <fctsys.h>
#include <wx/filename.h>
#if !wxCHECK_VERSION( 3, 0, 0 )
// implement missing wx2.8 function until >= wx3.0 pervades.
static wxString wxJoin(const wxArrayString& arr, const wxChar sep,
const wxChar escape = '\\')
{
size_t count = arr.size();
if ( count == 0 )
return wxEmptyString;
wxString str;
// pre-allocate memory using the estimation of the average length of the
// strings in the given array: this is very imprecise, of course, but
// better than nothing
str.reserve(count*(arr[0].length() + arr[count-1].length()) / 2);
if ( escape == wxT('\0') )
{
// escaping is disabled:
for ( size_t i = 0; i < count; i++ )
{
if ( i )
str += sep;
str += arr[i];
}
}
else // use escape character
{
for ( size_t n = 0; n < count; n++ )
{
if ( n )
str += sep;
for ( wxString::const_iterator i = arr[n].begin(),
end = arr[n].end();
i != end;
++i )
{
const wxChar ch = *i;
if ( ch == sep )
str += escape; // escape this separator
str += ch;
}
}
}
str.Shrink(); // release extra memory if we allocated too much
return str;
}
#endif
/// Put aPriorityPath in front of all paths in the value of aEnvVar.
const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath )
{
wxPathList paths;
paths.AddEnvList( aEnvVar );
paths.Insert( aPriorityPath, 0 );
return wxJoin( paths, wxPATH_SEP[0] );
}
......@@ -43,14 +43,13 @@ PROJECT::PROJECT()
PROJECT::~PROJECT()
{
/* @todo
careful here, this may work, but the virtual destructor may not
be in the same link image as PROJECT. Won't enable this until
we're more stable and destructor is assuredly in same image, i.e.
libki.so
#if 1
// careful here, this may work, but the virtual destructor may not
// be in the same link image as PROJECT.
for( unsigned i = 0; i<DIM(m_elems); ++i )
delete m_elems[i];
*/
#endif
}
......@@ -305,7 +304,7 @@ wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, const wxString&
void PROJECT::ConfigSave( const SEARCH_STACK& aSList, const wxString& aFileName,
const wxString& aGroupName, const PARAM_CFG_ARRAY& aParams )
{
std::auto_ptr<wxConfigBase> cfg( configCreate( aSList, aFileName, aGroupName, FORCE_LOCAL_CONFIG ) );
std::auto_ptr<wxConfigBase> cfg( configCreate( aSList, aFileName, aGroupName, true ) );
if( !cfg.get() )
{
......@@ -353,8 +352,7 @@ bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aFileName,
wxString timestamp = cfg->Read( wxT( "update" ) );
if( doLoadOnlyIfNew && timestamp.size() &&
timestamp == m_pro_date_and_time )
if( doLoadOnlyIfNew && timestamp.size() && timestamp == m_pro_date_and_time )
{
return false;
}
......
......@@ -51,74 +51,8 @@
// The functions we use will cause the program launcher to pull stuff in
// during linkage, keep the map file in mind to see what's going into it.
#if !wxCHECK_VERSION( 3, 0, 0 )
// implement missing wx2.8 function until >= wx3.0 pervades.
static wxString wxJoin(const wxArrayString& arr, const wxChar sep,
const wxChar escape = '\\')
{
size_t count = arr.size();
if ( count == 0 )
return wxEmptyString;
wxString str;
// pre-allocate memory using the estimation of the average length of the
// strings in the given array: this is very imprecise, of course, but
// better than nothing
str.reserve(count*(arr[0].length() + arr[count-1].length()) / 2);
if ( escape == wxT('\0') )
{
// escaping is disabled:
for ( size_t i = 0; i < count; i++ )
{
if ( i )
str += sep;
str += arr[i];
}
}
else // use escape character
{
for ( size_t n = 0; n < count; n++ )
{
if ( n )
str += sep;
for ( wxString::const_iterator i = arr[n].begin(),
end = arr[n].end();
i != end;
++i )
{
const wxChar ch = *i;
if ( ch == sep )
str += escape; // escape this separator
str += ch;
}
}
}
str.Shrink(); // release extra memory if we allocated too much
return str;
}
#endif
/// Put aPriorityPath in front of all paths in the value of aEnvVar.
const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath )
{
wxPathList paths;
paths.AddEnvList( aEnvVar );
paths.Insert( aPriorityPath, 0 );
return wxJoin( paths, wxPATH_SEP[0] );
}
/// Extend LIB_ENV_VAR list with the directory from which I came, prepending it.
void SetLibEnvVar( const wxString& aAbsoluteArgv0 )
static void set_lib_env_var( const wxString& aAbsoluteArgv0 )
{
// POLICY CHOICE 2: Keep same path, so that installer MAY put the
// "subsidiary DSOs" in the same directory as the kiway top process modules.
......@@ -149,6 +83,7 @@ void SetLibEnvVar( const wxString& aAbsoluteArgv0 )
#endif
}
// POLICY CHOICE 1: return the full path of the DSO to load from single_top.
static const wxString dso_full_path( const wxString& aAbsoluteArgv0 )
{
......@@ -339,7 +274,7 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp )
// Set LIB_ENV_VAR *before* loading the DSO, in case the top-level DSO holding the
// KIFACE has hard dependencies on subsidiary DSOs below it.
SetLibEnvVar( absoluteArgv0 );
set_lib_env_var( absoluteArgv0 );
if( !initPgm() )
return false;
......@@ -364,7 +299,7 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp )
// Give the DSO a single chance to do its "process level" initialization.
// "Process level" specifically means stay away from any projects in there.
if( !kiface->OnKifaceStart( this ) )
if( !kiface->OnKifaceStart( this, KFCTL_STANDALONE ) )
return false;
// Use KIFACE to create a top window that the KIFACE knows about.
......@@ -418,8 +353,11 @@ bool PGM_SINGLE_TOP::OnPgmInit( wxApp* aWxApp )
if( !argv1.GetExt() )
argv1.SetExt( wxT( PGM_DATA_FILE_EXT ) );
argSet[0] = argv1.GetFullPath();
#endif
argv1.MakeAbsolute();
argSet[0] = argv1.GetFullPath();
if( !Pgm().LockFile( argSet[0] ) )
{
wxLogSysError( _( "This file is already open." ) );
......
......@@ -100,7 +100,7 @@ static struct IFACE : public KIFACE_I
KIFACE_I( aName, aType )
{}
bool OnKifaceStart( PGM_BASE* aProgram );
bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
void OnKifaceEnd();
......@@ -276,13 +276,13 @@ FP_LIB_TABLE GFootprintTable;
// we skip setting KISYSMOD here for now. User should set the environment
// variable.
bool IFACE::OnKifaceStart( PGM_BASE* aProgram )
bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
{
// This is process level, not project level, initialization of the DSO.
// Do nothing in here pertinent to a project!
start_common();
start_common( aCtlBits );
// Set 3D shape path from environment variable KISYS3DMOD
set3DShapesPath( wxT("KISYS3DMOD") );
......
......@@ -720,8 +720,7 @@ int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
return 0;
}
wxString msg;
msg.Printf( _("File %s saved"), GetChars( fn.GetFullPath() ) );
wxString msg = wxString::Format( _("File %s saved"), GetChars( fn.GetFullPath() ) );
SetStatusText( msg );
return 1;
}
......@@ -68,7 +68,7 @@ static struct IFACE : public KIFACE_I
KIFACE_I( aName, aType )
{}
bool OnKifaceStart( PGM_BASE* aProgram );
bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
void OnKifaceEnd( PGM_BASE* aProgram )
{
......@@ -79,14 +79,6 @@ static struct IFACE : public KIFACE_I
{
switch( aClassId )
{
case LIBEDITOR_FRAME_TYPE:
{
LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway,
dynamic_cast<SCH_EDIT_FRAME*>( aParent ) );
return frame;
}
break;
case SCHEMATIC_FRAME_TYPE:
{
SCH_EDIT_FRAME* frame = new SCH_EDIT_FRAME( aKiway, aParent );
......@@ -96,9 +88,19 @@ static struct IFACE : public KIFACE_I
// Read a default config file in case no project given on command line.
frame->LoadProjectFile( wxEmptyString, true );
// @todo temporary
CreateServer( frame, KICAD_SCH_PORT_SERVICE_NUMBER );
if( Kiface().IsSingle() )
{
// only run this under single_top, not under a project manager.
CreateServer( frame, KICAD_SCH_PORT_SERVICE_NUMBER );
}
return frame;
}
break;
case LIBEDITOR_FRAME_TYPE:
{
LIB_EDIT_FRAME* frame = new LIB_EDIT_FRAME( aKiway,
dynamic_cast<SCH_EDIT_FRAME*>( aParent ) );
return frame;
}
break;
......@@ -152,13 +154,13 @@ PGM_BASE& Pgm()
}
bool IFACE::OnKifaceStart( PGM_BASE* aProgram )
bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
{
// This is process level, not project level, initialization of the DSO.
// Do nothing in here pertinent to a project!
start_common();
start_common( aCtlBits );
// Give a default colour for all layers
// (actual color will be initialized by config)
......
......@@ -819,7 +819,9 @@ void SCH_EDIT_FRAME::OnOpenLibraryEditor( wxCommandEvent& event )
}
else
{
wxWindow* w = Kiface().CreateWindow( this, LIBEDITOR_FRAME_TYPE, &Kiway() );
KIFACE_I& kf = Kiface();
wxWindow* w = kf.CreateWindow( this, LIBEDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() );
libeditFrame = dynamic_cast<LIB_EDIT_FRAME*>( w );
}
......
......@@ -73,7 +73,7 @@ static struct IFACE : public KIFACE_I
KIFACE_I( aName, aType )
{}
bool OnKifaceStart( PGM_BASE* aProgram );
bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
void OnKifaceEnd();
......@@ -145,9 +145,9 @@ PGM_BASE& Pgm()
}
bool IFACE::OnKifaceStart( PGM_BASE* aProgram )
bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
{
start_common();
start_common( aCtlBits );
// Must be called before creating the main frame in order to
// display the real hotkeys in menus or tool tips
......
......@@ -610,4 +610,8 @@ void SystemDirsAppend( SEARCH_STACK* aSearchStack );
wxString SearchHelpFileFullPath( const SEARCH_STACK& aSearchStack, const wxString& aBaseName );
/// Put aPriorityPath in front of all paths in the value of aEnvVar.
const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPath );
#endif // INCLUDE__COMMON_H_
......@@ -49,7 +49,6 @@
#define CONFIG_VERSION 1
#define FORCE_LOCAL_CONFIG true
/**
......
......@@ -43,7 +43,7 @@ public:
// see base class KIFACE in kiway.h for doxygen docs
VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram ) = 0;
VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) = 0;
/*
{
typically call start_common() in your overload
......@@ -58,7 +58,7 @@ public:
}
VTBL_ENTRY wxWindow* CreateWindow( wxWindow* aParent,
int aClassId, KIWAY* aKIWAY, int aCtlBits = 0 ) = 0;
int aClassId, KIWAY* aKIWAY, int aCtlBits ) = 0;
VTBL_ENTRY void* IfaceOrAddress( int aDataId ) = 0;
......@@ -76,7 +76,8 @@ public:
*/
KIFACE_I( const char* aKifaceName, KIWAY::FACE_T aId ) :
m_id( aId ),
m_bm( aKifaceName )
m_bm( aKifaceName ),
m_start_flags( 0 )
{
}
......@@ -85,7 +86,7 @@ public:
protected:
/// Common things to do for a top program module, during OnKifaceStart().
bool start_common();
bool start_common( int aCtlBits );
/// Common things to do for a top program module, during OnKifaceEnd();
void end_common();
......@@ -100,6 +101,18 @@ public:
wxConfigBase* KifaceSettings() const { return m_bm.m_config; }
/**
* Function StartFlags
* returns whatever was passed as @a aCtlBits to OnKifaceStart()
*/
int StartFlags() const { return m_start_flags; }
/**
* Function IsSingle
* is this KIFACE_I running under single_top?
*/
bool IsSingle() const { return m_start_flags & KFCTL_STANDALONE; }
/**
* Function GetHelpFileName
* returns just the basename portion of the current help file.
......@@ -116,6 +129,8 @@ private:
KIWAY::FACE_T m_id;
BIN_MOD m_bm;
int m_start_flags; ///< flags provided in OnKifaceStart()
};
......
......@@ -112,25 +112,20 @@ as such! As such, it is OK to use UTF8 characters:
// be mangled.
#define KIFACE_INSTANCE_NAME_AND_VERSION "KIFACE_1"
#if defined(__linux__)
#define LIB_ENV_VAR wxT( "LD_LIBRARY_PATH" )
#elif defined(__WXMAC__)
#define LIB_ENV_VAR wxT( "DYLD_LIBRARY_PATH" )
#elif defined(__MINGW32__)
#define LIB_ENV_VAR wxT( "PATH" )
#endif
class wxConfigBase;
class KIWAY;
class wxWindow;
class PGM_BASE;
class wxConfigBase;
class PGM_BASE;
class KIWAY;
/**
......@@ -151,6 +146,10 @@ struct KIFACE
// order of functions in this listing unless you recompile all clients of
// this interface.
#define KFCTL_STANDALONE (1<<0) ///< Am running as a standalone Top.
#define KFCTL_PROJECT_SUITE (1<<1) ///< Am running under a project mgr, possibly with others
/**
* Function OnKifaceStart
* is called just once shortly after the DSO is loaded. It is the second
......@@ -161,13 +160,15 @@ struct KIFACE
*
* @param aProgram is the process block: PGM_BASE*
*
* @param aCtlBits consists of bit flags from the set of KFCTL_* \#defines above.
*
* @return bool - true if DSO initialized OK, false if not. When returning
* false, the loader may optionally decide to terminate the process or not,
* but will not put out any UI because that is the duty of this function to say
* why it is returning false. Never return false without having reported
* to the UI why.
*/
VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram ) = 0;
VTBL_ENTRY bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) = 0;
/**
* Function OnKifaceEnd
......@@ -176,8 +177,6 @@ struct KIFACE
*/
VTBL_ENTRY void OnKifaceEnd() = 0;
#define KFCTL_STANDALONE (1<<0) ///< Am running as a standalone Top.
/**
* Function CreateWindow
* creates a wxWindow for the current project. The caller
......@@ -199,7 +198,7 @@ struct KIFACE
* not contained in the caller's link image.
*/
VTBL_ENTRY wxWindow* CreateWindow( wxWindow* aParent, int aClassId,
KIWAY* aKIWAY, int aCtlBits = 0 ) = 0;
KIWAY* aKIWAY, int aCtlBits ) = 0;
/**
* Function IfaceOrAddress
......@@ -249,7 +248,7 @@ class KIWAY : public wxEvtHandler
{
public:
/// DSO players on *this* KIWAY
/// Possible KIFACEs on *this* KIWAY
enum FACE_T
{
FACE_SCH, ///< eeschema DSO
......@@ -257,6 +256,7 @@ public:
FACE_PCB, ///< pcbnew DSO
// FACE_MOD,
FACE_CVPCB,
FACE_BMP2CMP,
FACE_GERBVIEW,
FACE_PL_EDITOR,
......@@ -265,41 +265,28 @@ public:
FACE_COUNT, ///< how many KIWAY player types
};
/* from edaappl.h, now pgm_base.h, obsoleted by above FACE_T enum.
enum PGM_BASE_T
{
APP_UNKNOWN,
APP_EESCHEMA,
APP_PCBNEW,
APP_CVPCB,
APP_GERBVIEW,
APP_KICAD,
APP_PL_EDITOR,
APP_BM2CMP,
};
*/
// If you change the vtable, recompile all of KiCad.
// Don't change the order of these VTBL_ENTRYs, add new ones at the end,
// unless you recompile all of KiCad.
VTBL_ENTRY KIFACE* KiFACE( FACE_T aFaceId, bool doLoad );
/**
* Function KiFACE
* returns the KIFACE* given a FACE_T. If it is not already loaded, the
* KIFACE is loaded and initialized with a call to KIFACE::OnKifaceStart()
*/
VTBL_ENTRY KIFACE* KiFACE( PGM_BASE* aProgram,
FACE_T aFaceId, bool doLoad = true );
VTBL_ENTRY PROJECT& Prj() const;
KIWAY();
private:
/*
/// Get the name of the DSO holding the requested FACE_T.
static const wxString dso_name( FACE_T aFaceId );
*/
// one for each FACE_T
static wxDynamicLibrary s_sch_dso;
static wxDynamicLibrary s_pcb_dso;
//static wxDynamicLibrary s_cvpcb_dso; // will get merged into pcbnew
/// Get the full path & name of the DSO holding the requested FACE_T.
static const wxString dso_full_path( FACE_T aFaceId );
KIFACE* m_kiface[FACE_COUNT];
int m_kiface_version[FACE_COUNT];
PROJECT m_project; // do not assume this is here, use Prj().
};
......
#ifndef KIWAY_MGR_H_
#define KIWAY_MGR_H_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2014 KiCad Developers, see CHANGELOG.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
*/
#include <kiway.h>
#include <boost/ptr_container/ptr_vector.hpp>
/**
* Class KIWAY_MGR
* is a container for all KIWAYS [and PROJECTS]. This class needs to work both
* for a C++ project manager and an a wxPython one (after being moved into a
* header later).
*/
class KIWAY_MGR
{
public:
//KIWAY_MGR();
// ~KIWAY_MGR();
bool OnStart( wxApp* aProcess );
void OnEnd();
KIWAY& operator[]( int aIndex )
{
wxASSERT( m_kiways.size() ); // stuffed in OnStart()
return m_kiways[aIndex];
}
private:
// KIWAYs may not be moved once doled out, since window DNA depends on the
// pointer being good forever.
// boost_ptr::vector however never moves the object pointed to.
typedef boost::ptr_vector<KIWAY> KIWAYS;
KIWAYS m_kiways;
};
extern KIWAY_MGR Kiways;
#endif // KIWAY_MGR_H_
......@@ -130,7 +130,7 @@ public:
* <p>
* Each derived class should handle this in a way specific to its needs.
* No prompting is done inside here for any file or project. There should be
* need to call this with aFileList which is empty. However, calling it with
* no need to call this with aFileList which is empty. However, calling it with
* a single filename which does not exist should indicate to the implementor
* that a new session is being started and that the given name is the desired
* name for the data file at time of save.
......@@ -166,4 +166,51 @@ public:
}
};
// psuedo code for OpenProjectFiles
#if 0
bool OpenProjectFiles( const std::vector<wxString>& aFileList, int aCtl = 0 )
{
if( aFileList.size() != 1 )
{
complain via UI.
return false
}
assert( aFileList[0] is absolute ) // bug in single_top.cpp or project manager.
if (window does not support appending) || !(aCtl & KICTL_OPEN_APPEND)
{
close any currently open project files.
}
if( aFileList[0] does not exist )
{
notify user file does not exist.
create an empty project file
mark file as modified.
use the default project config file.
}
else
{
load aFileList[0]
use the project config file for project given by aFileList[0]s full path.
}
UpdateTitle();
show contents.
}
#endif
#endif // KIWAY_PLAYER_H_
......@@ -59,7 +59,7 @@ int LAUNCHER_PANEL::GetPanelHeight() const
* Function CreateCommandToolbar
* create the buttons to call Eeschema CvPcb, Pcbnew and GerbView
*/
void LAUNCHER_PANEL::CreateCommandToolbar( void )
void LAUNCHER_PANEL::CreateCommandToolbar()
{
wxBitmapButton* btn;
......
......@@ -28,10 +28,11 @@
*/
#include <macros.h>
#include <fctsys.h>
#include <wx/stdpaths.h>
#include <kicad.h>
#include <kiway.h>
#include <kiway_mgr.h>
#include <pgm_kicad.h>
#include <tree_project_frame.h>
#include <online_help.h>
......@@ -40,6 +41,40 @@
#include <build_version.h>
/// Extend LIB_ENV_VAR list with the directory from which I came, prepending it.
static void set_lib_env_var( const wxString& aAbsoluteArgv0 )
{
// POLICY CHOICE 2: Keep same path, so that installer MAY put the
// "subsidiary DSOs" in the same directory as the kiway top process modules.
// A subsidiary shared library is one that is not a top level DSO, but rather
// some shared library that a top level DSO needs to even be loaded. It is
// a static link to a shared object from a top level DSO.
// This directory POLICY CHOICE 2 is not the only dir in play, since LIB_ENV_VAR
// has numerous path options in it, as does DSO searching on linux, windows, and OSX.
// See "man ldconfig" on linux. What's being done here is for quick installs
// into a non-standard place, and especially for Windows users who may not
// know what the PATH environment variable is or how to set it.
wxFileName fn( aAbsoluteArgv0 );
wxString ld_path( LIB_ENV_VAR );
wxString my_path = fn.GetPath();
wxString new_paths = PrePendPath( ld_path, my_path );
wxSetEnv( ld_path, new_paths );
#if defined(DEBUG)
{
wxString test;
wxGetEnv( ld_path, &test );
printf( "LIB_ENV_VAR:'%s'\n", TO_UTF8( test ) );
}
#endif
}
// a dummy to quiet linking with EDA_BASE_FRAME::config();
#include <kiface_i.h>
KIFACE_I& Kiface()
......@@ -62,7 +97,6 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp )
m_bm.Init();
#if 0 // copied from single_top.c, possibly for milestone B)
wxString absoluteArgv0 = wxStandardPaths::Get().GetExecutablePath();
if( !wxIsAbsolutePath( absoluteArgv0 ) )
......@@ -71,10 +105,9 @@ bool PGM_KICAD::OnPgmInit( wxApp* aWxApp )
return false;
}
// Set LIB_ENV_VAR *before* loading the DSO, in case the top-level DSO holding the
// KIFACE has hard dependencies on subsidiary DSOs below it.
SetLibEnvVar( absoluteArgv0 );
#endif
// Set LIB_ENV_VAR *before* loading the KIFACE DSOs, in case they have hard
// dependencies on subsidiary DSOs below it.
set_lib_env_var( absoluteArgv0 );
if( !initPgm() )
return false;
......@@ -218,39 +251,7 @@ void PGM_KICAD::destroy()
}
/**
* Class KIWAY_MGR
* is a container for all KIWAYS [and PROJECTS]. This class needs to work both
* for a C++ project manager and an a wxPython one (after being moved into a
* header later).
*/
class KIWAY_MGR
{
public:
//KIWAY_MGR();
// ~KIWAY_MGR();
bool OnStart( wxApp* aProcess );
void OnEnd();
KIWAY& operator[]( int aIndex )
{
wxASSERT( m_kiways.size() ); // stuffed in OnStart()
return m_kiways[aIndex];
}
private:
// KIWAYs may not be moved once doled out, since window DNA depends on the
// pointer being good forever.
// boost_ptr::vector however never moves the object pointed to.
typedef boost::ptr_vector<KIWAY> KIWAYS;
KIWAYS m_kiways;
};
static KIWAY_MGR kiways;
KIWAY_MGR Kiways;
/**
......@@ -261,7 +262,7 @@ struct APP_KICAD : public wxApp
{
bool OnInit() // overload wxApp virtual
{
if( kiways.OnStart( this ) )
if( Kiways.OnStart( this ) )
{
return Pgm().OnPgmInit( this );
}
......@@ -270,7 +271,7 @@ struct APP_KICAD : public wxApp
int OnExit() // overload wxApp virtual
{
kiways.OnEnd();
Kiways.OnEnd();
Pgm().OnPgmExit();
......@@ -296,7 +297,7 @@ IMPLEMENT_APP( APP_KICAD );
// this link image need this function.
PROJECT& Prj()
{
return kiways[0].Prj();
return Kiways[0].Prj();
}
......
......@@ -30,6 +30,8 @@
#include <fctsys.h>
#include <pgm_kicad.h>
#include <kiway_mgr.h>
#include <kiway_player.h>
#include <confirm.h>
#include <gestfich.h>
#include <macros.h>
......@@ -238,10 +240,23 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event )
legacy_board.SetExt( LegacyPcbFileExtension );
kicad_board.SetExt( KiCadPcbFileExtension );
if( !legacy_board.FileExists() || kicad_board.FileExists() )
Execute( this, PCBNEW_EXE, QuoteFullPath( kicad_board ) );
else
Execute( this, PCBNEW_EXE, QuoteFullPath( legacy_board ) );
wxFileName& board = ( !legacy_board.FileExists() || kicad_board.FileExists() ) ?
kicad_board : legacy_board;
#if 0 // it works!
KIFACE* kiface = Kiways[0].KiFACE( &Pgm(), KIWAY::FACE_PCB );
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) kiface->CreateWindow( this, PCB_FRAME_TYPE, &Kiways[0], KFCTL_PROJECT_SUITE );
frame->OpenProjectFiles( std::vector<wxString>( 1, board.GetFullPath() ) );
frame->Show( true );
frame->Raise();
#else
Execute( this, PCBNEW_EXE, QuoteFullPath( board ) );
#endif
}
......
......@@ -54,7 +54,7 @@ static struct IFACE : public KIFACE_I
KIFACE_I( aName, aType )
{}
bool OnKifaceStart( PGM_BASE* aProgram );
bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
void OnKifaceEnd();
......@@ -126,9 +126,9 @@ PGM_BASE& Pgm()
}
bool IFACE::OnKifaceStart( PGM_BASE* aProgram )
bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
{
start_common();
start_common( aCtlBits );
// Must be called before creating the main frame in order to
// display the real hotkeys in menus or tool tips
......
......@@ -55,7 +55,7 @@ static struct IFACE : public KIFACE_I
KIFACE_I( aName, aType )
{}
bool OnKifaceStart( PGM_BASE* aProgram );
bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
void OnKifaceEnd();
......@@ -117,9 +117,9 @@ PGM_BASE& Pgm()
}
bool IFACE::OnKifaceStart( PGM_BASE* aProgram )
bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
{
start_common();
start_common( aCtlBits );
return true;
}
......
......@@ -194,7 +194,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
if( !editor )
{
editor = (FOOTPRINT_EDIT_FRAME*) Kiface().CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway() );
KIFACE_I& kf = Kiface();
editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() );
editor->Show( true );
editor->Zoom_Automatique( false );
......@@ -220,7 +222,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
if( !viewer )
{
viewer = (FOOTPRINT_VIEWER_FRAME*) Kiface().CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway() );
KIFACE_I& kf = Kiface();
viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway(), kf.StartFlags() );
viewer->Show( true );
viewer->Zoom_Automatique( false );
......@@ -839,7 +843,9 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
if( !editor )
{
editor = (FOOTPRINT_EDIT_FRAME*) Kiface().CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway() );
KIFACE_I& kf = Kiface();
editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() );
}
editor->Load_Module_From_BOARD( (MODULE*)GetCurItem() );
......
......@@ -78,7 +78,9 @@ void PCB_EDIT_FRAME::InstallModuleOptionsFrame( MODULE* Module, wxDC* DC )
if( !editor )
{
editor = (FOOTPRINT_EDIT_FRAME*) Kiface().CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway() );
KIFACE_I& kf = Kiface();
editor = (FOOTPRINT_EDIT_FRAME*) kf.CreateWindow( this, MODULE_EDITOR_FRAME_TYPE, &Kiway(), kf.StartFlags() );
}
editor->Load_Module_From_BOARD( Module );
......
This diff is collapsed.
......@@ -271,7 +271,9 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
FOOTPRINT_VIEWER_FRAME* viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer( top_project );
if( !viewer )
{
viewer = (FOOTPRINT_VIEWER_FRAME*) Kiface().CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway() );
KIFACE_I& kf = Kiface();
viewer = (FOOTPRINT_VIEWER_FRAME*) kf.CreateWindow( this, MODULE_VIEWER_FRAME_TYPE, &Kiway(), kf.StartFlags() );
viewer->Show( true );
viewer->Zoom_Automatique( false );
}
......
......@@ -85,9 +85,6 @@
BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_SOCKET( ID_EDA_SOCKET_EVENT_SERV, PCB_EDIT_FRAME::OnSockRequestServer )
EVT_SOCKET( ID_EDA_SOCKET_EVENT, PCB_EDIT_FRAME::OnSockRequest )
EVT_COMBOBOX( ID_ON_ZOOM_SELECT, PCB_EDIT_FRAME::OnSelectZoom )
EVT_COMBOBOX( ID_ON_GRID_SELECT, PCB_EDIT_FRAME::OnSelectGrid )
......@@ -450,7 +447,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
#ifdef KICAD_SCRIPTING_WXPYTHON
#if defined(KICAD_SCRIPTING_WXPYTHON)
// Add the scripting panel
EDA_PANEINFO pythonAuiInfo;
pythonAuiInfo.ScriptingToolbarPane();
......@@ -831,7 +828,7 @@ void PCB_EDIT_FRAME::SetGridColor(EDA_COLOR_T aColor)
}
bool PCB_EDIT_FRAME::IsMicroViaAcceptable( void )
bool PCB_EDIT_FRAME::IsMicroViaAcceptable()
{
int copperlayercnt = GetBoard()->GetCopperLayerCount( );
LAYER_NUM currLayer = getActiveLayer();
......@@ -1106,7 +1103,7 @@ void PCB_EDIT_FRAME::UpdateTitle()
SetTitle( title );
}
#ifdef KICAD_SCRIPTING_WXPYTHON
#if defined(KICAD_SCRIPTING_WXPYTHON)
void PCB_EDIT_FRAME::ScriptingConsoleEnableDisable( wxCommandEvent& aEvent )
{
if ( m_pythonPanelHidden )
......@@ -1171,4 +1168,3 @@ void PCB_EDIT_FRAME::SetRotationAngle( int aRotationAngle )
m_rotationAngle = aRotationAngle;
}
......@@ -101,7 +101,7 @@ static struct IFACE : public KIFACE_I
KIFACE_I( aName, aType )
{}
bool OnKifaceStart( PGM_BASE* aProgram );
bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits );
void OnKifaceEnd();
......@@ -116,14 +116,16 @@ static struct IFACE : public KIFACE_I
frame->Zoom_Automatique( true );
#ifdef KICAD_SCRIPTING
#if defined(KICAD_SCRIPTING)
// give the scripting helpers access to our frame
ScriptingSetPcbEditFrame( frame );
#endif
// @todo temporarily here
CreateServer( frame, KICAD_PCB_PORT_SERVICE_NUMBER );
if( Kiface().IsSingle() )
{
// only run this under single_top, not under a project manager.
CreateServer( frame, KICAD_PCB_PORT_SERVICE_NUMBER );
}
return frame;
}
break;
......@@ -141,7 +143,6 @@ static struct IFACE : public KIFACE_I
/* Read a default config file in case no project given on command line.
frame->LoadProjectFile( wxEmptyString, true );
*/
return frame;
}
break;
......@@ -159,7 +160,6 @@ static struct IFACE : public KIFACE_I
/* Read a default config file in case no project given on command line.
frame->LoadProjectFile( wxEmptyString, true );
*/
return frame;
}
break;
......@@ -411,13 +411,13 @@ static bool scriptingSetup()
FP_LIB_TABLE GFootprintTable;
bool IFACE::OnKifaceStart( PGM_BASE* aProgram )
bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
{
// This is process level, not project level, initialization of the DSO.
// Do nothing in here pertinent to a project!
start_common();
start_common( aCtlBits );
// Must be called before creating the main frame in order to
// display the real hotkeys in menus or tool tips
......
......@@ -234,9 +234,10 @@ void PCB_BASE_FRAME::Build_Board_Ratsnest()
{
NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code );
if( net == NULL ) //Should not occur
if( !net ) // Should not occur
{
wxMessageBox( wxT( "Build_Board_Ratsnest() error: net not found" ) );
UTF8 msg = StrPrintf( "%s: error, net %d not found", __func__, current_net_code );
wxMessageBox( msg ); // BTW, it does happen.
return;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment