1 #ifndef oxygensimulator_h
2 #define oxygensimulator_h
3 
4 //////////////////////////////////////////////////////////////////////////////
5 // oxygensimulator.h
6 // simulates event chain passed to the application
7 // -------------------
8 //
9 // SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
10 //
11 // SPDX-License-Identifier: MIT
12 //////////////////////////////////////////////////////////////////////////////
13 
14 #include "../oxygen.h"
15 
16 #include <KLocalizedString>
17 #include <QAbstractButton>
18 #include <QTabBar>
19 #include <QTabWidget>
20 #include <QWidget>
21 
22 #include <QBasicTimer>
23 #include <QEvent>
24 #include <QList>
25 #include <QObject>
26 #include <QTimerEvent>
27 
28 namespace Oxygen
29 {
30     class Simulator: public QObject
31     {
32         Q_OBJECT
33 
34         public:
35 
36         //* constructor
Simulator(QObject * parent)37         explicit Simulator( QObject* parent ):
38             QObject( parent ),
39             _previousPosition( -1, -1 )
40             {}
41 
42         //*@name high level interface
43         //@{
44 
45         //* click on button
46         void click( QWidget* receiver, int delay = -1 );
47 
48         //* click on button
49         void click( QWidget*, const QPoint&, int = -1 );
50 
51         //* slide
52         void slide( QWidget* receiver, const QPoint& delta, int delay = -1 );
53 
54         //* select item
55         void selectItem( QWidget*, int row, int column = 0, int = -1 );
56 
57         //* select combobox item
58         void selectComboBoxItem( QWidget*, int, int = -1 );
59 
60         //* select menu item
61         void selectMenuItem( QWidget*, int, int = -1 );
62 
63         //* select tab in tabwidget
64         void selectTab( QTabWidget*, int, int = -1 );
65 
66         //* select tab in tabbar
67         void selectTab( QTabBar*, int, int = -1 );
68 
69         //* write sample text
70         void writeSampleText( QWidget* widget, int delay = -1 )
71         { writeText( widget, i18n( "This is a sample text" ), delay ); }
72 
73         //* write string
74         void writeText( QWidget*, QString, int = -1 );
75 
76         //* clear text
77         void clearText( QWidget*, int = -1 );
78 
79         //* delay
80         void wait( int delay );
81 
82         //@}
83 
84         //* true if aborted
aborted(void)85         bool aborted( void ) const
86         { return _aborted; }
87 
88         //* run stored events
89         void run( void );
90 
91         //* gab mouse
grabMouse(void)92         static bool grabMouse( void )
93         { return _grabMouse; }
94 
95         //* mouse grab
setGrabMouse(bool value)96         static void setGrabMouse( bool value )
97         { _grabMouse = value; }
98 
99         //* default delay
setDefaultDelay(int value)100         static void setDefaultDelay( int value )
101         { _defaultDelay = value; }
102 
103         Q_SIGNALS:
104 
105         //* emitted when simulator starts and stops
106         void stateChanged( bool );
107 
108         public Q_SLOTS:
109 
110         //* abort simulations
111         void abort( void );
112 
113         protected:
114 
115         //* timer event
116         void timerEvent( QTimerEvent* ) override;
117 
118         private:
119 
120         //*@name low level interface
121         //@{
122 
123         //* enter widget
124         bool enter( QWidget* receiver, int delay = -1 )
125         { return enter( receiver, receiver->rect().center(), delay ); }
126 
127         //* enter receiver
128         bool enter( QWidget*, const QPoint&, int = -1 );
129 
130         //* mouse click event
postMouseClickEvent(QWidget * widget)131         void postMouseClickEvent( QWidget* widget )
132         { postMouseClickEvent( widget, Qt::LeftButton, widget->rect().center() ); }
133 
134         //* mouse click event
135         void postMouseClickEvent( QWidget*, Qt::MouseButton, const QPoint& );
136 
137         //* 'basic' event
138         void postEvent( QWidget*, QEvent::Type ) const;
139 
140         //* hover
141         void postHoverEvent( QWidget*, QEvent::Type, const QPoint&, const QPoint& ) const;
142 
143         //* mouse event
144         void postMouseEvent( QWidget*, QEvent::Type, Qt::MouseButton , const QPoint&, Qt::MouseButtons = Qt::NoButton, Qt::KeyboardModifiers = Qt::NoModifier ) const;
145 
146         //* key event
147         void postKeyClickEvent( QWidget*, Qt::Key, QString, Qt::KeyboardModifiers = Qt::NoModifier ) const;
148 
149         //* key event
150         void postKeyModifiersEvent( QWidget*, QEvent::Type, Qt::KeyboardModifiers ) const;
151 
152         //* key event
153         void postKeyEvent( QWidget*, QEvent::Type, Qt::Key, QString, Qt::KeyboardModifiers = Qt::NoModifier ) const;
154 
155         //* delay
156         void postDelay( int );
157 
158         //* set focus to widget
159         void setFocus( QWidget* );
160 
161         //* move cursor
162         void moveCursor( const QPoint&, int steps = 10 );
163         //@}
164 
165         using WidgetPointer = WeakPointer<QWidget>;
166 
167         //* event
168         class Event
169         {
170             public:
171 
172             enum Type
173             {
174                 Wait,
175                 Click,
176                 Slide,
177                 SelectItem,
178                 SelectComboBoxItem,
179                 SelectMenuItem,
180                 SelectTab,
181                 WriteText,
182                 ClearText
183             };
184 
185             //* constructor
186             Event( Type type, QWidget* receiver, int delay = 0 ):
_type(type)187                 _type( type ),
188                 _receiver( receiver ),
189                 _delay( delay )
190             {}
191 
192             Type _type;
193             WidgetPointer _receiver;
194             QPoint _position;
195             QString _text;
196             int _delay = 0;
197 
198         };
199 
200         //* process event
201         void processEvent( const Event& );
202 
203         //* process Qt event
204         void postQEvent( QWidget*, QEvent* ) const;
205 
206         //* convert QChar to key
207         Qt::Key toKey( QChar ) const;
208 
209         //* list of events
210         using EventList = QList<Event>;
211         EventList _events;
212 
213         //* previous position in global coordinates
214         /** this is needed to have proper handling of enter/leave/hover events */
215         QPoint _previousPosition;
216 
217         //* previous widget
218         WidgetPointer _previousWidget;
219 
220         //* basic timer, for wait
221         QBasicTimer _timer;
222 
223         //* pending events timer
224         QBasicTimer _pendingEventsTimer;
225 
226         //* pending event
227         WidgetPointer _pendingWidget;
228         QList<QEvent*> _pendingEvents;
229 
230         //* true when simulations must be aborted
231         bool _aborted = false;
232 
233         //* true if simulations also grab mouse
234         static bool _grabMouse;
235 
236         //* default delay
237         static int _defaultDelay;
238 
239     };
240 
241 }
242 
243 #endif
244