diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 53fdaff9e3..176bffeb7c 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -182,7 +182,9 @@ set( COMMON_SRCS html_messagebox.cpp kiface_i.cpp kiway.cpp + kiway_express.cpp kiway_holder.cpp + kiway_player.cpp msgpanel.cpp netlist_keywords.cpp newstroke_font.cpp diff --git a/common/draw_frame.cpp b/common/draw_frame.cpp index 578520263e..75461e5f22 100644 --- a/common/draw_frame.cpp +++ b/common/draw_frame.cpp @@ -64,7 +64,7 @@ static const wxString GridColorEntryKeyword( wxT( "GridColor" ) ); static const wxString LastGridSizeIdKeyword( wxT( "_LastGridSize" ) ); -BEGIN_EVENT_TABLE( EDA_DRAW_FRAME, EDA_BASE_FRAME ) +BEGIN_EVENT_TABLE( EDA_DRAW_FRAME, KIWAY_PLAYER ) EVT_MOUSEWHEEL( EDA_DRAW_FRAME::OnMouseEvent ) EVT_MENU_OPEN( EDA_DRAW_FRAME::OnMenuOpen ) EVT_ACTIVATE( EDA_DRAW_FRAME::OnActivate ) diff --git a/common/kiway.cpp b/common/kiway.cpp index 5ee0300f9b..72e31aad3e 100644 --- a/common/kiway.cpp +++ b/common/kiway.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -292,3 +293,31 @@ bool KIWAY::PlayersClose( bool doForce ) return ret; } + + +void KIWAY::ExpressMail( FRAME_T aDestination, + int aCommand, const std::string& aPayload, wxWindow* aSource ) +{ + KIWAY_EXPRESS mail( aDestination, aCommand, aPayload, aSource ); + + ProcessEvent( mail ); +} + + +bool KIWAY::ProcessEvent( wxEvent& aEvent ) +{ + KIWAY_EXPRESS* mail = dynamic_cast( &aEvent ); + + if( mail ) + { + FRAME_T dest = mail->Dest(); + + // see if recipient is alive + KIWAY_PLAYER* alive = Player( dest, false ); + + if( alive ) + return alive->ProcessEvent( aEvent ); + } + + return false; +} diff --git a/common/kiway_express.cpp b/common/kiway_express.cpp new file mode 100644 index 0000000000..230880421d --- /dev/null +++ b/common/kiway_express.cpp @@ -0,0 +1,49 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck + * 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 + +//IMPLEMENT_DYNAMIC_CLASS( KIWAY_EXPRESS, wxEvent ) + + +const wxEventType KIWAY_EXPRESS::wxEVENT_ID = wxNewEventType(); + + +KIWAY_EXPRESS::KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ) : + wxEvent( anOther ) +{ + m_destination = anOther.m_destination; + m_payload = anOther.m_payload; +} + + +KIWAY_EXPRESS::KIWAY_EXPRESS( FRAME_T aDestination, int aCommand, + const std::string& aPayload, wxWindow* aSource ) : + wxEvent( aCommand, wxEVENT_ID ), + m_destination( aDestination ), + m_payload( aPayload ) +{ + SetEventObject( aSource ); +} + diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp new file mode 100644 index 0000000000..4706aac339 --- /dev/null +++ b/common/kiway_player.cpp @@ -0,0 +1,56 @@ + + +#include +#include +#include + + +BEGIN_EVENT_TABLE( KIWAY_PLAYER, EDA_BASE_FRAME ) + /* have not been able to get this to work yet: + EVT_KIWAY_EXPRESS( KIWAY_PLAYER::kiway_express ) + Use Connect() in constructor until this can be sorted out + */ +END_EVENT_TABLE() + + + +KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, + const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, + long aStyle, const wxString& aWdoName ) : + EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ), + KIWAY_HOLDER( aKiway ) +{ + DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) + Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); +} + + +KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle, + const wxPoint& aPos, const wxSize& aSize, long aStyle, + const wxString& aWdoName ) : + EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ), + KIWAY_HOLDER( 0 ) +{ + DBG( printf("KIWAY_EXPRESS::wxEVENT_ID:%d\n", KIWAY_EXPRESS::wxEVENT_ID );) + Connect( KIWAY_EXPRESS::wxEVENT_ID, wxKiwayExressHandler( KIWAY_PLAYER::kiway_express ) ); +} + + +void KIWAY_PLAYER::kiway_express( KIWAY_EXPRESS& aEvent ) +{ + // logging support +#if defined(DEBUG) + const char* class_name = typeid(this).name(); + + printf( "%s: cmd:%d pay:'%s'\n", class_name, + aEvent.GetEventType(), aEvent.GetPayload().c_str() ); +#endif + + KiwayMailIn( aEvent ); // call the virtual, overload in derived. +} + + +void KIWAY_PLAYER::KiwayMailIn( KIWAY_EXPRESS& aEvent ) +{ + // overload this. +} diff --git a/common/project.cpp b/common/project.cpp index 4825974a9c..df43e60a5e 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -30,6 +30,7 @@ #include #include #include +#include // NAMELESS_PROJECT #include #include #include @@ -57,7 +58,7 @@ void PROJECT::SetProjectFullName( const wxString& aFullPathAndName ) { m_project_name = aFullPathAndName; - wxASSERT( m_project_name.IsAbsolute() ); + wxASSERT( m_project_name.GetName() == NAMELESS_PROJECT || m_project_name.IsAbsolute() ); #if 0 wxASSERT( m_project_name.GetExt() == wxT( ".pro" ) ) #else diff --git a/eeschema/cross-probing.cpp b/eeschema/cross-probing.cpp index 5258944a90..0bc51934ab 100644 --- a/eeschema/cross-probing.cpp +++ b/eeschema/cross-probing.cpp @@ -161,10 +161,10 @@ std::string FormatProbeItem( EDA_ITEM* aComponent, SCH_COMPONENT* aPart ) void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aComponent, SCH_COMPONENT* aPart ) { #if 1 - wxASSERT( aComponent ); // fix the caller + wxASSERT( aComponent ); // fix the caller #else // WTF? - if( objectToSync == NULL ) // caller remains eternally stupid. + if( !aComponent ) // caller remains eternally stupid. return; #endif @@ -176,6 +176,7 @@ void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aComponent, SCH_COMPONENT* a SendCommand( MSG_TO_PCB, packet.c_str() ); else { + Kiway().ExpressMail( FRAME_PCB, 0, packet, this ); } } } diff --git a/include/kiway.h b/include/kiway.h index 9400bdf46d..ae4337b563 100644 --- a/include/kiway.h +++ b/include/kiway.h @@ -295,7 +295,8 @@ public: * If it is already created, then the existing KIWAY_PLAYER* pointer is returned. * * @param aFrameType is from enum #FRAME_T. - * @param doCreate when true asks that the player be created if it is not already created, false means do not create. + * @param doCreate when true asks that the player be created if it is not + * already created, false means do not create and maybe return NULL. * * @return KIWAY_PLAYER* - a valid opened KIWAY_PLAYER or NULL if there * is something wrong or doCreate was false and the player has yet to be created. @@ -315,13 +316,15 @@ public: /** * Function PlayersClose * calls the KIWAY_PLAYER::Close( bool force ) function on all the windows and - * if none are vetoed, returns true, else false. If window actually closes, then + * if none are vetoed, returns true, else false. If any window actually closes, then * this KIWAY marks it as not opened internally. * - * @return bool - true the window is closed and not vetoed, else false. + * @return bool - true indicates that all windows closed because none were vetoed, + * false means at least one cast a veto. Any that cast a veto are still open. */ VTBL_ENTRY bool PlayersClose( bool doForce ); + VTBL_ENTRY void ExpressMail( FRAME_T aDestination, int aCommand, const std::string& aPayload, wxWindow* aSource=NULL ); /** * Function Prj @@ -336,6 +339,8 @@ public: /// In case aTop may not be known at time of KIWAY construction: void SetTop( wxFrame* aTop ); + bool ProcessEvent( wxEvent& aEvent ); // overload virtual + private: /// Get the full path & name of the DSO holding the requested FACE_T. diff --git a/include/kiway_express.h b/include/kiway_express.h new file mode 100644 index 0000000000..6e95d5ae39 --- /dev/null +++ b/include/kiway_express.h @@ -0,0 +1,94 @@ +#ifndef KIWAY_EXPRESS_H_ +#define KIWAY_EXPRESS_H_ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2014 SoftPLC Corporation, Dick Hollenbeck + * 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 + */ + +// @see http://wiki.wxwidgets.org/Custom_Events_Tutorial + +#include +#include + +/** + * Class KIWAY_EXPRESS + * carries a payload from one KIWAY_PLAYER to anothing within a PROJECT. + */ +class KIWAY_EXPRESS : public wxEvent +{ +public: + /** + * Function Dest + * returns the destination player id of the message. + */ + FRAME_T Dest() { return m_destination; } + + /** + * Function Payload + * returns the payload, which can be any text but it typicall self + * identifying s-expression. + */ + const std::string& GetPayload() { return m_payload; } + void SetPayload( const std::string& aPayload ) { m_payload = aPayload; } + + KIWAY_EXPRESS* Clone() const { return new KIWAY_EXPRESS( *this ); } + + //KIWAY_EXPRESS() {} + + KIWAY_EXPRESS( FRAME_T aDestination, + wxEventType aCommand, + const std::string& aPayload, + wxWindow* aSource = NULL ); + + KIWAY_EXPRESS( const KIWAY_EXPRESS& anOther ); + + /// Is the wxEventType argument to wxEvent() and identifies the class + /// in a hurry. Allocated at startup by wxNewEventType(); + static const wxEventType wxEVENT_ID; + + //DECLARE_DYNAMIC_CLASS( KIWAY_EXPRESS ) + +private: + + void kiway_express( KIWAY_EXPRESS& aEvent ); + + FRAME_T m_destination; + std::string m_payload; +}; + + +typedef void ( wxEvtHandler::*kiwayExpressFunction )( KIWAY_EXPRESS& ); + +#define wxKiwayExressHandler(func) \ + (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(kiwayExpressFunction, &func) + + +#define EVT_KIWAY_EXPRESS( func ) \ + DECLARE_EVENT_TABLE_ENTRY( \ + KIWAY_EXPRESS::wxEVENT_ID, -1, -1, \ + (wxObjectEventFunction) \ + (kiwayExpressFunction) & func, \ + (wxObject*) NULL ), + + +#endif // KIWAY_EXPRESS_H_ + diff --git a/include/kiway_player.h b/include/kiway_player.h index 9a48085dd2..75b1189053 100644 --- a/include/kiway_player.h +++ b/include/kiway_player.h @@ -84,6 +84,8 @@ private: }; +class KIWAY_EXPRESS; + /** * Class KIWAY_PLAYER * is a wxFrame capable of the OpenProjectFiles function, meaning it can load @@ -100,19 +102,13 @@ class KIWAY_PLAYER : public EDA_BASE_FRAME, public KIWAY_HOLDER public: KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, - long aStyle, const wxString& aWdoName = wxFrameNameStr ) : - EDA_BASE_FRAME( aParent, aFrameType, aTitle, aPos, aSize, aStyle, aWdoName ), - KIWAY_HOLDER( aKiway ) - {} + long aStyle, const wxString& aWdoName = wxFrameNameStr ); /// Don't use this one, only wxformbuilder uses it, and it must be augmented with /// a SetKiway() early in derived constructor. KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle, const wxPoint& aPos, const wxSize& aSize, long aStyle, - const wxString& aWdoName = wxFrameNameStr ) : - EDA_BASE_FRAME( aParent, (FRAME_T) aId, aTitle, aPos, aSize, aStyle, aWdoName ), - KIWAY_HOLDER( 0 ) - {} + const wxString& aWdoName = wxFrameNameStr ); // For the aCtl argument of OpenProjectFiles() @@ -164,6 +160,20 @@ public: return false; } + + /** + * Function KiwayMailIn + * receives KIWAY_EXPRESS messages from other players. Merely override it + * in derived classes. + */ + virtual void KiwayMailIn( KIWAY_EXPRESS& aEvent ); + + DECLARE_EVENT_TABLE() + +//private: + + /// event handler, routes to virtual KiwayMailIn() + void kiway_express( KIWAY_EXPRESS& aEvent ); }; diff --git a/kicad/mainframe.cpp b/kicad/mainframe.cpp index b7b00ad9b4..32d19c8d37 100644 --- a/kicad/mainframe.cpp +++ b/kicad/mainframe.cpp @@ -248,10 +248,13 @@ void KICAD_MANAGER_FRAME::OnRunPcbNew( wxCommandEvent& event ) kicad_board : legacy_board; #if USE_KIFACE - KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB ); - - frame->OpenProjectFiles( std::vector( 1, board.GetFullPath() ) ); - frame->Show( true ); + KIWAY_PLAYER* frame = Kiway.Player( FRAME_PCB, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_PCB, true ); + frame->OpenProjectFiles( std::vector( 1, board.GetFullPath() ) ); + frame->Show( true ); + } frame->Raise(); #else Execute( this, PCBNEW_EXE, QuoteFullPath( board ) ); @@ -266,10 +269,13 @@ void KICAD_MANAGER_FRAME::OnRunCvpcb( wxCommandEvent& event ) fn.SetExt( NetlistFileExtension ); #if USE_KIFACE - KIWAY_PLAYER* frame = Kiway.Player( FRAME_CVPCB ); - - frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); - frame->Show( true ); + KIWAY_PLAYER* frame = Kiway.Player( FRAME_CVPCB, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_CVPCB, true ); + frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + frame->Show( true ); + } frame->Raise(); #else Execute( this, CVPCB_EXE, QuoteFullPath( fn ) ); @@ -284,10 +290,13 @@ void KICAD_MANAGER_FRAME::OnRunEeschema( wxCommandEvent& event ) fn.SetExt( SchematicFileExtension ); #if USE_KIFACE - KIWAY_PLAYER* frame = Kiway.Player( FRAME_SCH ); - - frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); - frame->Show( true ); + KIWAY_PLAYER* frame = Kiway.Player( FRAME_SCH, false ); + if( !frame ) + { + frame = Kiway.Player( FRAME_SCH, true ); + frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); + frame->Show( true ); + } frame->Raise(); #else Execute( this, EESCHEMA_EXE, QuoteFullPath( fn ) ); @@ -304,6 +313,8 @@ void KICAD_MANAGER_FRAME::OnRunGerbview( wxCommandEvent& event ) #if USE_KIFACE && 0 + // I cannot make sense of the fn. + #else Execute( this, GERBVIEW_EXE, path ); #endif diff --git a/pcbnew/cross-probing.cpp b/pcbnew/cross-probing.cpp index 93b98f3558..7c764e0805 100644 --- a/pcbnew/cross-probing.cpp +++ b/pcbnew/cross-probing.cpp @@ -131,6 +131,55 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) } +std::string FormatProbeItem( BOARD_ITEM* aItem ) +{ + MODULE* module; + + switch( aItem->Type() ) + { + case PCB_MODULE_T: + module = (MODULE*) aItem; + return StrPrintf( "$PART: \"%s\"", TO_UTF8( module->GetReference() ) ); + + case PCB_PAD_T: + { + module = (MODULE*) aItem->GetParent(); + wxString pad = ((D_PAD*)aItem)->GetPadName(); + + return StrPrintf( "$PART: \"%s\" $PAD: \"%s\"", + TO_UTF8( module->GetReference() ), + TO_UTF8( pad ) ); + } + + case PCB_MODULE_TEXT_T: + { + module = (MODULE*) aItem->GetParent(); + + TEXTE_MODULE* text_mod = (TEXTE_MODULE*) aItem; + + const char* text_key; + + if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) + text_key = "$REF:"; + else if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_VALUE ) + text_key = "$VAL:"; + else + break; + + return StrPrintf( "$PART: \"%s\" %s \"%s\"", + TO_UTF8( module->GetReference() ), + text_key, + TO_UTF8( text_mod->GetText() ) ); + } + + default: + break; + } + + return ""; +} + + /** * Send a remote command to Eeschema via a socket, * @param objectToSync = item to be located on schematic (module, pin or text) @@ -140,61 +189,25 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline ) * $PART: "reference" $REF: "reference" put cursor on the component ref * $PART: "reference" $VAL: "value" put cursor on the component value */ -void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* objectToSync ) +void PCB_EDIT_FRAME::SendMessageToEESCHEMA( BOARD_ITEM* aSyncItem ) { - std::string cmd; - const char* text_key; - MODULE* module = NULL; - D_PAD* pad; - TEXTE_MODULE* text_mod; - wxString msg; - - if( objectToSync == NULL ) +#if 1 + wxASSERT( aSyncItem ); // can't we fix the caller? +#else + if( !aSyncItem ) return; +#endif - switch( objectToSync->Type() ) - { - case PCB_MODULE_T: - module = (MODULE*) objectToSync; - StrPrintf( &cmd, "$PART: \"%s\"", TO_UTF8( module->GetReference() ) ); - break; + std::string packet = FormatProbeItem( aSyncItem ); - case PCB_PAD_T: - module = (MODULE*) objectToSync->GetParent(); - pad = (D_PAD*) objectToSync; - msg = pad->GetPadName(); - StrPrintf( &cmd, "$PART: \"%s\" $PAD: \"%s\"", - TO_UTF8( module->GetReference() ), - TO_UTF8( msg ) ); - break; - - case PCB_MODULE_TEXT_T: - module = (MODULE*) objectToSync->GetParent(); - text_mod = (TEXTE_MODULE*) objectToSync; - - if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) - text_key = "$REF:"; - else if( text_mod->GetType() == TEXTE_MODULE::TEXT_is_VALUE ) - text_key = "$VAL:"; - else - break; - - StrPrintf( &cmd, "$PART: \"%s\" %s \"%s\"", - TO_UTF8( module->GetReference() ), - text_key, - TO_UTF8( text_mod->GetText() ) ); - break; - - default: - break; - } - - if( module && cmd.size() ) + if( packet.size() ) { if( Kiface().IsSingle() ) - SendCommand( MSG_TO_SCH, cmd.c_str() ); + SendCommand( MSG_TO_SCH, packet.c_str() ); else { + Kiway().ExpressMail( FRAME_SCH, 0, packet, this ); } } } +