Example #1
0
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();
}
Example #2
0
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();
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #5
0
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;
}