← Back to team overview

kicad-developers team mailing list archive

kicad-project-editor-binding.patch

 

This patch add recursive directory parsing to the project editor as well 
as many python binding new features to the project editor.

I attach the updated version of the documentation with the patch

---
bitmaps/directory.xpm | 155 ++++++++++++++++++++++++
common/gestfich.cpp | 2
common/pyhandler.cpp | 24 ++-
include/wxstruct.h | 6
kicad/buildmnu.cpp | 57 ++++----
kicad/kicad.cpp | 81 ++++++++++++
kicad/kicad.h | 35 +++++
kicad/treeprj.cpp | 317 +++++++++++++++++++++++++++++++++++---------------
8 files changed, 543 insertions(+), 134 deletions(-)

 --------------040101040003050605080909 Content-Type: text/x-patch;
name="kicad-project-editor-binding.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="kicad-project-editor-binding.patch"

This patch add recursive directory parsing to the project editor as well as many python binding new features to the project editor.



---
bitmaps/directory.xpm | 155 ++++++++++++++++++++++++
common/gestfich.cpp | 2 
common/pyhandler.cpp | 24 ++-
include/wxstruct.h | 6 
kicad/buildmnu.cpp | 57 ++++----
kicad/kicad.cpp | 81 ++++++++++++
kicad/kicad.h | 35 +++++
kicad/treeprj.cpp | 317 +++++++++++++++++++++++++++++++++++---------------
8 files changed, 543 insertions(+), 134 deletions(-)


Index: kicad-dev/include/wxstruct.h
===================================================================
--- kicad-dev.orig/include/wxstruct.h	2006-12-11 09:31:58.000000000 +0100
+++ kicad-dev/include/wxstruct.h	2007-04-28 01:51:43.000000000 +0200
@@ -157,6 +157,10 @@
wxString m_FrameName;	// name used for writting and reading setup
// It is "SchematicFrame", "PcbFrame" ....

+	#ifdef KICAD_PYTHON
+	WinEDA_BasicFrame( const WinEDA_BasicFrame & ) {} // Should throw!!
+	WinEDA_BasicFrame() {} // Should throw!!
+	#endif
public:
// Constructor and destructor
WinEDA_BasicFrame( wxWindow * father, int idtype, WinEDA_App *parent,
@@ -292,7 +296,7 @@
virtual void HandleBlockPlace(wxDC * DC);
virtual int HandleBlockEnd(wxDC * DC);

-	void CopyToClipboard(wxCommandEvent& event);
+	void CopyToClipboard(wxCommandEvent& event);

/* interprocess communication */
void OnSockRequest(wxSocketEvent &evt);
Index: kicad-dev/kicad/kicad.cpp
===================================================================
--- kicad-dev.orig/kicad/kicad.cpp	2006-06-28 10:58:48.000000000 +0200
+++ kicad-dev/kicad/kicad.cpp	2007-04-29 23:32:00.000000000 +0200
@@ -18,6 +18,7 @@
#ifdef SPLASH_OK
#include <wx/splash.h>
#endif
+#include <wx/button.h>

#include "wxstruct.h"
#include "common.h"
@@ -25,6 +26,10 @@
#include "kicad.h"
#include "macros.h"

+#ifdef KICAD_PYTHON
+#include <pyhandler.h>
+#endif
+
/* Routines exportees */

/* fonctions importees */
@@ -40,6 +45,76 @@
// Create a new application object
IMPLEMENT_APP(WinEDA_App)

+#ifdef KICAD_PYTHON
+using namespace boost::python;
+
+static WinEDA_MainFrame& GetMainFrame(void) { return *( wxGetApp().m_MainFrame ); }
+object WinEDA_MainFrame::GetPrjName() const { return PyHandler::Convert( m_PrjFileName ); }
+static void WinEDAPrint( str msg ) { GetMainFrame().PrintMsg( PyHandler::MakeStr( msg ) + wxT("\n") ); }
+object WinEDA_MainFrame::ToWx() { return object( handle<>( borrowed( wxPyMake_wxObject( this, false ) ) ) ); }
+object WinEDA_PrjFrame::ToWx() { return object( handle<>( borrowed( wxPyMake_wxObject( this, false ) ) ) ); }
+WinEDA_PrjFrame* WinEDA_MainFrame::GetTree() const { return m_LeftWin; }
+object WinEDA_PrjFrame::GetFtExPy( enum TreeFileType type ) const { return PyHandler::Convert( GetFileExt( type ) ); }
+object WinEDA_PrjFrame::GetMenuPy( enum TreeFileType type )
+{ 
+ return object( handle<>( borrowed( wxPyMake_wxObject( GetContextMenu( (int) type ), false ) ) ) ); 
+}
+
+void WinEDA_PrjFrame::AddFilePy( str & file ) { AddFile( PyHandler::MakeStr( file ), m_root ); }
+
+void WinEDA_MainFrame::AddFastLaunchPy( object & button )
+{
+ wxButton * btn;
+ bool success = wxPyConvertSwigPtr( button.ptr(), (void**)&btn, _T("wxButton"));
+ if ( !success ) return;
+
+ Py_INCREF( button.ptr() );
+ AddFastLaunch( btn );
+}
+
+static void py_kicad_init(void)
+{
+ def( "GetMainFrame", &GetMainFrame, return_value_policy< reference_existing_object >() );
+
+ enum_<TreeFileType>( "FileType" )
+	.value( "PROJECT", TREE_PROJECT )
+	.value( "SCHEMA", TREE_SCHEMA )
+	.value( "BOARD", TREE_PCB )
+	.value( "PYSCRIPT", TREE_PY )
+	.value( "GERBER", TREE_GERBER )
+	.value( "PDF", TREE_PDF )
+	.value( "TXT", TREE_TXT )
+	.value( "NETLIST", TREE_NET )
+	.value( "UNKNOWN", TREE_UNKNOWN )
+	.value( "DIRECTORY", TREE_DIRECTORY )
+	.value( "MAX", TREE_MAX );
+
+ class_<WinEDA_PrjFrame>( "TreeWindow" )
+	.def( "ToWx",	&WinEDA_PrjFrame::ToWx )
+	.def( "GetContextMenu", &WinEDA_PrjFrame::GetMenuPy )
+	.def( "GetFileExtension", &WinEDA_PrjFrame::GetFtExPy )
+	.def( "AddFile",	&WinEDA_PrjFrame::AddFilePy )
+ .def( "AddFilter", &WinEDA_PrjFrame::AddFilter )
+ .def( "ClearFilters", &WinEDA_PrjFrame::ClearFilters )
+ .def( "RemoveFilter", &WinEDA_PrjFrame::RemoveFilterPy )
+ .def( "GetFilters", &WinEDA_PrjFrame::GetFilters, return_value_policy < copy_const_reference >() )
+ ;
+
+ class_<WinEDA_MainFrame>( "MainFrame" )
+	.def( "ToWx",	&WinEDA_MainFrame::ToWx )
+	.def( "AddFastLaunch",	&WinEDA_MainFrame::AddFastLaunchPy )
+	.def( "GetProjectName",	&WinEDA_MainFrame::GetPrjName )
+	.def( "GetProjectWindow",	&WinEDA_MainFrame::GetTree, return_value_policy< reference_existing_object >() );
+
+}
+
+static void py_common_init(void)
+{
+ def( "Print", &WinEDAPrint );
+}
+
+#endif
+
bool WinEDA_App::OnInit(void)
{
EDA_Appl = this;
@@ -87,6 +162,12 @@
m_MainFrame->Load_Prj_Config();
}

+	#ifdef KICAD_PYTHON
+	PyHandler::GetInstance()->AddToModule( wxT("kicad"), &py_kicad_init );
+	PyHandler::GetInstance()->AddToModule( wxT("common"), &py_common_init );
+	#endif
+
+
return TRUE;
}

