You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

370 lines
10 KiB

15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
18 years ago
18 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
15 years ago
  1. /****************************************/
  2. /* Module to load/save EESchema files. */
  3. /****************************************/
  4. #include "fctsys.h"
  5. #include "confirm.h"
  6. #include "kicad_string.h"
  7. #include "wxEeschemaStruct.h"
  8. #include "class_sch_screen.h"
  9. #include "richio.h"
  10. #include "general.h"
  11. #include "protos.h"
  12. #include "sch_marker.h"
  13. #include "sch_items.h"
  14. #include "sch_component.h"
  15. #include "sch_text.h"
  16. #include "sch_sheet.h"
  17. bool ReadSchemaDescr( LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window );
  18. static void LoadLayers( LINE_READER* aLine );
  19. /**
  20. * Routine to load an EESchema file.
  21. * Returns true if file has been loaded (at least partially.)
  22. */
  23. bool WinEDA_SchematicFrame::LoadOneEEFile( SCH_SCREEN* screen, const wxString& FullFileName )
  24. {
  25. char Name1[256];
  26. bool itemLoaded = false;
  27. SCH_ITEM* Phead;
  28. SCH_ITEM* Pnext;
  29. SCH_ITEM* item;
  30. wxString MsgDiag; // Error and log messages
  31. #define line ((char*)reader)
  32. if( screen == NULL )
  33. return FALSE;
  34. if( FullFileName.IsEmpty() )
  35. return FALSE;
  36. screen->SetCurItem( NULL );
  37. screen->m_FileName = FullFileName;
  38. // D(printf("LoadOneEEFile:%s\n", CONV_TO_UTF8( FullFileName ) ); )
  39. FILE* f;
  40. if( ( f = wxFopen( FullFileName, wxT( "rt" ) ) ) == NULL )
  41. {
  42. MsgDiag = _( "Failed to open " ) + FullFileName;
  43. DisplayError( this, MsgDiag );
  44. return FALSE;
  45. }
  46. // reader now owns the open FILE.
  47. FILE_LINE_READER reader( f, FullFileName );
  48. MsgDiag = _( "Loading " ) + screen->m_FileName;
  49. PrintMsg( MsgDiag );
  50. if( !reader.ReadLine()
  51. || strncmp( line + 9, SCHEMATIC_HEAD_STRING, sizeof(SCHEMATIC_HEAD_STRING) - 1 ) != 0 )
  52. {
  53. MsgDiag = FullFileName + _( " is NOT an EESchema file!" );
  54. DisplayError( this, MsgDiag );
  55. return FALSE;
  56. }
  57. // get the file version here.
  58. char *strversion = line + 9 + sizeof(SCHEMATIC_HEAD_STRING);
  59. // Skip blanks
  60. while( *strversion && *strversion < '0' )
  61. strversion++;
  62. int version = atoi(strversion);
  63. if( version > EESCHEMA_VERSION )
  64. {
  65. MsgDiag = FullFileName + _( " was created by a more recent \
  66. version of EESchema and may not load correctly. Please consider updating!" );
  67. DisplayInfoMessage( this, MsgDiag );
  68. }
  69. #if 0
  70. // Compile it if the new version is unreadable by previous eeschema versions
  71. else if( version < EESCHEMA_VERSION )
  72. {
  73. MsgDiag = FullFileName + _( " was created by an older version of \
  74. EESchema. It will be stored in the new file format when you save this file \
  75. again." );
  76. DisplayInfoMessage( this, MsgDiag );
  77. }
  78. #endif
  79. if( !reader.ReadLine() || strncmp( line, "LIBS:", 5 ) != 0 )
  80. {
  81. MsgDiag = FullFileName + _( " is NOT an EESchema file!" );
  82. DisplayError( this, MsgDiag );
  83. return FALSE;
  84. }
  85. LoadLayers( &reader );
  86. while( reader.ReadLine() )
  87. {
  88. item = NULL;
  89. char* sline = line;
  90. while( (*sline != ' ' ) && *sline )
  91. sline++;
  92. switch( line[0] )
  93. {
  94. case '$': // identification block
  95. if( line[1] == 'C' )
  96. item = new SCH_COMPONENT();
  97. else if( line[1] == 'S' )
  98. item = new SCH_SHEET();
  99. else if( line[1] == 'D' )
  100. itemLoaded = ReadSchemaDescr( &reader, MsgDiag, screen );
  101. break;
  102. case 'L': // Its a library item.
  103. item = new SCH_COMPONENT();
  104. break;
  105. case 'W': // Its a Segment (WIRE or BUS) item.
  106. item = new SCH_LINE();
  107. break;
  108. case 'E': // Its a WIRE or BUS item.
  109. item = new SCH_BUS_ENTRY();
  110. break;
  111. case 'P': // Its a polyline item.
  112. item = new SCH_POLYLINE();
  113. break;
  114. case 'C': // It is a connection item.
  115. item = new SCH_JUNCTION();
  116. break;
  117. case 'K': // It is a Marker item.
  118. // Markers are no more read from file. they are only created on
  119. // demand in schematic
  120. break;
  121. case 'N': // It is a NoConnect item.
  122. item = new SCH_NO_CONNECT();
  123. break;
  124. case 'T': // It is a text item.
  125. if( sscanf( sline, "%s", Name1 ) != 1 )
  126. {
  127. MsgDiag.Printf( wxT( "EESchema file text load error at line %d" ),
  128. reader.LineNumber() );
  129. itemLoaded = false;
  130. }
  131. else if( Name1[0] == 'L' )
  132. item = new SCH_LABEL();
  133. else if( Name1[0] == 'G' && version > 1 )
  134. item = new SCH_GLOBALLABEL();
  135. else if( (Name1[0] == 'H') || (Name1[0] == 'G' && version == 1) )
  136. item = new SCH_HIERLABEL();
  137. else
  138. item = new SCH_TEXT();
  139. break;
  140. default:
  141. itemLoaded = false;
  142. MsgDiag.Printf( wxT( "EESchema file undefined object at line %d, aborted" ),
  143. reader.LineNumber() );
  144. MsgDiag << wxT( "\n" ) << CONV_FROM_UTF8( line );
  145. }
  146. if( item )
  147. {
  148. itemLoaded = item->Load( reader, MsgDiag );
  149. if( !itemLoaded )
  150. {
  151. SAFE_DELETE( item );
  152. }
  153. else
  154. {
  155. item->SetNext( screen->EEDrawList );
  156. screen->EEDrawList = item;
  157. }
  158. }
  159. if( !itemLoaded )
  160. {
  161. DisplayError( this, MsgDiag );
  162. break;
  163. }
  164. }
  165. /* EEDrawList was constructed in reverse order - reverse it back: */
  166. Phead = NULL;
  167. while( screen->EEDrawList )
  168. {
  169. Pnext = screen->EEDrawList;
  170. screen->EEDrawList = screen->EEDrawList->Next();
  171. Pnext->SetNext( Phead );
  172. Phead = Pnext;
  173. }
  174. screen->EEDrawList = Phead;
  175. #if 0 && defined (DEBUG)
  176. screen->Show( 0, std::cout );
  177. #endif
  178. TestDanglingEnds( screen->EEDrawList, NULL );
  179. MsgDiag = _( "Done Loading " ) + screen->m_FileName;
  180. PrintMsg( MsgDiag );
  181. return true; // Although it may be that file is only partially loaded.
  182. }
  183. static void LoadLayers( LINE_READER* aLine )
  184. {
  185. int Number;
  186. //int Mode,Color,Layer;
  187. char Name[256];
  188. aLine->ReadLine();
  189. sscanf( *aLine, "%s %d %d", Name, &Number, &g_LayerDescr.CurrentLayer );
  190. if( strcmp( Name, "EELAYER" ) !=0 )
  191. {
  192. /* error : init par default */
  193. Number = MAX_LAYER;
  194. }
  195. if( Number <= 0 )
  196. Number = MAX_LAYER;
  197. if( Number > MAX_LAYER )
  198. Number = MAX_LAYER;
  199. g_LayerDescr.NumberOfLayers = Number;
  200. while( aLine->ReadLine() )
  201. {
  202. if( strnicmp( *aLine, "EELAYER END", 11 ) == 0 )
  203. break;
  204. }
  205. }
  206. /* Read the schematic header. */
  207. bool ReadSchemaDescr( LINE_READER* aLine, wxString& aMsgDiag, BASE_SCREEN* Window )
  208. {
  209. char Text[256], buf[1024];
  210. int ii;
  211. Ki_PageDescr* wsheet = &g_Sheet_A4;
  212. static Ki_PageDescr* SheetFormatList[] =
  213. {
  214. &g_Sheet_A4, &g_Sheet_A3, &g_Sheet_A2, &g_Sheet_A1, &g_Sheet_A0,
  215. &g_Sheet_A, &g_Sheet_B, &g_Sheet_C, &g_Sheet_D, &g_Sheet_E,
  216. &g_Sheet_user, NULL
  217. };
  218. wxSize PageSize;
  219. sscanf( ((char*)(*aLine)), "%s %s %d %d", Text, Text, &PageSize.x, &PageSize.y );
  220. wxString pagename = CONV_FROM_UTF8( Text );
  221. for( ii = 0; SheetFormatList[ii] != NULL; ii++ )
  222. {
  223. wsheet = SheetFormatList[ii];
  224. if( wsheet->m_Name.CmpNoCase( pagename ) == 0 ) /* Descr found ! */
  225. {
  226. // Get the user page size and make it the default
  227. if( wsheet == &g_Sheet_user )
  228. {
  229. g_Sheet_user.m_Size = PageSize;
  230. }
  231. break;
  232. }
  233. }
  234. if( SheetFormatList[ii] == NULL )
  235. {
  236. aMsgDiag.Printf( wxT( "EESchema file dimension definition error \
  237. line %d, \aAbort reading file.\n" ),
  238. aLine->LineNumber() );
  239. aMsgDiag << CONV_FROM_UTF8( ((char*)(*aLine)) );
  240. }
  241. Window->m_CurrentSheetDesc = wsheet;
  242. for( ; ; )
  243. {
  244. if( !aLine->ReadLine() )
  245. return TRUE;
  246. if( strnicmp( ((char*)(*aLine)), "$End", 4 ) == 0 )
  247. break;
  248. if( strnicmp( ((char*)(*aLine)), "Sheet", 2 ) == 0 )
  249. sscanf( ((char*)(*aLine)) + 5, " %d %d",
  250. &Window->m_ScreenNumber, &Window->m_NumberOfScreen );
  251. if( strnicmp( ((char*)(*aLine)), "Title", 2 ) == 0 )
  252. {
  253. ReadDelimitedText( buf, ((char*)(*aLine)), 256 );
  254. Window->m_Title = CONV_FROM_UTF8( buf );
  255. continue;
  256. }
  257. if( strnicmp( ((char*)(*aLine)), "Date", 2 ) == 0 )
  258. {
  259. ReadDelimitedText( buf, ((char*)(*aLine)), 256 );
  260. Window->m_Date = CONV_FROM_UTF8( buf );
  261. continue;
  262. }
  263. if( strnicmp( ((char*)(*aLine)), "Rev", 2 ) == 0 )
  264. {
  265. ReadDelimitedText( buf, ((char*)(*aLine)), 256 );
  266. Window->m_Revision = CONV_FROM_UTF8( buf );
  267. continue;
  268. }
  269. if( strnicmp( ((char*)(*aLine)), "Comp", 4 ) == 0 )
  270. {
  271. ReadDelimitedText( buf, ((char*)(*aLine)), 256 );
  272. Window->m_Company = CONV_FROM_UTF8( buf );
  273. continue;
  274. }
  275. if( strnicmp( ((char*)(*aLine)), "Comment1", 8 ) == 0 )
  276. {
  277. ReadDelimitedText( buf, ((char*)(*aLine)), 256 );
  278. Window->m_Commentaire1 = CONV_FROM_UTF8( buf );
  279. continue;
  280. }
  281. if( strnicmp( ((char*)(*aLine)), "Comment2", 8 ) == 0 )
  282. {
  283. ReadDelimitedText( buf, ((char*)(*aLine)), 256 );
  284. Window->m_Commentaire2 = CONV_FROM_UTF8( buf );
  285. continue;
  286. }
  287. if( strnicmp( ((char*)(*aLine)), "Comment3", 8 ) == 0 )
  288. {
  289. ReadDelimitedText( buf, ((char*)(*aLine)), 256 );
  290. Window->m_Commentaire3 = CONV_FROM_UTF8( buf );
  291. continue;
  292. }
  293. if( strnicmp( ((char*)(*aLine)), "Comment4", 8 ) == 0 )
  294. {
  295. ReadDelimitedText( buf, ((char*)(*aLine)), 256 );
  296. Window->m_Commentaire4 = CONV_FROM_UTF8( buf );
  297. continue;
  298. }
  299. }
  300. return true;
  301. }