1
0
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:
Roman Bovsunivskiy 2010-02-20 20:41:53 +00:00
parent e1c077eb09
commit 7a6fab95b6
15 changed files with 160 additions and 102 deletions

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
selectListItem w#newFirewallDialog templateList fw\_template\_3
moveMouse w#newFirewallDialog nextButton
clickWidget w#newFirewallDialog nextButton

View 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

View File

@ -0,0 +1,4 @@
#page requiresPrevPageDemonstrated prevEnabled undoActionCount
0 true false
1 true false
2 true false

View 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>

View 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.

View File

@ -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;
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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();

View File

@ -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">

View File

@ -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);
}

View File

@ -10,6 +10,7 @@ class TutorialHelper : public QObject
Q_OBJECT
QWidget *widget;
public:
int speed;
TutorialHelper();
public slots:
void clickWidget(QWidget*);