mirror of
https://github.com/fwbuilder/fwbuilder
synced 2025-06-15 14:47:52 +02:00
Removed tutorial dialog
This commit is contained in:
parent
a91930d5a7
commit
a53fd00a45
84
doc/README_animated_tutorial
Normal file
84
doc/README_animated_tutorial
Normal file
@ -0,0 +1,84 @@
|
||||
Анимация диалога состоит из таких классов:
|
||||
TutorialDialog
|
||||
TutorialAnimator
|
||||
TutorialHelper
|
||||
MouseBlocker
|
||||
Каждый из них представлен .cpp и .h файлом, а к TutorialDialog есть еще .ui
|
||||
файл с интерфейсом.
|
||||
|
||||
Что и как делает каждый класс:
|
||||
TutorialDialog
|
||||
Это сам интерфейс, в котором демонстрируется html файл с инструкциями. Он
|
||||
также содержит слайдер для регулировки скорости демонстрации и кнопку
|
||||
Demonstrate, нажатие на которую запускает анимацию.
|
||||
Содержимое инструкций заружается из файла :/Tutorial/html/pageN.html
|
||||
ресурсов программы. Кнопки next и previous активны в зависимости от наличия
|
||||
файла для следующей/прошлой страницы.
|
||||
Скорость регулируется от 20 до 70. Это базовое и минимальное значение
|
||||
скорости в милисекундах, быстрее которого не будет происходить ниодно
|
||||
действите анимации. Например, симуляция ввода с клавиатуры будет происходить
|
||||
с паузой в это значение между нажатиями на кнопки.
|
||||
По нажатию кнопки Demonstrate считывается файл :/Tutorial/commands/pageN.txt
|
||||
из ресурсов программы, в котором должны находиться инструкции по анимации
|
||||
действий описаных в html файле, который отображается в данный момент.
|
||||
Для анимации создается инстанс класс TutorialAnimator с аргументами: ссылкой
|
||||
на TutorialDialog и текстом файла комманд. Далее запускает его, после чего
|
||||
управление передается этому классу.
|
||||
TutorialAnimator
|
||||
Является наследником QThread, чтобы не блокироваться при открытии модальных
|
||||
диалогов и меню.
|
||||
При инициализации первым делом прячет TutorialDialog и разбивает полученый
|
||||
текст файла команд на строки, каждая из которых является отдельной командой.
|
||||
Создает инстанс класса TutorialHelper в GUI потоке, через который будет
|
||||
позже манипулировать интерфейсом.
|
||||
При запуске блокирует ввод и движения мышки при помощи методов blockInput и
|
||||
blockMouse из класса TutorialHelper. После чего начинает последовательно
|
||||
выполнять комманды полученые при инициализации.
|
||||
В данный момент поддерживаются следующие комманды:
|
||||
moveMouse X Y
|
||||
moveMouse objectName1 [objectName2 [... objectNameN]]
|
||||
clickWidget objectName1 [objectName2 [... objectNameN]]
|
||||
typeWidget objectName1 [objectName2 [... objectNameN]] text
|
||||
hoverMenuItem menuName itemName|itemIndex
|
||||
clickMenuItem menuName itemName|itemIndex
|
||||
selectComboItem objectName1 [objectName2 [... objectNameN]] itemIndex
|
||||
selectListItem objectName1 [objectName2 [... objectNameN]] itemIndex
|
||||
selectTab objectName1 [objectName2 [... objectNameN]] itemIndex
|
||||
wait SECONDS
|
||||
moveMouse - переместить указатель мыши в указаную точку или в центр виджета.
|
||||
clickWidget - переместить указатель мыши в центр виджета и кликнуть.
|
||||
typeWidget - напечатать текст на клавиатуре когда указаный обьект в фокусе.
|
||||
hoveMenuItem - переместить указатель мыши на пункт меню.
|
||||
clickMenuItem - кликнуть пункт меню мышью.
|
||||
selectComboItem - открыть combo box и выбрать в нем элемент.
|
||||
selectListItem - выбрать элемент в списке при помощи мыши.
|
||||
selectTab - выбрать вкладку QTabWidget при помощи мыши
|
||||
wait - ожидать указаное кол-во секунд.
|
||||
Для каждой из них есть отдельный метод, который ее обрабатывает.
|
||||
Все манипуляции с интерфейсом происходят через класс TutorialHelper, который
|
||||
был создан раньше и выполняется в GUI потоке. Но так как из треда, в котором
|
||||
TutorialAnimator, вызов метода TutorialHelper приведет к его выполнению не
|
||||
в GUI-потоке, для вызова этих методов используется QMetaObject::invokeMethod
|
||||
с аргументом Qt::BlockedQueuedConnection. Это позволяет выполнить метод
|
||||
когда выполнение программы вернется в основной поток и блокировать
|
||||
выполнение потока TutorialAnimator пока вызваный метод не выполнится.
|
||||
Этот класс также содержит такие полезные методы как findChild, findWidget и
|
||||
getWidget, который наверняка пригодятся также для написания unit-тестов. Они
|
||||
позволяют рекурсивно искать обьекты по дереву обьектов программы. Для этого
|
||||
используется поиск в ширину. В отличии от стандартной функции findChild, эти
|
||||
методы умеют искать не просто первый обьект с указаным именем, а последний
|
||||
обьект в цепочке наследования.
|
||||
Например, комманда clickWidget MainWindow SomeWidget TargetButton означает:
|
||||
найти виджет MainWindow, в нем SomeWidget, в нем TargetButton и кликнуть ее.
|
||||
Также поддерживается поиск по имени класса: w#className. Например6
|
||||
moveMouse w#FWWindow objectTreeView - найти обьект класса FWWindow, в
|
||||
котором найти objectTreeView и переместить курсор мыши в его центр.
|
||||
TutorialHelper
|
||||
Этот класс содержит все методы по манипулированию интерфейсом. Его методы
|
||||
вызываются из TutorialAnimator, но должны выполняться в GUI потоке.
|
||||
Он также содержит методы blockInput для блокировки ввода и blockMouse для
|
||||
блокировки движения мыши, которые могут выполняться с любого потока.
|
||||
MouseBlocker
|
||||
Наследник QThread, который когда запущен каждые 10 милисекунд перемещает
|
||||
указатель мыши в его текущее положение. Это полностью блокирует перемещение
|
||||
мыши пользователем. Используется через TutorialHelper::blockMouse.
|
@ -292,18 +292,13 @@
|
||||
<file>Images/fwbuilder3-128x128.png</file>
|
||||
<file>Images/fwbuilder3.png</file>
|
||||
<file>Tutorial/html/page0.html</file>
|
||||
<file>Tutorial/commands/page0.txt</file>
|
||||
<file>Tutorial/images/0.png</file>
|
||||
<file>Tutorial/images/1.png</file>
|
||||
<file>Tutorial/images/2.png</file>
|
||||
<file>Tutorial/images/3.png</file>
|
||||
<file>Tutorial/images/new_button.png</file>
|
||||
<file>Tutorial/html/page1.html</file>
|
||||
<file>Tutorial/commands/page1.txt</file>
|
||||
<file>Tutorial/controls.txt</file>
|
||||
<file>Tutorial/html/page2.html</file>
|
||||
<file>Tutorial/html/page3.html</file>
|
||||
<file>Tutorial/commands/page2.txt</file>
|
||||
<file>Tutorial/commands/page3.txt</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -1,24 +0,0 @@
|
||||
#include "MouseBlocker.h"
|
||||
#include <QCursor>
|
||||
#include <QTest>
|
||||
|
||||
MouseBlocker::MouseBlocker(QObject *parent) :
|
||||
QThread(parent)
|
||||
{
|
||||
this->alive = true;
|
||||
}
|
||||
|
||||
void MouseBlocker::run()
|
||||
{
|
||||
while (this->alive)
|
||||
{
|
||||
QCursor::setPos(QCursor::pos());
|
||||
QTest::qSleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
void MouseBlocker::die()
|
||||
{
|
||||
this->alive = false;
|
||||
while (this->isRunning()) QTest::qSleep(10);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#ifndef MOUSEBLOCKER_H
|
||||
#define MOUSEBLOCKER_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
class MouseBlocker : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
bool alive;
|
||||
public:
|
||||
explicit MouseBlocker(QObject *parent = 0);
|
||||
void run();
|
||||
void die();
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // MOUSEBLOCKER_H
|
@ -1,4 +0,0 @@
|
||||
moveMouse om newButton
|
||||
clickWidget om newButton
|
||||
hoverMenuItem newObjectPopup New\_Firewall
|
||||
clickMenuItem newObjectPopup New\_Firewall
|
@ -1,11 +0,0 @@
|
||||
moveMouse w#newFirewallDialog obj_name
|
||||
clickMouse w#newFirewallDialog obj_name
|
||||
typeWidget w#newFirewallDialog obj_name guardian
|
||||
selectComboItem w#newFirewallDialog platform iptables
|
||||
selectComboItem w#newFirewallDialog hostOS Linux\_2.4/2.6
|
||||
moveMouse w#newFirewallDialog useTemplate
|
||||
clickWidget w#newFirewallDialog useTemplate
|
||||
moveMouse w#newFirewallDialog templateUseStandart
|
||||
clickWidget w#newFirewallDialog templateUseStandart
|
||||
moveMouse w#newFirewallDialog nextButton
|
||||
clickWidget w#newFirewallDialog nextButton
|
@ -1,3 +0,0 @@
|
||||
selectListItem w#newFirewallDialog templateList fw\_template\_3
|
||||
moveMouse w#newFirewallDialog nextButton
|
||||
clickWidget w#newFirewallDialog nextButton
|
@ -1,5 +0,0 @@
|
||||
selectTab w#newFirewallDialog interfaceEditor2 1
|
||||
selectTab w#newFirewallDialog interfaceEditor2 2
|
||||
selectTab w#newFirewallDialog interfaceEditor2 0
|
||||
moveMouse w#newFirewallDialog finishButton
|
||||
clickWidget w#newFirewallDialog finishButton
|
@ -1,4 +0,0 @@
|
||||
#page requiresPrevPageDemonstrated prevEnabled undoActionCount
|
||||
0 true false
|
||||
1 true false
|
||||
2 true false
|
@ -1,3 +1,3 @@
|
||||
<p>This page of the wizard shows template objects and their configuration. Standard template objects represent firewalls with two or three interfaces, a host with one interface, a web server or a Cisco router. We'll choose fw template 3, a firewall with three interfaces, for this example. Click Finish to create a new firewall object using the chosen template.</p>
|
||||
<img src=":/Tutorial/images/2.png">
|
||||
<p>This page of the wizard shows template objects and their configuration. Standard template objects represent firewalls with two or three interfaces, a host with one interface, a web server or a Cisco router. We'll choose fw template 3, a firewall with three interfaces, for this example. Click Finish to create a new firewall object using the chosen template.</p><br>
|
||||
<img src=":/Tutorial/images/2.png"><br>
|
||||
<p>Clicking "Next" brings us to the next page of the wizard where we can change configuration of the interfaces of the template firewall.</p>
|
@ -1,379 +0,0 @@
|
||||
#include "TutorialAnimator.h"
|
||||
#include "../../config.h"
|
||||
#include "global.h"
|
||||
#include "utils.h"
|
||||
#include "utils_no_qt.h"
|
||||
#include "platforms.h"
|
||||
#include "FWWindow.h"
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QComboBox>
|
||||
#include <QTest>
|
||||
#include <QTimer>
|
||||
|
||||
Q_DECLARE_METATYPE(QMenu*);
|
||||
|
||||
using namespace libfwbuilder;
|
||||
using namespace std;
|
||||
|
||||
TutorialAnimator::TutorialAnimator(QObject *parent, QString commands) :
|
||||
QThread(parent)
|
||||
{
|
||||
qRegisterMetaType<QMenu*>("QMenu*");
|
||||
|
||||
// widget = new QWidget(dynamic_cast<QWidget*>(this->parent()));
|
||||
// widget->setFocus(Qt::ActiveWindowFocusReason);
|
||||
//dynamic_cast<QWidget*>(parent)->grabKeyboard();
|
||||
//dynamic_cast<QWidget*>(parent)->grabMouse();
|
||||
dynamic_cast<QWidget*>(parent)->hide();
|
||||
dynamic_cast<QWidget*>(parent)->setWindowModality(Qt::NonModal);
|
||||
currentCommand = 0;
|
||||
this->commands = commands.split('\n');
|
||||
|
||||
helper = new TutorialHelper(this);
|
||||
connect(this, SIGNAL(finished()), this, SLOT(scenarioFinished()));
|
||||
this->speed = 50;
|
||||
}
|
||||
|
||||
TutorialAnimator::~TutorialAnimator()
|
||||
{
|
||||
delete helper;
|
||||
}
|
||||
|
||||
void TutorialAnimator::scenarioFinished()
|
||||
{
|
||||
//dynamic_cast<QWidget*>(this->parent())->releaseKeyboard();
|
||||
//dynamic_cast<QWidget*>(this->parent())->releaseMouse();
|
||||
|
||||
dynamic_cast<QWidget*>(parent())->setWindowModality(Qt::ApplicationModal);
|
||||
dynamic_cast<QWidget*>(this->parent())->show();
|
||||
/*
|
||||
dynamic_cast<QWidget*>(this->parent())->grabMouse();
|
||||
dynamic_cast<QWidget*>(this->parent())->grabKeyboard();
|
||||
dynamic_cast<QWidget*>(this->parent())->releaseKeyboard();
|
||||
dynamic_cast<QWidget*>(this->parent())->releaseMouse();
|
||||
*/
|
||||
dynamic_cast<QWidget*>(this->parent())->raise();
|
||||
}
|
||||
|
||||
void TutorialAnimator::run()
|
||||
{
|
||||
this->helper->blockMouse(true);
|
||||
this->helper->blockInput(true);
|
||||
for (int i=0; i<this->commands.count(); i++)
|
||||
{
|
||||
animate(i);
|
||||
QTest::qWait(speed*20);
|
||||
}
|
||||
this->helper->blockMouse(false);
|
||||
this->helper->blockInput(false);
|
||||
//w->releaseKeyboard();
|
||||
//w->releaseMouse();
|
||||
}
|
||||
|
||||
void TutorialAnimator::animate(int command)
|
||||
{
|
||||
if (command == -1) command = currentCommand;
|
||||
QStringList input = commands.at(command).split(QRegExp("\\s+"));
|
||||
for(int i=0; i<input.size(); i++)
|
||||
{
|
||||
QString str = input.at(i);
|
||||
input[i] = str.replace(QRegExp("\\\\_"), " ");
|
||||
}
|
||||
QString baseCommand = input.first().trimmed();
|
||||
input.removeFirst();
|
||||
if (baseCommand == "moveMouse")
|
||||
moveMouse(input); // input: widget_tree OR x y
|
||||
if (baseCommand == "clickWidget")
|
||||
clickWidget(input); // input: widget_tree
|
||||
if (baseCommand == "typeWidget")
|
||||
typeWidget(input); // input: widget_tree text
|
||||
if (baseCommand == "hoverMenuItem")
|
||||
hoverMenuItem(input); // input: menu_name item_name
|
||||
if (baseCommand == "clickMenuItem")
|
||||
clickMenuItem(input); // input: menu_name item_name
|
||||
if (baseCommand == "selectComboItem")
|
||||
selectComboItem(input); // input: widget_tree item_index
|
||||
if (baseCommand == "selectListItem")
|
||||
selectListItem(input); // input: widget_tree item_index
|
||||
if (baseCommand == "selectTab")
|
||||
selectTab(input); // input: widget_tree item_index
|
||||
if (baseCommand == "wait")
|
||||
wait(input);
|
||||
}
|
||||
|
||||
QObject* TutorialAnimator::findChild(QObject *parent, QString name)
|
||||
{
|
||||
bool lookingForClass = false;
|
||||
if (name.startsWith("w#"))
|
||||
{
|
||||
name.remove(0, 2);
|
||||
lookingForClass = true;
|
||||
qDebug() << "looking for class" << name;
|
||||
}
|
||||
QObjectList queue;
|
||||
queue.append(parent);
|
||||
while(queue.size())
|
||||
{
|
||||
QObject *obj = queue.first();
|
||||
queue.removeFirst();
|
||||
if ( ( (!lookingForClass) && (obj->objectName() == name) ) ||
|
||||
( (lookingForClass) && (obj->metaObject()->className() == name) ) )
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
queue += obj->children();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QWidget* TutorialAnimator::findWidget(QString name)
|
||||
{
|
||||
bool lookingForClass = false;
|
||||
if (name.startsWith("w#"))
|
||||
{
|
||||
name.remove(0, 2);
|
||||
lookingForClass = true;
|
||||
}
|
||||
foreach(QWidget *w, app->allWidgets())
|
||||
{
|
||||
if ( ( (!lookingForClass) && (w->objectName() == name) ) ||
|
||||
( (lookingForClass) && (w->metaObject()->className() == name) ) )
|
||||
return w;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QObject* TutorialAnimator::getWidget(QStringList input)
|
||||
{
|
||||
QObject *obj = findChild(mw, input.first());
|
||||
if (obj == NULL)
|
||||
{
|
||||
obj = findWidget(input.first());
|
||||
if (obj == NULL)
|
||||
{
|
||||
qDebug() << "could not find such object";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
input.removeFirst();
|
||||
if (!input.empty())
|
||||
foreach (QString name, input)
|
||||
{
|
||||
obj = findChild(obj, name);
|
||||
if (obj == NULL)
|
||||
{
|
||||
qDebug() << "could not find such object";
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (obj == NULL)
|
||||
{
|
||||
qDebug() << "could not find such object";
|
||||
return NULL;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
void TutorialAnimator::moveMouse(QStringList input)
|
||||
{
|
||||
qDebug() << "input:" << input;
|
||||
// is first two arguments are ints, click mouse at this coordintates
|
||||
bool isInt1 = false, isInt2 = false;
|
||||
int x, y;
|
||||
if (input.size() == 2)
|
||||
{
|
||||
x = input.at(0).toInt(&isInt1, 10);
|
||||
y = input.at(1).toInt(&isInt2, 10);
|
||||
}
|
||||
if (isInt1 && isInt2)
|
||||
{
|
||||
qDebug() << "moving mouse to (" << x << "," << y << ")";
|
||||
helper->moveMouse(QPoint(x,y));
|
||||
}
|
||||
// if not, they should be widget names
|
||||
// find widget with name of last argument who's parent is previous argument recursively
|
||||
else
|
||||
{
|
||||
QObject *obj = getWidget(input);
|
||||
helper->moveMouse(dynamic_cast<QWidget*>(obj));
|
||||
}
|
||||
}
|
||||
|
||||
QPoint TutorialAnimator::findMenuItemPos(QMenu *menu, QString item)
|
||||
{
|
||||
int x = menu->width()/2;
|
||||
int top, bottom;
|
||||
for (int i=1; i<menu->height()-1; i++)
|
||||
{
|
||||
QAction *action = menu->actionAt(QPoint(x,i));
|
||||
if (action == NULL) continue;
|
||||
if (action->text() == item)
|
||||
{
|
||||
top = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i=menu->height()-1; i>1; i--)
|
||||
{
|
||||
QAction *action = menu->actionAt(QPoint(x,i));
|
||||
if (action == NULL) continue;
|
||||
if (action->text() == item)
|
||||
{
|
||||
bottom = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (top==bottom) return QPoint();
|
||||
return QPoint(x, (top+bottom)/2);
|
||||
}
|
||||
|
||||
QWidget* TutorialAnimator::topLevelWindow(QString className)
|
||||
{
|
||||
foreach (QWidget *w, app->topLevelWidgets())
|
||||
{
|
||||
if (w->metaObject()->className() == className)
|
||||
return w;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TutorialAnimator::hoverMenuItem(QStringList input)
|
||||
{
|
||||
QMenu *menu = dynamic_cast<QMenu*>(findWidget(input.first()));
|
||||
if (menu == NULL)
|
||||
{
|
||||
qDebug() << "could not find menu" << input.first();
|
||||
return;
|
||||
}
|
||||
QPoint pos = findMenuItemPos(menu, input.at(1));
|
||||
helper->moveMouse(dynamic_cast<QWidget*>(menu), pos);
|
||||
}
|
||||
|
||||
void TutorialAnimator::clickMenuItem(QStringList input)
|
||||
{
|
||||
QMenu *menu = dynamic_cast<QMenu*>(findWidget(input.first()));
|
||||
if (menu == NULL)
|
||||
{
|
||||
qDebug() << "could not find menu" << input.first();
|
||||
return;
|
||||
}
|
||||
QPoint pos = findMenuItemPos(menu, input.at(1));
|
||||
QTest::mouseMove(menu, pos);
|
||||
QMetaObject::invokeMethod(helper, "clickMenuItem", Qt::QueuedConnection,
|
||||
Q_ARG(QMenu*, menu), Q_ARG(QPoint, pos));
|
||||
}
|
||||
|
||||
void TutorialAnimator::wait(QStringList input)
|
||||
{
|
||||
if (input.size() < 1)
|
||||
{
|
||||
qDebug() << "Wrong command";
|
||||
return;
|
||||
}
|
||||
bool isInt = false;
|
||||
int n = input.first().toInt(&isInt, 10);
|
||||
if (isInt == false)
|
||||
{
|
||||
qDebug() << "Wrong command";
|
||||
return;
|
||||
}
|
||||
QTest::qWait(n);
|
||||
}
|
||||
|
||||
void TutorialAnimator::clickWidget(QStringList input)
|
||||
{
|
||||
if (input.size() < 1)
|
||||
{
|
||||
qDebug() << "Wrong command";
|
||||
return;
|
||||
}
|
||||
QWidget *w = dynamic_cast<QWidget*>(getWidget(input));
|
||||
if (w == NULL)
|
||||
{
|
||||
qDebug() << "Could not find widget:" << input;
|
||||
return;
|
||||
}
|
||||
QTest::mouseMove(w);
|
||||
QMetaObject::invokeMethod(helper, "clickWidget", Qt::QueuedConnection, Q_ARG(QWidget*, w));
|
||||
}
|
||||
|
||||
void TutorialAnimator::typeWidget(QStringList input)
|
||||
{
|
||||
if (input.size() < 2)
|
||||
{
|
||||
qDebug() << "Wrong command";
|
||||
return;
|
||||
}
|
||||
QString text = input.last();
|
||||
input.pop_back();
|
||||
QWidget *w = dynamic_cast<QWidget*>(getWidget(input));
|
||||
if (w == NULL)
|
||||
{
|
||||
qDebug() << "Could not find widget:" << input;
|
||||
return;
|
||||
}
|
||||
QMetaObject::invokeMethod(helper, "typeWidget", Qt::QueuedConnection,
|
||||
Q_ARG(QWidget*, w), Q_ARG(QString, text));
|
||||
QTest::qWait(text.length()*speed);
|
||||
}
|
||||
|
||||
void TutorialAnimator::selectComboItem(QStringList input)
|
||||
{
|
||||
QString idstr = input.last();
|
||||
bool isId;
|
||||
int id = idstr.toInt(&isId, 10);
|
||||
input.pop_back();
|
||||
QComboBox *combo = dynamic_cast<QComboBox*>(this->getWidget(input));
|
||||
if (isId)
|
||||
QMetaObject::invokeMethod(helper, "selectComboItem", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QWidget*, dynamic_cast<QWidget*>(combo)), Q_ARG(int, id));
|
||||
else
|
||||
QMetaObject::invokeMethod(helper, "selectComboItem", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QWidget*, dynamic_cast<QWidget*>(combo)), Q_ARG(QString, idstr));
|
||||
}
|
||||
|
||||
void TutorialAnimator::selectListItem(QStringList input)
|
||||
{
|
||||
QString idstr = input.last();
|
||||
bool isId;
|
||||
int id = idstr.toInt(&isId, 10);
|
||||
input.pop_back();
|
||||
qDebug() << "view:" << this->getWidget(input);
|
||||
QAbstractItemView *combo = dynamic_cast<QAbstractItemView*>(this->getWidget(input));
|
||||
qDebug() << "selecting list item:" << combo;
|
||||
if (isId)
|
||||
QMetaObject::invokeMethod(helper, "selectListItem", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QWidget*, dynamic_cast<QWidget*>(combo)), Q_ARG(int, id));
|
||||
else
|
||||
QMetaObject::invokeMethod(helper, "selectListItem", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QWidget*, dynamic_cast<QWidget*>(combo)), Q_ARG(QString, idstr));
|
||||
}
|
||||
|
||||
void TutorialAnimator::selectTab(QStringList input)
|
||||
{
|
||||
QString idstr = input.last();
|
||||
bool isId;
|
||||
int id = idstr.toInt(&isId, 10);
|
||||
input.pop_back();
|
||||
qDebug() << "view:" << this->getWidget(input);
|
||||
QTabWidget *combo = dynamic_cast<QTabWidget*>(this->getWidget(input));
|
||||
qDebug() << "selecting tab in widget:" << combo;
|
||||
if (isId)
|
||||
QMetaObject::invokeMethod(helper, "selectTab", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QWidget*, dynamic_cast<QWidget*>(combo)), Q_ARG(int, id));
|
||||
else
|
||||
QMetaObject::invokeMethod(helper, "selectTab", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QWidget*, dynamic_cast<QWidget*>(combo)), Q_ARG(QString, idstr));
|
||||
}
|
||||
|
||||
void TutorialAnimator::setSpeed(int speed)
|
||||
{
|
||||
this->speed = speed;
|
||||
this->helper->speed = speed;
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
#ifndef TUTORIALANIMATOR_H
|
||||
#define TUTORIALANIMATOR_H
|
||||
|
||||
#include <QMenu>
|
||||
#include <QPoint>
|
||||
#include <QThread>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QAction>
|
||||
|
||||
#include "TutorialHelper.h"
|
||||
|
||||
class TutorialAnimator : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
int speed;
|
||||
TutorialHelper *helper;
|
||||
QWidget *widget;
|
||||
|
||||
QStringList commands;
|
||||
int currentCommand;
|
||||
|
||||
void animate(int command);
|
||||
void moveMouse(QStringList input);
|
||||
void clickWidget(QStringList input);
|
||||
void typeWidget(QStringList input);
|
||||
void wait(QStringList input);
|
||||
void hoverMenuItem(QStringList input);
|
||||
void clickMenuItem(QStringList input);
|
||||
void selectComboItem(QStringList input);
|
||||
void selectListItem(QStringList input);
|
||||
void selectTab(QStringList input);
|
||||
|
||||
|
||||
public:
|
||||
explicit TutorialAnimator(QObject *parent, QString commands);
|
||||
~TutorialAnimator();
|
||||
void run();
|
||||
void setSpeed(int speed);
|
||||
|
||||
QObject* findChild(QObject *parent, QString name);
|
||||
QWidget* findWidget(QString name);
|
||||
QPoint findMenuItemPos(QMenu *menu, QString item);
|
||||
QObject* getWidget(QStringList input);
|
||||
QWidget* topLevelWindow(QString);
|
||||
|
||||
public slots:
|
||||
void scenarioFinished();
|
||||
|
||||
};
|
||||
|
||||
#endif // TUTORIALANIMATOR_H
|
@ -9,25 +9,9 @@ TutorialDialog::TutorialDialog(QWidget *parent) :
|
||||
ui(new Ui::TutorialDialog_q)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
animator = NULL;
|
||||
currentPage = 0;
|
||||
this->setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
this->setWindowModality(Qt::ApplicationModal);
|
||||
|
||||
QFile f(QString(":/Tutorial/controls.txt"));
|
||||
f.open(QFile::ReadOnly);
|
||||
foreach(QString line, QString(f.readAll()).split("\n"))
|
||||
{
|
||||
QStringList parts = line.split(" ");
|
||||
if (parts.size() < 3) continue;
|
||||
bool ok;
|
||||
int page = parts.at(0).toInt(&ok, 10);
|
||||
prevEnabled[page] = parts.at(2) == "true";
|
||||
requiresPrev[page] = parts.at(1) == "true";
|
||||
qDebug() << requiresPrev;
|
||||
}
|
||||
|
||||
|
||||
//this->setWindowModality(Qt::ApplicationModal);
|
||||
showPage(currentPage);
|
||||
}
|
||||
|
||||
@ -61,67 +45,25 @@ void TutorialDialog::next()
|
||||
|
||||
void TutorialDialog::previous()
|
||||
{
|
||||
runScenario(getUndoForPage(currentPage));
|
||||
currentPage--;
|
||||
showPage(currentPage);
|
||||
}
|
||||
|
||||
void TutorialDialog::reset()
|
||||
{
|
||||
runScenario(getResetForPage(currentPage));
|
||||
currentPage = 0;
|
||||
showPage(currentPage);
|
||||
}
|
||||
|
||||
void TutorialDialog::runScenario(QString scenario)
|
||||
{
|
||||
if (animator != NULL) animator->deleteLater();
|
||||
animator = new TutorialAnimator(this, scenario);
|
||||
animator->setSpeed(ui->speed->value());
|
||||
animator->start();
|
||||
}
|
||||
|
||||
QString TutorialDialog::getScenarioForPage(int page)
|
||||
{
|
||||
QFile src(QString(":/Tutorial/commands/page") + QString::number(page) + ".txt");
|
||||
src.open(QFile::ReadOnly);
|
||||
return QString(src.readAll());
|
||||
}
|
||||
|
||||
QString TutorialDialog::getUndoForPage(int page)
|
||||
{
|
||||
QFile src(QString(":/Tutorial/prev-commands/page") + QString::number(page) + ".txt");
|
||||
src.open(QFile::ReadOnly);
|
||||
return QString(src.readAll());
|
||||
}
|
||||
|
||||
QString TutorialDialog::getResetForPage(int page)
|
||||
{
|
||||
QFile src(QString(":/Tutorial/reset-commands/page") + QString::number(page) + ".txt");
|
||||
src.open(QFile::ReadOnly);
|
||||
return QString(src.readAll());
|
||||
}
|
||||
|
||||
void TutorialDialog::showPage(int page)
|
||||
{
|
||||
ui->demonstrate->setEnabled(true);
|
||||
QString filename = QString(":/Tutorial/html/page") + QString::number(page) + ".html";
|
||||
QFile src(filename);
|
||||
src.open(QFile::ReadOnly);
|
||||
QString text = src.readAll();
|
||||
ui->content->setText(text);
|
||||
qDebug() << "next should be enabled:" << page+1 << requiresPrev[page+1];
|
||||
bool nextPageExists = QFile::exists(QString(":/Tutorial/html/page") + QString::number(page+1) + ".html");
|
||||
ui->next->setEnabled(nextPageExists && (!requiresPrev[page+1]));
|
||||
ui->message->setVisible(nextPageExists && requiresPrev[page+1]);
|
||||
ui->prev->setEnabled(prevEnabled[page]);
|
||||
}
|
||||
|
||||
void TutorialDialog::demonstrate()
|
||||
{
|
||||
ui->demonstrate->setEnabled(false);
|
||||
runScenario(getScenarioForPage(currentPage));
|
||||
ui->next->setEnabled(QFile::exists(QString(":/Tutorial/html/page") + QString::number(currentPage+1) + ".html"));
|
||||
if (QFile::exists(QString(":/Tutorial/html/page") + QString::number(currentPage+1) + ".html"))
|
||||
showPage(++currentPage);
|
||||
bool prevPageExists = QFile::exists(QString(":/Tutorial/html/page") + QString::number(page-1) + ".html");
|
||||
ui->next->setEnabled(nextPageExists);
|
||||
ui->prev->setEnabled(prevPageExists);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
#define TUTORIALDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "TutorialAnimator.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
@ -28,15 +27,11 @@ protected:
|
||||
private:
|
||||
Ui::TutorialDialog_q *ui;
|
||||
int currentPage;
|
||||
TutorialAnimator *animator;
|
||||
QMap<int, bool> prevEnabled;
|
||||
QMap<int, bool> requiresPrev;
|
||||
|
||||
public slots:
|
||||
void previous();
|
||||
void next();
|
||||
void reset();
|
||||
void demonstrate();
|
||||
void showPage(int page);
|
||||
};
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>136</width>
|
||||
<height>494</height>
|
||||
<height>562</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -64,72 +64,6 @@
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Speed:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="speed">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>30</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="demonstrate">
|
||||
<property name="text">
|
||||
<string>Demonstrate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="message">
|
||||
<property name="text">
|
||||
<string>View demonstration to proceed to next step.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="sizeConstraint">
|
||||
@ -205,6 +139,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@ -212,14 +159,14 @@
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>next</sender>
|
||||
<sender>reset</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>TutorialDialog_q</receiver>
|
||||
<slot>next()</slot>
|
||||
<slot>reset()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>421</x>
|
||||
<y>514</y>
|
||||
<x>340</x>
|
||||
<y>619</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>241</x>
|
||||
@ -234,8 +181,8 @@
|
||||
<slot>previous()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>217</x>
|
||||
<y>514</y>
|
||||
<x>242</x>
|
||||
<y>619</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>241</x>
|
||||
@ -244,14 +191,14 @@
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>reset</sender>
|
||||
<sender>next</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>TutorialDialog_q</receiver>
|
||||
<slot>reset()</slot>
|
||||
<slot>next()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>319</x>
|
||||
<y>514</y>
|
||||
<x>438</x>
|
||||
<y>619</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>241</x>
|
||||
@ -260,18 +207,18 @@
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>demonstrate</sender>
|
||||
<sender>pushButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>TutorialDialog_q</receiver>
|
||||
<slot>demonstrate()</slot>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>410</x>
|
||||
<y>472</y>
|
||||
<x>507</x>
|
||||
<y>603</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>241</x>
|
||||
<y>271</y>
|
||||
<x>551</x>
|
||||
<y>609</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
@ -280,6 +227,5 @@
|
||||
<slot>previous()</slot>
|
||||
<slot>next()</slot>
|
||||
<slot>reset()</slot>
|
||||
<slot>demonstrate()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
|
@ -1,211 +0,0 @@
|
||||
#include "TutorialHelper.h"
|
||||
#include <QTest>
|
||||
#include <QDebug>
|
||||
#include <QMenu>
|
||||
#include <QAbstractItemView>
|
||||
#include <QDesktopWidget>
|
||||
#include <QApplication>
|
||||
#include <QCursor>
|
||||
#include "global.h"
|
||||
#include "FWWindow.h"
|
||||
#include "TutorialAnimator.h"
|
||||
|
||||
TutorialHelper::TutorialHelper(QObject* parent): QObject(parent)
|
||||
{
|
||||
speed = 50;
|
||||
widget = dynamic_cast<QWidget*>(parent->parent());//NULL;
|
||||
mouseBlocker = NULL;
|
||||
}
|
||||
|
||||
void TutorialHelper::blockInput(bool block)
|
||||
{
|
||||
if (block)
|
||||
{
|
||||
if (this->widget == NULL)
|
||||
this->widget = new QWidget();
|
||||
this->widget->grabKeyboard();
|
||||
this->widget->grabMouse();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->widget == NULL) return;
|
||||
this->widget->releaseKeyboard();
|
||||
this->widget->releaseMouse();
|
||||
}
|
||||
}
|
||||
|
||||
void TutorialHelper::blockMouse(bool block)
|
||||
{
|
||||
if (block)
|
||||
{
|
||||
if (mouseBlocker == NULL)
|
||||
mouseBlocker = new MouseBlocker();
|
||||
mouseBlocker->start();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mouseBlocker == NULL) return;
|
||||
mouseBlocker->die();
|
||||
mouseBlocker->terminate();
|
||||
// mouseBlocker->deleteLater();
|
||||
delete mouseBlocker;
|
||||
mouseBlocker = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void TutorialHelper::moveMouse(QPoint end)
|
||||
{
|
||||
qreal distance = QLineF(QCursor::pos(), end).length();
|
||||
qreal screenSize = QLineF(QPoint(0,0), QApplication::desktop()->geometry().bottomRight()).length();
|
||||
qreal time = (speed*2) * distance / screenSize;
|
||||
qreal step = distance / time;
|
||||
|
||||
int timestep = time / (distance/step);
|
||||
while (QLineF(QCursor::pos(), end).length() > step)
|
||||
{
|
||||
QLineF line(QCursor::pos(), end);
|
||||
line.setLength(step);
|
||||
QCursor::setPos(line.p2().toPoint());
|
||||
QTest::qWait(timestep);
|
||||
}
|
||||
QCursor::setPos(end);
|
||||
}
|
||||
|
||||
void TutorialHelper::moveMouse(QWidget *w, QPoint userpoint)
|
||||
{
|
||||
QPoint pos;
|
||||
if (userpoint == QPoint(-1,-1))
|
||||
pos = w->mapToGlobal(w->rect().center());
|
||||
else
|
||||
pos = w->mapToGlobal(userpoint);
|
||||
moveMouse(pos);
|
||||
}
|
||||
|
||||
void TutorialHelper::clickWidget(QWidget *w)
|
||||
{
|
||||
this->blockInput(false);
|
||||
QTest::mouseClick(w, Qt::LeftButton, Qt::NoModifier, QPoint(), speed*4);
|
||||
this->blockInput(true);
|
||||
}
|
||||
|
||||
void TutorialHelper::clickMenuItem(QMenu *menu, QPoint pos)
|
||||
{
|
||||
this->blockInput(false);
|
||||
QTest::mouseClick(menu, Qt::LeftButton, Qt::NoModifier, pos, speed);
|
||||
this->blockInput(true);
|
||||
}
|
||||
|
||||
void TutorialHelper::typeWidget(QWidget *w, QString text)
|
||||
{
|
||||
this->blockInput(false);
|
||||
QTest::keyClicks(w, text, Qt::NoModifier, 50);
|
||||
this->blockInput(true);
|
||||
}
|
||||
|
||||
QPoint TutorialHelper::findViewItem(QAbstractItemView *view, int id)
|
||||
{
|
||||
int x = view->width() / 5;
|
||||
int top = -1, bottom = -1;
|
||||
for (top=0; top<view->height(); top++)
|
||||
{
|
||||
if (view->indexAt(QPoint(x, top)).row() == id)
|
||||
break;
|
||||
}
|
||||
for (bottom=view->height(); bottom != 0; bottom--)
|
||||
{
|
||||
if (view->indexAt(QPoint(x, bottom)).row() == id)
|
||||
break;
|
||||
}
|
||||
return QPoint(x, (top+bottom)/2);
|
||||
}
|
||||
|
||||
void TutorialHelper::selectComboItem(QWidget *widget, int id)
|
||||
{
|
||||
QComboBox * combo = dynamic_cast<QComboBox*>(widget);
|
||||
moveMouse(combo);
|
||||
this->blockInput(false);
|
||||
QTest::mouseClick(combo, Qt::LeftButton);
|
||||
this->blockInput(true);
|
||||
QPoint itemPos = this->findViewItem(combo->view(), id);
|
||||
QTest::qWait(speed*4);
|
||||
moveMouse(combo->view(), itemPos);
|
||||
this->blockInput(false);
|
||||
QTest::mouseClick(combo->view(), Qt::LeftButton, 0, itemPos);
|
||||
this->blockInput(true);
|
||||
}
|
||||
|
||||
void TutorialHelper::selectComboItem(QWidget *widget, QString name)
|
||||
{
|
||||
QComboBox * combo = dynamic_cast<QComboBox*>(widget);
|
||||
int id = combo->findText(name);
|
||||
selectComboItem(widget, id);
|
||||
}
|
||||
|
||||
void TutorialHelper::selectListItem(QWidget *widget, int id)
|
||||
{
|
||||
QAbstractItemView *view = dynamic_cast<QAbstractItemView*>(widget);
|
||||
QPoint itemPos = findViewItem(view, id);
|
||||
view->scrollTo(view->indexAt(itemPos));
|
||||
itemPos = findViewItem(view, id);
|
||||
moveMouse(view, itemPos);
|
||||
view->setCurrentIndex(view->indexAt(itemPos));
|
||||
this->blockInput(false);
|
||||
QTest::mouseClick(view, Qt::LeftButton, 0, itemPos);
|
||||
this->blockInput(true);
|
||||
}
|
||||
|
||||
void TutorialHelper::selectListItem(QWidget *widget, QString name)
|
||||
{
|
||||
QAbstractItemView * view = dynamic_cast<QAbstractItemView*>(widget);
|
||||
int id = 0;
|
||||
for (; id < view->model()->rowCount(); id++)
|
||||
if (view->model()->data(view->model()->index(id, 0, QModelIndex())).toString() == name)
|
||||
break;
|
||||
selectListItem(widget, id);
|
||||
}
|
||||
|
||||
class PublicTabBar : public QTabWidget { public: using QTabWidget::tabBar; };
|
||||
|
||||
QPoint findTab(QTabBar *bar, int id)
|
||||
{
|
||||
int x = bar->width()/2;
|
||||
int top, bottom, left, right;
|
||||
for (top=0; top<bar->height(); top++)
|
||||
if (bar->tabAt(QPoint(x, top)) == id)
|
||||
break;
|
||||
for (bottom = bar->height(); bottom != 0; bottom--)
|
||||
if (bar->tabAt(QPoint(x, bottom)) == id)
|
||||
break;
|
||||
int y = bar->height()/2;
|
||||
for (left = 0; left < bar->width(); left++)
|
||||
if (bar->tabAt(QPoint(left, y)) == id)
|
||||
break;
|
||||
for (right = bar->width(); right!=0; right--)
|
||||
if (bar->tabAt(QPoint(right, y)) == id)
|
||||
break;
|
||||
return QPoint((left+right)/2, (top+bottom)/2);
|
||||
}
|
||||
|
||||
void TutorialHelper::selectTab(QWidget *widget, int id)
|
||||
{
|
||||
QTabBar *bar = dynamic_cast<QTabBar*>(dynamic_cast<TutorialAnimator*>(parent())->findChild(widget, "w#QTabBar"));
|
||||
QPoint pos = findTab(bar, id);
|
||||
moveMouse(bar, pos);
|
||||
QTest::qWait(speed*4);
|
||||
this->blockInput(false);
|
||||
QTest::mouseClick(bar, Qt::LeftButton, 0, pos);
|
||||
this->blockInput(true);
|
||||
|
||||
}
|
||||
|
||||
void TutorialHelper::selectTab(QWidget *widget, QString name)
|
||||
{
|
||||
QTabWidget * view = dynamic_cast<QTabWidget*>(widget);
|
||||
int id = 0;
|
||||
for (; id < view->count(); id++)
|
||||
if (view->tabText(id) == name)
|
||||
break;
|
||||
selectTab(widget, id);
|
||||
}
|
||||
|
||||
|
@ -1,36 +0,0 @@
|
||||
#ifndef TUTORIALHELPER_H
|
||||
#define TUTORIALHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMenu>
|
||||
#include <QComboBox>
|
||||
#include "MouseBlocker.h"
|
||||
|
||||
class TutorialHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QWidget *widget;
|
||||
MouseBlocker *mouseBlocker;
|
||||
public:
|
||||
int speed;
|
||||
TutorialHelper(QObject *parent = NULL);
|
||||
public slots:
|
||||
void clickWidget(QWidget*);
|
||||
void clickMenuItem(QMenu *menu, QPoint pos);
|
||||
void typeWidget(QWidget *w, QString text);
|
||||
void selectComboItem(QWidget *box, int id);
|
||||
void selectComboItem(QWidget *box, QString name);
|
||||
void selectListItem(QWidget *box, int id);
|
||||
void selectListItem(QWidget *box, QString name);
|
||||
void moveMouse(QPoint end);
|
||||
void moveMouse(QWidget *w, QPoint userpoint = QPoint(-1,-1));
|
||||
void selectTab(QWidget *widget, QString name);
|
||||
void selectTab(QWidget *widget, int id);
|
||||
|
||||
void blockInput(bool value);
|
||||
void blockMouse(bool value);
|
||||
|
||||
QPoint findViewItem(QAbstractItemView *view, int id);
|
||||
};
|
||||
|
||||
#endif // TUTORIALHELPER_H
|
@ -175,10 +175,7 @@ HEADERS += ../../config.h \
|
||||
FWCmdRule.h \
|
||||
UsageResolver.h \
|
||||
IconSetter.h \
|
||||
TutorialAnimator.h \
|
||||
TutorialDialog.h \
|
||||
TutorialHelper.h \
|
||||
MouseBlocker.h
|
||||
TutorialDialog.h
|
||||
SOURCES += ProjectPanel.cpp \
|
||||
ProjectPanel_events.cpp \
|
||||
ProjectPanel_file_ops.cpp \
|
||||
@ -351,10 +348,7 @@ SOURCES += ProjectPanel.cpp \
|
||||
FWCmdRule.cpp \
|
||||
IconSetter.cpp \
|
||||
UsageResolver.cpp \
|
||||
TutorialAnimator.cpp \
|
||||
TutorialDialog.cpp \
|
||||
TutorialHelper.cpp \
|
||||
MouseBlocker.cpp
|
||||
TutorialDialog.cpp
|
||||
FORMS = FWBMainWindow_q.ui \
|
||||
compileroutputpanel_q.ui \
|
||||
customservicedialog_q.ui \
|
||||
|
Loading…
x
Reference in New Issue
Block a user