Fixed issue on OSX where the QProcess was terminating without providing all the fossil output.
Corrected handling of new-lines in fossil output on OSX. The update command now logs only the actual update output from fossil. The log cursor is now repositioned to the end before any text is appended. Fixed minor static analysis warnings. FossilOrigin-Name: 4db466899df13050ac14c60097286f1df3adc46f
This commit is contained in:
parent
cb9fa1a754
commit
6b470516fa
@ -19,9 +19,8 @@ CommitDialog::CommitDialog(QWidget *parent, QString title, QStringList &files, c
|
||||
|
||||
// Activate the checkbox if we have some text
|
||||
ui->checkBox->setVisible(checkBoxText!=0);
|
||||
if(checkBoxText)
|
||||
if(checkBoxText && checkBoxValue)
|
||||
{
|
||||
Q_ASSERT(checkBoxValue);
|
||||
ui->checkBox->setText(*checkBoxText);
|
||||
ui->checkBox->setCheckState(*checkBoxValue ? Qt::Checked : Qt::Unchecked);
|
||||
}
|
||||
|
@ -23,12 +23,6 @@
|
||||
|
||||
#define COUNTOF(array) (sizeof(array)/sizeof(array[0]))
|
||||
|
||||
#ifdef QT_WS_WIN
|
||||
const QString EOL_MARK("\r\n");
|
||||
#else
|
||||
const QString EOL_MARK("\n");
|
||||
#endif
|
||||
|
||||
#define PATH_SEP "/"
|
||||
#define FOSSIL_CHECKOUT1 "_FOSSIL_"
|
||||
#define FOSSIL_CHECKOUT2 ".fslckout"
|
||||
@ -1018,13 +1012,14 @@ void MainWindow::updateStashView()
|
||||
//------------------------------------------------------------------------------
|
||||
void MainWindow::log(const QString &text, bool isHTML)
|
||||
{
|
||||
QTextCursor c = ui->textBrowser->textCursor();
|
||||
c.movePosition(QTextCursor::End);
|
||||
ui->textBrowser->setTextCursor(c);
|
||||
|
||||
if(isHTML)
|
||||
ui->textBrowser->insertHtml(text);
|
||||
else
|
||||
ui->textBrowser->insertPlainText(text);
|
||||
QTextCursor c = ui->textBrowser->textCursor();
|
||||
c.movePosition(QTextCursor::End);
|
||||
ui->textBrowser->setTextCursor(c);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -1091,10 +1086,8 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
|
||||
QString fossil = getFossilPath();
|
||||
|
||||
if(detached)
|
||||
{
|
||||
return QProcess::startDetached(fossil, args, wkdir);
|
||||
}
|
||||
|
||||
|
||||
// Make StatusBar message
|
||||
QString status_msg = tr("Running Fossil");
|
||||
if(args.length() > 0)
|
||||
@ -1102,8 +1095,7 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
|
||||
ScopedStatus status(status_msg, ui, progressBar);
|
||||
|
||||
// Create fossil process
|
||||
QProcess process(this);
|
||||
process.setProcessChannelMode(QProcess::MergedChannels);
|
||||
QLoggedProcess process(this);
|
||||
process.setWorkingDirectory(wkdir);
|
||||
|
||||
process.start(fossil, args);
|
||||
@ -1112,7 +1104,7 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
|
||||
log(tr("Could not start fossil executable '") + fossil + "''\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const QChar EOL_MARK('\n');
|
||||
QString ans_yes = 'y' + EOL_MARK;
|
||||
QString ans_no = 'n' + EOL_MARK;
|
||||
QString ans_always = 'a' + EOL_MARK;
|
||||
@ -1123,7 +1115,7 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
|
||||
while(true)
|
||||
{
|
||||
QProcess::ProcessState state = process.state();
|
||||
qint64 bytes_avail = process.bytesAvailable();
|
||||
qint64 bytes_avail = process.logBytesAvailable();
|
||||
|
||||
if(state!=QProcess::Running && bytes_avail<1)
|
||||
break;
|
||||
@ -1139,8 +1131,8 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
|
||||
break;
|
||||
}
|
||||
|
||||
process.waitForReadyRead(500);
|
||||
QByteArray input = process.readAll();
|
||||
QByteArray input;
|
||||
process.getLogAndClear(input);
|
||||
|
||||
#ifdef QT_DEBUG // Log fossil output in debug builds
|
||||
if(!input.isEmpty())
|
||||
@ -1154,12 +1146,16 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
|
||||
if(buffer.isEmpty())
|
||||
continue;
|
||||
|
||||
// Normalize line endings
|
||||
buffer = buffer.replace("\r\n", "\n");
|
||||
buffer = buffer.replace("\r", "\n");
|
||||
|
||||
// Extract the last line
|
||||
int last_line_start = buffer.lastIndexOf(EOL_MARK);
|
||||
|
||||
QString last_line;
|
||||
if(last_line_start != -1)
|
||||
last_line = buffer.mid(last_line_start+EOL_MARK.length());
|
||||
last_line = buffer.mid(last_line_start+1); // Including the EOL
|
||||
else
|
||||
last_line = buffer;
|
||||
|
||||
@ -1173,11 +1169,16 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
|
||||
|
||||
bool have_query = ends_qmark && (have_yn_query || have_yna_query || have_an_query);
|
||||
|
||||
// Flush only the unnecessary part of the buffer to the log
|
||||
// Flush all complete lines to the log and output
|
||||
QStringList log_lines = buffer.left(last_line_start).split(EOL_MARK);
|
||||
foreach(QString line, log_lines)
|
||||
for(int l=0; l<log_lines.length(); ++l)
|
||||
{
|
||||
line = line.trimmed();
|
||||
// Do not output the last line if it not complete
|
||||
if(l==log_lines.length()-1 && buffer[buffer.length()-1] != EOL_MARK )
|
||||
continue;
|
||||
|
||||
QString line = log_lines[l].trimmed();
|
||||
|
||||
if(line.isEmpty())
|
||||
continue;
|
||||
|
||||
@ -1188,8 +1189,8 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
|
||||
log(line+"\n");
|
||||
}
|
||||
|
||||
// Remove everything we processed
|
||||
buffer = buffer.mid(last_line_start);
|
||||
// Remove everything we processed (including the EOL)
|
||||
buffer = buffer.mid(last_line_start+1) ;
|
||||
|
||||
// Now process any query
|
||||
if(have_query && have_yna_query)
|
||||
@ -1949,13 +1950,13 @@ void MainWindow::on_actionUpdate_triggered()
|
||||
{
|
||||
QStringList res;
|
||||
|
||||
if(!runFossil(QStringList() << "update" << "--nochange", &res ))
|
||||
if(!runFossil(QStringList() << "update" << "--nochange", &res, RUNGLAGS_SILENT_ALL))
|
||||
return;
|
||||
|
||||
if(res.length()==0)
|
||||
return;
|
||||
|
||||
if(!FileActionDialog::run(this, tr("Update"), tr("The following files will be update. Are you sure?"), res))
|
||||
if(!FileActionDialog::run(this, tr("Update"), tr("The following files will be updated. Are you sure?"), res))
|
||||
return;
|
||||
|
||||
// Do Update
|
||||
@ -2444,6 +2445,9 @@ void MainWindow::onFileViewDragOut()
|
||||
getFileViewSelection(filenames);
|
||||
QString uris;
|
||||
|
||||
if(filenames.isEmpty())
|
||||
return;
|
||||
|
||||
// text/uri-list is a new-line separate list of uris
|
||||
foreach(QString f, filenames)
|
||||
{
|
||||
|
20
Utils.cpp
20
Utils.cpp
@ -291,3 +291,23 @@ bool ShowExplorerMenu(HWND hwnd, const QString &path, const QPoint &qpoint)
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
QLoggedProcess::QLoggedProcess(QObject *parent) : QProcess(parent)
|
||||
{
|
||||
setProcessChannelMode(QProcess::MergedChannels);
|
||||
connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(onReadyReadStandardOutput()));
|
||||
}
|
||||
|
||||
void QLoggedProcess::getLogAndClear(QByteArray &buffer)
|
||||
{
|
||||
QMutexLocker lck(&mutex);
|
||||
buffer = log;
|
||||
log.clear();
|
||||
}
|
||||
|
||||
void QLoggedProcess::onReadyReadStandardOutput()
|
||||
{
|
||||
QMutexLocker lck(&mutex);
|
||||
log.append(readAllStandardOutput());
|
||||
}
|
||||
|
||||
|
19
Utils.h
19
Utils.h
@ -3,6 +3,8 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QMessageBox>
|
||||
#include <QProcess>
|
||||
#include <QMutex>
|
||||
|
||||
QMessageBox::StandardButton DialogQuery(QWidget *parent, const QString &title, const QString &query, QMessageBox::StandardButtons buttons = QMessageBox::Yes|QMessageBox::No);
|
||||
|
||||
@ -10,4 +12,21 @@ QMessageBox::StandardButton DialogQuery(QWidget *parent, const QString &title, c
|
||||
bool ShowExplorerMenu(HWND hwnd, const QString &path, const QPoint &qpoint);
|
||||
#endif
|
||||
|
||||
class QLoggedProcess : public QProcess
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QLoggedProcess(QObject *parent = 0);
|
||||
void getLogAndClear(QByteArray &buffer);
|
||||
bool isLogEmpty() const { return log.isEmpty(); }
|
||||
qint64 logBytesAvailable() const { return log.size(); }
|
||||
|
||||
private slots:
|
||||
void onReadyReadStandardOutput();
|
||||
|
||||
private:
|
||||
QMutex mutex;
|
||||
QByteArray log;
|
||||
};
|
||||
|
||||
#endif // UTILS_H
|
||||
|
18
manifest
18
manifest
@ -1,9 +1,9 @@
|
||||
C Simplified\sstatus\sbar\shandlong\nWhen\sfossil\sis\srunning,\sa\sprogress\sbar\sis\snow\sdisplayed\sand\sinput\sevent\sprocessing\sis\sdisabled\n
|
||||
D 2012-05-09T14:20:26.209
|
||||
C Fixed\sissue\son\sOSX\swhere\sthe\sQProcess\swas\sterminating\swithout\sproviding\sall\sthe\sfossil\soutput.\nCorrected\shandling\sof\snew-lines\sin\sfossil\soutput\son\sOSX.\nThe\supdate\scommand\snow\slogs\sonly\sthe\sactual\supdate\soutput\sfrom\sfossil.\nThe\slog\scursor\sis\snow\srepositioned\sto\sthe\send\sbefore\sany\stext\sis\sappended.\nFixed\sminor\sstatic\sanalysis\swarnings.\n
|
||||
D 2012-05-12T07:56:42.282
|
||||
F CloneDialog.cpp 85bc6473d1e3a47d0f981e96357a376be63ab0bc
|
||||
F CloneDialog.h 1c63da4346ca20b67d52016b7b64875b9c5b477f
|
||||
F CloneDialog.ui 0fc820804df91f16506ee466a44519fdd44e468f
|
||||
F CommitDialog.cpp a46020a9361151d8d286a2670257d01d8967bf69
|
||||
F CommitDialog.cpp c62ce7fb234e43ca8641c16522c750e6419bf947
|
||||
F CommitDialog.h f1ee8db92103164e7db55a8407ccdcff24571b72
|
||||
F CommitDialog.ui 813d7cba316e226de1a22b7e480bb969fbe9b0c4
|
||||
F FileActionDialog.cpp fcaebf9986f789b3440d5390b3458ad5f86fe0c8
|
||||
@ -11,14 +11,14 @@ F FileActionDialog.h 15db1650b3a13d70bc338371e4c033c66e3b79ce
|
||||
F FileActionDialog.ui c63644428579741aeb5fa052e237ba799ced9ad7
|
||||
F FileTableView.cpp 5ddf8c391c9a3ac449ec61fb1db837b577afeec2
|
||||
F FileTableView.h 03e56d87c2d46411b9762b87f4d301619aaf18df
|
||||
F MainWindow.cpp c106d92d343817c381634251207b0fd6b85d9dd7
|
||||
F MainWindow.cpp 28297ee15b894776278e83442c9eaa6a768873e9
|
||||
F MainWindow.h f97ef3776d10211f42651cd2b7c7291d90bac3c1
|
||||
F MainWindow.ui 5f4e40bfb3e93b00f2e06a6071187998eb617224
|
||||
F SettingsDialog.cpp 296c77c5704bd8cb77a00d561db072aaaf60c1d6
|
||||
F SettingsDialog.h 9592ec491cd44a5bff70ea42853d7e1f053f4040
|
||||
F SettingsDialog.ui 8964629ea80c61971c0601624c84d1927902b1fd
|
||||
F Utils.cpp caca5268e3194abe77211040bf9511a82909d2e6
|
||||
F Utils.h 32e5d344a7f4d27e3ee83006022df007c90470ef
|
||||
F Utils.cpp 15c371dd26b9c565f098ae33a4f3e7ae7b21a7d6
|
||||
F Utils.h ea3b8a9e82bf9579949ac7e15bce2c9bb3ed8320
|
||||
F fuel.pro 41db75043b6959e870e6e87544bbbd4afe654d7d
|
||||
F fuel.rc 8e9ac966f283102c11a77cd7f936cdc09e09bd79
|
||||
F icons/Address\sBook-01.png ef2cec80ea5a559b72e8be4a344a1869fe69cbd8
|
||||
@ -179,7 +179,7 @@ F installer/fuel.iss 13b6a938bcdf273cbd3649d2549887baa1577214
|
||||
F installer/license.txt 4cc77b90af91e615a64ae04893fdffa7939db84c
|
||||
F main.cpp f2913af0af1a5fcbebe93fb53b8a9cf6e7bbf65a
|
||||
F resources.qrc e98383ed205f4e37100c60057e0129c3b86dea53
|
||||
P 3eb9f233b9f05d6e131a69b3fc25f5f8d5c11491
|
||||
R b9b3e1414a5ceae0afbe31f5cfee9426
|
||||
P 6dc326684138f1e61b1ea95ef96c6f421bf3a09d
|
||||
R 729ba5d54817d2542ae05776fa368ce7
|
||||
U kostas
|
||||
Z b2ff6e9c95bb4648cc5970dfe895a0d4
|
||||
Z f928875a10ac6a9b74c3c0986350f742
|
||||
|
@ -1 +1 @@
|
||||
6dc326684138f1e61b1ea95ef96c6f421bf3a09d
|
||||
4db466899df13050ac14c60097286f1df3adc46f
|
Loading…
x
Reference in New Issue
Block a user