43#include <wx/clipbrd.h>
44#include <wx/dcmemory.h>
47#include <wx/richmsgdlg.h>
58 wxASSERT( aSheet && aCurrentSheet );
66 if( destFilePath.IsEmpty() )
74 wxASSERT( wxFileName( destFilePath ).IsAbsolute() );
78 msg.Printf(
_(
"The sheet changes cannot be made because the destination sheet already "
79 "has the sheet '%s' or one of its subsheets as a parent somewhere in the "
80 "schematic hierarchy." ),
92 wxASSERT( aSheet && aSheet->
GetScreen() );
99 msg.Printf(
_(
"The schematic '%s' has not had its symbol library links remapped "
100 "to the symbol library table. The project this schematic belongs to "
101 "must first be remapped before it can be imported into the current "
172 const wxString& aFileName,
bool aSkipRecursionCheck,
175 wxASSERT( aSheet && aCurrentSheet );
178 wxFileName currentSheetFileName;
179 bool libTableChanged =
false;
183 if( schFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
184 schFileType = SCH_IO_MGR::SCH_KICAD;
187 std::unique_ptr< SCH_SHEET> tmpSheet = std::make_unique<SCH_SHEET>( &
Schematic() );
192 const_cast<KIID&
>( tmpSheet->m_Uuid ) = aSheet->
m_Uuid;
194 wxFileName fileName( aFileName );
196 if( !fileName.IsAbsolute() && !fileName.MakeAbsolute() )
198 wxFAIL_MSG( wxString::Format(
"Cannot make file name '%s' path absolute.", aFileName ) );
202 wxString fullFilename = fileName.GetFullPath();
208 tmpSheet.reset( pi->LoadSchematicFile( fullFilename, &
Schematic() ) );
212 tmpSheet->SetFileName( fullFilename );
213 pi->LoadSchematicFile( fullFilename, &
Schematic(), tmpSheet.get() );
216 if( !pi->GetError().IsEmpty() )
218 msg =
_(
"The entire schematic could not be loaded. Errors occurred attempting "
219 "to load hierarchical sheet schematics." );
221 wxMessageDialog msgDlg1(
this, msg,
_(
"Schematic Load Error" ),
222 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
223 wxCENTER | wxICON_QUESTION );
224 msgDlg1.SetOKLabel( wxMessageDialog::ButtonLabel(
_(
"Use partial schematic" ) ) );
225 msgDlg1.SetExtendedMessage( pi->GetError() );
227 if( msgDlg1.ShowModal() == wxID_CANCEL )
233 msg.Printf(
_(
"Error loading schematic '%s'." ), fullFilename );
236 msg.Printf(
_(
"Failed to load '%s'." ), fullFilename );
247 if( fileName.GetPathWithSep() !=
Prj().GetProjectPath() )
255 if( sheetPath.size() == 1 )
260 for(
unsigned i = 1; i < sheetPath.size(); i++ )
263 wxCHECK2( sheet,
continue );
266 wxCHECK2( screen,
continue );
269 wxFileName loadedSheetFileName = screen->
GetFileName();
270 wxCHECK2( loadedSheetFileName.IsAbsolute(),
continue );
272 wxFileName tmp = loadedSheetFileName;
273 wxString sheetFileName;
275 if( tmp.MakeRelativeTo( lastSheetPath ) )
276 sheetFileName = tmp.GetFullPath();
278 sheetFileName = loadedSheetFileName.GetFullPath();
280 sheetFileName.Replace( wxT(
"\\" ), wxT(
"/" ) );
282 lastSheetPath = loadedSheetFileName.GetPath();
304 wxArrayString newLibNames;
310 wxMessageDialog::ButtonLabel okButtonLabel(
_(
"Continue Load" ) );
311 wxMessageDialog::ButtonLabel cancelButtonLabel(
_(
"Cancel Load" ) );
317 if( ( tmpSheet->GetScreen()->GetFileFormatVersionAtLoad() < 20221002 )
318 && tmpSheet->GetScreen()->GetSymbolInstances().empty() )
320 msg =
_(
"There are hierarchical sheets in the loaded schematic file from an older "
321 "file version resulting in missing symbol instance data. This will "
322 "result in all of the symbols in the loaded schematic to use either the "
323 "default instance setting or fall back to the library symbol settings. "
324 "Loading the project that uses this schematic file and saving to the "
325 "latest file version will resolve this issue.\n\n"
326 "Do you wish to continue?" );
327 wxMessageDialog msgDlg7(
this, msg,
_(
"Continue Load Schematic" ),
328 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER | wxICON_QUESTION );
329 msgDlg7.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
331 if( msgDlg7.ShowModal() == wxID_CANCEL )
335 if( !aSkipLibCheck && !prjScreens.
HasSchematic( fullFilename ) )
337 if( fileName.GetPathWithSep() ==
Prj().GetProjectPath() )
343 for(
const wxString&
name : names )
346 newLibNames.Add(
name );
349 if( !newLibNames.IsEmpty() )
351 msg =
_(
"There are library names in the selected schematic that are missing "
352 "from the current project library table. This may result in broken "
353 "symbol library references for the loaded schematic.\n\n"
354 "Do you wish to continue?" );
355 wxMessageDialog msgDlg3(
this, msg,
_(
"Continue Load Schematic" ),
356 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
357 wxCENTER | wxICON_QUESTION );
358 msgDlg3.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
360 if( msgDlg3.ShowModal() == wxID_CANCEL )
364 else if( fileName.GetPathWithSep() !=
Prj().GetProjectPath() && projectTable )
372 wxArrayString duplicateLibNames;
374 for(
const wxString&
name : names )
377 newLibNames.Add(
name );
379 duplicateLibNames.Add(
name );
387 if( !newLibNames.IsEmpty() || !duplicateLibNames.IsEmpty() )
389 if( !symLibTableFn.Exists() || !symLibTableFn.IsFileReadable() )
391 msg =
_(
"The selected file was created as part of a different project. "
392 "Linking the file to this project may result in missing or "
393 "incorrect symbol library references.\n\n"
394 "Do you wish to continue?" );
395 wxMessageDialog msgDlg4(
this, msg,
_(
"Continue Load Schematic" ),
396 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER
398 msgDlg4.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
400 if( msgDlg4.ShowModal() == wxID_CANCEL )
407 msg.Printf(
_(
"Error loading the symbol library table '%s'." ),
408 symLibTableFn.GetFullPath() );
418 if( !newLibNames.IsEmpty() )
420 bool missingLibNames =
table.Rows().empty();
422 if( !missingLibNames )
424 for(
const wxString& newLibName : newLibNames )
426 if( !
table.HasRow( newLibName ) )
428 missingLibNames =
true;
434 if( missingLibNames )
436 msg =
_(
"There are symbol library names in the selected schematic that "
437 "are missing from the selected schematic project library table. "
438 "This may result in broken symbol library references.\n\n"
439 "Do you wish to continue?" );
440 wxMessageDialog msgDlg5(
this, msg,
_(
"Continue Load Schematic" ),
441 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
442 wxCENTER | wxICON_QUESTION );
443 msgDlg5.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
445 if( msgDlg5.ShowModal() == wxID_CANCEL )
453 if( !duplicateLibNames.IsEmpty() && !
table.Rows().empty() )
455 bool libNameConflict =
false;
457 for(
const wxString& duplicateLibName : duplicateLibNames )
463 thisRow = *adapter->
GetRow( duplicateLibName );
465 if(
table.HasRow( duplicateLibName ) )
466 otherRow = *
table.Row( duplicateLibName );
469 if( thisRow && !otherRow )
472 if( !thisRow || !otherRow )
475 wxFileName otherUriFileName;
479 if( otherURI.Contains(
"${KIPRJMOD}" ) || otherURI.Contains(
"$(KIPRJMOD)" ) )
483 otherUriFileName.SetPath( fileName.GetPath() );
484 otherUriFileName.SetFullName( otherURI.AfterLast(
'}' ) );
485 otherURI = otherUriFileName.GetFullPath();
488 if( thisURI != otherURI )
490 libNameConflict =
true;
495 if( libNameConflict )
497 msg =
_(
"A duplicate library name that references a different library exists "
498 "in the current library table. This conflict cannot be resolved and "
499 "may result in broken symbol library references.\n\n"
500 "Do you wish to continue?" );
501 wxMessageDialog msgDlg6(
this, msg,
_(
"Continue Load Schematic" ),
502 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
503 wxCENTER | wxICON_QUESTION );
504 msgDlg6.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
506 if( msgDlg6.ShowModal() == wxID_CANCEL )
514 if( !newLibNames.IsEmpty() && !
table.Rows().empty() )
516 for(
const wxString& libName : newLibNames )
530 if( uri.Contains(
"${KIPRJMOD}" ) || uri.Contains(
"$(KIPRJMOD)" ) )
534 newLib.SetPath( fileName.GetPath() );
535 newLib.SetFullName( uri.AfterLast(
'}' ) );
536 uri = newLib.GetFullPath();
554 libTableChanged =
true;
560 SCH_SCREEN* newScreen = tmpSheet->GetScreen();
561 wxCHECK_MSG( newScreen,
false,
"No screen defined for sheet." );
563 if( libTableChanged && projectTable )
565 projectTable->
Save().map_error(
568 wxMessageDialog dlg(
this,
_(
"Error saving project library table." ),
569 _(
"File Save Error" ), wxOK | wxICON_ERROR );
570 dlg.SetExtendedMessage( aError.
message );
608 bool* aIsUndoable,
bool* aClearAnnotationNewItems,
609 bool* aUpdateHierarchyNavigator,
610 wxString* aSourceSheetFilename )
612 if( aSheet ==
nullptr || aHierarchy ==
nullptr )
617 aUpdateHierarchyNavigator, aSourceSheetFilename );
639 double inch2Iu = 1000.0 *
schIUScale.IU_PER_MILS;
640 double scale = ppi / inch2Iu;
642 wxSize dcsize = drawArea.GetSize();
644 int maxdim = std::max( dcsize.x, dcsize.y );
647 const int maxbitmapsize = 5600;
649 while(
int( maxdim *
scale ) > maxbitmapsize )
652 scale = ppi / inch2Iu;
666 wxBitmap
image( dcsize );
667 dc.SelectObject(
image );
685 dc.SetUserScale( 1.0, 1.0 );
696 wxLogMessage(
_(
"Cannot create the schematic image") );
700 wxLogMessage(
"printout internal error" );
704 dc.SelectObject( wxNullBitmap );
709 if( wxTheClipboard->Open() )
712 wxBitmapDataObject* clipbrd_data =
new wxBitmapDataObject(
image );
713 wxTheClipboard->SetData( clipbrd_data );
714 wxTheClipboard->Flush();
715 wxTheClipboard->Close();
727 const wxString& aSchematicFileName )
731 wxFileName fn = aSchematicFileName;
733 wxCHECK( fn.IsAbsolute(),
false );
735 auto can_cause_issues = [&]() ->
bool
738 wxFileName rhs = aSchematicFileName;
739 wxFileName old = aOldName;
740 wxString oldLower = old.GetFullName().Lower();
741 wxString rhsLower = rhs.GetFullName().Lower();
746 wxCHECK( rhs.IsAbsolute(),
false );
750 lhs = sheet.LastScreen()->GetFileName();
752 if( lhs.GetPath() != rhs.GetPath() )
755 lhsLower = lhs.GetFullName().Lower();
757 if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
763 if( oldLower == rhsLower )
769 if(
eeconfig()->m_Appearance.show_sheet_filename_case_sensitivity_dialog && can_cause_issues() )
771 msg.Printf(
_(
"The file name '%s' can cause issues with an existing file name\n"
772 "already defined in the schematic on systems that support case\n"
773 "insensitive file names. This will cause issues if you copy this\n"
774 "project to an operating system that supports case insensitive file\n"
775 "names.\n\nDo you wish to continue?" ),
778 wxRichMessageDialog dlg(
this, msg,
_(
"Warning" ),
779 wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
780 dlg.ShowCheckBox(
_(
"Do not show this message again." ) );
781 dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel(
_(
"Create New Sheet" ) ),
782 wxMessageDialog::ButtonLabel(
_(
"Cancel" ) ) );
784 if( dlg.ShowModal() == wxID_NO )
788 !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.
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
std::optional< LIBRARY_TABLE * > ProjectTable() const
Retrieves the project library table for this adapter type, or nullopt if one doesn't exist.
bool HasLibrary(const wxString &aNickname, bool aCheckEnabled=false) const
Test for the existence of aNickname in the library tables.
std::optional< LIBRARY_TABLE_ROW * > GetRow(const wxString &aNickname, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH) const
Like LIBRARY_MANAGER::GetRow but filtered to the LIBRARY_TABLE_TYPE of this adapter.
std::optional< wxString > GetFullURI(LIBRARY_TABLE_TYPE aType, const wxString &aNickname, bool aSubstituted=false) const
Return the full location specifying URI for the LIB, either in original UI form or in environment var...
void SetOptions(const wxString &aOptions)
void SetNickname(const wxString &aNickname)
void SetType(const wxString &aType)
void SetDescription(const wxString &aDescription)
const wxString & Type() const
void SetURI(const wxString &aUri)
const wxString & Description() const
const wxString & Options() const
LIBRARY_RESULT< void > Save()
LIBRARY_TABLE_ROW & InsertRow()
Builds a new row and inserts it at the end of the table; returning a reference to the row.
static SYMBOL_LIBRARY_ADAPTER * SymbolLibAdapter(PROJECT *aProject)
Accessor for project symbol library manager adapter.
virtual const wxString GetProjectPath() const
Return the full path of the project.
SCH_SHEET_LIST Hierarchy() const
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.
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.
An interface to the global shared library manager that is schematic-specific and linked to one projec...
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 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.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
This file is part of the common library.
void GRForceBlackPen(bool flagforce)
void GRResetPenAndBrush(wxDC *DC)
static const std::string SymbolLibraryTableFileName
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
@ LAYER_DRAWINGSHEET
Sheet frame and title block.
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
bool title_block
Whether or not to print title block.
bool show_sheet_filename_case_sensitivity_dialog
VECTOR2< int32_t > VECTOR2I
wxSize ToWxSize(const VECTOR2I &aSize)
Definition of file extensions used in Kicad.