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.

1397 lines
44 KiB

  1. /*****************************************************************/
  2. /* Operations sur Blocks : deplacement, rotation, effacement ... */
  3. /*****************************************************************/
  4. #include "fctsys.h"
  5. #include "gr_basic.h"
  6. #include "common.h"
  7. #include "pcbnew.h"
  8. #include "autorout.h"
  9. #include "pcbplot.h"
  10. #include "trigo.h"
  11. #include "protos.h"
  12. #define BLOCK_COLOR BROWN
  13. /* Routines Locales */
  14. static void DrawMovingBlockOutlines(WinEDA_DrawPanel * panel, wxDC * DC, bool erase);
  15. static EDA_BaseStruct * IsStructInBox(DrawBlockStruct &blocklocate, EDA_BaseStruct * PtStruct );
  16. static TRACK * IsSegmentInBox(DrawBlockStruct & blocklocate, TRACK * PtSegm );
  17. static MODULE * IsModuleInBox(DrawBlockStruct& blocklocate, MODULE * Module );
  18. /* Variables locales :*/
  19. static bool Block_Include_Modules = TRUE;
  20. static bool Block_Include_Tracks = TRUE;
  21. static bool Block_Include_Zones = TRUE;
  22. static bool Block_Include_Draw_Items = TRUE;
  23. static bool Block_Include_Edges_Items = TRUE;
  24. static bool Block_Include_PcbTextes = TRUE;
  25. enum id_block_cmd
  26. {
  27. ID_ACCEPT_BLOCK_COMMAND = 8000,
  28. ID_CANCEL_BLOCK_COMMAND
  29. };
  30. /************************************/
  31. /* class WinEDA_ExecBlockCmdFrame */
  32. /************************************/
  33. class WinEDA_ExecBlockCmdFrame: public wxDialog
  34. {
  35. private:
  36. WinEDA_BasePcbFrame * m_Parent;
  37. wxCheckBox * m_Include_Modules;
  38. wxCheckBox * m_Include_Tracks;
  39. wxCheckBox * m_Include_Zones;
  40. wxCheckBox * m_Include_Draw_Items;
  41. wxCheckBox * m_Include_Edges_Items;
  42. wxCheckBox * m_Include_PcbTextes;
  43. public:
  44. // Constructor and destructor
  45. WinEDA_ExecBlockCmdFrame(WinEDA_BasePcbFrame *parent,
  46. const wxString & title);
  47. ~WinEDA_ExecBlockCmdFrame(void)
  48. {
  49. }
  50. private:
  51. void ExecuteCommand(wxCommandEvent& event);
  52. void Cancel(wxCommandEvent& event);
  53. DECLARE_EVENT_TABLE()
  54. };
  55. BEGIN_EVENT_TABLE(WinEDA_ExecBlockCmdFrame, wxDialog)
  56. EVT_BUTTON(ID_ACCEPT_BLOCK_COMMAND, WinEDA_ExecBlockCmdFrame::ExecuteCommand)
  57. EVT_BUTTON(ID_CANCEL_BLOCK_COMMAND, WinEDA_ExecBlockCmdFrame::Cancel)
  58. END_EVENT_TABLE()
  59. /**************************************************************/
  60. static bool InstallBlockCmdFrame(WinEDA_BasePcbFrame * parent,
  61. const wxString & title)
  62. /**************************************************************/
  63. {
  64. int nocmd;
  65. wxPoint oldpos = parent->GetScreen()->m_Curseur;
  66. parent->DrawPanel->m_IgnoreMouseEvents = TRUE;
  67. WinEDA_ExecBlockCmdFrame * frame = new WinEDA_ExecBlockCmdFrame(parent, title);
  68. nocmd = frame->ShowModal(); frame->Destroy();
  69. parent->GetScreen()->m_Curseur = oldpos;
  70. parent->DrawPanel->MouseToCursorSchema();
  71. parent->DrawPanel->m_IgnoreMouseEvents = FALSE;
  72. parent->DrawPanel->SetCursor(parent->DrawPanel->m_PanelCursor = parent->DrawPanel->m_PanelDefaultCursor);
  73. return ( nocmd ? FALSE : TRUE );
  74. }
  75. /******************************************************************************/
  76. WinEDA_ExecBlockCmdFrame::WinEDA_ExecBlockCmdFrame(WinEDA_BasePcbFrame *parent,
  77. const wxString & title):
  78. wxDialog(parent, -1, title, wxPoint(-1,-1), wxSize(280, 220),
  79. DIALOG_STYLE)
  80. /******************************************************************************/
  81. {
  82. wxPoint pos;
  83. wxButton * Button;
  84. m_Parent = parent;
  85. SetFont(*g_DialogFont);
  86. Centre();
  87. /* Creation des boutons de commande */
  88. pos.x = 170; pos.y = 10;
  89. Button = new wxButton(this, ID_ACCEPT_BLOCK_COMMAND,
  90. _("Ok"), pos);
  91. Button->SetForegroundColour(*wxRED);
  92. pos.y += Button->GetDefaultSize().y + 20;
  93. Button = new wxButton(this, ID_CANCEL_BLOCK_COMMAND,
  94. _("Cancel"), pos);
  95. Button->SetForegroundColour(*wxBLUE);
  96. pos.x = 5; pos.y = 20;
  97. // Selection des options :
  98. m_Include_Modules = new wxCheckBox(this, -1, _("Include Modules"), pos);
  99. m_Include_Modules->SetValue(Block_Include_Modules);
  100. pos.y += 20;
  101. m_Include_Tracks = new wxCheckBox(this, -1, _("Include tracks"), pos);
  102. m_Include_Tracks->SetValue(Block_Include_Tracks);
  103. pos.y += 20;
  104. m_Include_Zones = new wxCheckBox(this, -1, _("Include zones"), pos);
  105. m_Include_Zones->SetValue(Block_Include_Zones);
  106. pos.y += 20;
  107. m_Include_PcbTextes = new wxCheckBox(this, -1,
  108. _("Include Text on copper layers"), pos);
  109. m_Include_PcbTextes->SetValue(Block_Include_PcbTextes);
  110. pos.y += 20;
  111. m_Include_Draw_Items = new wxCheckBox(this, -1, _("Include drawings"), pos);
  112. m_Include_Draw_Items->SetValue(Block_Include_Draw_Items);
  113. pos.y += 20;
  114. m_Include_Edges_Items = new wxCheckBox(this, -1, _("Include egde layer"), pos);
  115. m_Include_Edges_Items->SetValue(Block_Include_Edges_Items);
  116. }
  117. /**********************************************************************/
  118. void WinEDA_ExecBlockCmdFrame::Cancel(wxCommandEvent& WXUNUSED(event))
  119. /**********************************************************************/
  120. {
  121. EndModal(1);
  122. }
  123. /*******************************************************************/
  124. void WinEDA_ExecBlockCmdFrame::ExecuteCommand(wxCommandEvent& event)
  125. /*******************************************************************/
  126. {
  127. Block_Include_Modules = m_Include_Modules->GetValue();
  128. Block_Include_Tracks = m_Include_Tracks->GetValue();
  129. Block_Include_Zones = m_Include_Zones->GetValue();
  130. Block_Include_Draw_Items = m_Include_Draw_Items->GetValue();
  131. Block_Include_Edges_Items = m_Include_Edges_Items->GetValue();
  132. Block_Include_PcbTextes = m_Include_PcbTextes->GetValue();
  133. EndModal(0);
  134. }
  135. /*************************************************/
  136. int WinEDA_PcbFrame::ReturnBlockCommand(int key)
  137. /*************************************************/
  138. /* Return the block command (BLOCK_MOVE, BLOCK_COPY...) corresponding to
  139. the key (ALT, SHIFT ALT ..)
  140. */
  141. {
  142. int cmd = 0;
  143. switch ( key )
  144. {
  145. default:
  146. cmd = key & 0x255;
  147. break;
  148. case 0:
  149. cmd = BLOCK_MOVE;
  150. break;
  151. case GR_KB_SHIFT:
  152. cmd = BLOCK_COPY;
  153. break;
  154. case GR_KB_CTRL :
  155. cmd = BLOCK_ROTATE;
  156. break;
  157. case GR_KB_SHIFTCTRL :
  158. cmd = BLOCK_DELETE;
  159. break;
  160. case GR_KB_ALT :
  161. cmd = BLOCK_INVERT;
  162. break;
  163. case MOUSE_MIDDLE:
  164. cmd = BLOCK_ZOOM;
  165. break;
  166. }
  167. return cmd ;
  168. }
  169. /*****************************************************/
  170. void WinEDA_PcbFrame::HandleBlockPlace(wxDC * DC)
  171. /*****************************************************/
  172. /* Routine to handle the BLOCK PLACE commande */
  173. {
  174. bool err = FALSE;
  175. if(DrawPanel->ManageCurseur == NULL)
  176. {
  177. err = TRUE;
  178. DisplayError(this, wxT("Error in HandleBlockPLace : ManageCurseur = NULL") );
  179. }
  180. GetScreen()->BlockLocate.m_State = STATE_BLOCK_STOP;
  181. switch(GetScreen()->BlockLocate.m_Command )
  182. {
  183. case BLOCK_IDLE:
  184. err = TRUE;
  185. break;
  186. case BLOCK_DRAG: /* Drag */
  187. case BLOCK_MOVE: /* Move */
  188. case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
  189. if ( DrawPanel->ManageCurseur )
  190. DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
  191. Block_Move(DC);
  192. GetScreen()->BlockLocate.m_BlockDrawStruct = NULL;
  193. break;
  194. case BLOCK_COPY: /* Copy */
  195. if ( DrawPanel->ManageCurseur )
  196. DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
  197. Block_Duplicate(DC);
  198. GetScreen()->BlockLocate.m_BlockDrawStruct = NULL;
  199. break;
  200. case BLOCK_PASTE:
  201. break;
  202. case BLOCK_ZOOM: // Handled by HandleBlockEnd()
  203. default:
  204. break;
  205. }
  206. GetScreen()->SetModify();
  207. DrawPanel->ManageCurseur = NULL;
  208. DrawPanel->ForceCloseManageCurseur = NULL;
  209. GetScreen()->BlockLocate.m_Flags = 0;
  210. GetScreen()->BlockLocate.m_State = STATE_NO_BLOCK;
  211. GetScreen()->BlockLocate.m_Command = BLOCK_IDLE;
  212. if ( GetScreen()->BlockLocate.m_BlockDrawStruct )
  213. {
  214. DisplayError(this, wxT("Error in HandleBlockPLace DrawStruct != NULL") );
  215. GetScreen()->BlockLocate.m_BlockDrawStruct = NULL;
  216. }
  217. DisplayToolMsg(wxEmptyString);
  218. }
  219. /**********************************************/
  220. int WinEDA_PcbFrame::HandleBlockEnd(wxDC * DC)
  221. /**********************************************/
  222. /* Routine de gestion de la commande BLOCK END
  223. returne :
  224. 0 si aucun compos ant selectionne
  225. 1 sinon
  226. -1 si commande termine et composants trouvs (block delete, block save)
  227. */
  228. {
  229. int endcommande = TRUE;
  230. if(DrawPanel->ManageCurseur )
  231. switch( GetScreen()->BlockLocate.m_Command )
  232. {
  233. case BLOCK_IDLE:
  234. DisplayError(this, wxT("Error in HandleBlockPLace") );
  235. break;
  236. case BLOCK_DRAG: /* Drag (not used, for future enhancements)*/
  237. case BLOCK_MOVE: /* Move */
  238. case BLOCK_COPY: /* Copy */
  239. case BLOCK_PRESELECT_MOVE: /* Move with preselection list*/
  240. GetScreen()->BlockLocate.m_State = STATE_BLOCK_MOVE;
  241. endcommande = FALSE;
  242. DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
  243. DrawPanel->ManageCurseur = DrawMovingBlockOutlines;
  244. DrawPanel->ManageCurseur(DrawPanel, DC, FALSE);
  245. break;
  246. case BLOCK_DELETE: /* Delete */
  247. // Turn off the block rectangle now so it is not redisplayed
  248. DrawPanel->ManageCurseur = NULL;
  249. GetScreen()->BlockLocate.m_State = STATE_BLOCK_STOP;
  250. DrawAndSizingBlockOutlines(DrawPanel, DC, FALSE);
  251. Block_Delete(DC);
  252. break;
  253. case BLOCK_ROTATE: /* Rotation */
  254. // Turn off the block rectangle now so it is not redisplayed
  255. DrawPanel->ManageCurseur = NULL;
  256. GetScreen()->BlockLocate.m_State = STATE_BLOCK_STOP;
  257. DrawAndSizingBlockOutlines(DrawPanel, DC, FALSE);
  258. Block_Rotate(DC);
  259. break;
  260. case BLOCK_INVERT: /* Flip */
  261. // Turn off the block rectangle now so it is not redisplayed
  262. DrawPanel->ManageCurseur = NULL;
  263. GetScreen()->BlockLocate.m_State = STATE_BLOCK_STOP;
  264. DrawAndSizingBlockOutlines(DrawPanel, DC, FALSE);
  265. Block_Invert(DC);
  266. break;
  267. case BLOCK_SAVE: /* Save (not used, for future enhancements)*/
  268. GetScreen()->BlockLocate.m_State = STATE_BLOCK_STOP;
  269. if( GetScreen()->BlockLocate.m_BlockDrawStruct != NULL)
  270. {
  271. DrawAndSizingBlockOutlines(DrawPanel, DC, FALSE);
  272. // SaveStruct(GetScreen()->BlockLocate.m_BlockDrawStruct);
  273. }
  274. break;
  275. case BLOCK_PASTE: break;
  276. case BLOCK_ZOOM: /* Window Zoom */
  277. //Turn off the redraw block routine now so it is not displayed
  278. // with one corner at the new center of the screen
  279. DrawPanel->ManageCurseur = NULL;
  280. Window_Zoom( GetScreen()->BlockLocate );
  281. break;
  282. default:
  283. break;
  284. }
  285. if ( endcommande == TRUE )
  286. {
  287. GetScreen()->BlockLocate.m_Flags = 0;
  288. GetScreen()->BlockLocate.m_State = STATE_NO_BLOCK;
  289. GetScreen()->BlockLocate.m_Command = BLOCK_IDLE;
  290. GetScreen()->BlockLocate.m_BlockDrawStruct = NULL;
  291. DrawPanel->ManageCurseur = NULL;
  292. DrawPanel->ForceCloseManageCurseur = NULL;
  293. DisplayToolMsg(wxEmptyString);
  294. }
  295. return(endcommande);
  296. }
  297. /**************************************************************************/
  298. static void DrawMovingBlockOutlines(WinEDA_DrawPanel * panel, wxDC * DC, bool erase)
  299. /**************************************************************************/
  300. /* Retrace le contour du block de repositionnement des structures a d�placer
  301. */
  302. {
  303. int Color;
  304. BASE_SCREEN * screen = panel->GetScreen();
  305. Color = YELLOW; GRSetDrawMode(DC, g_XorMode);
  306. /* Effacement ancien cadre */
  307. if( erase )
  308. {
  309. screen->BlockLocate.Draw(panel, DC);
  310. if ( screen->BlockLocate.m_MoveVector.x || screen->BlockLocate.m_MoveVector.y )
  311. {
  312. screen->BlockLocate.Offset(screen->BlockLocate.m_MoveVector);
  313. screen->BlockLocate.Draw(panel, DC);
  314. screen->BlockLocate.Offset(-screen->BlockLocate.m_MoveVector.x, -screen->BlockLocate.m_MoveVector.y);
  315. }
  316. }
  317. if ( panel->m_Parent->GetScreen()->BlockLocate.m_State != STATE_BLOCK_STOP )
  318. {
  319. screen->BlockLocate.m_MoveVector.x = screen->m_Curseur.x - screen->BlockLocate.GetRight();
  320. screen->BlockLocate.m_MoveVector.y = screen->m_Curseur.y - screen->BlockLocate.GetBottom();
  321. }
  322. screen->BlockLocate.Draw(panel, DC);
  323. if ( screen->BlockLocate.m_MoveVector.x || screen->BlockLocate.m_MoveVector.y )
  324. {
  325. screen->BlockLocate.Offset(screen->BlockLocate.m_MoveVector);
  326. screen->BlockLocate.Draw(panel, DC);
  327. screen->BlockLocate.Offset(-screen->BlockLocate.m_MoveVector.x, -screen->BlockLocate.m_MoveVector.y);
  328. }
  329. }
  330. /************************************************/
  331. void WinEDA_BasePcbFrame::Block_Delete(wxDC *DC)
  332. /************************************************/
  333. /*
  334. routine d'effacement du block deja selectionne
  335. */
  336. {
  337. EDA_BaseStruct * PtStruct, * NextS;
  338. int masque_layer;
  339. if( ! InstallBlockCmdFrame(this, _("Delete Block")) ) return ;
  340. GetScreen()->SetModify();
  341. GetScreen()->BlockLocate.Normalize();
  342. GetScreen()->m_CurrentItem = NULL;
  343. /* Effacement des modules */
  344. if ( Block_Include_Modules )
  345. {
  346. MODULE * module;
  347. Affiche_Message( _("Delete Footprints") ) ;
  348. module = m_Pcb->m_Modules;
  349. for ( ; module != NULL; module = (MODULE*) NextS)
  350. {
  351. NextS = module->Pnext;
  352. if( IsModuleInBox(GetScreen()->BlockLocate, module) == NULL ) continue;
  353. /* le module est ici bon a etre efface */
  354. module->m_Flags = 0;
  355. module->Draw(DrawPanel, DC, wxPoint(0,0),GR_XOR) ;
  356. DeleteStructure(module);
  357. m_Pcb->m_Status_Pcb = 0 ;
  358. }
  359. }
  360. /* Effacement des Pistes */
  361. if( Block_Include_Tracks )
  362. {
  363. TRACK * pt_segm;
  364. Affiche_Message( _("Delete tracks" )) ;
  365. for ( pt_segm = m_Pcb->m_Track; pt_segm != NULL; pt_segm = (TRACK*) NextS)
  366. {
  367. NextS = pt_segm->Pnext;
  368. if( IsSegmentInBox(GetScreen()->BlockLocate, pt_segm ) )
  369. { /* la piste est ici bonne a etre efface */
  370. pt_segm->Draw(DrawPanel, DC, GR_XOR) ;
  371. DeleteStructure(pt_segm);
  372. }
  373. }
  374. }
  375. /* Effacement des Elements De Dessin */
  376. masque_layer = EDGE_LAYER;
  377. if( Block_Include_Draw_Items ) masque_layer = ALL_LAYERS;
  378. if( ! Block_Include_Edges_Items ) masque_layer &= ~EDGE_LAYER;
  379. Affiche_Message( _("Delete draw layers") );
  380. PtStruct = m_Pcb->m_Drawings;
  381. for( ; PtStruct != NULL; PtStruct = NextS )
  382. {
  383. NextS = PtStruct->Pnext;
  384. switch( PtStruct->m_StructType )
  385. {
  386. case TYPEDRAWSEGMENT:
  387. #undef STRUCT
  388. #define STRUCT ((DRAWSEGMENT*)PtStruct)
  389. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  390. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  391. /* l'element est ici bon a etre efface */
  392. Trace_DrawSegmentPcb(DrawPanel, DC, (DRAWSEGMENT*)PtStruct,GR_XOR) ;
  393. DeleteStructure(PtStruct);
  394. break;
  395. case TYPETEXTE:
  396. if( ! Block_Include_PcbTextes ) break;
  397. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  398. /* le texte est ici bon a etre efface */
  399. ((TEXTE_PCB*) PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0), GR_XOR);
  400. /* Suppression du texte en Memoire*/
  401. DeleteStructure(PtStruct);
  402. break;
  403. case TYPEMIRE:
  404. #undef STRUCT
  405. #define STRUCT ((MIREPCB*) PtStruct)
  406. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  407. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  408. /* l'element est ici bon a etre efface */
  409. ((MIREPCB*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0),GR_XOR) ;
  410. DeleteStructure(PtStruct);
  411. break;
  412. case TYPECOTATION:
  413. #undef STRUCT
  414. #define STRUCT ((COTATION*) PtStruct)
  415. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  416. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  417. /* l'element est ici bon a etre efface */
  418. ((COTATION*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0),GR_XOR) ;
  419. DeleteStructure(PtStruct);
  420. break;
  421. default: break;
  422. }
  423. }
  424. /* Effacement des Zones */
  425. if(Block_Include_Zones)
  426. {
  427. TRACK * pt_segm;
  428. Affiche_Message( _("Delete zones") );
  429. for ( pt_segm = m_Pcb->m_Zone; pt_segm != NULL; pt_segm = (TRACK*) NextS)
  430. {
  431. NextS = pt_segm->Pnext;
  432. if( IsSegmentInBox(GetScreen()->BlockLocate, pt_segm ) )
  433. {/* la piste est ici bonne a etre efface */
  434. pt_segm->Draw(DrawPanel, DC, GR_XOR) ;
  435. DeleteStructure(pt_segm);
  436. }
  437. }
  438. }
  439. /* Rafraichissement de l'ecran : */
  440. RedrawActiveWindow(DC, TRUE);
  441. }
  442. /****************************************************/
  443. void WinEDA_BasePcbFrame::Block_Rotate(wxDC *DC)
  444. /****************************************************/
  445. /*
  446. routine de Rotation de 90 deg du block deja selectionne
  447. les elements sont tournes autour du centre du block
  448. */
  449. {
  450. MODULE * module;
  451. EDA_BaseStruct * PtStruct;
  452. int masque_layer;
  453. wxPoint oldpos;
  454. int Nx, Ny, centerX, centerY; /* centre de rotation de l'ensemble des elements */
  455. if( ! InstallBlockCmdFrame(this, _("Rotate Block") ) ) return ;
  456. oldpos = GetScreen()->m_Curseur;
  457. GetScreen()->BlockLocate.Normalize();
  458. /* calcul du centre de Rotation */
  459. centerX = GetScreen()->BlockLocate.Centre().x;
  460. centerY = GetScreen()->BlockLocate.Centre().y;
  461. GetScreen()->SetModify();
  462. /* Rotation des modules */
  463. if ( Block_Include_Modules )
  464. {
  465. Affiche_Message( _("Footprint rotation") );
  466. int Angle_Rot_Module = 900;
  467. module = m_Pcb->m_Modules;
  468. for ( ; module != NULL; module = (MODULE*) module->Pnext)
  469. {
  470. if( IsModuleInBox(GetScreen()->BlockLocate, module) == NULL ) continue;
  471. /* le module est ici bon a etre modifie */
  472. m_Pcb->m_Status_Pcb = 0 ;
  473. module->m_Flags = 0;
  474. module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ;
  475. /* calcul de la nouvelle position du Module */
  476. Nx = module->m_Pos.x; Ny = module->m_Pos.y;
  477. RotatePoint(&Nx, &Ny, centerX, centerY, 900 );
  478. GetScreen()->m_Curseur.x = Nx ;
  479. GetScreen()->m_Curseur.y = Ny ;
  480. Place_Module(module, DC);
  481. /* Rotation du module autour de son ancre */
  482. Rotate_Module(DC, module, Angle_Rot_Module, TRUE);
  483. }
  484. /* regeneration des valeurs originelles */
  485. GetScreen()->m_Curseur = oldpos;
  486. }
  487. /* Deplacement des Segments de piste */
  488. if(Block_Include_Tracks )
  489. {
  490. TRACK * track;
  491. Affiche_Message( _("Track rotation") );
  492. track = m_Pcb->m_Track;
  493. while( track )
  494. {
  495. if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
  496. { /* la piste est ici bonne a etre deplacee */
  497. m_Pcb->m_Status_Pcb = 0 ;
  498. track->Draw(DrawPanel, DC, GR_XOR) ; // effacement
  499. RotatePoint( &track->m_Start.x, &track->m_Start.y, centerX, centerY, 900);
  500. RotatePoint( &track->m_End.x, &track->m_End.y, centerX, centerY, 900);
  501. track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
  502. }
  503. track = track->Next();
  504. }
  505. }
  506. /* Deplacement des Segments de Zone */
  507. if( Block_Include_Zones )
  508. {
  509. TRACK * track;
  510. Affiche_Message( _("Zone rotation") );
  511. track = (TRACK*) m_Pcb->m_Zone;
  512. while( track )
  513. {
  514. if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
  515. { /* la piste est ici bonne a etre deplacee */
  516. track->Draw(DrawPanel, DC, GR_XOR) ; // effacement
  517. RotatePoint( &track->m_Start.x, &track->m_Start.y, centerX, centerY, 900);
  518. RotatePoint( &track->m_End.x, &track->m_End.y, centerX, centerY, 900);
  519. track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
  520. }
  521. track = track->Next();
  522. }
  523. }
  524. masque_layer = EDGE_LAYER;
  525. if( Block_Include_Draw_Items ) masque_layer = ALL_LAYERS;
  526. if( ! Block_Include_Edges_Items ) masque_layer &= ~EDGE_LAYER;
  527. Affiche_Message( _("Draw layers rotation") );
  528. PtStruct = m_Pcb->m_Drawings;
  529. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  530. {
  531. switch( PtStruct->m_StructType )
  532. {
  533. case TYPEDRAWSEGMENT:
  534. #undef STRUCT
  535. #define STRUCT ((DRAWSEGMENT*)PtStruct)
  536. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  537. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  538. /* l'element est ici bon a etre efface */
  539. Trace_DrawSegmentPcb(DrawPanel, DC, (DRAWSEGMENT*)PtStruct,GR_XOR) ;
  540. RotatePoint( &STRUCT->m_Start.x, &STRUCT->m_Start.y, centerX, centerY, 900);
  541. RotatePoint( &STRUCT->m_End.x, &STRUCT->m_End.y, centerX, centerY, 900);
  542. Trace_DrawSegmentPcb(DrawPanel, DC, (DRAWSEGMENT*)PtStruct,GR_OR) ;
  543. break;
  544. case TYPETEXTE:
  545. #undef STRUCT
  546. #define STRUCT ((TEXTE_PCB*) PtStruct)
  547. if( ! Block_Include_PcbTextes ) break;
  548. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  549. /* le texte est ici bon a etre deplace */
  550. ((TEXTE_PCB*) PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0), GR_XOR);
  551. /* Redessin du Texte */
  552. RotatePoint( &STRUCT->m_Pos.x, &STRUCT->m_Pos.y, centerX, centerY, 900);
  553. STRUCT->m_Orient += 900;
  554. if( STRUCT->m_Orient >= 3600) STRUCT->m_Orient -= 3600;
  555. STRUCT->CreateDrawData();
  556. ((TEXTE_PCB*) PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0), GR_OR);
  557. break;
  558. case TYPEMIRE:
  559. #undef STRUCT
  560. #define STRUCT ((MIREPCB*) PtStruct)
  561. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  562. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  563. /* l'element est ici bon a etre modifie */
  564. ((MIREPCB*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0),GR_XOR) ;
  565. RotatePoint(&STRUCT->m_Pos.x, &STRUCT->m_Pos.y, centerX, centerY, 900 );
  566. ((MIREPCB*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0),GR_OR) ;
  567. break;
  568. case TYPECOTATION:
  569. #undef STRUCT
  570. #define STRUCT ((COTATION*) PtStruct)
  571. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  572. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  573. /* l'element est ici bon a etre modifie */
  574. ((COTATION*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0),GR_XOR) ;
  575. RotatePoint(&STRUCT->m_Pos.x, &STRUCT->m_Pos.y, centerX, centerY, 900 );
  576. RotatePoint(&STRUCT->m_Text->m_Pos.x, &STRUCT->m_Text->m_Pos.y,
  577. centerX, centerY, 900 );
  578. STRUCT->m_Text->m_Orient += 900;
  579. if( STRUCT->m_Text->m_Orient >= 3600 )
  580. STRUCT->m_Text->m_Orient -= 3600;
  581. if( (STRUCT->m_Text->m_Orient > 900) &&
  582. (STRUCT->m_Text->m_Orient <2700) )
  583. STRUCT->m_Text->m_Orient -= 1800;
  584. RotatePoint(&STRUCT->Barre_ox, &STRUCT->Barre_oy, centerX, centerY, 900 );
  585. RotatePoint(&STRUCT->Barre_fx, &STRUCT->Barre_fy, centerX, centerY, 900 );
  586. RotatePoint(&STRUCT->TraitG_ox, &STRUCT->TraitG_oy, centerX, centerY, 900 );
  587. RotatePoint(&STRUCT->TraitG_fx, &STRUCT->TraitG_fy, centerX, centerY, 900 );
  588. RotatePoint(&STRUCT->TraitD_ox, &STRUCT->TraitD_oy, centerX, centerY, 900 );
  589. RotatePoint(&STRUCT->TraitD_fx, &STRUCT->TraitD_fy, centerX, centerY, 900 );
  590. RotatePoint(&STRUCT->FlecheG1_ox, &STRUCT->FlecheG1_oy, centerX, centerY, 900 );
  591. RotatePoint(&STRUCT->FlecheG1_fx, &STRUCT->FlecheG1_fy, centerX, centerY, 900 );
  592. RotatePoint(&STRUCT->FlecheG2_ox, &STRUCT->FlecheG2_oy, centerX, centerY, 900 );
  593. RotatePoint(&STRUCT->FlecheG2_fx, &STRUCT->FlecheG2_fy, centerX, centerY, 900 );
  594. RotatePoint(&STRUCT->FlecheD1_ox, &STRUCT->FlecheD1_oy, centerX, centerY, 900 );
  595. RotatePoint(&STRUCT->FlecheD1_fx, &STRUCT->FlecheD1_fy, centerX, centerY, 900 );
  596. RotatePoint(&STRUCT->FlecheD2_ox, &STRUCT->FlecheD2_oy, centerX, centerY, 900 );
  597. RotatePoint(&STRUCT->FlecheD2_fx, &STRUCT->FlecheD2_fy, centerX, centerY, 900 );
  598. ((COTATION*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0),GR_OR) ;
  599. break;
  600. default: break;
  601. }
  602. }
  603. RedrawActiveWindow(DC, TRUE) ;
  604. }
  605. /*****************************************************/
  606. void WinEDA_BasePcbFrame::Block_Invert(wxDC * DC)
  607. /*****************************************************/
  608. /*
  609. routine d'inversion miroir deg du block deja selectionne
  610. les elements sont inverse / axe horizontal,
  611. l'axe d'inversion est la mediane horizontale du block
  612. */
  613. #define INVERT(pos) (pos) = centerY - ((pos) - centerY)
  614. #define INVERT_ANGLE(phi) (phi) = -(phi)
  615. {
  616. MODULE * module;
  617. EDA_BaseStruct * PtStruct;
  618. int masque_layer;
  619. wxPoint memo;
  620. int Ny, centerY; /* position de l'axe d'inversion de l'ensemble des elements */
  621. if( ! InstallBlockCmdFrame(this, _("Block mirroring")) ) return ;
  622. memo = GetScreen()->m_Curseur;
  623. GetScreen()->BlockLocate.Normalize();
  624. /* calcul du centre d'inversion */
  625. centerY = GetScreen()->BlockLocate.Centre().y;
  626. GetScreen()->SetModify();
  627. /* Inversion des modules */
  628. if ( Block_Include_Modules )
  629. {
  630. Affiche_Message( _("Footprint mirroring") );
  631. module = m_Pcb->m_Modules;
  632. for ( ; module != NULL; module = (MODULE*) module->Pnext)
  633. {
  634. if( IsModuleInBox(GetScreen()->BlockLocate, module) == NULL ) continue;
  635. /* le module est ici bon a etre efface */
  636. m_Pcb->m_Status_Pcb = 0 ;
  637. module->m_Flags = 0;
  638. module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ;
  639. /* calcul de la nouvelle position du Module */
  640. Ny = module->m_Pos.y;
  641. INVERT(Ny);
  642. GetScreen()->m_Curseur.x = module->m_Pos.x;
  643. GetScreen()->m_Curseur.y = Ny ;
  644. Place_Module(module, DC);
  645. /* inversion du module */
  646. Change_Side_Module(module, DC);
  647. /* regeneration des valeurs originelles */
  648. GetScreen()->m_Curseur = memo;
  649. }
  650. }
  651. /* Deplacement des Segments de piste */
  652. if(Block_Include_Tracks )
  653. {
  654. TRACK * track;
  655. Affiche_Message( _("Track mirroring") );
  656. track = m_Pcb->m_Track;
  657. while( track )
  658. {
  659. if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
  660. { /* la piste est ici bonne a etre deplacee */
  661. m_Pcb->m_Status_Pcb = 0 ;
  662. track->Draw(DrawPanel, DC, GR_XOR) ; // effacement
  663. INVERT(track->m_Start.y);
  664. INVERT(track->m_End.y);
  665. if( track->m_StructType != TYPEVIA )
  666. {
  667. track->m_Layer = ChangeSideNumLayer(track->m_Layer);
  668. }
  669. track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
  670. }
  671. track = (TRACK*) track->Pnext;
  672. }
  673. }
  674. /* Deplacement des Segments de Zone */
  675. if( Block_Include_Zones )
  676. {
  677. TRACK * track;
  678. Affiche_Message( _("Zone mirroring") );
  679. track = (TRACK*)m_Pcb->m_Zone;
  680. while( track )
  681. {
  682. if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
  683. { /* la piste est ici bonne a etre deplacee */
  684. track->Draw(DrawPanel, DC, GR_XOR) ; // effacement
  685. INVERT(track->m_Start.y);
  686. INVERT(track->m_End.y);
  687. track->m_Layer = ChangeSideNumLayer(track->m_Layer);
  688. track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
  689. }
  690. track = (TRACK*) track->Pnext;
  691. }
  692. }
  693. masque_layer = EDGE_LAYER;
  694. if( Block_Include_Draw_Items ) masque_layer = ALL_LAYERS;
  695. if( ! Block_Include_Edges_Items ) masque_layer &= ~EDGE_LAYER;
  696. Affiche_Message( _("Draw layers mirroring") );
  697. PtStruct = m_Pcb->m_Drawings;
  698. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  699. {
  700. switch( PtStruct->m_StructType )
  701. {
  702. case TYPEDRAWSEGMENT:
  703. #undef STRUCT
  704. #define STRUCT ((DRAWSEGMENT*)PtStruct)
  705. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  706. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  707. /* l'element est ici bon a etre selectionne */
  708. Trace_DrawSegmentPcb(DrawPanel, DC, (DRAWSEGMENT*)PtStruct,GR_XOR) ;
  709. if ( STRUCT->m_Shape == S_ARC )
  710. {
  711. INVERT_ANGLE(STRUCT->m_Angle);
  712. }
  713. INVERT(STRUCT->m_Start.y);
  714. INVERT(STRUCT->m_End.y);
  715. STRUCT->m_Layer = ChangeSideNumLayer(STRUCT->m_Layer);
  716. Trace_DrawSegmentPcb(DrawPanel, DC, (DRAWSEGMENT*)PtStruct,GR_OR) ;
  717. break;
  718. case TYPETEXTE:
  719. #undef STRUCT
  720. #define STRUCT ((TEXTE_PCB*) PtStruct)
  721. if( ! Block_Include_PcbTextes ) break;
  722. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  723. /* le texte est ici bon a etre selectionne*/
  724. ((TEXTE_PCB*) PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0), GR_XOR);
  725. /* Redessin du Texte */
  726. INVERT(STRUCT->m_Pos.y);
  727. INVERT_ANGLE(STRUCT->m_Orient);
  728. if( (STRUCT->m_Layer == CUIVRE_N) || (STRUCT->m_Layer == CMP_N) )
  729. {
  730. STRUCT->m_Miroir ^= 1; /* inverse miroir */
  731. }
  732. STRUCT->m_Layer = ChangeSideNumLayer(STRUCT->m_Layer);
  733. STRUCT->CreateDrawData();
  734. ((TEXTE_PCB*) PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0), GR_OR);
  735. break;
  736. case TYPEMIRE:
  737. #undef STRUCT
  738. #define STRUCT ((MIREPCB*) PtStruct)
  739. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  740. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  741. /* l'element est ici bon a etre modifie */
  742. ((MIREPCB*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0),GR_XOR) ;
  743. INVERT(STRUCT->m_Pos.y);
  744. STRUCT->m_Layer = ChangeSideNumLayer(STRUCT->m_Layer);
  745. ((MIREPCB*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0),GR_OR) ;
  746. break;
  747. case TYPECOTATION:
  748. #undef STRUCT
  749. #define STRUCT ((COTATION*) PtStruct)
  750. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  751. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  752. /* l'element est ici bon a etre modifie */
  753. ((COTATION*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0),GR_XOR) ;
  754. INVERT(STRUCT->m_Pos.y);
  755. INVERT(STRUCT->m_Text->m_Pos.y);
  756. INVERT_ANGLE(STRUCT->m_Text->m_Orient);
  757. if( STRUCT->m_Text->m_Orient >= 3600 )
  758. STRUCT->m_Text->m_Orient -= 3600;
  759. if( (STRUCT->m_Text->m_Orient > 900) &&
  760. (STRUCT->m_Text->m_Orient <2700) )
  761. STRUCT->m_Text->m_Orient -= 1800;
  762. INVERT(STRUCT->Barre_oy);
  763. INVERT(STRUCT->Barre_fy);
  764. INVERT(STRUCT->TraitG_oy);
  765. INVERT(STRUCT->TraitG_fy);
  766. INVERT(STRUCT->TraitD_oy);
  767. INVERT(STRUCT->TraitD_fy);
  768. INVERT(STRUCT->FlecheG1_oy);
  769. INVERT(STRUCT->FlecheG1_fy);
  770. INVERT(STRUCT->FlecheG2_oy);
  771. INVERT(STRUCT->FlecheG2_fy);
  772. INVERT(STRUCT->FlecheD1_oy);
  773. INVERT(STRUCT->FlecheD1_fy);
  774. INVERT(STRUCT->FlecheD2_oy);
  775. INVERT(STRUCT->FlecheD2_fy);
  776. STRUCT->m_Layer = ChangeSideNumLayer(STRUCT->m_Layer);
  777. ((COTATION*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ;
  778. break;
  779. default: break;
  780. }
  781. }
  782. RedrawActiveWindow(DC, TRUE) ;
  783. }
  784. /************************************************/
  785. void WinEDA_BasePcbFrame::Block_Move(wxDC * DC)
  786. /************************************************/
  787. /*
  788. routine de deplacement des elements du block deja selectionne
  789. */
  790. {
  791. MODULE * module;
  792. EDA_BaseStruct * PtStruct;
  793. int masque_layer;
  794. int deltaX, deltaY;
  795. wxPoint oldpos;
  796. oldpos = GetScreen()->m_Curseur;
  797. DrawPanel->ManageCurseur = NULL;
  798. if( ! InstallBlockCmdFrame(this, _("Move Block") ) ) return ;
  799. GetScreen()->m_Curseur = oldpos;
  800. DrawPanel->MouseToCursorSchema();
  801. GetScreen()->SetModify();
  802. GetScreen()->BlockLocate.Normalize();
  803. /* Deplacement des modules */
  804. if ( Block_Include_Modules )
  805. {
  806. Affiche_Message( _("Move footprints") );
  807. module = m_Pcb->m_Modules;
  808. oldpos = GetScreen()->m_Curseur;
  809. for ( ; module != NULL; module = (MODULE*) module->Pnext)
  810. {
  811. if( IsModuleInBox(GetScreen()->BlockLocate, module) == NULL ) continue;
  812. /* le module est ici bon a etre deplace */
  813. m_Pcb->m_Status_Pcb = 0 ;
  814. module->m_Flags = 0;
  815. module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR) ;
  816. /* calcul du deplacement pour la routine Place_Module */
  817. /* calcul du vecteur de deplacement */
  818. GetScreen()->m_Curseur.x = module->m_Pos.x + GetScreen()->BlockLocate.m_MoveVector.x;
  819. GetScreen()->m_Curseur.y = module->m_Pos.y + GetScreen()->BlockLocate.m_MoveVector.y;
  820. Place_Module(module, DC);
  821. }
  822. GetScreen()->m_Curseur = oldpos;
  823. }
  824. /* calcul du vecteur de deplacement pour les deplacements suivants */
  825. deltaX = GetScreen()->BlockLocate.m_MoveVector.x ;
  826. deltaY = GetScreen()->BlockLocate.m_MoveVector.y ;
  827. /* Deplacement des Segments de piste */
  828. if(Block_Include_Tracks )
  829. {
  830. TRACK * track;
  831. Affiche_Message( _("Move tracks") );
  832. track = m_Pcb->m_Track;
  833. while( track )
  834. {
  835. if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
  836. { /* la piste est ici bonne a etre deplacee */
  837. m_Pcb->m_Status_Pcb = 0 ;
  838. track->Draw(DrawPanel, DC, GR_XOR) ; // effacement
  839. track->m_Start.x += deltaX ; track->m_Start.y += deltaY ;
  840. track->m_End.x += deltaX ; track->m_End.y += deltaY ;
  841. track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
  842. }
  843. track = (TRACK*) track->Pnext;
  844. }
  845. }
  846. /* Deplacement des Segments de Zone */
  847. if( Block_Include_Zones )
  848. {
  849. TRACK * track;
  850. Affiche_Message( _("Move zones") );
  851. track = (TRACK*)m_Pcb->m_Zone;
  852. while( track )
  853. {
  854. if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
  855. { /* la piste est ici bonne a etre deplacee */
  856. track->Draw(DrawPanel, DC, GR_XOR) ; // effacement
  857. track->m_Start.x += deltaX ; track->m_Start.y += deltaY ;
  858. track->m_End.x += deltaX ; track->m_End.y += deltaY ;
  859. track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
  860. }
  861. track = (TRACK*) track->Pnext;
  862. }
  863. }
  864. masque_layer = EDGE_LAYER;
  865. if( Block_Include_Draw_Items ) masque_layer = ALL_LAYERS;
  866. if( ! Block_Include_Edges_Items ) masque_layer &= ~EDGE_LAYER;
  867. Affiche_Message( _("Move draw layers") );
  868. PtStruct = m_Pcb->m_Drawings;
  869. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  870. {
  871. switch( PtStruct->m_StructType )
  872. {
  873. case TYPEDRAWSEGMENT:
  874. #undef STRUCT
  875. #define STRUCT ((DRAWSEGMENT*)PtStruct)
  876. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  877. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  878. /* l'element est ici bon a etre efface */
  879. Trace_DrawSegmentPcb(DrawPanel, DC, STRUCT,GR_XOR) ;
  880. STRUCT->m_Start.x += deltaX; STRUCT->m_Start.y += deltaY;
  881. STRUCT->m_End.x += deltaX; STRUCT->m_End.y += deltaY;
  882. Trace_DrawSegmentPcb(DrawPanel, DC, STRUCT,GR_OR) ;
  883. break;
  884. case TYPETEXTE:
  885. #undef STRUCT
  886. #define STRUCT ((TEXTE_PCB*) PtStruct)
  887. if( ! Block_Include_PcbTextes ) break;
  888. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  889. /* le texte est ici bon a etre deplace */
  890. STRUCT->Draw(DrawPanel, DC, wxPoint(0, 0), GR_XOR);
  891. /* Redessin du Texte */
  892. STRUCT->m_Pos.x += deltaX; STRUCT->m_Pos.y += deltaY;
  893. ((TEXTE_PCB*) PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0), GR_OR);
  894. break;
  895. case TYPEMIRE:
  896. #undef STRUCT
  897. #define STRUCT ((MIREPCB*) PtStruct)
  898. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  899. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  900. /* l'element est ici bon a etre efface */
  901. ((MIREPCB*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0),GR_XOR) ;
  902. STRUCT->m_Pos.x += deltaX; STRUCT->m_Pos.y += deltaY;
  903. ((MIREPCB*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0, 0),GR_OR) ;
  904. break;
  905. case TYPECOTATION:
  906. #undef STRUCT
  907. #define STRUCT ((COTATION*) PtStruct)
  908. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  909. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  910. /* l'element est ici bon a etre efface */
  911. ((COTATION*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0),GR_XOR) ;
  912. STRUCT->m_Pos.x += deltaX;
  913. STRUCT->m_Pos.y += deltaY;
  914. STRUCT->m_Text->m_Pos.x += deltaX;
  915. STRUCT->m_Text->m_Pos.y += deltaY;
  916. STRUCT->Barre_ox += deltaX; STRUCT->Barre_oy += deltaY;
  917. STRUCT->Barre_fx += deltaX; STRUCT->Barre_fy += deltaY;
  918. STRUCT->TraitG_ox += deltaX; STRUCT->TraitG_oy += deltaY;
  919. STRUCT->TraitG_fx += deltaX; STRUCT->TraitG_fy += deltaY;
  920. STRUCT->TraitD_ox += deltaX; STRUCT->TraitD_oy += deltaY;
  921. STRUCT->TraitD_fx += deltaX; STRUCT->TraitD_fy += deltaY;
  922. STRUCT->FlecheG1_ox += deltaX; STRUCT->FlecheG1_oy += deltaY;
  923. STRUCT->FlecheG1_fx += deltaX; STRUCT->FlecheG1_fy += deltaY;
  924. STRUCT->FlecheG2_ox += deltaX; STRUCT->FlecheG2_oy += deltaY;
  925. STRUCT->FlecheG2_fx += deltaX; STRUCT->FlecheG2_fy += deltaY;
  926. STRUCT->FlecheD1_ox += deltaX; STRUCT->FlecheD1_oy += deltaY;
  927. STRUCT->FlecheD1_fx += deltaX; STRUCT->FlecheD1_fy += deltaY;
  928. STRUCT->FlecheD2_ox += deltaX; STRUCT->FlecheD2_oy += deltaY;
  929. STRUCT->FlecheD2_fx += deltaX; STRUCT->FlecheD2_fy += deltaY;
  930. ((COTATION*)PtStruct)->Draw(DrawPanel, DC, wxPoint(0,0),GR_OR) ;
  931. break;
  932. default: break;
  933. }
  934. }
  935. DrawPanel->Refresh(TRUE);;
  936. }
  937. /**************************************************/
  938. void WinEDA_BasePcbFrame::Block_Duplicate(wxDC * DC)
  939. /**************************************************/
  940. /*
  941. routine de duplication des elements du block deja selectionne
  942. */
  943. {
  944. MODULE * module;
  945. EDA_BaseStruct * PtStruct;
  946. int masque_layer;
  947. int deltaX, deltaY;
  948. wxPoint oldpos;
  949. oldpos = GetScreen()->m_Curseur;
  950. DrawPanel->ManageCurseur = NULL;
  951. if( ! InstallBlockCmdFrame(this, _("Copy Block") ) ) return ;
  952. GetScreen()->m_Curseur = oldpos;
  953. DrawPanel->MouseToCursorSchema();
  954. GetScreen()->SetModify();
  955. GetScreen()->BlockLocate.Normalize();
  956. /* Module copy */
  957. if ( Block_Include_Modules )
  958. {
  959. Affiche_Message( _("Module copy") );
  960. module = m_Pcb->m_Modules;
  961. oldpos = GetScreen()->m_Curseur;
  962. for ( ; module != NULL; module = (MODULE*) module->Pnext)
  963. {
  964. MODULE * new_module;
  965. if( IsModuleInBox(GetScreen()->BlockLocate, module) == NULL ) continue;
  966. /* le module est ici bon a etre deplace */
  967. m_Pcb->m_Status_Pcb = 0 ;
  968. module->m_Flags = 0;
  969. new_module = new MODULE(m_Pcb);
  970. new_module->Copy(module);
  971. new_module->m_TimeStamp = GetTimeStamp();
  972. new_module->Pnext = m_Pcb->m_Modules;
  973. new_module->Pback = m_Pcb;
  974. m_Pcb->m_Modules->Pback = new_module;
  975. m_Pcb->m_Modules = new_module;
  976. /* calcul du deplacement pour la routine Place_Module */
  977. /* calcul du vecteur de deplacement */
  978. GetScreen()->m_Curseur.x = module->m_Pos.x + GetScreen()->BlockLocate.m_MoveVector.x;
  979. GetScreen()->m_Curseur.y = module->m_Pos.y + GetScreen()->BlockLocate.m_MoveVector.y;
  980. Place_Module(new_module, DC);
  981. }
  982. GetScreen()->m_Curseur = oldpos;
  983. }
  984. /* calcul du vecteur de deplacement pour les deplacements suivants */
  985. deltaX = GetScreen()->BlockLocate.m_MoveVector.x ;
  986. deltaY = GetScreen()->BlockLocate.m_MoveVector.y ;
  987. /* Deplacement des Segments de piste */
  988. if(Block_Include_Tracks )
  989. {
  990. TRACK * track, *next_track, *new_track;
  991. Affiche_Message( _("Track copy") );
  992. track = m_Pcb->m_Track;
  993. while( track )
  994. {
  995. next_track = track->Next();
  996. if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
  997. { /* la piste est ici bonne a etre deplacee */
  998. m_Pcb->m_Status_Pcb = 0 ;
  999. new_track = track->Copy(1);
  1000. new_track->Insert(m_Pcb,NULL);
  1001. new_track->m_Start.x += deltaX ; new_track->m_Start.y += deltaY ;
  1002. new_track->m_End.x += deltaX ; new_track->m_End.y += deltaY ;
  1003. new_track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
  1004. }
  1005. track = next_track;
  1006. }
  1007. }
  1008. /* Deplacement des Segments de Zone */
  1009. if( Block_Include_Zones )
  1010. {
  1011. TRACK * track, *next_track, *new_track;
  1012. Affiche_Message( _("Zone copy") );
  1013. track = (TRACK*)m_Pcb->m_Zone;
  1014. while( track )
  1015. {
  1016. next_track = track->Next();
  1017. if( IsSegmentInBox(GetScreen()->BlockLocate, track ) )
  1018. { /* la piste est ici bonne a etre deplacee */
  1019. new_track = new TRACK(m_Pcb);
  1020. new_track = track->Copy(1);
  1021. new_track->Insert(m_Pcb,NULL);
  1022. new_track->m_Start.x += deltaX ; new_track->m_Start.y += deltaY ;
  1023. new_track->m_End.x += deltaX ; new_track->m_End.y += deltaY ;
  1024. new_track->Draw(DrawPanel, DC, GR_OR) ; // reaffichage
  1025. }
  1026. track = next_track;
  1027. }
  1028. }
  1029. masque_layer = EDGE_LAYER;
  1030. if( Block_Include_Draw_Items ) masque_layer = ALL_LAYERS;
  1031. if( ! Block_Include_Edges_Items ) masque_layer &= ~EDGE_LAYER;
  1032. Affiche_Message( _("Draw layers copy") );
  1033. PtStruct = m_Pcb->m_Drawings;
  1034. for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
  1035. {
  1036. switch( PtStruct->m_StructType )
  1037. {
  1038. case TYPEDRAWSEGMENT:
  1039. {
  1040. #undef STRUCT
  1041. #define STRUCT ((DRAWSEGMENT*)PtStruct)
  1042. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  1043. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  1044. /* l'element est ici bon a etre copie */
  1045. DRAWSEGMENT * new_drawsegment = new DRAWSEGMENT (m_Pcb);
  1046. new_drawsegment->Copy(STRUCT);
  1047. new_drawsegment->Pnext = m_Pcb->m_Drawings;
  1048. new_drawsegment->Pback = m_Pcb;
  1049. m_Pcb->m_Drawings->Pback = new_drawsegment;
  1050. m_Pcb->m_Drawings = new_drawsegment;
  1051. new_drawsegment->m_Start.x += deltaX; new_drawsegment->m_Start.y += deltaY;
  1052. new_drawsegment->m_End.x += deltaX; new_drawsegment->m_End.y += deltaY;
  1053. Trace_DrawSegmentPcb(DrawPanel, DC, new_drawsegment,GR_OR) ;
  1054. break;
  1055. }
  1056. case TYPETEXTE:
  1057. {
  1058. #undef STRUCT
  1059. #define STRUCT ((TEXTE_PCB*) PtStruct)
  1060. if( ! Block_Include_PcbTextes ) break;
  1061. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  1062. /* le texte est ici bon a etre deplace */
  1063. TEXTE_PCB * new_pcbtext = new TEXTE_PCB(m_Pcb);
  1064. new_pcbtext->Copy(STRUCT);
  1065. new_pcbtext->Pnext = m_Pcb->m_Drawings;
  1066. new_pcbtext->Pback = m_Pcb;
  1067. m_Pcb->m_Drawings->Pback = new_pcbtext;
  1068. m_Pcb->m_Drawings = new_pcbtext;
  1069. /* Redessin du Texte */
  1070. new_pcbtext->m_Pos.x += deltaX; new_pcbtext->m_Pos.y += deltaY;
  1071. new_pcbtext->Draw(DrawPanel, DC, wxPoint(0, 0), GR_OR);
  1072. break;
  1073. }
  1074. case TYPEMIRE:
  1075. {
  1076. #undef STRUCT
  1077. #define STRUCT ((MIREPCB*) PtStruct)
  1078. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  1079. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  1080. /* l'element est ici bon a etre efface */
  1081. MIREPCB * new_mire = new MIREPCB(m_Pcb);
  1082. new_mire->Copy(STRUCT);
  1083. new_mire->Pnext = m_Pcb->m_Drawings;
  1084. new_mire->Pback = m_Pcb;
  1085. m_Pcb->m_Drawings->Pback = new_mire;
  1086. m_Pcb->m_Drawings = new_mire;
  1087. new_mire->m_Pos.x += deltaX; new_mire->m_Pos.y += deltaY;
  1088. new_mire->Draw(DrawPanel, DC, wxPoint(0, 0), GR_OR) ;
  1089. break;
  1090. }
  1091. case TYPECOTATION:
  1092. {
  1093. #undef STRUCT
  1094. #define STRUCT ((COTATION*) PtStruct)
  1095. if( (g_TabOneLayerMask[STRUCT->m_Layer] & masque_layer) == 0 ) break;
  1096. if(IsStructInBox(GetScreen()->BlockLocate, PtStruct ) == NULL ) break;
  1097. /* l'element est ici bon a etre copie */
  1098. COTATION * new_cotation = new COTATION(m_Pcb);
  1099. new_cotation->Copy(STRUCT);
  1100. new_cotation->Pnext = m_Pcb->m_Drawings;
  1101. new_cotation->Pback = m_Pcb;
  1102. m_Pcb->m_Drawings->Pback = new_cotation;
  1103. m_Pcb->m_Drawings = new_cotation;
  1104. new_cotation->m_Pos.x += deltaX;
  1105. new_cotation->m_Pos.y += deltaY;
  1106. new_cotation->m_Text->m_Pos.x += deltaX;
  1107. new_cotation->m_Text->m_Pos.y += deltaY;
  1108. new_cotation->Barre_ox += deltaX; new_cotation->Barre_oy += deltaY;
  1109. new_cotation->Barre_fx += deltaX; new_cotation->Barre_fy += deltaY;
  1110. new_cotation->TraitG_ox += deltaX; new_cotation->TraitG_oy += deltaY;
  1111. new_cotation->TraitG_fx += deltaX; new_cotation->TraitG_fy += deltaY;
  1112. new_cotation->TraitD_ox += deltaX; new_cotation->TraitD_oy += deltaY;
  1113. new_cotation->TraitD_fx += deltaX; new_cotation->TraitD_fy += deltaY;
  1114. new_cotation->FlecheG1_ox += deltaX; new_cotation->FlecheG1_oy += deltaY;
  1115. new_cotation->FlecheG1_fx += deltaX; new_cotation->FlecheG1_fy += deltaY;
  1116. new_cotation->FlecheG2_ox += deltaX; new_cotation->FlecheG2_oy += deltaY;
  1117. new_cotation->FlecheG2_fx += deltaX; new_cotation->FlecheG2_fy += deltaY;
  1118. new_cotation->FlecheD1_ox += deltaX; new_cotation->FlecheD1_oy += deltaY;
  1119. new_cotation->FlecheD1_fx += deltaX; new_cotation->FlecheD1_fy += deltaY;
  1120. new_cotation->FlecheD2_ox += deltaX; new_cotation->FlecheD2_oy += deltaY;
  1121. new_cotation->FlecheD2_fx += deltaX; new_cotation->FlecheD2_fy += deltaY;
  1122. new_cotation->Draw(DrawPanel, DC, wxPoint(0,0),GR_OR) ;
  1123. break;
  1124. }
  1125. default: break;
  1126. }
  1127. }
  1128. }
  1129. /*******************************************************************/
  1130. static EDA_BaseStruct * IsStructInBox(DrawBlockStruct & blocklocate,
  1131. EDA_BaseStruct * PtStruct )
  1132. /******************************************************************/
  1133. /* Teste si la structure PtStruct est inscrite dans le block selectionne
  1134. */
  1135. {
  1136. switch ( PtStruct->m_StructType )
  1137. {
  1138. case TYPEDRAWSEGMENT:
  1139. #undef STRUCT
  1140. #define STRUCT ((DRAWSEGMENT*)PtStruct)
  1141. if( ! blocklocate.Inside( STRUCT->m_Start.x, STRUCT->m_Start.y) ) return(NULL);
  1142. if( ! blocklocate.Inside(STRUCT->m_End.x, STRUCT->m_End.y) ) return(NULL);
  1143. return(PtStruct);
  1144. case TYPETEXTE:
  1145. #undef STRUCT
  1146. #define STRUCT ((TEXTE_PCB*) PtStruct)
  1147. if ( ! blocklocate.Inside(STRUCT->m_Pos.x, STRUCT->m_Pos.y) ) return(NULL);
  1148. return(PtStruct);
  1149. case TYPEMIRE:
  1150. #undef STRUCT
  1151. #define STRUCT ((MIREPCB*) PtStruct)
  1152. if( ! blocklocate.Inside( STRUCT->m_Pos.x, STRUCT->m_Pos.y) ) return(NULL);
  1153. return(PtStruct);
  1154. case TYPECOTATION:
  1155. #undef STRUCT
  1156. #define STRUCT ((COTATION*) PtStruct)
  1157. if ( ! blocklocate.Inside( STRUCT->m_Pos.x, STRUCT->m_Pos.y) ) return(NULL);
  1158. return(PtStruct);
  1159. default: return(NULL);
  1160. }
  1161. return(NULL);
  1162. }
  1163. /**************************************************************************/
  1164. static TRACK * IsSegmentInBox( DrawBlockStruct & blocklocate, TRACK * PtSegm )
  1165. /**************************************************************************/
  1166. /* Teste si la structure PtStruct est inscrite dans le block selectionne
  1167. Retourne PtSegm si oui
  1168. NULL si non
  1169. */
  1170. {
  1171. if ( blocklocate.Inside(PtSegm->m_Start.x ,PtSegm->m_Start.y) )
  1172. return ( PtSegm );
  1173. if ( blocklocate.Inside(PtSegm->m_End.x, PtSegm->m_End.y) )
  1174. return ( PtSegm );
  1175. return ( NULL );
  1176. }
  1177. /****************************************************************************/
  1178. static MODULE * IsModuleInBox( DrawBlockStruct& blocklocate, MODULE * Module )
  1179. /****************************************************************************/
  1180. /* Teste si le Module est inscrit dans le block selectionne
  1181. Retourne Module si oui
  1182. NULL si non
  1183. */
  1184. {
  1185. bool is_out_of_box = FALSE;
  1186. Module->SetRectangleExinscrit();
  1187. if ( Module->m_RealBoundaryBox.m_Pos.x < blocklocate.GetX() )
  1188. is_out_of_box = TRUE;
  1189. if ( Module->m_RealBoundaryBox.m_Pos.y < blocklocate.GetY() )
  1190. is_out_of_box = TRUE;
  1191. if ( Module->m_RealBoundaryBox.GetRight() > blocklocate.GetRight() )
  1192. is_out_of_box = TRUE;
  1193. if ( Module->m_RealBoundaryBox.GetBottom() > blocklocate.GetBottom() )
  1194. is_out_of_box = TRUE;
  1195. if (is_out_of_box) return ( NULL );
  1196. return ( Module );
  1197. }