← Back to team overview

kicad-developers team mailing list archive

[PATCH] Append schematic: copy the contents of one schematic file into another

 

Hi!

With this patch you will be able to bring all the contents of an
existing .sch file into the currently opened schematic document. This
may be useful to reuse components from one sheet to another, specially
graphical components.

The feature has been added to File -> Append Schematic. It will import
the library cache of the appended file in case it contains non standard
components, and it's also checked to import hierarchical components
correctly.

Make me know your opinion about the feature or any comments you have on
the patch.

Regards,
-- 
Jacobo Aragunde
Software Engineer at Igalia
=== modified file 'eeschema/class_library.cpp'
--- eeschema/class_library.cpp	2012-10-29 21:56:18 +0000
+++ eeschema/class_library.cpp	2013-01-16 10:45:36 +0000
@@ -860,13 +860,13 @@
 
 wxArrayString CMP_LIBRARY::GetLibraryNames( bool aSorted )
 {
-    wxString cacheName;
+    wxArrayString cacheNames;
     wxArrayString names;
 
     BOOST_FOREACH( CMP_LIBRARY& lib, CMP_LIBRARY::libraryList )
     {
         if( lib.isCache && aSorted )
-            cacheName = lib.GetName();
+            cacheNames.Add( lib.GetName() );
         else
             names.Add( lib.GetName() );
     }
@@ -875,8 +875,8 @@
     if( aSorted )
         names.Sort();
 
-    if( !cacheName.IsEmpty() )
-        names.Add( cacheName );
+    for( unsigned int i = 0; i<cacheNames.Count(); i++ )
+        names.Add( cacheNames.Item( i ) );
 
     return names;
 }

=== modified file 'eeschema/files-io.cpp'
--- eeschema/files-io.cpp	2013-01-04 12:06:50 +0000
+++ eeschema/files-io.cpp	2013-01-16 10:45:36 +0000
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@xxxxxxxxxxxxxxxxxx
  * Copyright (C) 2011 Wayne Stambaugh <stambaughw@xxxxxxxxxxx>
+ * Copyright (C) 2013 CERN (www.cern.ch)
  * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
  *
  * This program is free software; you can redistribute it and/or
@@ -172,6 +173,73 @@
 }
 
 
