1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-21 02:37:16 +01:00
fwbuilder/src/libgui/ObjectManipulator.cpp

1603 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/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 = 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));
// 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)
{
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)
{
if (fwbdebug) qDebug("ObjectManipulator::getMenuState");
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);
if (fwbdebug) qDebug() << "ObjectManipulator::getMenuState del_obj_library=" << del_obj_library;
FWObject *current_library = getCurrentLib();
if (fwbdebug) qDebug() << "ObjectManipulator::getMenuState current_library=" << current_library;
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;
if (fwbdebug)
qDebug() << "ObjectManipulator::getMenuState"
<< "obj=" << obj
<< "root=" << obj->getRoot()
<< "current_library root=" << current_library->getRoot();
QString object_path = obj->getPath(true).c_str();
if (parent == NULL) parent = obj->getParent();
else
{
if (parent != obj->getParent())
{
delMenuItem = false;
copyMenuItem = false;
}
}
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;
}
if (fwbdebug) qDebug("ObjectManipulator::getMenuState done");
}
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
m_objectManipulator->libs->setCurrentIndex(
libs_model->getIdxForLib(obj->getParent()->getLibrary()).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, QAbstractItemView::PositionAtCenter);
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);
if (fwbdebug)
{
qDebug("ObjectManipulator::getCurrentLib(): idx=%d lib=%p", idx, lib);
}
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());
}