KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sheet.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2004-2024 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <sch_draw_panel.h>
26#include <confirm.h>
27#include <kiface_base.h>
28#include <project.h>
29#include <math/vector2wx.h>
31#include <tool/tool_manager.h>
32#include <project_sch.h>
33#include <sch_edit_frame.h>
35#include <sch_sheet.h>
36#include <sch_sheet_path.h>
37#include <sch_view.h>
38#include <sch_painter.h>
39#include <schematic.h>
40#include <symbol_lib_table.h>
42#include <tool/actions.h>
43
44#include <wx/clipbrd.h>
45#include <wx/dcmemory.h>
46#include <wx/log.h>
47
48
50{
51 wxASSERT( aSheet && aCurrentSheet );
52
53 wxString msg;
54 SCH_SHEET_LIST hierarchy = Schematic().GetSheets(); // The full schematic sheet hierarchy.
55 SCH_SHEET_LIST sheetHierarchy( aSheet ); // This is the hierarchy of the loaded file.
56
57 wxString destFilePath = aCurrentSheet->LastScreen()->GetFileName();
58
59 if( destFilePath.IsEmpty() )
60 {
61 // If file is unsaved then there can't (yet) be any recursion.
62 return false;
63 }
64
65 // SCH_SCREEN object file paths are expected to be absolute. If this assert fires,
66 // something is seriously broken.
67 wxASSERT( wxFileName( destFilePath ).IsAbsolute() );
68
69 if( hierarchy.TestForRecursion( sheetHierarchy, destFilePath ) )
70 {
71 msg.Printf( _( "The sheet changes cannot be made because the destination sheet already "
72 "has the sheet '%s' or one of its subsheets as a parent somewhere in the "
73 "schematic hierarchy." ),
74 destFilePath );
75 DisplayError( this, msg );
76 return true;
77 }
78
79 return false;
80}
81
82
84{
85 wxASSERT( aSheet && aSheet->GetScreen() );
86
87 wxString msg;
88 SCH_SCREENS newScreens( aSheet );
89
90 if( newScreens.HasNoFullyDefinedLibIds() )
91 {
92 msg.Printf( _( "The schematic '%s' has not had its symbol library links remapped "
93 "to the symbol library table. The project this schematic belongs to "
94 "must first be remapped before it can be imported into the current "
95 "project." ),
96 aSheet->GetScreen()->GetFileName() );
97 DisplayInfoMessage( this, msg );
98 return true;
99 }
100
101 return false;
102}
103
104
105void SCH_EDIT_FRAME::InitSheet( SCH_SHEET* aSheet, const wxString& aNewFilename )
106{
107 SCH_SCREEN* newScreen = new SCH_SCREEN( &Schematic() );
108 aSheet->SetScreen( newScreen );
109 aSheet->GetScreen()->SetContentModified();
110 aSheet->GetScreen()->SetFileName( aNewFilename );
111
113 wxCHECK( cfg, /* void */ );
114
116 newScreen->SetPageSettings( GetScreen()->GetPageSettings() );
117
118 const TITLE_BLOCK& tb1 = GetScreen()->GetTitleBlock();
119 TITLE_BLOCK tb2 = newScreen->GetTitleBlock();
120
122 tb2.SetRevision( tb1.GetRevision() );
123
124 if( cfg->m_PageSettings.export_date )
125 tb2.SetDate( tb1.GetDate() );
126
128 tb2.SetTitle( tb1.GetTitle() );
129
131 tb2.SetCompany( tb1.GetCompany() );
132
134 tb2.SetComment( 0, tb1.GetComment( 0 ) );
135
137 tb2.SetComment( 1, tb1.GetComment( 1 ) );
138
140 tb2.SetComment( 2, tb1.GetComment( 2 ) );
141
143 tb2.SetComment( 3, tb1.GetComment( 3 ) );
144
146 tb2.SetComment( 4, tb1.GetComment( 4 ) );
147
149 tb2.SetComment( 5, tb1.GetComment( 5 ) );
150
152 tb2.SetComment( 6, tb1.GetComment( 6 ) );
153
155 tb2.SetComment( 7, tb1.GetComment( 7 ) );
156
158 tb2.SetComment( 8, tb1.GetComment( 8 ) );
159
160 newScreen->SetTitleBlock( tb2 );
161}
162
163
165 const wxString& aFileName )
166{
167 wxASSERT( aSheet && aCurrentSheet );
168
169 wxString msg;
170 wxFileName currentSheetFileName;
171 bool libTableChanged = false;
172
173 SCH_IO_MGR::SCH_FILE_T schFileType = SCH_IO_MGR::GuessPluginTypeFromSchPath( aFileName );
174
175 if( schFileType == SCH_IO_MGR::SCH_FILE_UNKNOWN )
176 schFileType = SCH_IO_MGR::SCH_KICAD;
177
178 IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( schFileType ) );
179 std::unique_ptr< SCH_SHEET> tmpSheet = std::make_unique<SCH_SHEET>( &Schematic() );
180
181 // This will cause the sheet UUID to be set to the UUID of the aSheet argument. This is
182 // required to ensure all of the sheet paths in any sub-sheets are correctly generated when
183 // using the temporary SCH_SHEET object that the file is loaded into..
184 const_cast<KIID&>( tmpSheet->m_Uuid ) = aSheet->m_Uuid;
185
186 wxFileName fileName( aFileName );
187
188 if( !fileName.IsAbsolute() && !fileName.MakeAbsolute() )
189 {
190 wxFAIL_MSG( wxString::Format( "Cannot make file name '%s' path absolute.", aFileName ) );
191 return false;
192 }
193
194 wxString fullFilename = fileName.GetFullPath();
195
196 try
197 {
198 if( aSheet->GetScreen() != nullptr )
199 {
200 tmpSheet.reset( pi->LoadSchematicFile( fullFilename, &Schematic() ) );
201 }
202 else
203 {
204 tmpSheet->SetFileName( fullFilename );
205 pi->LoadSchematicFile( fullFilename, &Schematic(), tmpSheet.get() );
206 }
207
208 if( !pi->GetError().IsEmpty() )
209 {
210 msg = _( "The entire schematic could not be loaded. Errors occurred attempting "
211 "to load hierarchical sheet schematics." );
212
213 wxMessageDialog msgDlg1( this, msg, _( "Schematic Load Error" ),
214 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
215 wxCENTER | wxICON_QUESTION );
216 msgDlg1.SetOKLabel( wxMessageDialog::ButtonLabel( _( "Use partial schematic" ) ) );
217 msgDlg1.SetExtendedMessage( pi->GetError() );
218
219 if( msgDlg1.ShowModal() == wxID_CANCEL )
220 return false;
221 }
222 }
223 catch( const IO_ERROR& ioe )
224 {
225 msg.Printf( _( "Error loading schematic '%s'." ), fullFilename );
226 DisplayErrorMessage( this, msg, ioe.What() );
227
228 msg.Printf( _( "Failed to load '%s'." ), fullFilename );
229 SetMsgPanel( wxEmptyString, msg );
230
231 return false;
232 }
233
234 // If the loaded schematic is in a different folder from the current project and
235 // it contains hierarchical sheets, the hierarchical sheet paths need to be updated.
236 if( fileName.GetPathWithSep() != Prj().GetProjectPath() && tmpSheet->CountSheets() )
237 {
238 SCH_SHEET_LIST loadedSheets( tmpSheet.get() );
239
240 for( const SCH_SHEET_PATH& sheetPath : loadedSheets )
241 {
242 // Skip the loaded sheet since the user already determined if the file path should
243 // be relative or absolute.
244 if( sheetPath.size() == 1 )
245 continue;
246
247 wxString lastSheetPath = fileName.GetPathWithSep();
248
249 for( unsigned i = 1; i < sheetPath.size(); i++ )
250 {
251 SCH_SHEET* sheet = sheetPath.at( i );
252 wxCHECK2( sheet, continue );
253
254 SCH_SCREEN* screen = sheet->GetScreen();
255 wxCHECK2( screen, continue );
256
257 // Use the screen file name which should always be absolute.
258 wxFileName loadedSheetFileName = screen->GetFileName();
259 wxCHECK2( loadedSheetFileName.IsAbsolute(), continue );
260
261 wxFileName tmp = loadedSheetFileName;
262 wxString sheetFileName;
263
264 if( tmp.MakeRelativeTo( lastSheetPath ) )
265 sheetFileName = tmp.GetFullPath();
266 else
267 sheetFileName = loadedSheetFileName.GetFullPath();
268
269 sheetFileName.Replace( wxT( "\\" ), wxT( "/" ) );
270 sheet->SetFileName( sheetFileName );
271 lastSheetPath = loadedSheetFileName.GetPath();
272 }
273 }
274 }
275
276 SCH_SHEET_LIST sheetHierarchy( tmpSheet.get() ); // This is the hierarchy of the loaded file.
277 SCH_SHEET_LIST hierarchy = Schematic().GetSheets(); // This is the schematic sheet hierarchy.
278
279 // Make sure any new sheet changes do not cause any recursion issues.
280 if( CheckSheetForRecursion( tmpSheet.get(), aCurrentSheet )
281 || checkForNoFullyDefinedLibIds( tmpSheet.get() ) )
282 {
283 return false;
284 }
285
286 // Make a valiant attempt to warn the user of all possible scenarios where there could
287 // be broken symbol library links.
288 wxArrayString names;
289 wxArrayString newLibNames;
290 SCH_SCREENS newScreens( tmpSheet.get() ); // All screens associated with the import.
291 SCH_SCREENS prjScreens( &Schematic().Root() );
292
293 newScreens.GetLibNicknames( names );
294
295 wxMessageDialog::ButtonLabel okButtonLabel( _( "Continue Load" ) );
296 wxMessageDialog::ButtonLabel cancelButtonLabel( _( "Cancel Load" ) );
297
298 // Prior to schematic file format 20221002, all symbol instance data was saved in the root
299 // sheet so loading a hierarchical sheet that is not the root sheet will have no symbol
300 // instance data. Give the user a chance to go back and save the project that contains this
301 // hierarchical sheet so the symbol instance data will be correct on load.
302 if( ( tmpSheet->GetScreen()->GetFileFormatVersionAtLoad() < 20221002 )
303 && tmpSheet->GetScreen()->GetSymbolInstances().empty() )
304 {
305 msg = _( "There are hierarchical sheets in the loaded schematic file from an older "
306 "file version resulting in missing symbol instance data. This will "
307 "result in all of the symbols in the loaded schematic to use either the "
308 "default instance setting or fall back to the library symbol settings. "
309 "Loading the project that uses this schematic file and saving to the "
310 "lastest file version will resolve this issue.\n\n"
311 "Do you wish to continue?" );
312 wxMessageDialog msgDlg7( this, msg, _( "Continue Load Schematic" ),
313 wxOK | wxCANCEL | wxCANCEL_DEFAULT | wxCENTER | wxICON_QUESTION );
314 msgDlg7.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
315
316 if( msgDlg7.ShowModal() == wxID_CANCEL )
317 return false;
318 }
319
320 if( !prjScreens.HasSchematic( fullFilename ) )
321 {
322 if( fileName.GetPathWithSep() == Prj().GetProjectPath() )
323 {
324 // A schematic in the current project path that isn't part of the current project.
325 // It's possible the user copied this schematic from another project so the library
326 // links may not be available. Even this is check is no guarantee that all symbol
327 // library links are valid but it's better than nothing.
328 for( const wxString& name : names )
329 {
330 if( !PROJECT_SCH::SchSymbolLibTable( &Prj() )->HasLibrary( name ) )
331 newLibNames.Add( name );
332 }
333
334 if( !newLibNames.IsEmpty() )
335 {
336 msg = _( "There are library names in the selected schematic that are missing "
337 "from the current project library table. This may result in broken "
338 "symbol library references for the loaded schematic.\n\n"
339 "Do you wish to continue?" );
340 wxMessageDialog msgDlg3( this, msg, _( "Continue Load Schematic" ),
341 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
342 wxCENTER | wxICON_QUESTION );
343 msgDlg3.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
344
345 if( msgDlg3.ShowModal() == wxID_CANCEL )
346 return false;
347 }
348 }
349 else if( fileName.GetPathWithSep() != Prj().GetProjectPath() )
350 {
351 // A schematic loaded from a path other than the current project path.
352
353 // If there are symbol libraries in the imported schematic that are not in the
354 // symbol library table of this project, there could be a lot of broken symbol
355 // library links. Attempt to add the missing libraries to the project symbol
356 // library table.
357 wxArrayString duplicateLibNames;
358
359 for( const wxString& name : names )
360 {
361 if( !PROJECT_SCH::SchSymbolLibTable( &Prj() )->HasLibrary( name ) )
362 newLibNames.Add( name );
363 else
364 duplicateLibNames.Add( name );
365 }
366
367 SYMBOL_LIB_TABLE table;
368 wxFileName symLibTableFn( fileName.GetPath(),
370
371 // If there are any new or duplicate libraries, check to see if it's possible that
372 // there could be any missing libraries that would cause broken symbol library links.
373 if( !newLibNames.IsEmpty() || !duplicateLibNames.IsEmpty() )
374 {
375 if( !symLibTableFn.Exists() || !symLibTableFn.IsFileReadable() )
376 {
377 msg = _( "The selected file was created as part of a different project. "
378 "Linking the file to this project may result in missing or "
379 "incorrect symbol library references.\n\n"
380 "Do you wish to continue?" );
381 wxMessageDialog msgDlg4( this, msg, _( "Continue Load Schematic" ),
382 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
383 wxCENTER | wxICON_QUESTION );
384 msgDlg4.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
385
386 if( msgDlg4.ShowModal() == wxID_CANCEL )
387 return false;
388 }
389 else
390 {
391 try
392 {
393 table.Load( symLibTableFn.GetFullPath() );
394 }
395 catch( const IO_ERROR& ioe )
396 {
397 msg.Printf( _( "Error loading the symbol library table '%s'." ),
398 symLibTableFn.GetFullPath() );
399 DisplayErrorMessage( nullptr, msg, ioe.What() );
400 return false;
401 }
402 }
403 }
404
405 // Check to see if any of the symbol libraries found in the appended schematic do
406 // not exist in the current project are missing from the appended project symbol
407 // library table.
408 if( !newLibNames.IsEmpty() )
409 {
410 bool missingLibNames = table.IsEmpty();
411
412 if( !missingLibNames )
413 {
414 for( const wxString& newLibName : newLibNames )
415 {
416 if( !table.HasLibrary( newLibName ) )
417 {
418 missingLibNames = true;
419 break;
420 }
421 }
422 }
423
424 if( missingLibNames )
425 {
426 msg = _( "There are symbol library names in the selected schematic that "
427 "are missing from the selected schematic project library table. "
428 "This may result in broken symbol library references.\n\n"
429 "Do you wish to continue?" );
430 wxMessageDialog msgDlg5( this, msg, _( "Continue Load Schematic" ),
431 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
432 wxCENTER | wxICON_QUESTION );
433 msgDlg5.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
434
435 if( msgDlg5.ShowModal() == wxID_CANCEL )
436 return false;
437 }
438 }
439
440 // The library name already exists in the current project. Check to see if the
441 // duplicate name is the same library in the current project. If it's not, it's
442 // most likely that the symbol library links will be broken.
443 if( !duplicateLibNames.IsEmpty() && !table.IsEmpty() )
444 {
445 bool libNameConflict = false;
446
447 for( const wxString& duplicateLibName : duplicateLibNames )
448 {
449 const SYMBOL_LIB_TABLE_ROW* thisRow = nullptr;
450 const SYMBOL_LIB_TABLE_ROW* otherRow = nullptr;
451
452 if( PROJECT_SCH::SchSymbolLibTable( &Prj() )->HasLibrary( duplicateLibName ) )
453 thisRow = PROJECT_SCH::SchSymbolLibTable( &Prj() )->FindRow( duplicateLibName );
454
455 if( table.HasLibrary( duplicateLibName ) )
456 otherRow = table.FindRow( duplicateLibName );
457
458 // It's in the global library table so there is no conflict.
459 if( thisRow && !otherRow )
460 continue;
461
462 if( !thisRow || !otherRow )
463 continue;
464
465 wxFileName otherUriFileName;
466 wxString thisURI = thisRow->GetFullURI( true );
467 wxString otherURI = otherRow->GetFullURI( false);
468
469 if( otherURI.Contains( "${KIPRJMOD}" ) || otherURI.Contains( "$(KIPRJMOD)" ) )
470 {
471 // Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
472 // not expand to a valid symbol library path.
473 otherUriFileName.SetPath( fileName.GetPath() );
474 otherUriFileName.SetFullName( otherURI.AfterLast( '}' ) );
475 otherURI = otherUriFileName.GetFullPath();
476 }
477
478 if( thisURI != otherURI )
479 {
480 libNameConflict = true;
481 break;
482 }
483 }
484
485 if( libNameConflict )
486 {
487 msg = _( "A duplicate library name that references a different library exists "
488 "in the current library table. This conflict cannot be resolved and "
489 "may result in broken symbol library references.\n\n"
490 "Do you wish to continue?" );
491 wxMessageDialog msgDlg6( this, msg, _( "Continue Load Schematic" ),
492 wxOK | wxCANCEL | wxCANCEL_DEFAULT |
493 wxCENTER | wxICON_QUESTION );
494 msgDlg6.SetOKCancelLabels( okButtonLabel, cancelButtonLabel );
495
496 if( msgDlg6.ShowModal() == wxID_CANCEL )
497 return false;
498 }
499 }
500
501 // All (most?) of the possible broken symbol library link cases are covered. Map the
502 // new appended schematic project symbol library table entries to the current project
503 // symbol library table.
504 if( !newLibNames.IsEmpty() && !table.IsEmpty() )
505 {
506 for( const wxString& libName : newLibNames )
507 {
508 if( !table.HasLibrary( libName )
509 || PROJECT_SCH::SchSymbolLibTable( &Prj() )->HasLibrary( libName ) )
510 {
511 continue;
512 }
513
514 // Don't expand environment variable because KIPRJMOD will not be correct
515 // for a different project.
516 wxString uri = table.GetFullURI( libName, false );
517 wxFileName newLib;
518
519 if( uri.Contains( "${KIPRJMOD}" ) || uri.Contains( "$(KIPRJMOD)" ) )
520 {
521 // Cannot use relative paths here, "${KIPRJMOD}../path-to-cache-lib" does
522 // not expand to a valid symbol library path.
523 newLib.SetPath( fileName.GetPath() );
524 newLib.SetFullName( uri.AfterLast( '}' ) );
525 uri = newLib.GetFullPath();
526 }
527 else
528 {
529 uri = table.GetFullURI( libName );
530 }
531
532 // Add the library from the imported project to the current project
533 // symbol library table.
534 const SYMBOL_LIB_TABLE_ROW* row = table.FindRow( libName );
535
536 wxCHECK( row, false );
537
538 SYMBOL_LIB_TABLE_ROW* newRow = new SYMBOL_LIB_TABLE_ROW( libName, uri,
539 row->GetType(),
540 row->GetOptions(),
541 row->GetDescr() );
542
544 libTableChanged = true;
545 }
546 }
547 }
548 }
549
550 SCH_SCREEN* newScreen = tmpSheet->GetScreen();
551 wxCHECK_MSG( newScreen, false, "No screen defined for sheet." );
552
553 if( libTableChanged )
554 {
555 PROJECT_SCH::SchSymbolLibTable( &Prj() )->Save( Prj().GetProjectPath() +
557 }
558
559 // Make the best attempt to set the symbol instance data for the loaded scheamtic.
560 if( newScreen->GetFileFormatVersionAtLoad() < 20221002 )
561 {
562 if( !newScreen->GetSymbolInstances().empty() )
563 {
564 // If the loaded schematic is a root sheet for another project, update the symbol
565 // instances.
566 sheetHierarchy.UpdateSymbolInstanceData( newScreen->GetSymbolInstances());
567 }
568 }
569
570 newScreen->MigrateSimModels();
571
572 // Attempt to create new symbol instances using the instance data loaded above.
573 sheetHierarchy.AddNewSymbolInstances( *aCurrentSheet );
574
575 // Add new sheet instance data.
576 sheetHierarchy.AddNewSheetInstances( *aCurrentSheet, hierarchy.GetLastVirtualPageNumber() );
577
578 // It is finally safe to add or append the imported schematic.
579 if( aSheet->GetScreen() == nullptr )
580 aSheet->SetScreen( newScreen );
581 else
582 aSheet->GetScreen()->Append( newScreen );
583
584 SCH_SCREENS allLoadedScreens( aSheet );
585 allLoadedScreens.ReplaceDuplicateTimeStamps();
586
587 return true;
588}
589
590
592 bool* aClearAnnotationNewItems,
593 bool* aUpdateHierarchyNavigator )
594{
595 if( aSheet == nullptr || aHierarchy == nullptr )
596 return false;
597
598 // Get the new texts
599 DIALOG_SHEET_PROPERTIES dlg( this, aSheet, aClearAnnotationNewItems,
600 aUpdateHierarchyNavigator );
601
602 if( dlg.ShowModal() == wxID_CANCEL )
603 return false;
604
606
607 return true;
608}
609
610
612{
613 wxRect drawArea;
614 BASE_SCREEN* screen = GetScreen();
615
616 drawArea.SetSize( ToWxSize( GetPageSizeIU() ) );
617
618 // Calculate a reasonable dc size, in pixels, and the dc scale to fit
619 // the drawings into the dc size
620 // scale is the ratio resolution (in PPI) / internal units
621 double ppi = 300; // Use 300 pixels per inch to create bitmap images on start
622 double inch2Iu = 1000.0 * schIUScale.IU_PER_MILS;
623 double scale = ppi / inch2Iu;
624
625 wxSize dcsize = drawArea.GetSize();
626
627 int maxdim = std::max( dcsize.x, dcsize.y );
628
629 // the max size in pixels of the bitmap used to build the sheet copy
630 const int maxbitmapsize = 5600;
631
632 while( int( maxdim * scale ) > maxbitmapsize )
633 {
634 ppi = ppi / 1.5;
635 scale = ppi / inch2Iu;
636 }
637
638 dcsize.x *= scale;
639 dcsize.y *= scale;
640
641 // Set draw offset, zoom... to values needed to draw in the memory DC
642 // after saving initial values:
643 VECTOR2I tmp_startvisu = screen->m_StartVisu;
644 VECTOR2I old_org = screen->m_DrawOrg;
645 screen->m_DrawOrg.x = screen->m_DrawOrg.y = 0;
646 screen->m_StartVisu.x = screen->m_StartVisu.y = 0;
647
648 wxMemoryDC dc;
649 wxBitmap image( dcsize );
650 dc.SelectObject( image );
651 dc.Clear();
652
653 GRResetPenAndBrush( &dc );
654 GRForceBlackPen( false );
655 dc.SetUserScale( scale, scale );
656
658
659 cfg->SetPrintDC( &dc );
660
661 // Init the color of the layer actually used to print the drawing sheet:
663
664 cfg->SetDefaultFont( eeconfig()->m_Appearance.default_font );
665
666 PrintPage( cfg );
667
668 // Deselect Bitmap from DC before using the bitmap
669 dc.SelectObject( wxNullBitmap );
670
671 {
672 wxLogNull doNotLog; // disable logging of failed clipboard actions
673
674 if( wxTheClipboard->Open() )
675 {
676 // This data objects are held by the clipboard, so do not delete them in the app.
677 wxBitmapDataObject* clipbrd_data = new wxBitmapDataObject( image );
678 wxTheClipboard->SetData( clipbrd_data );
679 wxTheClipboard->Flush(); // Allow data to be available after closing KiCad
680 wxTheClipboard->Close();
681 }
682 }
683
684 GRForceBlackPen( false );
685
686 screen->m_StartVisu = tmp_startvisu;
687 screen->m_DrawOrg = old_org;
688}
689
690
691bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName )
692{
693 wxString msg;
694 SCH_SCREENS screens( Schematic().Root() );
695 wxFileName fn = aSchematicFileName;
696
697 wxCHECK( fn.IsAbsolute(), false );
698
699 if( eeconfig()->m_Appearance.show_sheet_filename_case_sensitivity_dialog
700 && screens.CanCauseCaseSensitivityIssue( aSchematicFileName ) )
701 {
702 msg.Printf( _( "The file name '%s' can cause issues with an existing file name\n"
703 "already defined in the schematic on systems that support case\n"
704 "insensitive file names. This will cause issues if you copy this\n"
705 "project to an operating system that supports case insensitive file\n"
706 "names.\n\nDo you wish to continue?" ),
707 fn.GetName() );
708
709 wxRichMessageDialog dlg( this, msg, _( "Warning" ),
710 wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
711 dlg.ShowCheckBox( _( "Do not show this message again." ) );
712 dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Create New Sheet" ) ),
713 wxMessageDialog::ButtonLabel( _( "Discard New Sheet" ) ) );
714
715 if( dlg.ShowModal() == wxID_NO )
716 return false;
717
719 !dlg.IsCheckBoxChecked();
720 }
721
722 return true;
723}
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
Handles how to draw a screen (a board, a schematic ...)
Definition: base_screen.h:41
VECTOR2I m_DrawOrg
offsets for drawing the circuit on the screen
Definition: base_screen.h:88
VECTOR2I m_StartVisu
Coordinates in drawing units of the current view position (upper left corner of device)
Definition: base_screen.h:93
void SetContentModified(bool aModified=true)
Definition: base_screen.h:59
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
const KIID m_Uuid
Definition: eda_item.h:482
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.
Definition: actions.h:264
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
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.
Definition: sch_painter.h:72
Definition: kiid.h:49
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.
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:100
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
KIGFX::SCH_RENDER_SETTINGS * GetRenderSettings()
const PAGE_INFO & GetPageSettings() const override
bool LoadSheetFromFile(SCH_SHEET *aSheet, SCH_SHEET_PATH *aCurrentSheet, const wxString &aFileName)
Load a the KiCad schematic file aFileName into the sheet aSheet.
Definition: sheet.cpp:164
bool AllowCaseSensitiveFileNameClashes(const wxString &aSchematicFileName)
Check aSchematicFileName for a potential file name case sensitivity clashes.
Definition: sheet.cpp:691
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)
Definition: sheet.cpp:105
SCHEMATIC & Schematic() const
void DrawCurrentSheetToClipboard()
Use the wxWidgets print code to draw an image of the current sheet onto the clipboard.
Definition: sheet.cpp:611
bool EditSheetProperties(SCH_SHEET *aSheet, SCH_SHEET_PATH *aHierarchy, bool *aClearAnnotationNewItems, bool *aUpdateHierarchyNavigator=nullptr)
Edit an existing sheet or add a new sheet to the schematic.
Definition: sheet.cpp:591
bool checkForNoFullyDefinedLibIds(SCH_SHEET *aSheet)
Verify that the symbol library links aSheet and all of its child sheets have been remapped to the sym...
Definition: sheet.cpp:83
bool CheckSheetForRecursion(SCH_SHEET *aSheet, SCH_SHEET_PATH *aCurrentSheet)
Verify that aSheet will not cause a recursion error in aCurrentSheet.
Definition: sheet.cpp:49
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.
Definition: sch_io_mgr.cpp:165
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:704
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.
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
Definition: sch_screen.h:157
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:150
void SetPageSettings(const PAGE_INFO &aPageSettings)
Definition: sch_screen.h:132
const wxString & GetFileName() const
Definition: sch_screen.h:144
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:115
const std::vector< SCH_SYMBOL_INSTANCE > & GetSymbolInstances() const
Definition: sch_screen.h:515
int GetFileFormatVersionAtLoad() const
Definition: sch_screen.h:129
const TITLE_BLOCK & GetTitleBlock() const
Definition: sch_screen.h:155
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.
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.
Definition: sch_sheet.h:57
void SetFileName(const wxString &aFilename)
Definition: sch_sheet.h:314
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:110
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:162
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.
Definition: title_block.h:41
const wxString & GetCompany() const
Definition: title_block.h:96
void SetRevision(const wxString &aRevision)
Definition: title_block.h:81
void SetComment(int aIdx, const wxString &aComment)
Definition: title_block.h:101
const wxString & GetRevision() const
Definition: title_block.h:86
void SetTitle(const wxString &aTitle)
Definition: title_block.h:58
const wxString & GetDate() const
Definition: title_block.h:76
const wxString & GetComment(int aIdx) const
Definition: title_block.h:107
void SetCompany(const wxString &aCompany)
Definition: title_block.h:91
const wxString & GetTitle() const
Definition: title_block.h:63
void SetDate(const wxString &aDate)
Set the date field, and defaults to the current time and date.
Definition: title_block.h:71
TOOL_MANAGER * m_toolManager
Definition: tools_holder.h:167
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:332
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:305
This file is part of the common library.
#define _(s)
void GRForceBlackPen(bool flagforce)
Definition: gr_basic.cpp:159
void GRResetPenAndBrush(wxDC *DC)
Definition: gr_basic.cpp:73
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
Definition: io_mgr.h:33
PROJECT & Prj()
Definition: kicad.cpp:591
@ LAYER_DRAWINGSHEET
drawingsheet frame and titleblock
Definition: layer_ids.h:220
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition: layer_ids.h:394
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
const int scale
const double IU_PER_MILS
Definition: base_units.h:78
wxSize ToWxSize(const VECTOR2I &aSize)
Definition: vector2wx.h:55
Definition of file extensions used in Kicad.