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.

495 lines
15 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
  1. /************************************/
  2. /* delete.cpp */
  3. /************************************/
  4. #include "fctsys.h"
  5. #include "gr_basic.h"
  6. #include "common.h"
  7. #include "program.h"
  8. #include "general.h"
  9. #include "protos.h"
  10. #include "class_marker_sch.h"
  11. // Imported function:
  12. void DeleteItemsInList( WinEDA_DrawPanel* panel,
  13. PICKED_ITEMS_LIST& aItemsList );
  14. /*
  15. * Count number of items connected to point pos :
  16. * pins, end wire or bus, and junctions if TstJunction == TRUE
  17. * Return this count
  18. *
  19. * Used by WinEDA_SchematicFrame::DeleteConnection()
  20. */
  21. static int CountConnectedItems( WinEDA_SchematicFrame* frame,
  22. SCH_ITEM* ListStruct, wxPoint pos,
  23. bool TstJunction )
  24. {
  25. SCH_ITEM* Struct;
  26. int count = 0;
  27. if( frame->LocatePinEnd( ListStruct, pos ) )
  28. count++;
  29. for( Struct = ListStruct; Struct != NULL; Struct = Struct->Next() )
  30. {
  31. if( Struct->m_Flags & STRUCT_DELETED )
  32. continue;
  33. if( Struct->m_Flags & SKIP_STRUCT )
  34. continue;
  35. if( TstJunction && ( Struct->Type() == DRAW_JUNCTION_STRUCT_TYPE ) )
  36. {
  37. #define JUNCTION ( (SCH_JUNCTION*) Struct )
  38. if( JUNCTION->m_Pos == pos )
  39. count++;
  40. #undef JUNCTION
  41. }
  42. if( Struct->Type() != DRAW_SEGMENT_STRUCT_TYPE )
  43. continue;
  44. #define SEGM ( (SCH_LINE*) Struct )
  45. if( SEGM->IsOneEndPointAt( pos ) )
  46. count++;
  47. #undef SEGM
  48. }
  49. return count;
  50. }
  51. /*
  52. * Mark to "CANDIDATE" all wires or junction connected to "segment" in list
  53. * "ListStruct"
  54. * Search wire stop at an any pin
  55. *
  56. * Used by WinEDA_SchematicFrame::DeleteConnection()
  57. */
  58. static bool MarkConnected( WinEDA_SchematicFrame* frame, SCH_ITEM* ListStruct,
  59. SCH_LINE* segment )
  60. {
  61. EDA_BaseStruct* Struct;
  62. for( Struct = ListStruct; Struct != NULL; Struct = Struct->Next() )
  63. {
  64. if( Struct->m_Flags )
  65. continue;
  66. if( Struct->Type() == DRAW_JUNCTION_STRUCT_TYPE )
  67. {
  68. #define JUNCTION ( (SCH_JUNCTION*) Struct )
  69. if( segment->IsOneEndPointAt( JUNCTION->m_Pos ) )
  70. Struct->m_Flags |= CANDIDATE;
  71. continue;
  72. #undef JUNCTION
  73. }
  74. if( Struct->Type() != DRAW_SEGMENT_STRUCT_TYPE )
  75. continue;
  76. #define SEGM ( (SCH_LINE*) Struct )
  77. if( segment->IsOneEndPointAt( SEGM->m_Start ) )
  78. {
  79. if( !frame->LocatePinEnd( ListStruct, SEGM->m_Start ) )
  80. {
  81. Struct->m_Flags |= CANDIDATE;
  82. MarkConnected( frame, ListStruct, SEGM );
  83. }
  84. }
  85. if( segment->IsOneEndPointAt( SEGM->m_End ) )
  86. {
  87. if( !frame->LocatePinEnd( ListStruct, SEGM->m_End ) )
  88. {
  89. Struct->m_Flags |= CANDIDATE;
  90. MarkConnected( frame, ListStruct, SEGM );
  91. }
  92. }
  93. #undef SEGM
  94. }
  95. return TRUE;
  96. }
  97. /*
  98. * Delete a connection, i.e wires or bus connected
  99. * stop on a node (more than 2 wires (bus) connected)
  100. */
  101. void WinEDA_SchematicFrame::DeleteConnection( bool DeleteFullConnection )
  102. {
  103. wxPoint refpos = GetScreen()->m_Curseur;
  104. SCH_ITEM* DelStruct;
  105. PICKED_ITEMS_LIST pickList;
  106. /* Clear .m_Flags member for all items */
  107. for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL;
  108. DelStruct = DelStruct->Next() )
  109. DelStruct->m_Flags = 0;
  110. BreakSegmentOnJunction( (SCH_SCREEN*) GetScreen() );
  111. /* Locate all the wires, bus or junction under the mouse cursor, and put
  112. * them in a list of items to delete
  113. */
  114. ITEM_PICKER picker(NULL, UR_DELETED);
  115. SCH_SCREEN* screen = (SCH_SCREEN*) GetScreen();
  116. // Save the list entry point of this screen
  117. SCH_ITEM* savedEEDrawList = screen->EEDrawList;
  118. DelStruct = GetScreen()->EEDrawList;
  119. while( DelStruct
  120. && ( DelStruct = PickStruct( screen->m_Curseur, screen,
  121. JUNCTIONITEM | WIREITEM | BUSITEM ) ) != NULL )
  122. {
  123. DelStruct->m_Flags = SELECTEDNODE | STRUCT_DELETED;
  124. /* Put this structure in the picked list: */
  125. picker.m_PickedItem = DelStruct;
  126. picker.m_PickedItemType = DelStruct->Type();
  127. pickList.PushItem(picker);
  128. DelStruct = DelStruct->Next();
  129. screen->EEDrawList = DelStruct;
  130. }
  131. GetScreen()->EEDrawList = savedEEDrawList;
  132. /* Mark all wires, junctions, .. connected to one of the item to delete
  133. */
  134. if( DeleteFullConnection )
  135. {
  136. for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL;
  137. DelStruct = DelStruct->Next() )
  138. {
  139. if( !(DelStruct->m_Flags & SELECTEDNODE) )
  140. continue;
  141. #define SEGM ( (SCH_LINE*) DelStruct )
  142. if( DelStruct->Type() != DRAW_SEGMENT_STRUCT_TYPE )
  143. continue;
  144. MarkConnected( this, GetScreen()->EEDrawList, SEGM );
  145. #undef SEGM
  146. }
  147. // Search all removable wires (i.e wire with one new dangling end )
  148. for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL;
  149. DelStruct = DelStruct->Next() )
  150. {
  151. bool noconnect = FALSE;
  152. if( DelStruct->m_Flags & STRUCT_DELETED )
  153. continue; // Already seen
  154. if( !(DelStruct->m_Flags & CANDIDATE) )
  155. continue; // Already seen
  156. if( DelStruct->Type() != DRAW_SEGMENT_STRUCT_TYPE )
  157. continue;
  158. DelStruct->m_Flags |= SKIP_STRUCT;
  159. #define SEGM ( (SCH_LINE*) DelStruct )
  160. /* Test the SEGM->m_Start point: if this point was connected to
  161. * an STRUCT_DELETED wire, and now is not connected, the wire can
  162. * be deleted */
  163. EDA_BaseStruct* removed_struct;
  164. for( removed_struct = GetScreen()->EEDrawList;
  165. removed_struct != NULL;
  166. removed_struct = removed_struct->Next() )
  167. {
  168. if( ( removed_struct->m_Flags & STRUCT_DELETED ) == 0 )
  169. continue;
  170. if( removed_struct->Type() != DRAW_SEGMENT_STRUCT_TYPE )
  171. continue;
  172. #define WIRE ( (SCH_LINE*) removed_struct )
  173. if( WIRE->IsOneEndPointAt( SEGM->m_Start ) )
  174. break;
  175. }
  176. if( WIRE && !CountConnectedItems( this, GetScreen()->EEDrawList,
  177. SEGM->m_Start, TRUE ) )
  178. noconnect = TRUE;
  179. /* Test the SEGM->m_End point: if this point was connected to
  180. * an STRUCT_DELETED wire, and now is not connected, the wire
  181. * can be deleted */
  182. for( removed_struct = GetScreen()->EEDrawList;
  183. removed_struct != NULL;
  184. removed_struct = removed_struct->Next() )
  185. {
  186. if( ( removed_struct->m_Flags & STRUCT_DELETED ) == 0 )
  187. continue;
  188. if( removed_struct->Type() != DRAW_SEGMENT_STRUCT_TYPE )
  189. continue;
  190. if( WIRE->IsOneEndPointAt( SEGM->m_End ) )
  191. break;
  192. }
  193. if( removed_struct &&
  194. !CountConnectedItems( this, GetScreen()->EEDrawList,
  195. SEGM->m_End, TRUE ) )
  196. noconnect = TRUE;
  197. DelStruct->m_Flags &= ~SKIP_STRUCT;
  198. if( noconnect )
  199. {
  200. DelStruct->m_Flags |= STRUCT_DELETED;
  201. /* Put this structure in the picked list: */
  202. picker.m_PickedItem = DelStruct;
  203. picker.m_PickedItemType = DelStruct->Type();
  204. pickList.PushItem(picker);
  205. DelStruct = GetScreen()->EEDrawList;
  206. }
  207. #undef SEGM
  208. }
  209. // Delete redundant junctions (junctions which connect < 3 end wires
  210. // and no pin are removed)
  211. for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL;
  212. DelStruct = DelStruct->Next() )
  213. {
  214. int count;
  215. if( DelStruct->m_Flags & STRUCT_DELETED )
  216. continue;
  217. if( !(DelStruct->m_Flags & CANDIDATE) )
  218. continue;
  219. if( DelStruct->Type() == DRAW_JUNCTION_STRUCT_TYPE )
  220. {
  221. #define JUNCTION ( (SCH_JUNCTION*) DelStruct )
  222. count = CountConnectedItems( this, GetScreen()->EEDrawList,
  223. JUNCTION->m_Pos, FALSE );
  224. if( count <= 2 )
  225. {
  226. DelStruct->m_Flags |= STRUCT_DELETED;
  227. /* Put this structure in the picked list: */
  228. picker.m_PickedItem = DelStruct;
  229. picker.m_PickedItemType = DelStruct->Type();
  230. pickList.PushItem(picker);
  231. }
  232. #undef JUNCTION
  233. }
  234. }
  235. // Delete labels attached to wires
  236. wxPoint pos = GetScreen()->m_Curseur;
  237. for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL;
  238. DelStruct = DelStruct->Next() )
  239. {
  240. if( DelStruct->m_Flags & STRUCT_DELETED )
  241. continue;
  242. if( DelStruct->Type() != TYPE_SCH_LABEL )
  243. continue;
  244. GetScreen()->m_Curseur = ( (SCH_TEXT*) DelStruct )->m_Pos;
  245. EDA_BaseStruct* TstStruct =
  246. PickStruct( GetScreen()->m_Curseur, GetScreen(),
  247. WIREITEM | BUSITEM );
  248. if( TstStruct && TstStruct->m_Flags & STRUCT_DELETED )
  249. {
  250. DelStruct->m_Flags |= STRUCT_DELETED;
  251. /* Put this structure in the picked list: */
  252. picker.m_PickedItem = DelStruct;
  253. picker.m_PickedItemType = DelStruct->Type();
  254. pickList.PushItem(picker);
  255. }
  256. }
  257. GetScreen()->m_Curseur = pos;
  258. }
  259. for( DelStruct = GetScreen()->EEDrawList; DelStruct != NULL;
  260. DelStruct = DelStruct->Next() )
  261. DelStruct->m_Flags = 0;
  262. if( pickList.GetCount() )
  263. {
  264. DeleteItemsInList( DrawPanel, pickList );
  265. GetScreen()->SetModify();
  266. }
  267. }
  268. /*
  269. * Locate and delete the item found under the mouse cursor
  270. * If more than one item found: the priority order is:
  271. * 1 : MARKER
  272. * 2 : JUNCTION
  273. * 2 : NOCONNECT
  274. * 3 : WIRE or BUS
  275. * 4 : DRAWITEM
  276. * 5 : TEXT
  277. * 6 : COMPOSANT
  278. * 7 : SHEET
  279. *
  280. * return TRUE if an item was deleted
  281. */
  282. bool LocateAndDeleteItem( WinEDA_SchematicFrame* frame, wxDC* DC )
  283. {
  284. SCH_ITEM* DelStruct;
  285. SCH_SCREEN* screen = (SCH_SCREEN*) ( frame->GetScreen() );
  286. bool item_deleted = FALSE;
  287. DelStruct = PickStruct( screen->m_Curseur, screen, MARKERITEM );
  288. if( DelStruct == NULL )
  289. DelStruct = PickStruct( screen->m_Curseur, screen, JUNCTIONITEM );
  290. if( DelStruct == NULL )
  291. DelStruct = PickStruct( screen->m_Curseur, screen, NOCONNECTITEM );
  292. if( DelStruct == NULL )
  293. DelStruct = PickStruct( screen->m_Curseur, screen, RACCORDITEM );
  294. if( DelStruct == NULL )
  295. DelStruct = PickStruct( screen->m_Curseur, screen, WIREITEM | BUSITEM );
  296. if( DelStruct == NULL )
  297. DelStruct = PickStruct( screen->m_Curseur, screen, DRAWITEM );
  298. if( DelStruct == NULL )
  299. DelStruct = PickStruct( screen->m_Curseur, screen,
  300. TEXTITEM | LABELITEM );
  301. if( DelStruct == NULL )
  302. DelStruct = PickStruct( screen->m_Curseur, screen, LIBITEM );
  303. if( DelStruct == NULL )
  304. DelStruct = PickStruct( screen->m_Curseur, screen, SHEETITEM );
  305. if( DelStruct )
  306. {
  307. g_ItemToRepeat = NULL;
  308. DeleteStruct( frame->DrawPanel, DC, DelStruct );
  309. frame->TestDanglingEnds( frame->GetScreen()->EEDrawList, DC );
  310. frame->GetScreen()->SetModify();
  311. item_deleted = TRUE;
  312. }
  313. return item_deleted;
  314. }
  315. /*
  316. * Remove definition of a structure in a linked list
  317. * Elements of Drawing
  318. * DrawStruct * = pointer to the structure
  319. * Screen = pointer on the screen of belonging
  320. *
  321. * Note:
  322. * DRAW_SHEET_STRUCT_TYPE structures for the screen and structures
  323. * Corresponding keys are not.
  324. * They must be treated separately
  325. */
  326. void EraseStruct( SCH_ITEM* DrawStruct, SCH_SCREEN* Screen )
  327. {
  328. EDA_BaseStruct* DrawList;
  329. SCH_SHEET_PIN* SheetLabel, * NextLabel;
  330. if( DrawStruct == NULL )
  331. return;
  332. if( Screen == NULL )
  333. return;
  334. Screen->SetModify();
  335. if( DrawStruct->Type() == DRAW_HIERARCHICAL_PIN_SHEET_STRUCT_TYPE )
  336. {
  337. //this structure is attached to a sheet , which we must find.
  338. DrawList = Screen->EEDrawList;
  339. for( ; DrawList != NULL; DrawList = DrawList->Next() )
  340. {
  341. if( DrawList->Type() != DRAW_SHEET_STRUCT_TYPE )
  342. continue;
  343. /* See if our item is in this Sheet */
  344. SheetLabel = ( (SCH_SHEET*) DrawList )->m_Label;
  345. if( SheetLabel == NULL )
  346. continue;
  347. if( SheetLabel == (SCH_SHEET_PIN*) DrawStruct )
  348. {
  349. ( (SCH_SHEET*) DrawList )->m_Label =
  350. (SCH_SHEET_PIN*) SheetLabel->Next();
  351. SAFE_DELETE( DrawStruct );
  352. return;
  353. }
  354. else
  355. {
  356. while( SheetLabel->Next() )
  357. {
  358. NextLabel = (SCH_SHEET_PIN*) SheetLabel->Next();
  359. if( NextLabel == (SCH_SHEET_PIN*) DrawStruct )
  360. {
  361. SheetLabel->SetNext( (EDA_BaseStruct*) NextLabel->Next() );
  362. SAFE_DELETE( DrawStruct );
  363. return;
  364. }
  365. SheetLabel = NextLabel;
  366. }
  367. }
  368. }
  369. return;
  370. }
  371. else
  372. {
  373. if( DrawStruct == Screen->EEDrawList )
  374. {
  375. Screen->EEDrawList = DrawStruct->Next();
  376. SAFE_DELETE( DrawStruct );
  377. }
  378. else
  379. {
  380. DrawList = Screen->EEDrawList;
  381. while( DrawList && DrawList->Next() )
  382. {
  383. if( DrawList->Next() == DrawStruct )
  384. {
  385. DrawList->SetNext( DrawStruct->Next() );
  386. SAFE_DELETE( DrawStruct );
  387. return;
  388. }
  389. DrawList = DrawList->Next();
  390. }
  391. }
  392. }
  393. }
  394. void DeleteAllMarkers( int type )
  395. {
  396. SCH_SCREEN* screen;
  397. SCH_ITEM * DrawStruct, * NextStruct;
  398. SCH_MARKER* Marker;
  399. EDA_ScreenList ScreenList;
  400. for( screen = ScreenList.GetFirst(); screen != NULL;
  401. screen = ScreenList.GetNext() )
  402. {
  403. for( DrawStruct = screen->EEDrawList; DrawStruct != NULL;
  404. DrawStruct = NextStruct )
  405. {
  406. NextStruct = DrawStruct->Next();
  407. if( DrawStruct->Type() != TYPE_SCH_MARKER )
  408. continue;
  409. Marker = (SCH_MARKER*) DrawStruct;
  410. if( Marker->GetMarkerType() != type )
  411. continue;
  412. /* Remove marker */
  413. EraseStruct( DrawStruct, screen );
  414. }
  415. }
  416. }