Index: kicad-dev/kicad/kicad.h
===================================================================
--- kicad-dev.orig/kicad/kicad.h	2007-04-24 22:41:14.000000000 +0200
+++ kicad-dev/kicad/kicad.h	2007-04-29 23:32:08.000000000 +0200
@@ -5,6 +5,10 @@
#ifndef KICAD_H
#define KICAD_H

+#ifdef KICAD_PYTHON
+#include <pyhandler.h>
+#endif
+
#include <wx/treectrl.h>
#include <vector>

@@ -26,6 +30,7 @@

class WinEDA_MainFrame: public WinEDA_BasicFrame
{
+	/* This class is the main entry point of the py API */
public:

WinEDA_CommandFrame * m_CommandWin;
@@ -69,6 +74,17 @@
void CreateZipArchive(const wxString FullFileName);
void UnZipArchive(const wxString FullFileName);

+	#ifdef KICAD_PYTHON
+	boost::python::object GetPrjName() const;
+	WinEDA_MainFrame( const WinEDA_MainFrame& ) {}
+	WinEDA_MainFrame() {}
+	boost::python::object ToWx();
+	void AddFastLaunchPy( boost::python::object & button );
+	WinEDA_PrjFrame* GetTree() const;
+	#endif
+
+	void AddFastLaunch( wxButton * button, int sep = 20 );
+
DECLARE_EVENT_TABLE()
};

@@ -84,6 +100,7 @@
TREE_TXT,
TREE_NET,
TREE_UNKNOWN,
+ TREE_DIRECTORY,
TREE_MAX,
};

@@ -93,6 +110,7 @@
private:

std::vector< wxMenu* > m_ContextMenus;
+ std::vector< wxString > m_Filters;

protected:
wxMenu * GetContextMenu( int type );
@@ -106,7 +124,6 @@

wxTreeItemId m_root;

-
public:
WinEDA_PrjFrame(WinEDA_MainFrame * parent,
const wxPoint & pos, const wxSize & size );
@@ -122,6 +139,7 @@
void OnDeleteFile(wxCommandEvent &event );

void OnNewFile(wxCommandEvent & event);
+	void OnNewDirectory(wxCommandEvent & event);
void OnNewSchFile(wxCommandEvent & event);
void OnNewBrdFile(wxCommandEvent & event);
void OnNewPyFile(wxCommandEvent & event);
@@ -129,11 +147,24 @@
void OnNewTxtFile(wxCommandEvent & event);
void OnNewNetFile(wxCommandEvent & event);

+ void ClearFilters();
+ const std::vector<wxString > & GetFilters();
+ void RemoveFilter( const wxString & filter );
+
#ifdef KICAD_PYTHON
void OnRunPy(wxCommandEvent & event);
+	boost::python::object ToWx();
+	boost::python::object GetMenuPy( enum TreeFileType );
+	boost::python::object GetFtExPy ( enum TreeFileType ) const;
+	void AddFilePy( boost::python::str & name );
+	WinEDA_PrjFrame() {}
+	WinEDA_PrjFrame( const WinEDA_PrjFrame & ) {}
+
+ void RemoveFilterPy( const boost::python::str & filter );
+ void AddFilter( const boost::python::str & filter );
#endif

-	void AddFile( const wxString & name, int id );
+	void AddFile( const wxString & name, wxTreeItemId & root );
DECLARE_EVENT_TABLE()
};

Index: kicad-dev/common/pyhandler.cpp
===================================================================
--- kicad-dev.orig/common/pyhandler.cpp	2007-04-26 23:20:32.000000000 +0200
+++ kicad-dev/common/pyhandler.cpp	2007-04-29 23:40:14.000000000 +0200
@@ -41,13 +41,13 @@
mask, /* Masque d'affichage */
NULL,
open ? wxFD_OPEN : wxFD_SAVE,
- FALSE
+ TRUE
);

return PyHandler::Convert( script );
}

-static void Print( str message ) { std::cout << extract<char *>(message); }
+static void Print( str message ) { std::cout << extract<char *>(message) << std::endl; }