+bool SCH_EDIT_FRAME::LoadCacheLibrary( const wxString& aFilename )
+{
+    wxString msg;
+    bool LibCacheExist = false;
+    wxFileName fn = aFilename;
+
+    /* Loading the project library cache
+     * until apr 2009 the lib is named <root_name>.cache.lib
+     * and after (due to code change): <root_name>-cache.lib
+     * so if the <name>-cache.lib is not found, the old way will be tried
+     */
+    bool use_oldcachename = false;
+    wxString cachename =  fn.GetName() + wxT( "-cache" );
+
+    fn.SetName( cachename );
+    fn.SetExt( SchematicLibraryFileExtension );
+
+    if( ! fn.FileExists() )
+    {
+        fn = aFilename;
+        fn.SetExt( wxT( "cache.lib" ) );
+        use_oldcachename = true;
+    }
+
+    if( fn.FileExists() )
+    {
+        wxString errMsg;
+
+        wxLogDebug( wxT( "Load schematic cache library file <%s>" ),
+                    GetChars( fn.GetFullPath() ) );
+        msg = wxT( "Load " ) + fn.GetFullPath();
+
+        CMP_LIBRARY* LibCache = CMP_LIBRARY::LoadLibrary( fn, errMsg );
+
+        if( LibCache )
+        {
+            LibCache->SetCache();
+            msg += wxT( " OK" );
+
+            if ( use_oldcachename )     // set the new name
+            {
+                fn.SetName( cachename );
+                fn.SetExt( SchematicLibraryFileExtension );
+                LibCache->SetFileName( fn );
+            }
+
+            LibCacheExist = true;
+            CMP_LIBRARY::GetLibraryList().push_back( LibCache );
+        }
+        else
+        {
+            wxString prompt;
+
+            prompt.Printf( _( "Component library <%s> failed to load.\nError: %s" ),
+                           GetChars( fn.GetFullPath() ),
+                           GetChars( errMsg ) );
+            DisplayError( this, prompt );
+            msg += _( " ->Error" );
+        }
+
+        PrintMsg( msg );
+    }
+
+    return LibCacheExist;
+}
+
+
 bool SCH_EDIT_FRAME::LoadOneEEProject( const wxString& aFileName, bool aIsNew )
 {
     SCH_SCREEN* screen;
@@ -277,64 +345,7 @@
     // Delete old caches.
     CMP_LIBRARY::RemoveCacheLibrary();
 
-    /* Loading the project library cache
-     * until apr 2009 the lib is named <root_name>.cache.lib
-     * and after (due to code change): <root_name>-cache.lib
-     * so if the <name>-cache.lib is not found, the old way will be tried
-     */
-    fn = g_RootSheet->GetScreen()->GetFileName();
-
-    bool use_oldcachename = false;
-    wxString cachename =  fn.GetName() + wxT( "-cache" );
-
-    fn.SetName( cachename );
-    fn.SetExt( SchematicLibraryFileExtension );
-
-    if( ! fn.FileExists() )
-    {
-        fn = g_RootSheet->GetScreen()->GetFileName();
-        fn.SetExt( wxT( "cache.lib" ) );
-        use_oldcachename = true;
-    }
-
-    if( fn.FileExists() )
-    {
-        wxString errMsg;
-
-        wxLogDebug( wxT( "LoadOneEEProject() load schematic cache library file <%s>" ),
-                    GetChars( fn.GetFullPath() ) );
-        msg = wxT( "Load " ) + fn.GetFullPath();
-
-        CMP_LIBRARY* LibCache = CMP_LIBRARY::LoadLibrary( fn, errMsg );
-
-        if( LibCache )
-        {
-            LibCache->SetCache();
-            msg += wxT( " OK" );
-
-            if ( use_oldcachename )     // set the new name
-            {
-                fn.SetName( cachename );
-                fn.SetExt( SchematicLibraryFileExtension );
-                LibCache->SetFileName( fn );
-            }
-
-            LibCacheExist = true;
-            CMP_LIBRARY::GetLibraryList().push_back( LibCache );
-        }
-        else
-        {
-            wxString prompt;
-
-            prompt.Printf( _( "Component library <%s> failed to load.\nError: %s" ),
-                           GetChars( fn.GetFullPath() ),
-                           GetChars( errMsg ) );
-            DisplayError( this, prompt );
-            msg += _( " ->Error" );
-        }
-
-        PrintMsg( msg );
-    }
+    LibCacheExist = LoadCacheLibrary( g_RootSheet->GetScreen()->GetFileName() );
 
     if( !wxFileExists( g_RootSheet->GetScreen()->GetFileName() ) && !LibCacheExist )
     {
@@ -361,6 +372,70 @@
 }
 
 
+bool SCH_EDIT_FRAME::AppendOneEEProject()
+{
+    SCH_SCREEN* screen;
+    wxString    FullFileName;
+    wxString msg;
+
+    screen = GetScreen();
+
+    if( !screen )
+    {
+        wxLogError( wxT("Document not ready, cannot import") );
+        return false;
+    }
+
+    wxFileDialog dlg( this, _( "Import Schematic" ), wxGetCwd(),
+                      wxEmptyString, SchematicFileWildcard,
+                      wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+
+    if( dlg.ShowModal() == wxID_CANCEL )
+        return false;
+
+    FullFileName = dlg.GetPath();
+
+    wxFileName fn = FullFileName;
+
+    if( fn.IsRelative() )
+    {
+        fn.MakeAbsolute();
+        FullFileName = fn.GetFullPath();
+    }
+
+    LoadCacheLibrary( FullFileName );
+
+    wxLogDebug( wxT( "Importing schematic " ) + FullFileName );
+
+    // load the project.
+    bool success = LoadOneEEFile( screen, FullFileName, true );
+    if( success )
+         {
+             EDA_ITEM* bs = screen->GetDrawItems();
+
+             while( bs )
+             {
+                 if( bs->Type() ==  SCH_SHEET_T )
+                 {
+                     SCH_SHEET* sheetstruct = (SCH_SHEET*) bs;
+
+                     if( !sheetstruct->Load( this ) )
+                         success = false;
+                 }
+
+                 bs = bs->Next();
+             }
+         }
+
+    /* Redraw base screen (ROOT) if necessary. */
+    GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
+    Zoom_Automatique( false );
+    SetSheetNumberAndCount();
+    m_canvas->Refresh( true );
+    return success;
+}
+
+
 void SCH_EDIT_FRAME::OnSaveProject( wxCommandEvent& aEvent )
 {
     SCH_SCREEN* screen;

=== modified file 'eeschema/load_one_schematic_file.cpp'
--- eeschema/load_one_schematic_file.cpp	2012-10-13 18:54:33 +0000
+++ eeschema/load_one_schematic_file.cpp	2013-01-16 10:45:36 +0000
@@ -53,7 +53,7 @@
 static void LoadLayers( LINE_READER* aLine );
 
 
-bool SCH_EDIT_FRAME::LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFileName )
+bool SCH_EDIT_FRAME::LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFileName, bool append )
 {
     char            name1[256];
     bool            itemLoaded = false;
@@ -74,7 +74,8 @@
     wxLogTrace( traceAutoSave, wxT( "Loading schematic file " ) + aFullFileName );
 
     aScreen->SetCurItem( NULL );
-    aScreen->SetFileName( aFullFileName );
+    if( !append )
+        aScreen->SetFileName( aFullFileName );
 
     FILE* f;
     wxString fname = aFullFileName;

=== modified file 'eeschema/menubar.cpp'
--- eeschema/menubar.cpp	2012-09-28 17:47:41 +0000
+++ eeschema/menubar.cpp	2013-01-16 10:45:36 +0000
@@ -97,6 +97,12 @@
                  _( "Open a recent opened schematic project" ),
                  KiBitmap( open_project_xpm ) );
 
+    // Import
+    AddMenuItem( fileMenu,
+                 ID_APPEND_PROJECT, _( "&Append Schematic" ),
+                 _( "Append another schematic project to the current loaded schematic" ),
+                 KiBitmap( open_document_xpm ) );
+
     // Separator
     fileMenu->AppendSeparator();
 

=== modified file 'eeschema/schframe.cpp'
--- eeschema/schframe.cpp	2013-01-12 17:32:24 +0000
+++ eeschema/schframe.cpp	2013-01-16 10:45:40 +0000
@@ -75,6 +75,8 @@
 
     EVT_MENU_RANGE( wxID_FILE1, wxID_FILE9, SCH_EDIT_FRAME::OnLoadFile )
 
+    EVT_MENU( ID_APPEND_PROJECT, SCH_EDIT_FRAME::OnAppendProject )
+
     EVT_TOOL( ID_NEW_PROJECT, SCH_EDIT_FRAME::OnNewProject )
     EVT_TOOL( ID_LOAD_PROJECT, SCH_EDIT_FRAME::OnLoadProject )
 
@@ -735,6 +737,12 @@
 }
 
 
