1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-25 12:47:44 +01:00
fwbuilder/src/libgui/ProjectPanel.cpp
Vadim Kurland b8abb51339 see #2493 implemented "forward" function in addition to the "back"
function, added a button to the roolbar, using new icons for Back and
Forward buttons.
2011-06-20 16:30:53 -07:00

1271 lines
33 KiB
C++

/*
Firewall Builder
Copyright (C) 2008 NetCitadel, LLC
Author: alek@codeminders.com
refactoring and bugfixes: vadim@fwbuilder.org
$Id$
This program is free software which we release under the GNU General Public
License. You may redistribute and/or modify this program under the terms
of that license as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
To get a copy of the GNU General Public License, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../../config.h"
#include "global.h"
#include "utils.h"
#include <fwbuilder/Cluster.h>
#include <fwbuilder/Firewall.h>
#include <fwbuilder/RuleSet.h>
#include <fwbuilder/Policy.h>
#include <fwbuilder/NAT.h>
#include <fwbuilder/Routing.h>
#include "fwbuilder/RuleSet.h"
#include "fwbuilder/Rule.h"
#include "fwbuilder/RuleElement.h"
#include "FWBSettings.h"
#include "UserWorkflow.h"
#include "FWBTree.h"
#include "FWObjectPropertiesFactory.h"
#include "FWWindow.h"
#include "ProjectPanel.h"
#include "RCS.h"
#include "RuleSetView.h"
#include "findDialog.h"
#include "events.h"
#include "ObjectTreeView.h"
#include "FWObjectClipboard.h"
#include "WorkflowIcons.h"
#include "FirewallCodeViewer.h"
#include <QtDebug>
#include <QMdiSubWindow>
#include <QMdiArea>
#include <QTimer>
#include <QStatusBar>
#include <QFileInfo>
#include <QApplication>
#include <QUndoStack>
#include <QUndoGroup>
#include <QScrollBar>
#include <QMessageBox>
#include <iostream>
using namespace Ui;
using namespace libfwbuilder;
using namespace std;
void ProjectPanel::initMain(FWWindow *main)
{
mainW = main;
mdiWindow = NULL;
treeReloadPending = false;
// mdiWindow changes state several times right after it is opened,
// but we call saveState to store splitter position and its geometry
// when state changes. Flag "ready" is false after ProjectPanel is created
// and until FWWindow decides that ProjectPanel is ready for operation.
// Do not load or save state if flag ready is false.
ready = false;
int total_width = DEFAULT_H_SPLITTER_POSITION;
int total_height = DEFAULT_V_SPLITTER_POSITION;
if (mainW)
{
total_width = mainW->width();
total_height = mainW->height();
}
setMainSplitterPosition(DEFAULT_H_SPLITTER_POSITION,
total_width - DEFAULT_H_SPLITTER_POSITION);
loading_state = false;
oldState=-1;
main->undoGroup->addStack(undoStack);
fd = new findDialog(this, this);
fd->hide();
m_panel->icons->setUpSignals(this);
}
void ProjectPanel::reset()
{
undoStack->clear();
delete rcs;
rcs = NULL;
firewalls.clear();
visibleFirewall = NULL;
visibleRuleSet = NULL;
clearFirewallTabs();
clearObjects();
FWObjectClipboard::obj_clipboard->clear();
}
ProjectPanel::ProjectPanel(QWidget *parent):
QWidget(parent), // , Qt::WindowSystemMenuHint|Qt::Window),
mainW(0),
rcs(0),
systemFile(true),
safeMode(false),
editingStandardLib(false),
editingTemplateLib(false),
ruleSetRedrawPending(false),
objdb(0),
fd(0),
autosaveTimer(new QTimer(static_cast<QObject*>(this))), ruleSetTabIndex(0),
visibleFirewall(0),
visibleRuleSet(0),
lastFirewallIdx(-2),
changingTabs(false),
noFirewalls(tr("No firewalls defined")),
m_panel(0),
undoStack(0)
{
if (fwbdebug) qDebug("ProjectPanel constructor");
m_panel = new Ui::ProjectPanel_q();
m_panel->setupUi(this);
m_panel->om->setupProject(this);
m_panel->toolbar->hide();
undoStack = new QUndoStack(this);
setWindowTitle(getPageTitle());
if (fwbdebug) qDebug("New ProjectPanel %p", this);
connect(m_panel->topSplitter, SIGNAL(splitterMoved(int,int)),
this, SLOT(splitterPositionChanged(int,int)));
}
ProjectPanel::~ProjectPanel()
{
if (fwbdebug) qDebug() << "ProjectPanel::~ProjectPanel()";
undoStack->clear();
if (rcs) delete rcs;
if (objdb) delete objdb;
delete m_panel;
if (fwbdebug) qDebug() << "ProjectPanel::~ProjectPanel() done";
}
QString ProjectPanel::getPageTitle(bool file_path)
{
QString default_caption = tr("Untitled");
if (rcs)
{
QString caption;
if (file_path) caption = rcs->getFileName(); // full path
else
{
QFileInfo fi(rcs->getFileName());
caption = fi.fileName();
}
if (rcs->isInRCS()) caption= caption + ", rev " + rcs->getSelectedRev();
if (rcs->isRO()) caption = caption + " " + tr("(read-only)");
if (caption.isEmpty()) return default_caption;
return caption;
}
else return default_caption;
}
void ProjectPanel::restoreRuleSetTab()
{
if (fwbdebug) qDebug("ProjectPanel::()");
m_panel->ruleSets->setCurrentIndex(ruleSetTabIndex);
m_panel->toolbar->show();
}
void ProjectPanel::loadObjects()
{
m_panel->om->loadObjects();
}
void ProjectPanel::loadObjects(FWObjectDatabase*)
{
m_panel->om->loadObjects();
}
void ProjectPanel::clearObjects()
{
m_panel->om->clearObjects();
}
void ProjectPanel::clearFirewallTabs()
{
if (fwbdebug) qDebug() << "ProjectPanel::clearFirewallTabs";
m_panel->ruleSets->hide();
while (m_panel->ruleSets->count()!=0)
{
QWidget *p = m_panel->ruleSets->widget(0);
m_panel->ruleSets->removeWidget(
m_panel->ruleSets->widget(m_panel->ruleSets->indexOf(p)));
delete p;
}
m_panel->rulesetname->setText("");
m_panel->ruleSets->show();
ruleSetViews.clear();
}
void ProjectPanel::closeRuleSetPanel()
{
if (fwbdebug) qDebug() << "ProjectPanel::closeRuleSetPanel";
clearFirewallTabs();
visibleRuleSet = NULL;
}
void ProjectPanel::ensureObjectVisibleInRules(FWReference *obj)
{
if (fwbdebug) qDebug() << "ProjectPanel::ensureObjectVisibleInRules";
FWObject *p=obj;
while (p && RuleSet::cast(p)==NULL ) p=p->getParent();
if (p==NULL) return; // something is broken
// p is a pointer to RuleSet object @obj belongs to
if (p != getCurrentRuleSet()) openRuleSet(p);
getCurrentRuleSetView()->setFocus();
getCurrentRuleSetView()->selectRE( obj );
}
RuleSetView * ProjectPanel::getCurrentRuleSetView()
{
return dynamic_cast<RuleSetView*>(m_panel->ruleSets->currentWidget());
}
void ProjectPanel::reopenFirewall()
{
if (fwbdebug) qDebug("ProjectPanel::reopenFirewall()");
time_t last_modified = db()->getTimeLastModified();
if (fwbdebug)
qDebug("ProjectPanel::reopenFirewall(): checkpoint 1: "
"dirty=%d last_modified=%s",
db()->isDirty(), ctime(&last_modified));
if (ruleSetRedrawPending) return;
int currentPage = m_panel->ruleSets->currentIndex();
SelectionMemento memento;
RuleSetView* rv = dynamic_cast<RuleSetView*>(m_panel->ruleSets->currentWidget());
if (rv) rv->saveCurrentRowColumn(memento);
last_modified = db()->getTimeLastModified();
if (fwbdebug)
qDebug("ProjectPanel::reopenFirewall(): checkpoint 2: "
"dirty=%d last_modified=%s",
db()->isDirty(), ctime(&last_modified));
// since reopenFirewall deletes and recreates all RuleSetView
// widgets, it causes significant amount of repaint and
// flicker. Disable updates for the duration of operation to avoid
// that.
m_panel->ruleSets->setUpdatesEnabled(false);
changingTabs = true;
clearFirewallTabs();
last_modified = db()->getTimeLastModified();
if (fwbdebug)
qDebug("ProjectPanel::reopenFirewall(): checkpoint 3: "
"dirty=%d last_modified=%s",
db()->isDirty(), ctime(&last_modified));
if (visibleRuleSet==NULL) return ;
for (int i =0 ; i < m_panel->ruleSets->count (); i++)
m_panel->ruleSets->removeWidget(m_panel->ruleSets->widget(i));
m_panel->rulesetname->setTextFormat(Qt::RichText);
updateFirewallName();
last_modified = db()->getTimeLastModified();
if (fwbdebug)
qDebug("ProjectPanel::reopenFirewall(): checkpoint 4: "
"dirty=%d last_modified=%s",
db()->isDirty(), ctime(&last_modified));
RuleSetView* rulesetview =
RuleSetView::getRuleSetViewByType(this, visibleRuleSet, NULL);
if (rulesetview)
{
m_panel->ruleSets->addWidget(rulesetview);
last_modified = db()->getTimeLastModified();
if (fwbdebug)
qDebug("ProjectPanel::reopenFirewall(): checkpoint 5: "
"dirty=%d last_modified=%s",
db()->isDirty(), ctime(&last_modified));
m_panel->ruleSets->setCurrentIndex(currentPage);
m_panel->toolbar->show();
rv = dynamic_cast<RuleSetView*>(m_panel->ruleSets->currentWidget());
rv->restoreCurrentRowColumn(memento);
changingTabs = false;
mainW->updateGlobalToolbar();
m_panel->ruleSets->setUpdatesEnabled(true);
m_panel->ruleSets->show();
}
}
int ProjectPanel::findFirewallInList(FWObject *f)
{
vector<FWObject*>::iterator i;
int n=0;
for (i=firewalls.begin(); i!=firewalls.end(); i++,n++)
{
if ( (*i)->getId()==f->getId() ) return n;
}
return -1;
}
void ProjectPanel::updateFirewallName()
{
if (visibleRuleSet==NULL) return ;
QString name;
// mw->buildEditorTitleAndIcon(visibleRuleSet, ObjectEditor::optNone,
// &name, NULL, false);
// name = "<b>" + name + "</b>";
FWObject *fw = visibleRuleSet->getParent();
name = QString("%1 / %2")
.arg(QString::fromUtf8(fw->getName().c_str()))
.arg(QString::fromUtf8(visibleRuleSet->getName().c_str()));
m_panel->rulesetname->setText(name );
}
void ProjectPanel::openRuleSet(FWObject * obj, bool immediately)
{
//mw->blankEditor();
visibleRuleSet = RuleSet::cast(obj);
if (immediately) redrawRuleSets();
else registerRuleSetRedrawRequest();
}
void ProjectPanel::selectRules()
{
// `unselect();
RuleSetView* rv = dynamic_cast<RuleSetView*>(
m_panel->ruleSets->currentWidget());
if (rv) rv->setFocus();
}
void ProjectPanel::unselectRules()
{
bool havePolicies = (m_panel->ruleSets->count()!=0);
/* commented this out so that when I hit "Edit" in the object's pop-down
* menu in a rule, ruleset wont lose focus when object editor is opened.
* If rule set loses focus, the object's background turns from "selected" color
* to white and user loses context (which object is shown in the object editor)
*/
if (havePolicies)
{
RuleSetView* rv=dynamic_cast<RuleSetView*>(m_panel->ruleSets->currentWidget());
if (rv && rv->getSelectedObject()!=getSelectedObject())
{
rv->clearFocus();
}
}
mainW->disableActions(havePolicies);
}
void ProjectPanel::editCopy()
{
if (fwbdebug)
qDebug() << "ProjectPanel::editCopy() isManipulatorSelected()="
<< isManipulatorSelected();
if (isManipulatorSelected()) copyObj();
else
{
if (m_panel->ruleSets->count()!=0)
{
RuleSetView *rsv = dynamic_cast<RuleSetView*>(m_panel->ruleSets->currentWidget());
if (rsv)
rsv->copySelectedObject();
}
}
}
void ProjectPanel::editCut()
{
if (fwbdebug)
qDebug() << "ProjectPanel::editCut() isManipulatorSelected()="
<< isManipulatorSelected();
if (isManipulatorSelected()) cutObj();
else
{
if (m_panel->ruleSets->count()!=0)
{
RuleSetView *rsv = dynamic_cast<RuleSetView*>(m_panel->ruleSets->currentWidget());
if (rsv)
rsv->cutSelectedObject();
}
}
}
void ProjectPanel::editDelete()
{
if (fwbdebug)
qDebug() << "ProjectPanel::editDelete() isManipulatorSelected()="
<< isManipulatorSelected();
if (isManipulatorSelected()) deleteObj();
}
void ProjectPanel::editPaste()
{
if (fwbdebug)
qDebug() << "ProjectPanel::editPaste() isManipulatorSelected()="
<< isManipulatorSelected();
if (isManipulatorSelected()) pasteObj();
else
{
if (m_panel->ruleSets->count()!=0)
{
RuleSetView *rsv = dynamic_cast<RuleSetView*>(m_panel->ruleSets->currentWidget());
if (rsv)
rsv->pasteObject();
}
}
}
QString ProjectPanel::getDestDir(const QString &fname)
{
QString destdir = "";
if (st->getWDir().isEmpty())
{
if (fname.isEmpty())
{
destdir = userDataDir.c_str();
} else
{
QFileInfo fi(fname);
if (fi.isDir()) destdir = fname;
else
{
destdir = fi.canonicalPath();
}
}
} else
{
destdir = st->getWDir();
}
return destdir;
}
void ProjectPanel::setFileName(const QString &fname)
{
systemFile = false;
rcs->setFileName(fname);
db()->setFileName(fname.toLatin1().constData());
//setWindowTitle(getPageTitle());
QCoreApplication::postEvent(mw, new updateSubWindowTitlesEvent());
}
//wrapers for some ObjectManipulator functions
FWObject* ProjectPanel::getCurrentLib()
{
return m_panel->om->getCurrentLib();
}
void ProjectPanel::updateObjectInTree(FWObject *obj, bool subtree)
{
m_panel->om->updateObjectInTree(obj, subtree);
}
FWObject* ProjectPanel::createObject(const QString &objType,
const QString &objName,
FWObject *copyFrom)
{
return m_panel->om->createObject(objType, objName, copyFrom);
}
FWObject* ProjectPanel::createObject(FWObject *parent,
const QString &objType,
const QString &objName,
FWObject *copyFrom)
{
return m_panel->om->createObject(parent, objType, objName, copyFrom);
}
void ProjectPanel::moveObject(FWObject *target,
FWObject *obj)
{
m_panel->om->moveObject(target, obj);
}
void ProjectPanel::moveObject(const QString &targetLibName,
FWObject *obj)
{
m_panel->om->moveObject(targetLibName, obj);
}
FWObject* ProjectPanel::pasteTo(FWObject *target, FWObject *obj)
{
return m_panel->om->pasteTo(target, obj);
}
ObjectTreeView* ProjectPanel::getCurrentObjectTree()
{
return m_panel->om->getCurrentObjectTree();
}
void ProjectPanel::findAllFirewalls (std::list<Firewall *> &fws)
{
m_panel->om->findAllFirewalls(fws);
}
void ProjectPanel::showDeletedObjects(bool f)
{
m_panel->om->showDeletedObjects(f);
}
void ProjectPanel::select()
{
m_panel->om->select();
}
void ProjectPanel::unselect()
{
m_panel->om->unselect();
}
void ProjectPanel::clearManipulatorFocus()
{
m_panel->om->clearFocus();
}
void ProjectPanel::copyObj()
{
m_panel->om->copyObj();
}
bool ProjectPanel::isManipulatorSelected()
{
return m_panel->om->getCurrentObjectTree()->hasFocus();
}
void ProjectPanel::cutObj()
{
m_panel->om->cutObj();
}
void ProjectPanel::pasteObj()
{
m_panel->om->pasteObj();
}
void ProjectPanel::newObject()
{
m_panel->om->newObject();
}
void ProjectPanel::deleteObj()
{
m_panel->om->delObj();
}
FWObject* ProjectPanel::getSelectedObject()
{
return m_panel->om->getSelectedObject();
}
void ProjectPanel::reopenCurrentItemParent()
{
m_panel->om->reopenCurrentItemParent();
}
void ProjectPanel::back()
{
m_panel->om->back();
}
void ProjectPanel::forward()
{
m_panel->om->forward();
}
void ProjectPanel::lockObject()
{
m_panel->om->lockObject();
}
void ProjectPanel::unlockObject()
{
m_panel->om->unlockObject();
}
void ProjectPanel::setFDObject(FWObject *o)
{
fd->setObject(o);
fd->show();
}
void ProjectPanel::resetFD()
{
fd->reset();
}
void ProjectPanel::insertRule()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->insertRule();
}
void ProjectPanel::addRuleAfterCurrent()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->addRuleAfterCurrent();
}
void ProjectPanel::removeRule()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->removeRule();
}
void ProjectPanel::moveRule()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->moveRule();
}
void ProjectPanel::moveRuleUp()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->moveRuleUp();
}
void ProjectPanel::moveRuleDown()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->moveRuleDown();
}
void ProjectPanel::copyRule()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->copyRule();
}
void ProjectPanel::cutRule()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->cutRule();
}
void ProjectPanel::pasteRuleAbove()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->pasteRuleAbove();
}
void ProjectPanel::pasteRuleBelow()
{
if (visibleRuleSet==NULL || m_panel->ruleSets->count()==0) return;
getCurrentRuleSetView()->pasteRuleBelow();
}
bool ProjectPanel::editingLibrary()
{
return (rcs!=NULL &&
( rcs->getFileName().endsWith(".fwl")) );
}
void ProjectPanel::createRCS(const QString &filename)
{
rcs = new RCS(filename);
systemFile = true;
}
RCS * ProjectPanel::getRCS()
{
return rcs;
}
/*
* This slot is connected to the "add rule" button in the mini-toolbar
* at the top of the rule set view
*/
void ProjectPanel::addRule()
{
if (visibleRuleSet==NULL || getCurrentRuleSetView()==NULL) return ;
getCurrentRuleSetView()->insertRule();
}
void ProjectPanel::compileThis()
{
if (visibleRuleSet==NULL) return ;
save();
// see comment in FWWindow::compile()
if (db()->isDirty()) return;
wfl->registerFlag(UserWorkflow::COMPILE, true);
set<Firewall*> fw;
Firewall *f = Firewall::cast(visibleRuleSet->getParent());
if (f)
{
fw.insert(f);
mainW->compile(fw);
}
}
void ProjectPanel::installThis()
{
if (visibleRuleSet==NULL) return ;
save();
// see comment in FWWindow::compile()
if (db()->isDirty()) return;
wfl->registerFlag(UserWorkflow::INSTALL, true);
set<Firewall*> fw;
Firewall *f = Firewall::cast(visibleRuleSet->getParent());
if (f)
{
fw.insert(f);
mainW->install(fw);
}
}
void ProjectPanel::inspectThis()
{
if (visibleRuleSet==NULL) return;
save();
// see comment in FWWindow::compile()
if (db()->isDirty()) return;
Firewall *f = Firewall::cast(visibleRuleSet->getParent());
set<Firewall*> fwlist;
if (Cluster::isA(f))
{
std::list<Firewall*> cfws;
Cluster::cast(f)->getMembersList(cfws);
foreach(Firewall *fw, cfws)
fwlist.insert(fw);
}
else
{
fwlist.insert(f);
}
this->inspect(fwlist);
}
void ProjectPanel::inspectAll()
{
ObjectManipulator *om = this->findChild<ObjectManipulator*>();
list<Firewall*> fws;
om->findAllFirewalls(fws);
set<Firewall*> fwset;
foreach(Firewall *fw, fws)
{
if (Cluster::isA(fw))
{
std::list<Firewall*> cfws;
Cluster::cast(fw)->getMembersList(cfws);
foreach(Firewall *f, cfws)
fwset.insert(f);
}
else
{
fwset.insert(fw);
}
}
this->inspect(fwset);
}
void ProjectPanel::compile()
{
if (mw->isEditorVisible() &&
!mw->requestEditorOwnership(NULL,NULL,ObjectEditor::optNone,true))
return;
save();
// see comment in FWWindow::compile()
if (db()->isDirty()) return;
//fileSave();
wfl->registerFlag(UserWorkflow::COMPILE, true);
mainW->compile();
}
void ProjectPanel::compile(set<Firewall*> vf)
{
if (mw->isEditorVisible() &&
!mw->requestEditorOwnership(NULL, NULL, ObjectEditor::optNone, true))
return;
save();
// see comment in FWWindow::compile()
if (db()->isDirty()) return;
//fileSave();
wfl->registerFlag(UserWorkflow::COMPILE, true);
mainW->compile(vf);
}
void ProjectPanel::install(set<Firewall*> vf)
{
save();
// see comment in FWWindow::compile()
if (db()->isDirty()) return;
wfl->registerFlag(UserWorkflow::INSTALL, true);
mainW->install(vf);
}
void ProjectPanel::install()
{
save();
// see comment in FWWindow::compile()
if (db()->isDirty()) return;
wfl->registerFlag(UserWorkflow::INSTALL, true);
mainW->install();
}
void ProjectPanel::inspect(set<Firewall *> fws)
{
if (fws.empty())
return;
QMessageBox messageBox(this);
messageBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
messageBox.addButton(tr("Compile and Inspect files"), QMessageBox::AcceptRole);
messageBox.setIcon(QMessageBox::Critical);
set<Firewall*> needCompile;
foreach(Firewall *fw, fws)
if (fw->needsCompile())
needCompile.insert(fw);
if (!needCompile.empty())
{
QString text;
QStringList names;
foreach(Firewall *fw, needCompile)
names.append(fw->getName().c_str());
if (needCompile.size() > 1 && needCompile.size() < 5)
{
QString last = names.last();
names.pop_back();
QString firewalls = "\"" + names.join("\", \"") + "\" " + tr("and") + " \"" + last + "\"";
text = tr("Firewall objects %1 have been modified and need to be recompiled.").arg(firewalls);
}
else
if (needCompile.size() == 1)
text = tr("Firewall object \"%1\" has been modified and needs to be recompiled.").arg(names.first());
else
{
text = tr("%1 firewall objects have been modified and need to be recompiled.").arg(needCompile.size());
}
messageBox.setText(text);
messageBox.exec();
if (messageBox.result() == QMessageBox::Accepted)
{
this->compile(needCompile);
}
return;
}
QStringList files;
QSet<Firewall*> filesMissing;
Firewall *first_fw = NULL;
foreach(Firewall *fw, fws)
{
if (first_fw == NULL) first_fw = fw;
/*
* get full path to the generated file. The path is built from
* the file name returned by
* FirewallInstaller::getGeneratedFileName() and directory
* path from the .fwb file. Note that we use the same
* algorithm when GUI launches policy compiler, except there
* the path is passed to it via "-d" command line option.
*/
QString mainFile = FirewallInstaller::getGeneratedFileFullPath(fw);
// QString mainFile = FirewallInstaller::getGeneratedFileName(fw);
if (QFile::exists(mainFile))
{
instConf cnf;
cnf.fwobj = fw;
cnf.script = mainFile;
QMap<QString, QString> res;
FirewallInstaller(NULL, &cnf, "").readManifest(mainFile, &res);
QStringList current_files = res.keys();
foreach(QString file, current_files)
{
if (!QFile::exists(file))
filesMissing.insert(fw);
else
files.append(file);
}
}
else
filesMissing.insert(fw);
}
if (!filesMissing.isEmpty())
{
QString text;
QStringList names;
foreach(Firewall *fw, filesMissing)
names.append(fw->getName().c_str());
if (filesMissing.size() > 1 && filesMissing.size() < 5)
{
QString last = names.last();
names.pop_back();
QString firewalls = "\"" + names.join("\", \"") + "\" " + tr("and") + " \"" + last + "\"";
text = tr("Can not read generated files for the firewall objects %1. You need to compile them to create the files.").arg(firewalls);
}
else
if (filesMissing.size() == 1)
text = tr("Can not read generated files for the firewall objects %1. You need to compile it to create the files.").arg(names.first());
else
{
text = tr("Can not read generated files for the %1 firewall objects. You need to compile then to create the files.").arg(filesMissing.size());
}
messageBox.setText(text);
messageBox.exec();
if (messageBox.result() == QMessageBox::Accepted)
{
this->compile(fws);
}
return;
}
if (files.empty())
return;
QString viewer_title;
if (fws.size() > 1) viewer_title = tr("<b>Multiple firewalls</b>");
else viewer_title = QString("<b>%1</b>").arg(first_fw->getName().c_str());
FirewallCodeViewer *viewer =
new FirewallCodeViewer(files, viewer_title, this);
viewer->show();
}
QString ProjectPanel::printHeader()
{
QString headerText = rcs->getFileName().section("/",-1,-1);
if (rcs->isInRCS())
headerText = headerText + ", rev " + rcs->getSelectedRev();
return headerText;
}
void ProjectPanel::registerRuleSetRedrawRequest()
{
if (!ruleSetRedrawPending)
{
ruleSetRedrawPending = true;
//redrawRuleSets();
QTimer::singleShot( 0, this, SLOT(redrawRuleSets()) );
}
}
void ProjectPanel::redrawRuleSets()
{
ruleSetRedrawPending = false;
reopenFirewall();
}
void ProjectPanel::aboutToActivate()
{
if (fwbdebug) qDebug() << "ProjectPanel::aboutToActivate " << this;
}
void ProjectPanel::showEvent(QShowEvent *ev)
{
if (fwbdebug) qDebug() << "ProjectPanel::showEvent " << this
<< "title " << mdiWindow->windowTitle();
QWidget::showEvent(ev);
// we get this event when MDI window is maximized or restored
// loadState();
// visibilityChangedForTreePanel(true);
}
void ProjectPanel::hideEvent(QHideEvent *ev)
{
if (fwbdebug) qDebug() << "ProjectPanel::hideEvent " << this
<< "title " << mdiWindow->windowTitle();
QWidget::hideEvent(ev);
}
void ProjectPanel::closeEvent(QCloseEvent * ev)
{
if (fwbdebug) qDebug() << "ProjectPanel::closeEvent " << this
<< "title " << mdiWindow->windowTitle();
if (!saveIfModified() || !checkin(true))
{
ev->ignore();
return;
}
saveState();
fileClose();
mw->updateWindowTitle();
//QCoreApplication::postEvent(mw, new closeEditorPanelEvent());
QCoreApplication::postEvent(mw, new clearEditorPanelEvent());
QTimer::singleShot( 0, mw, SLOT(projectWindowClosed()) );
}
QString ProjectPanel::getFileName()
{
if (rcs!=NULL) return rcs->getFileName();
else return "";
}
void ProjectPanel::splitterMoved(int , int)
{
}
void ProjectPanel::resizeEvent(QResizeEvent*)
{
}
void ProjectPanel::registerTreeReloadRequest()
{
treeReloadPending = true;
QTimer::singleShot(0, this, SLOT(reloadTree()));
}
void ProjectPanel::reloadTree()
{
if (treeReloadPending)
{
m_panel->om->reload();
treeReloadPending = false;
}
}
void ProjectPanel::registerObjectToUpdateInTree(FWObject *o, bool update_subtree)
{
if (fwbdebug)
qDebug() << "ProjectPanel::registerObjectToUpdateInTree()"
<< "o=" << o->getName().c_str()
<< "update_subtree=" << update_subtree
<< "updateObjectsInTreePool.size()="
<< updateObjectsInTreePool.size();
if (updateObjectsInTreePool.find(o->getId()) == updateObjectsInTreePool.end())
{
updateObjectsInTreePool[o->getId()] = update_subtree;
QTimer::singleShot(0, this, SLOT(updateObjectInTree()));
}
}
void ProjectPanel::updateObjectInTree()
{
if (fwbdebug)
qDebug() << "ProjectPanel::updateObjectInTree()"
<< "updateObjectsInTreePool.size()="
<< updateObjectsInTreePool.size();
while (updateObjectsInTreePool.size() > 0)
{
map<int, bool>::iterator it = updateObjectsInTreePool.begin();
FWObject *obj = db()->findInIndex(it->first);
m_panel->om->updateObjectInTree(obj, it->second);
updateObjectsInTreePool.erase(it);
}
mdiWindow->update();
}
void ProjectPanel::registerModifiedObject(FWObject *o)
{
if (fwbdebug)
qDebug() << "ProjectPanel::registerModifiedObject "
<< "lastModifiedTimestampChangePool.size()="
<< lastModifiedTimestampChangePool.size()
<< "o=" << o->getName().c_str()
<< "(" << o->getTypeName().c_str() << ")"
<< "id=" << o->getId();
FWObject *modified_object = o;
/*
* a bit of optimization: the purpose of registering modified
* object here is to update "last modified" timestamp in the
* firewall object it belongs to. One of the frequent cases is
* when @o is rule element because user made some change to
* it. Massive find and replace operations can cause waves of
* registrations of rule elements, all of which belong to the
* same rule set. If I register rule set instead, there will be
* just one object to register.
*/
if (RuleElement::cast(o))
{
while (RuleSet::cast(modified_object) == NULL)
modified_object = modified_object->getParent();
}
if (lastModifiedTimestampChangePool.find(modified_object->getId()) ==
lastModifiedTimestampChangePool.end())
{
if (fwbdebug)
qDebug() << "ProjectPanel::registerModifiedObject "
<< "Add object" << modified_object->getName().c_str()
<< "id=" << modified_object->getId();
lastModifiedTimestampChangePool.insert(modified_object->getId());
QTimer::singleShot(
0, this, SLOT(updateLastModifiedTimestampForAllFirewalls()));
}
}
void ProjectPanel::updateLastModifiedTimestampForAllFirewalls()
{
if (fwbdebug)
qDebug() << "ProjectPanel::updateLastModifiedTimestampForAllFirewalls"
<< "lastModifiedTimestampChangePool.size()="
<< lastModifiedTimestampChangePool.size();
if (lastModifiedTimestampChangePool.size() == 0) return;
mw->showStatusBarMessage(
tr("Searching for firewalls affected by the change..."));
//QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,100);
QApplication::setOverrideCursor(QCursor( Qt::WaitCursor));
set<Firewall*> firewalls_to_update;
while (lastModifiedTimestampChangePool.size() > 0)
{
set<int>::iterator it = lastModifiedTimestampChangePool.begin();
FWObject *obj = db()->findInIndex(*it);
lastModifiedTimestampChangePool.erase(it);
if (fwbdebug)
qDebug() << "Modified object: " << obj->getName().c_str();
if (FWBTree().isSystem(obj)) continue;
list<Firewall *> fws = m_panel->om->findFirewallsForObject(obj);
if (fws.size())
{
Firewall *f;
for (list<Firewall *>::iterator i=fws.begin();
i!=fws.end();
++i)
{
f = *i;
if (f==obj) continue;
firewalls_to_update.insert(f);
}
}
}
if (fwbdebug)
qDebug() << "Will update " << firewalls_to_update.size() << " firewalls";
for (set<Firewall*>::iterator it=firewalls_to_update.begin();
it!=firewalls_to_update.end(); ++it)
{
Firewall *f = *it;
// when user locks firewall object, this code tries to
// update last_modified timestamp in it because it
// depends on itself. Dont.
if (f->isReadOnly()) continue;
f->updateLastModifiedTimestamp();
QCoreApplication::postEvent(
mw, new updateObjectInTreeEvent(getFileName(), f->getId()));
list<Cluster*> clusters = m_panel->om->findClustersUsingFirewall(f);
if (clusters.size() != 0)
{
list<Cluster*>::iterator it;
for (it=clusters.begin(); it!=clusters.end(); ++it)
{
Cluster *cl = *it;
if (cl->isReadOnly()) continue;
cl->updateLastModifiedTimestamp();
QCoreApplication::postEvent(
mw, new updateObjectInTreeEvent(getFileName(), cl->getId()));
}
}
}
QApplication::restoreOverrideCursor();
}
void ProjectPanel::toggleViewTree(bool f)
{
if (f) m_panel->treePanelFrame->show();
else m_panel->treePanelFrame->hide();
}
void ProjectPanel::setActive()
{
undoStack->setActive(true);
}
void ProjectPanel::splitterPositionChanged(int,int)
{
saveMainSplitter();
}