From e7c9ae2b45c3b3ad1b5bd36ae5272771189b9a0d Mon Sep 17 00:00:00 2001 From: charras Date: Sat, 18 Jul 2009 11:44:19 +0000 Subject: [PATCH] First work about net classes. This is a work in progress and a moving target --- CHANGELOG.txt | 7 + common/CMakeLists.txt | 1 + include/id.h | 2 +- include/wxPcbStruct.h | 5 + internat/fr/kicad.mo | Bin 187778 -> 189898 bytes internat/fr/kicad.po | 1053 +++++++++++++---------- pcbnew/CMakeLists.txt | 2 + pcbnew/class_board.cpp | 8 + pcbnew/class_board.h | 16 +- pcbnew/class_netclass.cpp | 298 +++++++ pcbnew/class_netclass.h | 156 ++++ pcbnew/class_netinfo.h | 99 ++- pcbnew/class_netinfo_item.cpp | 19 +- pcbnew/class_netinfolist.cpp | 1 + pcbnew/dialog_design_rules.cpp | 487 +++++++++++ pcbnew/dialog_design_rules.h | 52 ++ pcbnew/dialog_design_rules_base.cpp | 260 ++++++ pcbnew/dialog_design_rules_base.fbp | 1244 +++++++++++++++++++++++++++ pcbnew/dialog_design_rules_base.h | 99 +++ pcbnew/ioascii.cpp | 23 +- pcbnew/menubarpcb.cpp | 8 + pcbnew/onrightclick.cpp | 3 + pcbnew/pcbframe.cpp | 19 + pcbnew/tool_pcb.cpp | 3 - 24 files changed, 3378 insertions(+), 487 deletions(-) create mode 100644 pcbnew/class_netclass.cpp create mode 100644 pcbnew/class_netclass.h create mode 100644 pcbnew/dialog_design_rules.cpp create mode 100644 pcbnew/dialog_design_rules.h create mode 100644 pcbnew/dialog_design_rules_base.cpp create mode 100644 pcbnew/dialog_design_rules_base.fbp create mode 100644 pcbnew/dialog_design_rules_base.h diff --git a/CHANGELOG.txt b/CHANGELOG.txt index f5f1f10073..98ff68f633 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,13 @@ KiCad ChangeLog 2009 Please add newer entries at the top, list the date and your name with email address. +2009-july-18 UPDATE Jean-Pierre Charras +================================================================================ +++pcbnew + First work about net classes. This is a work in progress and a moving target. + Manual routing and DRC do not used yet this feature + + 2009-Jul-13 UPDATE Dick Hollenbeck ================================================================================ ++pcbnew diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e6e62b94ee..43f1c4c747 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -61,6 +61,7 @@ set(PCB_COMMON_SRCS ../pcbnew/class_drawsegment.cpp ../pcbnew/class_drc_item.cpp ../pcbnew/class_edge_mod.cpp + ../pcbnew/class_netclass.cpp ../pcbnew/class_netinfo_item.cpp ../pcbnew/class_netinfolist.cpp ../pcbnew/class_marker.cpp diff --git a/include/id.h b/include/id.h index 88dc0956c9..0b1de929f6 100644 --- a/include/id.h +++ b/include/id.h @@ -728,7 +728,7 @@ enum main_id { ID_PCB_USER_GRID_SETUP, ID_PCB_DISPLAY_FOOTPRINT_DOC, ID_PCB_GEN_BOM_FILE_FROM_BOARD, - ID_PCBUNUSED3, + ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, ID_PCBUNUSED4, ID_PCBUNUSED5, ID_PCBUNUSED6, diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index d1783c87d5..ece9c8c93a 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -431,6 +431,11 @@ public: void Show3D_Frame( wxCommandEvent& event ); void GeneralControle( wxDC* DC, wxPoint Mouse ); + /** function ShowDesignRulesEditor + * Display the Design Rules Editor. + */ + void ShowDesignRulesEditor( wxCommandEvent& event ); + /** * Function UpdateToolbarLayerInfo * updates the currently selected layer in the layer listbox and diff --git a/internat/fr/kicad.mo b/internat/fr/kicad.mo index ebc15325298b10163c493d43a2ed3020b23a2e89..941b95a3e2fecd04b1636aadf9c152d7f42b2361 100644 GIT binary patch delta 61331 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 delta 59478 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 diff --git a/internat/fr/kicad.po b/internat/fr/kicad.po index d8331ef93a..8153fb5ef8 100644 --- a/internat/fr/kicad.po +++ b/internat/fr/kicad.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: kicad\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-07-09 08:02+0100\n" -"PO-Revision-Date: 2009-07-09 08:06+0100\n" +"POT-Creation-Date: 2009-07-17 20:36+0100\n" +"PO-Revision-Date: 2009-07-17 20:53+0100\n" "Last-Translator: \n" "Language-Team: kicad team \n" "MIME-Version: 1.0\n" @@ -25,12 +25,12 @@ msgstr "" #: pcbnew/xchgmod.cpp:172 #, c-format msgid "file %s not found" -msgstr " fichier %s non trouvé" +msgstr "fichier %s non trouvé" #: pcbnew/xchgmod.cpp:186 #, c-format msgid "Unable to create file %s" -msgstr "Impossible de créer fichier <%s>" +msgstr "Impossible de créerle fichier <%s>" #: pcbnew/xchgmod.cpp:291 #, c-format @@ -427,7 +427,7 @@ msgid "Delete module?" msgstr "Effacer Module?" #: pcbnew/editmod.cpp:41 -#: pcbnew/edit.cpp:339 +#: pcbnew/edit.cpp:340 msgid "Module Editor" msgstr "Ouvrir Editeur de modules" @@ -485,7 +485,7 @@ msgid "Place anchor" msgstr "Place Ancre" #: pcbnew/modedit.cpp:439 -#: pcbnew/edit.cpp:772 +#: pcbnew/edit.cpp:773 msgid "Delete item" msgstr "Suppression d'éléments" @@ -897,7 +897,7 @@ msgstr "Grille" msgid "User Grid" msgstr "Grille perso" -#: pcbnew/tool_pcb.cpp:751 +#: pcbnew/tool_pcb.cpp:748 msgid "+/- to switch" msgstr "+/- pour commuter" @@ -934,47 +934,47 @@ msgstr "" "Plan de perçage: trop de diamètres différents pour tracer 1 symbole par diamètre (max 13)\n" "Le tracé utilise des cercles pour quelques valeurs " -#: pcbnew/edit.cpp:418 +#: pcbnew/edit.cpp:419 msgid "Add Tracks" msgstr "Addition de Pistes" -#: pcbnew/edit.cpp:427 +#: pcbnew/edit.cpp:428 msgid "Add Zones" msgstr "Addition de Zones" -#: pcbnew/edit.cpp:429 +#: pcbnew/edit.cpp:430 msgid "Warning: Display Zone is OFF!!!" msgstr "Attention: Affichage zones désactivé !!!" -#: pcbnew/edit.cpp:435 +#: pcbnew/edit.cpp:436 msgid "Add Layer Alignment Target" msgstr "Ajouter Mire de superposition" -#: pcbnew/edit.cpp:439 +#: pcbnew/edit.cpp:440 msgid "Adjust Zero" msgstr "Ajuster Zéro" -#: pcbnew/edit.cpp:445 +#: pcbnew/edit.cpp:446 msgid "Add Graphic" msgstr "Addition éléments graphiques" -#: pcbnew/edit.cpp:449 +#: pcbnew/edit.cpp:450 msgid "Add Text" msgstr "Ajout de Texte" -#: pcbnew/edit.cpp:453 +#: pcbnew/edit.cpp:454 msgid "Add Modules" msgstr "Addition de Modules" -#: pcbnew/edit.cpp:457 +#: pcbnew/edit.cpp:458 msgid "Add Dimension" msgstr "Ajout de cotes" -#: pcbnew/edit.cpp:465 +#: pcbnew/edit.cpp:466 msgid "Net Highlight" msgstr "Surbrillance des équipotentielles" -#: pcbnew/edit.cpp:469 +#: pcbnew/edit.cpp:470 msgid "Local Ratsnest" msgstr "Montrer le chevelu général" @@ -2126,151 +2126,163 @@ msgstr "&Lire Préférences" msgid "Read application preferences" msgstr "Lire les préférences de l'application" -#: pcbnew/menubarpcb.cpp:214 +#: pcbnew/menubarpcb.cpp:211 +msgid "Design Rules" +msgstr "Rrègles de Conception" + +#: pcbnew/menubarpcb.cpp:211 +msgid "Open the design rules dialog editor" +msgstr "Ouvrir la fenêtre de dialogue de l'éditeur de règles de conception" + +#: pcbnew/menubarpcb.cpp:221 msgid "Tracks and Vias" msgstr "Pistes et Vias" -#: pcbnew/menubarpcb.cpp:215 +#: pcbnew/menubarpcb.cpp:222 msgid "Adjust size and width for tracks and vias" msgstr "Ajuster largeur des pistes et diamètre de vias" -#: pcbnew/menubarpcb.cpp:220 +#: pcbnew/menubarpcb.cpp:227 msgid "Adjust User Grid" msgstr "Ajuster Grille utilisateur" -#: pcbnew/menubarpcb.cpp:225 +#: pcbnew/menubarpcb.cpp:232 msgid "Texts and Drawings" msgstr "Textes et Tracés" -#: pcbnew/menubarpcb.cpp:226 +#: pcbnew/menubarpcb.cpp:233 msgid "Adjust width for texts and drawings" msgstr "Ajuster dims pour textes et graphiques" -#: pcbnew/menubarpcb.cpp:231 +#: pcbnew/menubarpcb.cpp:238 msgid "Adjust size,shape,layers... for pads" msgstr "Ajuster taille, forme, couches... pour pads" -#: pcbnew/menubarpcb.cpp:236 +#: pcbnew/menubarpcb.cpp:243 msgid "&Save Setup" msgstr "&Sauver Options" -#: pcbnew/menubarpcb.cpp:237 +#: pcbnew/menubarpcb.cpp:244 msgid "Save options in current directory" msgstr "Sauver les options en répertoire de travail" -#: pcbnew/menubarpcb.cpp:246 +#: pcbnew/menubarpcb.cpp:253 msgid "Generate &Modules Position" msgstr "Créer &Modules Position" -#: pcbnew/menubarpcb.cpp:247 +#: pcbnew/menubarpcb.cpp:254 msgid "Generate modules position file" msgstr "Gen fichier Position des Modules" -#: pcbnew/menubarpcb.cpp:252 +#: pcbnew/menubarpcb.cpp:259 msgid "Create &Drill File" msgstr "Créer &Fichier de Perçage" -#: pcbnew/menubarpcb.cpp:253 +#: pcbnew/menubarpcb.cpp:260 msgid "Generate excellon2 drill file" msgstr "Créer Fichier de perçage Excellon2" -#: pcbnew/menubarpcb.cpp:258 +#: pcbnew/menubarpcb.cpp:265 msgid "Create &Component File" msgstr "Créer &Fichier Cmp" -#: pcbnew/menubarpcb.cpp:259 +#: pcbnew/menubarpcb.cpp:266 msgid "Recreate .cmp file for CvPcb" msgstr "Recréer le fichier .cmp pour CvPcb" -#: pcbnew/menubarpcb.cpp:264 +#: pcbnew/menubarpcb.cpp:271 msgid "Create &BOM File" msgstr "Créer Fichier Liste du &Matériel" -#: pcbnew/menubarpcb.cpp:265 +#: pcbnew/menubarpcb.cpp:272 msgid "Recreate .csv file for CvPcb" msgstr "Recréer le fichier .csv pour CvPcb" -#: pcbnew/menubarpcb.cpp:274 +#: pcbnew/menubarpcb.cpp:281 msgid "Global &Deletions" msgstr "Effacements &Généraux" -#: pcbnew/menubarpcb.cpp:275 +#: pcbnew/menubarpcb.cpp:282 msgid "Delete tracks, modules, texts... on board" msgstr "Effacer pistes, modules, textes... sur le C.I." -#: pcbnew/menubarpcb.cpp:280 +#: pcbnew/menubarpcb.cpp:287 msgid "&List Nets" msgstr "Liste Equipots" -#: pcbnew/menubarpcb.cpp:281 +#: pcbnew/menubarpcb.cpp:288 msgid "List nets (names and id)" msgstr "Lister équipotentielles (noms et numéros d'identification)" -#: pcbnew/menubarpcb.cpp:286 +#: pcbnew/menubarpcb.cpp:293 msgid "&Track Operations" msgstr "Opéra&tions sur Pistes" -#: pcbnew/menubarpcb.cpp:287 +#: pcbnew/menubarpcb.cpp:294 msgid "Clean stubs, vias, delete break points, or connect dangling tracks to pads and vias" msgstr "Nettoyer bouts de pistes, vias, points inutiles, ou connecter extrémités de pistes mal connectées au centre de pads ou vias" -#: pcbnew/menubarpcb.cpp:292 +#: pcbnew/menubarpcb.cpp:299 msgid "&Swap Layers" msgstr "&Permutte Couches" -#: pcbnew/menubarpcb.cpp:293 +#: pcbnew/menubarpcb.cpp:300 msgid "Swap tracks on copper layers or drawings on others layers" msgstr "Permutation de couches" -#: pcbnew/menubarpcb.cpp:301 +#: pcbnew/menubarpcb.cpp:308 msgid "&Contents" msgstr "&Contenu" -#: pcbnew/menubarpcb.cpp:302 +#: pcbnew/menubarpcb.cpp:309 msgid "Open the PCBNEW manual" msgstr "Ouvrir la Documentation de PCBNEW" -#: pcbnew/menubarpcb.cpp:306 +#: pcbnew/menubarpcb.cpp:313 msgid "&About PCBNEW" msgstr "&Au Sujet de PCBNEW" -#: pcbnew/menubarpcb.cpp:307 +#: pcbnew/menubarpcb.cpp:314 msgid "About PCBNEW printed circuit board designer" msgstr "Au Sujet de PCBNEW outil de conception de C.I." -#: pcbnew/menubarpcb.cpp:316 +#: pcbnew/menubarpcb.cpp:323 msgid "3D Display" msgstr "3D Visu" -#: pcbnew/menubarpcb.cpp:316 +#: pcbnew/menubarpcb.cpp:323 msgid "Show board in 3D viewer" msgstr "Visualisation du circuit en 3D" -#: pcbnew/menubarpcb.cpp:320 +#: pcbnew/menubarpcb.cpp:327 msgid "&File" msgstr "&Fichiers" -#: pcbnew/menubarpcb.cpp:321 +#: pcbnew/menubarpcb.cpp:328 msgid "&Preferences" msgstr "&Préférences" -#: pcbnew/menubarpcb.cpp:322 +#: pcbnew/menubarpcb.cpp:329 +msgid "&Design Rules" +msgstr "&Règles de Conception" + +#: pcbnew/menubarpcb.cpp:330 msgid "&Dimensions" msgstr "&Dimensions" -#: pcbnew/menubarpcb.cpp:323 +#: pcbnew/menubarpcb.cpp:331 msgid "&Miscellaneous" msgstr "&Divers" -#: pcbnew/menubarpcb.cpp:324 +#: pcbnew/menubarpcb.cpp:332 msgid "P&ostprocess" msgstr "P&ostprocesseurs" -#: pcbnew/menubarpcb.cpp:325 +#: pcbnew/menubarpcb.cpp:333 msgid "&3D Display" msgstr "&3D Visu" -#: pcbnew/menubarpcb.cpp:326 +#: pcbnew/menubarpcb.cpp:334 msgid "&Help" msgstr "&Aide" @@ -2377,105 +2389,105 @@ msgstr "Valeur incorrecte pour offset du pad" msgid "Unknown netname, no change" msgstr "Net inconnu, pas de changement" -#: pcbnew/pcbframe.cpp:309 +#: pcbnew/pcbframe.cpp:314 msgid "Board modified, Save before exit ?" msgstr "Circuit Imprimé modifié, Sauver avant de quitter ?" -#: pcbnew/pcbframe.cpp:310 +#: pcbnew/pcbframe.cpp:315 msgid "Confirmation" msgstr "Confirmation" -#: pcbnew/pcbframe.cpp:415 +#: pcbnew/pcbframe.cpp:420 msgid "DRC Off (Disable !!!), Currently: DRC is active" msgstr "DRC off (désactivée !!!), actuellement DRC active" -#: pcbnew/pcbframe.cpp:416 +#: pcbnew/pcbframe.cpp:421 msgid "DRC On (Currently: DRC is inactive !!!)" msgstr "DRC On (Actuellement, DRC désactivée !!!)" -#: pcbnew/pcbframe.cpp:427 +#: pcbnew/pcbframe.cpp:432 msgid "Polar Coords not show" msgstr "Coord Polaires non affichées" -#: pcbnew/pcbframe.cpp:428 +#: pcbnew/pcbframe.cpp:433 msgid "Display Polar Coords" msgstr "Affichage coord Polaires" -#: pcbnew/pcbframe.cpp:433 +#: pcbnew/pcbframe.cpp:438 msgid "Grid not show" msgstr "Grille non montrée" -#: pcbnew/pcbframe.cpp:433 +#: pcbnew/pcbframe.cpp:438 msgid "Show Grid" msgstr "Afficher grille" -#: pcbnew/pcbframe.cpp:442 +#: pcbnew/pcbframe.cpp:447 msgid "Hide General ratsnest" msgstr "Ne pas afficher le chevelu général" -#: pcbnew/pcbframe.cpp:443 +#: pcbnew/pcbframe.cpp:448 msgid "Show General ratsnest" msgstr "Afficher le chevelu général" -#: pcbnew/pcbframe.cpp:449 +#: pcbnew/pcbframe.cpp:454 msgid "Hide Module ratsnest" msgstr "Ne pas montrer le chevelu du module" -#: pcbnew/pcbframe.cpp:450 +#: pcbnew/pcbframe.cpp:455 msgid "Show Module ratsnest" msgstr "Montrer le chevelu du module" -#: pcbnew/pcbframe.cpp:457 +#: pcbnew/pcbframe.cpp:462 msgid "Disable Auto Delete old Track" msgstr "Ne pas Autoriser l'effacement automatique des pistes" -#: pcbnew/pcbframe.cpp:458 +#: pcbnew/pcbframe.cpp:463 msgid "Enable Auto Delete old Track" msgstr "Autoriser l'effacement automatique des pistes" -#: pcbnew/pcbframe.cpp:465 +#: pcbnew/pcbframe.cpp:470 msgid "Show Pads Sketch mode" msgstr "Afficher pastilles en contour" -#: pcbnew/pcbframe.cpp:466 +#: pcbnew/pcbframe.cpp:471 msgid "Show pads filled mode" msgstr "Afficher pastilles en mode plein" -#: pcbnew/pcbframe.cpp:472 +#: pcbnew/pcbframe.cpp:477 msgid "Show Tracks Sketch mode" msgstr "Afficher pistes en contour" -#: pcbnew/pcbframe.cpp:473 +#: pcbnew/pcbframe.cpp:478 msgid "Show Tracks filled mode" msgstr "Afficher pistes en mode plein" -#: pcbnew/pcbframe.cpp:479 +#: pcbnew/pcbframe.cpp:484 msgid "Normal Contrast Mode Display" msgstr "Mode d'affichage Contraste normal" -#: pcbnew/pcbframe.cpp:486 +#: pcbnew/pcbframe.cpp:491 msgid "Hide Invisible Text" msgstr "Cacher textes invisibles" -#: pcbnew/pcbframe.cpp:499 +#: pcbnew/pcbframe.cpp:504 msgid "Track" msgstr "Piste" -#: pcbnew/pcbframe.cpp:531 +#: pcbnew/pcbframe.cpp:536 #: pcbnew/dialog_drc_base.cpp:35 #: pcbnew/dialog_track_options_base.cpp:106 msgid "Clearance" msgstr "Isolation" -#: pcbnew/pcbframe.cpp:563 +#: pcbnew/pcbframe.cpp:568 msgid "Via" msgstr "Via" -#: pcbnew/pcbframe.cpp:635 +#: pcbnew/pcbframe.cpp:640 msgid "3D Frame already opened" msgstr "Fenêtre 3D déjà ouverte" -#: pcbnew/pcbframe.cpp:639 +#: pcbnew/pcbframe.cpp:644 msgid "3D Viewer" msgstr "Visu 3D" @@ -2812,6 +2824,33 @@ msgstr "Pas de couche sélectionnée" msgid "Error: Unexpected end of file !" msgstr "Erreur: Fin de fichier inattendue !" +#: pcbnew/specctra.cpp:133 +#: pcbnew/specctra.cpp:140 +msgid "Expecting" +msgstr "Attendu" + +#: pcbnew/specctra.cpp:147 +#: pcbnew/specctra.cpp:154 +msgid "Unexpected" +msgstr "Inattendu" + +#: pcbnew/specctra.cpp:324 +#: pcbnew/specctra.cpp:354 +#: pcbnew/specctra.cpp:3569 +#: pcbnew/specctra.cpp:3594 +#, c-format +msgid "Unable to open file \"%s\"" +msgstr "Ne peut pas ouvrirle fichier \"%s\"" + +#: pcbnew/specctra.cpp:3512 +#, c-format +msgid "System file error writing to file \"%s\"" +msgstr "Erreur système sur écriture fichier \"%s\"" + +#: pcbnew/specctra.cpp:3689 +msgid "Error writing to STRINGFORMATTER" +msgstr "Erreur d'écriture à STRINGFORMATTER" + #: pcbnew/class_zone.cpp:871 msgid "Zone Outline" msgstr "Contour de Zone" @@ -2860,33 +2899,6 @@ msgstr "Lignes de Hachure" msgid "Corners in DrawList" msgstr "Sommets en Liste de dessin" -#: pcbnew/specctra.cpp:133 -#: pcbnew/specctra.cpp:140 -msgid "Expecting" -msgstr "Attendu" - -#: pcbnew/specctra.cpp:147 -#: pcbnew/specctra.cpp:154 -msgid "Unexpected" -msgstr "Inattendu" - -#: pcbnew/specctra.cpp:324 -#: pcbnew/specctra.cpp:354 -#: pcbnew/specctra.cpp:3526 -#: pcbnew/specctra.cpp:3551 -#, c-format -msgid "Unable to open file \"%s\"" -msgstr "Ne peut pas ouvrirle fichier \"%s\"" - -#: pcbnew/specctra.cpp:3469 -#, c-format -msgid "System file error writing to file \"%s\"" -msgstr "Erreur système sur écriture fichier \"%s\"" - -#: pcbnew/specctra.cpp:3646 -msgid "Error writing to STRINGFORMATTER" -msgstr "Erreur d'écriture à STRINGFORMATTER" - #: pcbnew/sel_layer.cpp:93 msgid "Select Layer:" msgstr "Sélection couche:" @@ -3675,468 +3687,476 @@ msgid "Layer selection:" msgstr "Sélection couche:" #: pcbnew/onrightclick.cpp:42 +msgid "New Width/Size" +msgstr "Nouvelle Largeur/Taille" + +#: pcbnew/onrightclick.cpp:45 msgid "Auto Width" msgstr "Epaisseur Automatique" -#: pcbnew/onrightclick.cpp:44 +#: pcbnew/onrightclick.cpp:47 msgid "Use the track width when starting on a track, otherwise the current track width" msgstr "Si on démarre sur une piste existante, utiliser sa largeur, sinon utiliser la largeur courante" -#: pcbnew/onrightclick.cpp:58 +#: pcbnew/onrightclick.cpp:61 #, c-format msgid "Track %.1f" msgstr "Piste %.1f" -#: pcbnew/onrightclick.cpp:60 +#: pcbnew/onrightclick.cpp:63 #, c-format msgid "Track %.3f" msgstr "Piste %.3f" -#: pcbnew/onrightclick.cpp:78 +#: pcbnew/onrightclick.cpp:81 #, c-format msgid "Via %.1f" msgstr "Via %.1f" -#: pcbnew/onrightclick.cpp:80 +#: pcbnew/onrightclick.cpp:83 #, c-format msgid "Via %.3f" msgstr "Via %.3f" -#: pcbnew/onrightclick.cpp:196 +#: pcbnew/onrightclick.cpp:199 msgid "Lock Module" msgstr "Verrouiller Module" -#: pcbnew/onrightclick.cpp:204 +#: pcbnew/onrightclick.cpp:207 msgid "Unlock Module" msgstr "Déverrouiller Module" -#: pcbnew/onrightclick.cpp:212 +#: pcbnew/onrightclick.cpp:215 msgid "Auto Place Module" msgstr "Auto Place Module" -#: pcbnew/onrightclick.cpp:218 +#: pcbnew/onrightclick.cpp:221 msgid "Autoroute" msgstr "Autoroute" -#: pcbnew/onrightclick.cpp:234 +#: pcbnew/onrightclick.cpp:237 msgid "Move Drawing" msgstr "Déplace Tracé" -#: pcbnew/onrightclick.cpp:239 +#: pcbnew/onrightclick.cpp:242 msgid "End Drawing" msgstr "Fin tracé" -#: pcbnew/onrightclick.cpp:242 +#: pcbnew/onrightclick.cpp:245 msgid "Edit Drawing" msgstr "Edit Tracé" -#: pcbnew/onrightclick.cpp:244 +#: pcbnew/onrightclick.cpp:247 msgid "Delete Drawing" msgstr "Supprimer Tracé" -#: pcbnew/onrightclick.cpp:249 +#: pcbnew/onrightclick.cpp:252 msgid "Delete Zone Filling" msgstr "Supprimer Remplissage de Zone" -#: pcbnew/onrightclick.cpp:256 +#: pcbnew/onrightclick.cpp:259 msgid "Close Zone Outline" msgstr "Fermer Contour de Zone" -#: pcbnew/onrightclick.cpp:258 +#: pcbnew/onrightclick.cpp:261 msgid "Delete Last Corner" msgstr "Supprimer Dernier Sommet" -#: pcbnew/onrightclick.cpp:276 -msgid "Delete Marker" -msgstr "Effacer Marqueur" - -#: pcbnew/onrightclick.cpp:283 +#: pcbnew/onrightclick.cpp:285 msgid "Edit Dimension" msgstr "Edit Cote" -#: pcbnew/onrightclick.cpp:286 +#: pcbnew/onrightclick.cpp:288 msgid "Delete Dimension" msgstr "Suppression Cote" -#: pcbnew/onrightclick.cpp:293 +#: pcbnew/onrightclick.cpp:295 msgid "Move Target" msgstr "Déplacer Mire" -#: pcbnew/onrightclick.cpp:296 +#: pcbnew/onrightclick.cpp:298 msgid "Edit Target" msgstr "Editer Mire" -#: pcbnew/onrightclick.cpp:298 +#: pcbnew/onrightclick.cpp:300 msgid "Delete Target" msgstr "Supprimer Mire" -#: pcbnew/onrightclick.cpp:329 +#: pcbnew/onrightclick.cpp:331 msgid "Get and Move Footprint" msgstr "Sel. et Dépl. module" -#: pcbnew/onrightclick.cpp:343 +#: pcbnew/onrightclick.cpp:345 msgid "Fill or Refill All Zones" msgstr "Remplir ou Re-remplir Toutes les Zones" -#: pcbnew/onrightclick.cpp:345 +#: pcbnew/onrightclick.cpp:347 msgid "Remove Filled Areas in All Zones" msgstr "Supprimer le Remplissage de toutes les Zones" -#: pcbnew/onrightclick.cpp:350 -#: pcbnew/onrightclick.cpp:359 -#: pcbnew/onrightclick.cpp:371 -#: pcbnew/onrightclick.cpp:432 +#: pcbnew/onrightclick.cpp:352 +#: pcbnew/onrightclick.cpp:361 +#: pcbnew/onrightclick.cpp:373 +#: pcbnew/onrightclick.cpp:434 msgid "Select Working Layer" msgstr "Sélection de la couche de travail" -#: pcbnew/onrightclick.cpp:357 -#: pcbnew/onrightclick.cpp:429 +#: pcbnew/onrightclick.cpp:359 +#: pcbnew/onrightclick.cpp:431 msgid "Select Track Width" msgstr "Sélection Epais. Piste" -#: pcbnew/onrightclick.cpp:361 +#: pcbnew/onrightclick.cpp:363 msgid "Select Layer Pair for Vias" msgstr "Sélection Couple de Couches pour Vias" -#: pcbnew/onrightclick.cpp:377 +#: pcbnew/onrightclick.cpp:379 msgid "Footprint Documentation" msgstr "Documentation des Modules" -#: pcbnew/onrightclick.cpp:387 +#: pcbnew/onrightclick.cpp:389 msgid "Glob Move and Place" msgstr "Move et Place Globaux" -#: pcbnew/onrightclick.cpp:389 +#: pcbnew/onrightclick.cpp:391 msgid "Unlock All Modules" msgstr "Déverrouiller tous les Modules" -#: pcbnew/onrightclick.cpp:391 +#: pcbnew/onrightclick.cpp:393 msgid "Lock All Modules" msgstr "Verrouiller tous les Modules" -#: pcbnew/onrightclick.cpp:394 +#: pcbnew/onrightclick.cpp:396 msgid "Move All Modules" msgstr "Déplace tous les Modules" -#: pcbnew/onrightclick.cpp:395 +#: pcbnew/onrightclick.cpp:397 msgid "Move New Modules" msgstr "Déplace nouveaux Modules" -#: pcbnew/onrightclick.cpp:397 +#: pcbnew/onrightclick.cpp:399 msgid "Autoplace All Modules" msgstr "Autoplace Tous Modules" -#: pcbnew/onrightclick.cpp:398 +#: pcbnew/onrightclick.cpp:400 msgid "Autoplace New Modules" msgstr "AutoPlace nouveaux Modules" -#: pcbnew/onrightclick.cpp:399 +#: pcbnew/onrightclick.cpp:401 msgid "Autoplace Next Module" msgstr "Autoplace Module suivant" -#: pcbnew/onrightclick.cpp:402 +#: pcbnew/onrightclick.cpp:404 msgid "Orient All Modules" msgstr "Oriente Tous Modules" -#: pcbnew/onrightclick.cpp:409 +#: pcbnew/onrightclick.cpp:411 msgid "Global Autoroute" msgstr "Autoroutage global" -#: pcbnew/onrightclick.cpp:411 +#: pcbnew/onrightclick.cpp:413 msgid "Select Layer Pair" msgstr "Sélection Paire de Couches" -#: pcbnew/onrightclick.cpp:413 +#: pcbnew/onrightclick.cpp:415 msgid "Autoroute All Modules" msgstr "Autoroute Tous Modules" -#: pcbnew/onrightclick.cpp:415 +#: pcbnew/onrightclick.cpp:417 msgid "Reset Unrouted" msgstr "Réinit non Routés" -#: pcbnew/onrightclick.cpp:420 +#: pcbnew/onrightclick.cpp:422 msgid "Global AutoRouter" msgstr "Autorouteur Global" -#: pcbnew/onrightclick.cpp:422 +#: pcbnew/onrightclick.cpp:424 msgid "Read Global AutoRouter Data" msgstr "Lire Données de L'autorouteur global" -#: pcbnew/onrightclick.cpp:452 +#: pcbnew/onrightclick.cpp:454 msgid "Zoom Block" msgstr "Zoom Bloc" -#: pcbnew/onrightclick.cpp:459 +#: pcbnew/onrightclick.cpp:461 msgid "Flip Block" msgstr "Retourner Bloc" -#: pcbnew/onrightclick.cpp:482 +#: pcbnew/onrightclick.cpp:484 msgid "Drag Via" msgstr "Drag Via" -#: pcbnew/onrightclick.cpp:486 +#: pcbnew/onrightclick.cpp:488 msgid "Edit Via Drill" msgstr "Editer Perçage Via" -#: pcbnew/onrightclick.cpp:488 +#: pcbnew/onrightclick.cpp:490 msgid "Set Via Hole to Default" msgstr "Ajuste Perçage Via à Défaut" -#: pcbnew/onrightclick.cpp:489 +#: pcbnew/onrightclick.cpp:491 msgid "Set via hole to a specific value. This specific value is currently" msgstr "Ajuster diamètre perçage via à une valeur sécifique. Cette valeur spécifique est actuellement" -#: pcbnew/onrightclick.cpp:492 +#: pcbnew/onrightclick.cpp:494 msgid "Set Via Hole to Specific Value" msgstr "Ajuste Perçage Via à Valeur Spécifique" -#: pcbnew/onrightclick.cpp:494 +#: pcbnew/onrightclick.cpp:496 msgid "Set a specific via hole value. This value is currently" msgstr "Ajuste une valeur spécifique de perçage de la via. Cette valeur est actuellement" -#: pcbnew/onrightclick.cpp:497 +#: pcbnew/onrightclick.cpp:499 msgid "Change the Current Specific Drill Value" msgstr "Changer la Valeur du Perçage Spécifique Courant" -#: pcbnew/onrightclick.cpp:499 +#: pcbnew/onrightclick.cpp:501 msgid "Use this Via Hole as Specific Value" msgstr "Utiliser ce Perçage de Via comme Valeur Spécifique" -#: pcbnew/onrightclick.cpp:501 +#: pcbnew/onrightclick.cpp:503 msgid "Export this Via Hole to Others id Vias" msgstr "Exporte ce Perçage Via aux Autres Semblables." -#: pcbnew/onrightclick.cpp:503 +#: pcbnew/onrightclick.cpp:505 msgid "Set ALL Via Holes to Default" msgstr "Ajuste Perçage TOUTES Vias à Défaut" -#: pcbnew/onrightclick.cpp:516 +#: pcbnew/onrightclick.cpp:518 msgid "Move Node" msgstr "Déplace Noeud" -#: pcbnew/onrightclick.cpp:521 +#: pcbnew/onrightclick.cpp:523 msgid "Drag Segments, Keep Slope" msgstr "Drag Segments, Garder Direction" -#: pcbnew/onrightclick.cpp:523 +#: pcbnew/onrightclick.cpp:525 msgid "Drag Segment" msgstr "Drag Segment" -#: pcbnew/onrightclick.cpp:526 +#: pcbnew/onrightclick.cpp:528 msgid "Move Segment" msgstr "Déplace Segment" -#: pcbnew/onrightclick.cpp:529 +#: pcbnew/onrightclick.cpp:531 msgid "Break Track" msgstr "Briser Piste" -#: pcbnew/onrightclick.cpp:536 +#: pcbnew/onrightclick.cpp:538 msgid "Place Node" msgstr "Place noeud" -#: pcbnew/onrightclick.cpp:543 +#: pcbnew/onrightclick.cpp:545 msgid "End Track" msgstr "Terminer Piste" -#: pcbnew/onrightclick.cpp:546 +#: pcbnew/onrightclick.cpp:548 msgid "Place Via" msgstr "Place Via" -#: pcbnew/onrightclick.cpp:553 +#: pcbnew/onrightclick.cpp:555 msgid "Place Micro Via" msgstr "Place Micro Via" -#: pcbnew/onrightclick.cpp:565 +#: pcbnew/onrightclick.cpp:567 msgid "Change Width" msgstr "Change Largeur" -#: pcbnew/onrightclick.cpp:567 +#: pcbnew/onrightclick.cpp:569 msgid "Change Via Size" msgstr "Change Taille Via" -#: pcbnew/onrightclick.cpp:567 +#: pcbnew/onrightclick.cpp:569 msgid "Change Segment Width" msgstr "Change Largeur Segment" -#: pcbnew/onrightclick.cpp:570 +#: pcbnew/onrightclick.cpp:572 msgid "Change Track Width" msgstr "Change Largeur Piste" -#: pcbnew/onrightclick.cpp:572 +#: pcbnew/onrightclick.cpp:574 msgid "Change Net" msgstr "Change Net" -#: pcbnew/onrightclick.cpp:574 +#: pcbnew/onrightclick.cpp:576 msgid "Change ALL Tracks and Vias" msgstr "Changer TOUTES Pistes et Vias" -#: pcbnew/onrightclick.cpp:576 +#: pcbnew/onrightclick.cpp:578 msgid "Change ALL Vias (No Track)" msgstr "Changer TOUTES Vias (Pas les Pistes)" -#: pcbnew/onrightclick.cpp:578 +#: pcbnew/onrightclick.cpp:580 msgid "Change ALL Tracks (No Via)" msgstr "Changer TOUTES Pistes (Pas les Vias)" -#: pcbnew/onrightclick.cpp:584 -#: pcbnew/onrightclick.cpp:771 -#: pcbnew/onrightclick.cpp:826 -#: pcbnew/onrightclick.cpp:875 +#: pcbnew/onrightclick.cpp:586 +#: pcbnew/onrightclick.cpp:773 +#: pcbnew/onrightclick.cpp:828 +#: pcbnew/onrightclick.cpp:877 msgid "Delete" msgstr "Supprimer" -#: pcbnew/onrightclick.cpp:586 +#: pcbnew/onrightclick.cpp:588 msgid "Delete Via" msgstr "Suppression Via" -#: pcbnew/onrightclick.cpp:586 +#: pcbnew/onrightclick.cpp:588 msgid "Delete Segment" msgstr "Supprimer Segment" -#: pcbnew/onrightclick.cpp:593 +#: pcbnew/onrightclick.cpp:595 msgid "Delete Track" msgstr "Effacer Piste" -#: pcbnew/onrightclick.cpp:597 +#: pcbnew/onrightclick.cpp:599 msgid "Delete Net" msgstr "Supprimer Net" -#: pcbnew/onrightclick.cpp:602 +#: pcbnew/onrightclick.cpp:604 msgid "Set Flags" msgstr "Ajust. Flags" -#: pcbnew/onrightclick.cpp:603 +#: pcbnew/onrightclick.cpp:605 msgid "Locked: Yes" msgstr "Verrou: Oui" -#: pcbnew/onrightclick.cpp:604 +#: pcbnew/onrightclick.cpp:606 msgid "Locked: No" msgstr "Verrou: Non" -#: pcbnew/onrightclick.cpp:614 +#: pcbnew/onrightclick.cpp:616 msgid "Track Locked: Yes" msgstr "Piste Verrouillée: Oui" -#: pcbnew/onrightclick.cpp:615 +#: pcbnew/onrightclick.cpp:617 msgid "Track Locked: No" msgstr "Piste Verrouillée: Non" -#: pcbnew/onrightclick.cpp:617 +#: pcbnew/onrightclick.cpp:619 msgid "Net Locked: Yes" msgstr "Net Verrouillé: Oui" -#: pcbnew/onrightclick.cpp:618 +#: pcbnew/onrightclick.cpp:620 msgid "Net Locked: No" msgstr "Net Verrouillé: Non" -#: pcbnew/onrightclick.cpp:633 +#: pcbnew/onrightclick.cpp:635 msgid "Place Edge Outline" msgstr "Place Segment de Contour" -#: pcbnew/onrightclick.cpp:639 +#: pcbnew/onrightclick.cpp:641 msgid "Place Corner" msgstr "Place Sommet" -#: pcbnew/onrightclick.cpp:642 +#: pcbnew/onrightclick.cpp:644 msgid "Place Zone" msgstr "Place Zone" -#: pcbnew/onrightclick.cpp:649 +#: pcbnew/onrightclick.cpp:651 msgid "Zones" msgstr "Zones" -#: pcbnew/onrightclick.cpp:654 +#: pcbnew/onrightclick.cpp:656 msgid "Move Corner" msgstr "Déplace Sommet" -#: pcbnew/onrightclick.cpp:656 +#: pcbnew/onrightclick.cpp:658 msgid "Delete Corner" msgstr "Supprimer Sommet" -#: pcbnew/onrightclick.cpp:661 +#: pcbnew/onrightclick.cpp:663 msgid "Create Corner" msgstr "Créer Sommet" -#: pcbnew/onrightclick.cpp:663 +#: pcbnew/onrightclick.cpp:665 msgid "Drag Outline Segment" msgstr "Drag Segment Contour" -#: pcbnew/onrightclick.cpp:668 +#: pcbnew/onrightclick.cpp:670 msgid "Add Similar Zone" msgstr "Addition d'une Zone Semblable" -#: pcbnew/onrightclick.cpp:671 +#: pcbnew/onrightclick.cpp:673 msgid "Add Cutout Area" msgstr "Addition d'une Zone Interdite" -#: pcbnew/onrightclick.cpp:675 +#: pcbnew/onrightclick.cpp:677 msgid "Fill Zone" msgstr "Remplir Zone" -#: pcbnew/onrightclick.cpp:680 +#: pcbnew/onrightclick.cpp:682 msgid "Remove Filled Areas in Zone" msgstr "Supprimer le Remplissage de la Zone" -#: pcbnew/onrightclick.cpp:684 +#: pcbnew/onrightclick.cpp:686 msgid "Move Zone" msgstr "Déplace Zone" -#: pcbnew/onrightclick.cpp:687 +#: pcbnew/onrightclick.cpp:689 msgid "Edit Zone Params" msgstr "Editer Paramètres de la Zone" -#: pcbnew/onrightclick.cpp:692 +#: pcbnew/onrightclick.cpp:694 msgid "Delete Cutout" msgstr "Supprimer Zone Interdite" -#: pcbnew/onrightclick.cpp:695 +#: pcbnew/onrightclick.cpp:697 msgid "Delete Zone Outline" msgstr "Supprimer Contour de Zone" -#: pcbnew/onrightclick.cpp:717 -#: pcbnew/onrightclick.cpp:762 -#: pcbnew/onrightclick.cpp:800 -#: pcbnew/onrightclick.cpp:866 +#: pcbnew/onrightclick.cpp:719 +#: pcbnew/onrightclick.cpp:764 +#: pcbnew/onrightclick.cpp:802 +#: pcbnew/onrightclick.cpp:868 msgid "Move" msgstr "Déplacer" -#: pcbnew/onrightclick.cpp:720 -#: pcbnew/onrightclick.cpp:802 +#: pcbnew/onrightclick.cpp:722 +#: pcbnew/onrightclick.cpp:804 msgid "Drag" msgstr "Drag" -#: pcbnew/onrightclick.cpp:724 +#: pcbnew/onrightclick.cpp:726 msgid "Rotate +" msgstr "Rotation +" -#: pcbnew/onrightclick.cpp:728 +#: pcbnew/onrightclick.cpp:730 msgid "Rotate -" msgstr "Rotation -" -#: pcbnew/onrightclick.cpp:729 +#: pcbnew/onrightclick.cpp:731 msgid "Flip" msgstr "Change côté" -#: pcbnew/onrightclick.cpp:809 +#: pcbnew/onrightclick.cpp:811 msgid "Copy current pad settings to this pad" msgstr "Copier les réglages courants pour ce pad" -#: pcbnew/onrightclick.cpp:813 +#: pcbnew/onrightclick.cpp:815 msgid "Copy this pad settings to current pad settings" msgstr "Copier les caractéristiques de ce pad vers les caractéristiques courantes" -#: pcbnew/onrightclick.cpp:821 +#: pcbnew/onrightclick.cpp:823 msgid "Copy this pad settings to all pads in this footprint (or similar footprints)" msgstr "Copier les caractéristiques de ce pad vers tous les autres pads de ce module( ou modules similaires)" -#: pcbnew/onrightclick.cpp:833 +#: pcbnew/onrightclick.cpp:835 msgid "Autoroute Pad" msgstr "Autoroute Pad" -#: pcbnew/onrightclick.cpp:834 +#: pcbnew/onrightclick.cpp:836 msgid "Autoroute Net" msgstr "Autoroute Net" +#: pcbnew/onrightclick.cpp:884 +msgid "Delete Marker" +msgstr "Effacer Marqueur" + +#: pcbnew/onrightclick.cpp:885 +msgid "Marker Error Info" +msgstr "Info de Marqueurd'Erreur" + #: pcbnew/dialog_copper_zones_base.cpp:32 msgid "Zone Setup:" msgstr "Options Zone:" @@ -5158,23 +5178,23 @@ msgstr "(Specifique)" msgid "(Default)" msgstr "(Défaut)" -#: pcbnew/class_board.cpp:532 +#: pcbnew/class_board.cpp:537 msgid "Nodes" msgstr "Nodes" -#: pcbnew/class_board.cpp:535 +#: pcbnew/class_board.cpp:540 msgid "Nets" msgstr "Nets" -#: pcbnew/class_board.cpp:543 +#: pcbnew/class_board.cpp:548 msgid "Links" msgstr "Liens" -#: pcbnew/class_board.cpp:546 +#: pcbnew/class_board.cpp:551 msgid "Connect" msgstr "Connect" -#: pcbnew/class_board.cpp:549 +#: pcbnew/class_board.cpp:554 msgid "NoConn" msgstr "Non Conn" @@ -5519,6 +5539,7 @@ msgstr "" #: pcbnew/dialog_pcbnew_config_libs_and_paths_fbp.cpp:36 #: pcbnew/dialog_pcbnew_config_libs_and_paths_fbp.cpp:83 +#: pcbnew/dialog_design_rules_base.cpp:134 msgid "Add" msgstr "Ajouter" @@ -5537,6 +5558,7 @@ msgstr "Ajouter une nouvelle librairie avant la librairie sélectionnée, et la #: pcbnew/dialog_pcbnew_config_libs_and_paths_fbp.cpp:46 #: pcbnew/dialog_pcbnew_config_libs_and_paths_fbp.cpp:89 +#: pcbnew/dialog_design_rules_base.cpp:137 msgid "Remove" msgstr "Enlever" @@ -5670,6 +5692,126 @@ msgstr "Mire" msgid "size" msgstr "dimension" +#: pcbnew/dialog_design_rules_base.cpp:26 +msgid "Layers Count" +msgstr "Nombre de Couches" + +#: pcbnew/dialog_design_rules_base.cpp:46 +msgid "Active" +msgstr "Active" + +#: pcbnew/dialog_design_rules_base.cpp:47 +msgid "Status" +msgstr "Status" + +#: pcbnew/dialog_design_rules_base.cpp:48 +msgid "Name" +msgstr "Nom" + +#: pcbnew/dialog_design_rules_base.cpp:56 +msgid "Inner 14" +msgstr "Interne 14" + +#: pcbnew/dialog_design_rules_base.cpp:57 +msgid "Inner 13" +msgstr "Interne 13" + +#: pcbnew/dialog_design_rules_base.cpp:58 +msgid "Inner 12" +msgstr "Interne 12" + +#: pcbnew/dialog_design_rules_base.cpp:59 +msgid "Inner 11" +msgstr "Interne 11" + +#: pcbnew/dialog_design_rules_base.cpp:60 +msgid "Inner 10" +msgstr "Interne 10" + +#: pcbnew/dialog_design_rules_base.cpp:61 +msgid "Inner 9" +msgstr "Interne 9" + +#: pcbnew/dialog_design_rules_base.cpp:62 +msgid "Inner 8" +msgstr "Interne 8" + +#: pcbnew/dialog_design_rules_base.cpp:63 +msgid "Inner 7" +msgstr "Interne 7" + +#: pcbnew/dialog_design_rules_base.cpp:64 +msgid "Inner 6" +msgstr "Interne 6" + +#: pcbnew/dialog_design_rules_base.cpp:65 +msgid "Inner 5" +msgstr "Interne 5" + +#: pcbnew/dialog_design_rules_base.cpp:66 +msgid "Inner 4" +msgstr "Interne 4" + +#: pcbnew/dialog_design_rules_base.cpp:67 +msgid "Inner 3" +msgstr "Interne 3" + +#: pcbnew/dialog_design_rules_base.cpp:68 +msgid "Inner 2" +msgstr "Interne 2" + +#: pcbnew/dialog_design_rules_base.cpp:69 +msgid "Inner 1" +msgstr "Interne 1" + +#: pcbnew/dialog_design_rules_base.cpp:82 +msgid "Layers" +msgstr "Couches" + +#: pcbnew/dialog_design_rules_base.cpp:88 +msgid "Net classes:" +msgstr "Classes d'Equipotentielles:" + +#: pcbnew/dialog_design_rules_base.cpp:108 +msgid "Track size" +msgstr "Largeur piste" + +#: pcbnew/dialog_design_rules_base.cpp:109 +msgid "Vias size" +msgstr "Diamètre via" + +#: pcbnew/dialog_design_rules_base.cpp:111 +msgid "Track Min Size" +msgstr "Taille Min Piste" + +#: pcbnew/dialog_design_rules_base.cpp:119 +msgid "Default" +msgstr "Défaut" + +#: pcbnew/dialog_design_rules_base.cpp:120 +msgid "Special" +msgstr "Special" + +#: pcbnew/dialog_design_rules_base.cpp:163 +msgid "<<<" +msgstr "<<<" + +#: pcbnew/dialog_design_rules_base.cpp:166 +msgid ">>>" +msgstr ">>>" + +#: pcbnew/dialog_design_rules_base.cpp:172 +msgid "<< Select All" +msgstr "<< Selectionner Tout" + +#: pcbnew/dialog_design_rules_base.cpp:175 +msgid "Select All >>" +msgstr "Selectionner Tout >>" + +#: pcbnew/dialog_design_rules_base.cpp:209 +msgid "Net Classes" +msgstr "Classes d'Equipots." + #: pcbnew/editrack-part2.cpp:32 #, c-format msgid "Track Width: %s Vias Size : %s" @@ -5707,6 +5849,10 @@ msgstr "Change tous" msgid "Browse Libs modules" msgstr "Liste modules" +#: pcbnew/dialog_design_rules.cpp:319 +msgid "New Net Class Name:" +msgstr "Nouveau Nom de Classe d'Equipotentielle:" + #: eeschema/libedit.cpp:35 msgid " Part: " msgstr "Composant " @@ -6012,42 +6158,30 @@ msgstr "Impossible de trouver le composant " msgid " in library" msgstr " en librairie" -#: eeschema/netlist.cpp:202 +#: eeschema/netlist.cpp:93 msgid "List" msgstr "Liste" -#: eeschema/netlist.cpp:220 -msgid "No component" -msgstr "Pas de composants" - -#: eeschema/netlist.cpp:241 +#: eeschema/netlist.cpp:111 msgid "NbItems" msgstr "NbItems" -#: eeschema/netlist.cpp:345 -#: eeschema/netlist.cpp:387 -#: eeschema/netlist.cpp:410 -#: eeschema/netlist.cpp:427 +#: eeschema/netlist.cpp:219 +#: eeschema/netlist.cpp:263 +#: eeschema/netlist.cpp:284 msgid "Done" msgstr "Fini" -#: eeschema/netlist.cpp:351 +#: eeschema/netlist.cpp:225 msgid "Labels" msgstr "Labels" -#: eeschema/netlist.cpp:391 +#: eeschema/netlist.cpp:267 msgid "Hierar." msgstr "Hiérar." -#: eeschema/netlist.cpp:414 -msgid "Sorting Nets" -msgstr "Tri des Nets" - -#: eeschema/netlist.cpp:839 -msgid "Bad Bus Label: " -msgstr "Mauvais label de Bus: " - #: eeschema/selpart.cpp:39 +#: eeschema/find.cpp:649 msgid "No libraries are loaded" msgstr "Pas de librairies chargées" @@ -6251,8 +6385,8 @@ msgstr "" msgid "Error creating " msgstr "Erreur en création de " -#: eeschema/netform.cpp:63 -#: eeschema/netform.cpp:282 +#: eeschema/netform.cpp:62 +#: eeschema/netform.cpp:269 msgid "Failed to create file " msgstr "Impossible de créer le fichier " @@ -6574,62 +6708,61 @@ msgstr "Pin de Feuille de Hiérarchie" msgid "No New Hierarchal Label found" msgstr "Pas de nouveau Label Hiérarchique trouvé" -#: eeschema/erc.cpp:193 -msgid "Annotation Required!" -msgstr "Numérotation requise!" - -#: eeschema/erc.cpp:247 +#: eeschema/erc.cpp:200 msgid "Duplicate Sheet name" msgstr "Nom de feuille en double" -#: eeschema/erc.cpp:353 +#: eeschema/erc.cpp:239 +msgid "Annotation Required!" +msgstr "Numérotation requise!" + +#: eeschema/erc.cpp:363 msgid "ERC File" msgstr "Fichier ERC" -#: eeschema/erc.cpp:354 +#: eeschema/erc.cpp:364 msgid "Electronic rule check file (.erc)|*.erc" msgstr "Fichier Contrôle des règles électroniques (.erc)|*.erc" -#: eeschema/erc.cpp:406 +#: eeschema/erc.cpp:417 #, c-format msgid "HLabel %s not connected to SheetLabel" msgstr "HLabel %s non connecté à SheetLabel" -#: eeschema/erc.cpp:410 +#: eeschema/erc.cpp:421 #, c-format msgid "SheetLabel %s not connected to HLabel" msgstr "SheetLabel %s non connecté à HLabel" -#: eeschema/erc.cpp:432 +#: eeschema/erc.cpp:443 #, c-format msgid "Cmp %s, Pin %s (%s) Unconnected" msgstr "Cmp %s, Pin %s (%s) Non connectée" -#: eeschema/erc.cpp:447 +#: eeschema/erc.cpp:459 #, c-format msgid "Cmp %s, Pin %s (%s) not driven (Net %d)" msgstr "Cmp %s, Pin %s (%s) non pilotée (Net %d)" -#: eeschema/erc.cpp:460 +#: eeschema/erc.cpp:472 msgid "More than 1 Pin connected to UnConnect symbol" msgstr "Plus de 1 Pin connectée à un symbole de non connexion" -#: eeschema/erc.cpp:486 -#, fuzzy, c-format +#: eeschema/erc.cpp:498 +#, c-format msgid "Cmp %s, Pin %s (%s) connected to " -msgstr "Cmp %s, Pin %s (%s) Non connectée" +msgstr "Cmp %s, Pin %s (%s) connectée à " -#: eeschema/erc.cpp:492 -#, fuzzy, c-format +#: eeschema/erc.cpp:504 +#, c-format msgid "Cmp %s, Pin %s (%s) (net %d)" -msgstr "Cmp %s, Pin %s (%s) Non connectée" +msgstr "Cmp %s, Pin %s (%s) (net %d)" -#: eeschema/erc.cpp:609 -#, fuzzy +#: eeschema/erc.cpp:648 msgid "ERC report" -msgstr "Créer Rapport d'erreur" +msgstr "Rapport d'erreur" -#: eeschema/erc.cpp:619 +#: eeschema/erc.cpp:658 msgid "" "\n" "***** Sheet / (Root) \n" @@ -6637,7 +6770,7 @@ msgstr "" "\n" "***** Feuille/ ( Racine)\n" -#: eeschema/erc.cpp:624 +#: eeschema/erc.cpp:663 #, c-format msgid "" "\n" @@ -6646,7 +6779,7 @@ msgstr "" "\n" "***** Feuille %s\n" -#: eeschema/erc.cpp:643 +#: eeschema/erc.cpp:682 #, c-format msgid "" "\n" @@ -6954,10 +7087,6 @@ msgstr "Miroir Bloc ||" msgid "Copy to Clipboard" msgstr "Copie dans Presse papier" -#: eeschema/onrightclick.cpp:643 -msgid "About this Marker" -msgstr "" - #: eeschema/edit_label.cpp:48 msgid "Empty Text!" msgstr "Texte vide" @@ -7309,61 +7438,61 @@ msgstr "Les parts sont verrouillées" msgid "Fields" msgstr "Champs" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:95 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:97 msgid "Add a new custom field" msgstr "Ajouter un nouveau champ utilisateur" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:100 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:102 msgid "Delete one of the optional fields" msgstr "Supprimer un des champs optionnels." -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:104 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:106 msgid "Move Up" msgstr "Vers le haut ^" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:105 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:107 msgid "Move the selected optional fields up one position" msgstr "Déplacer le champ optionnel sélectionné de une position vers le haut" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:115 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:117 msgid "Visibility" msgstr "Visibilité" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:120 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:122 msgid "Show" msgstr "Visible" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:122 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:124 msgid "Check if you want this field visible" msgstr "Activer si vous voulez avoir ce champ visible" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:128 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:130 msgid "Check if you want this field's text rotated 90 degrees" msgstr "Activer si vous voulez avoir le texte de ce champ tourné à 90°" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:134 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:136 #: eeschema/dialog_edit_label_base.cpp:43 msgid "Bold" msgstr "Gras" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:134 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:136 #: eeschema/dialog_edit_label_base.cpp:43 msgid "Bold Italic" msgstr "Gras Italique" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:136 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:138 msgid "Style:" msgstr "Style:" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:138 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:140 msgid "The style of the currently selected field's text in the schemati" msgstr "Le style du texte du champ actuellement sélectionné" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:147 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:149 msgid "Field Name" msgstr "Nom Champ" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:152 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:154 msgid "" "The name of the currently selected field\n" "Some fixed fields names are not editable" @@ -7371,43 +7500,43 @@ msgstr "" "Le nom du champ actuellement sélectionné.\n" "Quelques noms de champs fixés ne sont pas modifiables." -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:161 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:163 msgid "Field Value" msgstr "Texte Champ" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:166 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:168 msgid "The text (or value) of the currently selected field" msgstr "Le texte (ou la valeur) du champ actuellement sélectionné" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:175 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:177 msgid "Size(\")" msgstr "Taille(\")" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:180 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:182 msgid "The size of the currently selected field's text in the schematic" msgstr "La taille du texte du champ actuellement sélectionné" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:192 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:194 msgid "PosX(\")" msgstr "PosX" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:197 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:199 msgid "The X coordinate of the text relative to the component" msgstr "La position X du texte relativement au composant" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:206 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:208 msgid "PosY(\")" msgstr "PosY" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:211 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:213 msgid "The Y coordinate of the text relative to the component" msgstr "La position Y du texte relativement au composant" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:222 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:224 msgid "Reset to Library Defaults" msgstr "Remettre aux Valeurs par Défaut en Librairie" -#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:223 +#: eeschema/dialog_edit_component_in_schematic_fbp.cpp:225 msgid "" "Set position and style of fields and component orientation to default lib value.\n" "Fields texts are not modified." @@ -7541,11 +7670,6 @@ msgstr "Cette feuille utilise des données partagées dans une hiérarchie compl msgid "Do we convert it in a simple hierarchical sheet (otherwise delete current sheet data)" msgstr "Doit on la convertir en une feuille de hiérarchie simple (autrement supprimer les données courantes)" -#: eeschema/class_drawsheet.cpp:703 -#: eeschema/dialog_create_component.cpp:147 -msgid "Name" -msgstr "Nom" - #: eeschema/class_drawsheet.cpp:704 msgid "FileName" msgstr "Nom Fichier" @@ -8128,93 +8252,93 @@ msgstr "Incrément Label:" msgid "Default Label Size" msgstr "Taille Label par défaut" -#: eeschema/netlist_control.cpp:131 -#: eeschema/netlist_control.cpp:255 +#: eeschema/netlist_control.cpp:129 +#: eeschema/netlist_control.cpp:253 msgid "Default format" msgstr "Format par défaut" -#: eeschema/netlist_control.cpp:142 +#: eeschema/netlist_control.cpp:140 msgid "&Browse Plugin" msgstr "&Examen Plugins" -#: eeschema/netlist_control.cpp:144 +#: eeschema/netlist_control.cpp:142 msgid "&Netlist" msgstr "&Netliste" -#: eeschema/netlist_control.cpp:157 +#: eeschema/netlist_control.cpp:155 msgid "&Ok" msgstr "&Ok" -#: eeschema/netlist_control.cpp:162 +#: eeschema/netlist_control.cpp:160 msgid "&Delete" msgstr "&Supprimer" -#: eeschema/netlist_control.cpp:171 -#: eeschema/netlist_control.cpp:275 +#: eeschema/netlist_control.cpp:169 +#: eeschema/netlist_control.cpp:273 msgid "Netlist" msgstr "Netliste" -#: eeschema/netlist_control.cpp:259 +#: eeschema/netlist_control.cpp:257 msgid "Use Net Names" msgstr "Utiliser nom de net" -#: eeschema/netlist_control.cpp:259 +#: eeschema/netlist_control.cpp:257 msgid "Use Net Numbers" msgstr "Utiliser numéro de net" -#: eeschema/netlist_control.cpp:260 +#: eeschema/netlist_control.cpp:258 msgid "Netlist Options:" msgstr "Options de Netliste:" -#: eeschema/netlist_control.cpp:269 +#: eeschema/netlist_control.cpp:267 msgid "Simulator command:" msgstr "Simulateur commande:" -#: eeschema/netlist_control.cpp:278 +#: eeschema/netlist_control.cpp:276 msgid "&Run Simulator" msgstr "&Simulateur" -#: eeschema/netlist_control.cpp:316 +#: eeschema/netlist_control.cpp:314 msgid "Add Plugin" msgstr "Ajouter Plugin" -#: eeschema/netlist_control.cpp:336 +#: eeschema/netlist_control.cpp:334 msgid "Netlist command:" msgstr "Commande netliste:" -#: eeschema/netlist_control.cpp:342 +#: eeschema/netlist_control.cpp:340 msgid "Title:" msgstr "Titre:" -#: eeschema/netlist_control.cpp:360 +#: eeschema/netlist_control.cpp:358 msgid "Plugin files:" msgstr "Fichiers Plugins:" -#: eeschema/netlist_control.cpp:383 +#: eeschema/netlist_control.cpp:381 msgid "Do not forget to choose a title for this netlist control page" msgstr "Ne pas oublier de choisir un titre pour cette page de contrôle de netliste" -#: eeschema/netlist_control.cpp:463 +#: eeschema/netlist_control.cpp:461 msgid "SPICE netlist file (.cir)|*.cir" msgstr "Fichier netliste SPICE (.cir)|*.cir" -#: eeschema/netlist_control.cpp:468 +#: eeschema/netlist_control.cpp:466 msgid "CadStar netlist file (.frp)|*.frp" msgstr "Fichier netliste CadStar (.frp)|*.frp" -#: eeschema/netlist_control.cpp:479 +#: eeschema/netlist_control.cpp:477 msgid "Save Netlist Files" msgstr "Sauver Fichiers Netlistes" -#: eeschema/netlist_control.cpp:491 +#: eeschema/netlist_control.cpp:489 msgid "Must be Annotated, Continue ?" msgstr "Annotation nécessaire, continuer?" -#: eeschema/netlist_control.cpp:654 +#: eeschema/netlist_control.cpp:651 msgid "Error. You must provide a command String" msgstr "Erreur. Vous devez entrer une ligne de commande" -#: eeschema/netlist_control.cpp:659 +#: eeschema/netlist_control.cpp:656 msgid "Error. You must provide a Title" msgstr "Erreur. Vous devez entrer un titre" @@ -8260,12 +8384,10 @@ msgid "Options :" msgstr "Options :" #: eeschema/dialog_cmp_graphic_properties.cpp:154 -#: eeschema/pinedit-dialog.cpp:180 msgid "Common to Units" msgstr "Commun aux Unités" #: eeschema/dialog_cmp_graphic_properties.cpp:158 -#: eeschema/pinedit-dialog.cpp:184 msgid "Common to convert" msgstr "Commun à converti" @@ -8484,43 +8606,43 @@ msgid "Text Shape:" msgstr "Aspect Texte:" #: eeschema/dialog_bodygraphictext_properties_base.cpp:82 -#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:54 +#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:56 msgid "Align left" msgstr "Alignement à gauche" #: eeschema/dialog_bodygraphictext_properties_base.cpp:82 #: eeschema/dialog_bodygraphictext_properties_base.cpp:88 -#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:54 -#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:67 +#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:56 +#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:69 msgid "Align center" msgstr "Alignement au centre" #: eeschema/dialog_bodygraphictext_properties_base.cpp:82 -#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:54 +#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:56 msgid "Align right" msgstr "Alignement à droite" #: eeschema/dialog_bodygraphictext_properties_base.cpp:84 -#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:56 +#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:58 msgid "Horiz. Justify" msgstr "Justification Horiz." #: eeschema/dialog_bodygraphictext_properties_base.cpp:88 -#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:67 +#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:69 msgid "Align bottom" msgstr "Alignement en bas" #: eeschema/dialog_bodygraphictext_properties_base.cpp:88 -#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:67 +#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:69 msgid "Align top" msgstr "Alignement au sommet" #: eeschema/dialog_bodygraphictext_properties_base.cpp:90 -#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:69 +#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:71 msgid "Vert. Justify" msgstr "Vert. Justifié" -#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:143 +#: eeschema/dialog_edit_libentry_fields_in_lib_base.cpp:145 msgid "The vertical height of the currently selected field's text in the schematic" msgstr "La taille du texte du champ actuellement sélectionné" @@ -8919,57 +9041,13 @@ msgstr "Valeur Composant" msgid "Component footprint" msgstr "Module du Composant" -#: eeschema/eelibs_read_libraryfiles.cpp:67 -#, c-format -msgid "Library <%s> not found" -msgstr "Librairie %s non trouvée" - -#: eeschema/eelibs_read_libraryfiles.cpp:161 -msgid " error!" -msgstr " erreur!" - -#: eeschema/eelibs_read_libraryfiles.cpp:169 -msgid "" -"The following libraries could not be found:\n" -"\n" -msgstr "" -"The following libraries could not be found:\n" -"\n" - -#: eeschema/eelibs_read_libraryfiles.cpp:171 -msgid "Load error!" -msgstr "Erreur de chargement!" - -#: eeschema/eelibs_read_libraryfiles.cpp:301 -#: eeschema/eelibs_read_libraryfiles.cpp:308 -msgid "File <" -msgstr "Fichier <" - -#: eeschema/eelibs_read_libraryfiles.cpp:301 -msgid "> is empty!" -msgstr "> est vide" - -#: eeschema/eelibs_read_libraryfiles.cpp:309 -msgid "> is NOT EESCHEMA library!" -msgstr "> n'est PAS une librairie EESCHEMA !" - -#: eeschema/eelibs_read_libraryfiles.cpp:326 -msgid "Library <" -msgstr "Librairie <" - -#: eeschema/eelibs_read_libraryfiles.cpp:327 -msgid "> header read error" -msgstr "> erreur lecture entête" - #: eeschema/class_drc_erc_item.cpp:39 -#, fuzzy msgid "ERC err unspecified" -msgstr "Non specifié" +msgstr "Erreur ERC non specifiée" #: eeschema/class_drc_erc_item.cpp:41 -#, fuzzy msgid "Duplicate sheet names within a given sheet" -msgstr "Nom de feuille en double" +msgstr "Nom de feuille en double dans une feuile donnée" #: eeschema/class_drc_erc_item.cpp:43 msgid "Pin not connected (and no connect symbol found on this pin)" @@ -8988,9 +9066,8 @@ msgid "Confict problem between pins. Severity: error" msgstr "Problème de conflit entre pins. Sévérité: erreur" #: eeschema/class_drc_erc_item.cpp:51 -#, fuzzy msgid "Mismatch between hierarchical labels and pins sheets" -msgstr "Addition de pins de hiérarchie dans les feuilles symboles de hiérarchie" +msgstr "Différence entre labels de hiérarchieet pins de hiérarchie" #: eeschema/class_drc_erc_item.cpp:53 msgid "A no connect symbol is connected to more than 1 pin" @@ -9012,28 +9089,28 @@ msgstr "Pas de nom de composant!" msgid "Component [%s] not found!" msgstr "Composant [%s] non trouvé!" -#: eeschema/load_one_schematic_file.cpp:71 +#: eeschema/load_one_schematic_file.cpp:70 msgid "Failed to open " msgstr "Erreur ouverture " -#: eeschema/load_one_schematic_file.cpp:76 +#: eeschema/load_one_schematic_file.cpp:75 msgid "Loading " msgstr "Chargement " -#: eeschema/load_one_schematic_file.cpp:83 -#: eeschema/load_one_schematic_file.cpp:114 +#: eeschema/load_one_schematic_file.cpp:82 +#: eeschema/load_one_schematic_file.cpp:113 msgid " is NOT an EESchema file!" msgstr " n'est PAS un fichier EESchema!" -#: eeschema/load_one_schematic_file.cpp:94 +#: eeschema/load_one_schematic_file.cpp:93 msgid " was created by a more recent version of EESchema and may not load correctly. Please consider updating!" msgstr " a été créé par une version plus récente de Eeschema et peut ne pas être chargé correctement. SVP mettez à jour Eeschema!" -#: eeschema/load_one_schematic_file.cpp:103 +#: eeschema/load_one_schematic_file.cpp:102 msgid " was created by an older version of EESchema. It will be stored in the new file format when you save this file again." msgstr " a été créé par une version plus ancienne de Eeschema. Il sera enregistré au nouveau format après la prochaine sauvegarde." -#: eeschema/load_one_schematic_file.cpp:415 +#: eeschema/load_one_schematic_file.cpp:380 msgid "Done Loading " msgstr "Chargement terminé" @@ -9170,14 +9247,12 @@ msgid "&Del Markers" msgstr "&Supprimer Marqueurs" #: eeschema/dialog_erc_base.cpp:101 -#, fuzzy msgid "Create ERC report" msgstr "Créer Rapport d'erreur" #: eeschema/dialog_erc_base.cpp:108 -#, fuzzy msgid "Markers:" -msgstr "Marqueur" +msgstr "Marqueurs:" #: eeschema/dialog_erc_base.cpp:120 msgid "ERC" @@ -9187,6 +9262,40 @@ msgstr "ERC" msgid "Reset" msgstr "Défaut" +#: eeschema/eelibs_read_libraryfiles.cpp:69 +#, c-format +msgid "Library <%s> not found" +msgstr "Librairie %s non trouvée" + +#: eeschema/eelibs_read_libraryfiles.cpp:163 +msgid " error!" +msgstr " erreur!" + +#: eeschema/eelibs_read_libraryfiles.cpp:172 +msgid "The following libraries could not be found:" +msgstr "Les librairies suivantes n'ont pas pu être trouvées:" + +#: eeschema/eelibs_read_libraryfiles.cpp:305 +#: eeschema/eelibs_read_libraryfiles.cpp:312 +msgid "File <" +msgstr "Fichier <" + +#: eeschema/eelibs_read_libraryfiles.cpp:305 +msgid "> is empty!" +msgstr "> est vide" + +#: eeschema/eelibs_read_libraryfiles.cpp:313 +msgid "> is NOT EESCHEMA library!" +msgstr "> n'est PAS une librairie EESCHEMA !" + +#: eeschema/eelibs_read_libraryfiles.cpp:330 +msgid "Library <" +msgstr "Librairie <" + +#: eeschema/eelibs_read_libraryfiles.cpp:331 +msgid "> header read error" +msgstr "> erreur lecture entête" + #: eeschema/component_wizard/dialog_component_setup.cpp:137 msgid "Quick KICAD Library Component Builder" msgstr "" @@ -9502,52 +9611,16 @@ msgstr "Modules (Tous): %d" msgid "Footprints (filtered): %d" msgstr "Modules (filtrés): %d" -#: cvpcb/listlib.cpp:63 -msgid "No PCB foot print libraries are listed in the current project file." -msgstr "Aucune librairie de modules PCB listée dans le fichier projet courant." - -#: cvpcb/listlib.cpp:64 -msgid "Project File Error" -msgstr "Erreur en Fichier Projet" - -#: cvpcb/listlib.cpp:80 #: cvpcb/loadcmp.cpp:50 #, c-format msgid "PCB foot print library file <%s> could not be found in the default search paths." msgstr "Le fichier librairie de modules PCB <%s> n'a pas pu être trouvé dans les chemins de recherche par défaut." -#: cvpcb/listlib.cpp:91 #: cvpcb/loadcmp.cpp:61 #, c-format msgid "Could not open PCB foot print library file <%s>." msgstr "Ne peut ouvrir le fichier librairie de modules PCB <%s>." -#: cvpcb/listlib.cpp:101 -#, c-format -msgid "<%s> is not a valid Kicad PCB foot print library" -msgstr "<%s> n'est pas un fichier librairie module Kicad PCB valide." - -#: cvpcb/listlib.cpp:133 -#, c-format -msgid "Unexpected end of file occurred while parsing PCB foot print library <%s>." -msgstr "Fin de fichier inattendue lors de l'analyse de la librairie de modules PCB <%s>." - -#: cvpcb/listlib.cpp:147 -msgid "" -"The following mdc files could not be found:\n" -"\n" -msgstr "" -"The following fichiers mdc could not be found:\n" -"\n" - -#: cvpcb/listlib.cpp:155 -msgid "" -"The following mdc files are invalid:\n" -"\n" -msgstr "" -"The fichiers mdcsuivants sont invalides:\n" -"\n" - #: cvpcb/loadcmp.cpp:74 #, c-format msgid "<%s> is not a valid Kicad PCB foot print library." @@ -9558,6 +9631,34 @@ msgstr "<%s> in'est pas un fichier de module PCB Kicad valide." msgid "Module %s not found" msgstr "Module %s non trouvé" +#: cvpcb/listlib.cpp:62 +msgid "No PCB foot print libraries are listed in the current project file." +msgstr "Aucune librairie de modules PCB listée dans le fichier projet courant." + +#: cvpcb/listlib.cpp:63 +msgid "Project File Error" +msgstr "Erreur en Fichier Projet" + +#: cvpcb/listlib.cpp:88 +msgid " (file cannot be opened)" +msgstr "(le fichier n'a pas pu être ouvert)" + +#: cvpcb/listlib.cpp:96 +msgid " (Not a Kicad file)" +msgstr "(N'est pas un fichier Kicad)" + +#: cvpcb/listlib.cpp:126 +msgid " (Unexpected end of file)" +msgstr "(Fin de fichier inattendue)" + +#: cvpcb/listlib.cpp:141 +msgid "Some files could not be found!" +msgstr "Certains fichiers n'ont pas pu être trouvés!" + +#: cvpcb/listlib.cpp:150 +msgid "Some files are invalid!" +msgstr "Certains fichiers sont invalides!" + #: cvpcb/autosel.cpp:93 #, c-format msgid "Footprint alias library file <%s> could not be found in the default search paths." @@ -9620,7 +9721,6 @@ msgid "1:1 zoom" msgstr "1:1 zoom" #: cvpcb/readschematicnetlist.cpp:114 -#: kicad/prjconfig.cpp:94 msgid "> not found" msgstr "> non trouvé" @@ -10713,10 +10813,6 @@ msgstr "Contour Pcb" msgid "BAD INDEX" msgstr "BAD INDEX" -#: common/edaappl.cpp:95 -msgid "Default" -msgstr "Défaut" - #: common/edaappl.cpp:112 msgid "French" msgstr "Français" @@ -10985,6 +11081,10 @@ msgstr "Via Aveugle/Enterrée" msgid "Kicad footprint library files (*.mod)|*.mod" msgstr "Fichiers Modules Kicad (*.mod)|*.mod" +#: common/class_marker_base.cpp:183 +msgid "Marker Info" +msgstr "Info Marqueur" + #: common/drawframe.cpp:302 msgid "Inch" msgstr "Pouce" @@ -10993,63 +11093,67 @@ msgstr "Pouce" msgid "??" msgstr "??" +#: common/dialog_load_error.cpp:5 +msgid "Load Error!" +msgstr "Erreur de Chargement!" + #: 3d-viewer/3d_aux.cpp:206 msgid "Vertex " msgstr "Vertex " -#: 3d-viewer/3d_canvas.cpp:323 +#: 3d-viewer/3d_canvas.cpp:330 msgid "Zoom +" msgstr "Zoom +" -#: 3d-viewer/3d_canvas.cpp:328 +#: 3d-viewer/3d_canvas.cpp:335 msgid "Zoom -" msgstr "Zoom -" -#: 3d-viewer/3d_canvas.cpp:334 +#: 3d-viewer/3d_canvas.cpp:341 msgid "Top View" msgstr "Vue de dessus" -#: 3d-viewer/3d_canvas.cpp:339 +#: 3d-viewer/3d_canvas.cpp:346 msgid "Bottom View" msgstr "Vue de dessous" -#: 3d-viewer/3d_canvas.cpp:345 +#: 3d-viewer/3d_canvas.cpp:352 msgid "Right View" msgstr "Vue à Droite" -#: 3d-viewer/3d_canvas.cpp:350 +#: 3d-viewer/3d_canvas.cpp:357 msgid "Left View" msgstr "Vue à Gauche" -#: 3d-viewer/3d_canvas.cpp:357 +#: 3d-viewer/3d_canvas.cpp:364 msgid "Front View" msgstr "Vue de face" -#: 3d-viewer/3d_canvas.cpp:362 +#: 3d-viewer/3d_canvas.cpp:369 msgid "Back View" msgstr "Vue arrière" -#: 3d-viewer/3d_canvas.cpp:368 +#: 3d-viewer/3d_canvas.cpp:375 #: 3d-viewer/3d_toolbar.cpp:85 msgid "Move left <-" msgstr "Vers la gauche <-" -#: 3d-viewer/3d_canvas.cpp:373 +#: 3d-viewer/3d_canvas.cpp:380 #: 3d-viewer/3d_toolbar.cpp:88 msgid "Move right ->" msgstr "Vers la droite ->" -#: 3d-viewer/3d_canvas.cpp:378 +#: 3d-viewer/3d_canvas.cpp:385 #: 3d-viewer/3d_toolbar.cpp:91 msgid "Move Up ^" msgstr "Vers le haut ^" -#: 3d-viewer/3d_canvas.cpp:383 +#: 3d-viewer/3d_canvas.cpp:390 #: 3d-viewer/3d_toolbar.cpp:94 msgid "Move Down" msgstr "Vers le bas" -#: 3d-viewer/3d_canvas.cpp:616 +#: 3d-viewer/3d_canvas.cpp:624 msgid "3D Image filename:" msgstr "Nom fichier Image 3D:" @@ -11278,6 +11382,10 @@ msgstr "Créer Fichier SVG" msgid "Fill Zones Options" msgstr "Options de Remplissage de Zone" +#: pcbnew/dialog_design_rules_base.h:94 +msgid "Design Rules Editor" +msgstr "Editeur deRègles de Conception" + #: pcbnew/dialog_non_copper_zones_properties_base.h:59 msgid "Non Copper Zones Properties" msgstr "Propriétés des Zones sur couches non cuivre" @@ -11650,6 +11758,25 @@ msgstr "DCodes id." msgid "Page Settings" msgstr "Ajustage opt Page" +#~ msgid "No component" +#~ msgstr "Pas de composants" +#~ msgid "Sorting Nets" +#~ msgstr "Tri des Nets" +#~ msgid "Bad Bus Label: " +#~ msgstr "Mauvais label de Bus: " +#~ msgid "<%s> is not a valid Kicad PCB foot print library" +#~ msgstr "<%s> n'est pas un fichier librairie module Kicad PCB valide." +#~ msgid "" +#~ "Unexpected end of file occurred while parsing PCB foot print library <%s>." +#~ msgstr "" +#~ "Fin de fichier inattendue lors de l'analyse de la librairie de modules " +#~ "PCB <%s>." +#~ msgid "" +#~ "The following mdc files could not be found:\n" +#~ "\n" +#~ msgstr "" +#~ "The following fichiers mdc could not be found:\n" +#~ "\n" #~ msgid "sheet %s (loc X=%f, Y=%f): %s\n" #~ msgstr "feuille %s (pos X=%f, Y=%f): %s\n" #~ msgid "ERC finished, no error\n" diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 05f21b1120..ee7a72dd3c 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -32,6 +32,8 @@ set(PCBNEW_SRCS deltrack.cpp dialog_copper_zones.cpp dialog_copper_zones_base.cpp + dialog_design_rules.cpp + dialog_design_rules_base.cpp dialog_display_options.cpp dialog_display_options_base.cpp dialog_drc_base.cpp diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 152c1151c3..e538ae6172 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -36,6 +36,11 @@ BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) : m_Layer[layer].m_Name = ReturnPcbLayerName( layer, true ); m_Layer[layer].m_Type = LT_SIGNAL; } + + // Add the default Netclass to list + m_NetClassesList.m_Parent = this; + NETCLASS * default_netclass = new NETCLASS(this); + m_NetClassesList.AddNetclass( default_netclass ); } @@ -929,6 +934,9 @@ bool BOARD::Save( FILE* aFile ) const bool rc = false; BOARD_ITEM* item; + // save the netclasses + m_NetClassesList.Save( aFile ); + // save the nets for( unsigned ii = 0; ii < m_NetInfo->GetNetsCount(); ii++ ) if( !m_NetInfo->GetNetItem( ii )->Save( aFile ) ) diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index 86e5a8c54b..c0f9c9e85e 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -22,7 +22,7 @@ enum LAYER_T { LT_SIGNAL, LT_POWER, LT_MIXED, - LT_JUMPER, + LT_JUMPER }; @@ -97,7 +97,8 @@ public: std::vector m_LocalRatsnest; /* Rastnest list relative to a given footprint * (used while moving a footprint) */ - ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress + NETCLASS_LIST m_NetClassesList; // List of current netclasses. There is always the default netclass + ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress BOARD( EDA_BaseStruct* aParent, WinEDA_BasePcbFrame* frame ); ~BOARD(); @@ -335,6 +336,17 @@ public: */ int ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount ); + /** + * Function TransfertDesignRulesToNets + * Copy Netclass parameters to each net, corresponding to its net class + * Must be called after a Design Rules edition, or after reading a netlist (or editing the list of nets) + * Also this function remove the non existing nets in netclasses and add net nets in default netclass + * (this happens after reading a netlist) + * @param none + * @return none + */ + void TransfertDesignRulesToNets( ); + /** * Function Save * writes the data structures for this object out to a FILE in "*.brd" format. diff --git a/pcbnew/class_netclass.cpp b/pcbnew/class_netclass.cpp new file mode 100644 index 0000000000..01823d3dae --- /dev/null +++ b/pcbnew/class_netclass.cpp @@ -0,0 +1,298 @@ +/*************************************/ +/* class to handle Net Classes */ +/**************************************/ + +#include "fctsys.h" + +#include "common.h" +#include "kicad_string.h" +#include "pcbnew.h" + + +NET_DESIGN_PARAMS::NET_DESIGN_PARAMS() +{ + m_TracksWidth = 170; // "Default" value for tracks thickness used to route this net + m_TracksMinWidth = 150; // Minimum value for tracks thickness (used in DRC) + m_ViasSize = 550; // "Default" value for vias sizes used to route this net + m_ViasMinSize = 400; // Minimum value for vias sizes (used in DRC) + m_Clearance = 140; // "Default" clearance when routing + m_MinClearance = 110; // Minimum value for clearance (used in DRC) +} + + +/* A NETCLASS handles a list of nets and the parameters used to route or test (in DRC) these nets + * This is mainly used in autotouters like Freeroute, but this can be also used in manual routing + */ + +NETCLASS::NETCLASS( BOARD* aParent, const wxString& aName ) +{ + m_Parent = aParent; + m_Name = aName; // Name of the net class +} + + +NETCLASS::~NETCLASS() +{ +} + + +NETCLASS_LIST::NETCLASS_LIST( BOARD* aParent ) +{ + m_Parent = aParent; + std::vector m_Netclass_List; +} + + +NETCLASS_LIST::~NETCLASS_LIST() +{ + ClearList(); +} + + +void NETCLASS_LIST::ClearList() +{ + // the NETCLASS_LIST is owner of its items, so delete them + for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ ) + delete m_Netclass_List[ii]; + + m_Netclass_List.clear(); +} + + +/** Function AddNetclass() + * @param aNetclass = a pointer to the netclass to add + * @return true if Ok, false if cannot be added (mainly because a netclass with the same name exists) + */ +bool NETCLASS_LIST::AddNetclass( NETCLASS* aNetclass ) +{ + // Test for an existing netclass: + for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ ) + { + if( m_Netclass_List[ii]->m_Name.CmpNoCase( aNetclass->m_Name ) == 0 ) + return false; // this netclass already exists + } + + m_Netclass_List.push_back( aNetclass ); + return true; +} + + +/** + * Function TransfertDesignRulesToNets + * Copy Netclass parameters to each net, corresponding to its net class + * Must be called after a Design Rules edition, or after reading a netlist (or editing the list of nets) + * Also this function remove the non existing nets in netclasses and add net nets in default netclass + * (this happens after reading a netlist) + * @param none + * @return none + */ +void BOARD::TransfertDesignRulesToNets() +{ + // Clear .m_Flag member of nets (used to detect not in netclass list nets) + for( unsigned ii = 1; ; ii++ ) + { + NETINFO_ITEM* net = FindNet( ii ); + if( net == NULL ) + break; + net->m_Flag = 0; + } + + for( unsigned ii = 0; ii < m_NetClassesList.m_Netclass_List.size(); ii++ ) + { + //Transfert rules and netclass name to nets: + NETCLASS* netclass = m_NetClassesList.m_Netclass_List[ii]; + for( unsigned jj = 0; jj < netclass->GetMembersCount(); jj++ ) + { + wxString netname = netclass->GetMemberName( jj ); + NETINFO_ITEM* net = FindNet( netname ); + if( net == NULL ) // This net does not exists: remove it + { + netclass->m_MembersNetNames.RemoveAt( jj ); + jj--; + } + else + { + net->SetClass( *netclass ); + net->m_Flag = 1; + } + } + } + + // Now, set nets that do not have yet a netclass to default netclass + NETCLASS* defaultnetclass = m_NetClassesList.m_Netclass_List[0]; + for( unsigned ii = 1; ; ii++ ) + { + NETINFO_ITEM* net = FindNet( ii ); + if( net == NULL ) + break; + if( net->m_Flag == 0 ) + { + net->SetClass( *defaultnetclass ); + defaultnetclass->AddMember( net->GetNetname() ); + } + } +} + + +/** + * Function Save + * writes the data structures for this object out to a FILE in "*.brd" format. + * @param aFile The FILE to write to. + * @return bool - true if success writing else false. + */ +bool NETCLASS_LIST::Save( FILE* aFile ) const +{ + bool success = true; + + for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ ) + { + success = m_Netclass_List[ii]->Save( aFile ); + if( !success ) + break; + } + + return success; +} + + +/** + * Function Save + * writes the data structures for this object out to a FILE in "*.brd" format. + * @param aFile The FILE to write to. + * @return bool - true if success writing else false. + */ +bool NETCLASS::Save( FILE* aFile ) const +{ + bool success = true; + + fprintf( aFile, "$NETCLASS\n" ); + fprintf( aFile, "Name \"%s\"\n", CONV_TO_UTF8( m_Name ) ); + + // Write parameters + success = m_NetParams.Save( aFile ); + + // Write members list: + for( unsigned ii = 0; ii < GetMembersCount(); ii++ ) + fprintf( aFile, "AddNet \"%s\"\n", CONV_TO_UTF8( GetMemberName( ii ) ) ); + + + fprintf( aFile, "$EndNETCLASS\n" ); + + return success; +} + + +/** + * Function Save + * writes the data structures for this object out to a FILE in "*.brd" format. + * @param aFile The FILE to write to. + * @return bool - true if success writing else false. + */ +bool NET_DESIGN_PARAMS::Save( FILE* aFile ) const +{ + bool success = true; + + fprintf( aFile, "$PARAMS_START\n" ); + fprintf( aFile, "TracksWidth %d\n", m_TracksWidth ); + fprintf( aFile, "TracksMinWidth %d\n", m_TracksMinWidth ); + fprintf( aFile, "ViasSize %d\n", m_ViasSize ); + fprintf( aFile, "ViasMinSize %d\n", m_ViasMinSize ); + fprintf( aFile, "Clearance %d\n", m_Clearance ); + fprintf( aFile, "MinClearance %d\n", m_MinClearance ); + fprintf( aFile, "$PARAMS_END\n" ); + + return success; +} + + +/** + * Function ReadDescr + * reads the data structures for this object from a FILE in "*.brd" format. + * @param aFile The FILE to read to. + * @return bool - true if success reading else false. + */ +bool NET_DESIGN_PARAMS::ReadDescr( FILE* aFile, int* aLineNum ) +{ + bool success = true; + char Line[1024]; + + while( GetLine( aFile, Line, aLineNum, 1024 ) != NULL ) + { + if( strnicmp( Line, "$PARAMS_END", 11 ) == 0 ) + return success; + + if( strnicmp( Line, "TracksWidth", 11 ) == 0 ) + { + m_TracksWidth = atoi( Line + 11 ); + continue; + } + if( strnicmp( Line, "TracksMinWidth", 14 ) == 0 ) + { + m_TracksMinWidth = atoi( Line + 14 ); + continue; + } + if( strnicmp( Line, "ViasSize", 8 ) == 0 ) + { + m_ViasSize = atoi( Line + 8 ); + continue; + } + if( strnicmp( Line, "ViasMinSize", 11 ) == 0 ) + { + m_ViasMinSize = atoi( Line + 11 ); + continue; + } + if( strnicmp( Line, "Clearance", 9 ) == 0 ) + { + m_Clearance = atoi( Line + 9 ); + continue; + } + if( strnicmp( Line, "MinClearance", 12 ) == 0 ) + { + m_MinClearance = atoi( Line + 12 ); + continue; + } + } + + return success; +} + + +/** + * Function ReadDescr + * reads the data structures for this object from a FILE in "*.brd" format. + * @param aFile The FILE to read to. + * @return bool - true if success reading else false. + */ +bool NETCLASS::ReadDescr( FILE* aFile, int* aLineNum ) +{ + bool success = true; + char Line[1024]; + char Buffer[1024]; + + while( GetLine( aFile, Line, aLineNum, 1024 ) != NULL ) + { + if( strnicmp( Line, "$endNETCLASS", 6 ) == 0 ) + return success; + + if( strnicmp( Line, "$PARAMS_START", 13 ) == 0 ) + { + m_NetParams.ReadDescr( aFile, aLineNum ); + continue; + } + + if( strnicmp( Line, "Name", 4 ) == 0 ) + { + ReadDelimitedText( Buffer, Line + 4, sizeof(Buffer) ); + m_Name = CONV_FROM_UTF8( Buffer ); + } + + if( strnicmp( Line, "AddNet", 6 ) == 0 ) + { + ReadDelimitedText( Buffer, Line + 6, sizeof(Buffer) ); + wxString netname = CONV_FROM_UTF8( Buffer ); + AddMember( netname ); + } + } + + return success; +} diff --git a/pcbnew/class_netclass.h b/pcbnew/class_netclass.h new file mode 100644 index 0000000000..3cde7cead1 --- /dev/null +++ b/pcbnew/class_netclass.h @@ -0,0 +1,156 @@ +/*************************************/ +/* class to Net Classes */ +/**************************************/ + +#ifndef CLASS_NETCLASS_H +#define CLASS_NETCLASS_H + +/* this small class NET_DESIGN_PARAMS handles netclass parameters. + * This is a separate class because these parameters are also duplicated + * (for calculation time consideration) in each NETINFO_ITEM when making tests DRC and routing + */ +class NET_DESIGN_PARAMS +{ +public: + int m_TracksWidth; // "Default" value for tracks thickness used to route this net + int m_TracksMinWidth; // Minimum value for tracks thickness (used in DRC) + int m_ViasSize; // "Default" value for vias sizes used to route this net + int m_ViasMinSize; // Minimum value for vias sizes (used in DRC) + int m_Clearance; // "Default" clearance when routing + int m_MinClearance; // Minimum value for clearance (used in DRC) +public: + NET_DESIGN_PARAMS(); + ~NET_DESIGN_PARAMS() {} + + /** + * Function Save + * writes the data structures for this object out to a FILE in "*.brd" format. + * @param aFile The FILE to write to. + * @return bool - true if success writing else false. + */ + bool Save( FILE* aFile ) const; + + /** + * Function ReadDescr + * reads the data structures for this object from a FILE in "*.brd" format. + * @param aFile The FILE to read to. + * @return bool - true if success reading else false. + */ + bool ReadDescr( FILE* aFile, int* aLineNum ); +}; + +/** + * @info A NETCLASS handles a list of nets and the parameters used to route or test these nets + */ +class NETCLASS +{ +public: + BOARD* m_Parent; + wxString m_Name; // Name of the net class + wxArrayString m_MembersNetNames; // List of nets members of this class + NET_DESIGN_PARAMS m_NetParams; // values of net classes parameters + +public: + NETCLASS( BOARD* aParent, const wxString& aName = wxT( "default" ) ); + ~NETCLASS(); + + /** Function GetMembersCount + *@return the number of nets using this rule + */ + unsigned GetMembersCount() const + { + return m_MembersNetNames.GetCount(); + } + + + void ClearMembersList() + { + m_MembersNetNames.Clear(); + } + + + void AddMember( const wxString& aNetname ) + { + m_MembersNetNames.Add( aNetname ); + } + + + wxString GetMemberName( unsigned aIdx ) const + { + if( aIdx < GetMembersCount() ) + return m_MembersNetNames[aIdx]; + else + return wxEmptyString; + } + + + /** + * Function Save + * writes the data structures for this object out to a FILE in "*.brd" format. + * @param aFile The FILE to write to. + * @return bool - true if success writing else false. + */ + bool Save( FILE* aFile ) const; + + /** + * Function ReadDescr + * reads the data structures for this object from a FILE in "*.brd" format. + * @param aFile The FILE to read to. + * @return bool - true if success reading else false. + */ + bool ReadDescr( FILE* aFile, int* aLineNum ); +}; + +/* This NETCLASS_LIST handles the list of NETCLASS for the board + * Note: the NETCLASS_LIST is owner of all NETCLASS in list + */ +class NETCLASS_LIST +{ +public: + BOARD* m_Parent; + std::vector m_Netclass_List; + +public: + NETCLASS_LIST( BOARD* aParent = NULL ); + ~NETCLASS_LIST(); + void ClearList(); + + /** Function GetNetClassCount() + * @return the number of existing netclasses + */ + unsigned GetNetClassCount() + { + return m_Netclass_List.size(); + } + + + /** Function GetNetClass() + * @param aIdx = the index in netclass list + * @return a NETCLASS* pointer on the netclass + */ + NETCLASS* GetNetClass( unsigned aIdx ) + { + if( GetNetClassCount() && aIdx < GetNetClassCount() ) + return m_Netclass_List[aIdx]; + else + return NULL; + } + + + /** Function AddNetclass() + * @param aNetclass = a pointer to the netclass to add + * @return true if Ok, false if cannot be added (mainly because a netclass with the same name exists) + */ + bool AddNetclass( NETCLASS* aNetclass ); + + /** + * Function Save + * writes the data structures for this object out to a FILE in "*.brd" format. + * @param aFile The FILE to write to. + * @return bool - true if success writing else false. + */ + bool Save( FILE* aFile ) const; +}; + + +#endif // #ifndef CLASS_NETCLASS_H diff --git a/pcbnew/class_netinfo.h b/pcbnew/class_netinfo.h index b49adce972..78ffd14a4e 100644 --- a/pcbnew/class_netinfo.h +++ b/pcbnew/class_netinfo.h @@ -9,6 +9,8 @@ #ifndef __CLASSES_NETINFO__ #define __CLASSES_NETINFO__ +#include "class_netclass.h" + // Forward declaration: class NETINFO_ITEM; @@ -147,17 +149,21 @@ private: class NETINFO_ITEM { private: - int m_NetCode; // this is a number equivalent to the net name - // Used for fast comparisons in rastnest and DRC computations. - wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema - wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout + int m_NetCode; // this is a number equivalent to the net name + // Used for fast comparisons in rastnest and DRC computations. + wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema + wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout + wxString m_NetClassName; /* Net Class name. if void this is equivalent to "default" (the first + * item of the net classes list + */ + NET_DESIGN_PARAMS m_NetParams; // values of net classes parameters public: - int m_NbNodes; // Pads count for this net + int m_NbNodes; // Pads count for this net int m_NbLink; // Ratsnets count for this net int m_NbNoconn; // Ratsnets remaining to route count - int m_ForceWidth; // specific width (0 = default width) + int m_Flag; // used in some calculations. Had no special meaning std::vector m_ListPad; // List of pads connected to this net unsigned m_RatsnestStartIdx; /* Starting point of ratsnests of this net (included) * in a general buffer of ratsnest (a vector buffer) @@ -168,7 +174,86 @@ public: ~NETINFO_ITEM(); - /* Readind and writing data on files */ + /** Functions SetClassParameters + * copy the class parameters in the locale buffer m_NetParams + */ + void SetClassParameters(const NET_DESIGN_PARAMS& aParams ) + { + m_NetParams = aParams; + } + + /** Functions SetClass + * copy the class Name and class parmeters + */ + void SetClass(const NETCLASS& aNetclass ) + { + m_NetParams = aNetclass.m_NetParams; + m_NetClassName = aNetclass.m_Name; + } + + /** Functions GetClassName + * @return the class Name + */ + wxString GetClassName( ) const + { + return m_NetClassName; + } + + /** function GetTracksWidth() + * @return the "default" value for tracks thickness used to route this net + */ + int GetTracksWidth() + { + return m_NetParams.m_TracksWidth; + } + + + /** Function GetTracksMinWidth() + * @return the Minimum value for tracks thickness (used in DRC) + */ + int GetTracksMinWidth() + { + return m_NetParams.m_TracksMinWidth = 150; + } + + + /** Function + * @return the "Default" value for vias sizes used to route this net + */ + int GetViasSize() + { + return m_NetParams.m_ViasSize; + } + + + /** Function GetViasMinSize() + * @return the Minimum value for vias sizes (used in DRC) + */ + int GetViasMinSize() + { + return m_NetParams.m_ViasMinSize; + } + + + /** Function GetClearance() + * @return the "Default" clearance when routing + */ + int GetClearance() + { + return m_NetParams.m_Clearance; + } + + + /** Function GetMinClearance() + * @return the Minimum value for clearance (used in DRC) + */ + int GetMinClearance() + { + return m_NetParams.m_MinClearance; + } + + + /* Reading and writing data on files */ int ReadDescr( FILE* File, int* LineNum ); /** diff --git a/pcbnew/class_netinfo_item.cpp b/pcbnew/class_netinfo_item.cpp index c0b2a99c71..509b9213de 100644 --- a/pcbnew/class_netinfo_item.cpp +++ b/pcbnew/class_netinfo_item.cpp @@ -17,8 +17,10 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent ) { SetNet( 0 ); - m_NbNodes = m_NbLink = m_NbNoconn = 0; - m_ForceWidth = 0; + m_NbNodes = 0; + m_NbLink = 0; + m_NbNoconn = 0; + m_Flag = 0; m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a general buffer of ratsnest m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net } @@ -58,10 +60,10 @@ int NETINFO_ITEM:: ReadDescr( FILE* File, int* LineNum ) continue; } - if( strncmp( Line, "Lw", 2 ) == 0 ) /* Texte */ + if( strncmp( Line, "NetClass", 8 ) == 0 ) /* Net Class */ { - sscanf( Line + 2, " %d", &tmp ); - m_ForceWidth = tmp; + ReadDelimitedText( Ltmp, Line + 8, sizeof(Ltmp) ); + m_NetClassName = CONV_FROM_UTF8( Ltmp ); continue; } } @@ -70,9 +72,9 @@ int NETINFO_ITEM:: ReadDescr( FILE* File, int* LineNum ) } -/**************************************/ +/*******************************************/ bool NETINFO_ITEM::Save( FILE* aFile ) const -/**************************************/ +/*******************************************/ /** Note: the old name of class NETINFO_ITEM was EQUIPOT * so in Save (and read) functions, for compatibility, we use EQUIPOT as keyword @@ -84,8 +86,7 @@ bool NETINFO_ITEM::Save( FILE* aFile ) const fprintf( aFile, "Na %d \"%s\"\n", GetNet(), CONV_TO_UTF8( m_Netname ) ); fprintf( aFile, "St %s\n", "~" ); - if( m_ForceWidth ) - fprintf( aFile, "Lw %d\n", m_ForceWidth ); + fprintf( aFile, "NetClass \"%s\"\n", CONV_TO_UTF8(m_NetClassName) ); if( fprintf( aFile, "$EndEQUIPOT\n" ) != sizeof("$EndEQUIPOT\n") - 1 ) goto out; diff --git a/pcbnew/class_netinfolist.cpp b/pcbnew/class_netinfolist.cpp index 4e1b32cf64..b3e9fb8bda 100644 --- a/pcbnew/class_netinfolist.cpp +++ b/pcbnew/class_netinfolist.cpp @@ -125,6 +125,7 @@ void NETINFO_LIST::BuildListOfNets() } m_Parent->m_NbNodes = nodes_count; + m_Parent->TransfertDesignRulesToNets( ); m_Parent->m_Status_Pcb |= NET_CODES_OK; diff --git a/pcbnew/dialog_design_rules.cpp b/pcbnew/dialog_design_rules.cpp new file mode 100644 index 0000000000..e943d3b1aa --- /dev/null +++ b/pcbnew/dialog_design_rules.cpp @@ -0,0 +1,487 @@ +///////////////////////////////////////////////////////////////////////////// + +// Name: dialog_design_rules.cpp +// Author: jean-pierre Charras +///////////////////////////////////////////////////////////////////////////// + +/* functions relatives to the design rules editor + */ +#include "fctsys.h" +#include "common.h" +#include "class_drawpanel.h" + +#include "confirm.h" +#include "pcbnew.h" + +#include "id.h" +#include "dialog_design_rules.h" +#include "wx/generic/gridctrl.h" + +// Fields Positions on layer grid +#define LAYERS_GRID_ROUTABLE_POSITION 0 +#define LAYERS_GRID_STATUS_POSITION 1 +#define LAYERS_GRID_NAME_POSITION 2 + +// Fields Positions on rules grid +#define RULE_GRID_TRACKSIZE_POSITION 0 +#define RULE_GRID_VIASIZE_POSITION 1 +#define RULE_GRID_CLEARANCE_POSITION 2 +#define RULE_GRID_MINTRACKSIZE_POSITION 3 +#define RULE_GRID_MINVIASIZE_POSITION 4 + +/***********************************************************************************/ +DIALOG_DESIGN_RULES::DIALOG_DESIGN_RULES( WinEDA_PcbFrame* parent ) : + DIALOG_DESIGN_RULES_BASE( parent ) +/***********************************************************************************/ +{ + m_Parent = parent; + + Init(); + SetAutoLayout( true ); + GetSizer()->Fit( this ); + GetSizer()->SetSizeHints( this ); +} + + +/********************************************************************/ +void DIALOG_DESIGN_RULES::Init() +/********************************************************************/ +{ + SetFocus(); + + // Initialize the layers grid: + m_ActivesLayersCount = g_DesignSettings.m_CopperLayerCount; + m_Pcb = m_Parent->GetBoard(); + m_Changes = 0; + + m_LayersCountSelection->SetSelection( m_ActivesLayersCount / 2 ); + + // Initialize the Routable column + SetRoutableLayerStatus(); + + // Initialize the Status column (layers attribute) + LAYER_T typelist[4] = { LT_SIGNAL, LT_POWER, LT_MIXED, LT_JUMPER }; + for( int ii = 0; ii < 4; ii++ ) + { + m_LayersType[ii] = typelist[ii]; + m_LayersTypeName[ii] = CONV_FROM_UTF8( LAYER::ShowType( typelist[ii] ) ); + } + + for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ ) + { + m_gridLayersProperties->SetCellEditor( ii, LAYERS_GRID_STATUS_POSITION, + new wxGridCellChoiceEditor( WXSIZEOF( + m_LayersTypeName ), + m_LayersTypeName ) ); + int select = LT_SIGNAL; + for( int jj = 0; jj < 4; jj++ ) + { + int layer = LAYER_CMP_N - ii; + if( m_Pcb->GetLayerType( layer ) == m_LayersType[jj] ) + { + select = m_LayersType[jj]; + break; + } + } + + m_gridLayersProperties->SetCellValue( ii, LAYERS_GRID_STATUS_POSITION, + m_LayersTypeName[select] ); + m_gridLayersProperties->SetCellOverflow( ii, LAYERS_GRID_STATUS_POSITION, false ); + } + + // Initialize the Name column + for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ ) + { + wxString layer_name = m_Pcb->GetLayerName( LAYER_CMP_N - ii ); + m_gridLayersProperties->SetCellValue( ii, LAYERS_GRID_NAME_POSITION, layer_name ); + } + + // Initialize the Rules List + InitRulesList(); + + /* Initialize the list of nets buffers + (note the netcode 0 is not a real net, so it is not loaded) + */ + for ( unsigned ii = 1; ; ii ++ ) + { + NETINFO_ITEM* net = m_Pcb->FindNet( ii ); + if( net == NULL ) + break; + m_StockNets.push_back(net); + // search the index in rules list for this net + int rules_idx = 0; + for (int jj = 0; jj < m_gridNetClassesProperties->GetNumberRows(); jj++ ) + { + if( m_gridNetClassesProperties->GetRowLabelValue(jj).CmpNoCase(net->GetClassName()) == 0 ) + { + rules_idx = jj; + break; + } + } + m_NetsLinkToClasses.push_back(rules_idx); // All nets are set to default net class + } + + InitializeRulesSelectionBoxes(); +} + +/** Function FillListBoxWithNetsNames + * populates the aListBox with net names members of the aNetclassIndex net class + * the "Client Data pointer" is used to store the index of nets in ne nets lists + */ +void DIALOG_DESIGN_RULES::FillListBoxWithNetsNames(wxListBox* aListBox, int aNetclassIndex) +{ + aListBox->Clear(); + unsigned idx = 0; + for(unsigned ii = 0; ii < m_StockNets.size(); ii++ ) + { + if (aNetclassIndex == m_NetsLinkToClasses[ii] ) + { + aListBox->Append( m_StockNets[ii]->GetNetname() ); + // Store the index of this net + aListBox->SetClientData(idx, (void *) ii); + idx++; + } + } +} + +/* Initialize the combno boxes by the list of existing net classes + */ +void DIALOG_DESIGN_RULES::InitializeRulesSelectionBoxes() +{ + m_CBoxRightSelection->Clear(); + m_CBoxLeftSelection->Clear(); + for (int ii = 0; ii < m_gridNetClassesProperties->GetNumberRows(); ii++ ) + { + m_CBoxRightSelection->Append(m_gridNetClassesProperties->GetRowLabelValue(ii)); + m_CBoxLeftSelection->Append(m_gridNetClassesProperties->GetRowLabelValue(ii)); + } + m_CBoxRightSelection->Select(0); + m_CBoxLeftSelection->Select(0); + m_buttonRightToLeft->Enable(false); + m_buttonLeftToRight->Enable(false);; + FillListBoxWithNetsNames(m_listBoxLeftNetSelect, m_CBoxLeftSelection->GetCurrentSelection() ); + FillListBoxWithNetsNames(m_listBoxRightNetSelect, m_CBoxRightSelection->GetCurrentSelection() ); +} + + +/* Initialize the Routable column, and the R/W property of some cells + */ +void DIALOG_DESIGN_RULES::SetRoutableLayerStatus() +{ + m_gridLayersProperties->SetColFormatBool( LAYERS_GRID_ROUTABLE_POSITION ); + for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ ) + { + int layer = LAYER_CMP_N - ii; + wxString value = layer < (m_ActivesLayersCount - 1) ? wxT( "1" ) : wxT( "0" ); + if( m_ActivesLayersCount > 1 && layer == LAYER_CMP_N ) + value = wxT( "1" ); + if( layer == COPPER_LAYER_N ) + value = wxT( "1" ); + m_gridLayersProperties->SetCellValue( ii, LAYERS_GRID_ROUTABLE_POSITION, value ); + m_gridLayersProperties->SetReadOnly( ii, LAYERS_GRID_ROUTABLE_POSITION ); + // Set to Read Only cell for non existing copper layers: + m_gridLayersProperties->SetReadOnly( ii, LAYERS_GRID_STATUS_POSITION, value != wxT( "1" ) ); + m_gridLayersProperties->SetReadOnly( ii, LAYERS_GRID_NAME_POSITION, value != wxT( "1" ) ); + } +} + +/* Initialize the rules list from board +*/ +void DIALOG_DESIGN_RULES::InitRulesList() +{ + for( int ii = 0; ; ii++ ) + { + const NETCLASS * netclass = m_Pcb->m_NetClassesList.GetNetClass(ii); + if ( netclass == NULL ) + break; + // Creates one entry if needed + if (ii >= m_gridNetClassesProperties->GetNumberRows() ) + m_gridNetClassesProperties->AppendRows( ); + // Init name + m_gridNetClassesProperties->SetRowLabelValue(ii, netclass->m_Name); + // Init data + wxString msg; + msg = ReturnStringFromValue( g_UnitMetric, + netclass->m_NetParams.m_TracksWidth, + m_Parent->m_InternalUnits, false ); + m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_TRACKSIZE_POSITION, msg); + msg = ReturnStringFromValue( g_UnitMetric, + netclass->m_NetParams.m_ViasSize, + m_Parent->m_InternalUnits, false ); + m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_VIASIZE_POSITION, msg); + msg = ReturnStringFromValue( g_UnitMetric, + netclass->m_NetParams.m_Clearance, + m_Parent->m_InternalUnits, false ); + m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_CLEARANCE_POSITION, msg); + msg = ReturnStringFromValue( g_UnitMetric, + netclass->m_NetParams.m_TracksMinWidth, + m_Parent->m_InternalUnits, false ); + m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_MINTRACKSIZE_POSITION, msg); + msg = ReturnStringFromValue( g_UnitMetric, + netclass->m_NetParams.m_ViasMinSize, + m_Parent->m_InternalUnits, false ); + m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_MINVIASIZE_POSITION, msg); + } +} + +/* Copy the rules list to board +*/ +void DIALOG_DESIGN_RULES::CopyRulesListToBoard() +{ + m_Pcb->m_NetClassesList.ClearList(); + for( int ii = 0; ii < m_gridNetClassesProperties->GetNumberRows(); ii++ ) + { + NETCLASS * netclass = new NETCLASS(m_Pcb, + m_gridNetClassesProperties->GetRowLabelValue(ii) ); + m_Pcb->m_NetClassesList.AddNetclass(netclass); + // Init data + netclass->m_NetParams.m_TracksWidth = + ReturnValueFromString( g_UnitMetric, + m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_TRACKSIZE_POSITION), + m_Parent->m_InternalUnits ); + + netclass->m_NetParams.m_ViasSize = + ReturnValueFromString( g_UnitMetric, + m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_VIASIZE_POSITION), + m_Parent->m_InternalUnits ); + + netclass->m_NetParams.m_Clearance = + ReturnValueFromString( g_UnitMetric, + m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_CLEARANCE_POSITION), + m_Parent->m_InternalUnits ); + + netclass->m_NetParams.m_TracksMinWidth = + ReturnValueFromString( g_UnitMetric, + m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_MINTRACKSIZE_POSITION), + m_Parent->m_InternalUnits ); + + netclass->m_NetParams.m_ViasMinSize = + ReturnValueFromString( g_UnitMetric, + m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_MINVIASIZE_POSITION), + m_Parent->m_InternalUnits ); + // Copy the list of nets associated to this netclass: + for(unsigned idx = 0; idx < m_StockNets.size(); idx++ ) + { + if( m_NetsLinkToClasses[idx] == ii ) + netclass->AddMember(m_StockNets[idx]->GetNetname()); + } + } + + m_Pcb->TransfertDesignRulesToNets( ); +} + +/*****************************************************************/ +void DIALOG_DESIGN_RULES::OnCancelButtonClick( wxCommandEvent& event ) +/*****************************************************************/ +{ + EndModal( 0 ); +} + + +/**************************************************************************/ +void DIALOG_DESIGN_RULES::OnOkButtonClick( wxCommandEvent& event ) +/**************************************************************************/ +{ + g_DesignSettings.m_CopperLayerCount = m_ActivesLayersCount; + + // Initialize the new layer name + for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ ) + { + wxString layer_name = m_gridLayersProperties->GetCellValue( ii, LAYERS_GRID_NAME_POSITION ); + if( layer_name != m_Pcb->GetLayerName( LAYER_CMP_N - ii ) ) + { + m_Pcb->SetLayerName( LAYER_CMP_N - ii, layer_name ); + } + } + + // Initialize the layer type + for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ ) + { + wxString txt = m_gridLayersProperties->GetCellValue( ii, LAYERS_GRID_STATUS_POSITION ); + int layer = LAYER_CMP_N - ii; + for( int jj = 0; jj < 3; jj++ ) + { + if( m_LayersTypeName[jj] == txt ) + { + m_Pcb->SetLayerType( layer, m_LayersType[jj] ); + break; + } + } + } + + CopyRulesListToBoard(); + + EndModal( 1 ); +} + + +/**************************************************************************/ +void DIALOG_DESIGN_RULES::OnLayerCountClick( wxCommandEvent& event ) +/**************************************************************************/ +{ + m_ActivesLayersCount = m_LayersCountSelection->GetSelection() * 2; + if( m_ActivesLayersCount <= 0 ) + m_ActivesLayersCount = 1; + + // Reinit the routable layers status + SetRoutableLayerStatus(); +} + + +/**************************************************************************/ +void DIALOG_DESIGN_RULES::OnAddNetclassClick( wxCommandEvent& event ) +/**************************************************************************/ +{ + wxString class_name; + if( Get_Message( _("New Net Class Name:"), + wxEmptyString, + class_name, + this ) ) + return; + + // The name must dot exists: + for( int ii = 0; ii < m_gridNetClassesProperties->GetNumberRows(); ii++ ) + { + wxString value; + value = m_gridNetClassesProperties->GetRowLabelValue(ii); + if( class_name.CmpNoCase( value) == 0 ) // Already exists! + { + DisplayError(this, _("This NetClass is alerady existing, cannot add it") ); + return; + } + } + + m_gridNetClassesProperties->AppendRows( ); + m_gridNetClassesProperties->SetRowLabelValue( + m_gridNetClassesProperties->GetNumberRows()-1, + class_name); + // Copy values of the previous class: + int irow = m_gridNetClassesProperties->GetNumberRows()-1; + for( int icol = 0; icol < m_gridNetClassesProperties->GetNumberCols(); icol++ ) + { + wxString value; + value = m_gridNetClassesProperties->GetCellValue(irow-1, icol); + m_gridNetClassesProperties->SetCellValue(irow, icol, value); + } + InitializeRulesSelectionBoxes(); +} + + +/**************************************************************************/ +void DIALOG_DESIGN_RULES::OnRemoveNetclassClick( wxCommandEvent& event ) +/**************************************************************************/ +{ + wxArrayInt select = m_gridNetClassesProperties->GetSelectedRows(); + for( int ii = select.GetCount()-1; ii >= 0; ii-- ) + { + if( select[ii] != 0 ) // Do not remove the default class + { + m_gridNetClassesProperties->DeleteRows(select[ii]); + // reset the net class to default for nets member of the removed net class + for ( unsigned jj = 0; jj< m_NetsLinkToClasses.size(); jj++ ) + if( m_NetsLinkToClasses[jj] == ii ) + m_NetsLinkToClasses[jj] = 0; // Reset to default net class + + } + } + InitializeRulesSelectionBoxes(); +} + +/* + * Called on the left Choice Box selection +*/ +void DIALOG_DESIGN_RULES::OnLeftCBSelection( wxCommandEvent& event ) +{ + FillListBoxWithNetsNames(m_listBoxLeftNetSelect, m_CBoxLeftSelection->GetCurrentSelection() ); + if ( m_CBoxLeftSelection->GetCurrentSelection() == m_CBoxRightSelection->GetCurrentSelection() ) + { + m_buttonRightToLeft->Enable(false); + m_buttonLeftToRight->Enable(false); + } + else + { + m_buttonRightToLeft->Enable(true); + m_buttonLeftToRight->Enable(true); + } +} + +/* + * Called on the Right Choice Box selection +*/ +void DIALOG_DESIGN_RULES::OnRightCBSelection( wxCommandEvent& event ) +{ + FillListBoxWithNetsNames(m_listBoxRightNetSelect, m_CBoxRightSelection->GetCurrentSelection() ); + if ( m_CBoxLeftSelection->GetCurrentSelection() == m_CBoxRightSelection->GetCurrentSelection() ) + { + m_buttonRightToLeft->Enable(false); + m_buttonLeftToRight->Enable(false);; + } + else + { + m_buttonRightToLeft->Enable(true); + m_buttonLeftToRight->Enable(true); + } +} + + +/* Called on clicking the "<<<" or Copy Right to Left button: + * Selected items are moved from the right list to the left list +*/ + +void DIALOG_DESIGN_RULES::OnRightToLeftCopyButton( wxCommandEvent& event ) +{ + int idx_class = m_CBoxLeftSelection->GetCurrentSelection(); + if ( idx_class == wxNOT_FOUND ) + return; + for( unsigned ii = 0; ii < m_listBoxRightNetSelect->GetCount(); ii++ ) + { + if( ! m_listBoxRightNetSelect->IsSelected(ii) ) + continue; + + unsigned idx = (unsigned) m_listBoxRightNetSelect->GetClientData( ii); + m_NetsLinkToClasses[idx] = idx_class; + } + + FillListBoxWithNetsNames(m_listBoxLeftNetSelect, m_CBoxLeftSelection->GetCurrentSelection()); + FillListBoxWithNetsNames(m_listBoxRightNetSelect, m_CBoxRightSelection->GetCurrentSelection()); +} + +/* Called on clicking the ">>>" or Copy Left to Right button: + * Selected items are moved from the left list to the right list +*/ +void DIALOG_DESIGN_RULES::OnLeftToRightCopyButton( wxCommandEvent& event ) +{ + int idx_class = m_CBoxRightSelection->GetCurrentSelection(); + if ( idx_class == wxNOT_FOUND ) + return; + for( unsigned ii = 0; ii < m_listBoxLeftNetSelect->GetCount(); ii++ ) + { + if( ! m_listBoxLeftNetSelect->IsSelected(ii) ) + continue; + + unsigned idx = (unsigned) m_listBoxLeftNetSelect->GetClientData(ii); + m_NetsLinkToClasses[idx] = idx_class; + } + + FillListBoxWithNetsNames(m_listBoxLeftNetSelect, m_CBoxLeftSelection->GetCurrentSelection()); + FillListBoxWithNetsNames(m_listBoxRightNetSelect, m_CBoxRightSelection->GetCurrentSelection()); +} + +/* Called on clicking the left "select all" button: + * select alls items of the left netname list lisxt box +*/ +void DIALOG_DESIGN_RULES::OnLeftSelectAllButton( wxCommandEvent& event ) +{ + for( unsigned ii = 0; ii < m_listBoxLeftNetSelect->GetCount(); ii++ ) + m_listBoxLeftNetSelect->SetSelection(ii); +} + +/* Called on clicking the right "select all" button: + * select alls items of the right netname list lisxt box +*/ +void DIALOG_DESIGN_RULES::OnRightSelectAllButton( wxCommandEvent& event ) +{ + for( unsigned ii = 0; ii < m_listBoxRightNetSelect->GetCount(); ii++ ) + m_listBoxRightNetSelect->SetSelection(ii); +} + diff --git a/pcbnew/dialog_design_rules.h b/pcbnew/dialog_design_rules.h new file mode 100644 index 0000000000..5a8ad290f7 --- /dev/null +++ b/pcbnew/dialog_design_rules.h @@ -0,0 +1,52 @@ +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_DESIGN_RULES +/////////////////////////////////////////////////////////////////////////////// + +#ifndef __dialog_design_rules_h_ +#define __dialog_design_rules_h_ + +#include "dialog_design_rules_base.h" + + +class DIALOG_DESIGN_RULES : public DIALOG_DESIGN_RULES_BASE +{ + private: + WinEDA_PcbFrame * m_Parent; + int m_ActivesLayersCount; + BOARD * m_Pcb; + int m_Changes; + LAYER_T m_LayersType[4]; + wxString m_LayersTypeName[4]; + std::vector m_StockNets; // full list of nets on board + std::vector m_NetsLinkToClasses; // index to affect each net to an existing net class + + private: + void OnLayerCountClick( wxCommandEvent& event ); + void OnLayerGridLeftClick( wxGridEvent& event ){ event.Skip(); } + void OnLayerGridRighttClick( wxGridEvent& event ){ event.Skip(); } + void OnNetClassesGridLeftClick( wxGridEvent& event ){ event.Skip(); } + void OnNetClassesGridRightClick( wxGridEvent& event ){ event.Skip(); } + void OnCancelButtonClick( wxCommandEvent& event ); + void OnOkButtonClick( wxCommandEvent& event ); + void OnAddNetclassClick( wxCommandEvent& event ); + void OnRemoveNetclassClick( wxCommandEvent& event ); + void OnLeftCBSelection( wxCommandEvent& event ); + void OnRightCBSelection( wxCommandEvent& event ); + void OnRightToLeftCopyButton( wxCommandEvent& event ); + void OnLeftToRightCopyButton( wxCommandEvent& event ); + void OnLeftSelectAllButton( wxCommandEvent& event ); + void OnRightSelectAllButton( wxCommandEvent& event ); + void Init(); + void InitRulesList(); + void InitializeRulesSelectionBoxes(); + void CopyRulesListToBoard(); + void SetRoutableLayerStatus( ); + void FillListBoxWithNetsNames(wxListBox* aListBox, int aNetclassIndex); + + public: + DIALOG_DESIGN_RULES( WinEDA_PcbFrame* parent ); + ~DIALOG_DESIGN_RULES( ) { }; + +}; + +#endif //__dialog_design_rules_h_ diff --git a/pcbnew/dialog_design_rules_base.cpp b/pcbnew/dialog_design_rules_base.cpp new file mode 100644 index 0000000000..082990b88d --- /dev/null +++ b/pcbnew/dialog_design_rules_base.cpp @@ -0,0 +1,260 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 16 2008) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "dialog_design_rules_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxSize( 600,450 ), wxDefaultSize ); + + wxBoxSizer* bMainSizer; + bMainSizer = new wxBoxSizer( wxVERTICAL ); + + m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + m_panelLayers = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bMainSizerLayers; + bMainSizerLayers = new wxBoxSizer( wxHORIZONTAL ); + + wxString m_LayersCountSelectionChoices[] = { _("1"), _("2"), _("4"), _("6"), _("8"), _("10"), _("12"), _("14"), _("16") }; + int m_LayersCountSelectionNChoices = sizeof( m_LayersCountSelectionChoices ) / sizeof( wxString ); + m_LayersCountSelection = new wxRadioBox( m_panelLayers, ID_LAYERS_COUNT_SELECTION, _("Layers Count"), wxDefaultPosition, wxDefaultSize, m_LayersCountSelectionNChoices, m_LayersCountSelectionChoices, 1, wxRA_SPECIFY_COLS ); + m_LayersCountSelection->SetSelection( 1 ); + bMainSizerLayers->Add( m_LayersCountSelection, 0, wxALL, 5 ); + + m_gridLayersProperties = new wxGrid( m_panelLayers, ID_LAYERS_PROPERTIES, wxDefaultPosition, wxDefaultSize, 0 ); + + // Grid + m_gridLayersProperties->CreateGrid( 16, 3 ); + m_gridLayersProperties->EnableEditing( true ); + m_gridLayersProperties->EnableGridLines( true ); + m_gridLayersProperties->EnableDragGridSize( false ); + m_gridLayersProperties->SetMargins( 0, 0 ); + + // Columns + m_gridLayersProperties->SetColSize( 0, 100 ); + m_gridLayersProperties->SetColSize( 1, 100 ); + m_gridLayersProperties->SetColSize( 2, 150 ); + m_gridLayersProperties->EnableDragColMove( false ); + m_gridLayersProperties->EnableDragColSize( true ); + m_gridLayersProperties->SetColLabelSize( 30 ); + m_gridLayersProperties->SetColLabelValue( 0, _("Active") ); + m_gridLayersProperties->SetColLabelValue( 1, _("Status") ); + m_gridLayersProperties->SetColLabelValue( 2, _("Name") ); + m_gridLayersProperties->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Rows + m_gridLayersProperties->AutoSizeRows(); + m_gridLayersProperties->EnableDragRowSize( true ); + m_gridLayersProperties->SetRowLabelSize( 80 ); + m_gridLayersProperties->SetRowLabelValue( 0, _("Top Layer") ); + m_gridLayersProperties->SetRowLabelValue( 1, _("Inner 14") ); + m_gridLayersProperties->SetRowLabelValue( 2, _("Inner 13") ); + m_gridLayersProperties->SetRowLabelValue( 3, _("Inner 12") ); + m_gridLayersProperties->SetRowLabelValue( 4, _("Inner 11") ); + m_gridLayersProperties->SetRowLabelValue( 5, _("Inner 10") ); + m_gridLayersProperties->SetRowLabelValue( 6, _("Inner 9") ); + m_gridLayersProperties->SetRowLabelValue( 7, _("Inner 8") ); + m_gridLayersProperties->SetRowLabelValue( 8, _("Inner 7") ); + m_gridLayersProperties->SetRowLabelValue( 9, _("Inner 6") ); + m_gridLayersProperties->SetRowLabelValue( 10, _("Inner 5") ); + m_gridLayersProperties->SetRowLabelValue( 11, _("Inner 4") ); + m_gridLayersProperties->SetRowLabelValue( 12, _("Inner 3") ); + m_gridLayersProperties->SetRowLabelValue( 13, _("Inner 2") ); + m_gridLayersProperties->SetRowLabelValue( 14, _("Inner 1") ); + m_gridLayersProperties->SetRowLabelValue( 15, _("Bottom Layer") ); + m_gridLayersProperties->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Label Appearance + + // Cell Defaults + m_gridLayersProperties->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + bMainSizerLayers->Add( m_gridLayersProperties, 1, wxALL|wxEXPAND, 5 ); + + m_panelLayers->SetSizer( bMainSizerLayers ); + m_panelLayers->Layout(); + bMainSizerLayers->Fit( m_panelLayers ); + m_notebook->AddPage( m_panelLayers, _("Layers"), true ); + m_panelNetClasses = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + wxBoxSizer* bmainSizerNclasses; + bmainSizerNclasses = new wxBoxSizer( wxVERTICAL ); + + wxStaticBoxSizer* sbSizer1; + sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( m_panelNetClasses, wxID_ANY, _("Net classes:") ), wxHORIZONTAL ); + + m_gridNetClassesProperties = new wxGrid( m_panelNetClasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + + // Grid + m_gridNetClassesProperties->CreateGrid( 1, 5 ); + m_gridNetClassesProperties->EnableEditing( true ); + m_gridNetClassesProperties->EnableGridLines( true ); + m_gridNetClassesProperties->EnableDragGridSize( false ); + m_gridNetClassesProperties->SetMargins( 0, 0 ); + + // Columns + m_gridNetClassesProperties->SetColSize( 0, 100 ); + m_gridNetClassesProperties->SetColSize( 1, 100 ); + m_gridNetClassesProperties->SetColSize( 2, 100 ); + m_gridNetClassesProperties->SetColSize( 3, 100 ); + m_gridNetClassesProperties->SetColSize( 4, 100 ); + m_gridNetClassesProperties->EnableDragColMove( false ); + m_gridNetClassesProperties->EnableDragColSize( true ); + m_gridNetClassesProperties->SetColLabelSize( 30 ); + m_gridNetClassesProperties->SetColLabelValue( 0, _("Track size") ); + m_gridNetClassesProperties->SetColLabelValue( 1, _("Vias size") ); + m_gridNetClassesProperties->SetColLabelValue( 2, _("Clearance") ); + m_gridNetClassesProperties->SetColLabelValue( 3, _("Track Min Size") ); + m_gridNetClassesProperties->SetColLabelValue( 4, _("Via Min Size") ); + m_gridNetClassesProperties->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Rows + m_gridNetClassesProperties->AutoSizeRows(); + m_gridNetClassesProperties->EnableDragRowSize( true ); + m_gridNetClassesProperties->SetRowLabelSize( 80 ); + m_gridNetClassesProperties->SetRowLabelValue( 0, _("Default") ); + m_gridNetClassesProperties->SetRowLabelValue( 1, _("Special") ); + m_gridNetClassesProperties->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Label Appearance + + // Cell Defaults + m_gridNetClassesProperties->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + m_gridNetClassesProperties->SetMinSize( wxSize( -1,100 ) ); + + sbSizer1->Add( m_gridNetClassesProperties, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizerButtons; + bSizerButtons = new wxBoxSizer( wxVERTICAL ); + + m_buttonADD = new wxButton( m_panelNetClasses, wxID_ADD_NETCLASS, _("Add"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtons->Add( m_buttonADD, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + m_buttonRemove = new wxButton( m_panelNetClasses, wxID_REMOVE_NETCLASS, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtons->Add( m_buttonRemove, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + sbSizer1->Add( bSizerButtons, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + bmainSizerNclasses->Add( sbSizer1, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizerNetSelect; + bSizerNetSelect = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bLeftSizerNetSelect; + bLeftSizerNetSelect = new wxBoxSizer( wxVERTICAL ); + + wxArrayString m_CBoxLeftSelectionChoices; + m_CBoxLeftSelection = new wxChoice( m_panelNetClasses, ID_LEFT_CHOICE_CLICK, wxDefaultPosition, wxDefaultSize, m_CBoxLeftSelectionChoices, 0 ); + m_CBoxLeftSelection->SetSelection( 0 ); + bLeftSizerNetSelect->Add( m_CBoxLeftSelection, 0, wxALL|wxEXPAND, 5 ); + + m_listBoxLeftNetSelect = new wxListBox( m_panelNetClasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_MULTIPLE ); + bLeftSizerNetSelect->Add( m_listBoxLeftNetSelect, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + bSizerNetSelect->Add( bLeftSizerNetSelect, 1, wxEXPAND, 5 ); + + wxBoxSizer* bmiddleSizerNetSelect; + bmiddleSizerNetSelect = new wxBoxSizer( wxVERTICAL ); + + m_buttonRightToLeft = new wxButton( m_panelNetClasses, ID_LEFT_TO_RIGHT_COPY, _("<<<"), wxDefaultPosition, wxDefaultSize, 0 ); + bmiddleSizerNetSelect->Add( m_buttonRightToLeft, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 ); + + m_buttonLeftToRight = new wxButton( m_panelNetClasses, ID_RIGHT_TO_LEFT_COPY, _(">>>"), wxDefaultPosition, wxDefaultSize, 0 ); + bmiddleSizerNetSelect->Add( m_buttonLeftToRight, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizerButtonsSelecAll; + bSizerButtonsSelecAll = new wxBoxSizer( wxHORIZONTAL ); + + m_buttonLeftSelAll = new wxButton( m_panelNetClasses, wxID_ANY, _("<< Select All"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtonsSelecAll->Add( m_buttonLeftSelAll, 0, wxTOP|wxBOTTOM, 5 ); + + m_buttonRightSelAll = new wxButton( m_panelNetClasses, wxID_ANY, _("Select All >>"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButtonsSelecAll->Add( m_buttonRightSelAll, 0, wxALIGN_RIGHT|wxALIGN_BOTTOM|wxTOP|wxBOTTOM, 5 ); + + bmiddleSizerNetSelect->Add( bSizerButtonsSelecAll, 0, wxALIGN_CENTER_HORIZONTAL, 5 ); + + bSizerNetSelect->Add( bmiddleSizerNetSelect, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + wxBoxSizer* bLeftSizerNetSelect1; + bLeftSizerNetSelect1 = new wxBoxSizer( wxVERTICAL ); + + wxArrayString m_CBoxRightSelectionChoices; + m_CBoxRightSelection = new wxChoice( m_panelNetClasses, ID_RIGHT_CHOICE_CLICK, wxDefaultPosition, wxDefaultSize, m_CBoxRightSelectionChoices, 0 ); + m_CBoxRightSelection->SetSelection( 0 ); + bLeftSizerNetSelect1->Add( m_CBoxRightSelection, 0, wxALL|wxEXPAND, 5 ); + + m_listBoxRightNetSelect = new wxListBox( m_panelNetClasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_MULTIPLE ); + bLeftSizerNetSelect1->Add( m_listBoxRightNetSelect, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + bSizerNetSelect->Add( bLeftSizerNetSelect1, 1, wxEXPAND, 5 ); + + bmainSizerNclasses->Add( bSizerNetSelect, 1, wxEXPAND, 5 ); + + m_staticTextMsg = new wxStaticText( m_panelNetClasses, wxID_ANY, _("Messages:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextMsg->Wrap( -1 ); + bmainSizerNclasses->Add( m_staticTextMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_MessagesList = new wxHtmlWindow( m_panelNetClasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO|wxSUNKEN_BORDER ); + m_MessagesList->SetMinSize( wxSize( -1,100 ) ); + + bmainSizerNclasses->Add( m_MessagesList, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 ); + + m_panelNetClasses->SetSizer( bmainSizerNclasses ); + m_panelNetClasses->Layout(); + bmainSizerNclasses->Fit( m_panelNetClasses ); + m_notebook->AddPage( m_panelNetClasses, _("Net Classes"), false ); + + bMainSizer->Add( m_notebook, 1, wxALL|wxEXPAND, 5 ); + + m_sdbSizer1 = new wxStdDialogButtonSizer(); + m_sdbSizer1OK = new wxButton( this, wxID_OK ); + m_sdbSizer1->AddButton( m_sdbSizer1OK ); + m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL ); + m_sdbSizer1->AddButton( m_sdbSizer1Cancel ); + m_sdbSizer1->Realize(); + bMainSizer->Add( m_sdbSizer1, 0, wxALIGN_RIGHT, 5 ); + + this->SetSizer( bMainSizer ); + this->Layout(); + + // Connect Events + m_LayersCountSelection->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerCountClick ), NULL, this ); + m_gridLayersProperties->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerGridLeftClick ), NULL, this ); + m_gridLayersProperties->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerGridRighttClick ), NULL, this ); + m_gridNetClassesProperties->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridLeftClick ), NULL, this ); + m_gridNetClassesProperties->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridRightClick ), NULL, this ); + m_buttonADD->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this ); + m_buttonRemove->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this ); + m_CBoxLeftSelection->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this ); + m_buttonRightToLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this ); + m_buttonLeftToRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this ); + m_buttonLeftSelAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftSelectAllButton ), NULL, this ); + m_buttonRightSelAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightSelectAllButton ), NULL, this ); + m_CBoxRightSelection->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightCBSelection ), NULL, this ); + m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnCancelButtonClick ), NULL, this ); + m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnOkButtonClick ), NULL, this ); +} + +DIALOG_DESIGN_RULES_BASE::~DIALOG_DESIGN_RULES_BASE() +{ + // Disconnect Events + m_LayersCountSelection->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerCountClick ), NULL, this ); + m_gridLayersProperties->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerGridLeftClick ), NULL, this ); + m_gridLayersProperties->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerGridRighttClick ), NULL, this ); + m_gridNetClassesProperties->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridLeftClick ), NULL, this ); + m_gridNetClassesProperties->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridRightClick ), NULL, this ); + m_buttonADD->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this ); + m_buttonRemove->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this ); + m_CBoxLeftSelection->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this ); + m_buttonRightToLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this ); + m_buttonLeftToRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this ); + m_buttonLeftSelAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftSelectAllButton ), NULL, this ); + m_buttonRightSelAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightSelectAllButton ), NULL, this ); + m_CBoxRightSelection->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightCBSelection ), NULL, this ); + m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnCancelButtonClick ), NULL, this ); + m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnOkButtonClick ), NULL, this ); +} diff --git a/pcbnew/dialog_design_rules_base.fbp b/pcbnew/dialog_design_rules_base.fbp new file mode 100644 index 0000000000..326284214d --- /dev/null +++ b/pcbnew/dialog_design_rules_base.fbp @@ -0,0 +1,1244 @@ + + + + + + C++ + 1 + UTF-8 + connect + dialog_design_rules_base + 1000 + none + 1 + dialog_design_rules_base + + . + + 1 + 0 + 0 + + + + + 1 + + + + 0 + wxID_ANY + + 600,450 + DIALOG_DESIGN_RULES_BASE + + 684,486 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + + Design Rules Editor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bMainSizer + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + + + 1 + + + 0 + wxID_ANY + + + m_notebook + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Layers + 1 + + + + 1 + + + 0 + wxID_ANY + + + m_panelLayers + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bMainSizerLayers + wxHORIZONTAL + none + + 5 + wxALL + 0 + + + "1" "2" "4" "6" "8" "10" "12" "14" "16" + + 1 + + + 0 + ID_LAYERS_COUNT_SELECTION + Layers Count + 1 + + + m_LayersCountSelection + protected + + 1 + + wxRA_SPECIFY_COLS + + + + + + + + + + + + + + + + + + + + + + + OnLayerCountClick + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + 0 + 1 + + + + wxALIGN_CENTRE + + wxALIGN_CENTRE + wxALIGN_CENTRE + 30 + "Active" "Status" "Name" + wxALIGN_CENTRE + 3 + 100,100,150 + + 0 + 1 + 0 + 1 + 1 + 1 + + + + 1 + 0 + ID_LAYERS_PROPERTIES + + + + 0 + 0 + + -1,-1 + m_gridLayersProperties + protected + + wxALIGN_CENTRE + 80 + "Top Layer" "Inner 14" "Inner 13" "Inner 12" "Inner 11" "Inner 10" "Inner 9" "Inner 8" "Inner 7" "Inner 6" "Inner 5" "Inner 4" "Inner 3" "Inner 2" "Inner 1" "Bottom Layer" + wxALIGN_CENTRE + + 16 + + + + + + + + + + + OnLayerGridLeftClick + + OnLayerGridRighttClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Net Classes + 0 + + + + 1 + + + 0 + wxID_ANY + + + m_panelNetClasses + protected + + + + + + + wxTAB_TRAVERSAL + + + + + + + + + + + + + + + + + + + + + + + + + + bmainSizerNclasses + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + wxID_ANY + Net classes: + + sbSizer1 + wxHORIZONTAL + none + + + 5 + wxALL|wxEXPAND + 1 + + 0 + 1 + + + + wxALIGN_LEFT + + wxALIGN_TOP + wxALIGN_CENTRE + 30 + "Track size" "Vias size" "Clearance" "Track Min Size" "Via Min Size" + wxALIGN_CENTRE + 5 + 100,100,100,100,100 + + 0 + 1 + 0 + 1 + 1 + 1 + + + + 1 + 0 + wxID_ANY + + + + 0 + 0 + + -1,100 + m_gridNetClassesProperties + protected + + wxALIGN_CENTRE + 80 + "Default" "Special" + wxALIGN_CENTRE + + 1 + + + + + + + + + + + OnNetClassesGridLeftClick + + OnNetClassesGridRightClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + bSizerButtons + wxVERTICAL + none + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 0 + 1 + + + 0 + wxID_ADD_NETCLASS + Add + + + m_buttonADD + protected + + + + + + + + + OnAddNetclassClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + + + 0 + 1 + + + 0 + wxID_REMOVE_NETCLASS + Remove + + + m_buttonRemove + protected + + + + + + + + + OnRemoveNetclassClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bSizerNetSelect + wxHORIZONTAL + none + + 5 + wxEXPAND + 1 + + + bLeftSizerNetSelect + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + + + + 1 + + + 0 + ID_LEFT_CHOICE_CLICK + + + m_CBoxLeftSelection + protected + + 0 + + + + + + + + OnLeftCBSelection + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 1 + + + + + 1 + + + 0 + wxID_ANY + + + m_listBoxLeftNetSelect + protected + + + wxLB_EXTENDED|wxLB_MULTIPLE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + bmiddleSizerNetSelect + wxVERTICAL + none + + 5 + wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + ID_LEFT_TO_RIGHT_COPY + <<< + + + m_buttonRightToLeft + protected + + + + + + + + + OnRightToLeftCopyButton + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + + + 0 + 1 + + + 0 + ID_RIGHT_TO_LEFT_COPY + >>> + + + m_buttonLeftToRight + protected + + + + + + + + + OnLeftToRightCopyButton + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_CENTER_HORIZONTAL + 0 + + + bSizerButtonsSelecAll + wxHORIZONTAL + none + + 5 + wxTOP|wxBOTTOM + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + << Select All + + + m_buttonLeftSelAll + protected + + + + + + + + + OnLeftSelectAllButton + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT|wxALIGN_BOTTOM|wxTOP|wxBOTTOM + 0 + + + + 0 + 1 + + + 0 + wxID_ANY + Select All >> + + + m_buttonRightSelAll + protected + + + + + + + + + OnRightSelectAllButton + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + + bLeftSizerNetSelect1 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + + + + 1 + + + 0 + ID_RIGHT_CHOICE_CLICK + + + m_CBoxRightSelection + protected + + 0 + + + + + + + + OnRightCBSelection + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 1 + + + + + 1 + + + 0 + wxID_ANY + + + m_listBoxRightNetSelect + protected + + + wxLB_EXTENDED|wxLB_MULTIPLE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + + + 1 + + + 0 + wxID_ANY + Messages: + + + m_staticTextMsg + protected + + + + + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND + 0 + + + + 1 + + + 0 + wxID_ANY + + -1,100 + m_MessagesList + protected + + + wxHW_SCROLLBAR_AUTO + + + + + wxSUNKEN_BORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALIGN_RIGHT + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizer1 + protected + + OnCancelButtonClick + + + + OnOkButtonClick + + + + + + + + diff --git a/pcbnew/dialog_design_rules_base.h b/pcbnew/dialog_design_rules_base.h new file mode 100644 index 0000000000..79cff66f79 --- /dev/null +++ b/pcbnew/dialog_design_rules_base.h @@ -0,0 +1,99 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Apr 16 2008) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __dialog_design_rules_base__ +#define __dialog_design_rules_base__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +#define ID_LAYERS_COUNT_SELECTION 1000 +#define ID_LAYERS_PROPERTIES 1001 +#define wxID_ADD_NETCLASS 1002 +#define wxID_REMOVE_NETCLASS 1003 +#define ID_LEFT_CHOICE_CLICK 1004 +#define ID_LEFT_TO_RIGHT_COPY 1005 +#define ID_RIGHT_TO_LEFT_COPY 1006 +#define ID_RIGHT_CHOICE_CLICK 1007 + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_DESIGN_RULES_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_DESIGN_RULES_BASE : public wxDialog +{ + private: + + protected: + wxNotebook* m_notebook; + wxPanel* m_panelLayers; + wxRadioBox* m_LayersCountSelection; + wxGrid* m_gridLayersProperties; + wxPanel* m_panelNetClasses; + wxGrid* m_gridNetClassesProperties; + wxButton* m_buttonADD; + wxButton* m_buttonRemove; + wxChoice* m_CBoxLeftSelection; + wxListBox* m_listBoxLeftNetSelect; + wxButton* m_buttonRightToLeft; + wxButton* m_buttonLeftToRight; + wxButton* m_buttonLeftSelAll; + wxButton* m_buttonRightSelAll; + wxChoice* m_CBoxRightSelection; + wxListBox* m_listBoxRightNetSelect; + wxStaticText* m_staticTextMsg; + wxHtmlWindow* m_MessagesList; + wxStdDialogButtonSizer* m_sdbSizer1; + wxButton* m_sdbSizer1OK; + wxButton* m_sdbSizer1Cancel; + + // Virtual event handlers, overide them in your derived class + virtual void OnLayerCountClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnLayerGridLeftClick( wxGridEvent& event ){ event.Skip(); } + virtual void OnLayerGridRighttClick( wxGridEvent& event ){ event.Skip(); } + virtual void OnNetClassesGridLeftClick( wxGridEvent& event ){ event.Skip(); } + virtual void OnNetClassesGridRightClick( wxGridEvent& event ){ event.Skip(); } + virtual void OnAddNetclassClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRemoveNetclassClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnLeftCBSelection( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRightToLeftCopyButton( wxCommandEvent& event ){ event.Skip(); } + virtual void OnLeftToRightCopyButton( wxCommandEvent& event ){ event.Skip(); } + virtual void OnLeftSelectAllButton( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRightSelectAllButton( wxCommandEvent& event ){ event.Skip(); } + virtual void OnRightCBSelection( wxCommandEvent& event ){ event.Skip(); } + virtual void OnCancelButtonClick( wxCommandEvent& event ){ event.Skip(); } + virtual void OnOkButtonClick( wxCommandEvent& event ){ event.Skip(); } + + + public: + DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Design Rules Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 684,486 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~DIALOG_DESIGN_RULES_BASE(); + +}; + +#endif //__dialog_design_rules_base__ diff --git a/pcbnew/ioascii.cpp b/pcbnew/ioascii.cpp index 4880166fb1..03b1acea85 100644 --- a/pcbnew/ioascii.cpp +++ b/pcbnew/ioascii.cpp @@ -410,7 +410,7 @@ int WinEDA_BasePcbFrame::ReadSetup( FILE* File, int* LineNum ) g_DesignSettings.m_ViasMinSize = atoi( data ); continue; } - + if( stricmp( Line, "MicroViaSize" ) == 0 ) { g_DesignSettings.m_CurrentMicroViaSize = atoi( data ); @@ -776,7 +776,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) /** ReadPcbFile * Read a board file .brd - * @param Append if 0: a previoulsy loaded boar is delete before loadin the file. + * @param Append if 0: a previoulsy loaded board is deleted before loading the file. * else all items of the board file are added to the existing board */ { @@ -790,6 +790,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) NbDraw = NbTrack = NbZone = NbMod = NbNets = -1; GetBoard()->m_Status_Pcb = 0; + GetBoard()->m_NetClassesList.ClearList(); while( GetLine( File, Line, &LineNum ) != NULL ) { @@ -831,6 +832,15 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) continue; } + if( strnicmp( Line, "$NETCLASS", 8 ) == 0 ) + { + NETCLASS* netclass = new NETCLASS( GetBoard() ); + netclass->ReadDescr( File, &LineNum ); + if( ! GetBoard()->m_NetClassesList.AddNetclass( netclass ) ) + delete netclass; + continue; + } + if( strnicmp( Line, "$CZONE_OUTLINE", 7 ) == 0 ) { ZONE_CONTAINER * zone_descr = new ZONE_CONTAINER(GetBoard()); @@ -913,6 +923,15 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append ) BestZoom(); + // One netclass *must* exists (the default netclass) + if( GetBoard()->m_NetClassesList.GetNetClassCount() == 0 ) + { + NETCLASS* ncdefault = new NETCLASS(GetBoard()); + GetBoard()->m_NetClassesList.AddNetclass( ncdefault ); + } + + + GetBoard()->TransfertDesignRulesToNets( ); GetBoard()->m_Status_Pcb = 0; return 1; } diff --git a/pcbnew/menubarpcb.cpp b/pcbnew/menubarpcb.cpp index 8b5e7a0abc..599ee44622 100644 --- a/pcbnew/menubarpcb.cpp +++ b/pcbnew/menubarpcb.cpp @@ -205,6 +205,13 @@ void WinEDA_PcbFrame::ReCreateMenuBar() configmenu->AppendSeparator(); AddHotkeyConfigMenu( configmenu ); + // Add acces to the Design Rules Dialog: + wxMenu* designRulesMenu = new wxMenu; + item = new wxMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, + _( "Design Rules" ), _( "Open the design rules dialog editor" ) ); + item->SetBitmap( hammer_xpm ); + designRulesMenu->Append( item ); + ///////////////////////////// // Ajustage de dimensions: // ///////////////////////////// @@ -319,6 +326,7 @@ void WinEDA_PcbFrame::ReCreateMenuBar() menuBar->Append( filesMenu, _( "&File" ) ); menuBar->Append( configmenu, _( "&Preferences" ) ); + menuBar->Append( designRulesMenu, _( "&Design Rules" ) ); menuBar->Append( sizes_menu, _( "&Dimensions" ) ); menuBar->Append( miscellaneous_menu, _( "&Miscellaneous" ) ); menuBar->Append( postprocess_menu, _( "P&ostprocess" ) ); diff --git a/pcbnew/onrightclick.cpp b/pcbnew/onrightclick.cpp index f478f47732..56ee88c992 100644 --- a/pcbnew/onrightclick.cpp +++ b/pcbnew/onrightclick.cpp @@ -38,6 +38,9 @@ static wxMenu* Append_Track_Width_List() trackwidth_menu = new wxMenu; + ADD_MENUITEM( trackwidth_menu, ID_PCB_TRACK_SIZE_SETUP, + _( "New Width/Size" ), showtrack_xpm ); + trackwidth_menu->Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Auto Width" ), _( diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 0a77943012..2ca0f954e3 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -16,6 +16,8 @@ #include "3d_viewer.h" #include "kbool/include/kbool/booleng.h" +#include "dialog_design_rules.h" + // Keys used in read/write config #define PCB_CURR_GRID wxT( "PcbCurrGrid" ) #define PCB_MAGNETIC_PADS_OPT wxT( "PcbMagPadOpt" ) @@ -116,6 +118,9 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame ) // Menu 3D Frame EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, WinEDA_PcbFrame::Show3D_Frame ) +// Menu Get Design Rules Editor + EVT_MENU( ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, WinEDA_PcbFrame::ShowDesignRulesEditor ) + // Horizontal toolbar EVT_TOOL( ID_TO_LIBRARY, WinEDA_PcbFrame::Process_Special_Functions ) EVT_TOOL( ID_SHEET_SET, WinEDA_DrawFrame::Process_PageSettings ) @@ -639,3 +644,17 @@ void WinEDA_PcbFrame::Show3D_Frame( wxCommandEvent& event ) m_Draw3DFrame = new WinEDA3D_DrawFrame( this, _( "3D Viewer" ) ); m_Draw3DFrame->Show( TRUE ); } + +/** + * Display the Design Rules Editor. + */ +void WinEDA_PcbFrame::ShowDesignRulesEditor( wxCommandEvent& event ) +{ + DIALOG_DESIGN_RULES dR_editor( this ); + int change = dR_editor.ShowModal( ); + if ( change ) + { + ReCreateLayerBox( NULL ); + GetScreen()->SetModify(); + } +} diff --git a/pcbnew/tool_pcb.cpp b/pcbnew/tool_pcb.cpp index cb33c5f6a4..ecead41702 100644 --- a/pcbnew/tool_pcb.cpp +++ b/pcbnew/tool_pcb.cpp @@ -678,9 +678,6 @@ void WinEDA_PcbFrame::UpdateToolbarLayerInfo() WinEDAChoiceBox* WinEDA_PcbFrame::ReCreateLayerBox( WinEDA_Toolbar* parent ) /**************************************************************************/ { - // wxASSERT("ReCreateLayerBox"==""); // get a stack trace, who is calling me and from where - D(printf("ReCreateLayerBox\n");) - if( m_SelLayerBox == NULL ) { if( parent == NULL )