diff --git a/src/commands.hxx b/src/commands.hxx index fa6ec2f..f685d0a 100644 --- a/src/commands.hxx +++ b/src/commands.hxx @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -464,6 +465,14 @@ class Script: public QObject { back += 2; _ignoreSignalsUntil = "loadStarted"; frame->load(url); + } else if ((*cmd)->command().startsWith("expect load")) { + QString url2((*cmd)->command()); + url2.remove("expect load"); + if (url2.size()) url=url2.trimmed(); + ----cmd; + back += 2; + _ignoreSignalsUntil = "loadStarted"; + frame->load(url); } else { throw; } @@ -782,33 +791,57 @@ class Expect: public Command { "Known signals and parameters are:\n" " - loadFinished \n" " - loadStarted\n" - " - urlChanged "; + " - urlChanged \n" + "There is a short hand:\n" + " - load \n" + " stands for the three signals:\n" + " - loadStarted\n" + " - urlChanged \n" + " - loadFinished true"; } QString command() const { - return "expect "+_signal+(_args.size()?" "+_args.join(' '):QString()); + return "expect "+_signal._signal + +(_signal._args.size()?" "+_signal._args.join(' '):QString()); } std::shared_ptr parse(Script*, QString args, QStringList&, int) { std::shared_ptr cmd(new Expect()); - cmd->_args = args.split(" "); - cmd->_signal = cmd->_args.takeFirst(); + cmd->_signal._args = args.split(" "); + cmd->_signal._signal = cmd->_signal._args.takeFirst(); return cmd; } bool execute(Script* script, QWebFrame*) { Logger log(this, script); - QString signal(_signal); - QStringList args; - Q_FOREACH(QString arg, _args) args.push_back(script->replacevars(arg)); - Script::Signal lastsignal(script->getSignal()); - QStringList lastargs; - Q_FOREACH(QString arg, lastsignal.second) - lastargs.push_back(script->replacevars(arg)); - if (lastsignal.first!=signal || (args.size() && args!=lastargs)) - throw WrongSignal(signal, args, lastsignal); + QList sigs; + if (_signal._signal=="load") { // special signal load + sigs += Signal("loadStarted"); + sigs += Signal("urlChanged", _signal._args); + sigs += Signal("loadFinished", "true"); + } else { + sigs += _signal; + } + Q_FOREACH(Signal signal, sigs) { + QStringList args; + Q_FOREACH(QString arg, signal._args) + args.push_back(script->replacevars(arg)); + Script::Signal lastsignal(script->getSignal()); + QStringList lastargs; + Q_FOREACH(QString arg, lastsignal.second) + lastargs.push_back(script->replacevars(arg)); + if (lastsignal.first!=signal._signal || (args.size() && args!=lastargs)) + throw WrongSignal(signal._signal, args, lastsignal); + } return true; } private: - QString _signal; - QStringList _args; + struct Signal { + Signal(QString s, QStringList a): _signal(s), _args(a) {} + Signal(QString s, QString a): _signal(s), _args(a) {} + Signal(QString s): _signal(s) {} + Signal() {} + QString _signal; + QStringList _args; + }; + Signal _signal; }; class Open: public Command { @@ -1396,24 +1429,23 @@ class Timeout: public Command { QString _timeout; }; - -class Certificate: public Command { +class CaCertificate: public Command { public: QString tag() const { - return "certificate"; + return "ca-certificate"; } QString description() const { return - "certificate " + "ca-certificate " "\n\n" "Load a CA certificate that will be accepted on SSL connections."; } QString command() const { - return "certificate "+_filename; + return "ca-certificate "+_filename; } std::shared_ptr parse(Script*, QString args, QStringList&, int) { - std::shared_ptr cmd(new (Certificate)); + std::shared_ptr cmd(new (CaCertificate)); cmd->_filename = args.trimmed(); return cmd; } @@ -1432,6 +1464,64 @@ class Certificate: public Command { QString _filename; }; +class ClientCertificate: public Command { + public: + QString tag() const { + return "client-certificate"; + } + QString description() const { + return + "client-certificate " + "\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" + " openssl pkcs12 -in certfile.p12 -out certfile.pem -nodes -clcerts\n" + " openssl pkcs12 -in certfile.p12 -out keyfile.pem -nocerts\n"; + } + QString command() const { + return "client-certificate "+_certfile+" "+_keyfile+" "+_password; + } + std::shared_ptr parse(Script*, QString args, + QStringList&, int) { + std::shared_ptr cmd(new (ClientCertificate)); + QStringList s(args.trimmed().split(' ')); + if (s.size()<3) throw MissingArguments(args, "certfile keyfile password"); + cmd->_certfile = s.takeFirst(); + cmd->_keyfile = s.takeFirst(); + cmd->_password = s.join(' '); + return cmd; + } + bool execute(Script* script, QWebFrame*) { + Logger log(this, script); + QSslConfiguration sslConfig(QSslConfiguration::defaultConfiguration()); + sslConfig.setProtocol(QSsl::AnyProtocol); + sslConfig.setPeerVerifyMode(QSslSocket::AutoVerifyPeer); + QString filename(script->replacevars(_certfile)); + QFile certfile(filename); + if (!certfile.exists() || !certfile.open(QIODevice::ReadOnly)) + throw FileNotFound(filename); + QSslCertificate cert(&certfile); + if (cert.isNull()) throw NotACertificate(filename); + sslConfig.setLocalCertificate(cert); + filename = script->replacevars(_keyfile); + QFile keyfile(filename); + if (!keyfile.exists() || !keyfile.open(QIODevice::ReadOnly)) + throw FileNotFound(filename); + keyfile.open(QIODevice::ReadOnly); + QSslKey k(&keyfile, QSsl::Rsa, QSsl::Pem, + QSsl::PrivateKey, _password.toUtf8()); + if (k.isNull()) throw KeyNotReadable(filename); + sslConfig.setPrivateKey(k); + QSslConfiguration::setDefaultConfiguration(sslConfig); + return true; + } + private: + QString _certfile; + QString _keyfile; + QString _password; +}; + /* Template: class : public Command { public: @@ -1507,7 +1597,8 @@ inline void Script::initPrototypes() { add(new Set); add(new UnSet); add(new Timeout); - add(new Certificate); + add(new CaCertificate); + add(new ClientCertificate); } #endif diff --git a/src/exceptions.hxx b/src/exceptions.hxx index 0c8e521..31fcd1c 100644 --- a/src/exceptions.hxx +++ b/src/exceptions.hxx @@ -40,6 +40,12 @@ class BadArgument: public ParseError { BadArgument(QString arg): ParseError("bad argument: "+arg) {} }; +class MissingArguments: public ParseError { + public: + MissingArguments(QString args, QString req): + ParseError("missing arguments, requires "+req+", got: "+args) {} +}; + class TestFailed: public Exception { public: TestFailed(QString why): Exception("Test Failed: "+why) {} @@ -114,6 +120,13 @@ class NotACertificate: public TestFailed { } }; +class KeyNotReadable: public TestFailed { + public: + KeyNotReadable(QString arg): + TestFailed("key file is not readable (password?): "+arg) { + } +}; + class NotUnattended: public TestFailed { public: NotUnattended(): TestFailed("web page is not in unattended test mode") {} diff --git a/src/networkaccessmanager.hxx b/src/networkaccessmanager.hxx index 0356d7b..b2a3e91 100644 --- a/src/networkaccessmanager.hxx +++ b/src/networkaccessmanager.hxx @@ -225,7 +225,9 @@ class NetworkAccessManager: public QNetworkAccessManager { } void sslErrorsLog(const QList& errors) { Q_FOREACH(const QSslError& error, errors) - log("**** SSL-Error: "+error.errorString()); + log("**** SSL-Error: "+error.errorString()+"\n"+ + " Certificate: "+error.certificate().toText()); + //QNetworkReply* reply(dynamic_cast(QObject::sender())); } void sslErrorsLog(QNetworkReply*, const QList&) { //log(__PRETTY_FUNCTION__); diff --git a/src/testgui.hxx b/src/testgui.hxx index 82efcc8..95dfd26 100644 --- a/src/testgui.hxx +++ b/src/testgui.hxx @@ -20,6 +20,7 @@ #include #include #include +#include class TestGUI: public QMainWindow, protected Ui::TestGUI { Q_OBJECT; @@ -301,36 +302,52 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI { case QEvent::MouseButtonRelease: { enterText(true); _lastFocused=element; - if (_record->isChecked() && !element.isNull()) { - QString selected(selector(_lastFocused)); - 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 "+mooCombo.captured(1)+">a"); - appendCommand("sleep 1"); - } else if (mooComboItem.hasMatch()) { - // special treatment for item in moo tools combobox - appendCommand - ("click li.active-result[data-option-array-index=\"" - +element.attribute("data-option-array-index")+"\"]"); - appendCommand("sleep 1"); + if (_record->isChecked()) { + if (!element.isNull()) { + QString selected(selector(_lastFocused)); + 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 "+mooCombo.captured(1)+">a"); + appendCommand("sleep 1"); + } else if (mooComboItem.hasMatch()) { + // special treatment for item in moo tools combobox + appendCommand + ("click li.active-result[data-option-array-index=\"" + +element.attribute("data-option-array-index")+"\"]"); + appendCommand("sleep 1"); + } else { + appendCommand("click "+selected); + } } else { - appendCommand("click "+selected); + appendCommand("# click, but where?"); } } } break; + case QEvent::MouseButtonPress: { + enterText(true); + } break; + case QEvent::ChildRemoved: { // select option value changed + enterText(true); + _typing = true; + _lastFocused=element; + _keyStrokes = "dummy"; + } break; case QEvent::InputMethodQuery: case QEvent::ToolTipChange: case QEvent::MouseMove: case QEvent::UpdateLater: case QEvent::Paint: break; - default: ;//LOG("Event: "<type()); + default:; + /* _log->appendPlainText(QString("Event: %1") + .arg(eventName(event->type()))); */ } _inEventFilter = false; return false; @@ -495,6 +512,158 @@ class TestGUI: public QMainWindow, protected Ui::TestGUI { 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, diff --git a/src/webtester.cxx b/src/webtester.cxx index 8cd3e86..8eab530 100644 --- a/src/webtester.cxx +++ b/src/webtester.cxx @@ -1,9 +1,17 @@ #include #include +#include -int main(int argc, char *argv[]) { - QApplication a(argc, argv); - TestGUI w(0, argc>1?argv[1]:""); - w.show(); - return a.exec(); -} +int main(int argc, char *argv[]) try { + QApplication a(argc, argv); + QCommandLineParser parser; + parser.addHelpOption(); + parser.process(a); + QStringList urls(parser.positionalArguments()); + TestGUI w(0, urls.size()?urls[0]:""); + w.show(); + return a.exec(); + } catch (std::exception &x) { + std::cerr<<"**** error: "<