mirror of
https://github.com/fwbuilder/fwbuilder
synced 2026-03-25 04:37:22 +01:00
Tutorial dialog now shows instructions on every step of new firewall dialog.
Tab selection now possible with scenario file. Added directories for prev and reset instructions (looks like simple undo will not work here).
This commit is contained in:
parent
e1c077eb09
commit
7a6fab95b6
@ -300,5 +300,10 @@
|
||||
<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,48 +1,4 @@
|
||||
moveMouse om newButton
|
||||
wait 1000
|
||||
clickWidget om newButton
|
||||
wait 1000
|
||||
hoverMenuItem newObjectPopup New\_Firewall
|
||||
wait 1000
|
||||
clickMenuItem newObjectPopup New\_Firewall
|
||||
wait 1000
|
||||
moveMouse w#newFirewallDialog obj_name
|
||||
clickMouse w#newFirewallDialog obj_name
|
||||
wait 100
|
||||
typeWidget w#newFirewallDialog obj_name guardian
|
||||
wait 1000
|
||||
hoverComboItem w#newFirewallDialog platform iptables
|
||||
wait 1000
|
||||
selectComboItem w#newFirewallDialog platform iptables
|
||||
wait 1000
|
||||
selectComboItem w#newFirewallDialog hostOS Linux\_2.4/2.6
|
||||
wait 1000
|
||||
moveMouse w#newFirewallDialog useTemplate
|
||||
clickWidget w#newFirewallDialog useTemplate
|
||||
wait 1000
|
||||
moveMouse w#newFirewallDialog templateUseStandart
|
||||
clickWidget w#newFirewallDialog templateUseStandart
|
||||
wait 1000
|
||||
moveMouse w#newFirewallDialog nextButton
|
||||
clickWidget w#newFirewallDialog nextButton
|
||||
wait 1000
|
||||
|
||||
// first dialog page finished
|
||||
|
||||
selectListItem w#newFirewallDialog templateList fw\_template\_3
|
||||
wait 1000
|
||||
moveMouse w#newFirewallDialog nextButton
|
||||
clickWidget w#newFirewallDialog nextButton
|
||||
wait 1000
|
||||
|
||||
|
||||
// second dialog page finished
|
||||
|
||||
wait 1000
|
||||
selectTab w#newFirewallDialog interfaceEditor2 1
|
||||
wait 1000
|
||||
|
||||
moveMouse w#newFirewallDialog finishButton
|
||||
wait 1000
|
||||
clickWidget w#newFirewallDialog finishButton
|
||||
wait 1000
|
||||
clickMenuItem newObjectPopup New\_Firewall
|
||||
@ -1 +1,11 @@
|
||||
typeWidget newFirewallDialog_q obj_name guardian
|
||||
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
|
||||
|
||||
3
src/gui/Tutorial/commands/page2.txt
Normal file
3
src/gui/Tutorial/commands/page2.txt
Normal file
@ -0,0 +1,3 @@
|
||||
selectListItem w#newFirewallDialog templateList fw\_template\_3
|
||||
moveMouse w#newFirewallDialog nextButton
|
||||
clickWidget w#newFirewallDialog nextButton
|
||||
5
src/gui/Tutorial/commands/page3.txt
Normal file
5
src/gui/Tutorial/commands/page3.txt
Normal file
@ -0,0 +1,5 @@
|
||||
selectTab w#newFirewallDialog interfaceEditor2 1
|
||||
selectTab w#newFirewallDialog interfaceEditor2 2
|
||||
selectTab w#newFirewallDialog interfaceEditor2 0
|
||||
moveMouse w#newFirewallDialog finishButton
|
||||
clickWidget w#newFirewallDialog finishButton
|
||||
4
src/gui/Tutorial/controls.txt
Normal file
4
src/gui/Tutorial/controls.txt
Normal file
@ -0,0 +1,4 @@
|
||||
#page requiresPrevPageDemonstrated prevEnabled undoActionCount
|
||||
0 true false
|
||||
1 true false
|
||||
2 true false
|
||||
3
src/gui/Tutorial/html/page2.html
Normal file
3
src/gui/Tutorial/html/page2.html
Normal file
@ -0,0 +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>Clicking "Next" brings us to the next page of the wizard where we can change configuration of the interfaces of the template firewall.</p>
|
||||
3
src/gui/Tutorial/html/page3.html
Normal file
3
src/gui/Tutorial/html/page3.html
Normal file
@ -0,0 +1,3 @@
|
||||
Here each tab represents an interface of the firewall (eth0, eth1, eth2 and lo). You can change interface name, label, its type and edit, add or remove IP addresses. You can manage both IPv4 and IPv6 addresses on this page of the wizard.<br>
|
||||
<br>
|
||||
Template object is preconfigured with generic IP addresses that likely do not match addressing scheme you use on your network. This page of the wizard allows you to change addresses to match your setup.
|
||||
@ -31,22 +31,31 @@ TutorialAnimator::TutorialAnimator(QObject *parent, QString commands) :
|
||||
|
||||
helper = new TutorialHelper();
|
||||
connect(this, SIGNAL(finished()), this, SLOT(scenarioFinished()));
|
||||
this->start();
|
||||
this->speed = 50;
|
||||
}
|
||||
|
||||
void TutorialAnimator::scenarioFinished()
|
||||
{
|
||||
//dynamic_cast<QWidget*>(this->parent())->releaseKeyboard();
|
||||
//dynamic_cast<QWidget*>(this->parent())->releaseMouse();
|
||||
|
||||
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())->show();
|
||||
*/
|
||||
dynamic_cast<QWidget*>(this->parent())->raise();
|
||||
}
|
||||
|
||||
void TutorialAnimator::run()
|
||||
{
|
||||
for (int i=0; i<this->commands.count(); i++)
|
||||
{
|
||||
animate(i);
|
||||
// dynamic_cast<QWidget*>(this->parent())->show();
|
||||
QTest::qWait(speed*20);
|
||||
}
|
||||
//w->releaseKeyboard();
|
||||
//w->releaseMouse();
|
||||
}
|
||||
@ -76,6 +85,8 @@ void TutorialAnimator::animate(int command)
|
||||
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);
|
||||
}
|
||||
@ -298,7 +309,7 @@ void TutorialAnimator::typeWidget(QStringList input)
|
||||
}
|
||||
QMetaObject::invokeMethod(helper, "typeWidget", Qt::QueuedConnection,
|
||||
Q_ARG(QWidget*, w), Q_ARG(QString, text));
|
||||
QTest::qWait(text.length()*50);
|
||||
QTest::qWait(text.length()*speed);
|
||||
}
|
||||
|
||||
void TutorialAnimator::selectComboItem(QStringList input)
|
||||
@ -340,8 +351,8 @@ void TutorialAnimator::selectTab(QStringList input)
|
||||
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;
|
||||
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));
|
||||
@ -349,3 +360,9 @@ void TutorialAnimator::selectTab(QStringList input)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
class TutorialAnimator : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
int speed;
|
||||
TutorialHelper *helper;
|
||||
QWidget *widget;
|
||||
|
||||
@ -30,14 +31,17 @@ Q_OBJECT
|
||||
void selectListItem(QStringList input);
|
||||
void selectTab(QStringList input);
|
||||
|
||||
|
||||
public:
|
||||
explicit TutorialAnimator(QObject *parent, QString commands);
|
||||
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:
|
||||
explicit TutorialAnimator(QObject *parent, QString commands);
|
||||
void run();
|
||||
|
||||
public slots:
|
||||
void scenarioFinished();
|
||||
|
||||
@ -4,10 +4,6 @@
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
|
||||
#define TUTORIALS_DIR "/Users/a2k/prog/fwbuilder/fwbuilder400.app/Contents/Resources/tutorials"
|
||||
//../Contents/Resources/tutorials"
|
||||
#define FS_SEPARATOR "/"
|
||||
|
||||
TutorialDialog::TutorialDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::TutorialDialog_q)
|
||||
@ -15,9 +11,24 @@ TutorialDialog::TutorialDialog(QWidget *parent) :
|
||||
ui->setupUi(this);
|
||||
animator = NULL;
|
||||
currentPage = 0;
|
||||
showPage(currentPage);
|
||||
this->setWindowFlags(this->windowFlags() | Qt::WindowStaysOnTopHint);
|
||||
// ui->content->setMaximumWidth(ui->scrollArea->viewport()->width());
|
||||
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.length() < 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;
|
||||
}
|
||||
|
||||
|
||||
showPage(currentPage);
|
||||
}
|
||||
|
||||
void TutorialDialog::resizeEvent(QResizeEvent *)
|
||||
@ -69,19 +80,30 @@ QString TutorialDialog::getScenarioForPage(int page)
|
||||
|
||||
void TutorialDialog::showPage(int page)
|
||||
{
|
||||
ui->demonstrate->setEnabled(true);
|
||||
QString filename = QString(":/Tutorial/html/page") + QString::number(page) + ".html";
|
||||
qDebug() << filename;
|
||||
QFile src(filename);
|
||||
src.open(QFile::ReadOnly);
|
||||
QString text = src.readAll();
|
||||
qDebug() << text;
|
||||
ui->content->setText(text);
|
||||
ui->next->setEnabled(QFile::exists(QString(":/Tutorial/html/page") + QString::number(page+1) + ".html"));
|
||||
ui->prev->setEnabled(QFile::exists(QString(":/Tutorial/html/page") + QString::number(page-1) + ".html"));
|
||||
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);
|
||||
if (animator != NULL) delete animator;
|
||||
animator = new TutorialAnimator(this, getScenarioForPage(currentPage));
|
||||
animator->setSpeed(ui->speed->value());
|
||||
animator->start();
|
||||
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);
|
||||
}
|
||||
//ui->message->setVisible(false);
|
||||
}
|
||||
|
||||
@ -26,6 +26,8 @@ private:
|
||||
Ui::TutorialDialog_q *ui;
|
||||
int currentPage;
|
||||
TutorialAnimator *animator;
|
||||
QMap<int, bool> prevEnabled;
|
||||
QMap<int, bool> requiresPrev;
|
||||
|
||||
public slots:
|
||||
void previous();
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>136</width>
|
||||
<height>520</height>
|
||||
<height>494</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -79,6 +79,38 @@
|
||||
</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">
|
||||
@ -88,6 +120,16 @@
|
||||
</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">
|
||||
|
||||
@ -8,44 +8,26 @@
|
||||
#include <QCursor>
|
||||
#include "global.h"
|
||||
#include "FWWindow.h"
|
||||
#include "math.h"
|
||||
#include "TutorialAnimator.h"
|
||||
|
||||
TutorialHelper::TutorialHelper()
|
||||
{
|
||||
}
|
||||
|
||||
int vectorLength(QPoint a, QPoint b)
|
||||
{
|
||||
return QLineF(a, b).length();
|
||||
}
|
||||
|
||||
QPoint getDirections(QPoint from, QPoint to, int step)
|
||||
{
|
||||
int y = to.y() - from.y(), x = to.x() - from.x();
|
||||
double direction = fabs(atan(((double)(y)/x)));
|
||||
int vstep, hstep;
|
||||
vstep = step*sin(direction);
|
||||
hstep = step*cos(direction);
|
||||
if (x<0) hstep = -abs(hstep);
|
||||
if (y<0) vstep = -abs(vstep);
|
||||
|
||||
return QPoint(hstep, vstep);
|
||||
speed = 50;
|
||||
}
|
||||
|
||||
void TutorialHelper::moveMouse(QPoint end)
|
||||
{
|
||||
qDebug() << end;
|
||||
QPoint start = QCursor::pos();
|
||||
int length = vectorLength(start, end);
|
||||
int maxlen = vectorLength(QPoint(0,0), QPoint(QApplication::desktop()->width(), QApplication::desktop()->height()));
|
||||
double time = 100*(((double)length)/maxlen);
|
||||
int step = ((double)length)/time;
|
||||
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 / (length/step);
|
||||
while (vectorLength(QCursor::pos(), end) > step)
|
||||
int timestep = time / (distance/step);
|
||||
while (QLineF(QCursor::pos(), end).length() > step)
|
||||
{
|
||||
QPoint newpos = QCursor::pos() + getDirections(QCursor::pos(), end, step);
|
||||
QCursor::setPos(newpos);
|
||||
QLineF line(QCursor::pos(), end);
|
||||
line.setLength(step);
|
||||
QCursor::setPos(line.p2().toPoint());
|
||||
QTest::qWait(timestep);
|
||||
}
|
||||
QCursor::setPos(end);
|
||||
@ -63,12 +45,12 @@ void TutorialHelper::moveMouse(QWidget *w, QPoint userpoint)
|
||||
|
||||
void TutorialHelper::clickWidget(QWidget *w)
|
||||
{
|
||||
QTest::mouseClick(w, Qt::LeftButton, Qt::NoModifier, QPoint(), 0);
|
||||
QTest::mouseClick(w, Qt::LeftButton, Qt::NoModifier, QPoint(), speed*4);
|
||||
}
|
||||
|
||||
void TutorialHelper::clickMenuItem(QMenu *menu, QPoint pos)
|
||||
{
|
||||
QTest::mouseClick(menu, Qt::LeftButton, Qt::NoModifier, pos);
|
||||
QTest::mouseClick(menu, Qt::LeftButton, Qt::NoModifier, pos, speed);
|
||||
}
|
||||
|
||||
void TutorialHelper::typeWidget(QWidget *w, QString text)
|
||||
@ -99,7 +81,7 @@ void TutorialHelper::selectComboItem(QWidget *widget, int id)
|
||||
moveMouse(combo);
|
||||
QTest::mouseClick(combo, Qt::LeftButton);
|
||||
QPoint itemPos = this->findViewItem(combo->view(), id);
|
||||
QTest::qWait(200);
|
||||
QTest::qWait(speed*4);
|
||||
moveMouse(combo->view(), itemPos);
|
||||
QTest::mouseClick(combo->view(), Qt::LeftButton, 0, itemPos);
|
||||
}
|
||||
@ -151,17 +133,16 @@ QPoint findTab(QTabBar *bar, int id)
|
||||
for (right = bar->width(); right!=0; right--)
|
||||
if (bar->tabAt(QPoint(right, y)) == id)
|
||||
break;
|
||||
qDebug() << left << right << top << bottom;
|
||||
return QPoint((left+right)/2, (top+bottom)/2);
|
||||
}
|
||||
|
||||
void TutorialHelper::selectTab(QWidget *widget, int id)
|
||||
{
|
||||
PublicTabBar *tabs = dynamic_cast<PublicTabBar*>(widget);
|
||||
QTabBar *bar = tabs->tabBar();
|
||||
|
||||
QTabBar *bar = dynamic_cast<QTabBar*>(dynamic_cast<TutorialAnimator*>(parent())->findChild(widget, "w#QTabBar"));
|
||||
QPoint pos = findTab(bar, id);
|
||||
moveMouse(bar, pos);
|
||||
QTest::qWait(200);
|
||||
QTest::qWait(speed*4);
|
||||
QTest::mouseClick(bar, Qt::LeftButton, 0, pos);
|
||||
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ class TutorialHelper : public QObject
|
||||
Q_OBJECT
|
||||
QWidget *widget;
|
||||
public:
|
||||
int speed;
|
||||
TutorialHelper();
|
||||
public slots:
|
||||
void clickWidget(QWidget*);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user