939 lines
27 KiB
C++
939 lines
27 KiB
C++
/*********************/
|
|
/* treeprj_frame.cpp */
|
|
/*********************/
|
|
|
|
#ifdef KICAD_PYTHON
|
|
#include <pyhandler.h>
|
|
#endif
|
|
|
|
#include "fctsys.h"
|
|
#include "gr_basic.h"
|
|
#include "common.h"
|
|
|
|
#include "kicad.h"
|
|
#include "protos.h"
|
|
|
|
#include "wx/image.h"
|
|
#include "wx/imaglist.h"
|
|
#include "wx/treectrl.h"
|
|
#include "wx/regex.h"
|
|
#include "wx/dir.h"
|
|
|
|
#include "bitmaps.h"
|
|
#ifdef KICAD_PYTHON
|
|
#include "bitmaps/new_python.xpm"
|
|
#endif
|
|
|
|
#include "id.h"
|
|
|
|
|
|
/******************************************************************/
|
|
WinEDA_PrjFrame::WinEDA_PrjFrame( WinEDA_MainFrame* parent,
|
|
const wxPoint& pos,
|
|
const wxSize& size ) :
|
|
wxSashLayoutWindow( parent, ID_LEFT_FRAME, pos, size,
|
|
wxNO_BORDER | wxSW_3D )
|
|
/******************************************************************/
|
|
{
|
|
m_Parent = parent;
|
|
m_TreeProject = NULL;
|
|
wxMenuItem* item;
|
|
m_PopupMenu = NULL;
|
|
|
|
/* Filtering is now inverted: the filters are actually used to _enable_ support
|
|
* for a given file type.
|
|
*/
|
|
m_Filters.push_back( wxT( "^.*\\.sch$" ) ); // note: sch filter must be first because of a test in AddFile() below
|
|
m_Filters.push_back( wxT( "^.*\\.pro$" ) );
|
|
m_Filters.push_back( wxT( "^.*\\.pdf$" ) );
|
|
m_Filters.push_back( wxT( "^[^$].*\\.brd$" ) );
|
|
m_Filters.push_back( wxT( "^.*\\.net$" ) );
|
|
m_Filters.push_back( wxT( "^.*\\.txt$" ) );
|
|
m_Filters.push_back( wxT( "^.*\\.pho$" ) );
|
|
m_Filters.push_back( wxT( "^no kicad files found" ) );
|
|
|
|
#ifdef KICAD_PYTHON
|
|
m_Filters.push_back( wxT( "^.*\\.py$" ) );
|
|
|
|
PyHandler::GetInstance()->DeclareEvent( wxT( "kicad::RunScript" ) );
|
|
PyHandler::GetInstance()->DeclareEvent( wxT( "kicad::EditScript" ) );
|
|
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" ) );
|
|
PyHandler::GetInstance()->DeclareEvent( wxT( "kicad::MoveFile" ) );
|
|
#endif
|
|
|
|
for( int i = 0; i < TREE_MAX; i++ )
|
|
m_ContextMenus.push_back( new wxMenu() );
|
|
|
|
// Python script context menu:
|
|
|
|
wxMenu* menu = m_ContextMenus[TREE_PY];
|
|
|
|
#ifdef KICAD_PYTHON
|
|
item = new wxMenuItem( menu, ID_PROJECT_RUNPY,
|
|
_( "&Run" ),
|
|
_( "Run the Python Script" ) );
|
|
|
|
item->SetBitmap( icon_python_small_xpm );
|
|
menu->Append( item );
|
|
#endif
|
|
|
|
item = new wxMenuItem( menu, ID_PROJECT_TXTEDIT,
|
|
_( "&Edit in a text editor" ),
|
|
_( "&Open the file in a Text Editor" ) );
|
|
|
|
item->SetBitmap( icon_txt_xpm );
|
|
menu->Append( item );
|
|
|
|
// New files context menu:
|
|
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 );
|
|
|
|
#ifdef KICAD_PYTHON
|
|
item = new wxMenuItem( menu, ID_PROJECT_NEWPY, _( "New P&ython Script" ), _(
|
|
"Create a New Python Script" ) );
|
|
|
|
item->SetBitmap( new_python_xpm );
|
|
menu->Append( item );
|
|
#endif
|
|
|
|
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 );
|
|
}
|
|
|
|
// Put the Rename and Delete file menu commands:
|
|
for( int i = TREE_PROJECT + 1; i < TREE_MAX; i++ )
|
|
{
|
|
menu = m_ContextMenus[i];
|
|
item = new wxMenuItem( menu, ID_PROJECT_RENAME,
|
|
TREE_DIRECTORY != i ? _ ("&Rename File") : _( "&Rename Directory" ),
|
|
TREE_DIRECTORY != i ? _ ("Rename the File") : _( "&Rename the Directory" ) );
|
|
|
|
item->SetBitmap( right_xpm );
|
|
menu->Append( item );
|
|
if( TREE_DIRECTORY != i )
|
|
{
|
|
item = new wxMenuItem( menu, ID_PROJECT_TXTEDIT,
|
|
_( "&Edit in a text editor" ),
|
|
_( "Open the file in a Text Editor" ) );
|
|
|
|
item->SetBitmap( icon_txt_xpm );
|
|
menu->Append( item );
|
|
}
|
|
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 );
|
|
}
|
|
|
|
ReCreateTreePrj();
|
|
}
|
|
|
|
|
|
BEGIN_EVENT_TABLE( WinEDA_PrjFrame, wxSashLayoutWindow )
|
|
|
|
EVT_TREE_BEGIN_LABEL_EDIT( ID_PROJECT_TREE, WinEDA_PrjFrame::OnRenameAsk )
|
|
EVT_TREE_END_LABEL_EDIT( ID_PROJECT_TREE, WinEDA_PrjFrame::OnRename )
|
|
EVT_TREE_ITEM_ACTIVATED( ID_PROJECT_TREE, WinEDA_PrjFrame::OnSelect )
|
|
EVT_TREE_ITEM_RIGHT_CLICK( ID_PROJECT_TREE, WinEDA_PrjFrame::OnRight )
|
|
EVT_TREE_BEGIN_DRAG( ID_PROJECT_TREE, WinEDA_PrjFrame::OnDragStart )
|
|
EVT_TREE_END_DRAG( ID_PROJECT_TREE, WinEDA_PrjFrame::OnDragEnd )
|
|
EVT_MENU( ID_PROJECT_TXTEDIT, WinEDA_PrjFrame::OnTxtEdit )
|
|
EVT_MENU( ID_PROJECT_NEWFILE, WinEDA_PrjFrame::OnNewFile )
|
|
EVT_MENU( ID_PROJECT_NEWDIR, WinEDA_PrjFrame::OnNewDirectory )
|
|
EVT_MENU( ID_PROJECT_NEWPY, WinEDA_PrjFrame::OnNewPyFile )
|
|
EVT_MENU( ID_PROJECT_NEWTXT, WinEDA_PrjFrame::OnNewTxtFile )
|
|
EVT_MENU( ID_PROJECT_DELETE, WinEDA_PrjFrame::OnDeleteFile )
|
|
EVT_MENU( ID_PROJECT_RENAME, WinEDA_PrjFrame::OnRenameFile )
|
|
|
|
#ifdef KICAD_PYTHON
|
|
EVT_MENU( ID_PROJECT_RUNPY, WinEDA_PrjFrame::OnRunPy )
|
|
#endif
|
|
END_EVENT_TABLE()
|
|
|
|
/********************************/
|
|
WinEDA_TreePrj::~WinEDA_TreePrj()
|
|
/********************************/
|
|
{
|
|
}
|
|
|
|
|
|
/*******************************************************/
|
|
void WinEDA_PrjFrame::OnDragStart( wxTreeEvent& event )
|
|
/*******************************************************/
|
|
|
|
// Allowing drag&drop of file other than the currently opened project
|
|
{
|
|
/* Ensure item is selected (Under Windows start drag does not activate the item) */
|
|
wxTreeItemId curr_item = event.GetItem();
|
|
|
|
m_TreeProject->SelectItem( curr_item );
|
|
TreePrjItemData* data = GetSelectedData();
|
|
if( data->GetFileName() == m_Parent->m_PrjFileName )
|
|
return;
|
|
|
|
wxTreeItemId id = m_TreeProject->GetSelection();
|
|
|
|
wxImage img = m_TreeProject->GetImageList()->GetBitmap( data->GetType() -
|
|
1 ).ConvertToImage();
|
|
m_DragCursor = wxCursor( img );
|
|
m_Parent->wxWindow::SetCursor( (wxCursor &)m_DragCursor );
|
|
event.Allow();
|
|
}
|
|
|
|
|
|
/*******************************************************/
|
|
void WinEDA_PrjFrame::OnDragEnd( wxTreeEvent& event )
|
|
/*******************************************************/
|
|
{
|
|
m_Parent->SetCursor( wxNullCursor );
|
|
|
|
wxTreeItemId moved = m_TreeProject->GetSelection();
|
|
TreePrjItemData* source_data = GetSelectedData();
|
|
wxTreeItemId dest = event.GetItem();
|
|
if( !dest.IsOk() )
|
|
return; // Cancelled ...
|
|
TreePrjItemData* destData = dynamic_cast<TreePrjItemData*>( m_TreeProject->GetItemData( dest ) );
|
|
if( !destData )
|
|
return;
|
|
|
|
// the item can be a member of the selected directory; get the directory itself
|
|
if( TREE_DIRECTORY != destData->GetType() && !m_TreeProject->ItemHasChildren( dest ) )
|
|
{ // the item is a member of the selected directory; get the directory itself
|
|
dest = m_TreeProject->GetItemParent( dest );
|
|
if( !dest.IsOk() )
|
|
return; // no parent ?
|
|
|
|
// Select the right destData:
|
|
destData = dynamic_cast<TreePrjItemData*>( m_TreeProject->GetItemData( dest ) );
|
|
if( !destData )
|
|
return;
|
|
}
|
|
|
|
source_data->Move( destData );
|
|
|
|
#if 0
|
|
/* Sort filenames by alphabetic order */
|
|
m_TreeProject->SortChildren( dest );
|
|
#endif
|
|
}
|
|
|
|
|
|
/************************************/
|
|
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
|
|
|
|
/********************************************************************************/
|
|
TreePrjItemData* WinEDA_PrjFrame::FindItemData( const boost::python::str& name )
|
|
/********************************************************************************/
|
|
|
|
// Return the data corresponding to the file, or NULL
|
|
{
|
|
// (Interative tree parsing)
|
|
std::vector< wxTreeItemId > roots1, roots2;
|
|
std::vector< wxTreeItemId > * root, * reserve;
|
|
wxString filename = PyHandler::MakeStr( name );
|
|
|
|
root = &roots1;
|
|
reserve = &roots2;
|
|
|
|
root->push_back( m_TreeProject->GetRootItem() );
|
|
|
|
// if we look for the root, return it ...
|
|
TreePrjItemData* data = dynamic_cast< TreePrjItemData*>(
|
|
m_TreeProject->GetItemData( root->at( 0 ) ) );
|
|
|
|
if( data->GetFileName() == filename )
|
|
return data;
|
|
|
|
// Then find in its child
|
|
while( root->size() )
|
|
{
|
|
// look in all roots
|
|
for( unsigned int i = 0; i < root->size(); i++ )
|
|
{
|
|
wxTreeItemId id = root->at( i );
|
|
|
|
// for each root check any child:
|
|
void* cookie = NULL;
|
|
wxTreeItemId child = m_TreeProject->GetFirstChild( id, cookie );
|
|
|
|
while( child.IsOk() )
|
|
{
|
|
TreePrjItemData* data = dynamic_cast< TreePrjItemData*>(
|
|
m_TreeProject->GetItemData( child ) );
|
|
|
|
if( data )
|
|
{
|
|
if( data->GetFileName() == filename )
|
|
return data;
|
|
if( m_TreeProject->ItemHasChildren( child ) )
|
|
reserve->push_back( child );
|
|
}
|
|
child = m_TreeProject->GetNextSibling( child );
|
|
}
|
|
}
|
|
|
|
// Swap the roots
|
|
root->clear();
|
|
std::vector< wxTreeItemId > * tmp;
|
|
tmp = root;
|
|
root = reserve;
|
|
reserve = tmp;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/******************************************************************/
|
|
void WinEDA_PrjFrame::RemoveFilterPy( const boost::python::str& filter )
|
|
/******************************************************************/
|
|
{
|
|
RemoveFilter( PyHandler::MakeStr( filter ) );
|
|
}
|
|
|
|
|
|
/******************************************************************/
|
|
void WinEDA_PrjFrame::AddFilter( const boost::python::str& filter )
|
|
/******************************************************************/
|
|
{
|
|
wxRegEx reg;
|
|
wxString text = PyHandler::MakeStr( filter );
|
|
|
|
if( !reg.Compile( text ) )
|
|
return;
|
|
m_Filters.push_back( text );
|
|
}
|
|
|
|
#endif
|
|
|
|
/******************************************************************/
|
|
const std::vector<wxString>& WinEDA_PrjFrame::GetFilters()
|
|
/******************************************************************/
|
|
{
|
|
return m_Filters;
|
|
}
|
|
|
|
|
|
/******************************************************************/
|
|
wxMenu* WinEDA_PrjFrame::GetContextMenu( int type )
|
|
/******************************************************************/
|
|
{
|
|
return m_ContextMenus[type];
|
|
}
|
|
|
|
|
|
void WinEDA_PrjFrame::OnNewDirectory( wxCommandEvent& event )
|
|
{
|
|
NewFile( TREE_DIRECTORY );
|
|
}
|
|
void WinEDA_PrjFrame::OnNewFile( wxCommandEvent& event )
|
|
{
|
|
NewFile( TREE_UNKNOWN );
|
|
}
|
|
void WinEDA_PrjFrame::OnNewPyFile( wxCommandEvent& event )
|
|
{
|
|
NewFile( TREE_PY );
|
|
}
|
|
void WinEDA_PrjFrame::OnNewTxtFile( wxCommandEvent& event )
|
|
{
|
|
NewFile( TREE_TXT );
|
|
}
|
|
|
|
/******************************************************************/
|
|
void WinEDA_PrjFrame::NewFile( TreeFileType type )
|
|
/******************************************************************/
|
|
{
|
|
wxString filename;
|
|
wxString mask = GetFileExt( type );
|
|
const wxString sep = wxFileName().GetPathSeparator();
|
|
|
|
// Get the directory:
|
|
wxString dir;
|
|
|
|
TreePrjItemData* treeData;
|
|
wxString FullFileName;
|
|
|
|
treeData = GetSelectedData();
|
|
if( !treeData )
|
|
return;
|
|
|
|
dir = treeData->GetDir();
|
|
|
|
// Ask for the new file name
|
|
|
|
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 | wxFD_OVERWRITE_PROMPT,
|
|
TRUE
|
|
);
|
|
if( filename.IsEmpty() )
|
|
return;
|
|
|
|
TreeFileType rootType = treeData->GetType();
|
|
wxTreeItemId root;
|
|
|
|
if( TREE_DIRECTORY == rootType )
|
|
{
|
|
root = m_TreeProject->GetSelection();
|
|
}
|
|
else
|
|
{
|
|
root = m_TreeProject->GetItemParent( m_TreeProject->GetSelection() );
|
|
if( !root.IsOk() )
|
|
root = m_TreeProject->GetSelection();
|
|
}
|
|
|
|
NewFile( filename, type, root );
|
|
}
|
|
|
|
|
|
/******************************************************************/
|
|
void WinEDA_PrjFrame::NewFile( const wxString& name,
|
|
TreeFileType type, wxTreeItemId& root )
|
|
/******************************************************************/
|
|
{
|
|
if( TREE_DIRECTORY != type )
|
|
{
|
|
wxFile( name, wxFile::write );
|
|
#ifdef KICAD_PYTHON
|
|
PyHandler::GetInstance()->TriggerEvent(
|
|
wxT( "kicad::NewFile" ), PyHandler::Convert( name ) );
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
wxMkdir( name );
|
|
#ifdef KICAD_PYTHON
|
|
PyHandler::GetInstance()->TriggerEvent(
|
|
wxT( "kicad::NewDirectory" ), PyHandler::Convert( name ) );
|
|
#endif
|
|
}
|
|
|
|
AddFile( name, root );
|
|
}
|
|
|
|
|
|
/******************************************************************/
|
|
wxString WinEDA_PrjFrame::GetFileExt( TreeFileType type )
|
|
/******************************************************************/
|
|
{
|
|
wxString ext;
|
|
|
|
switch( type )
|
|
{
|
|
case 0:
|
|
break; // 0 is not used
|
|
|
|
case TREE_PROJECT:
|
|
ext = wxT( ".pro" );
|
|
break;
|
|
|
|
case TREE_SCHEMA:
|
|
ext = g_SchExtBuffer;
|
|
break;
|
|
|
|
case TREE_PCB:
|
|
ext = g_BoardExtBuffer;
|
|
break;
|
|
|
|
case TREE_PY:
|
|
ext = wxT( ".py" );
|
|
break;
|
|
|
|
case TREE_GERBER:
|
|
ext = g_GerberExtBuffer;
|
|
break;
|
|
|
|
case TREE_PDF:
|
|
ext = wxT( ".pdf" );
|
|
break;
|
|
|
|
case TREE_TXT:
|
|
ext = wxT( ".txt" );
|
|
break;
|
|
|
|
case TREE_NET:
|
|
ext = wxT( ".net" );
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return ext;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
bool WinEDA_PrjFrame::AddFile( const wxString& name, wxTreeItemId& root )
|
|
/**************************************************************************/
|
|
|
|
/* add filename "name" to the tree
|
|
* if name is a directory, add the sub directory file names
|
|
*/
|
|
{
|
|
wxTreeItemId cellule;
|
|
|
|
// Check the file type
|
|
TreeFileType type = TREE_UNKNOWN;
|
|
|
|
if( wxDirExists( name ) )
|
|
{
|
|
type = TREE_DIRECTORY;
|
|
}
|
|
else
|
|
{
|
|
// Filter
|
|
wxRegEx reg;
|
|
|
|
bool isSchematic=false;
|
|
bool addFile=false;
|
|
for( unsigned i=0; i < m_Filters.size(); i++ )
|
|
{
|
|
reg.Compile( m_Filters[i], wxRE_ICASE );
|
|
if( reg.Matches( name ) )
|
|
{
|
|
addFile=true;
|
|
if( i==0 )
|
|
isSchematic = true;
|
|
}
|
|
}
|
|
if( !addFile )
|
|
return false;
|
|
|
|
// only show the schematic if it is a top level schematic. eeschema
|
|
// cannot open a schematic and display it properly unless it starts
|
|
// at the top of the hierarchy. The schematic is top level only if
|
|
// there is a line in the header saying:
|
|
// "Sheet 1 "
|
|
if( isSchematic )
|
|
{
|
|
char line[128]; // small because we just need a few bytes from the start of a line
|
|
FILE* fp;
|
|
|
|
wxString FullFileName = name;
|
|
|
|
fp = wxFopen( FullFileName, wxT( "rt" ) );
|
|
if( fp == NULL )
|
|
{
|
|
//printf("Unable to open \"%s\"\n", (const char*) FullFileName.mb_str() );
|
|
return false; // why show a file we cannot open?
|
|
}
|
|
|
|
addFile = false;
|
|
for( int i=0; i<20; ++i )
|
|
{
|
|
if( !fgets( line, sizeof(line), fp ) )
|
|
break;
|
|
|
|
if( !strncmp( line, "Sheet 1 ", 8 ) )
|
|
{
|
|
addFile = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
if( !addFile )
|
|
return false; // it is a non-top-level schematic
|
|
}
|
|
|
|
for( int i = TREE_PROJECT; i < TREE_MAX; i++ )
|
|
{
|
|
wxString ext = GetFileExt( (TreeFileType) i );
|
|
|
|
if( ext == wxT( "" ) )
|
|
continue;
|
|
|
|
reg.Compile( wxString::FromAscii( "^.*\\" ) + ext +
|
|
wxString::FromAscii("$" ), wxRE_ICASE );
|
|
|
|
if( reg.Matches( name ) )
|
|
{
|
|
type = (TreeFileType) i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//also check to see if it is already there.
|
|
wxTreeItemIdValue cookie;
|
|
wxTreeItemId kid = m_TreeProject->GetFirstChild(root, cookie);
|
|
while(kid.IsOk())
|
|
{
|
|
TreePrjItemData* itemData = (TreePrjItemData*)
|
|
m_TreeProject->GetItemData(kid);
|
|
if( itemData ){
|
|
if( itemData->m_FileName == name ){
|
|
return true; //well, we would have added it, but it is already here!
|
|
}
|
|
}
|
|
kid = m_TreeProject->GetNextChild(root, cookie);
|
|
}
|
|
// Append the item (only appending the filename not the full path):
|
|
|
|
wxString file = wxFileNameFromPath( name );
|
|
cellule = m_TreeProject->AppendItem( root, file );
|
|
TreePrjItemData* data = new TreePrjItemData( type, name, m_TreeProject );
|
|
|
|
m_TreeProject->SetItemFont( cellule, *g_StdFont );
|
|
m_TreeProject->SetItemData( cellule, data );
|
|
data->SetState( 0 );
|
|
|
|
/* Mark root files (files which have the same name as the project) */
|
|
wxFileName project( m_Parent->m_PrjFileName );
|
|
wxFileName currfile( file );
|
|
|
|
if( currfile.GetName().CmpNoCase( project.GetName() ) == 0 )
|
|
data->m_IsRootFile = true;
|
|
else
|
|
data->m_IsRootFile = false;
|
|
|
|
#ifdef KICAD_PYTHON
|
|
PyHandler::GetInstance()->TriggerEvent( wxT( "kicad::TreeAddFile" ), PyHandler::Convert( name ) );
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
|
|
/******************************************/
|
|
void WinEDA_PrjFrame::ReCreateTreePrj()
|
|
/******************************************/
|
|
|
|
/* Create or modify the tree showing project file names
|
|
*/
|
|
{
|
|
wxTreeItemId rootcellule;
|
|
wxString Text;
|
|
bool prjOpened = false;
|
|
|
|
if( !m_TreeProject )
|
|
m_TreeProject = new WinEDA_TreePrj( this );
|
|
else
|
|
m_TreeProject->DeleteAllItems();
|
|
|
|
m_TreeProject->SetFont( *g_StdFont );
|
|
|
|
if( m_Parent->m_PrjFileName.IsEmpty() )
|
|
Text = wxT( "noname" );
|
|
else
|
|
Text = wxFileNameFromPath( m_Parent->m_PrjFileName );
|
|
|
|
prjOpened = wxFileExists( Text );
|
|
|
|
// root tree:
|
|
m_root = rootcellule = m_TreeProject->AddRoot( Text, TREE_PROJECT - 1, TREE_PROJECT - 1 );
|
|
|
|
m_TreeProject->SetItemBold( rootcellule, TRUE );
|
|
|
|
m_TreeProject->SetItemData( rootcellule,
|
|
new TreePrjItemData( TREE_PROJECT, wxEmptyString, m_TreeProject ) );
|
|
|
|
m_TreeProject->SetItemFont( rootcellule, *g_StdFont );
|
|
|
|
ChangeFileNameExt( Text, wxEmptyString );
|
|
|
|
// Add at least a .scn / .brd if not existing:
|
|
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 )
|
|
{
|
|
wxDir dir( wxGetCwd() );
|
|
wxString dir_str = dir.GetName();
|
|
wxString sep = wxFileName().GetPathSeparator();
|
|
wxString filename;
|
|
|
|
if( dir.GetFirst( &filename ) )
|
|
{
|
|
do
|
|
{
|
|
if( filename == Text + wxT( ".pro" ) )
|
|
continue;
|
|
|
|
AddFile(dir_str + sep + filename, m_root );
|
|
|
|
} while( dir.GetNext( &filename ) );
|
|
}
|
|
}
|
|
|
|
m_TreeProject->Expand( rootcellule );
|
|
|
|
/* Sort filenames by alphabetic order */
|
|
m_TreeProject->SortChildren( m_root );
|
|
}
|
|
|
|
|
|
/**************************************************/
|
|
void WinEDA_PrjFrame::OnRight( wxTreeEvent& Event )
|
|
/**************************************************/
|
|
|
|
// Opens (popup) the context menu
|
|
{
|
|
int tree_id;
|
|
TreePrjItemData* tree_data;
|
|
wxString FullFileName;
|
|
wxTreeItemId curr_item = Event.GetItem();
|
|
|
|
/* Ensure item is selected (Under Windows right click does not select the item) */
|
|
m_TreeProject->SelectItem( curr_item );
|
|
|
|
// Delete and recreate the context menu
|
|
delete( m_PopupMenu );
|
|
m_PopupMenu = new wxMenu();
|
|
|
|
// Get the current filename:
|
|
tree_data = GetSelectedData();
|
|
if( !tree_data )
|
|
return;
|
|
|
|
tree_id = tree_data->GetType();
|
|
FullFileName = tree_data->GetFileName();
|
|
|
|
// copy menu contents in order of the next array:
|
|
wxMenu* menus[] =
|
|
{
|
|
GetContextMenu( tree_id ),
|
|
const_cast<wxMenu*>( tree_data->GetMenu() )
|
|
};
|
|
|
|
for( unsigned int j=0; j < sizeof(menus)/sizeof(wxMenu*); j++ )
|
|
{
|
|
wxMenu* menu = menus[j];
|
|
if( !menu )
|
|
continue;
|
|
|
|
wxMenuItemList list = menu->GetMenuItems();
|
|
|
|
for( unsigned int i = 0; i < list.GetCount(); i++ )
|
|
{
|
|
// Grrrr! wxMenu does not have any copy constructor !! (do it by hand)
|
|
wxMenuItem* src = list[i];
|
|
wxString label = src->GetText();
|
|
|
|
// for obscure reasons, the & is translated into _ ... so replace it
|
|
label.Replace( wxT( "_" ), wxT( "&" ), true );
|
|
wxMenuItem* item = new wxMenuItem( m_PopupMenu, src->GetId(),
|
|
label, src->GetHelp(), src->GetKind() );
|
|
|
|
item->SetBitmap( src->GetBitmap() );
|
|
m_PopupMenu->Append( item );
|
|
}
|
|
}
|
|
|
|
// At last, call python to let python add menu items "on the fly"
|
|
|
|
#ifdef KICAD_PYTHON
|
|
PyHandler::GetInstance()->TriggerEvent( wxT( "kicad::TreeContextMenu" ),
|
|
PyHandler::Convert( FullFileName ) );
|
|
#endif
|
|
|
|
if( m_PopupMenu )
|
|
PopupMenu( m_PopupMenu );
|
|
}
|
|
|
|
|
|
/*******************************************************/
|
|
void WinEDA_PrjFrame::OnTxtEdit( wxCommandEvent& event )
|
|
/*******************************************************/
|
|
{
|
|
TreePrjItemData* tree_data = GetSelectedData();
|
|
|
|
if( !tree_data )
|
|
return;
|
|
|
|
wxString FullFileName = tree_data->GetFileName();
|
|
AddDelimiterString( FullFileName );
|
|
wxString editorname = GetEditorName();
|
|
if( !editorname.IsEmpty() )
|
|
{
|
|
#ifdef KICAD_PYTHON
|
|
PyHandler::GetInstance()->TriggerEvent( wxT( "kicad::EditScript" ),
|
|
PyHandler::Convert( FullFileName ) );
|
|
#endif
|
|
ExecuteFile( this, editorname, FullFileName );
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************/
|
|
void WinEDA_PrjFrame::OnDeleteFile( wxCommandEvent& )
|
|
/***************************************************/
|
|
{
|
|
TreePrjItemData* tree_data = GetSelectedData();
|
|
|
|
if( !tree_data )
|
|
return;
|
|
tree_data->Delete();
|
|
}
|
|
|
|
|
|
/***************************************************/
|
|
void WinEDA_PrjFrame::OnRenameFile( wxCommandEvent& )
|
|
/***************************************************/
|
|
{
|
|
wxTreeItemId curr_item = m_TreeProject->GetSelection();
|
|
TreePrjItemData* tree_data = GetSelectedData();
|
|
|
|
if( !tree_data )
|
|
return;
|
|
|
|
wxString buffer = m_TreeProject->GetItemText( curr_item );
|
|
wxString msg = _( "Change File Name: " ) + tree_data->m_FileName;
|
|
if( Get_Message( msg, buffer, this ) != 0 )
|
|
return; //Abort command
|
|
|
|
if( tree_data->Rename( buffer, true ) )
|
|
{
|
|
m_TreeProject->SetItemText( curr_item, buffer );
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef KICAD_PYTHON
|
|
/***************************************************/
|
|
void WinEDA_PrjFrame::OnRunPy( wxCommandEvent& event )
|
|
/***************************************************/
|
|
{
|
|
TreePrjItemData* tree_data = GetSelectedData();
|
|
|
|
if( !tree_data )
|
|
return;
|
|
|
|
wxString FullFileName = tree_data->GetFileName();
|
|
PyHandler::GetInstance()->TriggerEvent( wxT( "kicad::RunScript" ),
|
|
PyHandler::Convert( FullFileName ) );
|
|
PyHandler::GetInstance()->RunScript( FullFileName );
|
|
}
|
|
|
|
|
|
/****************************************************************/
|
|
int WinEDA_PrjFrame::AddStatePy( boost::python::object& bitmap )
|
|
/****************************************************************/
|
|
|
|
// Add a state to the image list ...
|
|
{
|
|
wxBitmap* image;
|
|
bool success = wxPyConvertSwigPtr( bitmap.ptr(), (void**) &image, _T( "wxBitmap" ) );
|
|
|
|
if( !success )
|
|
return -1;
|
|
|
|
wxImageList* list = m_TreeProject->GetImageList();
|
|
int ret = list->GetImageCount() / ( TREE_MAX - 2 );
|
|
|
|
for( int i = 0; i < TREE_MAX - 1; i++ )
|
|
{
|
|
wxBitmap composed( list->GetBitmap ( i ) );
|
|
|
|
wxMemoryDC dc;
|
|
dc.SelectObject( composed );
|
|
dc.DrawBitmap( *image, 0, 0, true );
|
|
list->Add( composed );
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
/***************************************************/
|
|
void WinEDA_PrjFrame::OnRenameAsk( wxTreeEvent& event )
|
|
/***************************************************/
|
|
/* Prevent the main project to be renamed */
|
|
{
|
|
TreePrjItemData* tree_data = GetSelectedData();
|
|
|
|
if( !tree_data )
|
|
return;
|
|
if( m_Parent->m_PrjFileName == tree_data->GetFileName() )
|
|
event.Veto();
|
|
}
|
|
|
|
|
|
/***************************************************/
|
|
void WinEDA_PrjFrame::OnRename( wxTreeEvent& event )
|
|
/***************************************************/
|
|
/* rename a tree item on demand of the context menu */
|
|
{
|
|
TreePrjItemData* tree_data = GetSelectedData();
|
|
|
|
if( !tree_data )
|
|
return;
|
|
|
|
tree_data->OnRename( event );
|
|
}
|
|
|
|
|
|
/**************************************************/
|
|
void WinEDA_PrjFrame::OnSelect( wxTreeEvent& Event )
|
|
/**************************************************/
|
|
{
|
|
wxString FullFileName;
|
|
|
|
TreePrjItemData* tree_data = GetSelectedData();
|
|
|
|
if( !tree_data )
|
|
return;
|
|
tree_data->Activate(this);
|
|
}
|