/*! @file @id $Id$ */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 #ifndef TESTGUI_HXX #define TESTGUI_HXX #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class TestGUI: public QMainWindow, protected Ui::TestGUI { Q_OBJECT; public: explicit TestGUI(QWidget *parent = 0, QString url = QString(), QString setupScript = QString(), QString scriptFile = QString()): QMainWindow(parent), _typing(false), _inEventFilter(false) { setupUi(this); QSettings settings("mrw", "webtester"); restoreGeometry(settings.value("geometry").toByteArray()); restoreState(settings.value("windowstate").toByteArray()); if (!url.isEmpty()) { _url->setText(url); } TestWebPage* page(new TestWebPage(_web)); _web->setPage(page); _web->installEventFilter(this); // track mouse and keyboard page->setForwardUnsupportedContent(true); _commands->setText(Script().commands(Script::HTML)); connect(page, SIGNAL(uploadFile(QString)), SLOT(uploadFile(QString))); connect(page, SIGNAL(unsupportedContent(QNetworkReply*)), SLOT(unsupportedContent(QNetworkReply*))); connect(page, SIGNAL(downloadRequested(const QNetworkRequest&)), SLOT(downloadRequested(const QNetworkRequest&))); if (setupScript.size()) loadSetup(setupScript); if (scriptFile.size()) loadFile(scriptFile); } virtual ~TestGUI() {} public Q_SLOTS: void on__load_clicked() { enterText(true); if (_record->isChecked()) appendCommand("load "+map(_url->text())); _web->load(_url->text()); } void on__abort_clicked() { enterText(true); _web->stop(); } void on__actionOpen_triggered() { QString name(QFileDialog::getOpenFileName(this, tr("Open Test Script"))); if (name.isEmpty()) return; loadFile(name); } void on__actionOpenSetupScript_triggered() { QString name(QFileDialog::getOpenFileName(this, tr("Open Setup Script"))); if (name.isEmpty()) return; loadSetup(name); } void on__actionRevertToSaved_triggered() { loadFile(_filename); } void on__actionSaveAs_triggered() { QString name(QFileDialog::getSaveFileName(this, tr("Save Test Script"))); if (name.isEmpty()) return; _filename = name; on__actionSave_triggered(); } void on__actionSave_triggered() { QFile file(_filename); try { if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) throw std::runtime_error("file open failed"); QTextStream out(&file); out<<_testscript->toPlainText(); if (out.status()!=QTextStream::Ok) throw std::runtime_error(std::string("file write failed (") +char(out.status()+48)+")"); _actionSave->setEnabled(true); _actionRevertToSaved->setEnabled(true); } catch(const std::exception& x) { QMessageBox::critical(this, tr("Save Failed"), tr("Saving test script failed, %2. " "Cannot write test script to file %1.") .arg(_filename).arg(x.what())); } } void on__actionClear_triggered() { _testscript->clear(); _log->clear(); _filename.clear(); _actionSave->setEnabled(false); _actionRevertToSaved->setEnabled(false); } void on__run_clicked() { bool oldRecordState(_record->isChecked()); _record->setChecked(false); _record->setEnabled(false); _run->setEnabled(false); try { Script script; connect(&script, SIGNAL(logging(QString)), SLOT(logging(QString))); std::shared_ptr testsuites(new xml::Node("testsuite")); if (_setupscriptactive->isEnabled() && _setupscriptactive->isChecked()) { script.parse(_setupscript->toPlainText().split('\n'), "setup"); script.run(_web->page()->mainFrame(), testsuites, QString(), _screenshots->isChecked()); script.reset(); } QString text(_testscript->textCursor().selection().toPlainText()); if (text.isEmpty()) text = _testscript->toPlainText(); script.parse(text.split('\n'), "script"); script.run(_web->page()->mainFrame(), testsuites, QString(), _screenshots->isChecked()); } catch (std::exception &x) { QMessageBox::critical(this, tr("Script Failed"), tr("Script failed with message:\n%1") .arg(x.what())); } _run->setEnabled(true); _record->setEnabled(true); _record->setChecked(oldRecordState); } void on__focused_clicked() { enterText(true); QWebElement element(focused()); if (element.isNull()) return; highlight(element); _focusedText->setText(selector(element)); } void on__select_clicked() { enterText(true); highlight(_web->page()->mainFrame()->documentElement() .findFirst(_selector->text())); } void on__jsExecute_clicked() { enterText(true); _jsResult->setText(execute(selector(), _javascriptCode->toPlainText())); } void on__web_linkClicked(const QUrl& url) { enterText(true); if (_record->isChecked()) appendCommand("load "+map(url.url())); } void on__web_loadProgress(int progress) { enterText(true); _progress->setValue(progress); } void on__web_loadStarted() { enterText(true); if (_record->isChecked()) appendCommand("expect "+map("loadStarted")); _progress->setValue(0); _urlStack->setCurrentIndex(PROGRESS_VIEW); } void on__web_statusBarMessage(const QString&) { //std::cout<<"statusBarMessage: "<isChecked()) appendCommand("expect "+map("urlChanged "+url.url())); } void on__web_selectionChanged() { _source->setPlainText(_web->hasSelection() ? _web->selectedHtml() : _web->page()->mainFrame()->toHtml()); } void on__web_loadFinished(bool ok) { enterText(true); if (_record->isChecked()) { QString text(_testscript->toPlainText()); QStringList lines(text.split("\n")); if (ok && lines.size()>1 && lines.last().startsWith("expect urlChanged") && lines.at(lines.size()-2)=="expect loadStarted") { // replace three expect lines by one single line QString url(lines.last().replace("expect urlChanged", "").trimmed()); lines.removeLast(); lines.removeLast(); _testscript->setPlainText(lines.join("\n")); _testscript->moveCursor(QTextCursor::End); _testscript->ensureCursorVisible(); appendCommand("expect "+map("load "+url)); } else { appendCommand("expect "+map("loadFinished " +QString(ok?"true":"false"))); } } _urlStack->setCurrentIndex(URL_VIEW); on__web_selectionChanged(); setLinks(); setForms(); setDom(); } void on__setupscript_textChanged() { bool oldRecordState(_record->isChecked()); _run->setEnabled(false); _setupscriptactive->setEnabled(false); try { _setupscriptstatus->setText(trUtf8("?")); std::shared_ptr testsuites(new xml::Node("testsuite")); Script script; TestWebPage page(0, true); script.parse(_setupscript->toPlainText().split('\n'), "setup"); script.run(page.mainFrame(), testsuites, QString(), false); _setupScript.cleanup(); _setupScript.parse(_setupscript->toPlainText().split('\n'), "setup"); _setupScript.run(page.mainFrame(), testsuites, QString(), false); _setupscriptstatus->setText(trUtf8("✔")); _setupscriptactive->setEnabled(true); } catch (std::exception &x) { _setupscriptstatus->setText(trUtf8("✘")); } _run->setEnabled(true); _record->setChecked(oldRecordState); } void on__forms_currentItemChanged(QTreeWidgetItem* item, QTreeWidgetItem*) { if (!item) return; _source->setPlainText(item->data(0, Qt::UserRole).toString()); } void on__dom_currentItemChanged(QTreeWidgetItem* item, QTreeWidgetItem*) { if (!item) return; _source->setPlainText(item->data(0, Qt::UserRole).toString()); } void uploadFile(QString filename) { enterText(true); if (_record->isChecked()) appendCommand("upload "+map(filename)); } void unsupportedContent(QNetworkReply* reply) { if (!_record->isChecked()) return; QString filename(reply->url().toString().split('/').last()); if (reply->header(QNetworkRequest::ContentDispositionHeader).isValid()) { QString part(reply->header(QNetworkRequest::ContentDispositionHeader) .toString()); if (part.contains(QRegularExpression("attachment; *filename="))) { part.replace(QRegularExpression(".*attachment; *filename="), ""); if (part.size()) filename = part; } } QString text(_testscript->toPlainText()); int pos1(text.lastIndexOf(QRegularExpression("^do "))); int pos2(text.lastIndexOf(QRegularExpression("^load "))); int pos3(text.lastIndexOf(QRegularExpression("^click "))); text.insert(std::max({pos1, pos2, pos3}), "download "+filename); _testscript->setPlainText(text); _testscript->moveCursor(QTextCursor::End); _testscript->ensureCursorVisible(); } void downloadRequested(const QNetworkRequest&) { if (_record->isChecked()) appendCommand("download2"); } void logging(const QString& txt) { _log->appendPlainText(txt); QScrollBar *vb(_log->verticalScrollBar()); if (!vb) return; vb->setValue(vb->maximum()); } void appendCommand(const QString& txt) { _testscript->appendPlainText(txt); QScrollBar *vb(_testscript->verticalScrollBar()); _testscript->moveCursor(QTextCursor::End); _testscript->ensureCursorVisible(); if (!vb) return; vb->setValue(vb->maximum()); } protected: void closeEvent(QCloseEvent* event) { QSettings settings("mrw", "webtester"); settings.setValue("geometry", saveGeometry()); settings.setValue("windowstate", saveState()); QMainWindow::closeEvent(event); } bool eventFilter(QObject*, QEvent* event) { if (_inEventFilter) return false; _inEventFilter = true; enterText(); QWebElement element(focused(dynamic_cast(event))); switch (event->type()) { case QEvent::KeyPress: { QKeyEvent* k(dynamic_cast(event)); switch (k->key()) { case Qt::Key_Tab: case Qt::Key_Backtab: { enterText(true); } break; case Qt::Key_Backspace: { _keyStrokes.chop(1); } break; case Qt::Key_Shift: break; case Qt::Key_Enter: case Qt::Key_Return: { _keyStrokes += "\\n"; _lastFocused=element; _typing = true; } break; default: { _keyStrokes += k->text(); _lastFocused=element; _typing = true; } } } break; case QEvent::MouseButtonRelease: { enterText(true); _lastFocused=element; if (_record->isChecked()) { if (!element.isNull()) { QString selected(selector(element)); if (handleMooTools(_lastFocused)) { // handled in handleMooTools } else if (_lastFocused.tagName()=="SELECT") { // click on a select results in a value change // find all selected options ... QStringList v; Q_FOREACH(QWebElement option, _lastFocused.findAll("option")) { //! @bug QT does not support selected if (option.evaluateJavaScript("this.selected").toBool()) v += value(option); } setValue(selected, v); } else if (_lastFocused.tagName()=="TEXTAREA" || _lastFocused.tagName()=="INPUT" && _lastFocused.attribute("type")=="text") { // user clickt in a text edit field, so not the klick // is important, but the text that will be typed _typing = true; } else { if (_web->page()->selectedText() != "") // user has selected a text, append a check appendCommand("expect "+map(selected) +" -> "+_web->page()->selectedText()); else // user has clicked without selection, append a click appendCommand("click "+map(selected)); } } else { appendCommand("# click, but where?"); } } } break; case QEvent::MouseButtonPress: { } break; case QEvent::ChildRemoved: { // select option value changed enterText(true); _typing = true; _lastFocused=element; } break; case QEvent::InputMethodQuery: case QEvent::ToolTipChange: case QEvent::MouseMove: case QEvent::UpdateLater: case QEvent::Paint: break; default:; /* _log->appendPlainText(QString("Event: %1") .arg(eventName(event->type()))); */ } _inEventFilter = false; return false; } private: void loadFile(QString name) { QFile file(name); try { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) throw std::runtime_error("file open failed"); _testscript->setPlainText(QString::fromUtf8(file.readAll())); if (file.error()!=QFileDevice::NoError) throw std::runtime_error("file read failed"); _filename = name; _actionSave->setEnabled(true); _actionRevertToSaved->setEnabled(true); } catch(const std::exception& x) { QMessageBox::critical(this, tr("Open Failed"), tr("Reading test script failed, %2. " "Cannot read test script from file %1.") .arg(name).arg(x.what())); } } void loadSetup(QString name) { QFile file(name); try { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) throw std::runtime_error("file open failed"); _setupscript->setPlainText(QString::fromUtf8(file.readAll())); if (file.error()!=QFileDevice::NoError) throw std::runtime_error("file read failed"); on__setupscript_textChanged(); } catch(const std::exception& x) { QMessageBox::critical(this, tr("Open Failed"), tr("Reading test script failed, %2. " "Cannot read test script from file %1.") .arg(name).arg(x.what())); } } void enterText(bool force=false) { if (!force && (!_typing || _lastFocused==focused())) return; if (_typing && !_lastFocused.isNull()) setValue(selector(_lastFocused), value(_lastFocused)); _lastFocused = QWebElement(); _keyStrokes.clear(); _typing = false; } QWebElement selected() { return _web->page()->mainFrame()->documentElement().findFirst(selector()); } QString selector() { if (_takeFocused->isChecked()) return selector(focused()); else if (_takeSelect->isChecked()) return _selector->text(); else return QString(); // error } void highlight(QWebElement element) { element .evaluateJavaScript("var selection = window.getSelection();" "selection.setBaseAndExtent(this, 0, this, 1);"); } QWebElement focused(QMouseEvent* event = 0) { Q_FOREACH(QWebElement element, _web->page()->currentFrame()->findAllElements("*")) { if (element.hasFocus()) { return element; } } if (event) { // try to find element using mouse position QWebFrame* frame(_web->page()->frameAt(event->pos())); if (frame) { QWebHitTestResult hit(frame->hitTestContent(event->pos())); if (!hit.element().isNull()) return hit.element(); if (!hit.enclosingBlockElement().isNull()) return hit.enclosingBlockElement(); } } return QWebElement(); } bool unique(QString selector) { return _web->page()->mainFrame()->findAllElements(selector).count()==1; } QString quote(QString txt) { if (txt.contains('"')) return "'"+txt+"'"; return '"'+txt+'"'; } QString selector(const QWebElement& element) { if (element.isNull()) return QString(); if (element.hasAttribute("id") && unique("#"+element.attribute("id"))) { return "#"+element.attribute("id"); } else if (element.hasAttribute("name") && unique(element.tagName().toLower() +"[name="+quote(element.attribute("name"))+"]")) { return element.tagName().toLower() +"[name="+quote(element.attribute("name"))+"]"; } else { QString res; Q_FOREACH(QString attr, element.attributeNames()) { if (attr=="id") res = "#"+element.attribute("id")+res; else if (attr=="class") Q_FOREACH(QString c, element.attribute(attr).split(' ')) { if (!c.isEmpty()) res = '.'+c+res; } else if (element.attribute(attr).isEmpty()) res+="["+attr+"]"; else res+="["+attr+"="+quote(element.attribute(attr))+"]"; if (unique(element.tagName().toLower()+res)) return element.tagName().toLower()+res; } QString p(selector(element.parent())); if (unique(p+">"+element.tagName().toLower()+res)) return p+">"+element.tagName().toLower()+res; QString s(selector(element.previousSibling())); if (unique(s+"+"+element.tagName().toLower()+res)) return s+"+"+element.tagName().toLower()+res; if (!p.isEmpty()) return p+">"+element.tagName().toLower()+res; if (!s.isEmpty()) return s+"+"+element.tagName().toLower()+res; return element.tagName().toLower()+res; } } QString value(QWebElement element) { return element.evaluateJavaScript("this.value").toString(); //! @bug Bug in Qt, attribute("value") is always empty // if (element.hasAttribute("value")) // return element.attribute("value"); // else // return element.toPlainText(); } QString map(QString in) { if (_setupscriptactive->isEnabled() && _setupscriptactive->isChecked()) { return _setupScript.insertvars(in); } return in; } void javascript(const QString& selector, QString code) { if (_record->isChecked()) appendCommand("do "+map(selector)+"\n " +map(code).replace("\n", "\n ")); } void cleanup(const QString& selector) { QString text(_testscript->toPlainText()); QStringList lines(text.split("\n")); bool changed(false); while (lines.size() && (lines.last()=="click "+selector || lines.last().startsWith("setvalue "+selector+" -> "))) { lines.removeLast(); changed = true; } if (changed) { _testscript->setPlainText(lines.join("\n")); _testscript->moveCursor(QTextCursor::End); _testscript->ensureCursorVisible(); } } void setValue(const QString& selector, QString code) { if (_record->isChecked()) { cleanup(selector); appendCommand("setvalue "+map(selector)+" -> '" +map(code).replace("'", "\\'").replace("\n", "\\n")+"'"); } } void setValue(const QString& selector, QStringList code) { if (_record->isChecked()) { cleanup(selector); appendCommand("setvalue "+map(selector)+" -> '"+ map(code.replaceInStrings("'", "\\'") .replaceInStrings("\n", "\\n") .join("', '")+"'")); } } bool handleMooTools(QWebElement element) { QString selected(selector(element)); QRegularExpressionMatch mooCombo (QRegularExpression("^(#jform_[_A-Za-z0-9]+)_chzn>.*$") .match(selected)); QRegularExpressionMatch mooComboItem (QRegularExpression ("^li\\.highlighted(\\.result-selected)?\\.active-result$") .match(selected)); if (mooCombo.hasMatch()) { // special treatment for moo tools combobox (e.g. used // in joomla) appendCommand("click realmouse "+map(mooCombo.captured(1)+">a")); appendCommand("sleep "+map("1")); return true; } else if (mooComboItem.hasMatch()) { // special treatment for item in moo tools combobox appendCommand ("click realmouse "+map("li.active-result[data-option-array-index=\"" +element.attribute("data-option-array-index") +"\"]")); appendCommand("sleep "+map("1")); return true; } else if (element.tagName()=="INPUT") { for (QWebElement e(element); !(e=e.parent()).isNull();) if (e.hasClass("chzn-container")) { _lastFocused = e; appendCommand("# moo tools combobox with search field"); appendCommand("# first set all elements visible"); javascript(map(selector(e)+" ul"), "this.style.height = \"auto\";\n" "this.style.maxHeight = \"auto\";\n" "this.style.overflow = \"visible\""); appendCommand("sleep "+map("1")); appendCommand("# moo tools open combobox"); appendCommand("click realmouse "+map(selector(e))); return true; } } else if (element.hasAttribute("id") && // is it a selected option? element.attribute("id").contains("_chzn_o_")) { appendCommand("# moo tools select item"); appendCommand("click realmouse "+map(selector(element))); _lastFocused = element; return true; } return false; } QString execute(const QString& selector, const QString& code) { javascript(selector, code); return _web->page()->mainFrame()->documentElement().findFirst(selector) .evaluateJavaScript(code).toString(); } void setLinks() { QWebElementCollection links(_web->page()->mainFrame()->documentElement() .findAll("a")); _links->setRowCount(links.count()); for (int row(0); row<_links->rowCount(); ++row) { { QTableWidgetItem* item(new QTableWidgetItem()); item->setText(links[row].attribute("href")); _links->setItem(row, 0, item); } { QTableWidgetItem* item(new QTableWidgetItem()); item->setText(links[row].hasAttribute("title") ? links[row].attribute("title") : links[row].toInnerXml()); _links->setItem(row, 1, item); } _links->horizontalHeader()->resizeSections(QHeaderView::Stretch); } } void setForms() { QWebElementCollection forms(_web->page()->mainFrame()->documentElement() .findAll("form")); _forms->clear(); Q_FOREACH(const QWebElement &form, forms) { addDomElement(form, _forms->invisibleRootItem()); } } void setDom() { _dom->clear(); addDomElement(_web->page()->mainFrame()->documentElement(), _dom->invisibleRootItem()); } //void addDomChildren(const QWebElement&, QTreeWidgetItem*); void addDomElement(const QWebElement &element, QTreeWidgetItem *parent) { QTreeWidgetItem *item(new QTreeWidgetItem()); item->setText(0, element.tagName()); item->setData(0, Qt::UserRole, element.toOuterXml()); parent->addChild(item); addDomChildren(element, item); } void addDomChildren(const QWebElement &parentElement, QTreeWidgetItem *parentItem) { for (QWebElement element = parentElement.firstChild(); !element.isNull(); element = element.nextSibling()) { addDomElement(element, parentItem); } } QString eventName(QEvent::Type t) { switch (t) { case QEvent::None: return "QEvent::None - Not an event."; case QEvent::ActionAdded: return "QEvent::ActionAdded - A new action has been added (QActionEvent)."; case QEvent::ActionChanged: return "QEvent::ActionChanged - An action has been changed (QActionEvent)."; case QEvent::ActionRemoved: return "QEvent::ActionRemoved - An action has been removed (QActionEvent)."; case QEvent::ActivationChange: return "QEvent::ActivationChange - A widget's top-level window activation state has changed."; case QEvent::ApplicationActivate: return "QEvent::ApplicationActivate - This enum has been deprecated. Use ApplicationStateChange instead."; //case QEvent::ApplicationActivated: return "QEvent::ApplicationActivated - This enum has been deprecated. Use ApplicationStateChange instead."; case QEvent::ApplicationDeactivate: return "QEvent::ApplicationDeactivate - This enum has been deprecated. Use ApplicationStateChange instead."; case QEvent::ApplicationFontChange: return "QEvent::ApplicationFontChange - The default application font has changed."; case QEvent::ApplicationLayoutDirectionChange: return "QEvent::ApplicationLayoutDirectionChange - The default application layout direction has changed."; case QEvent::ApplicationPaletteChange: return "QEvent::ApplicationPaletteChange - The default application palette has changed."; case QEvent::ApplicationStateChange: return "QEvent::ApplicationStateChange - The state of the application has changed."; case QEvent::ApplicationWindowIconChange: return "QEvent::ApplicationWindowIconChange - The application's icon has changed."; case QEvent::ChildAdded: return "QEvent::ChildAdded - An object gets a child (QChildEvent)."; case QEvent::ChildPolished: return "QEvent::ChildPolished - A widget child gets polished (QChildEvent)."; case QEvent::ChildRemoved: return "QEvent::ChildRemoved - An object loses a child (QChildEvent)."; case QEvent::Clipboard: return "QEvent::Clipboard - The clipboard contents have changed (QClipboardEvent)."; case QEvent::Close: return "QEvent::Close - Widget was closed (QCloseEvent)."; case QEvent::CloseSoftwareInputPanel: return "QEvent::CloseSoftwareInputPanel - A widget wants to close the software input panel (SIP)."; case QEvent::ContentsRectChange: return "QEvent::ContentsRectChange - The margins of the widget's content rect changed."; case QEvent::ContextMenu: return "QEvent::ContextMenu - Context popup menu (QContextMenuEvent)."; case QEvent::CursorChange: return "QEvent::CursorChange - The widget's cursor has changed."; case QEvent::DeferredDelete: return "QEvent::DeferredDelete - The object will be deleted after it has cleaned up (QDeferredDeleteEvent)."; case QEvent::DragEnter: return "QEvent::DragEnter - The cursor enters a widget during a drag and drop operation (QDragEnterEvent)."; case QEvent::DragLeave: return "QEvent::DragLeave - The cursor leaves a widget during a drag and drop operation (QDragLeaveEvent)."; case QEvent::DragMove: return "QEvent::DragMove - A drag and drop operation is in progress (QDragMoveEvent)."; case QEvent::Drop: return "QEvent::Drop - A drag and drop operation is completed (QDropEvent)."; case QEvent::DynamicPropertyChange: return "QEvent::DynamicPropertyChange - A dynamic property was added, changed, or removed from the object."; case QEvent::EnabledChange: return "QEvent::EnabledChange - Widget's enabled state has changed."; case QEvent::Enter: return "QEvent::Enter - Mouse enters widget's boundaries (QEnterEvent)."; //case QEvent::EnterEditFocus: return "QEvent::EnterEditFocus - An editor widget gains focus for editing. QT_KEYPAD_NAVIGATION must be defined."; case QEvent::EnterWhatsThisMode: return "QEvent::EnterWhatsThisMode - Send to toplevel widgets when the application enters \"What's This?\" mode."; case QEvent::Expose: return "QEvent::Expose - Sent to a window when its on-screen contents are invalidated and need to be flushed from the backing store."; case QEvent::FileOpen: return "QEvent::FileOpen - File open request (QFileOpenEvent)."; case QEvent::FocusIn: return "QEvent::FocusIn - Widget or Window gains keyboard focus (QFocusEvent)."; case QEvent::FocusOut: return "QEvent::FocusOut - Widget or Window loses keyboard focus (QFocusEvent)."; case QEvent::FocusAboutToChange: return "QEvent::FocusAboutToChange - Widget or Window focus is about to change (QFocusEvent)"; case QEvent::FontChange: return "QEvent::FontChange - Widget's font has changed."; case QEvent::Gesture: return "QEvent::Gesture - A gesture was triggered (QGestureEvent)."; case QEvent::GestureOverride: return "QEvent::GestureOverride - A gesture override was triggered (QGestureEvent)."; case QEvent::GrabKeyboard: return "QEvent::GrabKeyboard - Item gains keyboard grab (QGraphicsItem only)."; case QEvent::GrabMouse: return "QEvent::GrabMouse - Item gains mouse grab (QGraphicsItem only)."; case QEvent::GraphicsSceneContextMenu: return "QEvent::GraphicsSceneContextMenu - Context popup menu over a graphics scene (QGraphicsSceneContextMenuEvent)."; case QEvent::GraphicsSceneDragEnter: return "QEvent::GraphicsSceneDragEnter - The cursor enters a graphics scene during a drag and drop operation (QGraphicsSceneDragDropEvent)."; case QEvent::GraphicsSceneDragLeave: return "QEvent::GraphicsSceneDragLeave - The cursor leaves a graphics scene during a drag and drop operation (QGraphicsSceneDragDropEvent)."; case QEvent::GraphicsSceneDragMove: return "QEvent::GraphicsSceneDragMove - A drag and drop operation is in progress over a scene (QGraphicsSceneDragDropEvent)."; case QEvent::GraphicsSceneDrop: return "QEvent::GraphicsSceneDrop - A drag and drop operation is completed over a scene (QGraphicsSceneDragDropEvent)."; case QEvent::GraphicsSceneHelp: return "QEvent::GraphicsSceneHelp - The user requests help for a graphics scene (QHelpEvent)."; case QEvent::GraphicsSceneHoverEnter: return "QEvent::GraphicsSceneHoverEnter - The mouse cursor enters a hover item in a graphics scene (QGraphicsSceneHoverEvent)."; case QEvent::GraphicsSceneHoverLeave: return "QEvent::GraphicsSceneHoverLeave - The mouse cursor leaves a hover item in a graphics scene (QGraphicsSceneHoverEvent)."; case QEvent::GraphicsSceneHoverMove: return "QEvent::GraphicsSceneHoverMove - The mouse cursor moves inside a hover item in a graphics scene (QGraphicsSceneHoverEvent)."; case QEvent::GraphicsSceneMouseDoubleClick: return "QEvent::GraphicsSceneMouseDoubleClick - Mouse press again (double click) in a graphics scene (QGraphicsSceneMouseEvent)."; case QEvent::GraphicsSceneMouseMove: return "QEvent::GraphicsSceneMouseMove - Move mouse in a graphics scene (QGraphicsSceneMouseEvent)."; case QEvent::GraphicsSceneMousePress: return "QEvent::GraphicsSceneMousePress - Mouse press in a graphics scene (QGraphicsSceneMouseEvent)."; case QEvent::GraphicsSceneMouseRelease: return "QEvent::GraphicsSceneMouseRelease - Mouse release in a graphics scene (QGraphicsSceneMouseEvent)."; case QEvent::GraphicsSceneMove: return "QEvent::GraphicsSceneMove - Widget was moved (QGraphicsSceneMoveEvent)."; case QEvent::GraphicsSceneResize: return "QEvent::GraphicsSceneResize - Widget was resized (QGraphicsSceneResizeEvent)."; case QEvent::GraphicsSceneWheel: return "QEvent::GraphicsSceneWheel - Mouse wheel rolled in a graphics scene (QGraphicsSceneWheelEvent)."; case QEvent::Hide: return "QEvent::Hide - Widget was hidden (QHideEvent)."; case QEvent::HideToParent: return "QEvent::HideToParent - A child widget has been hidden."; case QEvent::HoverEnter: return "QEvent::HoverEnter - The mouse cursor enters a hover widget (QHoverEvent)."; case QEvent::HoverLeave: return "QEvent::HoverLeave - The mouse cursor leaves a hover widget (QHoverEvent)."; case QEvent::HoverMove: return "QEvent::HoverMove - The mouse cursor moves inside a hover widget (QHoverEvent)."; case QEvent::IconDrag: return "QEvent::IconDrag - The main icon of a window has been dragged away (QIconDragEvent)."; case QEvent::IconTextChange: return "QEvent::IconTextChange - Widget's icon text has been changed."; case QEvent::InputMethod: return "QEvent::InputMethod - An input method is being used (QInputMethodEvent)."; case QEvent::InputMethodQuery: return "QEvent::InputMethodQuery - A input method query event (QInputMethodQueryEvent)"; case QEvent::KeyboardLayoutChange: return "QEvent::KeyboardLayoutChange - The keyboard layout has changed."; case QEvent::KeyPress: return "QEvent::KeyPress - Key press (QKeyEvent)."; case QEvent::KeyRelease: return "QEvent::KeyRelease - Key release (QKeyEvent)."; case QEvent::LanguageChange: return "QEvent::LanguageChange - The application translation changed."; case QEvent::LayoutDirectionChange: return "QEvent::LayoutDirectionChange - The direction of layouts changed."; case QEvent::LayoutRequest: return "QEvent::LayoutRequest - Widget layout needs to be redone."; case QEvent::Leave: return "QEvent::Leave - Mouse leaves widget's boundaries."; //case QEvent::LeaveEditFocus: return "QEvent::LeaveEditFocus - An editor widget loses focus for editing. QT_KEYPAD_NAVIGATION must be defined."; case QEvent::LeaveWhatsThisMode: return "QEvent::LeaveWhatsThisMode - Send to toplevel widgets when the application leaves \"What's This?\" mode."; case QEvent::LocaleChange: return "QEvent::LocaleChange - The system locale has changed."; case QEvent::NonClientAreaMouseButtonDblClick: return "QEvent::NonClientAreaMouseButtonDblClick - A mouse double click occurred outside the client area."; case QEvent::NonClientAreaMouseButtonPress: return "QEvent::NonClientAreaMouseButtonPress - A mouse button press occurred outside the client area."; case QEvent::NonClientAreaMouseButtonRelease: return "QEvent::NonClientAreaMouseButtonRelease - A mouse button release occurred outside the client area."; case QEvent::NonClientAreaMouseMove: return "QEvent::NonClientAreaMouseMove - A mouse move occurred outside the client area."; case QEvent::MacSizeChange: return "QEvent::MacSizeChange - The user changed his widget sizes (Mac OS X only)."; case QEvent::MetaCall: return "QEvent::MetaCall - An asynchronous method invocation via QMetaObject::invokeMethod()."; case QEvent::ModifiedChange: return "QEvent::ModifiedChange - Widgets modification state has been changed."; case QEvent::MouseButtonDblClick: return "QEvent::MouseButtonDblClick - Mouse press again (QMouseEvent)."; case QEvent::MouseButtonPress: return "QEvent::MouseButtonPress - Mouse press (QMouseEvent)."; case QEvent::MouseButtonRelease: return "QEvent::MouseButtonRelease - Mouse release (QMouseEvent)."; case QEvent::MouseMove: return "QEvent::MouseMove - Mouse move (QMouseEvent)."; case QEvent::MouseTrackingChange: return "QEvent::MouseTrackingChange - The mouse tracking state has changed."; case QEvent::Move: return "QEvent::Move - Widget's position changed (QMoveEvent)."; case QEvent::NativeGesture: return "QEvent::NativeGesture - The system has detected a gesture (QNativeGestureEvent)."; case QEvent::OrientationChange: return "QEvent::OrientationChange - The screens orientation has changes (QScreenOrientationChangeEvent)"; case QEvent::Paint: return "QEvent::Paint - Screen update necessary (QPaintEvent)."; case QEvent::PaletteChange: return "QEvent::PaletteChange - Palette of the widget changed."; case QEvent::ParentAboutToChange: return "QEvent::ParentAboutToChange - The widget parent is about to change."; case QEvent::ParentChange: return "QEvent::ParentChange - The widget parent has changed."; case QEvent::PlatformPanel: return "QEvent::PlatformPanel - A platform specific panel has been requested."; case QEvent::Polish: return "QEvent::Polish - The widget is polished."; case QEvent::PolishRequest: return "QEvent::PolishRequest - The widget should be polished."; case QEvent::QueryWhatsThis: return "QEvent::QueryWhatsThis - The widget should accept the event if it has \"What's This?\" help."; //case QEvent::ReadOnlyChange: return "QEvent::ReadOnlyChange - Widget's read-only state has changed (since Qt 5.4)."; case QEvent::RequestSoftwareInputPanel: return "QEvent::RequestSoftwareInputPanel - A widget wants to open a software input panel (SIP)."; case QEvent::Resize: return "QEvent::Resize - Widget's size changed (QResizeEvent)."; case QEvent::ScrollPrepare: return "QEvent::ScrollPrepare - The object needs to fill in its geometry information (QScrollPrepareEvent)."; case QEvent::Scroll: return "QEvent::Scroll - The object needs to scroll to the supplied position (QScrollEvent)."; case QEvent::Shortcut: return "QEvent::Shortcut - Key press in child for shortcut key handling (QShortcutEvent)."; case QEvent::ShortcutOverride: return "QEvent::ShortcutOverride - Key press in child, for overriding shortcut key handling (QKeyEvent)."; case QEvent::Show: return "QEvent::Show - Widget was shown on screen (QShowEvent)."; case QEvent::ShowToParent: return "QEvent::ShowToParent - A child widget has been shown."; case QEvent::SockAct: return "QEvent::SockAct - Socket activated, used to implement QSocketNotifier."; case QEvent::StateMachineSignal: return "QEvent::StateMachineSignal - A signal delivered to a state machine (QStateMachine::SignalEvent)."; case QEvent::StateMachineWrapped: return "QEvent::StateMachineWrapped - The event is a wrapper for, i.e., contains, another event (QStateMachine::WrappedEvent)."; case QEvent::StatusTip: return "QEvent::StatusTip - A status tip is requested (QStatusTipEvent)."; case QEvent::StyleChange: return "QEvent::StyleChange - Widget's style has been changed."; case QEvent::TabletMove: return "QEvent::TabletMove - Wacom tablet move (QTabletEvent)."; case QEvent::TabletPress: return "QEvent::TabletPress - Wacom tablet press (QTabletEvent)."; case QEvent::TabletRelease: return "QEvent::TabletRelease - Wacom tablet release (QTabletEvent)."; case QEvent::OkRequest: return "QEvent::OkRequest - Ok button in decoration pressed. Supported only for Windows CE."; case QEvent::TabletEnterProximity: return "QEvent::TabletEnterProximity - Wacom tablet enter proximity event (QTabletEvent), sent to QApplication."; case QEvent::TabletLeaveProximity: return "QEvent::TabletLeaveProximity - Wacom tablet leave proximity event (QTabletEvent), sent to QApplication."; case QEvent::ThreadChange: return "QEvent::ThreadChange - The object is moved to another thread. This is the last event sent to this object in the previous thread. See QObject::moveToThread()."; case QEvent::Timer: return "QEvent::Timer - Regular timer events (QTimerEvent)."; case QEvent::ToolBarChange: return "QEvent::ToolBarChange - The toolbar button is toggled on Mac OS X."; case QEvent::ToolTip: return "QEvent::ToolTip - A tooltip was requested (QHelpEvent)."; case QEvent::ToolTipChange: return "QEvent::ToolTipChange - The widget's tooltip has changed."; case QEvent::TouchBegin: return "QEvent::TouchBegin - Beginning of a sequence of touch-screen or track-pad events (QTouchEvent)."; case QEvent::TouchCancel: return "QEvent::TouchCancel - Cancellation of touch-event sequence (QTouchEvent)."; case QEvent::TouchEnd: return "QEvent::TouchEnd - End of touch-event sequence (QTouchEvent)."; case QEvent::TouchUpdate: return "QEvent::TouchUpdate - Touch-screen event (QTouchEvent)."; case QEvent::UngrabKeyboard: return "QEvent::UngrabKeyboard - Item loses keyboard grab (QGraphicsItem only)."; case QEvent::UngrabMouse: return "QEvent::UngrabMouse - Item loses mouse grab (QGraphicsItem only)."; case QEvent::UpdateLater: return "QEvent::UpdateLater - The widget should be queued to be repainted at a later time."; case QEvent::UpdateRequest: return "QEvent::UpdateRequest - The widget should be repainted."; case QEvent::WhatsThis: return "QEvent::WhatsThis - The widget should reveal \"What's This?\" help (QHelpEvent)."; case QEvent::WhatsThisClicked: return "QEvent::WhatsThisClicked - A link in a widget's \"What's This?\" help was clicked."; case QEvent::Wheel: return "QEvent::Wheel - Mouse wheel rolled (QWheelEvent)."; case QEvent::WinEventAct: return "QEvent::WinEventAct - A Windows-specific activation event has occurred."; case QEvent::WindowActivate: return "QEvent::WindowActivate - Window was activated."; case QEvent::WindowBlocked: return "QEvent::WindowBlocked - The window is blocked by a modal dialog."; case QEvent::WindowDeactivate: return "QEvent::WindowDeactivate - Window was deactivated."; case QEvent::WindowIconChange: return "QEvent::WindowIconChange - The window's icon has changed."; case QEvent::WindowStateChange: return "QEvent::WindowStateChange - The window's state (minimized, maximized or full-screen) has changed (QWindowStateChangeEvent)."; case QEvent::WindowTitleChange: return "QEvent::WindowTitleChange - The window title has changed."; case QEvent::WindowUnblocked: return "QEvent::WindowUnblocked - The window is unblocked after a modal dialog exited."; case QEvent::WinIdChange: return "QEvent::WinIdChange - The window system identifer for this native widget has changed."; case QEvent::ZOrderChange: return "QEvent::ZOrderChange - The widget's z-order has changed. This event is never sent to top level windows."; default: return QString("%1").arg(t); } } private: enum UrlStack { URL_VIEW = 0, PROGRESS_VIEW }; private: QString _filename; QWebElement _lastFocused; // cache for last focussed element QString _keyStrokes; // collect key strokes bool _typing; // user is typing bool _inEventFilter; // actually handling event filter Script _setupScript; }; #endif // TESTGUI_HXX