kicad/eeschema/sheetlab.cpp

469 lines
15 KiB
C++

/****************************************************************/
/* sheetlab.cpp module pour creation /editin des Sheet labels */
/****************************************************************/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "program.h"
#include "libcmp.h"
#include "general.h"
#include "protos.h"
/* Routines Locales */
static void ExitPinSheet( WinEDA_DrawPanel* Panel, wxDC* DC );
static void Move_PinSheet( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
/* Variables locales */
static int CurrentTypeLabel = NET_INPUT;
static wxSize NetSheetTextSize( DEFAULT_SIZE_TEXT, DEFAULT_SIZE_TEXT );
/****************************************/
/* class WinEDA_PinSheetPropertiesFrame */
/****************************************/
#define NBSHAPES 5
static wxString shape_list[NBSHAPES] =
{
wxT( "Input" ), wxT( "Output" ), wxT( "Bidi" ), wxT( "TriState" ), wxT( "Passive" )
};
enum id_Textdit {
ID_ACCEPT_PINSHEET_PROPERTIES = 1970,
ID_CANCEL_PINSHEET_PROPERTIES
};
/*****************************************************/
class WinEDA_PinSheetPropertiesFrame : public wxDialog
/*****************************************************/
{
private:
WinEDA_SchematicFrame* m_Parent;
DrawSheetLabelStruct* m_CurrentPinSheet;
wxRadioBox* m_PinSheetType;
wxRadioBox* m_PinSheetShape;
WinEDA_GraphicTextCtrl* m_TextWin;
public:
// Constructor and destructor
WinEDA_PinSheetPropertiesFrame( WinEDA_SchematicFrame* parent,
DrawSheetLabelStruct* curr_pinsheet,
const wxPoint& framepos = wxPoint( -1, -1 ) );
~WinEDA_PinSheetPropertiesFrame( void ) { };
private:
void PinSheetPropertiesAccept( wxCommandEvent& event );
void OnQuit( wxCommandEvent& event );
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE( WinEDA_PinSheetPropertiesFrame, wxDialog )
EVT_BUTTON( ID_ACCEPT_PINSHEET_PROPERTIES,
WinEDA_PinSheetPropertiesFrame::PinSheetPropertiesAccept )
EVT_BUTTON( ID_CANCEL_PINSHEET_PROPERTIES, WinEDA_PinSheetPropertiesFrame::OnQuit )
END_EVENT_TABLE()
/**********************************************************************************/
WinEDA_PinSheetPropertiesFrame::WinEDA_PinSheetPropertiesFrame(
WinEDA_SchematicFrame* parent,
DrawSheetLabelStruct* curr_pinsheet,
const wxPoint& framepos ) :
wxDialog( parent, -1, _( "PinSheet Properties:" ), framepos, wxSize( 340, 220 ),
DIALOG_STYLE )
/**********************************************************************************/
{
wxPoint pos;
wxString number;
wxButton* Button;
m_Parent = parent;
Centre();
wxBoxSizer* MainBoxSizer = new wxBoxSizer( wxHORIZONTAL );
SetSizer( MainBoxSizer );
wxBoxSizer* LeftBoxSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* RightBoxSizer = new wxBoxSizer( wxVERTICAL );
MainBoxSizer->Add( LeftBoxSizer, 0, wxGROW | wxALL, 5 );
MainBoxSizer->Add( RightBoxSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
m_CurrentPinSheet = curr_pinsheet;
/* Creation des boutons de commande */
Button = new wxButton( this, ID_ACCEPT_PINSHEET_PROPERTIES,
_( "Ok" ) );
Button->SetForegroundColour( *wxRED );
RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
Button = new wxButton( this, ID_CANCEL_PINSHEET_PROPERTIES,
_( "Cancel" ) );
Button->SetForegroundColour( *wxBLUE );
RightBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
m_TextWin = new WinEDA_GraphicTextCtrl( this, _( "Text:" ),
m_CurrentPinSheet->m_Text, m_CurrentPinSheet->m_Size.x,
g_UnitMetric, LeftBoxSizer, 200 );
// Selection de la forme :
m_PinSheetShape = new wxRadioBox( this, -1, _( "PinSheet Shape:" ),
wxDefaultPosition, wxSize( -1, -1 ),
NBSHAPES, shape_list, 1 );
m_PinSheetShape->SetSelection( m_CurrentPinSheet->m_Shape );
LeftBoxSizer->Add( m_PinSheetShape, 0, wxGROW | wxALL, 5 );
GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this );
}
/************************************************************************/
void WinEDA_PinSheetPropertiesFrame::OnQuit( wxCommandEvent& WXUNUSED (event) )
/************************************************************************/
{
// true is to force the frame to close
Close( true );
}
/***********************************************************************************/
void WinEDA_PinSheetPropertiesFrame::PinSheetPropertiesAccept( wxCommandEvent& event )
/***********************************************************************************/
{
m_CurrentPinSheet->m_Text = m_TextWin->GetText();
m_CurrentPinSheet->m_Size.x = m_CurrentPinSheet->m_Size.y = m_TextWin->GetTextSize();
m_CurrentPinSheet->m_Shape = m_PinSheetShape->GetSelection();
Close( TRUE );
}
/*****************************************************************/
static void ExitPinSheet( WinEDA_DrawPanel* Panel, wxDC* DC )
/*****************************************************************/
/* Routine de sortie du Menu d'Edition Des NETS (Labels) SHEET
*/
{
DrawSheetLabelStruct* SheetLabel = (DrawSheetLabelStruct*)
Panel->GetScreen()->GetCurItem();
if( SheetLabel == NULL )
return;
if( SheetLabel->m_Flags & IS_NEW )
{ /* Nouveau Placement en cours, on l'efface */
RedrawOneStruct( Panel, DC, SheetLabel, g_XorMode );
delete SheetLabel;
}
else
{
RedrawOneStruct( Panel, DC, SheetLabel, GR_DEFAULT_DRAWMODE );
SheetLabel->m_Flags = 0;
}
Panel->GetScreen()->SetCurItem( NULL );
Panel->ManageCurseur = NULL;
Panel->ForceCloseManageCurseur = NULL;
}
/* Cette routine place un nouveau NetSheet ou place un ancien en cours
* de deplacement
* Si le NetSheet est nouveau, il est pointe par NewSheetLabel
*/
void DrawSheetLabelStruct::Place( WinEDA_DrawFrame* frame, wxDC* DC )
{
DrawSheetStruct* Sheet = (DrawSheetStruct*) m_Parent;
if( m_Flags & IS_NEW ) /* ajout a la liste des structures */
{
if( Sheet->m_Label == NULL )
Sheet->m_Label = this;
else
{
DrawSheetLabelStruct* pinsheet = Sheet->m_Label;
while( pinsheet )
{
if( pinsheet->Pnext == NULL )
{
pinsheet->Pnext = this;
break;
}
pinsheet = (DrawSheetLabelStruct*) pinsheet->Pnext;
}
}
}
m_Flags = 0;
m_Pos.x = Sheet->m_Pos.x;
m_Edge = 0;
if( frame->GetScreen()->m_Curseur.x > ( Sheet->m_Pos.x + (Sheet->m_Size.x / 2) ) )
{
m_Edge = 1;
m_Pos.x = Sheet->m_Pos.x + Sheet->m_Size.x;
}
m_Pos.y = frame->GetScreen()->m_Curseur.y;
if( m_Pos.y < Sheet->m_Pos.y )
m_Pos.y = Sheet->m_Pos.y;
if( m_Pos.y > (Sheet->m_Pos.y + Sheet->m_Size.y) )
m_Pos.y = Sheet->m_Pos.y + Sheet->m_Size.y;
RedrawOneStruct( frame->DrawPanel, DC, Sheet, GR_DEFAULT_DRAWMODE );
frame->DrawPanel->ManageCurseur = NULL;
frame->DrawPanel->ForceCloseManageCurseur = NULL;
}
/*******************************************************************************/
void WinEDA_SchematicFrame::StartMove_PinSheet( DrawSheetLabelStruct* SheetLabel,
wxDC* DC )
/*******************************************************************************/
/* Initialise un deplacement de NetSheet */
{
NetSheetTextSize = SheetLabel->m_Size;
CurrentTypeLabel = SheetLabel->m_Shape;
SheetLabel->m_Flags |= IS_MOVED;
DrawPanel->ManageCurseur = Move_PinSheet;
DrawPanel->ForceCloseManageCurseur = ExitPinSheet;
DrawPanel->ManageCurseur( DrawPanel, DC, TRUE );
}
/**********************************************************************/
/* Routine de deplacement du NetSheet actif selon la position souris */
/**********************************************************************/
static void Move_PinSheet( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
{
DrawSheetLabelStruct* SheetLabel = (DrawSheetLabelStruct*)
panel->m_Parent->GetScreen()->GetCurItem();
if( SheetLabel == NULL )
return;
DrawSheetStruct* Sheet = (DrawSheetStruct*) SheetLabel->m_Parent;
if( Sheet == NULL )
return;
if( erase )
RedrawOneStruct( panel, DC, SheetLabel, g_XorMode );
SheetLabel->m_Edge = 0;
SheetLabel->m_Pos.x = Sheet->m_Pos.x;
if( panel->m_Parent->GetScreen()->m_Curseur.x > ( Sheet->m_Pos.x + (Sheet->m_Size.x / 2) ) )
{
SheetLabel->m_Edge = 1;
SheetLabel->m_Pos.x = Sheet->m_Pos.x + Sheet->m_Size.x;
}
SheetLabel->m_Pos.y = panel->m_Parent->GetScreen()->m_Curseur.y;
if( SheetLabel->m_Pos.y < Sheet->m_Pos.y )
SheetLabel->m_Pos.y = Sheet->m_Pos.y;
if( SheetLabel->m_Pos.y > (Sheet->m_Pos.y + Sheet->m_Size.y) )
SheetLabel->m_Pos.y = Sheet->m_Pos.y + Sheet->m_Size.y;
RedrawOneStruct( panel, DC, SheetLabel, g_XorMode );
}
/***************************************************************************/
void WinEDA_SchematicFrame::Edit_PinSheet( DrawSheetLabelStruct* SheetLabel,
wxDC* DC )
/***************************************************************************/
/* Modification du texte d'un net sheet */
{
if( SheetLabel == NULL )
return;
RedrawOneStruct( DrawPanel, DC, SheetLabel, g_XorMode );
WinEDA_PinSheetPropertiesFrame* frame =
new WinEDA_PinSheetPropertiesFrame( this, SheetLabel );
frame->ShowModal(); frame->Destroy();
RedrawOneStruct( DrawPanel, DC, SheetLabel, GR_DEFAULT_DRAWMODE );
}
/***************************************************************/
DrawSheetLabelStruct* WinEDA_SchematicFrame::Create_PinSheet(
DrawSheetStruct* Sheet, wxDC* DC )
/**************************************************************/
/* Addition d'un nouveau PinSheet sur la feuille selectionnee, a l'endroit
* pointe par la souris
*/
{
wxString Line, Text;
DrawSheetLabelStruct* NewSheetLabel;
switch( CurrentTypeLabel )
{
default:
CurrentTypeLabel = NET_INPUT;
case NET_INPUT:
Text = wxT( "Pin Input: " );
break;
case NET_OUTPUT:
Text = wxT( "Pin Output: " );
break;
case NET_BIDI:
Text = wxT( "Pin BiDi: " );
break;
case NET_TRISTATE:
Text = wxT( "Pin TriStat: " );
break;
case NET_UNSPECIFIED:
Text = wxT( "Pin Unspec.: " );
break;
}
Get_Message( Text, Line, this );
if( Line.IsEmpty() )
return NULL;
GetScreen()->SetModify();
/* Creation en memoire */
NewSheetLabel = new DrawSheetLabelStruct( Sheet, wxPoint( 0, 0 ), Line );
NewSheetLabel->m_Flags = IS_NEW;
NewSheetLabel->m_Size = NetSheetTextSize;
NewSheetLabel->m_Shape = CurrentTypeLabel;
GetScreen()->SetCurItem( NewSheetLabel );
DrawPanel->ManageCurseur = Move_PinSheet;
DrawPanel->ForceCloseManageCurseur = ExitPinSheet;
DrawPanel->ManageCurseur( DrawPanel, DC, TRUE );
return NewSheetLabel;
}
/*****************************************************************************/
DrawSheetLabelStruct* WinEDA_SchematicFrame::Import_PinSheet( DrawSheetStruct* Sheet, wxDC* DC )
/*****************************************************************************/
/* Permet de creer automatiquement les Sheet Labels a partir des Labels Globaux
* de la feuille de sous hierarchie correspondante
*/
{
EDA_BaseStruct* DrawStruct;
DrawSheetLabelStruct* NewSheetLabel, * SheetLabel = NULL;
DrawGlobalLabelStruct* GLabel = NULL;
DrawStruct = Sheet->EEDrawList;
GLabel = NULL;
for( ; DrawStruct != NULL; DrawStruct = DrawStruct->Pnext )
{
if( DrawStruct->m_StructType != DRAW_GLOBAL_LABEL_STRUCT_TYPE )
continue;
GLabel = (DrawGlobalLabelStruct*) DrawStruct;
/* Ici un G-Label a ete trouve: y a t-il un SheetLabel correspondant */
SheetLabel = Sheet->m_Label;
for( ; SheetLabel != NULL; SheetLabel = (DrawSheetLabelStruct*) SheetLabel->Pnext )
{
if( SheetLabel->m_Text.CmpNoCase( GLabel->m_Text ) == 0 )
{
break;
}
}
/* Ici si SheetLabel == NULL le G-Label n'a pas de SheetLabel corresp */
if( SheetLabel == NULL )
break;
}
if( (GLabel == NULL ) || SheetLabel )
{
DisplayError( this, _( "No New Global Label found" ), 10 );
return NULL;
}
/* Ici G-Label n'a pas de SheetLabel corresp, on va le creer */
GetScreen()->SetModify();
/* Creation en memoire */
NewSheetLabel = new DrawSheetLabelStruct( Sheet, wxPoint( 0, 0 ), GLabel->m_Text );
NewSheetLabel->m_Flags = IS_NEW;
NewSheetLabel->m_Size = NetSheetTextSize;
CurrentTypeLabel = NewSheetLabel->m_Shape = GLabel->m_Shape;
GetScreen()->SetCurItem( NewSheetLabel );
DrawPanel->ManageCurseur = Move_PinSheet;
DrawPanel->ForceCloseManageCurseur = ExitPinSheet;
Move_PinSheet( DrawPanel, DC, FALSE );
return NewSheetLabel;
}
/**************************************************************/
void WinEDA_SchematicFrame::DeleteSheetLabel( wxDC* DC,
DrawSheetLabelStruct* SheetLabelToDel )
/**************************************************************/
/*
* Routine de suppression de 1 Structure type (DrawSheetLabelStruct.
* Cette Structure ne peut etre mise en pile "undelete" car il ne serait pas
* possible de la ratacher a la 'DrawSheetStruct' d'origine
* si DC != NULL, effacement a l'ecran du dessin
*/
{
EDA_BaseStruct* DrawStruct;
DrawSheetLabelStruct* SheetLabel, * NextLabel;
if( DC )
RedrawOneStruct( DrawPanel, DC, SheetLabelToDel, g_XorMode );
/* Recherche de la DrawSheetStruct d'origine */
DrawStruct = SheetLabelToDel->m_Parent;
if( DrawStruct ) // Modification du chainage
{
if( DrawStruct->m_StructType != DRAW_SHEET_STRUCT_TYPE )
{
DisplayError( this,
wxT( "DeleteSheetLabel error: m_Parent != DRAW_SHEET_STRUCT_TYPE" ) );
return;
}
/* suppression chainage */
SheetLabel = ( (DrawSheetStruct*) DrawStruct )->m_Label;
if( SheetLabel == SheetLabelToDel )
( (DrawSheetStruct*) DrawStruct )->m_Label =
(DrawSheetLabelStruct*) SheetLabel->Pnext;
else
while( SheetLabel ) /* Examen de la liste dependante et suppression chainage */
{
NextLabel = (DrawSheetLabelStruct*) SheetLabel->Pnext;
if( NextLabel == SheetLabelToDel )
{
SheetLabel->Pnext = NextLabel->Pnext;
break;;
}
SheetLabel = NextLabel;
}
}
delete SheetLabelToDel;
}