static void RegisterCb( str objKey, object callback )
{ PyHandler::GetInstance()->RegisterCallback( PyHandler::MakeStr(objKey), callback ); }
@@ -107,6 +107,11 @@
RunSimpleString( initConsole );

AddToModule ( wxT( "common" ), &init_base_utils );
+
+ // Register converters
+
+ to_python_converter < std::vector< std::string >, std_vector_to_tuple< const std::vector < std::string > > > ();
+ to_python_converter < std::vector< wxString >, std_vector_to_tuple< const std::vector < wxString > > > ();
}

void PyHandler::DoInitModules()
@@ -166,24 +171,25 @@
void PyHandler::RunBaseScripts( const wxString & base )
/* Run scripts looking in 'base' directory */
{
+ const wxString sep = wxFileName().GetPathSeparator();

// check if we can have a kicad_startup.py around ?
-	wxString script = base + wxString::FromAscii( "scripts/kicad_startup.py" );
+	wxString script = base + wxT( "scripts" ) + sep + wxT( "kicad_startup.py" );
if ( wxFileExists( script ) ) RunScript( script );

// First find scripts/<name>.py and run it if found :

-	script = base + wxString::FromAscii( "scripts/" ) + m_appName + wxString::FromAscii(".py");
+	script = base + wxString::FromAscii( "scripts" ) + sep + m_appName + wxString::FromAscii(".py");
if ( wxFileExists( script ) ) RunScript( script );

// Now lets see if we can find a suitable plugin directory (plugin/<name>) somewhere

-	wxString pluginDir = base + wxString::FromAscii( "plugins/" ) + m_appName;
+	wxString pluginDir = base + wxT( "plugins" ) + sep + m_appName;
if ( wxDirExists( pluginDir ) )
{
// We do have a systemwide plugin dir, let's find files in it
wxArrayString pluginList;
-	wxDir::GetAllFiles( pluginDir, &pluginList, wxString::FromAscii("*.py") );
+	wxDir::GetAllFiles( pluginDir, &pluginList, wxT("*.py") );

for ( unsigned int i = 0; i < pluginList.Count() ; i++ )
{
@@ -197,13 +203,15 @@
{
// SYSTEMWIDE:

+ const wxString sep = wxFileName().GetPathSeparator();
+
wxString dataPath = ReturnKicadDatasPath();
if ( wxDirExists( dataPath ) )	RunBaseScripts( dataPath );

// USER Scripts:
-	wxString userDir = wxGetUserHome() + wxString::FromAscii("/.kicad.d/");
+	wxString userDir = wxGetUserHome() + sep + wxString::FromAscii(".kicad.d") + sep;
if ( wxDirExists( userDir ) ) RunBaseScripts( userDir );
-	userDir = wxGetUserHome() + wxString::FromAscii("/_kicad_d/");
+	userDir = wxGetUserHome() + sep + wxString::FromAscii("_kicad_d") + sep;
if ( wxDirExists( userDir ) ) RunBaseScripts( userDir );

}
Index: kicad-dev/kicad/buildmnu.cpp
===================================================================
--- kicad-dev.orig/kicad/buildmnu.cpp	2007-04-24 22:41:01.000000000 +0200
+++ kicad-dev/kicad/buildmnu.cpp	2007-04-28 01:55:05.000000000 +0200
@@ -283,46 +283,41 @@
void WinEDA_MainFrame::CreateCommandToolbar(void)
/*************************************************/
{
-#define SEPAR 20
-int sizex, sizey,width;
-wxBitmapButton * Butt;
-wxPoint pos;
+wxBitmapButton * btn;

// delete and recreate the toolbar
if( m_VToolBar ) return;

-	m_CommandWin->GetClientSize(&sizex, &sizey);
-	width = 300;

// Set up toolbar
-	width = 32;
-	pos.x = 20; pos.y = 20;
-
-	Butt = new wxBitmapButton(m_CommandWin, ID_TO_EESCHEMA,
-	BITMAP(icon_eeschema_xpm), pos );
-	Butt->SetToolTip(_("EeSchema (Schematic editor)"));
-
-	pos.x += width + SEPAR;
-	Butt = new wxBitmapButton(m_CommandWin,ID_TO_CVPCB,
-	BITMAP(icon_cvpcb_xpm), pos );
-	Butt->SetToolTip(_("Cvpcb (Componants to modules)"));
-
-	pos.x += width + SEPAR;
-	Butt = new wxBitmapButton(m_CommandWin, ID_TO_PCB,
-	BITMAP(a_icon_pcbnew_xpm), pos );
-	Butt->SetToolTip(_("Pcbnew ( board editor )"));
-
-	pos.x += width + SEPAR;
-	Butt = new wxBitmapButton(m_CommandWin, ID_TO_GERBVIEW,
-	BITMAP(icon_gerbview_xpm), pos );
-	Butt->SetToolTip(_("GerbView ( Gerber viewer )"));
+	btn = new wxBitmapButton( this, ID_TO_EESCHEMA, BITMAP(icon_eeschema_xpm) );
+	btn->SetToolTip(_("EeSchema (Schematic editor)"));
+	AddFastLaunch( btn );
+
+	btn = new wxBitmapButton( this,ID_TO_CVPCB, BITMAP(icon_cvpcb_xpm) );
+	btn->SetToolTip(_("Cvpcb (Componants to modules)"));
+	AddFastLaunch( btn );
+
+	btn = new wxBitmapButton( this, ID_TO_PCB, BITMAP(a_icon_pcbnew_xpm) );
+	btn->SetToolTip(_("Pcbnew ( board editor )"));
+	AddFastLaunch( btn );
+
+	btn = new wxBitmapButton( this, ID_TO_GERBVIEW, BITMAP(icon_gerbview_xpm) );
+	btn->SetToolTip(_("GerbView ( Gerber viewer )"));
+	AddFastLaunch( btn );

#ifdef KICAD_PYTHON
-	pos.x += width + SEPAR;
-	Butt = new wxBitmapButton(m_CommandWin, ID_RUN_PYTHON, //ID_TO_RUNPYTHON,
-	BITMAP(icon_python_xpm), pos );
-	Butt->SetToolTip(_("Run Python Script"));
+	btn = new wxBitmapButton( this, ID_RUN_PYTHON, BITMAP(icon_python_xpm) );
+	btn->SetToolTip(_("Run Python Script"));
+	AddFastLaunch( btn );
#endif
}

+void WinEDA_MainFrame::AddFastLaunch( wxButton * button, int sep )
+{
+	static wxPoint pos (20, 20);
+	button->Reparent( m_CommandWin );
+	button->Move( pos );
+	pos.x += button->GetSize().GetWidth() + sep;
+}

Index: kicad-dev/kicad/treeprj.cpp
===================================================================
--- kicad-dev.orig/kicad/treeprj.cpp	2007-04-24 22:48:11.000000000 +0200
+++ kicad-dev/kicad/treeprj.cpp	2007-04-30 00:23:32.000000000 +0200
@@ -31,10 +31,10 @@
#include "../bitmaps/new_pcb.xpm"
#include "../bitmaps/new_sch.xpm"
#include "../bitmaps/new_cvpcb.xpm"
+#include "../bitmaps/directory.xpm"

#include "id.h"

-
/***********************************************************/
/* Classes pour l'arbre de hierarchie de gestion du projet */
/***********************************************************/
@@ -50,6 +50,22 @@
m_Id = tree_id;
if ( data ) m_FileName = data;
}
+
+ wxString GetDir() const
+ {
+ if (TREE_DIRECTORY == m_Id ) return m_FileName;
+ 
+ wxFileName filename = wxFileName( m_FileName );
+ filename.MakeRelativeTo( wxGetCwd() );
+ wxArrayString dirs = filename.GetDirs();
+ 
+ wxString dir;
+ for ( unsigned int i = 0; i < dirs.Count(); i ++ )
+ {
+ dir += dirs[i] + filename.GetPathSeparator();
+ }
+ return dir;
+ }
};


@@ -58,6 +74,44 @@
/* Methodes de la Frame de l'arbre de hierarchie de gestion du projet */
/**********************************************************************/

+void WinEDA_PrjFrame::ClearFilters()
+{
+ m_Filters.clear();
+}
+
+void WinEDA_PrjFrame::RemoveFilter( const wxString & filter )
+{
+ for ( unsigned int i = 0; i < m_Filters.size(); i++ )
+ {
+ if ( filter == m_Filters[i] )
+ {
+ m_Filters.erase( m_Filters.begin() + i );
+ return;
+ }
+ }
+}
+
+#ifdef KICAD_PYTHON
+using namespace boost::python;
+
+void WinEDA_PrjFrame::RemoveFilterPy( const str & filter )
+{
+ RemoveFilter( PyHandler::MakeStr( filter ) );
+}
+
+void WinEDA_PrjFrame::AddFilter( const str & filter )
+{
+ wxRegEx reg;
+ if ( !reg.Compile( PyHandler::MakeStr( filter ) ) ) return;
+ m_Filters.push_back( PyHandler::MakeStr( filter ) );
+}
+#endif
+
+const std::vector< wxString > & WinEDA_PrjFrame::GetFilters()
+{
+ return m_Filters;
+}
+
WinEDA_PrjFrame::WinEDA_PrjFrame(WinEDA_MainFrame * parent,
const wxPoint & pos,
const wxSize & size ) :
@@ -75,6 +129,7 @@
PyHandler::GetInstance()->DeclareEvent( wxT( "kicad::TreeContextMenu" ) );
PyHandler::GetInstance()->DeclareEvent( wxT( "kicad::TreeAddFile" ) );
PyHandler::GetInstance()->DeclareEvent( wxT( "kicad::NewFile" ) );
+	PyHandler::GetInstance()->DeclareEvent( wxT( "kicad::NewDirectory" ) );
PyHandler::GetInstance()->DeclareEvent( wxT( "kicad::DeleteFile" ) );
PyHandler::GetInstance()->DeclareEvent( wxT( "kicad::RenameFile" ) );
#endif
@@ -102,40 +157,54 @@
// New files context menu:
menu = m_ContextMenus[TREE_PROJECT];

-	item = new wxMenuItem(menu, ID_PROJECT_NEWSCH, _("&New Schematic"), _("Create a New Schematic File") );
-	item->SetBitmap( new_sch_xpm );
-	menu->Append( item );
-
-	item = new wxMenuItem(menu, ID_PROJECT_NEWBRD, _("&New PCB"), _("Create a New PCB File") );
-	item->SetBitmap( new_pcb_xpm );
-	menu->Append( item );
-
-	item = new wxMenuItem(menu, ID_PROJECT_NEWGERBER, _("&New File Gerber"), _("Create a New Gerber File") );
-	item->SetBitmap( new_gerb_xpm );
-	menu->Append( item );
-
-	item = new wxMenuItem(menu, ID_PROJECT_NEWNET, _("&New Netlist"), _("Create a New Netlist") );
-	item->SetBitmap( new_cvpcb_xpm );
-	menu->Append( item );
-
-	item = new wxMenuItem(menu, ID_PROJECT_NEWPY, _("&New Python Script"), _("Create a New Python Script") );
-	item->SetBitmap( new_python_xpm );
-	menu->Append( item );
-
-	item = new wxMenuItem(menu, ID_PROJECT_NEWTXT, _("&New Text File"), _("Create a New Txt File") );
-	item->SetBitmap( new_txt_xpm );
-	menu->Append( item );
-
-	item = new wxMenuItem(menu, ID_PROJECT_NEWFILE, _("&New File"), _("Create a New File") );
-	item->SetBitmap( new_xpm );
-	menu->Append( item );
-
+ wxMenu * menus[2];
+ menus[0] = m_ContextMenus[TREE_DIRECTORY];
+ menus[1] = m_ContextMenus[TREE_PROJECT];
+ 
+ for ( int i = 0; i < 2; i ++ )
+ {
+ menu = menus[i];
+
+ item = new wxMenuItem(menu, ID_PROJECT_NEWDIR, _("New D&irectory"), _("Create a New Directory") );
+ item->SetBitmap( directory_xpm );
+ menu->Append( item );
+
+ item = new wxMenuItem(menu, ID_PROJECT_NEWSCH, _("New &Schematic"), _("Create a New Schematic File") );
+ item->SetBitmap( new_sch_xpm );
+ menu->Append( item );
+
+ item = new wxMenuItem(menu, ID_PROJECT_NEWBRD, _("New &PCB"), _("Create a New PCB File") );
+ item->SetBitmap( new_pcb_xpm );
+ menu->Append( item );
+
+ item = new wxMenuItem(menu, ID_PROJECT_NEWGERBER, _("New &Gerber File"), _("Create a New Gerber File") );
+ item->SetBitmap( new_gerb_xpm );
+ menu->Append( item );
+
+ item = new wxMenuItem(menu, ID_PROJECT_NEWNET, _("New &Netlist"), _("Create a New Netlist") );
+ item->SetBitmap( new_cvpcb_xpm );
+ menu->Append( item );
+
+ item = new wxMenuItem(menu, ID_PROJECT_NEWPY, _("New P&ython Script"), _("Create a New Python Script") );
+ item->SetBitmap( new_python_xpm );
+ menu->Append( item );
+
+ item = new wxMenuItem(menu, ID_PROJECT_NEWTXT, _("New &Text File"), _("Create a New Txt File") );
+ item->SetBitmap( new_txt_xpm );
+ menu->Append( item );
+
+ item = new wxMenuItem(menu, ID_PROJECT_NEWFILE, _("New &File"), _("Create a New File") );
+ item->SetBitmap( new_xpm );
+ menu->Append( item );
+ }

// Delete file menu command:
for ( int i = TREE_PROJECT + 1; i < TREE_MAX ; i++ )
{
menu = m_ContextMenus[i];
-	item = new wxMenuItem(menu, ID_PROJECT_DELETE, _("&Delete File"), _("Delete the File") );
+	item = new wxMenuItem(menu, ID_PROJECT_DELETE
+ , TREE_DIRECTORY != i ? _("&Delete File") : _("&Delete Directory")
+ , TREE_DIRECTORY != i ? _("Delete the File") : _("&Delete the Directory and its content") );
item->SetBitmap( delete_xpm );
menu->Append( item );
}
@@ -153,6 +222,7 @@
EVT_TREE_ITEM_RIGHT_CLICK(ID_PROJECT_TREE, WinEDA_PrjFrame::OnRight)
EVT_MENU(ID_PROJECT_TXTEDIT, WinEDA_PrjFrame::OnTxtEdit)
EVT_MENU(ID_PROJECT_NEWFILE, WinEDA_PrjFrame::OnNewFile)
+	EVT_MENU(ID_PROJECT_NEWFILE, WinEDA_PrjFrame::OnNewDirectory)
EVT_MENU(ID_PROJECT_NEWSCH, WinEDA_PrjFrame::OnNewSchFile)
EVT_MENU(ID_PROJECT_NEWBRD, WinEDA_PrjFrame::OnNewBrdFile)
EVT_MENU(ID_PROJECT_NEWPY, WinEDA_PrjFrame::OnNewPyFile)
@@ -167,6 +237,7 @@
END_EVENT_TABLE()


+void WinEDA_PrjFrame::OnNewDirectory(wxCommandEvent & event) { NewFile( event, TREE_DIRECTORY ); }
void WinEDA_PrjFrame::OnNewFile(wxCommandEvent & event) { NewFile( event, TREE_UNKNOWN ); }
void WinEDA_PrjFrame::OnNewSchFile(wxCommandEvent & event) { NewFile( event, TREE_SCHEMA ); }
void WinEDA_PrjFrame::OnNewBrdFile(wxCommandEvent & event) { NewFile( event, TREE_PCB ); }
@@ -179,23 +250,46 @@
{
wxString filename;
wxString mask = GetFileExt( type );
+ const wxString sep = wxFileName().GetPathSeparator();
+
+ // Get the directory:
+ wxString dir;
+
+ TreePrjItemData * treeData;
+ wxString FullFileName;
+ treeData = dynamic_cast<TreePrjItemData*>( m_TreeProject->GetItemData(m_TreeProject->GetSelection()) );
+ if (!treeData) return;
+
+ dir = treeData->GetDir();
+
+ // Ask for the new file name

-	filename = EDA_FileSelector(_("Create New File:"),
-	wxGetCwd(),	/* Chemin par defaut */
-	_("noname") + mask,	/* nom fichier par defaut */
-	mask,	/* extension par defaut */
-	mask,	/* Masque d'affichage */
+	filename = EDA_FileSelector( TREE_DIRECTORY != type ? _("Create New File:") : _("Create New Directory"),
+	wxGetCwd() + sep + dir,	/* Chemin par defaut */
+	_("noname") + mask,	/* nom fichier par defaut */
+	mask,	/* extension par defaut */
+	mask,	/* Masque d'affichage */
this,
-	wxFD_SAVE,
-	FALSE
+	wxFD_SAVE | wxOVERWRITE_PROMPT,
+	TRUE
);
if ( filename.IsEmpty() ) return;

-	#ifdef KICAD_PYTHON
-	PyHandler::GetInstance()->TriggerEvent( wxT("kicad::NewFile"), PyHandler::Convert(filename) );
-	#endif

-	wxFile( filename, wxFile::write );
+ if ( TREE_DIRECTORY != type )
+ {
+ wxFile( filename, wxFile::write );
+ #ifdef KICAD_PYTHON
+ PyHandler::GetInstance()->TriggerEvent( wxT("kicad::NewFile"), PyHandler::Convert(filename) );
+ #endif
+ }
+ else
+ {
+ wxMkdir( filename );
+ #ifdef KICAD_PYTHON
+ PyHandler::GetInstance()->TriggerEvent( wxT("kicad::NewDirectory"), PyHandler::Convert(filename) );
+ #endif
+ }
m_Parent->OnRefresh( event );
}

@@ -213,44 +307,76 @@
wxT( ".txt" ), // TREE_TXT
wxT( ".net" ),	// TREE_NET
wxT( "" ),	// TREE_UNKNOWN
+ wxT( "" ), // TREE_DIRECTORY
};

if ( type < TREE_MAX ) return extensions[type];
return wxEmptyString;
}

