1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-19 01:37:17 +01:00
fwbuilder/src/libgui/ObjectManipulator.cpp
Vadim Kurland 3a2041d16d per Mikes request, the GUI now opens rule set object of the firewall
when user opens the firewall or any of its children objects in the
editor. This includes any rule set, interface or any other child
object.

Also moved function Interface::getParentHost() from class Interface to
class Host as static FWObject* Host::getParentHost(FWObject *o). Its
behavior is now more logical, it returns non-NULL pointer only if an
object actually has a parent that is host, firewall or cluster. Old
function Interface::getParentHost() returned non-NULL pointer even
when object was not in the proper position in the tree.

Now this function can be used to get parent host/firewall/cluster for
any child object rather than only interface.

I had to fix bunch of problems in unit tests that got uncovered because
new function behaves in a more strict way (returns NULL when there is
no parent of correct type).
2011-06-05 21:38:46 -07:00

1617 lines
52 KiB
C++

/*
Firewall Builder
Copyright (C) 2003 NetCitadel, LLC
Author: Vadim Kurland 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_no_qt.h"
#include "platforms.h"
#include "events.h"
#include "listOfLibrariesModel.h"
#include "ProjectPanel.h"
#include "ObjectManipulator.h"
#include "ObjectEditor.h"
#include "ObjectTreeViewItem.h"
#include "ObjectTreeView.h"
#include "FWObjectClipboard.h"
#include "FWObjectPropertiesFactory.h"
#include "FWBSettings.h"
#include "findDialog.h"
#include "newGroupDialog.h"
#include "FindObjectWidget.h"
#include "AskLibForCopyDialog.h"
#include "FindWhereUsedWidget.h"
#include "interfaceProperties.h"
#include "interfacePropertiesObjectFactory.h"
#include "FWBTree.h"
#include "FWWindow.h"
#include "fwbuilder/AddressRange.h"
#include "fwbuilder/AddressTable.h"
#include "fwbuilder/AttachedNetworks.h"
#include "fwbuilder/Cluster.h"
#include "fwbuilder/CustomService.h"
#include "fwbuilder/DNSName.h"
#include "fwbuilder/FWObject.h"
#include "fwbuilder/FailoverClusterGroup.h"
#include "fwbuilder/Firewall.h"
#include "fwbuilder/Host.h"
#include "fwbuilder/ICMP6Service.h"
#include "fwbuilder/ICMPService.h"
#include "fwbuilder/IPService.h"
#include "fwbuilder/IPv4.h"
#include "fwbuilder/IPv6.h"
#include "fwbuilder/Interface.h"
#include "fwbuilder/Interval.h"
#include "fwbuilder/IntervalGroup.h"
#include "fwbuilder/Library.h"
#include "fwbuilder/Network.h"
#include "fwbuilder/NetworkIPv6.h"
#include "fwbuilder/ObjectGroup.h"
#include "fwbuilder/Resources.h"
#include "fwbuilder/RuleSet.h"
#include "fwbuilder/ServiceGroup.h"
#include "fwbuilder/StateSyncClusterGroup.h"
#include "fwbuilder/TCPService.h"
#include "fwbuilder/UDPService.h"
#include "fwbuilder/UserService.h"
#include "fwbuilder/NAT.h"
#include "fwbuilder/Policy.h"
#include "fwbuilder/Routing.h"
#include "fwbuilder/TagService.h"
#include <QMessageBox>
#include <QTime>
#include <QtDebug>
#include <QHeaderView>
#include <QUndoStack>
#include <QMenu>
#include <QAction>
#include <memory>
#include <algorithm>
using namespace std;
using namespace libfwbuilder;
HistoryItem::~HistoryItem() {}
ObjectManipulator::~ObjectManipulator()
{
delete m_objectManipulator;
delete libs_model;
}
ObjectManipulator::ObjectManipulator(QWidget *parent):
QWidget(parent), current_tree_view(0)
{
m_objectManipulator = new Ui::ObjectManipulator_q;
m_objectManipulator->setupUi(this);
setObjectName(tr("Object Manipulator"));
libs_model = new ListOfLibrariesModel();
m_objectManipulator->libs->setModel(libs_model);
m_project = NULL;
treeWidth = -1;
treeHeight = -1;
active = false;
current_tree_view=NULL;
previous_lib_index = -1;
// used in duplicateWithDependencies()
dedup_marker_global_counter = time(NULL);
buildNewObjectMenu();
}
void ObjectManipulator::setupProject(ProjectPanel *project)
{
m_project = project;
}
vector<QTreeWidget*> ObjectManipulator::getTreeWidgets()
{
vector<QTreeWidget*> res;
for (int i=0; i<libs_model->rowCount(); ++i)
{
QTreeWidget *objTreeView = libs_model->getTreeWidget(i);
if (objTreeView == NULL) continue;
res.push_back(objTreeView);
}
return res;
}
void ObjectManipulator::showDeletedObjects(bool f)
{
try
{
FWObject *dobj = m_project->db()->findInIndex(
FWObjectDatabase::DELETED_OBJECTS_ID);
if (fwbdebug)
qDebug("ObjectManipulator::showDeletedObjects f=%d dobj=%p",
f, dobj);
if (dobj==NULL)
{
dobj = m_project->db()->create(Library::TYPENAME);
dobj->setId(FWObjectDatabase::DELETED_OBJECTS_ID);
dobj->setName("Deleted Objects");
dobj->setReadOnly(false);
m_project->db()->add(dobj);
}
QModelIndex idx = libs_model->getIdxForLib(dobj);
if (fwbdebug)
qDebug("ObjectManipulator::showDeletedObjects idx.row()=%d", idx.row());
if (f)
{
if (idx.isValid()) return;
addLib( dobj );
openLib( dobj );
} else
{
if (!idx.isValid()) return;
QTreeWidget *otv = libs_model->getTreeWidget(idx);
if (fwbdebug)
qDebug("ObjectManipulator::showDeletedObjects otv=%p", otv);
assert(otv!=NULL);
m_objectManipulator->widgetStack->removeWidget( otv );
removeLib(idx.row());
}
}
catch(FWException &ex)
{
/* we get exception if file is opened read-only and there is no "deleted
* objects" library yet
*/
}
}
QString ObjectManipulator::getStandardName(FWObject *parent,
const string&,
const string &namesuffix)
{
QStringList names;
FWObject *po = parent;
while (po!=NULL)
{
names.push_front(QString::fromUtf8(po->getName().c_str()));
if (Host::cast(po)) break;
po = po->getParent();
}
// names.push_back(QString::fromUtf8(parent->getName().c_str()));
names.push_back(namesuffix.c_str());
return names.join(":");
}
void ObjectManipulator::currentTreePageChanged(int i)
{
QWidget *w = m_objectManipulator->widgetStack->widget(i);
switchingTrees(w);
}
void ObjectManipulator::switchingTrees(QWidget* w)
{
ObjectTreeView *new_otv = dynamic_cast<ObjectTreeView*>(w);
if (!new_otv)
return;//assert(new_otv)
if (current_tree_view!=NULL) current_tree_view->becomingHidden();
new_otv->becomingVisible();
current_tree_view = new_otv;
}
/*
* Make the name of the object @obj unique across all children of the
* given @target object. If this object is an interface, use pattern
* <ifname><ifnumber> and increment the number until the name becomes
* unique. For all other types use pattern <basename>-<number>
*
* This method has ugly side-effect: if @obj is an Interface, this
* method needs to check its type. To do that, it calls
* Interface::getOptionsObject() which creates options object if it
* does not exits. To do initial options configuration, it needs
* access to the parent. We call Interface::getOptionsObject() in copt
* and startDrag methods to make sure interfaces have options objects
* before copy or drag operation starts to avoid this problem here.
*
* In case of copy/paste or d&d of an interface, the naming
* conventions are dictated by the platform of the new parent firewall
* rather than the old one, which in this case is either <target> or
* its parent. So we'll use @target to get proper interfaceProperties
* object which will do checks for us.
*/
void ObjectManipulator::makeNameUnique(FWObject *target, FWObject *obj)
{
Interface *intf = Interface::cast(obj);
if (intf)
{
// check if this is vlan subinterface. We should not change
// names of those
if (intf->getOptionsObject()->getStr("type") == "8021q")
return;
// one of the typical usage patterns is to create vlan
// interface "eth0.101" and then immediately try to copy/paste
// it to under br0 to make it bridge port. In this case
// interface eth0.101 won't have type "8021q" just yet because
// the user did not open interface "advanced" settings dialog
// to set its type and VLAN ID. Users assume that if its name
// is "eth0.101", then it must be vlan interface. We should
// follow this assumption too. Also, check for names "vlanNNN"
// as well.
//
QString obj_name = QString::fromUtf8(obj->getName().c_str());
FWObject *fw = target;
while (fw && !Firewall::cast(fw)) fw = fw->getParent();
std::auto_ptr<interfaceProperties> int_prop(
interfacePropertiesObjectFactory::getInterfacePropertiesObject(fw));
if (int_prop->looksLikeVlanInterface(obj_name)) return;
}
QString newname = makeNameUnique(target,
QString::fromUtf8(obj->getName().c_str()),
obj->getTypeName().c_str());
obj->setName(string(newname.toUtf8()));
}
QString ObjectManipulator::makeNameUnique(FWObject* parent,
const QString &obj_name,
const QString &obj_type)
{
int suffix = 1;
QString basename = obj_name;
QString newname = basename;
if (fwbdebug)
qDebug("ObjectManipulator::makeNameUnique parent=%s obj_name=%s",
parent->getName().c_str(),
obj_name.toStdString().c_str());
if (obj_type == Interface::TYPENAME)
{
QRegExp rx("([a-zA-Z-]+)(\\d{1,})");
if (rx.indexIn(obj_name) != -1)
{
basename = rx.cap(1);
suffix = rx.cap(2).toInt();
}
}
/*
* Check if there is another object with the same name. Note that
* FWObject::findObjectByName() searches in depth, but we only need to
* scan child objects of the first level.
*/
while (true)
{
if (fwbdebug)
qDebug("ObjectManipulator::makeNameUnique newname=%s basename=%s suffix=%d",
newname.toStdString().c_str(),
basename.toStdString().c_str(),
suffix);
FWObject::const_iterator i = find_if(
parent->begin(), parent->end(),
FWObjectNameEQPredicate(newname.toStdString()));
if (i==parent->end()) break;
if (obj_type == Interface::TYPENAME)
newname = QString("%1%2").arg(basename).arg(suffix);
else
newname = QString("%1-%2").arg(basename).arg(suffix);
suffix++;
}
return newname;
}
void ObjectManipulator::contextMenuRequested(const QPoint &pos)
{
/* in extended selection mode there may be several selected items */
QTreeWidget *objTreeView = getCurrentObjectTree();
QTreeWidgetItem *item = objTreeView->itemAt(pos);//clicked item
if (fwbdebug)
qDebug("ObjectManipulator::contextMenu selectedObjects.size=%d",
getCurrentObjectTree()->getNumSelected());
ObjectTreeViewItem *otvi=dynamic_cast<ObjectTreeViewItem*>(item);
if (otvi==NULL) return; // happens when user clicks outside an item
if (!getCurrentObjectTree()->isSelected(otvi->getFWObject()))
openObjectInTree( otvi, true );
//if (currentObj==NULL) currentObj=otvi->getFWObject();
FWObject *currentObj = getSelectedObject();
popup_menu->clear();
if (item->childCount() > 0)
{
if (item->isExpanded())
popup_menu->addAction(tr("Collapse"), this,
SLOT(collapseCurrentTreeNode()));
else
popup_menu->addAction(tr("Expand"), this,
SLOT(expandCurrentTreeNode()));
popup_menu->addSeparator();
}
QAction *edtID;
if (currentObj->isReadOnly())
edtID = popup_menu->addAction(tr("Inspect"),
this, SLOT( editSelectedObject()));
else
edtID = popup_menu->addAction(tr("Edit"),
this, SLOT( editSelectedObject()));
if (RuleSet::cast(currentObj))
popup_menu->addAction(tr("Open"), this, SLOT( openSelectedRuleSet()));
QMenu *duptargets = NULL;
QAction *dupID = NULL;
QMenu *movetargets = NULL;
int moveTargetsCounter = 0;
if (!Interface::isA(currentObj) && RuleSet::cast(currentObj)==NULL &&
!Library::isA(currentObj) && !FWBTree().isStandardFolder(currentObj))
{
duptargets = popup_menu->addMenu( tr("Duplicate ...") );
movetargets = popup_menu->addMenu( tr("Move ...") );
connect ( duptargets, SIGNAL ( triggered(QAction*) ),
this, SLOT( duplicateObj(QAction*) ) );
connect ( movetargets, SIGNAL ( triggered(QAction*) ),
this, SLOT( moveObj(QAction*) ) );
/* we add " ... to library ..." submenu to the "Move " menu item only
* if user did not select a library, or if they selected several
* objects. Method moveObj knows that library should not be moved
* into another library.
*/
bool libSelected =
(getCurrentObjectTree()->getNumSelected()==1 &&
Library::isA(getCurrentObjectTree()->getSelectedObjects().front()));
FWObject *cl = getCurrentLib();
vector<FWObject*>::iterator i;
int N = libs_model->rowCount();
for (int row=0 ; row<N; ++row)
{
QModelIndex idx = libs_model->index(row, 0);
FWObject *lib = libs_model->getLibrary(idx);
if (lib == NULL) continue;
if ( lib->getId()==FWObjectDatabase::STANDARD_LIB_ID ||
lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID ||
lib->isReadOnly())
continue;
dupID = duptargets->addAction(
tr("place in library %1").arg(
QString::fromUtf8(lib->getName().c_str())));
dupID->setData(row);
// can't move to the same library
if (lib == cl) continue; // skip current library
if (!libSelected)
{
moveTargetsCounter++;
QAction* mact = movetargets->addAction(
tr("to library %1").arg(
QString::fromUtf8(lib->getName().c_str())));
mact->setData(row);
}
}
}
if (Library::isA(currentObj) &&
currentObj->getParent()->getId()==FWObjectDatabase::DELETED_OBJECTS_ID)
{
popup_menu->addAction( tr("Undelete"), this, SLOT(undeleteLibrary()));
}
popup_menu->addSeparator();
QAction *copyID = popup_menu->addAction(tr("Copy"), this, SLOT(copyObj()));
QAction *cutID = popup_menu->addAction(tr("Cut"), this, SLOT(cutObj()));
QAction *pasteID = popup_menu->addAction(tr("Paste"), this, SLOT(pasteObj()));
popup_menu->addSeparator();
QAction * delID = popup_menu->addAction( tr("Delete"), this,
SLOT( delObj() ) );
popup_menu->addSeparator();
QList<QAction*> AddObjectActions;
if (getCurrentObjectTree()->getNumSelected()==1)
{
if ( (Firewall::isA(currentObj) || Host::isA(currentObj)) &&
! currentObj->isReadOnly() )
{
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, Interface::TYPENAME));
}
if ((Firewall::isA(currentObj) || Cluster::isA(currentObj)) &&
! currentObj->isReadOnly())
{
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, Policy::TYPENAME));
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, NAT::TYPENAME));
}
if (Interface::isA(currentObj) && ! currentObj->isReadOnly())
{
Interface *iface = Interface::cast(currentObj);
FWObject *h = Host::getParentHost(iface);
//FWObject *h = iface->getParentHost();
bool supports_advanced_ifaces = false;
try {
/*
* ignore raised exception; this just means that the host_OS
* option is undefined for this target (e.g. for a host).
*/
supports_advanced_ifaces = Resources::getTargetCapabilityBool
(h->getStr("host_OS"), "supports_subinterfaces");
} catch (FWException &ex) { }
/*
* check if this interface can have subinterfaces. Show "Add Interface"
* menu item only if host_os has attribute "supports_subinterfaces"
* and if parent interface (currentObj) has the type that can have
* subinterfaces. Also, cluster interfaces can't have subinterfaces
* and only one level of subinterfaces is allowed.
*/
if (supports_advanced_ifaces && Firewall::isA(currentObj->getParent()))
{
list<QStringPair> subint_types;
getSubInterfaceTypes(iface, subint_types);
if (subint_types.size())
addNewObjectMenuItem(popup_menu, Interface::TYPENAME);
// popup_menu->addAction(
// tr("Add Interface"), this, SLOT( newInterface() ) );
}
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, IPv4::TYPENAME));
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, IPv6::TYPENAME));
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, physAddress::TYPENAME));
/*
* Add menu item to let user add AttachedNetworks object
* to an interface, but only if this object does not exist yet.
*
* Actions added to AddObjectActions are
* enabled and disabled all together based on the decision
* made in getMenuState() (argument newMenuItem). But we
* should always allow the user to add AttachedNetworks
* object to an interface.
*/
FWObject *att = currentObj->getFirstByType(AttachedNetworks::TYPENAME);
if (att == NULL)
addNewObjectMenuItem(popup_menu, AttachedNetworks::TYPENAME);
// Check if we should add menu item that creates failover
// group. if parent is a cluster, allow one vrrp type
// FailoverClusterGroup per Interface only
FWObject *parent = NULL;
parent = currentObj->getParent();
if (parent != NULL && Cluster::isA(parent))
{
QAction *failover_menu_id = addNewObjectMenuItem(
popup_menu, FailoverClusterGroup::TYPENAME);
// QAction *failover_menu_id = popup_menu->addAction(
// tr("Add Failover Group"), this,
// SLOT( newFailoverClusterGroup() ) );
failover_menu_id->setEnabled(
currentObj->getFirstByType(
FailoverClusterGroup::TYPENAME) == NULL);
}
}
if (Cluster::isA(currentObj) && ! currentObj->isReadOnly())
{
AddObjectActions.append(
addNewObjectMenuItem(
popup_menu, Interface::TYPENAME, "Add cluster interface"));
// allow multiple state syncing groups per cluster
// Rationale: these groups may represent different state syncing
// protocols that can synchronize different things.
AddObjectActions.append(
addNewObjectMenuItem(
popup_menu, StateSyncClusterGroup::TYPENAME));
}
if (currentObj->getPath(true)=="Firewalls")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, Firewall::TYPENAME));
if (currentObj->getPath(true)=="Clusters")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, Cluster::TYPENAME));
if (currentObj->getPath(true)=="Objects/Addresses")
{
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, IPv4::TYPENAME));
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, IPv6::TYPENAME));
}
if (currentObj->getPath(true)=="Objects/DNS Names")
{
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, DNSName::TYPENAME));
}
if (currentObj->getPath(true)=="Objects/Address Tables")
{
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, AddressTable::TYPENAME));
}
if (currentObj->getPath(true)=="Objects/Address Ranges")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, AddressRange::TYPENAME));
if (currentObj->getPath(true)=="Objects/Hosts")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, Host::TYPENAME));
if (currentObj->getPath(true)=="Objects/Networks")
{
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, Network::TYPENAME));
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, NetworkIPv6::TYPENAME));
}
if (currentObj->getPath(true)=="Objects/Groups")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, ObjectGroup::TYPENAME));
if (currentObj->getPath(true)=="Services/Custom")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, CustomService::TYPENAME));
if (currentObj->getPath(true)=="Services/IP")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, IPService::TYPENAME));
if (currentObj->getPath(true)=="Services/ICMP")
{
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, ICMPService::TYPENAME));
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, ICMP6Service::TYPENAME));
}
if (currentObj->getPath(true)=="Services/TCP")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, TCPService::TYPENAME));
if (currentObj->getPath(true)=="Services/UDP")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, UDPService::TYPENAME));
if (currentObj->getPath(true)=="Services/TagServices")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, TagService::TYPENAME));
if (currentObj->getPath(true)=="Services/Groups")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, ServiceGroup::TYPENAME));
if (currentObj->getPath(true)=="Services/Users")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, UserService::TYPENAME));
if (currentObj->getPath(true)=="Time")
AddObjectActions.append(
addNewObjectMenuItem(popup_menu, Interval::TYPENAME));
popup_menu->addSeparator();
QAction *findID =
popup_menu->addAction( tr("Find"), this, SLOT( findObject()));
QAction *whereUsedID =
popup_menu->addAction( tr("Where used"),
this, SLOT( findWhereUsedSlot()));
findID->setEnabled( !FWBTree().isStandardFolder(currentObj));
whereUsedID->setEnabled( !FWBTree().isStandardFolder(currentObj));
}
popup_menu->addSeparator();
popup_menu->addAction( tr("Group"), this, SLOT( groupObjects() ) )
->setDisabled(getCurrentObjectTree()->getNumSelected()==1);
if (Firewall::cast(currentObj)!=NULL ||
(ObjectGroup::cast(currentObj)!=NULL &&
currentObj->getName()=="Firewalls"))
{
bool canCreateCluster = true;
if (getCurrentObjectTree()->getNumSelected() > 1)
{
foreach( FWObject *obj, getCurrentObjectTree()->getSelectedObjects())
{
if (!Firewall::isA(obj))
{
canCreateCluster = false;
break;
}
}
} else canCreateCluster = false;
popup_menu->addAction( tr("New cluster from selected firewalls"),
this, SLOT( newClusterFromSelected() ) )->setEnabled(canCreateCluster);
popup_menu->addSeparator();
popup_menu->addAction( tr("Compile"), this, SLOT( compile()));
popup_menu->addAction( tr("Install"), this, SLOT( install()));
popup_menu->addAction( tr("Inspect"), this, SLOT( inspect()));
if (Firewall::cast(currentObj)!=NULL)
{
Resources* os_res = Resources::os_res[currentObj->getStr("host_OS")];
if (os_res)
{
string transfer = os_res->getTransferAgent();
if (!transfer.empty())
popup_menu->addAction( tr("Transfer"), this, SLOT(transferfw()));
}
}
if (ObjectGroup::cast(currentObj)!=NULL &&
currentObj->getName()=="Firewalls")
{
// Config transfer is currently only supported for Secuwall.
// Check if we have any
bool have_transfer_support = false;
for (FWObject::iterator it=currentObj->begin();
it!=currentObj->end(); ++it)
{
FWObject *fw = *it;
Resources* os_res = Resources::os_res[fw->getStr("host_OS")];
if (os_res)
{
string transfer = os_res->getTransferAgent();
have_transfer_support = have_transfer_support || (!transfer.empty());
}
}
if (have_transfer_support)
popup_menu->addAction( tr("Transfer"), this, SLOT(transferfw()));
}
}
popup_menu->addSeparator();
QAction* lckID = popup_menu->addAction(tr("Lock"), this, SLOT(lockObject()));
QAction* unlckID = popup_menu->addAction(tr("Unlock"), this, SLOT(unlockObject()));
lckID->setEnabled(isCurrentObjectLockable());
unlckID->setEnabled(isCurrentObjectUnlockable());
if (fwbdebug)
{
/* keep this for debugging */
popup_menu->addSeparator();
popup_menu->addAction( tr("dump"), this, SLOT( dumpObj()));
}
if (getCurrentObjectTree()->getNumSelected()==1)
{
edtID->setEnabled( !FWBTree().isStandardFolder(currentObj));
} else
edtID->setEnabled(false);
bool dupMenuItem = true;
bool moveMenuItem = true;
bool copyMenuItem = true;
bool pasteMenuItem = true;
bool delMenuItem = true;
bool newMenuItem = true;
bool inDeletedObjects = false;
getMenuState( (moveTargetsCounter>0),
dupMenuItem, moveMenuItem, copyMenuItem, pasteMenuItem,
delMenuItem, newMenuItem, inDeletedObjects);
if (dupID) dupID->setEnabled(dupMenuItem);
copyID->setEnabled(copyMenuItem);
pasteID->setEnabled(pasteMenuItem);
cutID->setEnabled(delMenuItem);
delID->setEnabled(delMenuItem);
// can not move object if can not delete it
if (movetargets)
movetargets->setEnabled(delMenuItem);
QList<QAction*>::iterator iter;
for (iter=AddObjectActions.begin(); iter!=AddObjectActions.end(); iter++)
(*iter)->setEnabled(newMenuItem);
// if (inDeletedObjects) movID->setText( tr("Undelete...") );
popup_menu->exec( objTreeView->mapToGlobal( pos ) );
}
bool ObjectManipulator::getDeleteMenuState(FWObject *obj)
{
if (obj->isReadOnly()) return false;
QString objPath = obj->getPath(true).c_str();
bool del_menu_item_state = FWBTree().getDeleteMenuState(objPath);
// can't delete last policy, nat and routing child objects
// also can't delete "top" policy ruleset
if (del_menu_item_state && RuleSet::cast(obj))
{
Firewall *fw = Firewall::cast(obj->getParent());
// fw can be NULL if this ruleset is in the Deleted objects
// library
if (fw==NULL) return del_menu_item_state;
list<FWObject*> child_objects = fw->getByType(obj->getTypeName());
if (child_objects.size()==1) del_menu_item_state = false;
}
return del_menu_item_state;
}
void ObjectManipulator::getMenuState(bool haveMoveTargets,
bool &dupMenuItem,
bool &moveMenuItem,
bool &copyMenuItem,
bool &pasteMenuItem,
bool &delMenuItem,
bool &newMenuItem,
bool &inDeletedObjects)
{
inDeletedObjects = false;
if (m_project->db() == NULL)
{
dupMenuItem = false;
moveMenuItem = false;
copyMenuItem = false;
pasteMenuItem = false;
delMenuItem = false;
newMenuItem = false;
return;
}
dupMenuItem = true;
moveMenuItem = true;
copyMenuItem = true;
pasteMenuItem = true;
delMenuItem = true;
newMenuItem = true;
FWObject *del_obj_library =
m_project->db()->findInIndex( FWObjectDatabase::DELETED_OBJECTS_ID);
FWObject *current_library = getCurrentLib();
if (getCurrentObjectTree()==NULL) return;
// delete, cut and copy menu items will be enabled only if all
// selected objects have the same parent (so user can not select
// an interface and one but not all of its addresses for deletion,
// see #1676)
FWObject *parent = NULL;
vector<FWObject*> so = getCurrentObjectTree()->getSelectedObjects();
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
{
FWObject *obj= *i;
QString object_path = obj->getPath(true).c_str();
if (parent == NULL) parent = obj->getParent();
else
{
if (parent != obj->getParent())
{
delMenuItem = false;
copyMenuItem = false;
}
}
if (AttachedNetworks::isA(obj))
{
dupMenuItem = false;
moveMenuItem = false;
copyMenuItem = false;
pasteMenuItem = false;
newMenuItem = false;
continue;
}
copyMenuItem = copyMenuItem && FWBTree().getCopyMenuState(object_path);
pasteMenuItem = pasteMenuItem &&
FWBTree().getPasteMenuState(object_path) &&
FWObjectClipboard::obj_clipboard &&
(FWObjectClipboard::obj_clipboard->size()!=0);
delMenuItem = delMenuItem && getDeleteMenuState(obj);
delMenuItem = delMenuItem && current_library != NULL &&
current_library->getId() != FWObjectDatabase::STANDARD_LIB_ID;
#if DISABLE_PASTE_MENU_ITEM_IF_PASTE_IS_ILLEGAL
if (pasteMenuItem)
{
/*
* We used to enable Paste menu item only if object can be
* pasted. The problem with this is that there was no
* indication why Paste operation was not allowed. Since
* we call validateForPaste during actual Paste operation
* anyway, it is more user friendly to let them try and
* actually see the error if it fails.
*/
vector<std::pair<int,ProjectPanel*> >::iterator i;
for (i= FWObjectClipboard::obj_clipboard->begin();
i!=FWObjectClipboard::obj_clipboard->end(); ++i)
{
FWObject *co= m_project->db()->findInIndex(i->first);
if (co==NULL)
{
continue ;
//QString s2 = obj->getTypeName().c_str();
}
QString s3 = obj->getTypeName().c_str();
QString err;
bool validated = FWBTree().validateForInsertion(obj, co, err);
pasteMenuItem = pasteMenuItem && validated;
}
}
#endif
dupMenuItem=
(dupMenuItem && ! FWBTree().isStandardFolder(obj) && ! Library::isA(obj) );
inDeletedObjects = (del_obj_library!=NULL && obj->isChildOf(del_obj_library));
dupMenuItem = dupMenuItem && !inDeletedObjects;
// can't move system objects or libraries
moveMenuItem = moveMenuItem && ! FWBTree().isStandardFolder(obj) && ! Library::isA(obj);
// can't move interfaces unless parent host object is also selected
if ( Interface::isA(obj) &&
std::find(so.begin(),so.end(),obj->getParent())==so.end())
moveMenuItem = false;
// can't move ip addresses if parent is interface
if (IPv4::isA(obj) && IPv6::isA(obj) && Interface::isA(obj->getParent()))
moveMenuItem = false;
// can't move physAddress objects
moveMenuItem = moveMenuItem && ! physAddress::isA(obj);
// can't move read-only objects
moveMenuItem = moveMenuItem && ! obj->isReadOnly();
// can't move libraries unless in deleted objects
if (Library::isA(obj) && ! inDeletedObjects) moveMenuItem = false;
// can't move if there is only one user-defined library in the tree
// but we dont care about number of libraries if this will become
// 'undelete' operation
if (!haveMoveTargets && ! inDeletedObjects) moveMenuItem = false;
newMenuItem= (newMenuItem && ! obj->isReadOnly() );
Interface *intf = Interface::cast(obj);
if (intf &&
(intf->isDyn() ||
intf->isUnnumbered() ||
intf->isBridgePort())
)
newMenuItem = false;
}
}
bool ObjectManipulator::isCurrentObjectLockable()
{
FWObject *currentObj = getSelectedObject();
return (currentObj && !currentObj->getParent()->isReadOnly() && !currentObj->getRO());
}
bool ObjectManipulator::isCurrentObjectUnlockable()
{
FWObject *currentObj = getSelectedObject();
return (currentObj && !currentObj->getParent()->isReadOnly() && currentObj->getRO());
}
void ObjectManipulator::filterFirewallsFromSelection(vector<FWObject*> &so,
set<Firewall*> &fo)
{
Firewall *fw;
ObjectGroup *gr;
Cluster *cl;
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
{
cl = Cluster::cast(*i);
if (cl != NULL)
{
list<Firewall*> members;
cl->getMembersList(members);
// display warning if no firewalls could be extracted for a cluster
if (members.size() == 0)
{
QMessageBox::warning(this, "Firewall Builder",
QObject::tr("No firewalls assigned to cluster '%1'").
arg(cl->getName().c_str()),
"&Continue", QString::null, QString::null, 0, 1 );
continue;
}
fo.insert(cl);
continue;
}
fw = Firewall::cast(*i);
if (fw!=NULL)
{
fo.insert(fw);
continue;
}
gr = ObjectGroup::cast(*i);
if (gr!=NULL)
{
extractFirewallsFromGroup(gr,fo);
}
}
}
void ObjectManipulator::extractFirewallsFromGroup(ObjectGroup *gr,
set<Firewall*> &fo)
{
set<FWObject*> oset;
m_project->db()->findObjectsInGroup(gr, oset);
set<FWObject*>::iterator i;
for(i=oset.begin();i!=oset.end();++i)
if (Firewall::cast(*i)) fo.insert(Firewall::cast(*i));
}
FWObject* ObjectManipulator::prepareForInsertion(FWObject *target, FWObject *obj)
{
if (fwbdebug)
qDebug("prepareForInsertion %s --> %s", obj->getName().c_str(),
target->getName().c_str());
FWObject *ta = target;
if (IPv4::isA(ta) || IPv6::isA(ta)) ta = ta->getParent();
if (Library::isA(target))
ta = FWBTree().getStandardSlotForObject(target,
obj->getTypeName().c_str());
QString err;
if (! FWBTree().validateForInsertion(ta, obj, err))
{
QMessageBox::critical(
this,"Firewall Builder",
err,
"&Continue", QString::null, QString::null,
0, 1 );
return NULL;
}
return ta;
}
void ObjectManipulator::editSelectedObject()
{
if (fwbdebug) qDebug("ObjectManipulator::editSelectedObject");
if (getCurrentObjectTree()->getNumSelected()==0) return;
FWObject *obj = getCurrentObjectTree()->getSelectedObjects().front();
if (obj==NULL) return;
// do not edit system folders (#1729)
if (FWBTree().isSystem(obj)) return;
if (RuleSet::cast(obj)!=NULL)
{
// Open rule set object in the editor if it is already opened
// in RuleSetView. If we just opened it in RuleSetView, check
// if the editor is visible and if yes, open the object in the
// editor right away. See #1331
if (m_project->getCurrentRuleSet() == obj)
{
QCoreApplication::postEvent(
mw, new openObjectInEditorEvent(
m_project->getFileName(), obj->getId()));
} else
{
QCoreApplication::postEvent(
m_project, new openRulesetEvent(
m_project->getFileName(), obj->getId()));
if (mw->isEditorVisible())
QCoreApplication::postEvent(
mw, new openObjectInEditorEvent(
m_project->getFileName(), obj->getId()));
}
} else
QCoreApplication::postEvent(
mw, new openObjectInEditorEvent(
m_project->getFileName(), obj->getId()));
}
void ObjectManipulator::openSelectedRuleSet()
{
if (getCurrentObjectTree()->getNumSelected()==0) return;
FWObject *obj = getCurrentObjectTree()->getSelectedObjects().front();
if (obj==NULL) return;
if (RuleSet::cast(obj)!=NULL && m_project->getCurrentRuleSet()!=obj)
QCoreApplication::postEvent(
m_project, new openRulesetEvent(m_project->getFileName(), obj->getId()));
}
bool ObjectManipulator::editObject(FWObject *obj)
{
if (fwbdebug) qDebug("ObjectManipulator::editObject");
if (!mw->isEditorVisible()) mw->showEditor();
return switchObjectInEditor(obj);
}
bool ObjectManipulator::switchObjectInEditor(FWObject *obj)
{
if (fwbdebug) qDebug("ObjectManipulator::switchObjectInEditor");
if (obj && fwbdebug)
{
qDebug("obj: %s", obj->getName().c_str());
FWObject *edt_obj = mw->getOpenedEditor();
if (edt_obj)
qDebug("in editor: %s", edt_obj->getName().c_str());
}
if (RuleSet::cast(obj)!=NULL)
{
if (obj!=m_project->getCurrentRuleSet())
{
m_project->openRuleSet(obj);
}
}
if (!mw->isEditorVisible()) return false;
if (!mw->requestEditorOwnership(this, obj, ObjectEditor::optNone, true))
{
if (fwbdebug) qDebug("Can not get editor panel ownership");
return false;
}
if (fwbdebug) qDebug("Open object in editor");
mw->openEditor(obj); // opens object in the editor
//currentObj = obj;
active = true;
if (fwbdebug) qDebug("ObjectManipulator::switchObjectInEditor done");
return true; // successfully (re)opened obj in the editor
}
void ObjectManipulator::closeObject()
{
//currentObj = NULL;
if (mw->isEditorVisible()) mw->hideEditor();
}
void ObjectManipulator::selectionChanged(QTreeWidgetItem *cur)
{
if (fwbdebug)
qDebug("ObjectManipulator::selectionChanged");
QTreeWidget *qlv = getCurrentObjectTree();
if (qlv==NULL) return;
ObjectTreeViewItem* otvi = dynamic_cast<ObjectTreeViewItem*>(cur);
if (otvi==NULL) return;
FWObject *obj = otvi->getFWObject();
if (obj==NULL) return;
if (fwbdebug) qDebug("ObjectManipulator::selectionChanged obj=%s",
obj->getName().c_str());
FWObject *o = obj;
//if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
if (history.empty() || otvi!=history.back().item() )
{
mw->enableBackAction();
history.push_back( HistoryItem(otvi, o->getId()) );
}
//currentObj = obj;
active = true;
update();
if (fwbdebug) qDebug("ObjectManipulator::selectionChanged done");
}
void ObjectManipulator::openObjectInTree(ObjectTreeViewItem *otvi,
bool register_in_history)
{
openObjectInTree(otvi->getFWObject(), register_in_history);
}
/*
* I could use default value for the parameter register_in_history,
* but that caused problems when this method was used as a slot
*/
void ObjectManipulator::openObjectInTree(QTreeWidgetItem *item)
{
ObjectTreeViewItem *otvi = dynamic_cast<ObjectTreeViewItem*>(item);
openObjectInTree(otvi, true);
}
void ObjectManipulator::openObjectInTree(FWObject *obj)
{
openObjectInTree(obj,true);
}
/* This method is called from the GroupObjectDialog when user double
* clicks on the object in a group, so first we should check if this
* object is shown in the tree and if not, find and open it.
*/
void ObjectManipulator::openObjectInTree(FWObject *obj, bool /*register_in_history*/)
{
if (fwbdebug)
qDebug() << "ObjectManipulator::openObjectInTree"
<< "obj:" << ((obj)?obj->getName().c_str():"NULL")
<< "id:" << ((obj)?obj->getId():0);
if (obj==NULL) return;
openLibForObject(obj);
//raise();
FWObject *o=obj;
if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
ObjectTreeViewItem *otvi = allItems[o];
// this changes selection and thus calls slot slectionChanged
showObjectInTree(otvi);
if (fwbdebug)
qDebug() << "ObjectManipulator::openObjectInTree"
<< "libs->currentIndex="
<< m_objectManipulator->libs->currentIndex();
updateCreateObjectMenu(obj->getLibrary());
if (fwbdebug) qDebug() << "ObjectManipulator::openObjectInTree: done";
}
void ObjectManipulator::openLibForObject(FWObject *obj)
{
// if obj is Library, its getLibrary() method returns itself. If
// this library has been deleted and is now in the Deleted Objects
// library, getIdxForLib() is not going to find it.
if (FWObjectDatabase::isA(obj->getParent()))
m_objectManipulator->libs->setCurrentIndex(
libs_model->getIdxForLib(obj->getLibrary()).row());
else
{
FWObject *parent = obj->getParent();
FWObject *lib = parent->getLibrary();
m_objectManipulator->libs->setCurrentIndex(
libs_model->getIdxForLib(lib).row());
}
}
void ObjectManipulator::showObjectInTree(ObjectTreeViewItem *otvi)
{
if (fwbdebug)
qDebug("ObjectManipulator::showObjectInTree");
if (otvi==NULL) return;
ObjectTreeView* otv = otvi->getTree();
if (fwbdebug)
qDebug() << "ObjectManipulator::showObjectInTree"
<< "current_tree_view=" << current_tree_view
<< "new_otv=" << otv;
// otv->raise();
m_objectManipulator->widgetStack->setCurrentWidget(otv);
otvi->getTree()->clearSelection();
otvi->getTree()->scrollToItem(otvi);
otvi->getTree()->setCurrentItem(otvi);
otvi->setSelected(true);
// otvi->getTree()->setFocus(Qt::OtherFocusReason);
}
void ObjectManipulator::libChangedById(int obj_id)
{
for (int i=0; i<libs_model->rowCount(); ++i)
{
QModelIndex idx = libs_model->index(i, 0);
FWObject *l = libs_model->getLibrary(idx);
if (l == NULL) continue;
if (l->getId() == obj_id)
{
libChanged(i);
m_objectManipulator->libs->setCurrentIndex(i);
return;
}
}
}
FWObject* ObjectManipulator::getNextUserLib(FWObject *after_this)
{
QString sid2 = "syslib000";
QString sid3 = "syslib001";
FWObject *lib = NULL;
if (after_this != NULL) lib = after_this->getLibrary();
for (int i=0; i<libs_model->rowCount(); ++i)
{
QModelIndex idx = libs_model->index(i, 0);
FWObject *l = libs_model->getLibrary(idx);
if (l == NULL) continue;
if (l == lib) continue;
QString sid1 = FWObjectDatabase::getStringId(l->getId()).c_str();
if ( sid1 == sid2 || sid1 == sid3) continue;
return l;
}
return NULL;
}
void ObjectManipulator::libChanged(int list_row)
{
if (fwbdebug) qDebug() << "ObjectManipulator::libChanged list_row=" << list_row;
previous_lib_index = list_row;
QTreeWidget *objTreeView = libs_model->getTreeWidget(list_row);
if (objTreeView == NULL)
{
if (fwbdebug)
{
qDebug() << "There is no object tree widget associated with this row";
qDebug() << "Scanning all rows:";
for (int i=0; i<libs_model->rowCount(); ++i)
{
qDebug() << "Row" << i;
QTreeWidget *objTreeView = libs_model->getTreeWidget(i);
FWObject *lib = libs_model->getLibrary(i);
qDebug() << "lib=" << lib << "objTreeView=" << objTreeView;
}
}
return;
}
ObjectTreeViewItem *otvi = dynamic_cast<ObjectTreeViewItem*>(objTreeView->currentItem());
if (otvi == NULL)
{
if (objTreeView->invisibleRootItem()->childCount() > 0)
otvi = dynamic_cast<ObjectTreeViewItem*>(
objTreeView->invisibleRootItem()->child(0));
else
assert(FALSE);
}
showObjectInTree( otvi );
QCoreApplication::postEvent(mw, new updateGUIStateEvent());
return;
}
void ObjectManipulator::updateCreateObjectMenu(FWObject* lib)
{
bool f = (
lib == NULL ||
lib->getId()==FWObjectDatabase::TEMPLATE_LIB_ID ||
lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID ||
lib->isReadOnly()
);
bool new_object_op_possible = !f;
emit libraryAccessChanged(new_object_op_possible);
m_objectManipulator->newButton->setEnabled(new_object_op_possible);
QAction *noa = (QAction*)(mw->findChild<QAction*>("newObjectAction"));
noa->setEnabled(new_object_op_possible);
}
FWObject* ObjectManipulator::getCurrentLib()
{
int idx = m_objectManipulator->libs->currentIndex();
if (idx == -1 ) return NULL;
FWObject *lib = libs_model->getLibrary(idx);
return lib;
}
ObjectTreeView* ObjectManipulator::getCurrentObjectTree()
{
return libs_model->getTreeWidget(m_objectManipulator->libs->currentIndex());
// return current_tree_view;
}
void ObjectManipulator::openLib(FWObject *obj)
{
openObjectInTree(obj->getLibrary(),false);
}
void ObjectManipulator::newObject()
{
m_objectManipulator->newButton->showMenu();
}
void ObjectManipulator::select()
{
FWObject *currentObj = getSelectedObject();
if (fwbdebug)
qDebug() << "ObjectManipulator::select()"
<< "currentObj=" << currentObj
<< ((currentObj)?currentObj->getName().c_str():" [unknown] ");
if (currentObj==NULL) return;
m_objectManipulator->libs->setCurrentIndex(
libs_model->getIdxForLib(currentObj->getLibrary()).row());
// TODO: I forget why do we need flag "active", check this.
ObjectTreeViewItem *otvi = allItems[currentObj];
if (otvi)
{
active = true;
}
if (fwbdebug) qDebug("ObjectManipulator::select() done");
}
void ObjectManipulator::unselect()
{
FWObject *currentObj = getSelectedObject();
if (currentObj==NULL) return;
for (int i=0; i<libs_model->rowCount(); ++i)
{
QTreeWidget *otv = libs_model->getTreeWidget(i);
if (otv == NULL) continue;
otv->clearSelection();
}
active=false;
}
list<Cluster*> ObjectManipulator::findClustersUsingFirewall(FWObject *fw)
{
list<Cluster*> res;
list<Cluster*> all_clusters;
findAllClusters(all_clusters);
list<Cluster*>::iterator it;
for (it=all_clusters.begin(); it!=all_clusters.end(); ++it)
{
Cluster *cl = *it;
list<Firewall*> members;
cl->getMembersList(members);
if (std::find(members.begin(), members.end(), Firewall::cast(fw)) != members.end())
res.push_back(cl);
}
return res;
}
void ObjectManipulator::findAllFirewalls(list<Firewall*> &fws)
{
if (fwbdebug) qDebug("ObjectManipulator::findAllFirewalls");
list<FWObject*> fwlist;
findByObjectType(m_project->db(), Firewall::TYPENAME, fwlist);
for (list<FWObject*>::iterator m=fwlist.begin(); m!=fwlist.end(); m++)
fws.push_back(Firewall::cast(*m));
}
void ObjectManipulator::findAllClusters(list<Cluster*> &clusters)
{
list<FWObject*> cllist;
findByObjectType(m_project->db(), Cluster::TYPENAME, cllist);
for (list<FWObject*>::iterator m=cllist.begin(); m!=cllist.end(); m++)
clusters.push_back(Cluster::cast(*m));
}
void ObjectManipulator::simulateInstall()
{
if (fwbdebug) qDebug("ObjectManipulator::simulateInstall");
if (getCurrentObjectTree()->getNumSelected()==0) return;
Firewall *fw;
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
{
fw= Firewall::cast( *i );
if (fw!=NULL)
{
fw->updateLastCompiledTimestamp();
fw->updateLastInstalledTimestamp();
}
}
}
FWObject* ObjectManipulator::getSelectedObject()
{
QTreeWidgetItem *cur = getCurrentObjectTree()->currentItem();
if (cur)
{
ObjectTreeViewItem* otvi = dynamic_cast<ObjectTreeViewItem*>(cur);
return otvi->getFWObject();
}
return NULL;
}
void ObjectManipulator::reopenCurrentItemParent()
{
QTreeWidgetItem *itm = getCurrentObjectTree()->currentItem();
if (itm) itm = itm->parent();
if (!itm) return;
itm->parent()->setExpanded(false);
itm->parent()->setExpanded(true);
getCurrentObjectTree()->scrollToItem(itm, QAbstractItemView::EnsureVisible);
getCurrentObjectTree()->update();
}
void ObjectManipulator::loadSectionSizes()
{
for (int i=0; i<libs_model->rowCount(); ++i)
{
QTreeWidget *objTreeView = libs_model->getTreeWidget(i);
FWObject *lib = libs_model->getLibrary(i);
if (lib == NULL || objTreeView == NULL) continue;
objTreeView->header()->resizeSection(
0,
st->getTreeSectionSize(
m_project->getFileName(), lib->getName().c_str(), 0));
objTreeView->header()->resizeSection(
1,
st->getTreeSectionSize(
m_project->getFileName(), lib->getName().c_str(), 1));
}
}
void ObjectManipulator::saveSectionSizes()
{
for (int i=0; i<libs_model->rowCount(); ++i)
{
QTreeWidget *objTreeView = libs_model->getTreeWidget(i);
FWObject *lib = libs_model->getLibrary(i);
if (lib == NULL || objTreeView == NULL) continue;
st->setTreeSectionSize(
m_project->getFileName(), lib->getName().c_str(), 0,
objTreeView->header()->sectionSize(0));
st->setTreeSectionSize(
m_project->getFileName(), lib->getName().c_str(), 1,
objTreeView->header()->sectionSize(1));
}
}
void ObjectManipulator::loadExpandedTreeItems()
{
if (fwbdebug) qDebug() << "ObjectManipulator::loadExpandedTreeItems()";
for (int i=0; i<libs_model->rowCount(); ++i)
{
if (fwbdebug) qDebug() << "i=" << i;
ObjectTreeView *objTreeView = libs_model->getTreeWidget(i);
FWObject *lib = libs_model->getLibrary(i);
if (lib == NULL || objTreeView == NULL) continue;
set<int> expanded_objects;
st->getExpandedObjectIds(m_project->getFileName(),
lib->getName().c_str(),
expanded_objects);
objTreeView->ExpandTreeItems(expanded_objects);
// there is no need to resize columns because call to
//loadExpandedTreeItems is usually followed by the call to loadSectionSizes
//objTreeView->header()->resizeSections(QHeaderView::ResizeToContents);
}
}
void ObjectManipulator::saveExpandedTreeItems()
{
for (int i=0; i<libs_model->rowCount(); ++i)
{
ObjectTreeView *objTreeView = libs_model->getTreeWidget(i);
FWObject *lib = libs_model->getLibrary(i);
if (lib == NULL || objTreeView == NULL) continue;
st->setExpandedObjectIds(m_project->getFileName(),
lib->getName().c_str(),
objTreeView->getListOfExpandedObjectIds());
}
}
void ObjectManipulator::setAttributesColumnEnabled(bool)
{
for (int i=0; i<libs_model->rowCount(); ++i)
{
ObjectTreeView *objTreeView = libs_model->getTreeWidget(i);
if (objTreeView == NULL) continue;
objTreeView->showOrHideAttributesColumn();
}
}
void ObjectManipulator::findWhereUsedRecursively(FWObject *obj,
FWObject *top,
set<FWObject*> &resset)
{
UsageResolver().findWhereUsedRecursively(obj, top, resset, this->m_project->db());
}
list<Firewall*> ObjectManipulator::findFirewallsForObject(FWObject *o)
{
return UsageResolver().findFirewallsForObject(o, this->m_project->db());
}