void SCH_EDIT_FRAME::OnSaveProject( wxCommandEvent& aEvent ) { SCH_SCREEN* screen; wxFileName fn; wxFileName tmp; SCH_SCREENS ScreenList; fn = g_RootSheet->GetFileName(); // Ensure a path exists. if no path, assume the cwd is used // The IsWritable function expects the path to be set if( !fn.GetPath().IsEmpty() ) tmp.AssignDir( fn.GetPath() ); else tmp.AssignDir( wxGetCwd() ); if( !IsWritable( tmp ) ) return; for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() ) SaveEEFile( screen ); CreateArchiveLibraryCacheFile(); UpdateTitle(); }
void SCH_EDIT_FRAME::Save_File( wxCommandEvent& event ) { int id = event.GetId(); switch( id ) { case ID_UPDATE_ONE_SHEET: SaveEEFile( NULL ); break; case ID_SAVE_ONE_SHEET_UNDER_NEW_NAME: if( SaveEEFile( NULL, true ) ) { CreateArchiveLibraryCacheFile( true ); } break; } UpdateTitle(); }
bool SCH_EDIT_FRAME::doAutoSave() { wxFileName tmpFileName = g_RootSheet->GetFileName(); wxFileName fn = tmpFileName; wxFileName tmp; SCH_SCREENS screens; bool autoSaveOk = true; tmp.AssignDir( fn.GetPath() ); if( !IsWritable( tmp ) ) return false; for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() ) { // Only create auto save files for the schematics that have been modified. if( !screen->IsSave() ) continue; tmpFileName = fn = screen->GetFileName(); // Auto save file name is the normal file name prefixed with $. fn.SetName( wxT( "$" ) + fn.GetName() ); screen->SetFileName( fn.GetFullPath() ); if( SaveEEFile( screen, false, NO_BACKUP_FILE ) ) screen->SetModify(); else autoSaveOk = false; screen->SetFileName( tmpFileName.GetFullPath() ); } if( autoSaveOk ) m_autoSaveState = false; return autoSaveOk; }
bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy ) { if( aSheet == NULL || aHierarchy == NULL ) return false; SCH_SHEET_LIST hierarchy; // This is the schematic sheet hierarchy. // Get the new texts DIALOG_SCH_SHEET_PROPS dlg( this ); wxString units = GetUnitsLabel( g_UserUnit ); dlg.SetFileName( aSheet->GetFileName() ); dlg.SetFileNameTextSize( StringFromValue( g_UserUnit, aSheet->GetFileNameSize() ) ); dlg.SetFileNameTextSizeUnits( units ); dlg.SetSheetName( aSheet->GetName() ); dlg.SetSheetNameTextSize( StringFromValue( g_UserUnit, aSheet->GetSheetNameSize() ) ); dlg.SetSheetNameTextSizeUnits( units ); dlg.SetSheetTimeStamp( wxString::Format( wxT("%8.8lX"), (unsigned long) aSheet->GetTimeStamp() ) ); /* This ugly hack fixes a bug in wxWidgets 2.8.7 and likely earlier * versions for the flex grid sizer in wxGTK that prevents the last * column from being sized correctly. It doesn't cause any problems * on win32 so it doesn't need to wrapped in ugly #ifdef __WXGTK__ * #endif. * Still presen in wxWidgets 3.0.2 */ dlg.Layout(); dlg.Fit(); dlg.SetMinSize( dlg.GetSize() ); dlg.GetSizer()->Fit( &dlg ); if( dlg.ShowModal() == wxID_CANCEL ) return false; wxFileName fileName = dlg.GetFileName(); fileName.SetExt( SchematicFileExtension ); if( !fileName.IsOk() ) { DisplayError( this, _( "File name is not valid!" ) ); return false; } // Duplicate sheet names are not valid. const SCH_SHEET* sheet = hierarchy.FindSheetByName( dlg.GetSheetName() ); if( sheet && (sheet != aSheet) ) { DisplayError( this, wxString::Format( _( "A sheet named \"%s\" already exists." ), GetChars( dlg.GetSheetName() ) ) ); return false; } wxString msg; bool loadFromFile = false; SCH_SCREEN* useScreen = NULL; wxString newFilename = fileName.GetFullPath(); // Search for a schematic file having the same filename // already in use in the hierarchy or on disk, in order to reuse it. if( !g_RootSheet->SearchHierarchy( newFilename, &useScreen ) ) { // if user entered a relative path, allow that to stay, but do the // file existence test with an absolute (full) path. This transformation // is local to this scope, but is the same one used at load time later. wxString absolute = Prj().AbsolutePath( newFilename ); loadFromFile = wxFileExists( absolute ); } // Inside Eeschema, filenames are stored using unix notation newFilename.Replace( wxT( "\\" ), wxT( "/" ) ); if( aSheet->GetScreen() == NULL ) // New sheet. { if( useScreen || loadFromFile ) // Load from existing file. { if( useScreen != NULL ) { msg.Printf( _( "A file named '%s' already exists in the current schematic " "hierarchy." ), GetChars( newFilename ) ); } else { msg.Printf( _( "A file named '%s' already exists." ), GetChars( newFilename ) ); } msg += _( "\n\nDo you want to create a sheet with the contents of this file?" ); if( !IsOK( this, msg ) ) { return false; } } else // New file. { aSheet->SetScreen( new SCH_SCREEN( &Kiway() ) ); aSheet->GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax ); aSheet->GetScreen()->SetFileName( newFilename ); } } else // Existing sheet. { bool isUndoable = true; bool renameFile = false; // We are always using here a case insensitive comparison // to avoid issues under Windows, although under Unix // filenames are case sensitive. // But many users create schematic under both Unix and Windows if( newFilename.CmpNoCase( aSheet->GetFileName() ) != 0 ) { // Sheet file name changes cannot be undone. isUndoable = false; msg = _( "Changing the sheet file name cannot be undone. " ); if( useScreen || loadFromFile ) // Load from existing file. { wxString tmp; if( useScreen != NULL ) { tmp.Printf( _( "A file named <%s> already exists in the current schematic " "hierarchy." ), GetChars( newFilename ) ); } else { tmp.Printf( _( "A file named <%s> already exists." ), GetChars( newFilename ) ); } msg += tmp; msg += _( "\n\nDo you want to replace the sheet with the contents of this file?" ); if( !IsOK( this, msg ) ) return false; if( loadFromFile ) aSheet->SetScreen( NULL ); } else // Save to new file name. { if( aSheet->GetScreenCount() > 1 ) { msg += _( "This sheet uses shared data in a complex hierarchy.\n\n" ); msg += _( "Do you wish to convert it to a simple hierarchical sheet?" ); if( !IsOK( NULL, msg ) ) return false; } renameFile = true; } } m_canvas->SetIgnoreMouseEvents( true ); if( isUndoable ) SaveCopyInUndoList( aSheet, UR_CHANGED ); if( renameFile ) { aSheet->GetScreen()->SetFileName( newFilename ); SaveEEFile( aSheet->GetScreen() ); // If the the associated screen is shared by more than one sheet, remove the // screen and reload the file to a new screen. Failure to do this will trash // the screen reference counting in complex hierarchies. if( aSheet->GetScreenCount() > 1 ) { aSheet->SetScreen( NULL ); loadFromFile = true; } } } aSheet->SetFileName( newFilename ); if( useScreen ) aSheet->SetScreen( useScreen ); else if( loadFromFile ) aSheet->Load( this ); aSheet->SetFileNameSize( ValueFromString( g_UserUnit, dlg.GetFileNameTextSize() ) ); aSheet->SetName( dlg.GetSheetName() ); aSheet->SetSheetNameSize( ValueFromString( g_UserUnit, dlg.GetSheetNameTextSize() ) ); if( aSheet->GetName().IsEmpty() ) aSheet->SetName( wxString::Format( wxT( "Sheet%8.8lX" ), (long unsigned) aSheet->GetTimeStamp() ) ); // Make sure the sheet changes do not cause any recursion. SCH_SHEET_LIST sheetHierarchy( aSheet ); // Make sure files have fully qualified path and file name. wxFileName destFn = aHierarchy->Last()->GetFileName(); if( destFn.IsRelative() ) destFn.MakeAbsolute( Prj().GetProjectPath() ); if( hierarchy.TestForRecursion( sheetHierarchy, destFn.GetFullPath( wxPATH_UNIX ) ) ) { msg.Printf( _( "The sheet changes cannot be made because the destination sheet already " "has the sheet <%s> or one of it's subsheets as a parent somewhere in " "the schematic hierarchy." ), GetChars( newFilename ) ); DisplayError( this, msg ); return false; } m_canvas->MoveCursorToCrossHair(); m_canvas->SetIgnoreMouseEvents( false ); OnModify(); return true; }
bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, wxDC* aDC ) { if( aSheet == NULL ) return false; // Get the new texts DIALOG_SCH_SHEET_PROPS dlg( this ); wxString units = GetUnitsLabel( g_UserUnit ); dlg.SetFileName( aSheet->GetFileName() ); dlg.SetFileNameTextSize( ReturnStringFromValue( g_UserUnit, aSheet->GetFileNameSize() ) ); dlg.SetFileNameTextSizeUnits( units ); dlg.SetSheetName( aSheet->GetName() ); dlg.SetSheetNameTextSize( ReturnStringFromValue( g_UserUnit, aSheet->GetSheetNameSize() ) ); dlg.SetSheetNameTextSizeUnits( units ); /* This ugly hack fixes a bug in wxWidgets 2.8.7 and likely earlier * versions for the flex grid sizer in wxGTK that prevents the last * column from being sized correctly. It doesn't cause any problems * on win32 so it doesn't need to wrapped in ugly #ifdef __WXGTK__ * #endif. */ dlg.Layout(); dlg.Fit(); dlg.SetMinSize( dlg.GetSize() ); if( dlg.ShowModal() == wxID_CANCEL ) return false; wxFileName fileName = dlg.GetFileName(); fileName.SetExt( SchematicFileExtension ); if( !fileName.IsOk() ) { DisplayError( this, _( "File name is not valid!" ) ); return false; } // Duplicate sheet names are not valid. const SCH_SHEET* sheet = GetScreen()->GetSheet( dlg.GetSheetName() ); if( (sheet != NULL) && (sheet != aSheet) ) { DisplayError( this, wxString::Format( _( "A sheet named \"%s\" already exists." ), GetChars( dlg.GetSheetName() ) ) ); return false; } wxString msg; wxString tmp; bool loadFromFile = false; SCH_SCREEN* useScreen = NULL; wxString newFullFilename = fileName.GetFullPath(); // Inside Eeschema, filenames are stored using unix notation newFullFilename.Replace( wxT("\\"), wxT("/") ); // Search for a schematic file having the same filename exists, // already in use in the hierarchy, or on disk, // in order to reuse it if( !g_RootSheet->SearchHierarchy( newFullFilename, &useScreen ) ) loadFromFile = fileName.FileExists(); if( aSheet->GetScreen() == NULL ) // New sheet. { if( ( useScreen != NULL ) || loadFromFile ) // Load from existing file. { if( useScreen != NULL ) { msg.Printf( _( "A file named <%s> already exists in the current schematic hierarchy." ), GetChars( newFullFilename ) ); } else { msg.Printf( _( "A file named <%s> already exists." ), GetChars( newFullFilename ) ); } msg += _("\n\nDo you want to create a sheet with the contents of this file?" ); if( !IsOK( this, msg ) ) return false; } else // New file. { aSheet->SetScreen( new SCH_SCREEN() ); aSheet->GetScreen()->SetFileName( newFullFilename ); } } else // Existing sheet. { bool isUndoable = true; bool renameFile = false; // We are always using here a case insensitive comparison // to avoid issues under Windows, although under Unix // filenames are case sensitive. // But many users create schematic under both Unix and Windows if( newFullFilename.CmpNoCase( aSheet->GetFileName() ) != 0 ) { // Sheet file name changes cannot be undone. isUndoable = false; msg = _( "Changing the sheet file name cannot be undone. " ); if( ( useScreen != NULL ) || loadFromFile ) // Load from existing file. { wxString tmp; if( useScreen != NULL ) { tmp.Printf( _( "A file named <%s> already exists in the current schematic hierarchy." ), GetChars( newFullFilename ) ); } else { tmp.Printf( _( "A file named <%s> already exists." ), GetChars( newFullFilename ) ); } msg += tmp; msg += _("\n\nDo you want to replace the sheet with the contents of this file?" ); if( !IsOK( this, msg ) ) return false; if( loadFromFile ) aSheet->SetScreen( NULL ); } else // Save to new file name. { if( aSheet->GetScreenCount() > 1 ) { msg += _( "This sheet uses shared data in a complex hierarchy.\n\n" ); msg += _( "Do you wish to convert it to a simple hierarchical sheet?" ); if( !IsOK( NULL, msg ) ) return false; } renameFile = true; } } aSheet->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode ); m_canvas->SetIgnoreMouseEvents( true ); if( isUndoable ) SaveCopyInUndoList( aSheet, UR_CHANGED ); if( renameFile ) { aSheet->GetScreen()->SetFileName( newFullFilename ); SaveEEFile( aSheet->GetScreen() ); // If the the associated screen is shared by more than one sheet, remove the // screen and reload the file to a new screen. Failure to do this will trash // the screen reference counting in complex hierarchies. if( aSheet->GetScreenCount() > 1 ) { aSheet->SetScreen( NULL ); loadFromFile = true; } } } aSheet->SetFileName( newFullFilename ); if( useScreen ) aSheet->SetScreen( useScreen ); else if( loadFromFile ) aSheet->Load( this ); aSheet->SetFileNameSize( ReturnValueFromString( g_UserUnit, dlg.GetFileNameTextSize() ) ); aSheet->SetName( dlg.GetSheetName() ); aSheet->SetSheetNameSize( ReturnValueFromString( g_UserUnit, dlg.GetSheetNameTextSize() ) ); if( aSheet->GetName().IsEmpty() ) aSheet->SetName( wxString::Format( wxT( "Sheet%8.8lX" ), aSheet->GetTimeStamp() ) ); m_canvas->MoveCursorToCrossHair(); m_canvas->SetIgnoreMouseEvents( false ); aSheet->Draw( m_canvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); OnModify(); return true; }