[gparted] Enhance line discipline in PipeCapture::OnReadable() (#709276)



commit 1b54123580aa668d3a2c391cce2d60c65a1668f9
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Thu Oct 3 15:22:43 2013 +0100

    Enhance line discipline in PipeCapture::OnReadable() (#709276)
    
    Add concept of cursor position within the current line, separate from
    the end of the buffer.  This is so that programs which output a text
    progress bar using backspace, such as resize2fs -p, are displayed
    correctly.
    
    Bug #709276 - Percentage indicator for subcommand

 include/PipeCapture.h |    5 +++--
 src/PipeCapture.cc    |   44 ++++++++++++++++++++++++++++----------------
 2 files changed, 31 insertions(+), 18 deletions(-)
---
diff --git a/include/PipeCapture.h b/include/PipeCapture.h
index 25b9697..0493da7 100644
--- a/include/PipeCapture.h
+++ b/include/PipeCapture.h
@@ -28,8 +28,9 @@ namespace GParted {
 class PipeCapture
 {
        Glib::ustring &buff;
-       unsigned int backcount;
-       unsigned int linelength;
+       Glib::ustring::size_type linestart ;
+       Glib::ustring::size_type cursor ;
+       Glib::ustring::size_type lineend ;
        Glib::RefPtr<Glib::IOChannel> channel;
        guint sourceid;
        bool OnReadable( Glib::IOCondition condition );
diff --git a/src/PipeCapture.cc b/src/PipeCapture.cc
index 5ec1fa3..1a55cc2 100644
--- a/src/PipeCapture.cc
+++ b/src/PipeCapture.cc
@@ -20,7 +20,8 @@
 
 namespace GParted {
 
-PipeCapture::PipeCapture( int fd, Glib::ustring &string ) : buff( string ), backcount( 0 ), linelength( 0 ),
+PipeCapture::PipeCapture( int fd, Glib::ustring &string ) : buff( string ),
+                                                            linestart( 0 ), cursor( 0 ), lineend( 0 ),
                                                             sourceid( 0 )
 {
        // tie fd to string
@@ -47,34 +48,45 @@ gboolean PipeCapture::_OnReadable( GIOChannel *source,
 
 bool PipeCapture::OnReadable( Glib::IOCondition condition )
 {
-       // read from pipe and store in buff
+       //Read from pipe and store in buff.  Provide minimal interpretation so
+       //  programs which use text progress bars are displayed correctly.
+       //  Linestart, cursor and lineend are offsets into buff like this:
+       //      "Previous line\n
+       //       Current line.  Text progress bar: XXXXXXXXXX----------"
+       //      /\                                          /\        /\
+       //      linestart                                   cursor    lineend
        Glib::ustring str;
        Glib::IOStatus status = channel->read( str, 512 );
        if (status == Glib::IO_STATUS_NORMAL)
        {
-               for( Glib::ustring::iterator s = str.begin();
-                    s != str.end(); s++ )
+               for( Glib::ustring::iterator s = str.begin(); s != str.end(); s++ )
                {
-                       if( *s == '\b' )
-                               backcount++;
+                       if( *s == '\b' ) {
+                               if ( cursor > linestart )
+                                       cursor -- ;
+                       }
                        else if( *s == '\r' )
-                               backcount = linelength;
+                               cursor = linestart ;
                        else if( *s == '\n' ) {
-                               linelength = 0;
-                               buff += '\n';
-                               backcount = 0;
+                               cursor = lineend ;
+                               buff .append( 1, '\n' ) ;
+                               cursor ++ ;
+                               linestart = cursor ;
+                               lineend = cursor ;
                        }
                        else if (*s == '\x01' || *s == '\x02' )
                                //Skip Ctrl-A and Ctrl-B chars e2fsck uses to bracket the progress bar
                                continue;
                        else {
-                               if (backcount) {
-                                       buff.erase( buff.length() - backcount, backcount );
-                                       linelength -= backcount;
-                                       backcount = 0;
+                               if ( cursor < lineend ) {
+                                       buff .replace( cursor, 1, 1, *s ) ;
+                                       cursor ++ ;
+                               }
+                               else {
+                                       buff .append( 1, *s ) ;
+                                       cursor ++ ;
+                                       lineend = cursor ;
                                }
-                               buff += *s;
-                               ++linelength;
                        }
                }
                signal_update.emit();


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