KiCad PCB EDA Suite
pcb_control.cpp File Reference
#include <tools/edit_tool.h>
#include <tools/board_inspection_tool.h>
#include <router/router_tool.h>
#include <pgm_base.h>
#include <tools/pcb_actions.h>
#include <tools/pcb_control.h>
#include <tools/pcb_picker_tool.h>
#include <tools/pcb_selection_tool.h>
#include <tools/board_reannotate_tool.h>
#include <3d_viewer/eda_3d_viewer_frame.h>
#include <board_commit.h>
#include <board.h>
#include <board_design_settings.h>
#include <board_item.h>
#include <dialogs/dialog_paste_special.h>
#include <pcb_dimension.h>
#include <footprint.h>
#include <pcb_group.h>
#include <pcb_textbox.h>
#include <pcb_track.h>
#include <wildcards_and_files_ext.h>
#include <zone.h>
#include <fp_shape.h>
#include <fp_textbox.h>
#include <confirm.h>
#include <connectivity/connectivity_data.h>
#include <core/kicad_algo.h>
#include <kicad_clipboard.h>
#include <origin_viewitem.h>
#include <pcb_edit_frame.h>
#include <pcb_painter.h>
#include <string_utf8_map.h>
#include <settings/color_settings.h>
#include <tool/tool_manager.h>
#include <footprint_edit_frame.h>
#include <widgets/wx_progress_reporters.h>
#include <widgets/wx_infobar.h>
#include <wx/hyperlink.h>

Go to the source code of this file.

Macros

#define ALPHA_MIN   0.20
 
#define ALPHA_MAX   1.00
 
#define ALPHA_STEP   0.05
 
#define HITTEST_THRESHOLD_PIXELS   5
 

Functions

bool AskLoadBoardFileName (PCB_EDIT_FRAME *aParent, int *aCtl, wxString *aFileName, bool aKicadFilesOnly=false)
 Show a wxFileDialog asking for a BOARD filename to open. More...
 
IO_MGR::PCB_FILE_T plugin_type (const wxString &aFileName, int aCtl)
 
template<class T >
void Flip (T &aValue)
 
static void pasteFootprintItemsToFootprintEditor (FOOTPRINT *aClipFootprint, BOARD *aBoard, std::vector< BOARD_ITEM * > &aPastedItems)
 
template<typename T >
static void moveUnflaggedItems (std::deque< T > &aList, std::vector< BOARD_ITEM * > &aTarget, bool aIsNew)
 
static void moveUnflaggedItems (ZONES &aList, std::vector< BOARD_ITEM * > &aTarget, bool aIsNew)
 

Macro Definition Documentation

◆ ALPHA_MAX

#define ALPHA_MAX   1.00

Definition at line 444 of file pcb_control.cpp.

◆ ALPHA_MIN

#define ALPHA_MIN   0.20

Definition at line 443 of file pcb_control.cpp.

◆ ALPHA_STEP

#define ALPHA_STEP   0.05

Definition at line 445 of file pcb_control.cpp.

◆ HITTEST_THRESHOLD_PIXELS

#define HITTEST_THRESHOLD_PIXELS   5

Definition at line 561 of file pcb_control.cpp.

Function Documentation

◆ AskLoadBoardFileName()

bool AskLoadBoardFileName ( PCB_EDIT_FRAME aParent,
int *  aCtl,
wxString *  aFileName,
bool  aKicadFilesOnly 
)

Show a wxFileDialog asking for a BOARD filename to open.

Parameters
aParentis a wxFrame passed to wxFileDialog.
aCtlis where to put the OpenProjectFiles() control bits.
aFileNameon entry is a probable choice, on return is the chosen filename.
aKicadFilesOnlytrue to list KiCad pcb files plugins only, false to list import plugins.
Returns
true if chosen, else false if user aborted.

Definition at line 90 of file pcbnew/files.cpp.

