Improved support for fossil interactive questions

FossilOrigin-Name: 2c36e183b8e8816ada688991ea6da7ad64caf2a8
This commit is contained in:
kostas 2011-08-07 03:14:37 +00:00
parent 40fabe4378
commit d939003b9f
4 changed files with 104 additions and 97 deletions

View File

@ -17,7 +17,11 @@
#define SILENT_STATUS true
#define COUNTOF(array) (sizeof(array)/sizeof(array[0]))
//#define DEV_SETTINGS
#ifdef QT_WS_WIN
#define EOL_MARK "\r\n"
#else
#define EOL_MARK "\n"
#endif
enum
{
@ -84,24 +88,17 @@ MainWindow::MainWindow(QWidget *parent) :
statusLabel->setMinimumSize( statusLabel->sizeHint() );
ui->statusBar->addWidget( statusLabel, 1 );
#ifdef DEV_SETTINGS
currentWorkspace = "/home/kostas/tmp/testfossil";
fossilPath = "fossil";
#else
loadSettings();
#endif
refresh();
rebuildRecent();
fossilAbort = false;
}
//------------------------------------------------------------------------------
MainWindow::~MainWindow()
{
stopUI();
#ifndef DEV_SETTINGS
saveSettings();
#endif
delete ui;
}
const QString &MainWindow::getCurrentWorkspace()
@ -447,18 +444,18 @@ bool MainWindow::runFossil(const QStringList &args, QStringList *output, bool si
}
//------------------------------------------------------------------------------
static QString ParseFossilQuery(QString query)
static QString ParseFossilQuery(QString line)
{
// Extract question
int qend = query.indexOf('(');
int qend = line.indexOf('(');
if(qend == -1)
qend = query.indexOf('[');
qend = line.indexOf('[');
Q_ASSERT(qend!=-1);
query = query.left(qend);
query = query.trimmed();
query += "?";
query[0]=QString(query[0]).toUpper()[0];
return query;
line = line.left(qend);
line = line.trimmed();
line += "?";
line[0]=QString(line[0]).toUpper()[0];
return line;
}
//------------------------------------------------------------------------------
@ -487,39 +484,67 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
return false;
}
#ifdef Q_WS_WIN
const char *ans_yes = "y\r\n";
const char *ans_no = "n\r\n";
const char *ans_always = "a\r\n";
#else
const char *ans_yes = "y\n";
const char *ans_no = "n\n";
const char *ans_always = "a\n";
#endif
const char *ans_yes = "y" EOL_MARK;
const char *ans_no = "n" EOL_MARK;
const char *ans_always = "a" EOL_MARK;
QStringList local_output;
while(process.state()==QProcess::Running || !process.atEnd())
fossilAbort = false;
QString buffer;
while(process.state()==QProcess::Running)
{
bool has_line = process.canReadLine();
qint64 bytes_available=process.bytesAvailable();
if(!process.waitForReadyRead(1*1000) && !has_line && bytes_available==0)
if(fossilAbort)
{
log("\n* Terminated *\n");
process.terminate();
break;
}
// If no line yet, but some bytes available, maybe fossil is waiting for
// user input
if(!has_line && bytes_available>0)
process.waitForReadyRead(500);
buffer += process.readAll();
if(buffer.isEmpty())
continue;
// 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+COUNTOF(EOL_MARK));
else
last_line = buffer;
last_line = last_line.trimmed();
// Check if we have a query
bool ends_qmark = !last_line.isEmpty() && last_line[last_line.length()-1]=='?';
bool have_yn_query = last_line.toLower().indexOf("y/n")!=-1;
int have_yna_query = last_line.toLower().indexOf("a=always/y/n")!=-1;
bool have_query = ends_qmark && (have_yn_query || have_yna_query);
// Flush only the unneccessary part of the buffer to the log
QStringList log_lines = buffer.left(last_line_start).split(EOL_MARK);
foreach(QString line, log_lines)
{
QString line = process.readAll();
line = line.trimmed();
QString query = line.toLower();
if(line.isEmpty())
continue;
// Have we encountered a y/n query?
if(line[line.length()-1]=='?' && query.indexOf("y/n")!=-1)
if(output)
output->append(line);
if(!silent)
log(line+"\n");
}
// Remove everything we processed
buffer = buffer.mid(last_line_start);
// Now process any query
if(have_query && have_yn_query)
{
log(line);
// Extract question
query = ParseFossilQuery(query);
QString query = ParseFossilQuery(last_line);
int res = QMessageBox::question(this, "Fossil", query, QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
if(res==QMessageBox::Yes)
@ -532,13 +557,12 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
process.write(ans_no, COUNTOF(ans_no));
log("N\n");
}
buffer.clear();
}
// Have we encountered a y/n/always query?
else if(line[line.length()-1]=='?' && query.indexOf("a=always/y/n")!=-1)
else if(have_query && have_yna_query)
{
log(line);
// Extract question
query = ParseFossilQuery(query);
QString query = ParseFossilQuery(query);
int res = QMessageBox::question(this, "Fossil", query, QMessageBox::Yes|QMessageBox::No|QMessageBox::YesToAll, QMessageBox::No);
if(res==QDialogButtonBox::Yes)
@ -556,28 +580,10 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int
process.write(ans_no, COUNTOF(ans_no));
log("N\n");
}
buffer.clear();
}
}
while(process.canReadLine())
{
QString line = process.readLine();
line = line.trimmed();
//QString line = it->trimmed();
if(line.isEmpty())
continue;
local_output.append(line);
if(output)
output->append(line);
if(!silent)
log(line+"\n");
}
}
// Must be finished by now
Q_ASSERT(process.state()==QProcess::NotRunning);

