/********************************/ /* Scehematic component edition */ /********************************/ #include "fctsys.h" #include "gr_basic.h" #include "common.h" #include "program.h" #include "libcmp.h" #include "general.h" #include "wx/checklst.h" #include "protos.h" /* Fonctions locales */ static void AbortMoveCmpField( WinEDA_DrawPanel* Panel, wxDC* DC ); static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ); /************************************************************************************/ void WinEDA_SchematicFrame::StartMoveCmpField( SCH_CMP_FIELD* aField, wxDC* DC ) /************************************************************************************/ /* Prepare le deplacement du texte en cours d'edition */ { EDA_LibComponentStruct* Entry; SetCurrentField( aField ); if( aField == NULL ) return; if( aField->m_Text == wxEmptyString ) { DisplayError( this, _( "No Field to move" ), 10 ); return; } wxPoint pos, newpos; int x1, y1; SCH_COMPONENT* comp = (SCH_COMPONENT*) aField->GetParent(); SAFE_DELETE( g_ItemToUndoCopy ); g_ItemToUndoCopy = comp->GenCopy(); pos = comp->m_Pos; /* Les positions sont calculees par la matrice TRANSPOSEE de la matrice * de rotation-miroir */ x1 = aField->m_Pos.x - pos.x; y1 = aField->m_Pos.y - pos.y; // Empirically this is necessary. The Y coordinate appears to be inverted // under some circumstances, but that inversion is not preserved by all // combinations of mirroring and rotation. The following clause is true // when the number of rotations and the number of mirrorings are both odd. if( comp->m_Transform[1][0] * comp->m_Transform[0][1] < 0 ) { y1 = -y1; } newpos.x = pos.x + comp->m_Transform[0][0] * x1 + comp->m_Transform[1][0] * y1; newpos.y = pos.y + comp->m_Transform[0][1] * x1 + comp->m_Transform[1][1] * y1; DrawPanel->CursorOff( DC ); GetScreen()->m_Curseur = newpos; DrawPanel->MouseToCursorSchema(); m_OldPos = aField->m_Pos; m_Multiflag = 0; if( aField->m_FieldId == REFERENCE ) { Entry = FindLibPart( comp->m_ChipName.GetData(), wxEmptyString, FIND_ROOT ); if( Entry != NULL ) { if( Entry->m_UnitCount > 1 ) m_Multiflag = 1; } } DrawPanel->ForceCloseManageCurseur = AbortMoveCmpField; DrawPanel->ManageCurseur = MoveCmpField; aField->m_Flags = IS_MOVED; DrawPanel->CursorOn( DC ); } /**********************************************************************************/ void WinEDA_SchematicFrame::EditCmpFieldText( SCH_CMP_FIELD* Field, wxDC* DC ) /**********************************************************************************/ /* Edit the field Field (text, size) */ { int fieldNdx, flag; EDA_LibComponentStruct* Entry; if( Field == NULL ) { DisplayError( this, _( "No Field To Edit" ), 10 ); return; } SCH_COMPONENT* Cmp = (SCH_COMPONENT*) Field->GetParent(); fieldNdx = Field->m_FieldId; if( fieldNdx == VALUE ) { Entry = FindLibPart( Cmp->m_ChipName.GetData(), wxEmptyString, FIND_ROOT ); if( Entry && (Entry->m_Options == ENTRY_POWER) ) { DisplayInfo( this, _( "Part is a POWER, value cannot be modified!\nYou must create a new power" ) ); return; } } flag = 0; if( fieldNdx == REFERENCE ) { Entry = FindLibPart( Cmp->m_ChipName.GetData(), wxEmptyString, FIND_ROOT ); if( Entry != NULL ) { if( Entry->m_UnitCount > 1 ) flag = 1; } } /* save old cmp in undo list if not already in edit, or moving ... */ if( Field->m_Flags == 0 ) SaveCopyInUndoList( Cmp, IS_CHANGED ); wxString newtext = Field->m_Text; DrawPanel->m_IgnoreMouseEvents = TRUE; Get_Message( Field->m_Name, _("Component field text"), newtext, this ); DrawPanel->MouseToCursorSchema(); DrawPanel->m_IgnoreMouseEvents = FALSE; Field->m_AddExtraText = flag; Field->Draw( DrawPanel, DC, wxPoint(0,0), g_XorMode ); if( !newtext.IsEmpty() ) { if( Field->m_Text.IsEmpty() ) { Field->m_Pos = Cmp->m_Pos; Field->m_Size.x = Field->m_Size.y = m_TextFieldSize; } Field->m_Text = newtext; if( fieldNdx == REFERENCE ){ Cmp->SetRef(GetSheet(), newtext); } } else /* Nouveau texte NULL */ { if( fieldNdx == REFERENCE ) { DisplayError( this, _( "Reference needed !, No change" ) ); } else if( fieldNdx == VALUE ) { DisplayError( this, _( "Value needed !, No change" ) ); } else { Field->m_Text = wxT( "~" ); } } Field->Draw( DrawPanel, DC, wxPoint(0,0), g_XorMode ); Cmp->Display_Infos( this ); GetScreen()->SetModify(); } /************************************************************************/ static void MoveCmpField( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) /************************************************************************/ /* Routine de deplacement d'un texte type Field. * Celle routine est normalement attachee au deplacement du curseur */ { wxPoint pos; int x1, y1; int fieldNdx; WinEDA_SchematicFrame* frame = (WinEDA_SchematicFrame*) panel->GetParent(); SCH_CMP_FIELD* currentField = frame->GetCurrentField(); if( currentField == NULL ) return; SCH_COMPONENT* component = (SCH_COMPONENT*) currentField->GetParent(); fieldNdx = currentField->m_FieldId; // Effacement: currentField->m_AddExtraText = frame->m_Multiflag; if( erase ) { currentField->Draw( panel, DC, wxPoint(0,0), g_XorMode ); } pos = ( (SCH_COMPONENT*) currentField->GetParent() )->m_Pos; /* Les positions sont caculees par la matrice TRANSPOSEE de la matrice * de rotation-miroir */ x1 = panel->GetScreen()->m_Curseur.x - pos.x; y1 = panel->GetScreen()->m_Curseur.y - pos.y; currentField->m_Pos.x = pos.x + component->m_Transform[0][0] * x1 + component->m_Transform[1][0] * y1; currentField->m_Pos.y = pos.y + component->m_Transform[0][1] * x1 + component->m_Transform[1][1] * y1; currentField->Draw( panel, DC, wxPoint(0,0), g_XorMode ); } /******************************************************************/ static void AbortMoveCmpField( WinEDA_DrawPanel* Panel, wxDC* DC ) /******************************************************************/ { Panel->ForceCloseManageCurseur = NULL; Panel->ManageCurseur = NULL; WinEDA_SchematicFrame* frame = (WinEDA_SchematicFrame*) Panel->GetParent(); SCH_CMP_FIELD* currentField = frame->GetCurrentField(); if( currentField ) { currentField->m_AddExtraText = frame->m_Multiflag; currentField->Draw( Panel, DC, wxPoint(0,0), g_XorMode ); currentField->m_Flags = 0; currentField->m_Pos = frame->m_OldPos; currentField->Draw( Panel, DC, wxPoint(0,0), g_XorMode ); } frame->SetCurrentField( NULL ); SAFE_DELETE( g_ItemToUndoCopy ); } /*********************************************************************************/ void WinEDA_SchematicFrame::RotateCmpField( SCH_CMP_FIELD* Field, wxDC* DC ) /*********************************************************************************/ { int fieldNdx, flag; EDA_LibComponentStruct* Entry; if( Field == NULL ) return; if( Field->m_Text == wxEmptyString ) return; SCH_COMPONENT* Cmp = (SCH_COMPONENT*) Field->GetParent(); fieldNdx = Field->m_FieldId; flag = 0; if( fieldNdx == REFERENCE ) { Entry = FindLibPart( ( (SCH_COMPONENT*) Field->GetParent() )->m_ChipName.GetData(), wxEmptyString, FIND_ROOT ); if( Entry != NULL ) { if( Entry->m_UnitCount > 1 ) flag = 1; } } /* save old cmp in undo list if not already in edit, or moving ... */ if( Field->m_Flags == 0 ) SaveCopyInUndoList( Cmp, IS_CHANGED ); Field->m_AddExtraText = flag; Field->Draw( DrawPanel, DC, wxPoint(0,0), g_XorMode ); if( Field->m_Orient == TEXT_ORIENT_HORIZ ) Field->m_Orient = TEXT_ORIENT_VERT; else Field->m_Orient = TEXT_ORIENT_HORIZ; Field->Draw( DrawPanel, DC, wxPoint(0,0), g_XorMode ); GetScreen()->SetModify(); } /*********************************************************************/ void SCH_CMP_FIELD::Place( WinEDA_SchematicFrame* frame, wxDC* DC ) /*********************************************************************/ { int fieldNdx; EDA_LibComponentStruct* Entry; frame->DrawPanel->ManageCurseur = NULL; frame->DrawPanel->ForceCloseManageCurseur = NULL; SCH_COMPONENT* component = (SCH_COMPONENT*) GetParent(); // save old cmp in undo list if( g_ItemToUndoCopy && ( g_ItemToUndoCopy->Type() == component->Type()) ) { component->SwapData( (SCH_COMPONENT*) g_ItemToUndoCopy ); frame->SaveCopyInUndoList( component, IS_CHANGED ); component->SwapData( (SCH_COMPONENT*) g_ItemToUndoCopy ); } fieldNdx = m_FieldId; m_AddExtraText = 0; if( fieldNdx == REFERENCE ) { Entry = FindLibPart( component->m_ChipName.GetData(), wxEmptyString, FIND_ROOT ); if( Entry != NULL ) { if( Entry->m_UnitCount > 1 ) m_AddExtraText = 1; } } Draw( frame->DrawPanel, DC, wxPoint(0,0), GR_DEFAULT_DRAWMODE ); m_Flags = 0; frame->GetScreen()->SetCurItem( NULL ); frame->GetScreen()->SetModify(); frame->SetCurrentField( NULL ); } /**************************************************************************************************/ void WinEDA_SchematicFrame::EditComponentReference( SCH_COMPONENT* Cmp, wxDC* DC ) /**************************************************************************************************/ /* Edit the component text reference*/ { EDA_LibComponentStruct* Entry; int flag = 0; if( Cmp == NULL ) return; Entry = FindLibPart( Cmp->m_ChipName.GetData(), wxEmptyString, FIND_ROOT ); if( Entry == NULL ) return; if( Entry->m_UnitCount > 1 ) flag = 1; wxString ref = Cmp->GetRef(GetSheet()); Get_Message( _( "Reference" ), _("Component reference"), ref, this ); if( !ref.IsEmpty() ) // New text entered { /* save old cmp in undo list if not already in edit, or moving ... */ if( Cmp->m_Flags == 0 ) SaveCopyInUndoList( Cmp, IS_CHANGED ); Cmp->SetRef(GetSheet(), ref); Cmp->GetField( REFERENCE )->m_AddExtraText = flag; Cmp->GetField( REFERENCE )->Draw( DrawPanel, DC, wxPoint(0,0), g_XorMode ); Cmp->SetRef(GetSheet(), ref ); Cmp->GetField( REFERENCE )->Draw( DrawPanel, DC, wxPoint(0,0), Cmp->m_Flags ? g_XorMode : GR_DEFAULT_DRAWMODE ); GetScreen()->SetModify(); } Cmp->Display_Infos( this ); } /*****************************************************************************************/ void WinEDA_SchematicFrame::EditComponentValue( SCH_COMPONENT* Cmp, wxDC* DC ) /*****************************************************************************************/ /* Routine de changement du texte selectionne */ { wxString message; EDA_LibComponentStruct* Entry; if( Cmp == NULL ) return; Entry = FindLibPart( Cmp->m_ChipName.GetData(), wxEmptyString, FIND_ROOT ); if( Entry == NULL ) return; SCH_CMP_FIELD* TextField = Cmp->GetField( VALUE ); message = TextField->m_Text; if( Get_Message( _( "Value" ), _("Component value"), message, this ) ) message.Empty(); //allow the user to remove the value. if( !message.IsEmpty() && !message.IsEmpty()) { /* save old cmp in undo list if not already in edit, or moving ... */ if( Cmp->m_Flags == 0 ) SaveCopyInUndoList( Cmp, IS_CHANGED ); TextField->Draw( DrawPanel, DC, wxPoint(0,0), g_XorMode ); TextField->m_Text = message; TextField->Draw( DrawPanel, DC, wxPoint(0,0), Cmp->m_Flags ? g_XorMode : GR_DEFAULT_DRAWMODE ); GetScreen()->SetModify(); } Cmp->Display_Infos( this ); } /*****************************************************************************************/ void WinEDA_SchematicFrame::EditComponentFootprint( SCH_COMPONENT* Cmp, wxDC* DC ) /*****************************************************************************************/ { wxString message; EDA_LibComponentStruct* Entry; bool wasEmpty = false; if( Cmp == NULL ) return; Entry = FindLibPart( Cmp->m_ChipName.GetData(), wxEmptyString, FIND_ROOT ); if( Entry == NULL ) return; SCH_CMP_FIELD* TextField = Cmp->GetField( FOOTPRINT ); message = TextField->m_Text; if(message.IsEmpty() ) wasEmpty = true; if( Get_Message( _( "Footprint" ), _("Component footprint"), message, this ) ) message.Empty(); // allow the user to remove the value. // save old cmp in undo list if not already in edit, or moving ... if( Cmp->m_Flags == 0 ) SaveCopyInUndoList( Cmp, IS_CHANGED ); Cmp->GetField( FOOTPRINT )->Draw( DrawPanel, DC, wxPoint(0,0), g_XorMode ); // move the field if it was new. if( wasEmpty && !message.IsEmpty() ) { Cmp->GetField( FOOTPRINT )->m_Pos = Cmp->GetField( REFERENCE )->m_Pos; // add offset here - ? suitable heuristic below? Cmp->GetField( FOOTPRINT )->m_Pos.x += (Cmp->GetField( REFERENCE )->m_Pos.x - Cmp->m_Pos.x) > 0 ? (Cmp->GetField( REFERENCE )->m_Size.x) : (-1*Cmp->GetField( REFERENCE )->m_Size.x); Cmp->GetField( FOOTPRINT )->m_Pos.y += (Cmp->GetField( REFERENCE )->m_Pos.y - Cmp->m_Pos.y) > 0 ? (Cmp->GetField( REFERENCE )->m_Size.y) : (-1*Cmp->GetField( REFERENCE )->m_Size.y); Cmp->GetField( FOOTPRINT )->m_Orient = Cmp->GetField( REFERENCE )->m_Orient; } TextField->m_Text = message; Cmp->GetField( FOOTPRINT )->Draw( DrawPanel, DC, wxPoint(0,0), Cmp->m_Flags ? g_XorMode : GR_DEFAULT_DRAWMODE ); GetScreen()->SetModify(); Cmp->Display_Infos( this ); }