-void WinEDA_PrjFrame::AddFile( const wxString & name, int id )
+void WinEDA_PrjFrame::AddFile( const wxString & name, wxTreeItemId & root )
{
wxTreeItemId cellule;
-// Check the file type :
-int type = TREE_UNKNOWN;
-wxRegEx reg;
-	
-	for ( int i = TREE_PROJECT; i < TREE_MAX; i++ )
-	{
-	wxString ext = GetFileExt( (enum TreeFileType) i );

-	if ( ext == wxT( "" ) ) continue;
+ // Filter
+ wxRegEx reg;

-	reg.Compile( wxString::FromAscii( "^.*\\" ) + ext + wxString::FromAscii( "$" ), wxRE_ICASE );
-	if ( reg.Matches( name ) )
-	{
-	type = i;
-	break;
-	}
-	}
-
- // Append the item :
-
-	cellule = m_TreeProject->AppendItem( m_root, name, id, id);
-	m_TreeProject->SetItemData( cellule, new TreePrjItemData(type, name) );
-	m_TreeProject->SetItemFont(cellule, *g_StdFont);
+ for ( unsigned int i = 0; i < m_Filters.size(); i++ )
+ {
+ reg.Compile( m_Filters[i], wxRE_ICASE );
+ if ( reg.Matches( name ) ) return;
+ }
+
+ // Check the file type
+ int type = TREE_UNKNOWN;
+
+ if ( wxDirExists( name ) )
+ {
+ type = TREE_DIRECTORY;
+ }
+ else
+ {
+ for ( int i = TREE_PROJECT; i < TREE_MAX; i++ )
+ {
+ wxString ext = GetFileExt( (enum TreeFileType) i );
+
+ if ( ext == wxT( "" ) ) continue;
+
+ reg.Compile( wxString::FromAscii( "^.*\\" ) + ext + wxString::FromAscii( "$" ), wxRE_ICASE );
+ if ( reg.Matches( name ) )
+ {
+ type = i;
+ break;
+ }
+ }
+ }
+
+ // Append the item (only appending the filename not the full path):
+
+ wxString file = wxFileNameFromPath( name );
+	cellule = m_TreeProject->AppendItem( root, file );
+	m_TreeProject->SetItemData( cellule, new TreePrjItemData( type, name ) );
+	m_TreeProject->SetItemFont( cellule, *g_StdFont );
m_TreeProject->SetItemImage( cellule, type - 1 );
m_TreeProject->SetItemImage( cellule, type - 1, wxTreeItemIcon_Selected );

#ifdef KICAD_PYTHON
PyHandler::GetInstance()->TriggerEvent( wxT("kicad::TreeAddFile"), PyHandler::Convert( name ) );
#endif
+
+ if ( TREE_DIRECTORY == type )
+ {
+ const wxString sep = wxFileName().GetPathSeparator();
+ wxDir dir( name );
+ wxString file;
+ if ( dir.GetFirst( &file ) )
+ {
+ do
+ {
+ AddFile( name + sep + file, cellule );
+ } while ( dir.GetNext( &file ) );
+ }
+ }
}

