From 2a55c65876ec602f0718f4f81156833e82ff909b Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Mon, 8 Feb 2016 20:02:42 +0000 Subject: [PATCH] Leave commands with progress bars shown in the applying dialog (#760709) For non-progress tracked external commands the command being executed is displayed in the Apply pending operations dialog, just below the top pulsing progress bar. However for progress tracked external commands the description of the parent operation detail is displayed instead. Example 1: non-progress tracked xfs check repair: TreePath Check and repair file system (xfs) on /dev/sdc1 0 + calibrate /dev/sdc1 0:0 + check file system on /dev/sdc1 for errors and (if po... 0:1 + xfs_repair -v /dev/sdc1 0:1:0 + [empty stdout] 0:1:0:0 + [stderr]Phase 1 - find and verify superblock... 0:1:0:1 "xfs_repair -v /dev/sdc1" (TreePath 0:1:0) is shown because it is the latest updated operation detail which is timed (set to status executing). Example 2: progress tracked ext4 copy using e2image: TreePath Copy /dev/sdc2 to /dev/sdc3 0 + calibrate /dev/sdc2 0:0 + check file system on /dev/sdc2 for errors and (if po... 0:1 + set partition type on /dev/sdc3 0:2 + copy file system of /dev/sdc2 to /dev/sdc3 0:3 + e2image -ra -p /dev/sdc2 /dev/sdc3 0:3:0 + [stdout]Scanning inodes... 0:3:0:0 + [stderr]e2image 1.42.9 (28-Dec-2013)... 0:3:0:1 "copy file system of /dev/sdc2 to /dev/sdc3" (TreePath 0:3) is shown because that operation detail is also timed and it is being constantly updated by the progress bar updates via it. Change execute_command() to update the progress bar via the operation detail it creates to hold the command being executed, instead of the parent operation detail, to resolve the above. Also replaces calling operationdetail.get_last_child() throughout the method. Bug 760709 - Add progress bars to XFS and EXT2/3/4 file system specific copy methods --- src/FileSystem.cc | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/FileSystem.cc b/src/FileSystem.cc index 1cd6a1d6..fdfbdbc9 100644 --- a/src/FileSystem.cc +++ b/src/FileSystem.cc @@ -110,6 +110,7 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati TimedSlot timed_progress_slot ) { operationdetail.add_child( OperationDetail( command, STATUS_EXECUTE, FONT_BOLD_ITALIC ) ); + OperationDetail & cmd_operationdetail = operationdetail.get_last_child(); Glib::Pid pid; // set up pipes for capture int out, err; @@ -127,8 +128,7 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati &err ); } catch (Glib::SpawnError &e) { std::cerr << e.what() << std::endl; - operationdetail.get_last_child().add_child( - OperationDetail( e.what(), STATUS_ERROR, FONT_ITALIC ) ); + cmd_operationdetail.add_child( OperationDetail( e.what(), STATUS_ERROR, FONT_ITALIC ) ); return Utils::get_failure_status( e ); } fcntl( out, F_SETFL, O_NONBLOCK ); @@ -141,11 +141,9 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati PipeCapture errorcapture( err, error ); outputcapture.signal_eof.connect( sigc::mem_fun( *this, &FileSystem::execute_command_eof ) ); errorcapture.signal_eof.connect( sigc::mem_fun( *this, &FileSystem::execute_command_eof ) ); - operationdetail.get_last_child().add_child( - OperationDetail( output, STATUS_NONE, FONT_ITALIC ) ); - operationdetail.get_last_child().add_child( - OperationDetail( error, STATUS_NONE, FONT_ITALIC ) ); - std::vector &children = operationdetail.get_last_child().get_childs(); + cmd_operationdetail.add_child( OperationDetail( output, STATUS_NONE, FONT_ITALIC ) ); + cmd_operationdetail.add_child( OperationDetail( error, STATUS_NONE, FONT_ITALIC ) ); + std::vector &children = cmd_operationdetail.get_childs(); outputcapture.signal_update.connect( sigc::bind( sigc::ptr_fun( update_command_output ), children[children.size() - 2], &output ) ); @@ -155,17 +153,17 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati sigc::connection timed_conn; if ( flags & EXEC_PROGRESS_STDOUT && ! stream_progress_slot.empty() ) // Call progress tracking callback when stdout updates - outputcapture.signal_update.connect( sigc::bind( stream_progress_slot, &operationdetail ) ); + outputcapture.signal_update.connect( sigc::bind( stream_progress_slot, &cmd_operationdetail ) ); else if ( flags & EXEC_PROGRESS_STDERR && ! stream_progress_slot.empty() ) // Call progress tracking callback when stderr updates - errorcapture.signal_update.connect( sigc::bind( stream_progress_slot, &operationdetail ) ); + errorcapture.signal_update.connect( sigc::bind( stream_progress_slot, &cmd_operationdetail ) ); else if ( flags & EXEC_PROGRESS_TIMED && ! timed_progress_slot.empty() ) // Call progress tracking callback every 500 ms - timed_conn = Glib::signal_timeout().connect( sigc::bind( timed_progress_slot, &operationdetail ), 500 ); + timed_conn = Glib::signal_timeout().connect( sigc::bind( timed_progress_slot, &cmd_operationdetail ), 500 ); outputcapture.connect_signal(); errorcapture.connect_signal(); - operationdetail.get_last_child().signal_cancel.connect( + cmd_operationdetail.signal_cancel.connect( sigc::bind( sigc::ptr_fun( cancel_command ), pid, @@ -175,15 +173,15 @@ int FileSystem::execute_command_internal( const Glib::ustring & command, Operati if ( flags & EXEC_CHECK_STATUS ) { if ( !exit_status ) - operationdetail.get_last_child().set_status( STATUS_SUCCES ); + cmd_operationdetail.set_status( STATUS_SUCCES ); else - operationdetail.get_last_child().set_status( STATUS_ERROR ); + cmd_operationdetail.set_status( STATUS_ERROR ); } close( out ); close( err ); if ( timed_conn.connected() ) timed_conn.disconnect(); - operationdetail.stop_progressbar(); + cmd_operationdetail.stop_progressbar(); return exit_status; }