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

*) 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
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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 );
}
+1 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ set( COMMON_SRCS
    msgpanel.cpp
    netlist_keywords.cpp
    newstroke_font.cpp
    prependpath.cpp
    project.cpp
    ptree.cpp
    reporter.cpp
+3 −1
Original line number Diff line number Diff line
@@ -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 );
+58 −20
Original line number Diff line number Diff line
@@ -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,18 +86,48 @@ 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;
}

common/prependpath.cpp

0 → 100644
+70 −0
Original line number Diff line number Diff line

#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] );
}
Loading