/******************************************/
@@ -261,7 +387,6 @@
{
wxTreeItemId rootcellule;
wxString Text;
-int id;
bool prjOpened = false;

if ( ! m_TreeProject ) m_TreeProject = new WinEDA_TreePrj(this);
@@ -274,8 +399,7 @@
prjOpened = wxFileExists( Text );

// root tree:
-	id = 0;
-	m_root = rootcellule = m_TreeProject->AddRoot(Text, id, id);
+	m_root = rootcellule = m_TreeProject->AddRoot(Text);
m_TreeProject->SetItemBold(rootcellule, TRUE);
m_TreeProject->SetItemData( rootcellule, new TreePrjItemData(TREE_PROJECT, wxEmptyString) );
m_TreeProject->SetItemFont(rootcellule, *g_StdFont);
@@ -283,21 +407,22 @@
ChangeFileNameExt(Text, wxEmptyString);

// Add at least a .scn / .brd if not existing:
-	if ( !wxFileExists(Text+g_SchExtBuffer) ) AddFile( Text + g_SchExtBuffer, id++ );
-	if ( !wxFileExists(Text+g_BoardExtBuffer) ) AddFile( Text + g_BoardExtBuffer, id++ );
+	if ( !wxFileExists(Text+g_SchExtBuffer) ) AddFile( Text + g_SchExtBuffer, m_root );
+	if ( !wxFileExists(Text+g_BoardExtBuffer) ) AddFile( Text + g_BoardExtBuffer, m_root );

// Now adding all current files if available
if ( prjOpened )
{
-	wxArrayString fileList;
-	wxDir::GetAllFiles( wxGetCwd(), &fileList, wxEmptyString, wxDIR_FILES );
-	for ( unsigned int i = 0; i < fileList.Count() ; ++i )
-	{
-	if (wxDirExists(fileList[i])) continue;
-	wxString file = wxFileNameFromPath( fileList[i] );
-	if ( file == Text + wxT( ".pro" ) ) continue;
-	AddFile( file, id++ );
-	}
+ wxDir dir( wxGetCwd() );
+ wxString file;
+ if ( dir.GetFirst( &file ) )
+ {
+ do
+ {
+ if ( file == Text + wxT( ".pro" ) ) continue;
+ AddFile( file, m_root );
+ } while ( dir.GetNext( &file ) );
+ }
}

m_TreeProject->Expand(rootcellule);
@@ -309,8 +434,8 @@
TreePrjItemData * tree_data;
wxString FullFileName;

-	tree_data = (TreePrjItemData*)
-	m_TreeProject->GetItemData(m_TreeProject->GetSelection());
+	tree_data = dynamic_cast<TreePrjItemData*>( m_TreeProject->GetItemData(m_TreeProject->GetSelection()) );
+ if (!tree_data) return;

tree_id = tree_data->m_Id;
FullFileName = tree_data->m_FileName;
@@ -330,7 +455,8 @@

void WinEDA_PrjFrame::OnTxtEdit(wxCommandEvent & event )
{
-	TreePrjItemData * tree_data = (TreePrjItemData*) m_TreeProject->GetItemData(m_TreeProject->GetSelection());
+	TreePrjItemData * tree_data = dynamic_cast<TreePrjItemData*> (m_TreeProject->GetItemData(m_TreeProject->GetSelection()) );
+ if (!tree_data) return;

wxString FullFileName = tree_data->m_FileName;
AddDelimiterString( FullFileName );
@@ -344,7 +470,9 @@

void WinEDA_PrjFrame::OnDeleteFile(wxCommandEvent &event )
{
-	TreePrjItemData * tree_data = (TreePrjItemData*) m_TreeProject->GetItemData(m_TreeProject->GetSelection());
+	TreePrjItemData * tree_data = dynamic_cast<TreePrjItemData*>( m_TreeProject->GetItemData(m_TreeProject->GetSelection()) );
+ if (!tree_data) return;
+
wxString filename = tree_data->m_FileName;

wxMessageDialog dialog( this, _("Do you really want to delete ") + filename, _("Delete File") 
@@ -363,7 +491,9 @@
#ifdef KICAD_PYTHON
void WinEDA_PrjFrame::OnRunPy(wxCommandEvent & event )
{
-	TreePrjItemData * tree_data = (TreePrjItemData*) m_TreeProject->GetItemData(m_TreeProject->GetSelection());
+	TreePrjItemData * tree_data = dynamic_cast<TreePrjItemData*>( m_TreeProject->GetItemData(m_TreeProject->GetSelection()) );
+ if (!tree_data) return;
+
wxString FullFileName = tree_data->m_FileName;
PyHandler::GetInstance()->TriggerEvent( wxT("kicad::RunScript"), PyHandler::Convert( FullFileName ) );
PyHandler::GetInstance()->RunScript( FullFileName );
@@ -372,21 +502,22 @@

void WinEDA_PrjFrame::OnRenameAsk(wxTreeEvent & Event)
{
-	TreePrjItemData * tree_data;
-	tree_data = (TreePrjItemData*)
-	m_TreeProject->GetItemData(m_TreeProject->GetSelection());
+	TreePrjItemData * tree_data = dynamic_cast<TreePrjItemData*>( m_TreeProject->GetItemData(m_TreeProject->GetSelection()) );
+ if (!tree_data) return;

int tree_id = tree_data->m_Id;
if ( TREE_PROJECT == tree_id ) Event.Veto();
}
void WinEDA_PrjFrame::OnRename(wxTreeEvent & event)
{
-	TreePrjItemData * tree_data;
-	tree_data = (TreePrjItemData*)
-	m_TreeProject->GetItemData(m_TreeProject->GetSelection());
+ const wxString sep = wxFileName().GetPathSeparator();
+
+	TreePrjItemData * tree_data = dynamic_cast<TreePrjItemData*>( m_TreeProject->GetItemData(m_TreeProject->GetSelection()) );
+ if (!tree_data) return;
+
int tree_id = tree_data->m_Id;
wxString filename = tree_data->m_FileName;
-	wxString newFile = event.GetLabel();
+	wxString newFile = tree_data->GetDir() + sep + event.GetLabel();

wxRegEx reg( wxString::FromAscii( "^.*\\" ) + GetFileExt( (enum TreeFileType) tree_id ) + wxString::FromAscii( "$" ), wxRE_ICASE );
if ( tree_id != TREE_UNKNOWN && !reg.Matches( newFile ) )
@@ -402,6 +533,8 @@

wxRenameFile( filename, newFile );

+ tree_data->m_FileName = newFile;
+
#ifdef KICAD_PYTHON
boost::python::object param = boost::python::make_tuple( PyHandler::Convert( filename )
, PyHandler::Convert( newFile ) );
@@ -415,11 +548,10 @@
/**************************************************/
{
int tree_id;
-TreePrjItemData * tree_data;
wxString FullFileName;

-	tree_data = (TreePrjItemData*)
-	m_TreeProject->GetItemData(m_TreeProject->GetSelection());
+	TreePrjItemData * tree_data = dynamic_cast<TreePrjItemData*>( m_TreeProject->GetItemData(m_TreeProject->GetSelection()) );
+ if (!tree_data) return;

tree_id = tree_data->m_Id;
FullFileName = tree_data->m_FileName;
@@ -498,6 +630,7 @@
m_ImageList->Add(wxBitmap(icon_txt_xpm));	// TREE_TXT
m_ImageList->Add(wxBitmap(icon_cvpcb_small_xpm));	// TREE_NET
m_ImageList->Add(wxBitmap(unknown_xpm));	// TREE_UNKNOWN
+	m_ImageList->Add(wxBitmap(directory_xpm));	// TREE_DIRECTORY

SetImageList(m_ImageList);

Index: kicad-dev/bitmaps/directory.xpm
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ kicad-dev/bitmaps/directory.xpm	2007-04-29 11:47:52.000000000 +0200
@@ -0,0 +1,155 @@
+/* XPM */
+static char * directory_xpm[] = {
+"16 16 136 2",
+" c None",
+". c #469FFF",
+"+ c #4193FF",
+"@ c #4499FF",
+"# c #2C63AC",
+"$ c #4DA0FF",
+"% c #B5D9FB",
+"& c #AAD3FB",
+"* c #ADD3FB",
+"= c #89C4FF",
+"- c #184888",
+"; c #4495FF",
+"> c #AED5FB",
+", c #6DB3F9",
+"' c #6FB2F9",
+") c #6BAEF8",
+"! c #67ABF6",
+"~ c #549FF9",
+"{ c #3E91FF",
+"] c #ACD4FB",
+"^ c #6BAEF9",
+"/ c #6CAFF8",
+"( c #66AAF7",
+"_ c #5DA3F6",
+": c #74AEF7",
+"< c #9EC4F8",
+"[ c #92BCF7",
+"} c #8DB5F5",
+"| c #88B1F3",
+"1 c #83ABF2",
+"2 c #80A8F0",
+"3 c #87AEF5",
+"4 c #0940B7",
+"5 c #AAD2FB",
+"6 c #67ACF8",
+"7 c #68ABF8",
+"8 c #61A4F7",
+"9 c #5B9FF5",
+"0 c #5399F3",
+"a c #498FF1",
+"b c #3F85EF",
+"c c #367CEB",
+"d c #2E73E8",
+"e c #286BE6",
+"f c #2164E2",
+"g c #2163E5",
+"h c #023AB6",
+"i c #4394FF",
+"j c #A7D0FA",
+"k c #63A9F7",
+"l c #61A7F7",
+"m c #5BA0F6",
+"n c #5499F4",
+"o c #4B90F2",
+"p c #4186EF",
+"q c #377DEB",
+"r c #2E73E7",
+"s c #266AE5",
+"t c #2062E2",
+"u c #1C5DDF",
+"v c #1A5CE2",
+"w c #A4CEF9",
+"x c #5DA5F7",
+"y c #5DA1F6",
+"z c #559AF4",
+"A c #4C91F3",
+"B c #4489F1",
+"C c #3A7FED",
+"D c #3075E9",
+"E c #276BE5",
+"F c #2062E1",
+"G c #1B5CDE",
+"H c #1758DB",
+"I c #1857DE",
+"J c #0239B6",
+"K c #A1CBF9",
+"L c #589FF6",
+"M c #559BF5",
+"N c #4F96F3",
+"O c #478CF2",
+"P c #3D84F0",
+"Q c #3378EB",
+"R c #2B6EE7",
+"S c #2265E3",
+"T c #1C5DDE",
+"U c #1757DB",
+"V c #1554DA",
+"W c #1555DD",
+"X c #0139B5",
+"Y c #4696FF",
+"Z c #FFFFFF",
+"` c #FBFBFB",
+" .	c #F2F2F2",
+"..	c #E9E9E9",
+"+.	c #E0E0E0",
+"@.	c #D7D7D7",
+"#.	c #D4D4D4",
+"$.	c #A9A9A9",
+"%.	c #BABABA",
+"&.	c #9E9990",
+"*.	c #0A3DAF",
+"=.	c #FEFEFE",
+"-.	c #F8F8F8",
+";.	c #F1F1F1",
+">.	c #E8E8E8",
+",.	c #DCDCDC",
+"'.	c #D6D6D6",
+").	c #D2D2D2",
+"!.	c #A7A7A7",
+"~.	c #B7B7B7",
+"{.	c #929292",
+"].	c #BAB6AC",
+"^.	c #0E41B3",
+"/.	c #F0F0F0",
+"(.	c #E5E5E5",
+"_.	c #DDDDDD",
+":.	c #D3D3D3",
+"<.	c #D0D0D0",
+"[.	c #ABABAB",
+"}.	c #B5B5B5",
+"|.	c #939393",
+"1.	c #ADADAD",
+"2.	c #938E85",
+"3.	c #0A3DAE",
+"4.	c #FFFFFE",
+"5.	c #F4F4F4",
+"6.	c #EDEDED",
+"7.	c #DBDBDB",
+"8.	c #AEAEAE",
+"9.	c #969696",
+"0.	c #878787",
+"a.	c #AFABA1",
+"b.	c #0D40B2",
+"c.	c #0037B2",
+"d.	c #0034A8",
+"e.	c #0038B6",
+" ",
+" . + @ # ",
+" $ % & * = - ",
+"; > , ' ) ! ~ { + + + + + . ",
+"; ] ^ / ( _ : < [ } | 1 2 3 4 ",
+"; 5 6 7 8 9 0 a b c d e f g h ",
+"i j k l m n o p q r s t u v h ",
+"i w x y z A B C D E F G H I J ",
+"i K L M N O P Q R S T U V W X ",
+"Y Z Z Z Z ` ...+.@.#.$.%.&.*. ",
+"Y Z Z =.-.;.>.,.'.).!.~.{.].^. ",
+"Y Z =.-./.(._.:.<.[.}.|.1.2.3. ",
+"Y 4.5.6.(.7.#.<.1.8.9.!.0.a.b. ",
+" c.d.d.d.d.d.d.d.d.d.d.d.e. ",
+" ",
+" "};
Index: kicad-dev/common/gestfich.cpp
===================================================================
--- kicad-dev.orig/common/gestfich.cpp	2007-04-29 14:07:57.000000000 +0200
+++ kicad-dev/common/gestfich.cpp	2007-04-29 17:43:25.000000000 +0200
@@ -277,6 +277,8 @@
defaultpath.Replace(wxT("/"), STRING_DIR_SEP);
if ( defaultpath.IsEmpty() ) defaultpath = wxGetCwd();

+ wxSetWorkingDirectory( defaultpath );
+
fullfilename = wxFileSelector( wxString(Title),
defaultpath,
defaultname,
 --------------040101040003050605080909 Content-Type: application/vnd.oasis.opendocument.text;
name="python.odt"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
filename="python.odt"

[Attachment content not displayed.] --------------040101040003050605080909--