1 // Copyright (c) 2017 Matthew Brennan Jones <matthew.brennan.jones@gmail.com> 2 // Boost Software License - Version 1.0 3 // A simple progress dialog for the D programming language 4 // https://github.com/workhorsy/d-progress-dialog 5 6 7 module progress_dialog_zenity; 8 9 import progress_dialog : ProgressDialogBase, use_log; 10 11 12 class ProgressDialogZenity : ProgressDialogBase { 13 import std.process : ProcessPipes; 14 15 this(string title, string message) { 16 super(title, message); 17 } 18 19 override void show(void delegate() cb) { 20 import std.process : ProcessPipes, ProcessException, pipeProcess, Redirect, tryWait; 21 import progress_dialog_helpers : programPaths, logProgramOutput; 22 23 string[] paths = programPaths(["zenity"]); 24 if (paths.length < 1) { 25 this.fireOnError(new Exception("Failed to find zenity")); 26 return; 27 } 28 29 string[] args = [ 30 paths[0], 31 "--progress", 32 "--title=" ~ _title, 33 "--text=" ~ _message, 34 "--percentage=0", 35 "--auto-close", 36 "--no-cancel", 37 "--modal", 38 ]; 39 ProcessPipes pipes; 40 try { 41 pipes = pipeProcess(args, Redirect.stdin | Redirect.stdout | Redirect.stderr); 42 } catch (ProcessException err) { 43 this.fireOnError(err); 44 return; 45 } 46 47 // Make sure the program did not terminate 48 if (tryWait(pipes.pid).terminated) { 49 this.fireOnError(new Exception("Failed to run zenity")); 50 return; 51 } 52 53 _pipes = pipes; 54 55 try { 56 cb(); 57 if (use_log) { 58 logProgramOutput(pipes); 59 } 60 } catch (Throwable err) { 61 this.fireOnError(err); 62 } 63 } 64 65 override void setPercent(int percent) { 66 import std..string : format; 67 _pipes.stdin.writef("%s\n".format(percent)); 68 _pipes.stdin.flush(); 69 } 70 71 override void close() { 72 import std.process : wait; 73 import progress_dialog_helpers : logProgramOutput; 74 75 this.setPercent(100); 76 77 if (wait(_pipes.pid) != 0) { 78 throw new Exception("Failed to close dialog"); 79 } 80 81 if (use_log) { 82 logProgramOutput(_pipes); 83 } 84 } 85 86 static bool isSupported() { 87 import progress_dialog_helpers : programPaths; 88 return programPaths(["zenity"]).length > 0; 89 } 90 91 ProcessPipes _pipes; 92 }