Hi all,

This patch adds the progress reporter dialog to GerbView file loading, when
loading multiple files and the total load time goes over 1 second.  I've
also done some refactoring to share code between loading multiple files via
a gerber job file and via the regular open dialog.

-Jon
From d968f0a64200fd483b03c52f4efdfb25f8f51e60 Mon Sep 17 00:00:00 2001
From: Jon Evans <j...@craftyjon.com>
Date: Tue, 20 Feb 2018 21:58:53 -0500
Subject: [PATCH] Add progress reporting for GerbView file loading

---
 common/widgets/progress_reporter.cpp |  4 +--
 gerbview/files.cpp                   | 51 +++++++++++++++++++++++++++++++-----
 gerbview/gerbview_frame.h            |  9 +++++++
 gerbview/job_file_reader.cpp         | 39 +++------------------------
 include/widgets/progress_reporter.h  |  4 ++-
 5 files changed, 61 insertions(+), 46 deletions(-)

diff --git a/common/widgets/progress_reporter.cpp b/common/widgets/progress_reporter.cpp
index ddd46668b..213c8a93f 100644
--- a/common/widgets/progress_reporter.cpp
+++ b/common/widgets/progress_reporter.cpp
@@ -100,7 +100,7 @@ bool PROGRESS_REPORTER::KeepRefreshing( bool aWait )
 
 
 WX_PROGRESS_REPORTER::WX_PROGRESS_REPORTER( wxWindow* aParent, const wxString& aTitle,
-                                            int aNumPhases ) :
+                                            int aNumPhases, bool aCanAbort ) :
     PROGRESS_REPORTER( aNumPhases ),
     wxProgressDialog( aTitle, wxT( "" ), 1, aParent,
                       // wxPD_APP_MODAL |   // Don't use; messes up OSX when called from
@@ -108,7 +108,7 @@ WX_PROGRESS_REPORTER::WX_PROGRESS_REPORTER( wxWindow* aParent, const wxString& a
                       wxPD_AUTO_HIDE |      // *MUST* use; otherwise wxWidgets will spin
                                             // up another event loop on completion which
                                             // causes all sorts of grief
-                      wxPD_CAN_ABORT |
+                      ( aCanAbort ? wxPD_CAN_ABORT : 0 ) |
                       wxPD_ELAPSED_TIME )
 {
 }
diff --git a/gerbview/files.cpp b/gerbview/files.cpp
index f659ae123..76f7e06ed 100644
--- a/gerbview/files.cpp
+++ b/gerbview/files.cpp
@@ -39,8 +39,10 @@
 #include <gerbview_frame.h>
 #include <gerbview_id.h>
 #include <gerber_file_image.h>
+#include <gerber_file_image_list.h>
 #include <gerbview_layer_widget.h>
 #include <wildcards_and_files_ext.h>
+#include <widgets/progress_reporter.h>
 
 // HTML Messages used more than one time:
 #define MSG_NO_MORE_LAYER\
@@ -216,6 +218,15 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
     // Set the busy cursor
     wxBusyCursor wait;
 
+    return loadListOfGerberFiles( currentPath, filenamesList );
+}
+
+
+bool GERBVIEW_FRAME::loadListOfGerberFiles( const wxString& aPath,
+                                            const wxArrayString& aFilenameList )
+{
+    wxFileName filename;
+
     // Read gerber files: each file is loaded on a new GerbView layer
     bool success = true;
     int layer = GetActiveLayer();
@@ -224,12 +235,30 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
     wxString msg;
     WX_STRING_REPORTER reporter( &msg );
 
-    for( unsigned ii = 0; ii < filenamesList.GetCount(); ii++ )
+    // Show progress dialog after 1 second of loading
+    static const long long progressShowDelay = 1000;
+
+    auto startTime = wxGetUTCTimeMillis();
+    std::unique_ptr<WX_PROGRESS_REPORTER> progress = nullptr;
+
+    for( unsigned ii = 0; ii < aFilenameList.GetCount(); ii++ )
     {
-        filename = filenamesList[ii];
+        if( !progress && wxGetUTCTimeMillis() - startTime > progressShowDelay )
+        {
+            progress = std::make_unique<WX_PROGRESS_REPORTER>( this,
+                            _( "Loading Gerber files..." ), 1, false );
+            progress->SetMaxProgress( aFilenameList.GetCount() - 1 );
+            progress->Report( _("Loading Gerber files..." ) );
+        }
+        else if( progress )
+        {
+            progress->KeepRefreshing();
+        }
+
+        filename = aFilenameList[ii];
 
         if( !filename.IsAbsolute() )
-            filename.SetPath( currentPath );
+            filename.SetPath( aPath );
 
         m_lastFileName = filename.GetFullPath();
 
@@ -241,16 +270,16 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
 
             layer = getNextAvailableLayer( layer );
 
-            if( layer == NO_AVAILABLE_LAYERS && ii < filenamesList.GetCount()-1 )
+            if( layer == NO_AVAILABLE_LAYERS && ii < aFilenameList.GetCount()-1 )
             {
                 success = false;
                 reporter.Report( MSG_NO_MORE_LAYER, REPORTER::RPT_ERROR );
 
                 // Report the name of not loaded files:
                 ii += 1;
-                while( ii < filenamesList.GetCount() )
+                while( ii < aFilenameList.GetCount() )
                 {
-                    filename = filenamesList[ii++];
+                    filename = aFilenameList[ii++];
                     wxString txt;
                     txt.Printf( MSG_NOT_LOADED,
                                 GetChars( filename.GetFullName() ) );
@@ -261,10 +290,15 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
 
             SetActiveLayer( layer, false );
         }
+
+        if( progress )
+            progress->AdvanceProgress();
     }
 
     if( !success )
     {
+        wxSafeYield();  // Allows slice of time to redraw the screen
+                        // to refresh widgets, before displaying messages
         HTML_MESSAGE_BOX mbox( this, _( "Errors" ) );
         mbox.ListSet( msg );
         mbox.ShowModal();
@@ -272,11 +306,14 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
 
     Zoom_Automatique( false );
 
+    GetImagesList()->SortImagesByZOrder();
+
     // Synchronize layers tools with actual active layer:
     ReFillLayerWidget();
     SetActiveLayer( GetActiveLayer() );
     m_LayersManager->UpdateLayerIcons();
-    syncLayerBox();
+    syncLayerBox( true );
+
     return success;
 }
 
diff --git a/gerbview/gerbview_frame.h b/gerbview/gerbview_frame.h
index 729541d94..ca7e35d12 100644
--- a/gerbview/gerbview_frame.h
+++ b/gerbview/gerbview_frame.h
@@ -216,6 +216,15 @@ private:
     /// Updates the GAL with display settings changes
     void applyDisplaySettingsToGAL();
 
+    /**
+     * Loads a list of Gerber files and updates the view based on them
+     * @param aPath is the base path for the filenames if they are relative
+     * @param aFilenameList is a list of filenames to load
+     * @return true if every file loaded successfully
+     */
+    bool                loadListOfGerberFiles( const wxString& aPath,
+                                               const wxArrayString& aFilenameList );
+
 public:
     GERBVIEW_FRAME( KIWAY* aKiway, wxWindow* aParent );
     ~GERBVIEW_FRAME();
diff --git a/gerbview/job_file_reader.cpp b/gerbview/job_file_reader.cpp
index 80f54ee38..b5c919e80 100644
--- a/gerbview/job_file_reader.cpp
+++ b/gerbview/job_file_reader.cpp
@@ -144,6 +144,7 @@ bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
 {
     wxFileName filename = aFullFileName;
     wxString currentPath;
+    bool success = true;
 
     if( !filename.IsOk() )
     {
@@ -189,41 +190,7 @@ bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
 
             wxArrayString& gbrfiles = gbjReader.GetGerberFiles();
 
-            wxFileName gbr_fn = filename;
-            bool read_ok;
-            int layer = 0;
-            SetActiveLayer( layer, false );
-
-            for( unsigned ii = 0; ii < gbrfiles.GetCount(); ii++ )
-            {
-                gbr_fn.SetFullName( gbrfiles[ii] );
-
-                if( gbr_fn.FileExists() )
-                {
-                    //LoadGerberFiles( gbr_fn.GetFullPath() );
-                    read_ok = Read_GERBER_File( gbr_fn.GetFullPath() );
-
-                    if( read_ok )
-                    {
-                        layer = getNextAvailableLayer( layer );
-                        SetActiveLayer( layer, false );
-                    }
-                }
-                else
-                    read_ok = false;
-
-                if( !read_ok )
-                {
-                    wxString err;
-                    err.Printf( _( "Can't load Gerber file:<br><i>%s</i><br>" ), gbr_fn.GetFullPath() );
-                    reporter.Report( err, REPORTER::RPT_WARNING );
-                }
-            }
-
-            GetImagesList()->SortImagesByZOrder();
-            ReFillLayerWidget();
-            syncLayerBox( true );
-            GetCanvas()->Refresh();
+            success = loadListOfGerberFiles( currentPath, gbrfiles );
         }
     }
 
@@ -238,7 +205,7 @@ bool GERBVIEW_FRAME::LoadGerberJobFile( const wxString& aFullFileName )
         mbox.ShowModal();
     }
 
-    return true;
+    return success;
 }
 
 
diff --git a/include/widgets/progress_reporter.h b/include/widgets/progress_reporter.h
index 2eff0f217..6594d388b 100644
--- a/include/widgets/progress_reporter.h
+++ b/include/widgets/progress_reporter.h
@@ -102,8 +102,10 @@ public:
      * aNumPhases = 1 is the usual progress bar
      * aNumPhases = n creates n virtual progress bar zones: a 0 to 100 percent width
      * of a virtual zone fills 0 to 1/n progress bar full size of the nth virtual zone index
+     * @param aCanAbort is true if the abort button should be shown
      */
-    WX_PROGRESS_REPORTER( wxWindow* aParent, const wxString& aTitle, int aNumPhases );
+    WX_PROGRESS_REPORTER( wxWindow* aParent, const wxString& aTitle, int aNumPhases,
+                          bool aCanAbort = true );
     ~WX_PROGRESS_REPORTER();
 
 private:
-- 
2.14.1

_______________________________________________
Mailing list: https://launchpad.net/~kicad-developers
Post to     : kicad-developers@lists.launchpad.net
Unsubscribe : https://launchpad.net/~kicad-developers
More help   : https://help.launchpad.net/ListHelp

Reply via email to