File indexing completed on 2024-05-19 05:35:24

0001 #ifndef oxygensimulator_h
0002 #define oxygensimulator_h
0003 
0004 //////////////////////////////////////////////////////////////////////////////
0005 // oxygensimulator.h
0006 // simulates event chain passed to the application
0007 // -------------------
0008 //
0009 // SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0010 //
0011 // SPDX-License-Identifier: MIT
0012 //////////////////////////////////////////////////////////////////////////////
0013 
0014 #include "../oxygen.h"
0015 
0016 #include <KLocalizedString>
0017 #include <QAbstractButton>
0018 #include <QTabBar>
0019 #include <QTabWidget>
0020 #include <QWidget>
0021 
0022 #include <QBasicTimer>
0023 #include <QEvent>
0024 #include <QList>
0025 #include <QObject>
0026 #include <QTimerEvent>
0027 
0028 namespace Oxygen
0029 {
0030 class Simulator : public QObject
0031 {
0032     Q_OBJECT
0033 
0034 public:
0035     //* constructor
0036     explicit Simulator(QObject *parent)
0037         : QObject(parent)
0038         , _previousPosition(-1, -1)
0039     {
0040     }
0041 
0042     //*@name high level interface
0043     //@{
0044 
0045     //* click on button
0046     void click(QWidget *receiver, int delay = -1);
0047 
0048     //* click on button
0049     void click(QWidget *, const QPoint &, int = -1);
0050 
0051     //* slide
0052     void slide(QWidget *receiver, const QPoint &delta, int delay = -1);
0053 
0054     //* select item
0055     void selectItem(QWidget *, int row, int column = 0, int = -1);
0056 
0057     //* select combobox item
0058     void selectComboBoxItem(QWidget *, int, int = -1);
0059 
0060     //* select menu item
0061     void selectMenuItem(QWidget *, int, int = -1);
0062 
0063     //* select tab in tabwidget
0064     void selectTab(QTabWidget *, int, int = -1);
0065 
0066     //* select tab in tabbar
0067     void selectTab(QTabBar *, int, int = -1);
0068 
0069     //* write sample text
0070     void writeSampleText(QWidget *widget, int delay = -1)
0071     {
0072         writeText(widget, i18n("This is a sample text"), delay);
0073     }
0074 
0075     //* write string
0076     void writeText(QWidget *, QString, int = -1);
0077 
0078     //* clear text
0079     void clearText(QWidget *, int = -1);
0080 
0081     //* delay
0082     void wait(int delay);
0083 
0084     //@}
0085 
0086     //* true if aborted
0087     bool aborted(void) const
0088     {
0089         return _aborted;
0090     }
0091 
0092     //* run stored events
0093     void run(void);
0094 
0095     //* gab mouse
0096     static bool grabMouse(void)
0097     {
0098         return _grabMouse;
0099     }
0100 
0101     //* mouse grab
0102     static void setGrabMouse(bool value)
0103     {
0104         _grabMouse = value;
0105     }
0106 
0107     //* default delay
0108     static void setDefaultDelay(int value)
0109     {
0110         _defaultDelay = value;
0111     }
0112 
0113 Q_SIGNALS:
0114 
0115     //* emitted when simulator starts and stops
0116     void stateChanged(bool);
0117 
0118 public Q_SLOTS:
0119 
0120     //* abort simulations
0121     void abort(void);
0122 
0123 protected:
0124     //* timer event
0125     void timerEvent(QTimerEvent *) override;
0126 
0127 private:
0128     //*@name low level interface
0129     //@{
0130 
0131     //* enter widget
0132     bool enter(QWidget *receiver, int delay = -1)
0133     {
0134         return enter(receiver, receiver->rect().center(), delay);
0135     }
0136 
0137     //* enter receiver
0138     bool enter(QWidget *, const QPoint &, int = -1);
0139 
0140     //* mouse click event
0141     void postMouseClickEvent(QWidget *widget)
0142     {
0143         postMouseClickEvent(widget, Qt::LeftButton, widget->rect().center());
0144     }
0145 
0146     //* mouse click event
0147     void postMouseClickEvent(QWidget *, Qt::MouseButton, const QPoint &);
0148 
0149     //* 'basic' event
0150     void postEvent(QWidget *, QEvent::Type) const;
0151 
0152     //* hover
0153     void postHoverEvent(QWidget *, QEvent::Type, const QPoint &, const QPoint &) const;
0154 
0155     //* mouse event
0156     void
0157     postMouseEvent(QWidget *, QEvent::Type, Qt::MouseButton, const QPoint &, Qt::MouseButtons = Qt::NoButton, Qt::KeyboardModifiers = Qt::NoModifier) const;
0158 
0159     //* key event
0160     void postKeyClickEvent(QWidget *, Qt::Key, QString, Qt::KeyboardModifiers = Qt::NoModifier) const;
0161 
0162     //* key event
0163     void postKeyModifiersEvent(QWidget *, QEvent::Type, Qt::KeyboardModifiers) const;
0164 
0165     //* key event
0166     void postKeyEvent(QWidget *, QEvent::Type, Qt::Key, QString, Qt::KeyboardModifiers = Qt::NoModifier) const;
0167 
0168     //* delay
0169     void postDelay(int);
0170 
0171     //* set focus to widget
0172     void setFocus(QWidget *);
0173 
0174     //* move cursor
0175     void moveCursor(const QPoint &, int steps = 10);
0176     //@}
0177 
0178     using WidgetPointer = WeakPointer<QWidget>;
0179 
0180     //* event
0181     class Event
0182     {
0183     public:
0184         enum Type { Wait, Click, Slide, SelectItem, SelectComboBoxItem, SelectMenuItem, SelectTab, WriteText, ClearText };
0185 
0186         //* constructor
0187         Event(Type type, QWidget *receiver, int delay = 0)
0188             : _type(type)
0189             , _receiver(receiver)
0190             , _delay(delay)
0191         {
0192         }
0193 
0194         Type _type;
0195         WidgetPointer _receiver;
0196         QPoint _position;
0197         QString _text;
0198         int _delay = 0;
0199     };
0200 
0201     //* process event
0202     void processEvent(const Event &);
0203 
0204     //* process Qt event
0205     void postQEvent(QWidget *, QEvent *) const;
0206 
0207     //* convert QChar to key
0208     Qt::Key toKey(QChar) const;
0209 
0210     //* list of events
0211     using EventList = QList<Event>;
0212     EventList _events;
0213 
0214     //* previous position in global coordinates
0215     /** this is needed to have proper handling of enter/leave/hover events */
0216     QPoint _previousPosition;
0217 
0218     //* previous widget
0219     WidgetPointer _previousWidget;
0220 
0221     //* basic timer, for wait
0222     QBasicTimer _timer;
0223 
0224     //* pending events timer
0225     QBasicTimer _pendingEventsTimer;
0226 
0227     //* pending event
0228     WidgetPointer _pendingWidget;
0229     QList<QEvent *> _pendingEvents;
0230 
0231     //* true when simulations must be aborted
0232     bool _aborted = false;
0233 
0234     //* true if simulations also grab mouse
0235     static bool _grabMouse;
0236 
0237     //* default delay
0238     static int _defaultDelay;
0239 };
0240 }
0241 
0242 #endif