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

View File

@ -169,6 +169,7 @@ private:
QProcess fossilUI; QProcess fossilUI;
class QAction *recentWorkspaceActs[MAX_RECENT]; class QAction *recentWorkspaceActs[MAX_RECENT];
class QLabel *statusLabel; class QLabel *statusLabel;
bool fossilAbort;
Settings settings; Settings settings;
QString projectName; 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 C Improved\ssupport\sfor\sfossil\sinteractive\squestions
D 2011-08-06T16:15:50.633 D 2011-08-07T03:14:37.316
F CommitDialog.cpp a1fcdc94933f4e1a144224c7c70f1e067d3ee31e F CommitDialog.cpp a1fcdc94933f4e1a144224c7c70f1e067d3ee31e
F CommitDialog.h 0550b1b652924ae54b6f6c9274cad2d4c491808a F CommitDialog.h 0550b1b652924ae54b6f6c9274cad2d4c491808a
F CommitDialog.ui 5067623f6af6f5a42c87df903278e383e945e154 F CommitDialog.ui 5067623f6af6f5a42c87df903278e383e945e154
F FileActionDialog.cpp fcaebf9986f789b3440d5390b3458ad5f86fe0c8 F FileActionDialog.cpp fcaebf9986f789b3440d5390b3458ad5f86fe0c8
F FileActionDialog.h 15db1650b3a13d70bc338371e4c033c66e3b79ce F FileActionDialog.h 15db1650b3a13d70bc338371e4c033c66e3b79ce
F FileActionDialog.ui c63644428579741aeb5fa052e237ba799ced9ad7 F FileActionDialog.ui c63644428579741aeb5fa052e237ba799ced9ad7
F MainWindow.cpp 10d04becd808da62ccf380d6c16f5bad8f3b06e9 F MainWindow.cpp 18c298a5cc9a8d27f59d377c4d363c7a9b7e1085
F MainWindow.h 8a23caf1a70d41fe60a25894649a88b1efb851ba F MainWindow.h 81a5061a551c9969a7acfcc49c84adc076e5eaf6
F MainWindow.ui 9f901c1f06b24df3cbd36d5349ffe0d82896c05b F MainWindow.ui 9f901c1f06b24df3cbd36d5349ffe0d82896c05b
F RepoDialog.cpp 8f20e1511526973555c774350ec413dcecf51c9e F RepoDialog.cpp 8f20e1511526973555c774350ec413dcecf51c9e
F RepoDialog.h a958c5f98f1e6882bf41dbdd2e4df3cb89700802 F RepoDialog.h a958c5f98f1e6882bf41dbdd2e4df3cb89700802
@ -173,7 +173,7 @@ F icons/fuel.icns 81e535004b62db801a02f3e15d0a33afc9d4070b
F icons/fuel.ico eb529ab3332a17b9302ef3e851db5b9ebce2a038 F icons/fuel.ico eb529ab3332a17b9302ef3e851db5b9ebce2a038
F main.cpp aed85ed9766ddb8685e300e8ca4a0dc193ae2586 F main.cpp aed85ed9766ddb8685e300e8ca4a0dc193ae2586
F resources.qrc e98383ed205f4e37100c60057e0129c3b86dea53 F resources.qrc e98383ed205f4e37100c60057e0129c3b86dea53
P d80b84c6b58b7daf71174d32a8c33cab0e2aabac P 6a6a654b0db2537fc73774e7dc37d25cb2ae63d7
R dc4d20cff6babdcbf4a5e0cb3bc252f9 R 40a5f682e0b0200d3bd354258d471c18
U kostas U kostas
Z ac4a65db19b5eab4386101e1f0358467 Z 68777a7f034546864430c866d1616086

View File

@ -1 +1 @@
6a6a654b0db2537fc73774e7dc37d25cb2ae63d7 2c36e183b8e8816ada688991ea6da7ad64caf2a8