void DISPLAY_FOOTPRINTS_FRAME::InitDisplay() { wxString msg; CVPCB_MAINFRAME* parentframe = (CVPCB_MAINFRAME *) GetParent(); wxString footprintName = parentframe->m_footprintListBox->GetSelectedFootprint(); if( !footprintName.IsEmpty() ) { msg.Printf( _( "Footprint: %s" ), GetChars( footprintName ) ); SetTitle( msg ); const FOOTPRINT_INFO* module_info = parentframe->m_footprints.GetModuleInfo( footprintName ); const wxChar* libname; if( module_info ) libname = GetChars( module_info->GetNickname() ); else libname = GetChars( wxT( "???" ) ); msg.Printf( _( "Lib: %s" ), libname ); SetStatusText( msg, 0 ); if( GetBoard()->m_Modules.GetCount() ) { // there is only one module in the list GetBoard()->m_Modules.DeleteAll(); } MODULE* module = Get_Module( footprintName ); if( module ) GetBoard()->m_Modules.PushBack( module ); Zoom_Automatique( false ); } else // No footprint to display. Erase old footprint, if any { if( GetBoard()->m_Modules.GetCount() ) { GetBoard()->m_Modules.DeleteAll(); Zoom_Automatique( false ); SetStatusText( wxEmptyString, 0 ); } } // Display new cursor coordinates and zoom value: UpdateStatusBar(); GetCanvas()->Refresh(); EDA_3D_FRAME* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) draw3DFrame->NewDisplay(); }
bool PCB_BASE_FRAME::Update3DView( const wxString* aTitle ) { // Update the 3D view only if the viewer is opened by this frame EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame == NULL ) return false; // Ensure the viewer was created by me, and not by another editor: PCB_BASE_FRAME* owner = draw3DFrame->Parent(); // if I am not the owner, do not use the current viewer instance if( this != owner ) return false; if( aTitle ) draw3DFrame->SetTitle( *aTitle ); // The 3D view update can be time consumming to rebuild a board 3D view. // So do not use a immediate update in the board editor bool immediate_update = true; if( IsType( FRAME_PCB ) ) immediate_update = false; draw3DFrame->NewDisplay( immediate_update ); return true; }
void PCB_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event ) { EDA_3D_FRAME* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) { // Raising the window does not show the window on Windows if iconized. // This should work on any platform. if( draw3DFrame->IsIconized() ) draw3DFrame->Iconize( false ); draw3DFrame->Raise(); // Raising the window does not set the focus on Linux. This should work on any platform. if( wxWindow::FindFocus() != draw3DFrame ) draw3DFrame->SetFocus(); return; } draw3DFrame = new EDA_3D_FRAME( &Kiway(), this, _( "3D Viewer" ) ); draw3DFrame->SetDefaultFileName( GetBoard()->GetFileName() ); draw3DFrame->Raise(); // Needed with some Window Managers draw3DFrame->Show( true ); }
void FOOTPRINT_WIZARD_FRAME::Show3D_Frame( wxCommandEvent& event ) { EDA_3D_FRAME* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) { // Raising the window does not show the window on Windows if iconized. // This should work on any platform. if( draw3DFrame->IsIconized() ) draw3DFrame->Iconize( false ); draw3DFrame->Raise(); // Raising the window does not set the focus on Linux. This should work on any platform. if( wxWindow::FindFocus() != draw3DFrame ) draw3DFrame->SetFocus(); return; } draw3DFrame = new EDA_3D_FRAME( &Kiway(), this, wxEmptyString ); Update3D_Frame( false ); draw3DFrame->Raise(); // Needed with some Window Managers draw3DFrame->Show( true ); }
FOOTPRINT_WIZARD_FRAME::~FOOTPRINT_WIZARD_FRAME() { EDA_3D_FRAME* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) draw3DFrame->Destroy(); }
void DISPLAY_FOOTPRINTS_FRAME::OnCloseWindow( wxCloseEvent& event ) { EDA_3D_FRAME* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) draw3DFrame->Close( true ); Destroy(); }
void PCB_EDIT_FRAME::OnModify( ) { PCB_BASE_FRAME::OnModify(); EDA_3D_FRAME* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) draw3DFrame->ReloadRequest(); }
void PCB_BASE_FRAME::CommonSettingsChanged() { EDA_DRAW_FRAME::CommonSettingsChanged(); ReCreateHToolbar(); ReCreateAuxiliaryToolbar(); ReCreateVToolbar(); ReCreateOptToolbar(); EDA_3D_VIEWER* viewer = Get3DViewerFrame(); if( viewer ) { // The 3D viewer isn't in the Kiway, so send its update manually viewer->CommonSettingsChanged(); } }
/** * Function Update3D_Frame * must be called after a footprint selection * Updates the 3D view and 3D frame title. */ void FOOTPRINT_WIZARD_FRAME::Update3D_Frame( bool aForceReloadFootprint ) { EDA_3D_FRAME* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame == NULL ) return; wxString frm3Dtitle; frm3Dtitle.Printf( _( "ModView: 3D Viewer [%s]" ), GetChars( m_wizardName ) ); draw3DFrame->SetTitle( frm3Dtitle ); if( aForceReloadFootprint ) { draw3DFrame->ReloadRequest(); // Force 3D screen refresh immediately if( GetBoard()->m_Modules ) draw3DFrame->NewDisplay(); } }
bool PCB_BASE_FRAME::CreateAndShow3D_Frame( bool aForceRecreateIfNotOwner ) { EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); // Ensure the viewer was created by me, and not by another editor: PCB_BASE_FRAME* owner = draw3DFrame ? draw3DFrame->Parent() : nullptr; // if I am not the owner, do not use the current viewer instance if( draw3DFrame && this != owner ) { if( aForceRecreateIfNotOwner ) { draw3DFrame->Destroy(); draw3DFrame = nullptr; } else return false; } if( !draw3DFrame ) { draw3DFrame = new EDA_3D_VIEWER( &Kiway(), this, _( "3D Viewer" ) ); draw3DFrame->Raise(); // Needed with some Window Managers draw3DFrame->Show( true ); return true; } // Raising the window does not show the window on Windows if iconized. This should work // on any platform. if( draw3DFrame->IsIconized() ) draw3DFrame->Iconize( false ); draw3DFrame->Raise(); // Raising the window does not set the focus on Linux. This should work on any platform. if( wxWindow::FindFocus() != draw3DFrame ) draw3DFrame->SetFocus(); return true; }
bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ) { // This is for python: if( aFileSet.size() != 1 ) { UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ ); DisplayError( this, msg ); return false; } wxString fullFileName( aFileSet[0] ); // We insist on caller sending us an absolute path, if it does not, we say it's a bug. wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "Path is not absolute!" ) ); std::unique_ptr<wxSingleInstanceChecker> lockFile = ::LockFile( fullFileName ); if( !lockFile ) { wxString msg = wxString::Format( _( "PCB file \"%s\" is already open." ), fullFileName ); DisplayError( this, msg ); return false; } if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) { if( !HandleUnsavedChanges( this, _( "The current PCB has been modified. Save changes?" ), [&]()->bool { return SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE ); } ) ) { return false; } } // Release the lock file, until the new file is actually loaded ReleaseFile(); wxFileName pro = fullFileName; pro.SetExt( ProjectFileExtension ); bool is_new = !wxFileName::IsFileReadable( fullFileName ); // If its a non-existent schematic and caller thinks it exists if( is_new && !( aCtl & KICTL_CREATE ) ) { // notify user that fullFileName does not exist, ask if user wants to create it. wxString ask = wxString::Format( _( "PCB \"%s\" does not exist. Do you wish to create it?" ), fullFileName ); if( !IsOK( this, ask ) ) return false; } Clear_Pcb( false ); // pass false since we prompted above for a modified board IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl ); bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD_SEXP; if( !converted ) { // PROJECT::SetProjectFullName() is an impactful function. It should only be // called under carefully considered circumstances. // The calling code should know not to ask me here to change projects unless // it knows what consequences that will have on other KIFACEs running and using // this same PROJECT. It can be very harmful if that calling code is stupid. Prj().SetProjectFullName( pro.GetFullPath() ); // load project settings before BOARD LoadProjectSettings(); } if( is_new ) { OnModify(); } else { BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); // This will rename the file if there is an autosave and the user want to recover CheckForAutoSaveFile( fullFileName ); try { PROPERTIES props; char xbuf[30]; char ybuf[30]; // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. sprintf( xbuf, "%d", GetPageSizeIU().x ); sprintf( ybuf, "%d", GetPageSizeIU().y ); props["page_width"] = xbuf; props["page_height"] = ybuf; #if USE_INSTRUMENTATION // measure the time to load a BOARD. unsigned startTime = GetRunningMicroSecs(); #endif loadedBoard = pi->Load( fullFileName, NULL, &props ); #if USE_INSTRUMENTATION unsigned stopTime = GetRunningMicroSecs(); printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime ); #endif } catch( const IO_ERROR& ioe ) { if( ioe.Problem() != wxT( "CANCEL" ) ) { wxString msg = wxString::Format( _( "Error loading board file:\n%s" ), fullFileName ); DisplayErrorMessage( this, msg, ioe.What() ); } return false; } // 6.0 TODO: some settings didn't make it into the board file in 5.1 so as not to // change the file format. For 5.1 we must copy them across from the config-initialized // board. BOARD_DESIGN_SETTINGS& bds = loadedBoard->m_designSettings; BOARD_DESIGN_SETTINGS& configBds = GetBoard()->GetDesignSettings(); bds.m_RequireCourtyards = configBds.m_RequireCourtyards; bds.m_ProhibitOverlappingCourtyards = configBds.m_ProhibitOverlappingCourtyards; bds.m_HoleToHoleMin = configBds.m_HoleToHoleMin; bds.m_LineThickness[LAYER_CLASS_OTHERS] = configBds.m_LineThickness[LAYER_CLASS_OTHERS]; bds.m_TextSize[LAYER_CLASS_OTHERS] = configBds.m_TextSize[LAYER_CLASS_OTHERS]; bds.m_TextThickness[LAYER_CLASS_OTHERS] = configBds.m_TextThickness[LAYER_CLASS_OTHERS]; std::copy( configBds.m_TextItalic, configBds.m_TextItalic + 4, bds.m_TextItalic ); std::copy( configBds.m_TextUpright, configBds.m_TextUpright + 4, bds.m_TextUpright ); bds.m_DiffPairDimensionsList = configBds.m_DiffPairDimensionsList; bds.m_CopperEdgeClearance = configBds.m_CopperEdgeClearance; SetBoard( loadedBoard ); // we should not ask PLUGINs to do these items: loadedBoard->BuildListOfNets(); loadedBoard->SynchronizeNetsAndNetClasses(); // If this is a legacy board then we set the copper edge clearance to 1/2 the edge-cut // line width (which was a legacy kludge for implementing edge clearances). if( bds.m_CopperEdgeClearance == Millimeter2iu( LEGACY_COPPEREDGECLEARANCE ) ) bds.SetCopperEdgeClearance( inferLegacyEdgeClearance( loadedBoard ) ); if( loadedBoard->IsModified() ) OnModify(); else GetScreen()->ClrModify(); if( pluginType == IO_MGR::LEGACY && loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION ) { DisplayInfoMessage( this, _( "This file was created by an older version of Pcbnew.\n" "It will be stored in the new file format when you save this file again." ) ); } } { wxFileName fn = fullFileName; if( converted ) fn.SetExt( PcbFileExtension ); wxString fname = fn.GetFullPath(); fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); GetBoard()->SetFileName( fname ); } // Lock the file newly opened: m_file_checker.reset( lockFile.release() ); if( !converted ) UpdateFileHistory( GetBoard()->GetFileName() ); // Rebuild the new pad list (for drc and ratsnet control ...) GetBoard()->m_Status_Pcb = 0; // Select netclass Default as current netclass (it always exists) SetCurrentNetClass( NETCLASS::Default ); // Rebuild list of nets (full ratsnest rebuild) Compile_Ratsnest( NULL, true ); GetBoard()->BuildConnectivity(); onBoardLoaded(); // Refresh the 3D view, if any EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) draw3DFrame->NewDisplay(); #if 0 && defined(DEBUG) // Output the board object tree to stdout, but please run from command prompt: GetBoard()->Show( 0, std::cout ); #endif // from EDA_APPL which was first loaded BOARD only: { /* For an obscure reason the focus is lost after loading a board file * when starting up the process. * (seems due to the recreation of the layer manager after loading the file) * Give focus to main window and Drawpanel * must be done for these 2 windows (for an obscure reason ...) * Linux specific * This is more a workaround than a fix. */ SetFocus(); GetCanvas()->SetFocus(); } return true; }
bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl ) { // This is for python: if( aFileSet.size() != 1 ) { UTF8 msg = StrPrintf( "Pcbnew:%s() takes only a single filename", __func__ ); DisplayError( this, msg ); return false; } wxString fullFileName( aFileSet[0] ); // We insist on caller sending us an absolute path, if it does not, we say it's a bug. wxASSERT_MSG( wxFileName( fullFileName ).IsAbsolute(), wxT( "bug in single_top.cpp or project manager." ) ); if( !LockFile( fullFileName ) ) { wxString msg = wxString::Format( _( "PCB file '%s' is already open." ), GetChars( fullFileName ) ); DisplayError( this, msg ); return false; } if( GetScreen()->IsModify() ) { int response = YesNoCancelDialog( this, _( "The current board has been modified. Do you wish to save the changes?" ), wxEmptyString, _( "Save and Load" ), _( "Load Without Saving" ) ); if( response == wxID_CANCEL ) return false; else if( response == wxID_YES ) SavePcbFile( GetBoard()->GetFileName(), CREATE_BACKUP_FILE ); else { // response == wxID_NO, fall thru } } wxFileName pro = fullFileName; pro.SetExt( ProjectFileExtension ); bool is_new = !wxFileName::IsFileReadable( fullFileName ); // If its a non-existent schematic and caller thinks it exists if( is_new && !( aCtl & KICTL_CREATE ) ) { // notify user that fullFileName does not exist, ask if user wants to create it. wxString ask = wxString::Format( _( "Board '%s' does not exist. Do you wish to create it?" ), GetChars( fullFileName ) ); if( !IsOK( this, ask ) ) return false; } Clear_Pcb( false ); // pass false since we prompted above for a modified board IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl ); bool converted = pluginType != IO_MGR::LEGACY && pluginType != IO_MGR::KICAD; if( !converted ) { // PROJECT::SetProjectFullName() is an impactful function. It should only be // called under carefully considered circumstances. // The calling code should know not to ask me here to change projects unless // it knows what consequences that will have on other KIFACEs running and using // this same PROJECT. It can be very harmful if that calling code is stupid. Prj().SetProjectFullName( pro.GetFullPath() ); // load project settings before BOARD LoadProjectSettings(); } if( is_new ) { OnModify(); } else { BOARD* loadedBoard = 0; // it will be set to non-NULL if loaded OK PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); try { PROPERTIES props; char xbuf[30]; char ybuf[30]; // EAGLE_PLUGIN can use this info to center the BOARD, but it does not yet. sprintf( xbuf, "%d", GetPageSizeIU().x ); sprintf( ybuf, "%d", GetPageSizeIU().y ); props["page_width"] = xbuf; props["page_height"] = ybuf; #if USE_INSTRUMENTATION // measure the time to load a BOARD. unsigned startTime = GetRunningMicroSecs(); #endif loadedBoard = pi->Load( fullFileName, NULL, &props ); #if USE_INSTRUMENTATION unsigned stopTime = GetRunningMicroSecs(); printf( "PLUGIN::Load(): %u usecs\n", stopTime - startTime ); #endif } catch( const IO_ERROR& ioe ) { wxString msg = wxString::Format( _( "Error loading board.\n%s" ), GetChars( ioe.errorText ) ); DisplayError( this, msg ); return false; } SetBoard( loadedBoard ); // we should not ask PLUGINs to do these items: loadedBoard->BuildListOfNets(); loadedBoard->SynchronizeNetsAndNetClasses(); SetStatusText( wxEmptyString ); BestZoom(); // update the layer names in the listbox ReCreateLayerBox( false ); GetScreen()->ClrModify(); { wxFileName fn = fullFileName; CheckForAutoSaveFile( fullFileName, fn.GetExt() ); } if( pluginType == IO_MGR::LEGACY && loadedBoard->GetFileFormatVersionAtLoad() < LEGACY_BOARD_FILE_VERSION ) { DisplayInfoMessage( this, _( "This file was created by an older version of Pcbnew.\n" "It will be stored in the new file format when you save this file again." ) ); } } { wxFileName fn = fullFileName; if( converted ) fn.SetExt( PcbFileExtension ); wxString fname = fn.GetFullPath(); fname.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP ); GetBoard()->SetFileName( fname ); } UpdateTitle(); if( !converted ) UpdateFileHistory( GetBoard()->GetFileName() ); // Rebuild the new pad list (for drc and ratsnet control ...) GetBoard()->m_Status_Pcb = 0; // Select netclass Default as current netclass (it always exists) SetCurrentNetClass( NETCLASS::Default ); // Rebuild list of nets (full ratsnest rebuild) { wxBusyCursor dummy; // Displays an Hourglass while building connectivity Compile_Ratsnest( NULL, true ); GetBoard()->GetRatsnest()->ProcessBoard(); } // Update info shown by the horizontal toolbars ReFillLayerWidget(); ReCreateLayerBox(); // upate the layer widget to match board visibility states, both layers and render columns. syncLayerVisibilities(); syncLayerWidgetLayer(); syncRenderStates(); // Update the tracks / vias available sizes list: ReCreateAuxiliaryToolbar(); // Update the RATSNEST items, which were not loaded at the time // BOARD::SetVisibleElements() was called from within any PLUGIN. // See case RATSNEST_VISIBLE: in BOARD::SetElementVisibility() GetBoard()->SetVisibleElements( GetBoard()->GetVisibleElements() ); // Display the loaded board: Zoom_Automatique( false ); SetMsgPanel( GetBoard() ); // Refresh the 3D view, if any EDA_3D_VIEWER* draw3DFrame = Get3DViewerFrame(); if( draw3DFrame ) draw3DFrame->NewDisplay(); #if 0 && defined(DEBUG) // Output the board object tree to stdout, but please run from command prompt: GetBoard()->Show( 0, std::cout ); #endif // from EDA_APPL which was first loaded BOARD only: { /* For an obscure reason the focus is lost after loading a board file * when starting up the process. * (seems due to the recreation of the layer manager after loading the file) * Give focus to main window and Drawpanel * must be done for these 2 windows (for an obscure reason ...) * Linux specific * This is more a workaround than a fix. */ SetFocus(); GetCanvas()->SetFocus(); } return true; }