42#include <wx/clipbrd.h>
43#include <wx/dcmemory.h>
49 wxASSERT( aSheet && aHierarchy );
59 wxASSERT( destFile.IsAbsolute() );
63 msg.Printf(
_(
"The sheet changes cannot be made because the destination sheet already "
64 "has the sheet '%s' or one of its subsheets as a parent somewhere in the "
65 "schematic hierarchy." ),
66 destFile.GetFullPath() );
77 wxASSERT( aSheet && aSheet->
GetScreen() );
84 msg.Printf(
_(
"The schematic '%s' has not had its symbol library links remapped "
85 "to the symbol library table. The project this schematic belongs to "
86 "must first be remapped before it can be imported into the current "
106 const wxString& aFileName )
108 wxASSERT( aSheet && aHierarchy );
111 wxFileName currentSheetFileName;
112 bool libTableChanged =
false;
115 std::unique_ptr< SCH_SHEET> tmpSheet = std::make_unique<SCH_SHEET>( &
Schematic() );
120 const_cast<KIID&
>( tmpSheet->m_Uuid ) = aSheet->
m_Uuid;
122 wxFileName fileName( aFileName );
124 if( !fileName.IsAbsolute() && !fileName.MakeAbsolute() )
126 wxFAIL_MSG(
wxString::Format(
"Cannot make file name '%s' path absolute.", aFileName ) );
130 wxString fullFilename = fileName.GetFullPath();
140 tmpSheet->SetFileName( fullFilename );
146 msg =
_(
"The entire schematic could not be loaded. Errors occurred attempting "
147 "to load hierarchical sheet schematics." );
149 wxMessageDialog msgDlg1(
this, msg,
_(
"Schematic Load Error" ),
150 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
151 wxCENTER | wxICON_QUESTION );
152 msgDlg1.SetOKLabel( wxMessageDialog::ButtonLabel(
_(
"Use partial schematic" ) ) );
153 msgDlg1.SetExtendedMessage( pi->
GetError() );
155 if( msgDlg1.ShowModal() == wxID_CANCEL )
161 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFilename );
164 msg.Printf(
_(
"Failed to load '%s'." ), fullFilename );
172 if( fileName.GetPathWithSep() !=
Prj().GetProjectPath() && tmpSheet->CountSheets() )
180 if( sheetPath.size() == 1 )
183 wxString lastSheetPath = fileName.GetPathWithSep();
185 for(
unsigned i = 1; i < sheetPath.size(); i++ )
188 wxCHECK2( sheet,
continue );
191 wxCHECK2( screen,
continue );
194 wxFileName loadedSheetFileName = screen->
GetFileName();
195 wxCHECK2( loadedSheetFileName.IsAbsolute(),
continue );
197 wxFileName tmp = loadedSheetFileName;
198 wxString sheetFileName;
200 if( tmp.MakeRelativeTo( lastSheetPath ) )
201 sheetFileName = tmp.GetFullPath();
203 sheetFileName = loadedSheetFileName.GetFullPath();
205 sheetFileName.Replace( wxT(
"\\" ), wxT(
"/" ) );
207 lastSheetPath = loadedSheetFileName.GetPath();
225 wxArrayString newLibNames;
231 wxMessageDialog::ButtonLabel okButtonLabel(
_(
"Continue Load" ) );
232 wxMessageDialog::ButtonLabel cancelButtonLabel(
_(
"Cancel Load" ) );
238 if( ( tmpSheet->GetScreen()->GetFileFormatVersionAtLoad() < 20221002 )
239 && tmpSheet->GetScreen()->GetSymbolInstances().empty() )
241 msg =
_(
"There are hierarchical sheets in the loaded schematic file from an older "
242 "file version resulting in missing symbol instance data. This will "
243 "result in all of the symbols in the loaded schematic to use either the "
244 "default instance setting or fall back to the library symbol settings. "
245 "Loading the project that uses this schematic file and saving to the "
246 "lastest file version will resolve this issue.\n\n"
247 "Do you wish to continue?" );
248 wxMessageDialog msgDlg7(
this, msg,
_(
"Continue Load Schematic" ),
249 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER | wxICON_QUESTION );
250 msgDlg7.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
252 if( msgDlg7.ShowModal() == wxID_CANCEL )
258 if( fileName.GetPathWithSep() ==
Prj().GetProjectPath() )
264 for(
const wxString&
name : names )
266 if( !
Prj().SchSymbolLibTable()->HasLibrary(
name ) )
267 newLibNames.Add(
name );
270 if( !newLibNames.IsEmpty() )
272 msg =
_(
"There are library names in the selected schematic that are missing "
273 "from the current project library table. This may result in broken "
274 "symbol library references for the loaded schematic.\n\n"
275 "Do you wish to continue?" );
276 wxMessageDialog msgDlg3(
this, msg,
_(
"Continue Load Schematic" ),
277 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
278 wxCENTER | wxICON_QUESTION );
279 msgDlg3.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
281 if( msgDlg3.ShowModal() == wxID_CANCEL )
285 else if( fileName.GetPathWithSep() !=
Prj().GetProjectPath() )
293 wxArrayString duplicateLibNames;
295 for(
const wxString&
name : names )
297 if( !
Prj().SchSymbolLibTable()->HasLibrary(
name ) )
298 newLibNames.Add(
name );
300 duplicateLibNames.Add(
name );
304 wxFileName symLibTableFn( fileName.GetPath(),
309 if( !newLibNames.IsEmpty() || !duplicateLibNames.IsEmpty() )
311 if( !symLibTableFn.Exists() || !symLibTableFn.IsFileReadable() )
313 msg =
_(
"The selected file was created as part of a different project. "
314 "Linking the file to this project may result in missing or "
315 "incorrect symbol library references.\n\n"
316 "Do you wish to continue?" );
317 wxMessageDialog msgDlg4(
this, msg,
_(
"Continue Load Schematic" ),
318 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
319 wxCENTER | wxICON_QUESTION );
320 msgDlg4.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
322 if( msgDlg4.ShowModal() == wxID_CANCEL )
329 table.
Load( symLibTableFn.GetFullPath() );
333 msg.Printf(
_(
"Error loading the symbol library table '%s'." ),
334 symLibTableFn.GetFullPath() );
344 if( !newLibNames.IsEmpty() )
346 bool missingLibNames = table.
IsEmpty();
348 if( !missingLibNames )
350 for(
const wxString& newLibName : newLibNames )
354 missingLibNames =
true;
360 if( missingLibNames )
362 msg =
_(
"There are symbol library names in the selected schematic that "
363 "are missing from the selected schematic project library table. "
364 "This may result in broken symbol library references.\n\n"
365 "Do you wish to continue?" );
366 wxMessageDialog msgDlg5(
this, msg,
_(
"Continue Load Schematic" ),
367 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
368 wxCENTER | wxICON_QUESTION );
369 msgDlg5.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
371 if( msgDlg5.ShowModal() == wxID_CANCEL )
379 if( !duplicateLibNames.IsEmpty() && !table.
IsEmpty() )
381 bool libNameConflict =
false;
383 for(
const wxString& duplicateLibName : duplicateLibNames )
388 if(
Prj().SchSymbolLibTable()->HasLibrary( duplicateLibName ) )
389 thisRow =
Prj().SchSymbolLibTable()->FindRow( duplicateLibName );
392 otherRow = table.
FindRow( duplicateLibName );
395 if( thisRow && !otherRow )
398 if( !thisRow || !otherRow )
401 wxFileName otherUriFileName;
402 wxString thisURI = thisRow->
GetFullURI(
true );
403 wxString otherURI = otherRow->
GetFullURI(
false);
405 if( otherURI.Contains(
"${KIPRJMOD}" ) || otherURI.Contains(
"$(KIPRJMOD)" ) )
409 otherUriFileName.SetPath( fileName.GetPath() );
410 otherUriFileName.SetFullName( otherURI.AfterLast(
'}' ) );
411 otherURI = otherUriFileName.GetFullPath();
414 if( thisURI != otherURI )
416 libNameConflict =
true;
421 if( libNameConflict )
423 msg =
_(
"A duplicate library name that references a different library exists "
424 "in the current library table. This conflict cannot be resolved and "
425 "may result in broken symbol library references.\n\n"
426 "Do you wish to continue?" );
427 wxMessageDialog msgDlg6(
this, msg,
_(
"Continue Load Schematic" ),
428 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
429 wxCENTER | wxICON_QUESTION );
430 msgDlg6.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
432 if( msgDlg6.ShowModal() == wxID_CANCEL )
440 if( !newLibNames.IsEmpty() && !table.
IsEmpty() )
442 for(
const wxString& libName : newLibNames )
445 ||
Prj().SchSymbolLibTable()->HasLibrary( libName ) )
452 wxString uri = table.
GetFullURI( libName,
false );
455 if( uri.Contains(
"${KIPRJMOD}" ) || uri.Contains(
"$(KIPRJMOD)" ) )
459 newLib.SetPath( fileName.GetPath() );
460 newLib.SetFullName( uri.AfterLast(
'}' ) );
461 uri = newLib.GetFullPath();
472 wxCHECK( row,
false );
479 Prj().SchSymbolLibTable()->InsertRow( newRow );
480 libTableChanged =
true;
486 SCH_SCREEN* newScreen = tmpSheet->GetScreen();
487 wxCHECK_MSG( newScreen,
false,
"No screen defined for sheet." );
489 if( libTableChanged )
491 Prj().SchSymbolLibTable()->Save(
Prj().GetProjectPath() +
528 bool* aClearAnnotationNewItems )
530 if( aSheet ==
nullptr || aHierarchy ==
nullptr )
536 if( dlg.ShowModal() == wxID_CANCEL )
555 double scale = ppi / inch2Iu;
557 wxSize dcsize = DrawArea.GetSize();
559 int maxdim = std::max( dcsize.x, dcsize.y );
562 const int maxbitmapsize = 5600;
564 while(
int( maxdim *
scale ) > maxbitmapsize )
567 scale = ppi / inch2Iu;
581 wxBitmap
image( dcsize );
582 dc.SelectObject(
image );
603 if( wxTheClipboard->Open() )
606 wxBitmapDataObject* clipbrd_data =
new wxBitmapDataObject(
image );
607 wxTheClipboard->SetData( clipbrd_data );
608 wxTheClipboard->Flush();
609 wxTheClipboard->Close();
614 dc.SelectObject( wxNullBitmap );
627 wxFileName fn = aSchematicFileName;
629 wxCHECK( fn.IsAbsolute(),
false );
631 if(
eeconfig()->m_Appearance.show_sheet_filename_case_sensitivity_dialog
634 msg.Printf(
_(
"The file name '%s' can cause issues with an existing file name\n"
635 "already defined in the schematic on systems that support case\n"
636 "insensitive file names. This will cause issues if you copy this\n"
637 "project to an operating system that supports case insensitive file\n"
638 "names.\n\nDo you wish to continue?" ),
641 wxRichMessageDialog dlg(
this, msg,
_(
"Warning" ),
642 wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
643 dlg.ShowCheckBox(
_(
"Do not show this message again." ) );
644 dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel(
_(
"Create New Sheet" ) ),
645 wxMessageDialog::ButtonLabel(
_(
"Discard New Sheet" ) ) );
647 if( dlg.ShowModal() == wxID_NO )
651 !dlg.IsCheckBoxChecked();
constexpr EDA_IU_SCALE schIUScale
Handles how to draw a screen (a board, a schematic ...)
VECTOR2I m_DrawOrg
offsets for drawing the circuit on the screen
VECTOR2I m_StartVisu
Coordinates in drawing units of the current view position (upper left corner of device)
void SetContentModified(bool aModified=true)
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
void SetLayerColor(int aLayer, const COLOR4D &aColor)
Change the color used to draw a layer.
void SetDefaultFont(const wxString &aFont)
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
void SetPrintDC(wxDC *aDC)
Store schematic specific render settings.
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
const wxString & GetOptions() const
Return the options string, which may hold a password or anything else needed to instantiate the under...
const wxString & GetDescr() const
Return the description of the library referenced by this row.
const wxString GetFullURI(bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library table.
void Load(const wxString &aFileName)
Load the library table using the path defined by aFileName aFallBackTable.
wxString GetFullURI(const wxString &aLibNickname, bool aExpandEnvVars=true) const
Return the full URI of the library mapped to aLibNickname.
bool IsEmpty(bool aIncludeFallback=true)
Return true if the table is empty.
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
const wxSize GetPageSizeIU() const override
Works off of GetPageSettings() to return the size of the paper page in the internal units of this par...
EESCHEMA_SETTINGS * eeconfig() const
KIGFX::SCH_RENDER_SETTINGS * GetRenderSettings()
bool LoadSheetFromFile(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, const wxString &aFileName)
Load a the KiCad schematic file aFileName into the sheet aSheet.
bool AllowCaseSensitiveFileNameClashes(const wxString &aSchematicFileName)
Check aSchematicFileName for a potential file name case sensitivity clashes.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void InitSheet(SCH_SHEET *aSheet, const wxString &aNewFilename)
bool CheckSheetForRecursion(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy)
Verify that aSheet will not cause a recursion error in aHierarchy.
SCHEMATIC & Schematic() const
void DrawCurrentSheetToClipboard()
Use the wxWidgets print code to draw an image of the current sheet onto the clipboard.
bool checkForNoFullyDefinedLibIds(SCH_SHEET *aSheet)
Verify that the symbol library links aSheet and all of its child sheets have been remapped to the sym...
bool EditSheetProperties(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, bool *aClearAnnotationNewItems)
Edit an existing sheet or add a new sheet to the schematic.
virtual void PrintPage(const RENDER_SETTINGS *aSettings) override
Plot or print the current sheet to the clipboard.
static SCH_FILE_T GuessPluginTypeFromSchPath(const wxString &aSchematicPath)
Return a plugin type given a schematic using the file extension of aSchematicPath.
Helper object to release a SCH_PLUGIN in the context of a potential thrown exception through its dest...
virtual const wxString & GetError() const
Return an error string to the caller.
virtual SCH_SHEET * Load(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const STRING_UTF8_MAP *aProperties=nullptr)
Load information from some input file format that this SCH_PLUGIN implementation knows about,...
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
bool CanCauseCaseSensitivityIssue(const wxString &aSchematicFileName) const
Check aSchematicFileName for a potential file name case sensitivity issue.
bool HasNoFullyDefinedLibIds()
Test all of the schematic symbols to see if all LIB_ID objects library nickname is not set.
int ReplaceDuplicateTimeStamps()
Test all sheet and symbol objects in the schematic for duplicate time stamps and replaces them as nec...
bool HasSchematic(const wxString &aSchematicFileName)
Check if one of the schematics in the list of screens is aSchematicFileName.
size_t GetLibNicknames(wxArrayString &aLibNicknames)
Fetch all of the symbol library nicknames into aLibNicknames.
const wxString & GetFileName() const
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
const std::vector< SCH_SYMBOL_INSTANCE > & GetSymbolInstances() const
int GetFileFormatVersionAtLoad() const
void MigrateSimModels()
Migrate any symbols having V6 simulation models to their V7 equivalents.
void Append(SCH_ITEM *aItem)
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
int GetLastVirtualPageNumber() const
void UpdateSymbolInstanceData(const std::vector< SCH_SYMBOL_INSTANCE > &aSymbolInstances)
Update all of the symbol instance information using aSymbolInstances.
void AddNewSheetInstances(const SCH_SHEET_PATH &aPrefixSheetPath, int aLastVirtualPageNumber)
void AddNewSymbolInstances(const SCH_SHEET_PATH &aPrefixSheetPath)
Attempt to add new symbol instances for all symbols in this list of sheet paths prefixed with aPrefix...
bool TestForRecursion(const SCH_SHEET_LIST &aSrcSheetHierarchy, const wxString &aDestFileName)
Test every SCH_SHEET_PATH in this SCH_SHEET_LIST to verify if adding the sheets stored in aSrcSheetHi...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Hold a record identifying a symbol library accessed by the appropriate symbol library SCH_PLUGIN obje...
const wxString GetType() const override
Return the type of symbol library table represented by this row.
static const wxString & GetSymbolLibTableFileName()
SYMBOL_LIB_TABLE_ROW * FindRow(const wxString &aNickName, bool aCheckIfEnabled=false)
Return an SYMBOL_LIB_TABLE_ROW if aNickName is found in this table or in any chained fallBack table f...
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
void GRForceBlackPen(bool flagforce)
void GRResetPenAndBrush(wxDC *DC)
@ LAYER_DRAWINGSHEET
drawingsheet frame and titleblock
@ LAYER_SCHEMATIC_DRAWINGSHEET
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
bool show_sheet_filename_case_sensitivity_dialog
Definition of file extensions used in Kicad.