/****************************/ /* EESchema - libedit.cpp */ /****************************/ /* Routines de maintenanace des librairies: * sauvegarde, modification de librairies. * creation edition suppression de composants */ #include "fctsys.h" #include "gr_basic.h" #include "common.h" #include "class_drawpanel.h" #include "confirm.h" #include "gestfich.h" #include "program.h" #include "libcmp.h" #include "general.h" #include "protos.h" #include "id.h" #include "dialog_create_component.h" /**********************************************/ void WinEDA_LibeditFrame::DisplayLibInfos() /**********************************************/ /* Affiche dans la zone messages la librairie , et le composant edite */ { wxString msg = wxT( "Libedit: " ); msg += CurrentLib ? CurrentLib->m_FullFileName : wxT( "No Lib" ); SetTitle( msg ); msg = _( " Part: " ); if( CurrentLibEntry == NULL ) { msg += _( "None" ); } else { msg += CurrentLibEntry->m_Name.m_Text; if( !CurrentAliasName.IsEmpty() ) msg << wxT( " Alias " ) << CurrentAliasName; } static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" ); msg << wxT( " Unit " ) << UnitLetter[CurrentUnit]; if( CurrentConvert > 1 ) msg += _( " Convert" ); else msg += _( " Normal" ); if( CurrentLibEntry && (CurrentLibEntry->m_Options == ENTRY_POWER) ) msg += _( " (Power Symbol)" ); SetStatusText( msg, 0 ); } /**************************************************/ void WinEDA_LibeditFrame::SelectActiveLibrary() /**************************************************/ /* Function to select the current library (working library) */ { LibraryStruct* Lib; Lib = SelectLibraryFromList( this ); if( Lib ) { CurrentLib = Lib; } DisplayLibInfos(); } bool WinEDA_LibeditFrame::LoadOneLibraryPart() /** * Function LoadOneLibraryPart() * load a library component from the current selected library * Prompt user for component name * If there is no current selected library, * prompt user for library name and make the selected library the current lib. */ { int i; wxString msg; wxString CmpName; EDA_LibComponentStruct* LibEntry = NULL; if( g_ScreenLib->IsModify() ) { if( !IsOK( this, _( "Current Part not saved.\nContinue?" ) ) ) return FALSE; } if( CurrentLib == NULL ) // No current lib, ask user for the library to use { SelectActiveLibrary(); if( CurrentLib == NULL ) return FALSE; } i = GetNameOfPartToLoad( this, CurrentLib, CmpName ); if( i == 0 ) return FALSE; g_ScreenLib->ClrModify(); CurrentDrawItem = NULL; // Delete previous library component, if any if( CurrentLibEntry ) { SAFE_DELETE( CurrentLibEntry ); } /* Load the new library component */ LibEntry = FindLibPart( CmpName.GetData(), CurrentLib->m_Name, FIND_ALIAS ); if( LibEntry == NULL ) { msg = _( "Component \"" ); msg << CmpName << _( "\" not found." ); DisplayError( this, msg, 20 ); return FALSE; } LoadOneLibraryPartAux( LibEntry, CurrentLib ); ReCreateHToolbar(); Zoom_Automatique( FALSE ); DrawPanel->Refresh(); return TRUE; } /**************************************************************************/ int WinEDA_LibeditFrame::LoadOneLibraryPartAux( EDA_LibComponentStruct* LibEntry, LibraryStruct* Library, int noMsg ) /**************************************************************************/ /* Routine Pour Charger en memoire la copie de 1 libpart. * retourne * 0 si OK * 1 si err * CurrentLibEntry pointe la copie ainsi creee */ { wxString msg; const wxChar* CmpName, * RootName = NULL; if( (LibEntry == NULL) || (Library == NULL) ) return 1; CmpName = LibEntry->m_Name.m_Text.GetData(); CurrentAliasName.Empty(); if( LibEntry->Type != ROOT ) { RootName = ( (EDA_LibCmpAliasStruct*) LibEntry )->m_RootName.GetData(); if( !noMsg ) { msg.Printf( wxT( "\"<%s>\" is Alias of \"<%s>\"" ), CmpName, RootName ); } LibEntry = FindLibPart( RootName, Library->m_Name, FIND_ROOT ); if( LibEntry == NULL ) { msg.Printf( wxT( "Root Part \"<%s>\" not found." ), RootName ); DisplayError( this, msg, 20 ); return 1; } CurrentAliasName = CmpName; } if( CurrentLibEntry ) { SAFE_DELETE( CurrentLibEntry ); } CurrentLibEntry = CopyLibEntryStruct( this, LibEntry ); CurrentUnit = 1; CurrentConvert = 1; DisplayLibInfos(); BuildAliasData( Library, CurrentLibEntry ); g_ScreenLib->ClrModify(); g_AsDeMorgan = 0; if( LookForConvertPart( CurrentLibEntry ) > 1 ) g_AsDeMorgan = 1; return 0; } /*********************************************************************/ void WinEDA_LibeditFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg ) /*********************************************************************/ /* Function to redraw the current loaded library component */ { if( GetScreen() == NULL ) return; ActiveScreen = GetScreen(); DC->SetBackground( *wxBLACK_BRUSH ); DC->SetBackgroundMode( wxTRANSPARENT ); GRResetPenAndBrush( DC ); DrawPanel->CursorOff( DC ); // erase cursor if( DrawPanel->ManageCurseur ) { DrawPanel->ManageCurseur( DrawPanel, DC, FALSE ); // effacement affichage lie au curseur } if( EraseBg ) DrawPanel->EraseScreen( DC ); DrawPanel->DrawBackGround( DC ); if( CurrentLibEntry ) DrawLibEntry( DrawPanel, DC, CurrentLibEntry, wxPoint( 0, 0 ), CurrentUnit, CurrentConvert, GR_DEFAULT_DRAWMODE ); DrawPanel->CursorOn( DC ); // redraw cursor if( DrawPanel->ManageCurseur ) { DrawPanel->ManageCurseur( DrawPanel, DC, FALSE ); } GetScreen()->ClrRefreshReq(); DisplayLibInfos(); UpdateStatusBar(); } /*************************************************/ void WinEDA_LibeditFrame::SaveActiveLibrary() /*************************************************/ /* Save (on disk) the current library * if exists the old file is renamed (.bak) */ { wxFileName fn; wxString msg; if( CurrentLib == NULL ) { DisplayError( this, wxT( "No Library specified" ) ); return; } fn = wxFileName( CurrentLib->m_FullFileName ); msg = _( "Modify Library File \"" ) + fn.GetFullPath() + _( "\"?" ); if( !IsOK( this, msg ) ) return; bool success = CurrentLib->SaveLibrary( fn.GetFullPath() ); MsgPanel->EraseMsgBox(); if( !success ) { msg = _( "Error while saving Library File \"" ) + fn.GetFullPath() + _( "\"." ); Affiche_1_Parametre( this, 1, wxT( " *** ERROR : **" ), msg, BLUE ); DisplayError( this, msg ); } else { msg = _( "Library File \"" ) + fn.GetFullName() + wxT( "\" Ok" ); fn.SetExt( DOC_EXT ); wxString msg1 = _( "Document File \"" ) + fn.GetFullPath() + wxT( "\" Ok" ); Affiche_1_Parametre( this, 1, msg, msg1, BLUE ); } } /**************************************************************/ void WinEDA_LibeditFrame::DisplayCmpDoc( const wxString& Name ) /**************************************************************/ /* * Affiche la documentation du composant selectionne * Utilis�e lors de l'affichage de la liste des composants en librairie */ { LibCmpEntry* CmpEntry; if( CurrentLib == NULL ) return; MsgPanel->EraseMsgBox(); CmpEntry = FindLibPart( Name.GetData(), CurrentLib->m_Name, FIND_ALIAS ); if( CmpEntry == NULL ) return; AfficheDoc( this, CmpEntry->m_Doc, CmpEntry->m_KeyWord ); } /*********************************************/ void WinEDA_LibeditFrame::DeleteOnePart() /*********************************************/ /* Routine de suppression d'un composant dans la librairie courante * (effacement en memoire uniquement, le fichier n'est pas modifie) * Le composant peut etre un alias, ou la definition de base. * Si c'est un alias: * il est supprime, et la liste des alias de la definition * de base est modifiee * Si c'est le composant de base: * Si la liste des alias est nulle, il est supprime * Sinon le premier alias devient le composant de base, et les autres * alias deviennent dependants de celui ci. */ { wxString CmpName; int NumOfParts; EDA_LibComponentStruct* LibEntry; WinEDAListBox* ListBox; const wxChar** ListNames; wxString msg; CurrentDrawItem = NULL; if( CurrentLib == NULL ) { SelectActiveLibrary(); if( CurrentLib == NULL ) { DisplayError( this, _( "No Active Library" ), 20 ); return; } } NumOfParts = 0; PQCompFunc( (PQCompFuncType) LibraryEntryCompare ); LibEntry = (EDA_LibComponentStruct*) PQFirst( &CurrentLib->m_Entries, FALSE ); while( LibEntry != NULL ) { NumOfParts++; LibEntry = (EDA_LibComponentStruct*) PQNext( CurrentLib->m_Entries, LibEntry, NULL ); } ListNames = (const wxChar**) MyZMalloc( (NumOfParts + 1) * sizeof(wxChar*) ); LibEntry = (EDA_LibComponentStruct*) PQFirst( &CurrentLib->m_Entries, FALSE ); msg.Printf( _( "Select Component (%d items)" ), NumOfParts ); NumOfParts = 0; while( LibEntry != NULL ) { ListNames[NumOfParts] = LibEntry->m_Name.m_Text.GetData(); NumOfParts++; LibEntry = (EDA_LibComponentStruct*) PQNext( CurrentLib->m_Entries, LibEntry, NULL ); } ListBox = new WinEDAListBox( this, msg, ListNames, wxEmptyString, NULL, wxColour( 255, 255, 255 ) ); int ii = ListBox->ShowModal(); ListBox->Destroy(); if( ii >= 0 ) { CmpName = ListNames[ii]; LibEntry = FindLibPart( CmpName.GetData(), CurrentLib->m_Name, FIND_ALIAS ); if( LibEntry == NULL ) DisplayError( this, _( "Component not found" ), 20 ); else { msg = _( "Delete component \"" ) + LibEntry->m_Name.m_Text + _( "\" from library \"" ) + CurrentLib->m_Name + wxT( "\"?" ); if( IsOK( this, msg ) ) { DeletePartInLib( CurrentLib, LibEntry ); } } } free( ListNames ); } /****************************************************/ void WinEDA_LibeditFrame::CreateNewLibraryPart() /****************************************************/ /* Routine to create a new library component * If an old component is currently in edit, it is deleted. */ { wxString msg; EDA_LibComponentStruct* NewStruct; int diag; if( CurrentLibEntry && !IsOK( this, _( "Clear old component from screen (changes will be lost)?" ) ) ) return; CurrentDrawItem = NULL; WinEDA_CreateCmpDialog Dialogbox( this ); diag = Dialogbox.ShowModal(); if( diag != wxID_OK ) return; msg = Dialogbox.ReturnCmpName(); if( msg.IsEmpty() ) return; msg.MakeUpper(); msg.Replace( wxT( " " ), wxT( "_" ) ); /* Test: y a t-il un composant deja de ce nom */ if( CurrentLib ) { if( FindLibPart( msg.GetData(), CurrentLib->m_Name, FIND_ALIAS ) ) { wxString msg; msg << _( "Component \"" ) << Dialogbox.ReturnCmpName() << _( "\" exists in library \"" ) << CurrentLib->m_Name << _( "\"." ); DisplayError( this, msg ); return; } } NewStruct = new EDA_LibComponentStruct( msg ); Dialogbox.SetComponentData( *NewStruct ); if( NewStruct->m_Prefix.m_Text.IsEmpty() ) NewStruct->m_Prefix.m_Text = wxT( "U" ); NewStruct->m_Prefix.m_Text.MakeUpper(); // Effacement ancien composant affich� if( CurrentLibEntry ) { SAFE_DELETE( CurrentLibEntry ); } CurrentLibEntry = NewStruct; CurrentUnit = 1; CurrentConvert = 1; ReCreateHToolbar(); DisplayLibInfos(); } /*******************************************************************/ void WinEDA_LibeditFrame::DeletePartInLib( LibraryStruct* Library, EDA_LibComponentStruct* Entry ) /*******************************************************************/ /* Suppression du composant Entry en librairie Library. * (effacement en memoire uniquement, le fichier n'est pas modifie) * Le composant peut etre un alias, ou la definition de base. * Si c'est un alias: * il est supprime, et la liste des alias de la definition * de base est modifiee * Si c'est le composant de base: * Si la liste des alias est nulle, il est supprime * Sinon le premier alias devient le composant de base, et les autres * alias deviennent dependants de celui ci. */ { EDA_LibComponentStruct* RootEntry; EDA_LibCmpAliasStruct* AliasEntry; if( ( Library == NULL ) || ( Entry == NULL ) ) return; PQCompFunc( (PQCompFuncType) LibraryEntryCompare ); Library->m_Modified = 1; if( Entry->Type == ALIAS ) { RootEntry = FindLibPart( ( (EDA_LibCmpAliasStruct*) Entry )->m_RootName.GetData(), Library->m_Name, FIND_ROOT ); /* Remove alias name from the root component alias list */ if( RootEntry == NULL ) { DisplayError( this, wxT( "Warning: for Alias, root not found" ), 30 ); } else { int index = wxNOT_FOUND; if( RootEntry->m_AliasList.GetCount() != 0 ) { index = RootEntry->m_AliasList.Index( Entry->m_Name.m_Text.GetData(), FALSE ); if( index != wxNOT_FOUND ) RootEntry->m_AliasList.RemoveAt( index ); } if( index == wxNOT_FOUND ) DisplayError( this, wxT( "Warning: Root for Alias as no alias list" ), 30 ); } /* Effacement memoire pour cet alias */ PQDelete( &Library->m_Entries, (void*) Entry ); SAFE_DELETE( Entry ); if( Library->m_NumOfParts > 0 ) CurrentLib->m_NumOfParts--; return; } /* Entry is a standard component (not an alias) */ if( Entry->m_AliasList.GetCount() == 0 ) // Trivial case: no alias, we can safety delete e=this entry { PQDelete( &Library->m_Entries, Entry ); SAFE_DELETE( Entry ); if( Library->m_NumOfParts > 0 ) Library->m_NumOfParts--; return; } /* Entry is a component with alias * We must change the first alias to a "root" component, and for all the aliases * we must change the root component (which is deleted) by the first alias */ wxString AliasName = Entry->m_AliasList[0]; /* The root component is not really deleted, it is renamed with the first alias name */ AliasEntry = (EDA_LibCmpAliasStruct*) FindLibPart( AliasName.GetData(), Library->m_Name, FIND_ALIAS ); if( AliasEntry == NULL ) { wxString msg; msg.Printf( wxT( "Warning: Alias <%s> not found" ), AliasName.GetData() ); DisplayError( this, msg, 30 ); } else { if( Library->m_NumOfParts > 0 ) Library->m_NumOfParts--; /* remove the root component from library */ PQDelete( &Library->m_Entries, Entry ); /* remove the first alias from library*/ PQDelete( &Library->m_Entries, AliasEntry ); /* remove the first alias name from alias list: */ Entry->m_AliasList.RemoveAt( 0 ); /* change the old name. New name for "root" is the name of the first alias */ Entry->m_Name.m_Text = AliasName; Entry->m_Doc = AliasEntry->m_Doc; Entry->m_KeyWord = AliasEntry->m_KeyWord; FreeLibraryEntry( (EDA_LibComponentStruct*) AliasEntry ); /* root component (renamed) placed in library */ PQInsert( &Library->m_Entries, Entry ); } /* Change the "RootName", for other aliases */ for( unsigned ii = 0; ii < Entry->m_AliasList.GetCount(); ii++ ) { AliasName = Entry->m_AliasList[ii]; AliasEntry = (EDA_LibCmpAliasStruct*) FindLibPart( AliasName.GetData(), Library->m_Name, FIND_ALIAS ); if( AliasEntry == NULL ) { // Should not occurs. If happens, this is an error (or bug) wxString msg; msg.Printf( wxT( "Warning: Alias <%s> not found" ), AliasName.GetData() ); DisplayError( this, msg, 30 ); continue; } if( AliasEntry->Type != ALIAS ) { // Should not occurs. If happens, this is an error (or bug) wxString msg; msg.Printf( wxT( "Warning: <%s> is not an Alias" ), AliasName.GetData() ); DisplayError( this, msg, 30 ); continue; } AliasEntry->m_RootName = Entry->m_Name.m_Text; } } /***************************************************/ void WinEDA_LibeditFrame::SaveOnePartInMemory() /***************************************************/ /* Routine de sauvegarde de la "partlib" courante dans la librairie courante * Sauvegarde en memoire uniquement, et PAS sur fichier * La routine efface l'ancien composant ( ou / et les alias ) a remplacer * s'il existe, et sauve le nouveau et cree les alias correspondants. */ { EDA_LibComponentStruct* Entry; EDA_LibCmpAliasStruct* AliasEntry; wxString msg; bool NewCmp = TRUE; if( CurrentLibEntry == NULL ) { DisplayError( this, _( "No component to Save." ) ); return; } if( CurrentLib == NULL ) SelectActiveLibrary(); if( CurrentLib == NULL ) { DisplayError( this, _( "No Library specified." ), 20 ); return; } CurrentLib->m_Modified = 1; g_ScreenLib->ClrModify(); PQCompFunc( (PQCompFuncType) LibraryEntryCompare ); if( ( Entry = FindLibPart( CurrentLibEntry->m_Name.m_Text.GetData(), CurrentLib->m_Name, FIND_ROOT ) ) != NULL ) { msg.Printf( _( "Component \"%s\" exists. Change it?" ), Entry->m_Name.m_Text.GetData() ); if( !IsOK( this, msg ) ) return; NewCmp = FALSE; } /* Effacement des alias deja existants en librairie */ for( unsigned ii = 0; ii < CurrentLibEntry->m_AliasList.GetCount(); ii += ALIAS_NEXT ) { EDA_LibComponentStruct* LocalEntry; wxString aliasname = CurrentLibEntry->m_AliasList[ii + ALIAS_NAME]; while( ( LocalEntry = FindLibPart( aliasname.GetData(), CurrentLib->m_Name, FIND_ALIAS ) ) != NULL ) { DeletePartInLib( CurrentLib, LocalEntry ); } } if( !NewCmp ) DeletePartInLib( CurrentLib, Entry ); Entry = CopyLibEntryStruct( this, CurrentLibEntry ); Entry->m_AliasList.Clear(); PQInsert( &CurrentLib->m_Entries, (void*) Entry ); CurrentLib->m_NumOfParts++; /* Creation des nouveaux alias */ for( unsigned ii = 0; ii < CurrentLibEntry->m_AliasList.GetCount(); ii += ALIAS_NEXT ) { wxString aliasname = CurrentLibEntry->m_AliasList[ii + ALIAS_NAME]; Entry->m_AliasList.Add( aliasname ); AliasEntry = new EDA_LibCmpAliasStruct( aliasname.GetData(), Entry->m_Name.m_Text ); AliasEntry->m_Doc = CurrentLibEntry->m_AliasList[ii + ALIAS_DOC]; AliasEntry->m_KeyWord = CurrentLibEntry->m_AliasList[ii + ALIAS_KEYWORD]; AliasEntry->m_DocFile = CurrentLibEntry->m_AliasList[ii + ALIAS_DOC_FILENAME]; /* Placement en liste des composants de l'Alias */ PQInsert( &CurrentLib->m_Entries, (void*) AliasEntry ); CurrentLib->m_NumOfParts++; } msg.Printf( _( "Component %s saved in %s" ), Entry->m_Name.m_Text.GetData(), CurrentLib->m_Name.GetData() ); Affiche_Message( msg ); }