92{
93 // This is a subset of all PLUGINs which are trusted to be able to
94 // load a BOARD. User may occasionally use the wrong plugin to load a
95 // *.brd file (since both legacy and eagle use *.brd extension),
96 // but eventually *.kicad_pcb will be more common than legacy *.brd files.
97
98 // clang-format off
99 static const struct
100 {
101 const wxString& filter;
102 IO_MGR::PCB_FILE_T pluginType;
103 } loaders[] =
104 {
105 // Current Kicad board files.
107
108 // Old Kicad board files.
110
111 // Import Altium Circuit Maker board files.
113
114 // Import Altium Circuit Studio board files.
116
117 // Import Altium Designer board files.
119
120 // Import Cadstar PCB Archive board files.
122
123 // Import Eagle board files.
125
126 // Import PCAD board files.
128
129 // Import Fabmaster board files.
131 };
132 // clang-format on
133
134 wxFileName fileName( *aFileName );
135 wxString fileFilters;
136
137 if( aKicadFilesOnly )
138 {
139 std::vector<std::string> fileExtensions;
140
141 for( unsigned ii = 0; ii < 2; ++ii )
142 {
143 if( !fileFilters.IsEmpty() )
144 fileFilters += wxChar( '|' );
145
146 fileFilters += wxGetTranslation( loaders[ii].filter );
147
148 PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
149 wxCHECK( plugin, false );
150 fileExtensions.push_back( plugin->GetFileExtension().ToStdString() );
151 }
152
153 fileFilters = _( "All KiCad Board Files" ) + AddFileExtListToFilter( fileExtensions )
154 + wxT( "|" ) + fileFilters;
155 }
156 else
157 {
158 wxString allWildcards;
159
160 for( unsigned ii = 2; ii < arrayDim( loaders ); ++ii )
161 {
162 if( !fileFilters.IsEmpty() )
163 fileFilters += wxChar( '|' );
164
165 fileFilters += wxGetTranslation( loaders[ii].filter );
166
167 PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
168 wxCHECK( plugin, false );
169 allWildcards += wxT( "*." ) + formatWildcardExt( plugin->GetFileExtension() ) +
170 wxT( ";" );
171 }
172
173 fileFilters = _( "All supported formats" ) + wxT( "|" ) + allWildcards + wxT( "|" ) +
174 fileFilters;
175 }
176
177
178 wxString path;
179 wxString name;
180
181 if( fileName.FileExists() )
182 {
183 path = fileName.GetPath();
184 name = fileName.GetFullName();
185 }
186 else
187 {
188 path = aParent->GetMruPath();
189
190 if( path.IsEmpty() )
192 // leave name empty
193 }
194
195 wxFileDialog dlg( aParent,
196 aKicadFilesOnly ? _( "Open Board File" ) : _( "Import Non KiCad Board File" ),
197 path, name, fileFilters, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
198
199 if( dlg.ShowModal() == wxID_OK )
200 {
201 // For import option, if Eagle (*.brd files), tell OpenProjectFiles() to use Eagle plugin.
202 // It's the only special case because of the duplicate use of the *.brd file extension.
203 // Other cases are clear because of unique file extensions.
204 *aCtl = aKicadFilesOnly ? 0 : KICTL_EAGLE_BRD;
205 *aFileName = dlg.GetPath();
206 aParent->SetMruPath( wxFileName( dlg.GetPath() ).GetPath() );
207 return true;
208 }
209 else
210 {
211 return false;
212 }
213}
const char * name
Definition: DXF_plotter.cpp:56
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
wxString GetMruPath() const
void SetMruPath(const wxString &aPath)
PCB_FILE_T
The set of file types that the IO_MGR knows about, and for which there has been a plugin written.
Definition: io_mgr.h:54
@ LEGACY
Legacy Pcbnew file formats prior to s-expression.
Definition: io_mgr.h:55
@ ALTIUM_DESIGNER
Definition: io_mgr.h:60
@ KICAD_SEXP
S-expression Pcbnew file format.
Definition: io_mgr.h:56
@ ALTIUM_CIRCUIT_MAKER
Definition: io_mgr.h:62
@ PCAD
Definition: io_mgr.h:58
@ EAGLE
Definition: io_mgr.h:57
@ CADSTAR_PCB_ARCHIVE
Definition: io_mgr.h:63
@ FABMASTER
Definition: io_mgr.h:59
@ ALTIUM_CIRCUIT_STUDIO
Definition: io_mgr.h:61
static PLUGIN * PluginFind(PCB_FILE_T aFileType)
Return a PLUGIN which the caller can use to import, export, save, or load design documents.
Definition: io_mgr.cpp:58
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:139
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
Definition: io_mgr.h:564
#define _(s)
wxString AddFileExtListToFilter(const std::vector< std::string > &aExts)
Build the wildcard extension file dialog wildcard filter to add to the base message dialog.
wxString formatWildcardExt(const wxString &aWildcard)
Format wildcard extension to support case sensitive file dialogs.
wxString LegacyPcbFileWildcard()
wxString CadstarPcbArchiveFileWildcard()
wxString AltiumDesignerPcbFileWildcard()
wxString PCadPcbFileWildcard()
wxString EaglePcbFileWildcard()
wxString FabmasterPcbFileWildcard()
wxString AltiumCircuitMakerPcbFileWildcard()
wxString AltiumCircuitStudioPcbFileWildcard()
wxString PcbFileWildcard()
#define KICTL_EAGLE_BRD
chosen *.brd file is Eagle according to user.
Definition: kiway_player.h:81

References _, AddFileExtListToFilter(), IO_MGR::ALTIUM_CIRCUIT_MAKER, IO_MGR::ALTIUM_CIRCUIT_STUDIO, IO_MGR::ALTIUM_DESIGNER, AltiumCircuitMakerPcbFileWildcard(), AltiumCircuitStudioPcbFileWildcard(), AltiumDesignerPcbFileWildcard(), arrayDim(), IO_MGR::CADSTAR_PCB_ARCHIVE, CadstarPcbArchiveFileWildcard(), IO_MGR::EAGLE, EaglePcbFileWildcard(), IO_MGR::FABMASTER, FabmasterPcbFileWildcard(), filter, formatWildcardExt(), PATHS::GetDefaultUserProjectsPath(), PLUGIN::GetFileExtension(), EDA_BASE_FRAME::GetMruPath(), IO_MGR::KICAD_SEXP, KICTL_EAGLE_BRD, IO_MGR::LEGACY, LegacyPcbFileWildcard(), name, path, IO_MGR::PCAD, PCadPcbFileWildcard(), PcbFileWildcard(), IO_MGR::PluginFind(), and EDA_BASE_FRAME::SetMruPath().

Referenced by PCB_CONTROL::AppendBoardFromFile(), PCB_EDIT_FRAME::Files_io_from_id(), and PCB_EDIT_FRAME::OnFileHistory().

◆ Flip()

template<class T >
void Flip ( T &  aValue)

Definition at line 140 of file pcb_control.cpp.

141{
142 aValue = !aValue;
143}

Referenced by PCB_CONTROL::ToggleRatsnest(), PCB_CONTROL::TrackDisplayMode(), and PCB_CONTROL::ViaDisplayMode().

◆ moveUnflaggedItems() [1/2]

template<typename T >
static void moveUnflaggedItems ( std::deque< T > &  aList,
std::vector< BOARD_ITEM * > &  aTarget,
bool  aIsNew 
)
static

Definition at line 1024 of file pcb_control.cpp.

1026{
1027 std::copy_if( aList.begin(), aList.end(), std::back_inserter( aTarget ),
1028 [aIsNew]( T aItem )
1029 {
1030 bool doCopy = ( aItem->GetFlags() & SKIP_STRUCT ) == 0;
1031
1032 aItem->ClearFlags( SKIP_STRUCT );
1033 aItem->SetFlags( aIsNew ? IS_NEW : 0 );
1034
1035 return doCopy;
1036 } );
1037
1038 if( aIsNew )
1039 aList.clear();
1040}

Referenced by PCB_CONTROL::placeBoardItems().

◆ moveUnflaggedItems() [2/2]

static void moveUnflaggedItems ( ZONES aList,
std::vector< BOARD_ITEM * > &  aTarget,
bool  aIsNew 
)
static

Definition at line 1043 of file pcb_control.cpp.

1044{
1045 if( aList.size() == 0 )
1046 return;
1047
1048 auto obj = aList.front();
1049 int idx = 0;
1050
1051 if( aIsNew )
1052 {
1053 obj = aList.back();
1054 aList.pop_back();
1055 }
1056
1057 for( ; obj ; )
1058 {
1059 if( obj->HasFlag( SKIP_STRUCT ) )
1060 obj->ClearFlags( SKIP_STRUCT );
1061 else
1062 aTarget.push_back( obj );
1063
1064 if( aIsNew )
1065 {
1066 if( aList.size() )
1067 {
1068 obj = aList.back();
1069 aList.pop_back();
1070 }
1071 else
1072 {
1073 obj = nullptr;
1074 }
1075 }
1076 else
1077 {
1078 obj = idx < int(aList.size()-1) ? aList[++idx] : nullptr;
1079 }
1080 }
1081}
#define SKIP_STRUCT
flag indicating that the structure should be ignored

References SKIP_STRUCT.

◆ pasteFootprintItemsToFootprintEditor()

static void pasteFootprintItemsToFootprintEditor ( FOOTPRINT aClipFootprint,
BOARD aBoard,
std::vector< BOARD_ITEM * > &  aPastedItems 
)
static

Definition at line 665 of file pcb_control.cpp.

667{
668 FOOTPRINT* editorFootprint = aBoard->GetFirstFootprint();
669
670 aClipFootprint->SetParent( aBoard );
671
672 for( PAD* pad : aClipFootprint->Pads() )
673 {
674 pad->SetParent( editorFootprint );
675 aPastedItems.push_back( pad );
676 }
677
678 aClipFootprint->Pads().clear();
679
680 // Not all graphic items can be added to the current footprint:
681 // Reference and value are already existing in the current footprint, and
682 // must be unique.
683 // So they will be skipped
684 for( BOARD_ITEM* item : aClipFootprint->GraphicalItems() )
685 {
686 if( item->Type() == PCB_FP_SHAPE_T || item->Type() == PCB_FP_TEXTBOX_T )
687 {
688 FP_SHAPE* shape = static_cast<FP_SHAPE*>( item );
689
690 shape->SetParent( nullptr );
691 shape->SetLocalCoord();
692 }
693 else if( item->Type() == PCB_FP_TEXT_T )
694 {
695 FP_TEXT* text = static_cast<FP_TEXT*>( item );
696
697 if( text->GetType() != FP_TEXT::TEXT_is_DIVERS )
698 continue;
699
700 text->SetTextAngle( text->GetTextAngle() + aClipFootprint->GetOrientation() );
701
702 text->SetParent( nullptr );
703 text->SetLocalCoord();
704 }
705
706 item->SetParent( editorFootprint );
707 aPastedItems.push_back( item );
708 }
709
710 aClipFootprint->GraphicalItems().clear();
711
712 for( FP_ZONE* zone : aClipFootprint->Zones() )
713 {
714 zone->SetParent( editorFootprint );
715 aPastedItems.push_back( zone );
716 }
717
718 aClipFootprint->Zones().clear();
719
720 for( PCB_GROUP* group : aClipFootprint->Groups() )
721 {
722 group->SetParent( editorFootprint );
723 aPastedItems.push_back( group );
724 }
725
726 aClipFootprint->Groups().clear();
727}
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:70
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:403
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
EDA_ANGLE GetOrientation() const
Definition: footprint.h:191
FP_GROUPS & Groups()
Definition: footprint.h:179
PADS & Pads()
Definition: footprint.h:170
FP_ZONES & Zones()
Definition: footprint.h:176
DRAWINGS & GraphicalItems()
Definition: footprint.h:173
virtual void SetLocalCoord()
Set relative coordinates from draw coordinates.
Definition: fp_shape.cpp:52
@ TEXT_is_DIVERS
Definition: fp_text.h:51
A specialization of ZONE for use in footprints.
Definition: zone.h:916
Definition: pad.h:60
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:51
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
@ PCB_FP_TEXTBOX_T
class FP_TEXTBOX, wrapped text in a footprint
Definition: typeinfo.h:93
@ PCB_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92

References BOARD::GetFirstFootprint(), FOOTPRINT::GetOrientation(), FOOTPRINT::GraphicalItems(), group, FOOTPRINT::Groups(), pad, FOOTPRINT::Pads(), PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PCB_FP_TEXTBOX_T, FP_SHAPE::SetLocalCoord(), EDA_ITEM::SetParent(), text, FP_TEXT::TEXT_is_DIVERS, and FOOTPRINT::Zones().

Referenced by PCB_CONTROL::Paste().

◆ plugin_type()

IO_MGR::PCB_FILE_T plugin_type ( const wxString &  aFileName,
int  aCtl 
)

Definition at line 486 of file pcbnew/files.cpp.

487{
488 IO_MGR::PCB_FILE_T pluginType;
489
490 wxFileName fn = aFileName;
491
492 // Note: file extensions are expected to be in lower case.
493 // This is not always true, especially when importing files, so the string
494 // comparisons are case insensitive to try to find the suitable plugin.
495
496 if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::LEGACY ) ) == 0 )
497 {
498 wxFileInputStream input( aFileName );
499 bool is_legacy = true;
500
501 if(input.IsOk() && !input.Eof() )
502 {
503 wxTextInputStream text( input );
504 wxString line = text.ReadLine();
505
506 if( !line.StartsWith( wxT( "PCBNEW" ) ) )
507 is_legacy = false;
508 }
509
510 // both legacy and eagle share a common file extension.
511 pluginType = ( aCtl & KICTL_EAGLE_BRD ) || !is_legacy ? IO_MGR::EAGLE : IO_MGR::LEGACY;
512 }
513 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::PCAD ) ) == 0 )
514 {
515 pluginType = IO_MGR::PCAD;
516 }
517 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_DESIGNER ) ) == 0 )
518 {
519 pluginType = IO_MGR::ALTIUM_DESIGNER;
520 }
521 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_STUDIO ) ) == 0 )
522 {
524 }
525 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::ALTIUM_CIRCUIT_MAKER ) ) == 0 )
526 {
527 pluginType = IO_MGR::ALTIUM_CIRCUIT_MAKER;
528 }
529 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::CADSTAR_PCB_ARCHIVE ) ) == 0 )
530 {
531 pluginType = IO_MGR::CADSTAR_PCB_ARCHIVE;
532 }
533 else if( fn.GetExt().CmpNoCase( IO_MGR::GetFileExtension( IO_MGR::FABMASTER ) ) == 0 )
534 {
535 pluginType = IO_MGR::FABMASTER;
536 }
537 else
538 {
539 pluginType = IO_MGR::KICAD_SEXP;
540 }
541
542 return pluginType;
543}
static const wxString GetFileExtension(PCB_FILE_T aFileType)
Return the file extension for aFileType.
Definition: io_mgr.cpp:109

References IO_MGR::ALTIUM_CIRCUIT_MAKER, IO_MGR::ALTIUM_CIRCUIT_STUDIO, IO_MGR::ALTIUM_DESIGNER, IO_MGR::CADSTAR_PCB_ARCHIVE, IO_MGR::EAGLE, IO_MGR::FABMASTER, IO_MGR::GetFileExtension(), IO_MGR::KICAD_SEXP, KICTL_EAGLE_BRD, IO_MGR::LEGACY, IO_MGR::PCAD, and text.

Referenced by PCB_CONTROL::AppendBoardFromFile(), PCB_CONTROL::DdAppendBoard(), and PCB_EDIT_FRAME::OpenProjectFiles().