kicad/eeschema/find.cpp

494 lines
14 KiB
C++

/****************************************************************/
/* EESchema: find.cpp (functions for seraching a schematic item */
/****************************************************************/
/*
Search a text (text, value, reference) withing e composent or
search a composant in libraries, a marker ...,
in current sheet or whole the project
*/
#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
#include "program.h"
#include "libcmp.h"
#include "general.h"
/* Variables Locales */
static int s_ItemsCount, s_MarkerCount;
static wxString s_OldStringFound;
#include "dialog_find.cpp"
#include "protos.h"
/**************************************************************/
void InstallFindFrame(WinEDA_SchematicFrame *parent, wxPoint & pos)
/**************************************************************/
{
parent->DrawPanel->m_IgnoreMouseEvents = TRUE;
WinEDA_FindFrame * frame = new WinEDA_FindFrame(parent);
frame->ShowModal(); frame->Destroy();
parent->DrawPanel->m_IgnoreMouseEvents = FALSE;
}
/**************************************************************/
void WinEDA_FindFrame::FindMarker(wxCommandEvent& event)
/**************************************************************/
/* Search de markers in whole the hierarchy.
Mouse cursor is put on the marker
search the first marker, or next marker
*/
{
int id = event.GetId();
if( id != FIND_NEXT_MARKER ) m_Parent->FindMarker(0);
else m_Parent->FindMarker(1);
Close();
}
/*****************************************************************/
EDA_BaseStruct * WinEDA_SchematicFrame::FindMarker(int SearchType)
/*****************************************************************/
/* Search markers in whole the hierarchy.
Mouse cursor is put on the marker
SearchType = 0: search the first marker, else search next marker
*/
{
SCH_SCREEN * Screen, * FirstScreen = NULL;
EDA_BaseStruct *DrawList, *FirstStruct = NULL, *Struct = NULL;
DrawMarkerStruct * Marker = NULL;
int StartCount;
bool NotFound;
wxPoint firstpos, pos;
wxSize size = DrawPanel->GetClientSize();
wxPoint curpos, old_cursor_position;
bool force_recadre = FALSE;
wxString msg, WildText;
g_LastSearchIsMarker = TRUE;
/* Set s_MarkerCount to 0 if we are look for the first marker */
if( SearchType == 0 ) s_MarkerCount = 0;
EDA_ScreenList ScreenList(NULL);
NotFound = TRUE; StartCount = 0;
/* Search for s_MarkerCount markers */
for ( Screen = ScreenList.GetFirst(); Screen != NULL; Screen = ScreenList.GetNext() )
{
DrawList = Screen->EEDrawList;
while ( DrawList && NotFound )
{
if(DrawList->m_StructType == DRAW_MARKER_STRUCT_TYPE )
{
Marker = (DrawMarkerStruct *) DrawList;
NotFound = FALSE;
pos = Marker->m_Pos;
if ( FirstScreen == NULL ) /* First item found */
{
FirstScreen = Screen; firstpos = pos;
FirstStruct = DrawList;
}
StartCount++;
if( s_MarkerCount >= StartCount )
{
NotFound = TRUE; /* Search for other markers */
}
else /* We have found s_MarkerCount markers -> Ok */
{
Struct = DrawList; s_MarkerCount++; break ;
}
}
DrawList = DrawList->Pnext;
}
if( NotFound == FALSE ) break;
}
if( NotFound && FirstScreen ) // markers are found, but we have reach the last marker */
{ // After the last marker, the first marker is used */
NotFound = FALSE; Screen = FirstScreen;
Struct = FirstStruct;
pos = firstpos; s_MarkerCount = 1;
}
if( NotFound == FALSE)
{
if ( Screen != GetScreen() )
{
Screen->SetZoom(GetScreen()->GetZoom() );
m_CurrentScreen = ActiveScreen = Screen;
force_recadre = TRUE;
}
old_cursor_position = Screen->m_Curseur;
Screen->m_Curseur = pos;
curpos = DrawPanel->CursorScreenPosition();
// calcul des coord curseur avec origine = screen
DrawPanel->GetViewStart(&m_CurrentScreen->m_StartVisu.x,
&m_CurrentScreen->m_StartVisu.y);
curpos.x -= m_CurrentScreen->m_StartVisu.x;
curpos.y -= m_CurrentScreen->m_StartVisu.y;
/* Il y a peut-etre necessite de recadrer le dessin: */
if( (curpos.x <= 0) || (curpos.x >= size.x-1) ||
(curpos.y <= 0) || (curpos.y >= size.y) || force_recadre )
{
Recadre_Trace(TRUE);
}
else
{
wxClientDC dc(DrawPanel);
DrawPanel->PrepareGraphicContext(&dc);
EXCHG(old_cursor_position, Screen->m_Curseur);
DrawPanel->CursorOff(&dc);
GRMouseWarp(DrawPanel, curpos );
EXCHG(old_cursor_position, Screen->m_Curseur);
DrawPanel->CursorOn(&dc);
}
msg.Printf( _("Marker %d found in %s"), s_MarkerCount, Screen->m_FileName.GetData());
Affiche_Message(msg);
}
else
{
Affiche_Message(wxEmptyString);
msg = _("Marker Not Found");
DisplayError(this,msg, 10);
}
return Marker;
}
/**************************************************************/
void WinEDA_FindFrame::FindSchematicItem(wxCommandEvent& event)
/**************************************************************/
/* Find a string in schematic.
Call to WinEDA_SchematicFrame::FindSchematicItem()
*/
{
int id = event.GetId();
if( id == FIND_SHEET )
m_Parent->FindSchematicItem(m_NewTextCtrl->GetValue(), 0);
else if( id == FIND_HIERARCHY )
m_Parent->FindSchematicItem(m_NewTextCtrl->GetValue(), 1);
else if( id == FIND_NEXT )
m_Parent->FindSchematicItem(wxEmptyString, 2);
Close();
}
/************************************************************************/
EDA_BaseStruct * WinEDA_SchematicFrame::FindSchematicItem(
const wxString & pattern, int SearchType)
/************************************************************************/
/* Find a string in schematic.
Search is made in current sheet (SearchType = 0),
or the whole hierarchy (SearchType = 1),
or for the next item (SearchType = 2).
Mouse cursor is put on item
*/
{
SCH_SCREEN * Screen, * FirstScreen = NULL;
EDA_BaseStruct *DrawList = NULL, *FirstStruct = NULL, *Struct = NULL;
int StartCount, ii, jj;
bool NotFound;
wxPoint firstpos, pos, old_cursor_position;
static int Find_in_hierarchy;
wxSize size = DrawPanel->GetClientSize();
wxPoint curpos;
bool force_recadre = FALSE;
wxString msg, WildText;
g_LastSearchIsMarker = FALSE;
if( SearchType == 0 )
{
s_OldStringFound = pattern;
Find_in_hierarchy = FALSE;
}
if( SearchType == 1 )
{
s_OldStringFound = pattern;
Find_in_hierarchy = TRUE;
}
if( SearchType != 2 ) s_ItemsCount = 0;
WildText = s_OldStringFound;
NotFound = TRUE; StartCount = 0;
EDA_ScreenList ScreenList(NULL);
Screen = ScreenList.GetFirst();
if ( ! Find_in_hierarchy ) Screen = (SCH_SCREEN*) m_CurrentScreen;
for ( ; Screen != NULL; Screen = ScreenList.GetNext() )
{
DrawList = Screen->EEDrawList;
while ( DrawList )
{
switch (DrawList->m_StructType)
{
case DRAW_LIB_ITEM_STRUCT_TYPE :
#undef STRUCT
#define STRUCT ((EDA_SchComponentStruct*)DrawList)
if( WildCompareString( WildText, STRUCT->m_Field[REFERENCE].m_Text, FALSE ) )
{
NotFound = FALSE;
pos = STRUCT->m_Field[REFERENCE].m_Pos;
break;
}
if( WildCompareString( WildText, STRUCT->m_Field[VALUE].m_Text, FALSE ) )
{
NotFound = FALSE;
pos = STRUCT->m_Field[VALUE].m_Pos;
}
break;
case DRAW_LABEL_STRUCT_TYPE :
case DRAW_GLOBAL_LABEL_STRUCT_TYPE :
case DRAW_TEXT_STRUCT_TYPE :
#undef STRUCT
#define STRUCT ((DrawTextStruct*)DrawList)
if( WildCompareString( WildText, STRUCT->m_Text, FALSE ) )
{
NotFound = FALSE;
pos = STRUCT->m_Pos;
}
break;
default:
break;
}
if(NotFound == FALSE) /* Element trouve */
{
if ( FirstScreen == NULL ) /* 1er element trouve */
{
FirstScreen = Screen; firstpos = pos;
FirstStruct = DrawList;
}
StartCount++;
if( s_ItemsCount >= StartCount )
{
NotFound = TRUE; /* Continue recherche de l'element suivant */
}
else
{
Struct = DrawList; s_ItemsCount++; break ;
}
}
if( NotFound == FALSE ) break;
DrawList = DrawList->Pnext;
}
if( NotFound == FALSE ) break;
if( Find_in_hierarchy == FALSE ) break;
}
if( NotFound && FirstScreen )
{
NotFound = FALSE; Screen = FirstScreen; Struct = FirstStruct;
pos = firstpos; s_ItemsCount = 1;
}
if( NotFound == FALSE)
{
if ( Screen != GetScreen() )
{
Screen->SetZoom(GetScreen()->GetZoom() );
m_CurrentScreen = ActiveScreen = Screen;
force_recadre = TRUE;
}
/* Si la struct localisee est du type DRAW_LIB_ITEM_STRUCT_TYPE,
Les coordonnes sont a recalculer en fonction de la matrice
d'orientation */
if( Struct->m_StructType == DRAW_LIB_ITEM_STRUCT_TYPE )
{
#undef STRUCT
#define STRUCT ((EDA_SchComponentStruct*)Struct)
pos.x -= STRUCT->m_Pos.x; pos.y -= STRUCT->m_Pos.y;
ii = STRUCT->m_Transform[0][0] * pos.x + STRUCT->m_Transform[0][1] * pos.y;
jj = STRUCT->m_Transform[1][0] * pos.x + STRUCT->m_Transform[1][1] * pos.y;
pos.x = ii + STRUCT->m_Pos.x; pos.y = jj + STRUCT->m_Pos.y;
}
old_cursor_position = Screen->m_Curseur;
Screen->m_Curseur = pos;
curpos = DrawPanel->CursorScreenPosition();
DrawPanel->GetViewStart(&m_CurrentScreen->m_StartVisu.x,
&m_CurrentScreen->m_StartVisu.y);
// calcul des coord curseur avec origine = screen
curpos.x -= m_CurrentScreen->m_StartVisu.x;
curpos.y -= m_CurrentScreen->m_StartVisu.y;
/* Il y a peut-etre necessite de recadrer le dessin: */
if( (curpos.x <= 0) || (curpos.x >= size.x-1) ||
(curpos.y <= 0) || (curpos.y >= size.y) || force_recadre )
{
Recadre_Trace(TRUE);
}
else
{
wxClientDC dc(DrawPanel);
DrawPanel->PrepareGraphicContext(&dc);
EXCHG(old_cursor_position, Screen->m_Curseur);
DrawPanel->CursorOff(&dc);
GRMouseWarp(DrawPanel, curpos );
EXCHG(old_cursor_position, Screen->m_Curseur);
DrawPanel->CursorOn(&dc);
}
msg = WildText + _(" Found in ") + Screen->m_FileName;
Affiche_Message(msg);
}
else
{
Affiche_Message(wxEmptyString);
msg = WildText + _(" Not Found");
DisplayError(this,msg, 10);
}
return DrawList;
}
/*************************************************************/
void WinEDA_FindFrame::LocatePartInLibs(wxCommandEvent& event)
/*************************************************************/
/* Recherche exhaustive d'un composant en librairies, meme non chargees
*/
{
wxString Text, FindList;
const wxChar ** ListNames;
LibraryStruct *Lib = NULL;
EDA_LibComponentStruct * LibEntry;
bool FoundInLib = FALSE; // True si reference trouvee ailleurs qu'en cache
Text = m_NewTextCtrl->GetValue();
if ( Text.IsEmpty() )
{
Close(); return;
}
s_OldStringFound = Text;
int ii, nbitems, NumOfLibs = NumOfLibraries();
if (NumOfLibs == 0)
{
DisplayError(this, _("No libraries are loaded"));
Close(); return;
}
ListNames = GetLibNames();
nbitems = 0;
for (ii = 0; ii < NumOfLibs; ii++ ) /* Recherche de la librairie */
{
bool IsLibCache;
Lib = FindLibrary(ListNames[ii]);
if ( Lib == NULL ) break;
if ( Lib->m_Name.Contains( wxT(".cache")) ) IsLibCache = TRUE;
else IsLibCache = FALSE;
LibEntry = (EDA_LibComponentStruct *) PQFirst(&Lib->m_Entries, FALSE);
while( LibEntry )
{
if( WildCompareString(Text, LibEntry->m_Name.m_Text, FALSE) )
{
nbitems ++;
if ( ! IsLibCache ) FoundInLib = TRUE;
if ( ! FindList.IsEmpty() ) FindList += wxT("\n");
FindList << _("Found ")
+ LibEntry->m_Name.m_Text
+ _(" in lib ") + Lib->m_Name;
}
LibEntry = (EDA_LibComponentStruct *) PQNext(Lib->m_Entries, LibEntry, NULL);
}
}
free (ListNames);
if ( ! FoundInLib )
{
if ( nbitems ) FindList = wxT("\n") + Text + _(" found only in cache");
else FindList = Text + _(" not found");
FindList += _("\nExplore All Libraries?");
if ( IsOK(this, FindList) )
{
FindList.Empty();
ExploreAllLibraries(Text, FindList);
if ( FindList.IsEmpty() ) DisplayInfo(this, _("Nothing found") );
else DisplayInfo(this, FindList);
}
}
else DisplayInfo(this, FindList);
Close();
}
/***************************************************************************************/
int WinEDA_FindFrame::ExploreAllLibraries(const wxString & wildmask, wxString & FindList)
/***************************************************************************************/
{
wxString FullFileName;
FILE * file;
int nbitems = 0, LineNum = 0;
char Line[2048], *name;
FullFileName = MakeFileName(g_RealLibDirBuffer, wxT("*"), g_LibExtBuffer);
FullFileName = wxFindFirstFile(FullFileName);
while ( ! FullFileName.IsEmpty() )
{
file = wxFopen(FullFileName, wxT("rt"));
if (file == NULL) continue;
while (GetLine(file, Line, &LineNum, sizeof(Line)) )
{
if (strnicmp(Line, "DEF", 3) == 0)
{ /* Read one DEF part from library: DEF 74LS00 U 0 30 Y Y 4 0 N */
strtok(Line, " \t\r\n");
name = strtok(NULL, " \t\r\n");
wxString st_name = CONV_FROM_UTF8(name);
if( WildCompareString(wildmask, st_name, FALSE) )
{
nbitems ++;
if ( ! FindList.IsEmpty() ) FindList += wxT("\n");
FindList << _("Found ") << CONV_FROM_UTF8(name)
<< _(" in lib ") << FullFileName;
}
}
else if (strnicmp(Line, "ALIAS", 5) == 0)
{ /* Read one ALIAS part from library: ALIAS 74HC00 74HCT00 7400 74LS37 */
strtok(Line, " \t\r\n");
while ( (name = strtok(NULL, " \t\r\n")) != NULL )
{
wxString st_name = CONV_FROM_UTF8(name);
if( WildCompareString( wildmask, st_name, FALSE) )
{
nbitems ++;
if ( ! FindList.IsEmpty() ) FindList += wxT("\n");
FindList << _("Found ") << CONV_FROM_UTF8(name)
<< _(" in lib ") << FullFileName;
}
}
}
}
fclose(file);
FullFileName = wxFindNextFile();
}
return nbitems;
}