kicad/eeschema/sheetlab.cpp

446 lines
13 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()->m_CurrentItem;
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()->m_CurrentItem = 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()->m_CurrentItem;
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()->m_CurrentItem = 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()->m_CurrentItem = 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;
}