automatically open include files in new tabs; show in syntax highlighting, whether a file is readable
This commit is contained in:
@@ -9,9 +9,12 @@
|
|||||||
#include <QSyntaxHighlighter>
|
#include <QSyntaxHighlighter>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QRegularExpressionMatch>
|
#include <QRegularExpressionMatch>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
class Highlighter: public QSyntaxHighlighter {
|
class Highlighter: public QSyntaxHighlighter {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
Q_SIGNALS:
|
||||||
|
void include(QString);
|
||||||
public:
|
public:
|
||||||
Highlighter(QTextDocument *parent): QSyntaxHighlighter(parent) {
|
Highlighter(QTextDocument *parent): QSyntaxHighlighter(parent) {
|
||||||
QString commands="auth|ca-certificate|call|case|check|clear-cookies|click|clicktype|client-certificate|do|download|echo|execute|exists|exit|expect|fail|for|function|if|ignoreto|include|label|load|not|offline-storage-path|open|screenshot|set|setvalue|sleep|testcase|testsuite|timeout|unset|upload";
|
QString commands="auth|ca-certificate|call|case|check|clear-cookies|click|clicktype|client-certificate|do|download|echo|execute|exists|exit|expect|fail|for|function|if|ignoreto|include|label|load|not|offline-storage-path|open|screenshot|set|setvalue|sleep|testcase|testsuite|timeout|unset|upload";
|
||||||
@@ -20,6 +23,18 @@ class Highlighter: public QSyntaxHighlighter {
|
|||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
void highlightBlock(const QString &text) {
|
void highlightBlock(const QString &text) {
|
||||||
|
static QRegularExpression inc("^ *include +([^ ].*.\\.wt)");
|
||||||
|
QRegularExpressionMatch m(inc.match(text));
|
||||||
|
if (m.hasMatch()) {
|
||||||
|
QTextCharFormat fmt;
|
||||||
|
if (QFile(m.captured(1)).exists()) {
|
||||||
|
fmt.setForeground(Qt::darkGreen);
|
||||||
|
} else {
|
||||||
|
fmt.setForeground(Qt::darkRed);
|
||||||
|
}
|
||||||
|
setFormat(m.capturedStart(1), m.capturedLength(1), fmt);
|
||||||
|
include(m.captured(1));
|
||||||
|
}
|
||||||
for (auto e: _expressions) {
|
for (auto e: _expressions) {
|
||||||
auto m(e.re.match(text));
|
auto m(e.re.match(text));
|
||||||
for (int i(0); i<=m.lastCapturedIndex(); ++i) {
|
for (int i(0); i<=m.lastCapturedIndex(); ++i) {
|
||||||
@@ -53,13 +68,16 @@ class LineNumberArea: public QWidget {
|
|||||||
|
|
||||||
class CodeEditor: public QPlainTextEdit {
|
class CodeEditor: public QPlainTextEdit {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
Q_SIGNALS:
|
||||||
|
void include(QString);
|
||||||
public:
|
public:
|
||||||
CodeEditor(QWidget *parent = 0): QPlainTextEdit(parent) {
|
CodeEditor(QWidget *parent = 0): QPlainTextEdit(parent) {
|
||||||
new Highlighter(document());
|
Highlighter *highlighter(new Highlighter(document()));
|
||||||
lineNumberArea = new LineNumberArea(this);
|
lineNumberArea = new LineNumberArea(this);
|
||||||
connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
|
assert(connect(this, SIGNAL(blockCountChanged(int)), SLOT(updateLineNumberAreaWidth(int))));
|
||||||
connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
|
assert(connect(this, SIGNAL(updateRequest(QRect,int)), SLOT(updateLineNumberArea(QRect,int))));
|
||||||
connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
|
assert(connect(this, SIGNAL(cursorPositionChanged()), SLOT(highlightCurrentLine())));
|
||||||
|
assert(connect(highlighter, SIGNAL(include(QString)), SIGNAL(include(QString))));
|
||||||
updateLineNumberAreaWidth(0);
|
updateLineNumberAreaWidth(0);
|
||||||
highlightCurrentLine();
|
highlightCurrentLine();
|
||||||
}
|
}
|
||||||
|
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
bin_PROGRAMS = webtester webrunner
|
bin_PROGRAMS = webtester webrunner
|
||||||
|
|
||||||
webtester_MOCFILES = moc_testgui.cxx moc_commands.cxx moc_webpage.cxx \
|
webtester_MOCFILES = moc_testgui.cxx moc_scriptfile.cxx moc_commands.cxx moc_webpage.cxx \
|
||||||
moc_networkaccessmanager.cxx moc_editor.cxx
|
moc_networkaccessmanager.cxx moc_editor.cxx
|
||||||
webtester_UIFILES = ui_testgui.hxx
|
webtester_UIFILES = ui_testgui.hxx ui_scriptfile.hxx
|
||||||
webtester_SOURCES = version.cxx webtester.cxx exceptions.hxx version.hxx \
|
webtester_SOURCES = version.cxx webtester.cxx exceptions.hxx version.hxx \
|
||||||
${webtester_MOCFILES} ${webtester_UIFILES}
|
${webtester_MOCFILES} ${webtester_UIFILES}
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <webpage.hxx>
|
#include <webpage.hxx>
|
||||||
#include <editor.hxx>
|
#include <editor.hxx>
|
||||||
#include <commands.hxx>
|
#include <commands.hxx>
|
||||||
|
#include <scriptfile.hxx>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QWebFrame>
|
#include <QWebFrame>
|
||||||
@@ -63,11 +64,12 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
|||||||
_web->installEventFilter(this); // track mouse and keyboard
|
_web->installEventFilter(this); // track mouse and keyboard
|
||||||
page->setForwardUnsupportedContent(true);
|
page->setForwardUnsupportedContent(true);
|
||||||
_commands->setText(Script().commands(Script::HTML));
|
_commands->setText(Script().commands(Script::HTML));
|
||||||
connect(page, SIGNAL(uploadFile(QString)), SLOT(uploadFile(QString)));
|
assert(connect(page, SIGNAL(uploadFile(QString)), SLOT(uploadFile(QString))));
|
||||||
connect(page, SIGNAL(unsupportedContent(QNetworkReply*)),
|
assert(connect(page, SIGNAL(unsupportedContent(QNetworkReply*)),
|
||||||
SLOT(unsupportedContent(QNetworkReply*)));
|
SLOT(unsupportedContent(QNetworkReply*))));
|
||||||
connect(page, SIGNAL(downloadRequested(const QNetworkRequest&)),
|
assert(connect(page, SIGNAL(downloadRequested(const QNetworkRequest&)),
|
||||||
SLOT(downloadRequested(const QNetworkRequest&)));
|
SLOT(downloadRequested(const QNetworkRequest&))));
|
||||||
|
assert(connect(_testscript, SIGNAL(include(QString)), SLOT(include(QString))));
|
||||||
if (setupScript.size()) loadSetup(setupScript);
|
if (setupScript.size()) loadSetup(setupScript);
|
||||||
if (scriptFile.size()) loadFile(scriptFile);
|
if (scriptFile.size()) loadFile(scriptFile);
|
||||||
}
|
}
|
||||||
@@ -338,6 +340,32 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
|||||||
if (!vb) return;
|
if (!vb) return;
|
||||||
vb->setValue(vb->maximum());
|
vb->setValue(vb->maximum());
|
||||||
}
|
}
|
||||||
|
void include(QString name) {
|
||||||
|
if (_testscripts.contains(name)) return;
|
||||||
|
_testscripts[name] = new ScriptFile(this);
|
||||||
|
assert(connect(_testscripts[name], SIGNAL(include(QString)), SLOT(include(QString))));
|
||||||
|
assert(connect(_testscripts[name], SIGNAL(close(ScriptFile*)), SLOT(remove(ScriptFile*))));
|
||||||
|
QFile file(name);
|
||||||
|
try {
|
||||||
|
if (!file.open(QIODevice::ReadOnly|QIODevice::Text))
|
||||||
|
throw std::runtime_error("file open failed");
|
||||||
|
_testscripts[name]->editor()->setPlainText(QString::fromUtf8(file.readAll()));
|
||||||
|
if (file.error()!=QFileDevice::NoError)
|
||||||
|
throw std::runtime_error("file read failed");
|
||||||
|
_testscripts[name]->name(name);
|
||||||
|
tabifyDockWidget(_scriptDock, _testscripts[name]);
|
||||||
|
QDockWidget* d(0);
|
||||||
|
for (QWidget* w(QApplication::focusWidget()); w&&!(d=qobject_cast<QDockWidget*>(w));
|
||||||
|
w=qobject_cast<QWidget*>(w->parent()));
|
||||||
|
if (d) d->raise();
|
||||||
|
} catch(const std::exception& x) {
|
||||||
|
remove(_testscripts[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void remove(ScriptFile* scriptfile) {
|
||||||
|
_testscripts.remove(scriptfile->name());
|
||||||
|
delete scriptfile;
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent* event) {
|
void closeEvent(QCloseEvent* event) {
|
||||||
QSettings settings("mrw", "webtester");
|
QSettings settings("mrw", "webtester");
|
||||||
@@ -900,6 +928,7 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
|||||||
bool _typing; // user is typing
|
bool _typing; // user is typing
|
||||||
bool _inEventFilter; // actually handling event filter
|
bool _inEventFilter; // actually handling event filter
|
||||||
Script _setupScript;
|
Script _setupScript;
|
||||||
|
QMap<QString, ScriptFile*> _testscripts;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TESTGUI_HXX
|
#endif // TESTGUI_HXX
|
||||||
|
@@ -134,7 +134,7 @@
|
|||||||
<widget class="QStatusBar" name="statusbar"/>
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
<widget class="QDockWidget" name="_domDock">
|
<widget class="QDockWidget" name="_domDock">
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>DOM Tree</string>
|
<string>D&OM Tree</string>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="dockWidgetArea">
|
<attribute name="dockWidgetArea">
|
||||||
<number>2</number>
|
<number>2</number>
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<widget class="QDockWidget" name="_sourceDock">
|
<widget class="QDockWidget" name="_sourceDock">
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>HTML Source</string>
|
<string>HTML &Source</string>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="dockWidgetArea">
|
<attribute name="dockWidgetArea">
|
||||||
<number>8</number>
|
<number>8</number>
|
||||||
@@ -596,7 +596,7 @@ this.dispatchEvent(evObj);</string>
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPlainTextEdit" name="_setupscript"/>
|
<widget class="CodeEditor" name="_setupscript"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
Reference in New Issue
Block a user