44#include <wx/clipbrd.h>
45#include <wx/dcmemory.h>
48#include <wx/richmsgdlg.h>
56 wxASSERT( aSheet && aCurrentSheet );
64 if( destFilePath.IsEmpty() )
72 wxASSERT( wxFileName( destFilePath ).IsAbsolute() );
76 msg.Printf(
_(
"The sheet changes cannot be made because the destination sheet already "
77 "has the sheet '%s' or one of its subsheets as a parent somewhere in the "
78 "schematic hierarchy." ),
90 wxASSERT( aSheet && aSheet->
GetScreen() );
97 msg.Printf(
_(
"The schematic '%s' has not had its symbol library links remapped "
98 "to the symbol library table. The project this schematic belongs to "
99 "must first be remapped before it can be imported into the current "
170 const wxString& aFileName,
bool aSkipRecursionCheck,
173 wxASSERT( aSheet && aCurrentSheet );
176 wxFileName currentSheetFileName;
177 bool libTableChanged =
false;
181 if( schFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
182 schFileType = SCH_IO_MGR::SCH_KICAD;
185 std::unique_ptr< SCH_SHEET> tmpSheet = std::make_unique<SCH_SHEET>( &
Schematic() );
190 const_cast<KIID&
>( tmpSheet->m_Uuid ) = aSheet->
m_Uuid;
192 wxFileName fileName( aFileName );
194 if( !fileName.IsAbsolute() && !fileName.MakeAbsolute() )
196 wxFAIL_MSG( wxString::Format(
"Cannot make file name '%s' path absolute.", aFileName ) );
200 wxString fullFilename = fileName.GetFullPath();
206 tmpSheet.reset( pi->LoadSchematicFile( fullFilename, &
Schematic() ) );
210 tmpSheet->SetFileName( fullFilename );
211 pi->LoadSchematicFile( fullFilename, &
Schematic(), tmpSheet.get() );
214 if( !pi->GetError().IsEmpty() )
216 msg =
_(
"The entire schematic could not be loaded. Errors occurred attempting "
217 "to load hierarchical sheet schematics." );
219 wxMessageDialog msgDlg1(
this, msg,
_(
"Schematic Load Error" ),
220 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
221 wxCENTER | wxICON_QUESTION );
222 msgDlg1.SetOKLabel( wxMessageDialog::ButtonLabel(
_(
"Use partial schematic" ) ) );
223 msgDlg1.SetExtendedMessage( pi->GetError() );
225 if( msgDlg1.ShowModal() == wxID_CANCEL )
231 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFilename );
234 msg.Printf(
_(
"Failed to load '%s'." ), fullFilename );
245 if( fileName.GetPathWithSep() !=
Prj().GetProjectPath() )
253 for(
unsigned i = 0; i < sheetPath.size(); i++ )
256 wxCHECK2( sheet,
continue );
259 wxCHECK2( screen,
continue );
265 screenFileName.MakeRelativeTo( fileName.GetPath() );
266 screenFileName.MakeAbsolute(
Prj().GetProjectPath() );
267 screen->
SetFileName( screenFileName.GetFullPath() );
270 wxFileName loadedSheetFileName = screen->
GetFileName();
271 wxCHECK2( loadedSheetFileName.IsAbsolute(),
continue );
273 wxFileName tmp = loadedSheetFileName;
274 wxString sheetFileName;
276 if( tmp.MakeRelativeTo( lastSheetPath ) )
277 sheetFileName = tmp.GetFullPath();
279 sheetFileName = loadedSheetFileName.GetFullPath();
282 lastSheetPath = loadedSheetFileName.GetPath();
301 wxArrayString newLibNames;
307 wxMessageDialog::ButtonLabel okButtonLabel(
_(
"Continue Load" ) );
308 wxMessageDialog::ButtonLabel cancelButtonLabel(
_(
"Cancel Load" ) );
314 if( ( tmpSheet->GetScreen()->GetFileFormatVersionAtLoad() < 20221002 )
315 && tmpSheet->GetScreen()->GetSymbolInstances().empty() )
317 msg =
_(
"There are hierarchical sheets in the loaded schematic file from an older "
318 "file version resulting in missing symbol instance data. This will "
319 "result in all of the symbols in the loaded schematic to use either the "
320 "default instance setting or fall back to the library symbol settings. "
321 "Loading the project that uses this schematic file and saving to the "
322 "lastest file version will resolve this issue.\n\n"
323 "Do you wish to continue?" );
324 wxMessageDialog msgDlg7(
this, msg,
_(
"Continue Load Schematic" ),
325 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER | wxICON_QUESTION );
326 msgDlg7.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
328 if( msgDlg7.ShowModal() == wxID_CANCEL )
334 if( fileName.GetPathWithSep() ==
Prj().GetProjectPath() )
340 for(
const wxString&
name : names )
343 newLibNames.Add(
name );
346 if( !newLibNames.IsEmpty() )
348 msg =
_(
"There are library names in the selected schematic that are missing "
349 "from the current project library table. This may result in broken "
350 "symbol library references for the loaded schematic.\n\n"
351 "Do you wish to continue?" );
352 wxMessageDialog msgDlg3(
this, msg,
_(
"Continue Load Schematic" ),
353 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
354 wxCENTER | wxICON_QUESTION );
355 msgDlg3.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
357 if( msgDlg3.ShowModal() == wxID_CANCEL )
361 else if( fileName.GetPathWithSep() !=
Prj().GetProjectPath() )
369 wxArrayString duplicateLibNames;
371 for(
const wxString&
name : names )
374 newLibNames.Add(
name );
376 duplicateLibNames.Add(
name );
380 wxFileName symLibTableFn( fileName.GetPath(),
385 if( !aSkipLibCheck && ( !newLibNames.IsEmpty() || !duplicateLibNames.IsEmpty() ) )
387 if( !symLibTableFn.Exists() || !symLibTableFn.IsFileReadable() )
389 msg =
_(
"The selected file was created as part of a different project. "
390 "Linking the file to this project may result in missing or "
391 "incorrect symbol library references.\n\n"
392 "Do you wish to continue?" );
393 wxMessageDialog msgDlg4(
this, msg,
_(
"Continue Load Schematic" ),
394 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER
396 msgDlg4.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
398 if( msgDlg4.ShowModal() == wxID_CANCEL )
405 table.
Load( symLibTableFn.GetFullPath() );
409 msg.Printf(
_(
"Error loading the symbol library table '%s'." ),
410 symLibTableFn.GetFullPath() );
420 if( !newLibNames.IsEmpty() )
422 bool missingLibNames = table.
IsEmpty();
424 if( !missingLibNames )
426 for(
const wxString& newLibName : newLibNames )
430 missingLibNames =
true;
436 if( missingLibNames )
438 msg =
_(
"There are symbol library names in the selected schematic that "
439 "are missing from the selected schematic project library table. "
440 "This may result in broken symbol library references.\n\n"
441 "Do you wish to continue?" );
442 wxMessageDialog msgDlg5(
this, msg,
_(
"Continue Load Schematic" ),
443 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
444 wxCENTER | wxICON_QUESTION );
445 msgDlg5.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
447 if( msgDlg5.ShowModal() == wxID_CANCEL )
455 if( !duplicateLibNames.IsEmpty() && !table.
IsEmpty() )
457 bool libNameConflict =
false;
459 for(
const wxString& duplicateLibName : duplicateLibNames )
468 otherRow = table.
FindRow( duplicateLibName );
471 if( thisRow && !otherRow )
474 if( !thisRow || !otherRow )
477 wxFileName otherUriFileName;
478 wxString thisURI = thisRow->
GetFullURI(
true );
479 wxString otherURI = otherRow->
GetFullURI(
false);
481 if( otherURI.Contains(
"${KIPRJMOD}" ) || otherURI.Contains(
"$(KIPRJMOD)" ) )
485 otherUriFileName.SetPath( fileName.GetPath() );
486 otherUriFileName.SetFullName( otherURI.AfterLast(
'}' ) );
487 otherURI = otherUriFileName.GetFullPath();
490 if( thisURI != otherURI )
492 libNameConflict =
true;
497 if( libNameConflict )
499 msg =
_(
"A duplicate library name that references a different library exists "
500 "in the current library table. This conflict cannot be resolved and "
501 "may result in broken symbol library references.\n\n"
502 "Do you wish to continue?" );
503 wxMessageDialog msgDlg6(
this, msg,
_(
"Continue Load Schematic" ),
504 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
505 wxCENTER | wxICON_QUESTION );
506 msgDlg6.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
508 if( msgDlg6.ShowModal() == wxID_CANCEL )
516 if( !newLibNames.IsEmpty() && !table.
IsEmpty() )
518 for(
const wxString& libName : newLibNames )
528 wxString uri = table.
GetFullURI( libName,
false );
531 if( uri.Contains(
"${KIPRJMOD}" ) || uri.Contains(
"$(KIPRJMOD)" ) )
535 newLib.SetPath( fileName.GetPath() );
536 newLib.SetFullName( uri.AfterLast(
'}' ) );
537 uri = newLib.GetFullPath();
548 wxCHECK( row,
false );
556 libTableChanged =
true;
562 SCH_SCREEN* newScreen = tmpSheet->GetScreen();
563 wxCHECK_MSG( newScreen,
false,
"No screen defined for sheet." );
565 if( libTableChanged )
604 bool* aIsUndoable,
bool* aClearAnnotationNewItems,
605 bool* aUpdateHierarchyNavigator,
606 wxString* aSourceSheetFilename )
608 if( aSheet ==
nullptr || aHierarchy ==
nullptr )
613 aUpdateHierarchyNavigator, aSourceSheetFilename );
637 double scale = ppi / inch2Iu;
639 wxSize dcsize = drawArea.GetSize();
641 int maxdim = std::max( dcsize.x, dcsize.y );
644 const int maxbitmapsize = 5600;
646 while(
int( maxdim *
scale ) > maxbitmapsize )
649 scale = ppi / inch2Iu;
663 wxBitmap
image( dcsize );
664 dc.SelectObject(
image );
684 dc.SetUserScale( 1.0, 1.0 );
689 wxLogMessage(
_(
"Cannot create the schematic image") );
693 wxLogMessage(
"printout internal error" );
700 dc.SelectObject( wxNullBitmap );
705 if( wxTheClipboard->Open() )
708 wxBitmapDataObject* clipbrd_data =
new wxBitmapDataObject(
image );
709 wxTheClipboard->SetData( clipbrd_data );
710 wxTheClipboard->Flush();
711 wxTheClipboard->Close();
726 wxFileName fn = aSchematicFileName;
728 wxCHECK( fn.IsAbsolute(),
false );
730 auto can_cause_issues = [&]() ->
bool
733 wxFileName rhs = aSchematicFileName;
734 wxFileName old = aOldName;
735 wxString oldLower = old.GetFullName().Lower();
736 wxString rhsLower = rhs.GetFullName().Lower();
741 wxCHECK( rhs.IsAbsolute(),
false );
745 lhs = sheet.LastScreen()->GetFileName();
747 if( lhs.GetPath() != rhs.GetPath() )
750 lhsLower = lhs.GetFullName().Lower();
752 if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
758 if( oldLower == rhsLower )
764 if(
eeconfig()->m_Appearance.show_sheet_filename_case_sensitivity_dialog && can_cause_issues() )
766 msg.Printf(
_(
"The file name '%s' can cause issues with an existing file name\n"
767 "already defined in the schematic on systems that support case\n"
768 "insensitive file names. This will cause issues if you copy this\n"
769 "project to an operating system that supports case insensitive file\n"
770 "names.\n\nDo you wish to continue?" ),
773 wxRichMessageDialog dlg(
this, msg,
_(
"Warning" ),
774 wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
775 dlg.ShowCheckBox(
_(
"Do not show this message again." ) );
776 dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel(
_(
"Create New Sheet" ) ),
777 wxMessageDialog::ButtonLabel(
_(
"Cancel" ) ) );
779 if( dlg.ShowModal() == wxID_NO )
783 !dlg.IsCheckBoxChecked();
constexpr EDA_IU_SCALE schIUScale
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
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.
PAGE_SETTINGS m_PageSettings
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
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)
wxDC * GetPrintDC() const
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.
bool InsertRow(LIB_TABLE_ROW *aRow, bool doReplace=false)
Adds aRow if it does not already exist or if doReplace is true.
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.
void Save(const wxString &aFileName) const
Write this library table to aFileName in s-expression form.
static SYMBOL_LIB_TABLE * SchSymbolLibTable(PROJECT *aProject)
Accessor for project symbol library table.
virtual const wxString GetProjectPath() const
Return the full path of the project.
SCH_SHEET_LIST Hierarchy() const override
Return the full schematic flattened hierarchical sheet list.
SCH_RENDER_SETTINGS * GetRenderSettings()
const VECTOR2I 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
const PAGE_INFO & GetPageSettings() const override
bool AllowCaseSensitiveFileNameClashes(const wxString &aOldName, 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 LoadSheetFromFile(SCH_SHEET *aSheet, SCH_SHEET_PATH *aCurrentSheet, const wxString &aFileName, bool aSkipRecursionCheck=false, bool aSkipLibCheck=false)
Load a the KiCad schematic file aFileName into the sheet aSheet.
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 *aIsUndoable=nullptr, bool *aClearAnnotationNewItems=nullptr, bool *aUpdateHierarchyNavigator=nullptr, wxString *aSourceSheetFilename=nullptr)
Edit an existing sheet or add a new sheet to the schematic.
bool CheckSheetForRecursion(SCH_SHEET *aSheet, SCH_SHEET_PATH *aCurrentSheet)
Verify that aSheet will not cause a recursion error in aCurrentSheet.
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, int aCtl=0)
Return a plugin type given a schematic using the file extension of aSchematicPath.
Custom print out for printing schematics.
bool PrintPage(SCH_SCREEN *aScreen, wxDC *aDC, bool aForPrinting)
Print the current SCH_SCREEN using a given wxDC.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
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.
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetPageSettings(const PAGE_INFO &aPageSettings)
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
const TITLE_BLOCK & GetTitleBlock() const
void MigrateSimModels()
Migrate any symbols having V6 simulation models to their V7 equivalents.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void AddNewSymbolInstances(const SCH_SHEET_PATH &aPrefixSheetPath, const wxString &aProjectName)
Attempt to add new symbol instances for all symbols in this list of sheet paths prefixed with aPrefix...
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)
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_IO object i...
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...
Hold the information shown in the lower right corner of a plot, printout, or editing view.
const wxString & GetCompany() const
void SetRevision(const wxString &aRevision)
void SetComment(int aIdx, const wxString &aComment)
const wxString & GetRevision() const
void SetTitle(const wxString &aTitle)
const wxString & GetDate() const
const wxString & GetComment(int aIdx) const
void SetCompany(const wxString &aCompany)
const wxString & GetTitle() const
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
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)
bool m_EnableEeschemaExportClipboardCairo
Enable Eeschema Export to clipboard using Cairo.
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
@ LAYER_DRAWINGSHEET
drawingsheet frame and titleblock
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
bool show_sheet_filename_case_sensitivity_dialog
wxSize ToWxSize(const VECTOR2I &aSize)
Definition of file extensions used in Kicad.