comparison hgrunner.cpp @ 62:68aebc316898

* Some adjustments to process running (avoid timer): caller must now report errors * Function to find user's real name * Locate hg executable in path explicitly, use a setting to remember it
author Chris Cannam
date Wed, 17 Nov 2010 13:32:56 +0000
parents 4557da8bdee6
children 794db9353c7f
comparison
equal deleted inserted replaced
61:bf57a16315bd 62:68aebc316898
14 License, or (at your option) any later version. See the file 14 License, or (at your option) any later version. See the file
15 COPYING included with this distribution for more information. 15 COPYING included with this distribution for more information.
16 */ 16 */
17 17
18 #include "hgrunner.h" 18 #include "hgrunner.h"
19 #include "common.h"
19 #include "debug.h" 20 #include "debug.h"
20 21
21 #include <QPushButton> 22 #include <QPushButton>
22 #include <QListWidget> 23 #include <QListWidget>
23 #include <QDialog> 24 #include <QDialog>
24 #include <QLabel> 25 #include <QLabel>
25 #include <QVBoxLayout> 26 #include <QVBoxLayout>
27 #include <QSettings>
26 28
27 #include <iostream> 29 #include <iostream>
28 #include <unistd.h> 30 #include <unistd.h>
29 31
30 HgRunner::HgRunner(QWidget * parent): QProgressBar(parent) 32 HgRunner::HgRunner(QWidget * parent): QProgressBar(parent)
42 44
43 stdOut.clear(); 45 stdOut.clear();
44 stdErr.clear(); 46 stdErr.clear();
45 47
46 connect(proc, SIGNAL(started()), this, SLOT(started())); 48 connect(proc, SIGNAL(started()), this, SLOT(started()));
47 connect(proc, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError))); 49 connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
48 connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus))); 50 this, SLOT(finished(int, QProcess::ExitStatus)));
51
52 reportErrors = false;
49 } 53 }
50 54
51 HgRunner::~HgRunner() 55 HgRunner::~HgRunner()
52 { 56 {
53 delete proc; 57 delete proc;
54 } 58 }
55 59
60 QString HgRunner::getHgBinaryName()
61 {
62 QSettings settings;
63 QString hg = settings.value("hgbinary", "hg").toString();
64 if (hg == "") hg = "hg";
65 hg = findExecutable(hg);
66 settings.setValue("hgbinary", hg);
67 return hg;
68 }
69
56 void HgRunner::started() 70 void HgRunner::started()
57 { 71 {
58 proc -> closeWriteChannel(); 72 proc -> closeWriteChannel();
73 }
74
75 void HgRunner::saveOutput()
76 {
77 stdOut = QString::fromUtf8(proc -> readAllStandardOutput());
78 stdErr = QString::fromUtf8(proc -> readAllStandardError());
59 } 79 }
60 80
61 void HgRunner::setProcExitInfo(int procExitCode, QProcess::ExitStatus procExitStatus) 81 void HgRunner::setProcExitInfo(int procExitCode, QProcess::ExitStatus procExitStatus)
62 { 82 {
63 exitCode = procExitCode; 83 exitCode = procExitCode;
64 exitStatus = procExitStatus; 84 exitStatus = procExitStatus;
65 stdOut = QString::fromUtf8(proc -> readAllStandardOutput());
66 stdErr = QString::fromUtf8(proc -> readAllStandardError());
67 85
68 DEBUG << "setProcExitInfo: " << stdOut.split("\n").size() << " line(s) of stdout, " << stdErr.split("\n").size() << " line(s) of stderr"; 86 DEBUG << "setProcExitInfo: " << stdOut.split("\n").size() << " line(s) of stdout, " << stdErr.split("\n").size() << " line(s) of stderr";
69 87
70 // std::cerr << "stdout was " << stdOut.toStdString() << std::endl; 88 // std::cerr << "stdout was " << stdOut.toStdString() << std::endl;
71 }
72
73 void HgRunner::presentErrorToUser()
74 {
75 QPushButton *okButton;
76 QListWidget *stdoL;
77 QListWidget *stdeL;
78 QString tmp;
79
80 QDialog *dlg = new QDialog(this);
81 dlg -> setMinimumWidth(800);
82 QVBoxLayout layout;
83
84 dlg -> setWindowTitle(tr("Mercurial error / warning"));
85
86 tmp.sprintf("%s: %d, %s: %d", "Exitcode", exitCode, "Exit status", exitStatus);
87 layout.addWidget(new QLabel(getLastCommandLine()));
88 layout.addWidget(new QLabel(tmp));
89 layout.addWidget(new QLabel(tr("Standard out:")));
90 stdoL = new QListWidget();
91 stdoL -> addItems(stdOut.split("\n"));
92 layout.addWidget(stdoL);
93
94 layout.addWidget(new QLabel(tr("Standard error:")));
95 stdeL = new QListWidget();
96 stdeL -> addItems(stdErr.split("\n"));
97 layout.addWidget(stdeL);
98
99 okButton = new QPushButton("Ok");
100 layout.addWidget(okButton);
101
102 connect(okButton, SIGNAL(clicked()), dlg, SLOT(accept()));
103 dlg -> setLayout(&layout);
104
105 dlg -> setModal(true);
106 dlg -> exec();
107 }
108
109
110
111 void HgRunner::error(QProcess::ProcessError)
112 {
113 setProcExitInfo(proc -> exitCode(), proc -> exitStatus());
114
115 if (reportErrors)
116 {
117 presentErrorToUser();
118 }
119
120 isRunning = false;
121 } 89 }
122 90
123 QString HgRunner::getLastCommandLine() 91 QString HgRunner::getLastCommandLine()
124 { 92 {
125 return QString("Command line: " + lastHgCommand + " " + lastParams); 93 return QString("Command line: " + lastHgCommand + " " + lastParams);
126 } 94 }
127 95
128 void HgRunner::finished(int procExitCode, QProcess::ExitStatus procExitStatus) 96 void HgRunner::finished(int procExitCode, QProcess::ExitStatus procExitStatus)
129 { 97 {
130 setProcExitInfo(procExitCode, procExitStatus); 98 setProcExitInfo(procExitCode, procExitStatus);
99 isRunning = false;
131 100
132 if (reportErrors) 101 if (procExitCode == 0 || procExitStatus == QProcess::NormalExit) {
133 { 102 emit commandCompleted();
134 if ((exitCode == 0) && (exitStatus == QProcess::NormalExit)) 103 } else {
135 { 104 emit commandFailed();
136 //All ok
137 }
138 else
139 {
140 presentErrorToUser();
141 }
142 } 105 }
143
144 isRunning = false;
145 } 106 }
146 107
147 bool HgRunner::isProcRunning() 108 bool HgRunner::isCommandRunning()
148 { 109 {
149 return isRunning; 110 return isRunning;
150 } 111 }
151 112
152 void HgRunner::killProc() 113 void HgRunner::killCurrentCommand()
153 { 114 {
154 if (isProcRunning()) 115 if (isCommandRunning()) {
155 {
156 proc -> kill(); 116 proc -> kill();
157 } 117 }
158 } 118 }
159 119
120 void HgRunner::startHgCommand(QString workingDir, QStringList params)
121 {
122 startCommand(getHgBinaryName(), workingDir, params);
123 }
160 124
161 void HgRunner::startProc(QString hgExePathAndName, QString workingDir, QStringList params, bool reportErrors) 125 void HgRunner::startCommand(QString command, QString workingDir, QStringList params)
162 { 126 {
163 this -> reportErrors = reportErrors;
164 isRunning = true; 127 isRunning = true;
165 setRange(0, 0); 128 setRange(0, 0);
166 setVisible(true); 129 setVisible(true);
167 stdOut.clear(); 130 stdOut.clear();
168 stdErr.clear(); 131 stdErr.clear();
172 if (!workingDir.isEmpty()) 135 if (!workingDir.isEmpty())
173 { 136 {
174 proc -> setWorkingDirectory(workingDir); 137 proc -> setWorkingDirectory(workingDir);
175 } 138 }
176 139
177 lastHgCommand = hgExePathAndName; 140 lastHgCommand = command;
178 lastParams = params.join(" "); 141 lastParams = params.join(" ");
179 142
180 QString cmdline = hgExePathAndName; 143 QString cmdline = command;
181 foreach (QString param, params) cmdline += " " + param; 144 foreach (QString param, params) cmdline += " " + param;
182 DEBUG << "HgRunner: starting: " << cmdline; 145 DEBUG << "HgRunner: starting: " << cmdline;
183 146
184 proc -> start(hgExePathAndName, params); 147 proc -> start(command, params);
185
186 } 148 }
187 149
188 int HgRunner::getExitCode() 150 int HgRunner::getExitCode()
189 { 151 {
190 return exitCode; 152 return exitCode;