View File

@ -169,6 +169,7 @@ private:
QProcess fossilUI;
class QAction *recentWorkspaceActs[MAX_RECENT];
class QLabel *statusLabel;
bool fossilAbort;
Settings settings;
QString projectName;

View File

@ -1,13 +1,13 @@
C Support\sfor\sFossil\squeries\nFileActionDialog\snow\sbecomes\sa\s(lame)\squestion\sdialog\sbox\swhen\sno\sdata\sis\sprovided\n
D 2011-08-06T16:15:50.633
C Improved\ssupport\sfor\sfossil\sinteractive\squestions
D 2011-08-07T03:14:37.316
F CommitDialog.cpp a1fcdc94933f4e1a144224c7c70f1e067d3ee31e
F CommitDialog.h 0550b1b652924ae54b6f6c9274cad2d4c491808a
F CommitDialog.ui 5067623f6af6f5a42c87df903278e383e945e154
F FileActionDialog.cpp fcaebf9986f789b3440d5390b3458ad5f86fe0c8
F FileActionDialog.h 15db1650b3a13d70bc338371e4c033c66e3b79ce
F FileActionDialog.ui c63644428579741aeb5fa052e237ba799ced9ad7
F MainWindow.cpp 10d04becd808da62ccf380d6c16f5bad8f3b06e9
F MainWindow.h 8a23caf1a70d41fe60a25894649a88b1efb851ba
F MainWindow.cpp 18c298a5cc9a8d27f59d377c4d363c7a9b7e1085
F MainWindow.h 81a5061a551c9969a7acfcc49c84adc076e5eaf6
F MainWindow.ui 9f901c1f06b24df3cbd36d5349ffe0d82896c05b
F RepoDialog.cpp 8f20e1511526973555c774350ec413dcecf51c9e
F RepoDialog.h a958c5f98f1e6882bf41dbdd2e4df3cb89700802
@ -173,7 +173,7 @@ F icons/fuel.icns 81e535004b62db801a02f3e15d0a33afc9d4070b
F icons/fuel.ico eb529ab3332a17b9302ef3e851db5b9ebce2a038
F main.cpp aed85ed9766ddb8685e300e8ca4a0dc193ae2586
F resources.qrc e98383ed205f4e37100c60057e0129c3b86dea53
P d80b84c6b58b7daf71174d32a8c33cab0e2aabac
R dc4d20cff6babdcbf4a5e0cb3bc252f9
P 6a6a654b0db2537fc73774e7dc37d25cb2ae63d7
R 40a5f682e0b0200d3bd354258d471c18
U kostas
Z ac4a65db19b5eab4386101e1f0358467
Z 68777a7f034546864430c866d1616086

View File

@ -1 +1 @@
6a6a654b0db2537fc73774e7dc37d25cb2ae63d7
2c36e183b8e8816ada688991ea6da7ad64caf2a8