[gparted] Write a generic progress bar class (#760709)



commit 0ca8ed73696eaf12d6c32828e0d746e7d0e3b442
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Mon Jan 11 12:19:05 2016 +0000

    Write a generic progress bar class (#760709)
    
    Write a generic progress bar class.  Has the following features:
    * Has separate progress and target numbers, rather than a single
      completion fraction, to enable the the next feature.
    * Optionally generates text reporting the amount of data copied using
      the progress and target numbers like this:
          "1.00 MiB of 16.00 MiB copied"
    * After running for 5 seconds, also add estimated remaining time.
      (Waits to allow the data copying rate to settle down a little before
      estimating the remaining time).  Looks like this:
          "1.00 MiB of 16.00 MiB copied (00:01:59) remaining)"
    
    The ProgressBar class is not driving the visual progress bar yet.  It
    has just been added into the internal block copy algorithm and generates
    debug messages showing the progress bar is operating correctly.
    Debugging looks like this:
    
        DEBUG: ProgressBar::start(target=2.0636e+09, text_mode=PROGRESSBAR_TEXT_COPY_BYTES)
        DEBUG: ProgressBar::update(progress=1.30023e+08) m_fraction=0.0630081 m_text="124.00 MiB of 1.92 GiB 
copied"
        DEBUG: ProgressBar::update(progress=2.67387e+08) m_fraction=0.129573 m_text="255.00 MiB of 1.92 GiB 
copied"
        DEBUG: ProgressBar::update(progress=4.0475e+08) m_fraction=0.196138 m_text="386.00 MiB of 1.92 GiB 
copied"
        ...
        DEBUG: ProgressBar::update(progress=1.13351e+09) m_fraction=0.549289 m_text="1.06 GiB of 1.92 GiB 
copied (00:00:04 remaining)"
        DEBUG: ProgressBar::update(progress=1.26249e+09) m_fraction=0.611789 m_text="1.18 GiB of 1.92 GiB 
copied (00:00:04 remaining)"
        DEBUG: ProgressBar::update(progress=1.39041e+09) m_fraction=0.67378 m_text="1.29 GiB of 1.92 GiB 
copied (00:00:03 remaining)"
        ...
        DEBUG: ProgressBar::update(progress=1.97552e+09) m_fraction=0.957317 m_text="1.84 GiB of 1.92 GiB 
copied (00:00:00 remaining)"
        DEBUG: ProgressBar::update(progress=2.0636e+09) m_fraction=1 m_text="1.92 GiB of 1.92 GiB copied"
        DEBUG: ProgressBar::stop()
    
    Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific
                 copy methods

 include/Copy_Blocks.h |    7 +++-
 include/Makefile.am   |    1 +
 include/ProgressBar.h |   63 +++++++++++++++++++++++++
 po/POTFILES.in        |    1 +
 src/Copy_Blocks.cc    |    8 +++
 src/Makefile.am       |    1 +
 src/ProgressBar.cc    |  121 +++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 201 insertions(+), 1 deletions(-)
---
diff --git a/include/Copy_Blocks.h b/include/Copy_Blocks.h
index e2a604e..fcf81ef 100644
--- a/include/Copy_Blocks.h
+++ b/include/Copy_Blocks.h
@@ -17,7 +17,11 @@
 #ifndef GPARTED_COPY_BLOCKS_H
 #define GPARTED_COPY_BLOCKS_H
 
-#include "../include/Operation.h"
+#include "../include/OperationDetail.h"
+#include "../include/ProgressBar.h"
+#include "../include/Utils.h"
+
+#include <glibmm/ustring.h>
 #include <parted/parted.h>
 
 namespace GParted {
@@ -41,6 +45,7 @@ class copy_blocks {
        void copy_thread();
        bool cancel;
        bool cancel_safe;
+       ProgressBar progressbar;
        void set_cancel( bool force );
 public:
        bool set_progress_info();
diff --git a/include/Makefile.am b/include/Makefile.am
index 9a09c1e..61f722e 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -41,6 +41,7 @@ EXTRA_DIST = \
        PartitionVector.h               \
        PipeCapture.h                   \
        Proc_Partitions_Info.h          \
+       ProgressBar.h                   \
        SWRaid_Info.h                   \
        TreeView_Detail.h               \
        Utils.h                         \
diff --git a/include/ProgressBar.h b/include/ProgressBar.h
new file mode 100644
index 0000000..03f998e
--- /dev/null
+++ b/include/ProgressBar.h
@@ -0,0 +1,63 @@
+/* Copyright (C) 2016 Mike Fleetwood
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef GPARTED_PROGRESSBAR_H
+#define GPARTED_PROGRESSBAR_H
+
+#include <glibmm/ustring.h>
+#include <glibmm/timer.h>
+
+namespace GParted
+{
+
+enum ProgressBar_Text
+{
+       PROGRESSBAR_TEXT_NONE,
+       PROGRESSBAR_TEXT_COPY_BYTES
+};
+
+class ProgressBar
+{
+public:
+       ProgressBar();
+       ~ProgressBar();
+
+       void start( double target, ProgressBar_Text text_mode = PROGRESSBAR_TEXT_NONE );
+       void update( double progress );
+       void stop();
+       bool running() const;
+       double get_fraction() const;
+       Glib::ustring get_text() const;
+
+private:
+       ProgressBar( const ProgressBar & src );              // Not implemented copy constructor
+       ProgressBar & operator=( const ProgressBar & rhs );  // Not implemented copy assignment operator
+
+       void do_update();
+
+       bool              m_running;    // Is this progress bar running?
+       double            m_target;     // Progress bar target should be > 0.0
+       double            m_progress;   // Should be 0.0 <= m_progress <= m_target
+       double            m_fraction;   // Always between 0.0 and 1.0 for passing to 
Gtk::ProgressBar.set_fraction()
+       ProgressBar_Text  m_text_mode;  // Whether to and style of text generation
+       Glib::ustring     m_text;       // Optional text for passing to Gtk::ProgressBar.set_text()
+       Glib::Timer       m_timer;      // Measures elapsed time to the microsecond for accurate estimation
+};
+
+}//GParted
+
+#endif /* GPARTED_PROGRESS_H */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5cce178..3ef9bc2 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -34,6 +34,7 @@ src/OperationResizeMove.cc
 src/Partition.cc
 src/PartitionLUKS.cc
 src/PartitionVector.cc
+src/ProgressBar.cc
 src/SWRaid_Info.cc
 src/TreeView_Detail.cc
 src/Utils.cc
diff --git a/src/Copy_Blocks.cc b/src/Copy_Blocks.cc
index 392398a..c1a0fb3 100644
--- a/src/Copy_Blocks.cc
+++ b/src/Copy_Blocks.cc
@@ -17,6 +17,11 @@
  */
 
 #include "../include/Copy_Blocks.h"
+#include "../include/OperationDetail.h"
+#include "../include/ProgressBar.h"
+#include "../include/Utils.h"
+
+#include <glibmm/ustring.h>
 #include <gtkmm/main.h>
 #include <errno.h>
 
@@ -57,6 +62,7 @@ copy_blocks::copy_blocks( const Glib::ustring & in_src_device,
 bool copy_blocks::set_progress_info()
 {
        Byte_Value done = llabs(this->done);
+       progressbar.update( (double)done );
        OperationDetail &operationdetail = this->operationdetail.get_last_child().get_last_child();
        operationdetail.fraction = done / static_cast<double>( length );
 
@@ -160,6 +166,7 @@ bool copy_blocks::copy()
                        String::ucompose( _("copy %1 using a block size of %2"),
                                          Utils::format_size( length, 1 ),
                                          Utils::format_size( blocksize, 1 ) ) ) );
+       progressbar.start( (double)length, PROGRESSBAR_TEXT_COPY_BYTES );
 
        done = length % blocksize;
 
@@ -195,6 +202,7 @@ bool copy_blocks::copy()
        else
                error_message = Glib::strerror( errno );
 
+       progressbar.stop();
        operationdetail.get_last_child().set_status( success ? STATUS_SUCCES : STATUS_ERROR );
        return success;
 }
diff --git a/src/Makefile.am b/src/Makefile.am
index ef3447b..819c910 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,6 +52,7 @@ gpartedbin_SOURCES = \
        PartitionVector.cc              \
        PipeCapture.cc                  \
        Proc_Partitions_Info.cc         \
+       ProgressBar.cc                  \
        SWRaid_Info.cc                  \
        TreeView_Detail.cc              \
        Utils.cc                        \
diff --git a/src/ProgressBar.cc b/src/ProgressBar.cc
new file mode 100644
index 0000000..3daa96a
--- /dev/null
+++ b/src/ProgressBar.cc
@@ -0,0 +1,121 @@
+/* Copyright (C) 2016 Mike Fleetwood
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "../include/ProgressBar.h"
+#include "../include/Utils.h"
+
+#include <glibmm/ustring.h>
+
+namespace GParted
+{
+
+ProgressBar::ProgressBar() : m_running( false ), m_target( 1.0 ), m_progress( 0.0 ), m_fraction( 0.0 ),
+                             m_text_mode( PROGRESSBAR_TEXT_NONE )
+{
+}
+
+ProgressBar::~ProgressBar()
+{
+}
+
+void ProgressBar::start( double target, ProgressBar_Text text_mode )
+{
+       std::cout << "DEBUG: ProgressBar::start(target=" << target
+                 << ", text_mode=" << (text_mode==PROGRESSBAR_TEXT_NONE ? "PROGRESSBAR_TEXT_NONE" :
+                                                                          "PROGRESSBAR_TEXT_BLOCK_COPY") << 
")"
+                 << std::endl;
+       m_running = true;
+       m_target = target;
+       m_progress = 0.0;
+       m_text_mode = text_mode;
+       m_timer.start();
+       do_update();
+}
+
+void ProgressBar::update( double progress )
+{
+       std::cout << "DEBUG: ProgressBar::update(progress=" << progress << ")";
+       if ( m_running )
+       {
+               m_progress = progress;
+               do_update();
+               std::cout << " m_fraction=" << m_fraction << " m_text=\"" << m_text << "\"";
+       }
+       std::cout << std::endl;
+}
+
+void ProgressBar::stop()
+{
+       std::cout << "DEBUG: ProgressBar::stop()" << std::endl;
+       m_running = false;
+       m_timer.stop();
+       do_update();
+}
+
+bool ProgressBar::running() const
+{
+       return m_running;
+}
+
+double ProgressBar::get_fraction() const
+{
+       return m_fraction;
+}
+
+Glib::ustring ProgressBar::get_text() const
+{
+       return m_text;
+}
+
+// Private methods
+
+// Update m_fraction and m_text as required.
+void ProgressBar::do_update()
+{
+       m_fraction = m_progress / m_target;
+       if ( m_fraction < 0.0 )
+               m_fraction = 0.0;
+       else if ( m_fraction > 1.0 )
+               m_fraction = 1.0;
+
+       if ( m_text_mode == PROGRESSBAR_TEXT_COPY_BYTES )
+       {
+               double elapsed = m_timer.elapsed();
+               if ( m_running && elapsed >= 5.0 )
+               {
+                       /* Only show "(00:01:59 remaining)" when a progress bar has been
+                        * running for at least 5 seconds to allow the data copying rate
+                        * to settle down a little before estimating the remaining time.
+                        */
+                       std::time_t remaining = Utils::round( (m_target - m_progress) /
+                                                             (m_progress / elapsed) );
+                       m_text = String::ucompose( /* TO TRANSLATORS: looks like   1.00 MiB of 16.00 MiB 
copied (00:01:59 remaining) */
+                                                _("%1 of %2 copied (%3 remaining)"),
+                                                Utils::format_size( (long long)m_progress, 1 ),
+                                                Utils::format_size( (long long)m_target, 1 ),
+                                                Utils::format_time( remaining ) );
+               }
+               else
+               {
+                       m_text = String::ucompose( /* TO TRANSLATORS: looks like   1.00 MiB of 16.00 MiB 
copied */
+                                                _("%1 of %2 copied"),
+                                                Utils::format_size( m_progress, 1 ),
+                                                Utils::format_size( m_target, 1 ) );
+               }
+       }
+}
+
+}//GParted


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]