new features implemented, switch to Version 3.0; done: find, replace, goto line
This commit is contained in:
@@ -8,8 +8,9 @@
|
||||
|
||||
# change this:
|
||||
m4_define(x_package_name, webtester) # project's name
|
||||
m4_define(x_major, 2) # project's major version
|
||||
m4_define(x_minor, 2) # project's minor version
|
||||
m4_define(x_major, 3) # project's major version
|
||||
m4_define(x_minor, 0) # project's minor version
|
||||
m4_define(x_least_diff, 123)
|
||||
|
||||
# never edit this block:
|
||||
m4_include(ax_init_standard_project.m4)
|
||||
|
148
src/commands.hxx
148
src/commands.hxx
@@ -278,7 +278,7 @@ class Empty: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
""
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Empty lines are allowed";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -306,7 +306,7 @@ class Comment: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
"# comment"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Comments are lines that start with #";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -383,7 +383,7 @@ class Screenshot: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <filename-base>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Create a PNG screenshot of the actual web page and store it in the "
|
||||
"file <filename-base>.png. If not already opened, a browser window "
|
||||
"will pop up to take the screenshot.";
|
||||
@@ -450,6 +450,7 @@ class Script: public QObject {
|
||||
void logging(QString);
|
||||
void progress(QString, int, int, int);
|
||||
public:
|
||||
typedef std::map<QString, std::shared_ptr<Command>> Prototypes;
|
||||
typedef std::pair<QString, QStringList> Signal;
|
||||
enum ClickType {
|
||||
REAL_MOUSE_CLICK,
|
||||
@@ -500,56 +501,78 @@ class Script: public QObject {
|
||||
}
|
||||
QString syntax() const {
|
||||
return
|
||||
"Script syntax is a text file that consists of list of commands. Each "
|
||||
"Script syntax is a text file that consists of a list of commands. Each "
|
||||
"command starts at the begin of a new line. Empty lines are allowed. "
|
||||
"Lines that start with \"#\" are treated as comments."
|
||||
"\n\n"
|
||||
"Subcommands are indented. The first indented line defines the level of "
|
||||
"indentation. All following lines must be indented by the same level."
|
||||
"indentation. All following lines must be indented at least by the same level."
|
||||
"\n\n"
|
||||
"Note: When a selector is required as parameter, then the selector "
|
||||
"is a CSS selector."
|
||||
"\n\n"
|
||||
"Thanks to the filter script doxygen-webtester.sed, you cab use the "
|
||||
"Thanks to the filter script doxygen-webtester.sed, you can use the "
|
||||
"comments for producing doxygen documenation. Just start comments with "
|
||||
"\"##\" to import them to doxygen. This script is automatically configured, "
|
||||
"when you use the autotools bootstrap from:\n"
|
||||
"https://dev.marc.waeckerlin.org/redmine/projects/bootstrap-build-environment";
|
||||
"https://mrw.sh/development/bootstrap-build-environment";
|
||||
}
|
||||
/// set workdir
|
||||
void path(QString path) {
|
||||
_path = (path.size()?path:".")+QDir::separator();
|
||||
}
|
||||
/// get workdir
|
||||
QString path() {
|
||||
QString path() const {
|
||||
return _path;
|
||||
}
|
||||
/// get all command prototypes
|
||||
const Prototypes& prototypes() const {
|
||||
return _prototypes;
|
||||
}
|
||||
QString commands(Formatting f = PLAIN) const {
|
||||
QString cmds;
|
||||
for (auto it(_prototypes.begin()); it!=_prototypes.end(); ++it)
|
||||
switch (f) {
|
||||
case PLAIN: {
|
||||
for (auto it(_prototypes.begin()); it!=_prototypes.end(); ++it)
|
||||
cmds+="\n\n\nCOMMAND: "+it->first+"\n\n"+it->second->description();
|
||||
} break;
|
||||
case HTML: {
|
||||
cmds+="<h1>"+it->first+"</h1><p>"
|
||||
+it->second->description()
|
||||
auto format = [](QString s) {
|
||||
return s
|
||||
.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace(QRegularExpression("<([^ ]+)>"),
|
||||
"<i>\\1</i>")
|
||||
.replace(QRegularExpression("(\n[^ ][^\n]*)(\n +-)"),
|
||||
"\\1<ul>\\2")
|
||||
.replace(QRegularExpression("(\n +-[^\n]*\n)([^ ])"),
|
||||
"\\1</ul>\\2")
|
||||
.replace(QRegularExpression("\n +- ([^\n]*)(</ul>)?"),
|
||||
"<li>\\1</li>\\2")
|
||||
.replace(QRegularExpression("<([-_A-Za-z0-9]+)>"), "<i>\\1</i>")
|
||||
.replace(QRegularExpression("(\n[^ ][^\n]*)(\n +-)"), "\\1<ul>\\2")
|
||||
.replace(QRegularExpression("(\n +-[^\n]*\n)([^ ])"), "\\1</ul>\\2")
|
||||
.replace(QRegularExpression("\n +- ([^\n]*)(</ul>)?"), "<li>\\1</li>\\2")
|
||||
.replace("</li>\n", "</li>")
|
||||
.replace("\n ", "\n ")
|
||||
.replace("\n\n", "</p><p>")
|
||||
.replace("\n", "<br/>")
|
||||
+"</p>";
|
||||
.replace(QRegularExpression("(http(s)?://[-/^a-z0-9.]+)"), "<a href=\"\\1\">\\1</a>");
|
||||
};
|
||||
cmds = "<style>div#table-of-contents {border: 2px solid black; background-color: red; width: 100%; column-width: 5em;}</style>"
|
||||
"<h1>Contents</h1><ul>"
|
||||
"<li id=\"top-syntax-description\"><a href=\"#syntax-description\">Syntax</a></li>"
|
||||
"<li id=\"top-command-list\"><a href=\"#command-list\">Commands</a><ul>";
|
||||
for (auto[name,command]: _prototypes)
|
||||
cmds += "<li id=\"top-"+name+"\"><a href=\"#"+name+"\">"+name+"</a></li>";
|
||||
cmds += "</ul></li></ul>"
|
||||
"<h1 id=\"syntax-description\"><a href=\"#top-syntax-description\">Syntax</a></h1>"
|
||||
+format(syntax())+
|
||||
"<h1 id=\"command-list\"><a href=\"#top-command-list\">Commands</a></h1>";
|
||||
for (auto[name,command]: _prototypes) {
|
||||
QStringList doc(command->description().split("\n\n--\n\n"));
|
||||
assert(doc.size()==2); // description does not match expected format
|
||||
QString usage(doc.takeFirst());
|
||||
QString description(doc.takeFirst());
|
||||
cmds += "<h2 id=\""+name+"\"><a href=\"#top-"+name+"\">"+name+"</a></h2><h3>Usage</h3><p>"
|
||||
+ format(usage)
|
||||
+ "</p><h3>Description</h3><p>"
|
||||
+ format(description)
|
||||
+ "</p>";
|
||||
}
|
||||
} break;
|
||||
}
|
||||
return cmds.trimmed();
|
||||
@@ -1155,7 +1178,6 @@ class Script: public QObject {
|
||||
QString username;
|
||||
QString password;
|
||||
};
|
||||
typedef std::map<QString, std::shared_ptr<Command>> Prototypes;
|
||||
typedef std::vector<std::shared_ptr<Command>> Commands;
|
||||
Prototypes _prototypes;
|
||||
Commands _script;
|
||||
@@ -1205,7 +1227,7 @@ class Do: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" [<selector>]\n <javascript-line1>\n <javascript-line2>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Execute JavaScript on a CSS selected object. The object is the first "
|
||||
"object in the DOM tree that matches the given CSS selector. You can "
|
||||
"refere to the selected object within the scripy by \"this\". The "
|
||||
@@ -1248,7 +1270,7 @@ class Load: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <url>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Load an URL, the URL is given as parameter in full syntax.";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -1277,7 +1299,7 @@ class Expect: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <signal> [<parameter>]"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Expect a signal. Signals are emitted by webkit and may contain "
|
||||
"parameter. If a parameter is given in the script, then the parameter "
|
||||
"must match exactly. If no parameter is given, then the signal must "
|
||||
@@ -1346,7 +1368,7 @@ class Open: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Open the browser window, so you can follow the test steps visually.";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -1372,7 +1394,7 @@ class Sleep: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <seconds>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Sleep for a certain amount of seconds. This helps, if you must wait "
|
||||
"for some javascript actions, i.e. AJAX or slow pages, and the "
|
||||
"excpeted signals are not sufficient.";
|
||||
@@ -1410,7 +1432,7 @@ class Exit: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Successfully terminate script immediately. The following commands "
|
||||
"are not executed. This helps when you debug your scripts and you "
|
||||
"want the script stop at a certain point for investigations.";
|
||||
@@ -1437,7 +1459,7 @@ class IgnoreTo: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <label>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Ignore all following commands up to a given label. The following "
|
||||
"commands are not executed until the given label appears in the "
|
||||
"script. This helps when you debug your scripts and you "
|
||||
@@ -1470,7 +1492,7 @@ class Label: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <label>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"This marks the label refered by command \"ignoreto\".";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -1500,7 +1522,7 @@ class Upload: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <selector> -> <filename>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Presses the specified file upload button and passes a given file "
|
||||
"name. The command requires a CSS selector followed by a filename. "
|
||||
"The first object that matches the selector is used.";
|
||||
@@ -1554,7 +1576,7 @@ class Exists: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <selector> -> <text>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Assert that a certain text exists in the selected object, or if no "
|
||||
"text is given, assert that the specified object exists. The object "
|
||||
"is given by a CSS selector. All matching objects are search for the "
|
||||
@@ -1610,7 +1632,7 @@ class Not: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <selector> -> <text>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Assert that a certain text does not exists in the selected object, "
|
||||
"or if no text is given, assert that the specified object does not "
|
||||
"exists. The object is given by a CSS selector. All matching objects "
|
||||
@@ -1659,7 +1681,7 @@ class Execute: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <command>\n <line1>\n <line2>\n <...>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Execute <command>. The command can have space separated arguments. "
|
||||
"Following lines that are intended by at least "
|
||||
"one space are streamed into the command. This way, you can e.g. "
|
||||
@@ -1726,7 +1748,7 @@ class Download: public Command {
|
||||
return
|
||||
tag()+" <filename>\n"
|
||||
" <command-to-start-download>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Set download file before loading a download link or clicking on a "
|
||||
"download button. The next line must be exactly one command that "
|
||||
"initiates the download.\n\n"
|
||||
@@ -1807,7 +1829,7 @@ class Click: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" [<clicktype>] <selector>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Click on the specified element. Either you explicitely specify a click"
|
||||
" type, such as <realmouse> or <javascript>, or the previously set or"
|
||||
" the default clicktype is used.";
|
||||
@@ -1861,10 +1883,10 @@ class Set: public Command {
|
||||
}
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <variable>=<value>\n"+
|
||||
tag()+" <variable>=<value>\n\n"+
|
||||
tag()+" <variable>\n"
|
||||
" <command>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Sets the value of a variable either to a constant, or to the output"
|
||||
" of a command. A command should be a command that produces an"
|
||||
" output, such as <do>, which returns the result of JavaScript or"
|
||||
@@ -1920,7 +1942,7 @@ class UnSet: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <variable>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Undo the setting of a variable. The opposite of «set».";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -1949,7 +1971,7 @@ class Timeout: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <seconds>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Set the timeout in seconds (defaults to 10).";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -1982,7 +2004,7 @@ class CaCertificate: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <filename.pem>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Load a CA certificate that will be accepted on SSL connections.";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -2018,7 +2040,7 @@ class ClientCertificate: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <certfile.pem> <keyfile.pem> <keypassword>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Load a client certificate to authenticate on SSL connections. "
|
||||
"The password for the keyfile should not contain spaces. "
|
||||
"Create the two files from a PKCS#12 file using OpenSSL:\n"
|
||||
@@ -2078,7 +2100,7 @@ class ClickType: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <type>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Set how mouseclicks should be mapped. The best solution depends on"
|
||||
" your problem. Normally it is good to call \"click()\" on the element"
|
||||
" using javascript. But with complex javascript infected websites, it"
|
||||
@@ -2122,9 +2144,9 @@ class SetValue: public Command {
|
||||
}
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <selector> -> '<value>'\n"+
|
||||
tag()+" <selector> -> '<value>'\n\n"+
|
||||
tag()+" <selector> -> '<value1>', '<value2>', <...>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Set the selected element to a given value. It is mostly the same as"
|
||||
" the following constuct, except that options in a select are evaluated"
|
||||
" correctly:\n\n"
|
||||
@@ -2191,7 +2213,7 @@ class Function: public CommandContainer {
|
||||
" <command1>\n"
|
||||
" <command2>\n"
|
||||
" <...>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Define a function with arguments. The arguments are treated like"
|
||||
" local variables. In a sequence of scripts within the same testrun,"
|
||||
" functions are inherited from all followin scripts, so you can first"
|
||||
@@ -2241,7 +2263,7 @@ class Call: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <name> ['<arg1>', '<arg2>', ...]"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Calls a function. The number of arguments must be exactly the same"
|
||||
" as in the function definition.\n\n"
|
||||
"If you quote the values, then quote all values with the same"
|
||||
@@ -2296,7 +2318,7 @@ class If: public CommandContainer {
|
||||
" <command3>\n"
|
||||
" <command4>\n"
|
||||
" <...>\n"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Execute commands conditionally. "
|
||||
"The first variant compares a variable to a value. "
|
||||
"The comparision <cmp> can be = ! . ^ ~ < >, "
|
||||
@@ -2408,7 +2430,7 @@ class While: public CommandContainer {
|
||||
" <command1>\n"
|
||||
" <command2>\n"
|
||||
" <...>\n"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Repeats commands conditionally. "
|
||||
"The first variant compares a variable to a value. "
|
||||
"The comparision <cmp> can be = ! . ^ ~ < >, "
|
||||
@@ -2501,7 +2523,7 @@ class TestSuite: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <name>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Start a testsuite and give it a name.";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -2530,7 +2552,7 @@ class TestCase: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <name>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Start a testcase and give it a name.";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -2558,10 +2580,10 @@ class Check: public Command {
|
||||
}
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <value1> <cmp> <value2>\n"+
|
||||
tag()+" <value1> <cmp> <value2>\n\n"+
|
||||
tag()+" <value1> <cmp>\n"
|
||||
" <command>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Compares two values (you can use variables) or compares a value to the"
|
||||
" result of a command. The command should be a command that produces an"
|
||||
" output, such as <do>, which returns the result of JavaScript or"
|
||||
@@ -2644,7 +2666,7 @@ class For: public CommandContainer {
|
||||
" <command1>\n"
|
||||
" <command2>\n"
|
||||
" <...>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Executes the given commands with the variable set to the specifier values,"
|
||||
"repeated once per given value. The variable is treated like a local variale"
|
||||
" in the loop.\n\n"
|
||||
@@ -2696,7 +2718,7 @@ class Echo: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <text>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Echoes a text to the log.";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -2725,7 +2747,7 @@ class OfflineStoragePath: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <path>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Set offline storage path. Defaults to /tmp.";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -2758,7 +2780,7 @@ class ClearCookies: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <url>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Clear all cookies of given URL <url>, or of the current URL if no"
|
||||
" <url> is specified.";
|
||||
}
|
||||
@@ -2794,7 +2816,7 @@ class Include: public CommandContainer {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <filename>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Include a test script.";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -2861,7 +2883,7 @@ class Case: public Command {
|
||||
" <command>\n"
|
||||
" <command>\n"
|
||||
" <...>\n"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Execute commands conditionally depending on a variable. "
|
||||
"It is equivalent to neested if-else-if commands."
|
||||
"The first variant compares a variable to a value. "
|
||||
@@ -2981,7 +3003,7 @@ class Fail: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <text>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Fail with error text.";
|
||||
}
|
||||
QString command() const {
|
||||
@@ -3012,7 +3034,7 @@ class Auth: public Command {
|
||||
tag()+" <realm> <username> <password>"
|
||||
"\n\n"+
|
||||
tag()+" <realm>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Set basic authentication credentials for <realm> to"
|
||||
" <username> and <password>. If no realm is given,"
|
||||
" the credentials for the given realm are removed.";
|
||||
@@ -3054,7 +3076,7 @@ class Ignore: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <signal1> <signal2> <...>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Ignores a specific signal. It will not be placed in the queue "
|
||||
"and any expect for this signal is always true. You can call "
|
||||
"ignore with a space separated list of signal names. You cannot "
|
||||
@@ -3086,7 +3108,7 @@ class UnIgnore: public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+" <signal1> <signal2> <...>"
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"Undo ignoring a specific signal. It will be placed in the queue "
|
||||
"and any expect this signal checks the queue. You can call "
|
||||
"unignore with a space separated list of signal names. You cannot "
|
||||
@@ -3119,7 +3141,7 @@ class : public Command {
|
||||
QString description() const {
|
||||
return
|
||||
tag()+
|
||||
"\n\n"
|
||||
"\n\n--\n\n"
|
||||
"";
|
||||
}
|
||||
QString command() const {
|
||||
|
@@ -76,6 +76,13 @@ class CodeEditor: public QPlainTextEdit {
|
||||
Q_SIGNALS:
|
||||
void include(QString);
|
||||
void link(QString);
|
||||
public Q_SLOTS:
|
||||
void gotoLine(int line) {
|
||||
if (textCursor().blockNumber()==line-1) return;
|
||||
QTextCursor cursor(document()->findBlockByNumber(line-1));
|
||||
setTextCursor(cursor);
|
||||
highlightCurrentLine();
|
||||
}
|
||||
public:
|
||||
CodeEditor(QWidget *parent = 0): QPlainTextEdit(parent) {
|
||||
Highlighter *highlighter(new Highlighter(document()));
|
||||
@@ -87,11 +94,6 @@ class CodeEditor: public QPlainTextEdit {
|
||||
updateLineNumberAreaWidth(0);
|
||||
highlightCurrentLine();
|
||||
}
|
||||
void gotoLine(int line) {
|
||||
QTextCursor cursor(document()->findBlockByNumber(line-1));
|
||||
setTextCursor(cursor);
|
||||
highlightCurrentLine();
|
||||
}
|
||||
void lineNumberAreaPaintEvent(QPaintEvent *event) {
|
||||
QPainter painter(lineNumberArea);
|
||||
painter.fillRect(event->rect(), Qt::lightGray);
|
||||
|
54
src/help.hxx
Normal file
54
src/help.hxx
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef __HELP__HXX
|
||||
#define __HELP__HXX
|
||||
|
||||
#include <ui_help.hxx>
|
||||
#include <commands.hxx>
|
||||
#include <cassert>
|
||||
|
||||
class Help: public QDockWidget, protected Ui::Help {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Help(QWidget* p = nullptr): QDockWidget(p) {
|
||||
setupUi(this);
|
||||
_search->hide();
|
||||
_help->setText(script.commands(Script::HTML));
|
||||
}
|
||||
public Q_SLOTS:
|
||||
void on__search_textEdited(const QString& txt) {
|
||||
_help->moveCursor(QTextCursor::Start);
|
||||
if (script.prototypes().count(txt))
|
||||
_help->scrollToAnchor(txt);
|
||||
else
|
||||
_help->find(txt);
|
||||
}
|
||||
void on__search_returnPressed() {
|
||||
next();
|
||||
}
|
||||
void next() {
|
||||
_help->find(_search->text());
|
||||
}
|
||||
void previous() {
|
||||
_help->find(_search->text(), QTextDocument::FindBackward);
|
||||
}
|
||||
void startSearch() {
|
||||
_search->show();
|
||||
_search->setFocus();
|
||||
_search->selectAll();
|
||||
}
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *e) {
|
||||
if (e->matches(QKeySequence::Find))
|
||||
startSearch();
|
||||
if (e->matches(QKeySequence::FindNext))
|
||||
next();
|
||||
if (e->matches(QKeySequence::FindPrevious))
|
||||
previous();
|
||||
if (e->matches(QKeySequence::Cancel))
|
||||
_search->hide();
|
||||
return QDockWidget::keyPressEvent(e);
|
||||
}
|
||||
private:
|
||||
const Script script;
|
||||
};
|
||||
|
||||
#endif
|
36
src/help.ui
Normal file
36
src/help.ui
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Help</class>
|
||||
<widget class="QDockWidget" name="Help">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Help?!?</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="_help">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="_search"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@@ -8,9 +8,10 @@
|
||||
|
||||
bin_PROGRAMS = webtester webrunner
|
||||
|
||||
webtester_MOCFILES = moc_testgui.cxx moc_scriptfile.cxx moc_commands.cxx moc_webpage.cxx \
|
||||
webtester_MOCFILES = moc_testgui.cxx moc_scriptfile.cxx moc_help.cxx \
|
||||
moc_commands.cxx moc_webpage.cxx \
|
||||
moc_networkaccessmanager.cxx moc_editor.cxx
|
||||
webtester_UIFILES = ui_testgui.hxx ui_scriptfile.hxx
|
||||
webtester_UIFILES = ui_testgui.hxx ui_scriptfile.hxx ui_help.hxx
|
||||
webtester_SOURCES = version.cxx webtester.cxx exceptions.hxx version.hxx \
|
||||
${webtester_MOCFILES} ${webtester_UIFILES}
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
#include <ui_scriptfile.hxx>
|
||||
#include <QMessageBox>
|
||||
#include <QScrollBar>
|
||||
#include <QShortcut>
|
||||
#include <QTextDocumentFragment>
|
||||
#include <cassert>
|
||||
|
||||
@@ -16,17 +17,18 @@ class ScriptFile: public QDockWidget, protected Ui::ScriptFile {
|
||||
void include(QString);
|
||||
void close(ScriptFile*);
|
||||
void run(const QString&, const QString&, bool, Script&);
|
||||
void running(QString file, int line);
|
||||
void progress(QString, int, int, int);
|
||||
public:
|
||||
ScriptFile(QWidget* p = nullptr): QDockWidget(p) {
|
||||
ScriptFile(QWidget* p = nullptr, QString name = QString()): QDockWidget(p), _name(name) {
|
||||
setupUi(this);
|
||||
setWindowTitle(_name+"[*]");
|
||||
assert(connect(_editor, SIGNAL(textChanged()), SLOT(modified())));
|
||||
assert(connect(_editor, SIGNAL(include(QString)), SIGNAL(include(QString))));
|
||||
assert(connect(_editor, SIGNAL(link(QString)), SIGNAL(link(QString))));
|
||||
assert(connect(_editor, SIGNAL(cursorPositionChanged()), SLOT(setLine())));
|
||||
assert(connect(_line, SIGNAL(valueChanged(int)), SLOT(gotoLine(int))));
|
||||
_searchBar->hide();
|
||||
_replaceBar->hide();
|
||||
_lineBar->hide();
|
||||
_progress->hide();
|
||||
_status->setCurrentIndex(STATUS_NONE);
|
||||
}
|
||||
CodeEditor* editor() {
|
||||
@@ -40,10 +42,14 @@ class ScriptFile: public QDockWidget, protected Ui::ScriptFile {
|
||||
setWindowTitle(name+"[*]");
|
||||
setWindowModified(false);
|
||||
}
|
||||
public Q_SLOTS:
|
||||
void setLine() {
|
||||
int pos(_editor->textCursor().blockNumber()+1);
|
||||
if (pos) _line->setValue(pos);
|
||||
}
|
||||
void gotoLine(int line) {
|
||||
_editor->gotoLine(line);
|
||||
}
|
||||
public Q_SLOTS:
|
||||
void load(QString name = QString()) {
|
||||
if (isWindowModified() &&
|
||||
QMessageBox::question(this, tr("Changes Not Saved"),
|
||||
@@ -108,8 +114,6 @@ class ScriptFile: public QDockWidget, protected Ui::ScriptFile {
|
||||
modified(this);
|
||||
}
|
||||
void run() {
|
||||
_progress->reset();
|
||||
_progress->show();
|
||||
_status->setCurrentIndex(STATUS_RUNNING);
|
||||
bool oldRecordState(_record->isChecked());
|
||||
_record->setChecked(false);
|
||||
@@ -118,9 +122,7 @@ class ScriptFile: public QDockWidget, protected Ui::ScriptFile {
|
||||
Script script;
|
||||
try {
|
||||
assert(connect(&script, SIGNAL(progress(QString, int, int, int)),
|
||||
SLOT(progress(QString, int, int, int))));
|
||||
assert(connect(&script, SIGNAL(progress(QString, int, int, int)),
|
||||
SIGNAL(running(QString, int))));
|
||||
SIGNAL(progress(QString, int, int, int))));
|
||||
QString text(_editor->textCursor().selection().toPlainText());
|
||||
if (text.isEmpty()) text = _editor->toPlainText();
|
||||
run(_name, text, _screenshots->isChecked(), script);
|
||||
@@ -158,7 +160,6 @@ class ScriptFile: public QDockWidget, protected Ui::ScriptFile {
|
||||
_run->setEnabled(true);
|
||||
_record->setEnabled(true);
|
||||
_record->setChecked(oldRecordState);
|
||||
_progress->hide();
|
||||
}
|
||||
void appendCommand(const QString& txt) {
|
||||
if (!_record->isChecked()) return;
|
||||
@@ -225,22 +226,69 @@ class ScriptFile: public QDockWidget, protected Ui::ScriptFile {
|
||||
_editor->moveCursor(QTextCursor::End);
|
||||
_editor->ensureCursorVisible();
|
||||
}
|
||||
void progress(const QString& file, int line, int pos, int max) {
|
||||
_progress->setFormat(QString("%1:%2 — %p%").arg(file).arg(line));
|
||||
_progress->setMinimum(0);
|
||||
_progress->setMaximum(max);
|
||||
_progress->setValue(pos);
|
||||
}
|
||||
void runEnabled(bool f = true) {
|
||||
_run->setEnabled(false);
|
||||
_run->setEnabled(f);
|
||||
}
|
||||
void on__run_clicked() {
|
||||
run();
|
||||
}
|
||||
void on__from_textEdited(const QString& txt) {
|
||||
on__next_clicked();
|
||||
}
|
||||
void on__next_clicked() {
|
||||
if (_regex->isChecked())
|
||||
_editor->find(QRegExp(_from->text()));
|
||||
else
|
||||
_editor->find(_from->text());
|
||||
}
|
||||
void on__previous_clicked() {
|
||||
if (_regex->isChecked())
|
||||
_editor->find(QRegExp(_from->text()), QTextDocument::FindBackward);
|
||||
else
|
||||
_editor->find(_from->text(), QTextDocument::FindBackward);
|
||||
}
|
||||
void on__replace_clicked() {
|
||||
QTextCursor tc(_editor->textCursor());
|
||||
if (tc.hasSelection()) tc.insertText(_to->text());
|
||||
}
|
||||
void on__replaceAll_clicked() {
|
||||
QTextCursor cursor(_editor->textCursor());
|
||||
if (_regex->isChecked())
|
||||
_editor->setPlainText(_editor->toPlainText().replace(QRegExp(_from->text()), _to->text()));
|
||||
else
|
||||
_editor->setPlainText(_editor->toPlainText().replace(_from->text(), _to->text()));
|
||||
_editor->setTextCursor(cursor);
|
||||
}
|
||||
void startSearch() {
|
||||
_searchBar->show();
|
||||
_from->setFocus();
|
||||
_from->selectAll();
|
||||
}
|
||||
void startReplace() {
|
||||
_searchBar->show();
|
||||
_replaceBar->show();
|
||||
_to->setFocus();
|
||||
_to->selectAll();
|
||||
}
|
||||
protected:
|
||||
void closeEvent(QCloseEvent*) {
|
||||
close(this);
|
||||
}
|
||||
void keyPressEvent(QKeyEvent *e) {
|
||||
if (e->matches(QKeySequence::Find))
|
||||
startSearch();
|
||||
if (e->matches(QKeySequence::Replace))
|
||||
startReplace();
|
||||
if (e->matches(QKeySequence::FindNext))
|
||||
on__next_clicked();
|
||||
if (e->matches(QKeySequence::FindPrevious))
|
||||
on__previous_clicked();
|
||||
if (e->matches(QKeySequence::Cancel)) {
|
||||
_searchBar->hide();
|
||||
_replaceBar->hide();
|
||||
}
|
||||
return QDockWidget::keyPressEvent(e);
|
||||
}
|
||||
private:
|
||||
enum RunStatus {
|
||||
STATUS_NONE = 0,
|
||||
|
@@ -133,6 +133,13 @@
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="_line">
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -158,9 +165,9 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="_all">
|
||||
<widget class="QCheckBox" name="_regex">
|
||||
<property name="text">
|
||||
<string>all</string>
|
||||
<string>RegularExpression</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -181,38 +188,15 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="_regex">
|
||||
<widget class="QPushButton" name="_replaceAll">
|
||||
<property name="text">
|
||||
<string>RegularExpression</string>
|
||||
<string>replace all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="_lineBar" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="_line"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="_goLine">
|
||||
<property name="text">
|
||||
<string>line</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="_progress">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
@@ -224,5 +208,38 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>_from</sender>
|
||||
<signal>returnPressed()</signal>
|
||||
<receiver>_next</receiver>
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>259</x>
|
||||
<y>496</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>303</x>
|
||||
<y>505</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>_to</sender>
|
||||
<signal>returnPressed()</signal>
|
||||
<receiver>_replace</receiver>
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>564</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>562</x>
|
||||
<y>558</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <QScrollBar>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QShortcut>
|
||||
#include <QCompleter>
|
||||
#include <ui_testgui.hxx>
|
||||
#include <stdexcept>
|
||||
@@ -42,14 +43,16 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
setDockOptions(dockOptions()|QMainWindow::GroupedDragging);
|
||||
#endif
|
||||
menuViews->addAction(_setupScriptDock->toggleViewAction());
|
||||
menuViews->addAction(_scriptCommandsDock->toggleViewAction());
|
||||
menuViews->addAction(_helpDock->toggleViewAction());
|
||||
menuViews->addAction(_domDock->toggleViewAction());
|
||||
menuViews->addAction(_linksDock->toggleViewAction());
|
||||
menuViews->addAction(_formsDock->toggleViewAction());
|
||||
menuViews->addAction(_logDock->toggleViewAction());
|
||||
menuViews->addAction(_sourceDock->toggleViewAction());
|
||||
menuViews->addAction(_executeDock->toggleViewAction());
|
||||
|
||||
menuHelp->addAction(_helpDock->toggleViewAction());
|
||||
statusbar->addPermanentWidget(_progress = new QProgressBar(), 1);
|
||||
_progress->hide();
|
||||
QSettings settings("mrw", "webtester");
|
||||
restoreGeometry(settings.value("geometry").toByteArray());
|
||||
restoreState(settings.value("windowstate").toByteArray());
|
||||
@@ -64,7 +67,6 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
_web->setPage(pg);
|
||||
_web->installEventFilter(this); // track mouse and keyboard
|
||||
pg->setForwardUnsupportedContent(true);
|
||||
_commands->setText(Script().commands(Script::HTML));
|
||||
assert(connect(menuFile, SIGNAL(aboutToShow()), SLOT(fileMenuOpened())));
|
||||
assert(connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)),
|
||||
SLOT(focusChanged(QWidget*, QWidget*))));
|
||||
@@ -89,6 +91,26 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
enterText(true);
|
||||
_web->stop();
|
||||
}
|
||||
void on__actionAbout_triggered() {
|
||||
QMessageBox::about(this, tr("About"),
|
||||
tr("Webtester\n"
|
||||
"Version: %1\n"
|
||||
"Builddate: %2\n"
|
||||
"Release: %3\n"
|
||||
"Libraries:\n"
|
||||
"qt-%4 (%5)\n")
|
||||
.arg(VERSION)
|
||||
.arg(BUILD_DATE)
|
||||
.arg(PACKAGE_VERSION)
|
||||
.arg(qVersion())
|
||||
.arg(QT_VERSION_STR));
|
||||
}
|
||||
void on__actionNew_triggered() {
|
||||
QString name(QFileDialog::getSaveFileName(this, tr("Filename for new Test Script")));
|
||||
QFileInfo info(name);
|
||||
if (info.absoluteDir()==QDir::current()) name = info.fileName();
|
||||
if (!name.isEmpty()) newScript(name);
|
||||
}
|
||||
void on__actionOpen_triggered() {
|
||||
QString name(QFileDialog::getOpenFileName(this, tr("Open Test Script")));
|
||||
if (name.isEmpty()) return;
|
||||
@@ -117,10 +139,6 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
ScriptFile* active(activeScriptFile());
|
||||
if (active) active->clear();
|
||||
}
|
||||
void on__actionRun_triggered() {
|
||||
ScriptFile* active(activeScriptFile());
|
||||
if (active) active->run();
|
||||
}
|
||||
void on__focused_clicked() {
|
||||
enterText(true);
|
||||
QWebElement element(focused());
|
||||
@@ -239,7 +257,6 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
_actionSaveAs->setEnabled(active);
|
||||
_actionSave->setEnabled(active&&active->isWindowModified());
|
||||
_actionClear->setEnabled(active);
|
||||
_actionRun->setEnabled(active);
|
||||
}
|
||||
QString activate(QString name) {
|
||||
QFileInfo info(name);
|
||||
@@ -247,7 +264,6 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
if (!_testscripts.contains(name)) return load(name);
|
||||
_testscripts[name]->show();
|
||||
_testscripts[name]->raise();
|
||||
_testscripts[name]->activateWindow();
|
||||
return name;
|
||||
}
|
||||
QString load(QString name) {
|
||||
@@ -259,24 +275,29 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
} catch(const std::exception& x) {
|
||||
remove(_testscripts[name]);
|
||||
}
|
||||
QDockWidget* first(_testscripts.isEmpty()?_setupScriptDock:_testscripts.last());
|
||||
_testscripts[name] = new ScriptFile(this);
|
||||
assert(connect(_testscripts[name], SIGNAL(modified(ScriptFile*)), SLOT(modified(ScriptFile*))));
|
||||
assert(connect(_testscripts[name], SIGNAL(link(QString)), SLOT(activate(QString))));
|
||||
assert(connect(_testscripts[name], SIGNAL(close(ScriptFile*)), SLOT(remove(ScriptFile*))));
|
||||
assert(connect(_testscripts[name], SIGNAL(run(const QString&, const QString&, bool, Script&)),
|
||||
SLOT(run(const QString&, const QString&, bool, Script&))));
|
||||
assert(connect(_testscripts[name], SIGNAL(running(QString, int)),
|
||||
SLOT(showFileLine(QString, int))));
|
||||
newScript(name);
|
||||
try {
|
||||
_testscripts[name]->load(name);
|
||||
tabifyDockWidget(first, _testscripts[name]);
|
||||
return activate(name);
|
||||
} catch(const std::exception& x) {
|
||||
remove(_testscripts[name]);
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
QString newScript(QString name) {
|
||||
if (_testscripts.contains(name)) return activate(name);
|
||||
QDockWidget* first(_testscripts.isEmpty()?_setupScriptDock:_testscripts.last());
|
||||
_testscripts[name] = new ScriptFile(this, name);
|
||||
assert(connect(_testscripts[name], SIGNAL(modified(ScriptFile*)), SLOT(modified(ScriptFile*))));
|
||||
assert(connect(_testscripts[name], SIGNAL(link(QString)), SLOT(activate(QString))));
|
||||
assert(connect(_testscripts[name], SIGNAL(close(ScriptFile*)), SLOT(remove(ScriptFile*))));
|
||||
assert(connect(_testscripts[name], SIGNAL(run(const QString&, const QString&, bool, Script&)),
|
||||
SLOT(run(const QString&, const QString&, bool, Script&))));
|
||||
assert(connect(_testscripts[name], SIGNAL(progress(QString, int, int, int)),
|
||||
SLOT(progress(QString, int, int, int))));
|
||||
tabifyDockWidget(first, _testscripts[name]);
|
||||
return name;
|
||||
}
|
||||
void remove(ScriptFile* scriptfile) {
|
||||
/// @todo check if modified
|
||||
_testscripts.remove(scriptfile->name());
|
||||
@@ -294,7 +315,12 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
script.parse(text.split('\n'), name);
|
||||
script.run(_web->page()->mainFrame(), testsuites, QString(), screenshots);
|
||||
}
|
||||
void showFileLine(QString file, int line) {
|
||||
void progress(QString file, int line, int pos, int max) {
|
||||
_progress->setVisible(max>0&&pos!=max);
|
||||
_progress->setFormat(QString("%1:%2 — %p%").arg(file).arg(line));
|
||||
_progress->setMinimum(0);
|
||||
_progress->setMaximum(max);
|
||||
_progress->setValue(pos);
|
||||
if (!_actionCursorFollowsFiles->isChecked() || file.isEmpty() || file=="setup") return;
|
||||
try {
|
||||
QString name(activate(file));
|
||||
@@ -304,10 +330,9 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
}
|
||||
protected:
|
||||
ScriptFile* activeScriptFile(QWidget* focus=nullptr) {
|
||||
//for (auto win: _testscripts) if (win->isActiveWindow()) return win;
|
||||
ScriptFile* active(nullptr);
|
||||
for (QObject* wid(focus?focus:QApplication::focusWidget()); !active && wid; wid = wid->parent())
|
||||
active = dynamic_cast<ScriptFile*>(wid);
|
||||
active = qobject_cast<ScriptFile*>(wid);
|
||||
return active;
|
||||
}
|
||||
void closeEvent(QCloseEvent* event) {
|
||||
@@ -324,7 +349,7 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
}
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
bool eventFilter(QObject*, QEvent* event) {
|
||||
bool eventFilter(QObject* target, QEvent* event) {
|
||||
if (_inEventFilter) return false;
|
||||
_inEventFilter = true;
|
||||
enterText();
|
||||
@@ -829,6 +854,7 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI {
|
||||
bool _inEventFilter; // actually handling event filter
|
||||
Script _setupScript;
|
||||
QMap<QString, ScriptFile*> _testscripts;
|
||||
QProgressBar* _progress = nullptr;
|
||||
};
|
||||
|
||||
#endif // TESTGUI_HXX
|
||||
|
129
src/testgui.ui
129
src/testgui.ui
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>888</width>
|
||||
<height>1180</height>
|
||||
<width>852</width>
|
||||
<height>759</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
@@ -103,7 +103,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>888</width>
|
||||
<width>852</width>
|
||||
<height>34</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -116,6 +116,7 @@
|
||||
<property name="title">
|
||||
<string>F&ile</string>
|
||||
</property>
|
||||
<addaction name="_actionNew"/>
|
||||
<addaction name="_actionOpen"/>
|
||||
<addaction name="_actionOpenSetupScript"/>
|
||||
<addaction name="separator"/>
|
||||
@@ -123,15 +124,14 @@
|
||||
<addaction name="_actionSaveAs"/>
|
||||
<addaction name="_actionRevertToSaved"/>
|
||||
<addaction name="_actionClear"/>
|
||||
<addaction name="_actionRun"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="_actionQuit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuHelp">
|
||||
<property name="title">
|
||||
<string>Help</string>
|
||||
<string>&Help</string>
|
||||
</property>
|
||||
<addaction name="_actionCommands"/>
|
||||
<addaction name="_actionAbout"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuOptions">
|
||||
<property name="title">
|
||||
@@ -254,7 +254,7 @@
|
||||
<string>Execute &JavaScript on First Selected Item</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>8</number>
|
||||
<number>1</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents_10">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
@@ -476,24 +476,13 @@ this.dispatchEvent(evObj);</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="_scriptCommandsDock">
|
||||
<widget class="Help" name="_helpDock">
|
||||
<property name="windowTitle">
|
||||
<string>Script &Commands</string>
|
||||
<string>&Help</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>4</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents_3">
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextBrowser" name="_commands">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<action name="_actionDOMTree">
|
||||
<property name="checkable">
|
||||
@@ -588,17 +577,6 @@ this.dispatchEvent(evObj);</string>
|
||||
<string>Ctrl+Q</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="_actionRun">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Run</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+R</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="_actionRunLine">
|
||||
<property name="text">
|
||||
<string>Run &Line</string>
|
||||
@@ -650,9 +628,9 @@ this.dispatchEvent(evObj);</string>
|
||||
<string>O&pen Setup Script ...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="_actionCommands">
|
||||
<action name="_actionAbout">
|
||||
<property name="text">
|
||||
<string>&Commands ...</string>
|
||||
<string>&About</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="_actionCursorFollowsFiles">
|
||||
@@ -663,12 +641,17 @@ this.dispatchEvent(evObj);</string>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cursor Follows Files</string>
|
||||
<string>&Cursor Follows Files</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>When running a script, the currently running file and line is highlighted. So the cursor follows the current file and line when running a script.</p></body></html></string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="_actionNew">
|
||||
<property name="text">
|
||||
<string>&New ...</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
@@ -681,12 +664,20 @@ this.dispatchEvent(evObj);</string>
|
||||
<extends>QPlainTextEdit</extends>
|
||||
<header>editor.hxx</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>Help</class>
|
||||
<extends>QDockWidget</extends>
|
||||
<header>help.hxx</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>_load</tabstop>
|
||||
<tabstop>_web</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<resources>
|
||||
<include location="ressourcen.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>_selector</sender>
|
||||
@@ -695,12 +686,12 @@ this.dispatchEvent(evObj);</string>
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>785</x>
|
||||
<y>1144</y>
|
||||
<x>267</x>
|
||||
<y>589</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>875</x>
|
||||
<y>1075</y>
|
||||
<x>360</x>
|
||||
<y>496</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@@ -711,12 +702,12 @@ this.dispatchEvent(evObj);</string>
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>785</x>
|
||||
<y>1144</y>
|
||||
<x>267</x>
|
||||
<y>589</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>874</x>
|
||||
<y>1144</y>
|
||||
<x>359</x>
|
||||
<y>589</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@@ -731,8 +722,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>630</x>
|
||||
<y>971</y>
|
||||
<x>369</x>
|
||||
<y>599</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@@ -743,8 +734,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<slot>setChecked(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>630</x>
|
||||
<y>971</y>
|
||||
<x>369</x>
|
||||
<y>599</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
@@ -763,8 +754,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>748</x>
|
||||
<y>374</y>
|
||||
<x>851</x>
|
||||
<y>337</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@@ -775,8 +766,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<slot>setChecked(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>748</x>
|
||||
<y>374</y>
|
||||
<x>851</x>
|
||||
<y>337</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
@@ -795,8 +786,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>748</x>
|
||||
<y>537</y>
|
||||
<x>851</x>
|
||||
<y>468</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@@ -807,8 +798,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<slot>setChecked(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>748</x>
|
||||
<y>537</y>
|
||||
<x>851</x>
|
||||
<y>468</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
@@ -827,8 +818,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>748</x>
|
||||
<y>699</y>
|
||||
<x>851</x>
|
||||
<y>599</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@@ -839,8 +830,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<slot>setChecked(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>748</x>
|
||||
<y>699</y>
|
||||
<x>851</x>
|
||||
<y>599</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
@@ -860,7 +851,7 @@ this.dispatchEvent(evObj);</string>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>182</x>
|
||||
<y>971</y>
|
||||
<y>730</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@@ -872,7 +863,7 @@ this.dispatchEvent(evObj);</string>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>182</x>
|
||||
<y>971</y>
|
||||
<y>730</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
@@ -891,8 +882,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>842</x>
|
||||
<y>1004</y>
|
||||
<x>851</x>
|
||||
<y>730</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@@ -903,8 +894,8 @@ this.dispatchEvent(evObj);</string>
|
||||
<slot>setChecked(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>842</x>
|
||||
<y>1004</y>
|
||||
<x>851</x>
|
||||
<y>730</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>-1</x>
|
||||
@@ -935,12 +926,12 @@ this.dispatchEvent(evObj);</string>
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>277</x>
|
||||
<y>315</y>
|
||||
<x>513</x>
|
||||
<y>257</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>549</x>
|
||||
<y>315</y>
|
||||
<x>603</x>
|
||||
<y>258</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
Reference in New Issue
Block a user