+void SCH_EDIT_FRAME::OnAppendProject( wxCommandEvent& event )
+{
+    AppendOneEEProject();
+}
+
+
 void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event )
 {
     wxFileName fn = g_RootSheet->GetScreen()->GetFileName();

=== modified file 'include/id.h'
--- include/id.h	2012-10-14 16:57:11 +0000
+++ include/id.h	2013-01-16 10:45:36 +0000
@@ -47,6 +47,7 @@
     ID_TO_PCB = wxID_HIGHEST,
     ID_TO_CVPCB,
     ID_LOAD_PROJECT,
+    ID_APPEND_PROJECT,
     ID_NEW_PROJECT,
     ID_NEW_PROJECT_FROM_TEMPLATE,
     ID_SAVE_PROJECT,

=== modified file 'include/wxEeschemaStruct.h'
--- include/wxEeschemaStruct.h	2012-09-28 18:45:04 +0000
+++ include/wxEeschemaStruct.h	2013-01-16 10:45:36 +0000
@@ -631,6 +631,14 @@
     bool LoadOneEEProject( const wxString& aFileName, bool aIsNew );
 
     /**
+     * Function AppendOneEEProject
+     * read an entire project and loads it into the schematic editor *whitout* replacing the
+     * existing contents.
+     * @return True if the project was imported properly.
+     */
+    bool AppendOneEEProject();
+
+    /**
      * Function LoadOneEEFile
      * loads the schematic (.sch) file \a aFullFileName into \a aScreen.
      *
@@ -638,9 +646,11 @@
      *                \a aFullFileName.
      * @param aFullFileName A reference to a wxString object containing the absolute path
      *                      and file name to load.
+     * @param append True if loaded file is being appended to the currently open file instead
+ *                   of replacing it.
      * @return True if \a aFullFileName has been loaded (at least partially.)
      */
-    bool LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFileName );
+    bool LoadOneEEFile( SCH_SCREEN* aScreen, const wxString& aFullFileName, bool append = false );
 
     bool ReadInputStuffFile();
 
@@ -746,6 +756,7 @@
     void OnLoadStuffFile( wxCommandEvent& event );
     void OnNewProject( wxCommandEvent& event );
     void OnLoadProject( wxCommandEvent& event );
+    void OnAppendProject( wxCommandEvent& event );
     void OnOpenPcbnew( wxCommandEvent& event );
     void OnOpenCvpcb( wxCommandEvent& event );
     void OnOpenLibraryEditor( wxCommandEvent& event );
@@ -874,6 +885,8 @@
     void InstallHierarchyFrame( wxDC* DC, wxPoint& pos );
     SCH_SHEET* CreateSheet( wxDC* DC );
     void ReSizeSheet( SCH_SHEET* Sheet, wxDC* DC );
+    // Loads the cache library associated to the aFileName
+    bool LoadCacheLibrary( const wxString& aFileName );
 
 public:
     /**


Follow ups