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.

1059 lines
31 KiB

17 years ago
  1. /***************************/
  2. /* EESchema - PinEdit.cpp */
  3. /***************************/
  4. #include "fctsys.h"
  5. #include "program.h"
  6. #include "libeditfrm.h"
  7. #include "eeschema_id.h"
  8. #include "class_libentry.h"
  9. #include "pinedit-dialog.h"
  10. #include "dialog_display_info_HTML_base.h"
  11. static int CodeOrient[4] =
  12. {
  13. PIN_RIGHT,
  14. PIN_LEFT,
  15. PIN_UP,
  16. PIN_DOWN
  17. };
  18. #define NBSHAPES 7
  19. static wxString shape_list[NBSHAPES] =
  20. {
  21. _( "line" ), _( "invert" ), _( "clock" ), _( "clock inv" ),
  22. _( "low in" ), _( "low clock" ), _( "low out" )
  23. };
  24. int CodeShape[NBSHAPES] =
  25. {
  26. NONE, INVERT, CLOCK, CLOCK | INVERT, LOWLEVEL_IN, LOWLEVEL_IN | CLOCK,
  27. LOWLEVEL_OUT
  28. };
  29. /* Routines locales */
  30. static void CreateImagePins( LIB_PIN* Pin, int unit, int convert,
  31. bool asDeMorgan );
  32. static void AbortPinMove( WinEDA_DrawPanel* Panel, wxDC* DC );
  33. static void DrawMovePin( WinEDA_DrawPanel* panel, wxDC* DC, bool erase );
  34. /* Variables importees */
  35. /* Variables locales */
  36. static wxPoint OldPos, PinPreviousPos;
  37. static int LastPinType = PIN_INPUT,
  38. LastPinOrient = PIN_RIGHT,
  39. LastPinShape = NONE,
  40. LastPinSize = 300,
  41. LastPinNameSize = 50,
  42. LastPinNumSize = 50,
  43. LastPinCommonConvert = false,
  44. LastPinCommonUnit = false,
  45. LastPinNoDraw = false;
  46. #include "pinedit-dialog.cpp"
  47. /*************************************************************************/
  48. void WinEDA_PinPropertiesFrame::PinPropertiesAccept( wxCommandEvent& event )
  49. /*************************************************************************/
  50. /* Met a jour les differents parametres pour le composant en cours d'�dition
  51. */
  52. {
  53. wxString msg;
  54. LastPinType = m_PinElectricalType->GetSelection();
  55. LastPinShape = CodeShape[m_PinShape->GetSelection()];
  56. LastPinOrient = CodeOrient[m_PinOrient->GetSelection()];
  57. LastPinCommonConvert = m_CommonConvert->GetValue();
  58. LastPinCommonUnit = m_CommonUnit->GetValue();
  59. LastPinNoDraw = m_NoDraw->GetValue();
  60. msg = m_PinSizeCtrl->GetValue();
  61. LastPinSize = ReturnValueFromString( g_UnitMetric, msg,
  62. m_Parent->m_InternalUnits );
  63. msg = m_PinNameSizeCtrl->GetValue();
  64. LastPinNameSize = ReturnValueFromString( g_UnitMetric, msg,
  65. m_Parent->m_InternalUnits );
  66. msg = m_PinNumSizeCtrl->GetValue();
  67. LastPinNumSize = ReturnValueFromString( g_UnitMetric, msg,
  68. m_Parent->m_InternalUnits );
  69. LIB_DRAW_ITEM* item = m_Parent->GetDrawItem();
  70. if( item == NULL )
  71. return;
  72. if( !( item->m_Flags & IS_NEW ) ) // if IS_NEW, copy for undo is done before place
  73. m_Parent->SaveCopyInUndoList( item->GetParent() );
  74. SetPinName( m_PinNameCtrl->GetValue(), LastPinNameSize );
  75. msg = m_PinNumCtrl->GetValue();
  76. if( msg.IsEmpty() )
  77. msg = wxT( "~" );
  78. SetPinNum( msg, LastPinNumSize );
  79. NewSizePin( LastPinSize );
  80. SetPinShape( LastPinShape );
  81. SetPinType( LastPinType );
  82. SetPinOrientation( LastPinOrient );
  83. // Set all attributes (visibility, common to units and common to
  84. // convert options)
  85. SetPinAttributes( true, true, true );
  86. item->DisplayInfo( m_Parent );
  87. m_Parent->DrawPanel->Refresh();
  88. }
  89. /*
  90. * Called when installing the edit pin dialog frame
  91. * Set pins flags (.m_Flags pins member) to ensure a correctins edition:
  92. * If 2 or more pins are on the same location (and the same orientation) they
  93. * are all moved or resized.
  94. * This is usefull for components which have more than one part per package
  95. * In this case all parts can be edited at once.
  96. * Note: if the option "Edit Pin per Pin" (tool of the main toolbar) is
  97. * activated, only the current part is edited.
  98. */
  99. void WinEDA_LibeditFrame::InitEditOnePin()
  100. {
  101. LIB_PIN* Pin;
  102. LIB_PIN* CurrentPin = (LIB_PIN*) m_drawItem;
  103. if( m_component == NULL || CurrentPin == NULL
  104. || m_drawItem->Type() != COMPONENT_PIN_DRAW_TYPE )
  105. return;
  106. for( Pin = m_component->GetNextPin(); Pin != NULL;
  107. Pin = m_component->GetNextPin( Pin ) )
  108. {
  109. if( Pin == CurrentPin )
  110. continue;
  111. if( ( Pin->m_Pos == CurrentPin->m_Pos )
  112. && ( Pin->m_Orient == CurrentPin->m_Orient )
  113. && ( !( CurrentPin->m_Flags & IS_NEW ) )
  114. && ( g_EditPinByPinIsOn == false ) )
  115. Pin->m_Flags |= IS_LINKED | IN_EDIT;
  116. else
  117. Pin->m_Flags = 0;
  118. }
  119. CurrentPin->DisplayInfo( this );
  120. }
  121. /**
  122. * Clean up after aborting a move pin command.
  123. */
  124. static void AbortPinMove( WinEDA_DrawPanel* Panel, wxDC* DC )
  125. {
  126. WinEDA_LibeditFrame* parent = (WinEDA_LibeditFrame*) Panel->GetParent();
  127. if( parent == NULL )
  128. return;
  129. LIB_PIN* CurrentPin = (LIB_PIN*) parent->GetDrawItem();
  130. if( CurrentPin == NULL || CurrentPin->Type() != COMPONENT_PIN_DRAW_TYPE )
  131. return;
  132. if( CurrentPin->m_Flags & IS_NEW )
  133. delete CurrentPin;
  134. else
  135. CurrentPin->m_Flags = 0;
  136. /* clear edit flags */
  137. Panel->ManageCurseur = NULL;
  138. Panel->ForceCloseManageCurseur = NULL;
  139. parent->SetDrawItem( NULL );
  140. parent->SetLastDrawItem( NULL );
  141. Panel->Refresh( true );
  142. }
  143. /**
  144. * Managed cursor callback for placing component pins.
  145. */
  146. void WinEDA_LibeditFrame::PlacePin( wxDC* DC )
  147. {
  148. LIB_PIN* Pin;
  149. LIB_PIN* CurrentPin = (LIB_PIN*) m_drawItem;
  150. bool ask_for_pin = true;
  151. wxPoint newpos;
  152. bool status;
  153. if( CurrentPin == NULL )
  154. return;
  155. newpos.x = GetScreen()->m_Curseur.x;
  156. newpos.y = -GetScreen()->m_Curseur.y;
  157. // Tst for an other pin in same new position:
  158. for( Pin = m_component->GetNextPin(); Pin != NULL;
  159. Pin = m_component->GetNextPin( Pin ) )
  160. {
  161. if( Pin == CurrentPin || newpos != Pin->m_Pos || Pin->m_Flags )
  162. continue;
  163. if( ask_for_pin && !g_EditPinByPinIsOn )
  164. {
  165. DrawPanel->m_IgnoreMouseEvents = true;
  166. status =
  167. IsOK( this, _( "This position is already occupied by \
  168. another pin. Continue?" ) );
  169. DrawPanel->MouseToCursorSchema();
  170. DrawPanel->m_IgnoreMouseEvents = false;
  171. if( !status )
  172. return;
  173. else
  174. ask_for_pin = false;
  175. }
  176. }
  177. DrawPanel->ManageCurseur = NULL;
  178. DrawPanel->ForceCloseManageCurseur = NULL;
  179. GetScreen()->SetModify();
  180. CurrentPin->m_Pos = newpos;
  181. if( CurrentPin->m_Flags & IS_NEW )
  182. {
  183. LastPinOrient = CurrentPin->m_Orient;
  184. LastPinType = CurrentPin->m_PinType;
  185. LastPinShape = CurrentPin->m_PinShape;
  186. CreateImagePins( CurrentPin, m_unit, m_convert, m_showDeMorgan );
  187. m_lastDrawItem = CurrentPin;
  188. m_component->AddDrawItem( m_drawItem );
  189. }
  190. /* Put linked pins in new position, and clear flags */
  191. for( Pin = m_component->GetNextPin(); Pin != NULL;
  192. Pin = m_component->GetNextPin( Pin ) )
  193. {
  194. if( Pin->m_Flags == 0 )
  195. continue;
  196. Pin->m_Pos = CurrentPin->m_Pos;
  197. Pin->m_Flags = 0;
  198. }
  199. DrawPanel->CursorOff( DC );
  200. bool showPinText = true;
  201. CurrentPin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE,
  202. &showPinText, DefaultTransformMatrix );
  203. DrawPanel->CursorOn( DC );
  204. m_drawItem = NULL;
  205. };
  206. void WinEDA_PinPropertiesFrame::SetPinOrientation( int neworient )
  207. {
  208. LIB_PIN* CurrentPin = (LIB_PIN*) m_Parent->GetDrawItem();
  209. LIB_PIN* Pin, * RefPin = CurrentPin;
  210. if( CurrentPin == NULL || CurrentPin->GetParent() == NULL || RefPin == NULL )
  211. return;
  212. m_Parent->GetScreen()->SetModify();
  213. /* Rotation */
  214. RefPin->m_Orient = neworient;
  215. Pin = CurrentPin->GetParent()->GetNextPin();
  216. for( ; Pin != NULL; Pin = CurrentPin->GetParent()->GetNextPin( Pin ) )
  217. {
  218. if( Pin->m_Flags == 0 )
  219. continue;
  220. Pin->m_Orient = RefPin->m_Orient;
  221. if( CurrentPin == NULL )
  222. Pin->m_Flags = 0;
  223. }
  224. }
  225. /**
  226. * Prepare le deplacement d'une pin :
  227. * Localise la pin pointee par le curseur, et si elle existe active
  228. * la fonction de gestion curseur ( DrawMovePin() ).
  229. */
  230. void WinEDA_LibeditFrame::StartMovePin( wxDC* DC )
  231. {
  232. LIB_PIN* Pin;
  233. LIB_PIN* CurrentPin = (LIB_PIN*) m_drawItem;
  234. wxPoint startPos;
  235. /* Marquage des pins a traiter */
  236. Pin = m_component->GetNextPin();
  237. for( ; Pin != NULL; Pin = m_component->GetNextPin( Pin ) )
  238. {
  239. Pin->m_Flags = 0;
  240. if( Pin == CurrentPin )
  241. continue;
  242. if( ( Pin->m_Pos == CurrentPin->m_Pos )
  243. && ( Pin->m_Orient == CurrentPin->m_Orient )
  244. && ( g_EditPinByPinIsOn == false ) )
  245. Pin->m_Flags |= IS_LINKED | IS_MOVED;
  246. }
  247. CurrentPin->m_Flags |= IS_LINKED | IS_MOVED;
  248. PinPreviousPos = OldPos = CurrentPin->m_Pos;
  249. startPos.x = OldPos.x;
  250. startPos.y = -OldPos.y;
  251. DrawPanel->CursorOff( DC );
  252. GetScreen()->m_Curseur = startPos;
  253. DrawPanel->MouseToCursorSchema();
  254. CurrentPin->DisplayInfo( this );
  255. DrawPanel->ManageCurseur = DrawMovePin;
  256. DrawPanel->ForceCloseManageCurseur = AbortPinMove;
  257. DrawPanel->CursorOn( DC );
  258. }
  259. /******************************************************************************/
  260. /* Routine de deplacement de la Pin courante selon position du curseur souris */
  261. /* Routine normalement appelee par la routine de gestion du curseur */
  262. /******************************************************************************/
  263. static void DrawMovePin( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
  264. {
  265. WinEDA_LibeditFrame* parent = (WinEDA_LibeditFrame*) panel->GetParent();
  266. if( parent == NULL )
  267. return;
  268. LIB_PIN* CurrentPin = (LIB_PIN*) parent->GetDrawItem();
  269. if( CurrentPin == NULL || CurrentPin->Type() != COMPONENT_PIN_DRAW_TYPE )
  270. return;
  271. wxPoint pinpos = CurrentPin->m_Pos;
  272. bool showPinText = true;
  273. /* Erase pin in old position */
  274. if( erase || ( CurrentPin->m_Flags & IS_NEW ) )
  275. {
  276. wxLogDebug( _( "Initial pin position (%d, %d)" ),
  277. PinPreviousPos.x, PinPreviousPos.y );
  278. CurrentPin->m_Pos = PinPreviousPos;
  279. CurrentPin->Draw( panel, DC, wxPoint( 0, 0 ), -1, g_XorMode,
  280. &showPinText, DefaultTransformMatrix );
  281. }
  282. /* Redraw pin in new position */
  283. CurrentPin->m_Pos.x = panel->GetScreen()->m_Curseur.x;
  284. CurrentPin->m_Pos.y = -panel->GetScreen()->m_Curseur.y;
  285. CurrentPin->Draw( panel, DC, wxPoint( 0, 0 ), -1, wxCOPY,
  286. &showPinText, DefaultTransformMatrix );
  287. PinPreviousPos = CurrentPin->m_Pos;
  288. /* Keep the original position for existing pin (for Undo command)
  289. * and the current position for a new pin */
  290. if( ( CurrentPin->m_Flags & IS_NEW ) == 0 )
  291. CurrentPin->m_Pos = pinpos;
  292. }
  293. /**********************************************************/
  294. void WinEDA_PinPropertiesFrame::SetPinShape( int newshape )
  295. /**********************************************************/
  296. /* Changement de la forme de la pin courante.
  297. * Le changement est egalement fait sur les autres pins correspondantes
  298. * des autres unites de la seule forme convert courante
  299. */
  300. {
  301. LIB_PIN* Pin;
  302. LIB_PIN* CurrentPin = (LIB_PIN*) m_Parent->GetDrawItem();
  303. if( CurrentPin )
  304. {
  305. CurrentPin->m_PinShape = newshape;
  306. m_Parent->GetScreen()->SetModify();
  307. CurrentPin->DisplayInfo( m_Parent );
  308. Pin = CurrentPin->GetParent()->GetNextPin();
  309. for( ; Pin != NULL; Pin = CurrentPin->GetParent()->GetNextPin( Pin ) )
  310. {
  311. if( Pin->m_Flags == 0 || Pin->m_Convert != CurrentPin->m_Convert )
  312. continue;
  313. Pin->m_PinShape = newshape;
  314. }
  315. }
  316. }
  317. /******************************************************/
  318. void WinEDA_PinPropertiesFrame::SetPinType( int newtype )
  319. /******************************************************/
  320. /* Changement du type electrique de la pin courante.
  321. * Le changement est egalement fait sur les autres pins correspondantes
  322. * des autres unites du boitier
  323. */
  324. {
  325. LIB_PIN* Pin;
  326. LIB_PIN* CurrentPin = (LIB_PIN*) m_Parent->GetDrawItem();
  327. if( CurrentPin == NULL || CurrentPin->GetParent() == NULL )
  328. return;
  329. CurrentPin->m_PinType = newtype;
  330. m_Parent->GetScreen()->SetModify();
  331. Pin = CurrentPin->GetParent()->GetNextPin();
  332. for( ; Pin != NULL; Pin = CurrentPin->GetParent()->GetNextPin( Pin ) )
  333. {
  334. if( Pin->m_Flags == 0 )
  335. continue;
  336. Pin->m_PinType = newtype;
  337. }
  338. }
  339. /********************************************************************************/
  340. void WinEDA_PinPropertiesFrame::SetPinName( const wxString& newname, int newsize )
  341. /********************************************************************************/
  342. /* Met a jour le nom et la taille de ce nom de la pin courante
  343. * si newname == NULL, pas de changement de nom
  344. * si newsize < 0 : pas de changement de taille
  345. */
  346. {
  347. LIB_PIN* Pin;
  348. LIB_PIN* CurrentPin = (LIB_PIN*) m_Parent->GetDrawItem();
  349. wxString buf;
  350. if( CurrentPin == NULL || CurrentPin->GetParent() == NULL )
  351. return;
  352. buf = newname;
  353. buf.Replace( wxT( " " ), wxT( "_" ) );
  354. if( newsize >= 0 )
  355. CurrentPin->m_PinNameSize = newsize;
  356. CurrentPin->m_PinName = buf;
  357. m_Parent->GetScreen()->SetModify();
  358. /* Traitement des autres pins */
  359. Pin = CurrentPin->GetParent()->GetNextPin();
  360. for( ; Pin != NULL; Pin = CurrentPin->GetParent()->GetNextPin( Pin ) )
  361. {
  362. if( (Pin->m_Flags & IS_LINKED) == 0 )
  363. continue;
  364. if( newsize >= 0 )
  365. Pin->m_PinNameSize = newsize;
  366. Pin->m_PinName = buf;
  367. }
  368. }
  369. /******************************************************************************/
  370. void WinEDA_PinPropertiesFrame::SetPinNum( const wxString& newnum, int newsize )
  371. /******************************************************************************/
  372. /* Changement du numero de la pin courante.
  373. * Le changement est egalement fait sur les autres pins correspondantes
  374. * a la forme convertie
  375. * Si newnum == NULL: pas de changement de numero
  376. * Si newsize < 0 ) pase de changement de taille
  377. */
  378. {
  379. LIB_PIN* Pin;
  380. LIB_PIN* CurrentPin = (LIB_PIN*) m_Parent->GetDrawItem();
  381. wxString buf;
  382. buf = newnum;
  383. buf.Replace( wxT( " " ), wxT( "_" ) );
  384. if( CurrentPin == NULL || CurrentPin->GetParent() == NULL )
  385. return;
  386. CurrentPin->m_PinNum = 0;
  387. if( newsize >= 0 )
  388. CurrentPin->m_PinNumSize = newsize;
  389. CurrentPin->SetPinNumFromString( buf );
  390. m_Parent->GetScreen()->SetModify();
  391. Pin = CurrentPin->GetParent()->GetNextPin();
  392. for( ; Pin != NULL; Pin = CurrentPin->GetParent()->GetNextPin( Pin ) )
  393. {
  394. if( ( Pin->m_Flags & IS_LINKED ) == 0
  395. || Pin->m_Unit != CurrentPin->m_Unit )
  396. continue;
  397. if( newsize >= 0 )
  398. Pin->m_PinNumSize = newsize;
  399. Pin->m_PinNum = CurrentPin->m_PinNum;
  400. }
  401. }
  402. /*************************************************/
  403. void WinEDA_LibeditFrame::DeletePin( wxDC* DC,
  404. LIB_COMPONENT* LibEntry,
  405. LIB_PIN* Pin )
  406. /*************************************************/
  407. /* Routine d'effacement de la pin pointee par la souris
  408. * Si g_EditPinByPinIsOn == false :
  409. * toutes les pins de meme coordonnee seront effacees.
  410. * Sinon seule la pin de l'unite en convert courante sera effacee
  411. */
  412. {
  413. LIB_PIN* tmp;
  414. wxPoint PinPos;
  415. if( LibEntry == NULL || Pin == NULL )
  416. return;
  417. PinPos = Pin->m_Pos;
  418. LibEntry->RemoveDrawItem( (LIB_DRAW_ITEM*) Pin, DrawPanel, DC );
  419. /* Effacement des autres pins de meme coordonnees */
  420. if( g_EditPinByPinIsOn == false )
  421. {
  422. tmp = LibEntry->GetNextPin();
  423. while( tmp != NULL )
  424. {
  425. Pin = tmp;
  426. tmp = LibEntry->GetNextPin( Pin );
  427. if( Pin->m_Pos != PinPos )
  428. continue;
  429. LibEntry->RemoveDrawItem( (LIB_DRAW_ITEM*) Pin );
  430. }
  431. }
  432. GetScreen()->SetModify();
  433. }
  434. /*
  435. * Create a new pin.
  436. */
  437. void WinEDA_LibeditFrame::CreatePin( wxDC* DC )
  438. {
  439. LIB_PIN* CurrentPin;
  440. bool showPinText = true;
  441. if( m_component == NULL )
  442. return;
  443. /* Effacement des flags */
  444. m_component->ClearStatus();
  445. CurrentPin = new LIB_PIN( m_component );
  446. m_drawItem = CurrentPin;
  447. if( CurrentPin == NULL || CurrentPin->Type() != COMPONENT_PIN_DRAW_TYPE )
  448. return;
  449. CurrentPin->m_Flags = IS_NEW;
  450. CurrentPin->m_Unit = m_unit;
  451. CurrentPin->m_Convert = m_convert;
  452. /* Flag pins to consider */
  453. if( g_EditPinByPinIsOn == false )
  454. CurrentPin->m_Flags |= IS_LINKED;
  455. CurrentPin->m_Pos.x = GetScreen()->m_Curseur.x;
  456. CurrentPin->m_Pos.y = -GetScreen()->m_Curseur.y;
  457. CurrentPin->m_PinLen = LastPinSize;
  458. CurrentPin->m_Orient = LastPinOrient;
  459. CurrentPin->m_PinType = LastPinType;
  460. CurrentPin->m_PinShape = LastPinShape;
  461. CurrentPin->m_PinNameSize = LastPinNameSize;
  462. CurrentPin->m_PinNumSize = LastPinNumSize;
  463. if( LastPinCommonConvert )
  464. CurrentPin->m_Convert = 0;
  465. else
  466. CurrentPin->m_Convert = m_convert;
  467. if( LastPinCommonUnit )
  468. CurrentPin->m_Unit = 0;
  469. else
  470. CurrentPin->m_Unit = m_unit;
  471. if( LastPinNoDraw )
  472. CurrentPin->m_Attributs |= PINNOTDRAW;
  473. else
  474. CurrentPin->m_Attributs &= ~PINNOTDRAW;
  475. if( DC )
  476. CurrentPin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, wxCOPY,
  477. &showPinText, DefaultTransformMatrix );
  478. PinPreviousPos = CurrentPin->m_Pos;
  479. wxLogDebug( _( "Initial pin position (%d, %d)" ),
  480. PinPreviousPos.x, PinPreviousPos.y );
  481. DrawPanel->m_IgnoreMouseEvents = true;
  482. InstallPineditFrame( this, DC, wxPoint( -1, -1 ) );
  483. DrawPanel->MouseToCursorSchema();
  484. DrawPanel->m_IgnoreMouseEvents = false;
  485. DrawPanel->ManageCurseur = DrawMovePin;
  486. DrawPanel->ForceCloseManageCurseur = AbortPinMove;
  487. CurrentPin->DisplayInfo( this );
  488. GetScreen()->SetModify();
  489. }
  490. /* si draw == true
  491. * - Ajuste le flag visible / invisible (.U.Pin.Flags bit 0 ) de la pin
  492. * editee
  493. *
  494. * si unit == true
  495. * - Modifie l'attribut Commun / Particulier U.Pin.Unit = 0 ou Num Unite
  496. * de la pin editee
  497. *
  498. * si convert == true
  499. * - Modifie l'attribut Commun / Particulier U.Pin.Convert = 0 ou Num Unite
  500. * de la pin editee
  501. *
  502. */
  503. void WinEDA_PinPropertiesFrame::SetPinAttributes( bool draw, bool unit,
  504. bool convert )
  505. {
  506. LIB_PIN* tmp;
  507. LIB_PIN* Pin;
  508. LIB_PIN* CurrentPin = (LIB_PIN*) m_Parent->GetDrawItem();
  509. if( CurrentPin == NULL )
  510. return;
  511. m_Parent->GetScreen()->SetModify();
  512. if( unit )
  513. {
  514. if( LastPinCommonUnit )
  515. CurrentPin->m_Unit = 0;
  516. else
  517. CurrentPin->m_Unit = m_Parent->GetUnit();
  518. if( CurrentPin->m_Unit == 0 )
  519. {
  520. tmp = CurrentPin->GetParent()->GetNextPin();
  521. while( tmp != NULL )
  522. {
  523. Pin = tmp;
  524. tmp = CurrentPin->GetParent()->GetNextPin( Pin );
  525. if( Pin->m_Flags == 0 || Pin == CurrentPin )
  526. continue;
  527. if( CurrentPin->m_Convert
  528. && ( CurrentPin->m_Convert != Pin->m_Convert ) )
  529. continue;
  530. if( CurrentPin->m_Pos != Pin->m_Pos )
  531. continue;
  532. if( Pin->m_Orient != CurrentPin->m_Orient )
  533. continue;
  534. CurrentPin->GetParent()->RemoveDrawItem( (LIB_DRAW_ITEM*) Pin );
  535. }
  536. }
  537. } // end if unit
  538. if( convert )
  539. {
  540. if( LastPinCommonConvert )
  541. CurrentPin->m_Convert = 0;
  542. else
  543. CurrentPin->m_Convert = m_Parent->GetConvert();
  544. if( CurrentPin->m_Convert == 0 ) /* Effacement des pins redondantes */
  545. {
  546. tmp = CurrentPin->GetParent()->GetNextPin();
  547. while( tmp != NULL )
  548. {
  549. Pin = tmp;
  550. tmp = CurrentPin->GetParent()->GetNextPin( Pin );
  551. if( Pin->m_Flags == 0 )
  552. continue;
  553. if( Pin == CurrentPin )
  554. continue;
  555. if( CurrentPin->m_Unit && ( CurrentPin->m_Unit != Pin->m_Unit ) )
  556. continue;
  557. if( CurrentPin->m_Pos != Pin->m_Pos )
  558. continue;
  559. if( Pin->m_Orient != CurrentPin->m_Orient )
  560. continue;
  561. CurrentPin->GetParent()->RemoveDrawItem( (LIB_DRAW_ITEM*) Pin );
  562. }
  563. }
  564. } // end if convert
  565. if( draw )
  566. {
  567. if( LastPinNoDraw )
  568. CurrentPin->m_Attributs |= PINNOTDRAW;
  569. else
  570. CurrentPin->m_Attributs &= ~PINNOTDRAW;
  571. Pin = CurrentPin->GetParent()->GetNextPin();
  572. for( ; Pin != NULL; Pin = CurrentPin->GetParent()->GetNextPin( Pin ) )
  573. {
  574. if( Pin->m_Flags == 0 )
  575. continue;
  576. if( LastPinNoDraw )
  577. Pin->m_Attributs |= PINNOTDRAW;
  578. else
  579. Pin->m_Attributs &= ~PINNOTDRAW;
  580. }
  581. }
  582. }
  583. /******************************************************/
  584. void WinEDA_PinPropertiesFrame::NewSizePin( int newsize )
  585. /******************************************************/
  586. /* Fonction permettant la mise aux dimensions courantes:
  587. * - longueur, dimension des textes
  588. * de la pin courante
  589. *
  590. */
  591. {
  592. LIB_PIN* RefPin, * Pin = (LIB_PIN*) m_Parent->GetDrawItem();
  593. if( Pin == NULL || Pin->GetParent() == NULL )
  594. return;
  595. m_Parent->GetScreen()->SetModify();
  596. Pin->m_PinLen = newsize;
  597. Pin->DisplayInfo( m_Parent );
  598. RefPin = Pin;
  599. if( g_EditPinByPinIsOn == false )
  600. {
  601. Pin = Pin->GetParent()->GetNextPin();
  602. for( ; Pin != NULL; Pin = Pin->GetParent()->GetNextPin( Pin ) )
  603. {
  604. if( Pin->m_Pos != RefPin->m_Pos )
  605. continue;
  606. if( Pin->m_Orient != RefPin->m_Orient )
  607. continue;
  608. if( Pin->m_Convert == RefPin->m_Convert )
  609. Pin->m_PinLen = newsize;
  610. }
  611. }
  612. }
  613. static void CreateImagePins( LIB_PIN* Pin, int unit, int convert,
  614. bool asDeMorgan )
  615. {
  616. int ii;
  617. LIB_PIN* NewPin;
  618. bool CreateConv = false;
  619. if( g_EditPinByPinIsOn )
  620. return;
  621. if( asDeMorgan && ( Pin->m_Convert != 0 ) )
  622. CreateConv = true;
  623. /* Creation de la pin " convert " pour la part courante */
  624. if( CreateConv == true )
  625. {
  626. NewPin = (LIB_PIN*) Pin->GenCopy();
  627. if( Pin->m_Convert > 1 )
  628. NewPin->m_Convert = 1;
  629. else
  630. NewPin->m_Convert = 2;
  631. Pin->GetParent()->AddDrawItem( NewPin );
  632. }
  633. for( ii = 1; ii <= Pin->GetParent()->GetPartCount(); ii++ )
  634. {
  635. if( ii == unit || Pin->m_Unit == 0 )
  636. continue; /* Pin commune a toutes les unites */
  637. /* Creation pour la representation "normale" */
  638. NewPin = (LIB_PIN*) Pin->GenCopy();
  639. if( convert != 0 )
  640. NewPin->m_Convert = 1;
  641. NewPin->m_Unit = ii;
  642. Pin->GetParent()->AddDrawItem( NewPin );
  643. /* Creation pour la representation "Convert" */
  644. if( CreateConv == false )
  645. continue;
  646. NewPin = (LIB_PIN*) Pin->GenCopy();
  647. NewPin->m_Convert = 2;
  648. if( Pin->m_Unit != 0 )
  649. NewPin->m_Unit = ii;
  650. Pin->GetParent()->AddDrawItem( NewPin );
  651. }
  652. }
  653. /* Depending on "id":
  654. * - Change pin text size (name or num) (range 10 .. 1000 mil)
  655. * - Change pin lenght.
  656. *
  657. * If Pin is selected ( .m_flag == IS_SELECTED ) only the other selected
  658. * pins are modified
  659. */
  660. void WinEDA_LibeditFrame::GlobalSetPins( wxDC* DC, LIB_PIN* MasterPin, int id )
  661. {
  662. LIB_PIN* Pin;
  663. bool selected = ( MasterPin->m_Selected & IS_SELECTED ) != 0;
  664. bool showPinText = true;
  665. if( ( m_component == NULL ) || ( MasterPin == NULL ) )
  666. return;
  667. if( MasterPin->Type() != COMPONENT_PIN_DRAW_TYPE )
  668. return;
  669. GetScreen()->SetModify();
  670. Pin = m_component->GetNextPin();
  671. for( ; Pin != NULL; Pin = m_component->GetNextPin( Pin ) )
  672. {
  673. if( ( Pin->m_Convert ) && ( Pin->m_Convert != m_convert ) )
  674. continue;
  675. // Is it the "selected mode" ?
  676. if( selected && ( Pin->m_Selected & IS_SELECTED ) == 0 )
  677. continue;
  678. Pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, g_XorMode,
  679. &showPinText, DefaultTransformMatrix );
  680. switch( id )
  681. {
  682. case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNUMSIZE_ITEM:
  683. Pin->m_PinNumSize = MasterPin->m_PinNumSize;
  684. break;
  685. case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINNAMESIZE_ITEM:
  686. Pin->m_PinNameSize = MasterPin->m_PinNameSize;
  687. break;
  688. case ID_POPUP_LIBEDIT_PIN_GLOBAL_CHANGE_PINSIZE_ITEM:
  689. Pin->m_PinLen = MasterPin->m_PinLen;
  690. break;
  691. }
  692. Pin->Draw( DrawPanel, DC, wxPoint( 0, 0 ), -1, GR_DEFAULT_DRAWMODE,
  693. &showPinText, DefaultTransformMatrix );
  694. }
  695. }
  696. /************************************************************************/
  697. void WinEDA_LibeditFrame::RepeatPinItem( wxDC* DC, LIB_PIN* SourcePin )
  698. /************************************************************************/
  699. /* Creation d'une nouvelle pin par copie de la pr�c�dente ( fct REPEAT) */
  700. {
  701. LIB_PIN* Pin;
  702. wxString msg;
  703. int ox = 0, oy = 0;
  704. if( m_component == NULL || SourcePin == NULL
  705. || SourcePin->Type() != COMPONENT_PIN_DRAW_TYPE )
  706. return;
  707. Pin = (LIB_PIN*) SourcePin->GenCopy();
  708. m_component->AddDrawItem( Pin );
  709. Pin->m_Flags = IS_NEW;
  710. Pin->m_Pos.x += g_RepeatStep.x;
  711. ox = Pin->m_Pos.x;
  712. Pin->m_Pos.y += -g_RepeatStep.y;
  713. oy = Pin->m_Pos.y; // ici axe Y comme en math
  714. /*** Increment du numero de label ***/
  715. IncrementLabelMember( Pin->m_PinName );
  716. Pin->ReturnPinStringNum( msg );
  717. IncrementLabelMember( msg );
  718. Pin->SetPinNumFromString( msg );
  719. m_drawItem = Pin;
  720. /* Marquage des pins a traiter */
  721. if( g_EditPinByPinIsOn == false )
  722. Pin->m_Flags |= IS_LINKED;
  723. wxPoint savepos = GetScreen()->m_Curseur;
  724. DrawPanel->CursorOff( DC );
  725. GetScreen()->m_Curseur.x = Pin->m_Pos.x;
  726. GetScreen()->m_Curseur.y = -Pin->m_Pos.y;
  727. PlacePin( DC );
  728. GetScreen()->m_Curseur = savepos;
  729. // DrawPanel->MouseToCursorSchema();
  730. DrawPanel->CursorOn( DC );
  731. Pin->DisplayInfo( this );
  732. GetScreen()->SetModify();
  733. }
  734. /* helper function to sort pins by pin num */
  735. bool sort_by_pin_number( const LIB_PIN* ref, const LIB_PIN* tst )
  736. {
  737. int test = ref->m_PinNum - tst->m_PinNum;
  738. if( test == 0 )
  739. {
  740. test = ref->m_Convert - tst->m_Convert;
  741. }
  742. if( test == 0 )
  743. {
  744. test = ref->m_Unit - tst->m_Unit;
  745. }
  746. return test < 0;
  747. }
  748. /* Test for duplicate pins and off grid pins:
  749. * Pins are considered off grid when they are not on the 25 mils grid
  750. * A grid smaller than 25 mils must be used only to build graphic shapes.
  751. */
  752. void WinEDA_LibeditFrame::OnCheckComponent( wxCommandEvent& event )
  753. {
  754. #define MIN_GRID_SIZE 25
  755. int dup_error;
  756. int offgrid_error;
  757. LIB_PIN* Pin;
  758. wxString msg;
  759. wxString aux_msg;
  760. if( m_component == NULL )
  761. return;
  762. // Build the pin list:
  763. std::vector <LIB_PIN* >PinList;
  764. Pin = m_component->GetNextPin();
  765. for( ; Pin != NULL; Pin = m_component->GetNextPin( Pin ) )
  766. {
  767. if( Pin->Type() == COMPONENT_PIN_DRAW_TYPE )
  768. PinList.push_back( Pin );
  769. }
  770. if( PinList.size() == 0 )
  771. {
  772. DisplayInfoMessage( this, _( "No pins!" ) );
  773. return;
  774. }
  775. // Sort pins by pin num, so 2 duplicate pins
  776. // (pins with the same number) will be consecutive in list
  777. sort( PinList.begin(), PinList.end(), sort_by_pin_number );
  778. // Test for duplicates:
  779. dup_error = 0;
  780. DIALOG_DISPLAY_HTML_TEXT_BASE error_display( this, wxID_ANY, _( "Marker Info" ),
  781. wxDefaultPosition, wxSize( 750, 600 ) );
  782. for( unsigned ii = 1; ii < PinList.size(); ii++ )
  783. {
  784. wxString stringPinNum, stringCurrPinNum;
  785. LIB_PIN* curr_pin = PinList[ii];
  786. Pin = PinList[ii - 1];
  787. if( Pin->m_PinNum != curr_pin->m_PinNum
  788. || Pin->m_Convert != curr_pin->m_Convert
  789. || Pin->m_Unit != curr_pin->m_Unit )
  790. continue;
  791. dup_error++;
  792. Pin->ReturnPinStringNum( stringPinNum );
  793. curr_pin->ReturnPinStringNum( stringCurrPinNum );
  794. msg.Printf( _(
  795. "<b>Duplicate pin %s</b> \"%s\" at location <b>(%.3f, %.3f)</b> conflicts \
  796. with pin %s \"%s\" at location <b>(%.3f, %.3f)</b>" ),
  797. GetChars( stringCurrPinNum ),
  798. GetChars( curr_pin->m_PinName ),
  799. (float) curr_pin->m_Pos.x / 1000.0, (float) -curr_pin->m_Pos.y / 1000.0,
  800. GetChars( stringPinNum ),
  801. GetChars( Pin->m_PinName ),
  802. (float) Pin->m_Pos.x / 1000.0, (float) -Pin->m_Pos.y / 1000.0 );
  803. if( m_component->GetPartCount() > 1 )
  804. {
  805. aux_msg.Printf( _( " in part %c" ), 'A' + curr_pin->m_Unit );
  806. msg += aux_msg;
  807. }
  808. if( m_showDeMorgan )
  809. {
  810. if( curr_pin->m_Convert )
  811. msg += _( " of converted" );
  812. else
  813. msg += _( " of normal" );
  814. }
  815. msg += wxT( ".<br>" );
  816. error_display.m_htmlWindow->AppendToPage( msg );
  817. }
  818. // Test for off grid pins:
  819. offgrid_error = 0;
  820. for( unsigned ii = 0; ii < PinList.size(); ii++ )
  821. {
  822. Pin = PinList[ii];
  823. if( ( (Pin->m_Pos.x % MIN_GRID_SIZE) == 0 ) &&
  824. ( (Pin->m_Pos.y % MIN_GRID_SIZE) == 0 ) )
  825. continue;
  826. // A pin is foun here off grid
  827. offgrid_error++;
  828. wxString stringPinNum;
  829. Pin->ReturnPinStringNum( stringPinNum );
  830. msg.Printf( _( "<b>Off grid pin %s</b> \"%s\" at location <b>(%.3f, %.3f)</b>" ),
  831. GetChars( stringPinNum ),
  832. GetChars( Pin->m_PinName ),
  833. (float) Pin->m_Pos.x / 1000.0, (float) -Pin->m_Pos.y / 1000.0
  834. );
  835. if( m_component->GetPartCount() > 1 )
  836. {
  837. aux_msg.Printf( _( " in part %c" ), 'A' + Pin->m_Unit );
  838. msg += aux_msg;
  839. }
  840. if( m_showDeMorgan )
  841. {
  842. if( Pin->m_Convert )
  843. msg += _( " of converted" );
  844. else
  845. msg += _( " of normal" );
  846. }
  847. msg += wxT( ".<br>" );
  848. error_display.m_htmlWindow->AppendToPage( msg );
  849. }
  850. if( !dup_error && !offgrid_error )
  851. DisplayInfoMessage( this, _( "No off grid or duplicate pins were found." ) );
  852. else
  853. error_display.ShowModal();
  854. }