1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-22 03:07:20 +01:00

fixes #486, #393 Implemented ability to show object attributes in the tree

This commit is contained in:
Vadim Kurland 2009-09-30 22:37:35 +00:00
parent ed4bd7c90e
commit caaf341458
14 changed files with 298 additions and 54 deletions

View File

@ -1 +1 @@
#define BUILD_NUM 1527
#define BUILD_NUM 1528

View File

@ -1,3 +1,17 @@
2009-09-30 vadim <vadim@vk.crocodile.org>
* ObjectManipulator.cpp (ObjectManipulator::setAttributesColumnEnabled):
New feature: the GUI can show brief summary of object attributes
in the second column in the object tree. This is controlled by a
checkbox in the global preferences dialog, tab "Objects". This is
off by default. The first column always shows object icon and its
name, the second (optional) column shows its attributes. Interface
label is shown in the second column. The width of both columns in
the tree is set automatically to accommodate all the text, then
can be adjusted by the user using mouse. Column width is saved in
settings and will be restored upon program restart. Column width
is saved per-file, per-library.
2009-09-23 vadim <vadim@vk.crocodile.org>
* ../src/res/configlets/linux24/update_bonding: Generated iptables

View File

@ -772,6 +772,28 @@ void FWBSettings::setExpandedObjectIds(const QString &filename,
strl.join(","));
}
int FWBSettings::getTreeSectionSize(const QString &filename,
const QString &lib,
int section_index)
{
int v = value(
QString(SETTINGS_PATH_PREFIX "/Window/%1/%2/TreeSection/%3")
.arg(filename).arg(lib).arg(section_index)).toInt();
if (v <= 0) v = 300;
return v;
}
void FWBSettings::setTreeSectionSize(const QString &filename,
const QString &lib,
int section_index,
int size)
{
setValue(
QString(SETTINGS_PATH_PREFIX "/Window/%1/%2/TreeSection/%3")
.arg(filename).arg(lib).arg(section_index),
size);
}
int FWBSettings::getVisibleRuleSetId(const QString &filename,
const QString &lib)
{

View File

@ -197,6 +197,14 @@ class FWBSettings : public QSettings {
const QString &lib,
const std::set<int> &ids);
int getTreeSectionSize(const QString &filename,
const QString &lib,
int section_index);
void setTreeSectionSize(const QString &filename,
const QString &lib,
int section_index,
int size);
int getVisibleRuleSetId(const QString &filename,
const QString &lib);
void setVisibleRuleSet(const QString &filename,

View File

@ -79,10 +79,148 @@ using namespace std;
using namespace libfwbuilder;
/*
* API methods return STL string, so it is easier to use STL class
* ostringstream to assemble text and then convert it to QString
* rather than convert piece by piece.
* This method returns brief summary of properties, guaranteed to be 1
* line of text
*/
QString FWObjectPropertiesFactory::getObjectPropertiesBrief(FWObject *obj)
{
QString res;
QTextStream str(&res, QIODevice::WriteOnly);
FWObject *parent_obj = obj->getParent();
try
{
if (Library::isA(obj))
{
if (obj->isReadOnly()) str << "(read only)";
} else if (IPv4::isA(obj))
{
str << IPv4::cast(obj)->getAddressPtr()->toString().c_str();
if (parent_obj && Interface::isA(parent_obj))
{
str << "/";
str << IPv4::cast(obj)->getNetmaskPtr()->toString().c_str();
}
} else if (IPv6::isA(obj))
{
str << IPv6::cast(obj)->getAddressPtr()->toString().c_str();
if (parent_obj && Interface::isA(parent_obj))
{
str << "/";
str << QString("%1").arg(IPv6::cast(obj)->getNetmaskPtr()->getLength());
}
} else if (physAddress::isA(obj))
{
str << physAddress::cast(obj)->getPhysAddress().c_str();
} else if (DNSName::isA(obj))
{
str << DNSName::cast(obj)->getSourceName().c_str();
} else if (AddressTable::isA(obj))
{
str << AddressTable::cast(obj)->getSourceName().c_str();
} else if (AddressRange::isA(obj))
{
AddressRange *ar=AddressRange::cast(obj);
str << ar->getRangeStart().toString().c_str();
str << " - ";
str << ar->getRangeEnd().toString().c_str();
} else if (Firewall::cast(obj))
{
if (Firewall::cast(obj)->needsInstall()) str << " * ";
QString platform = obj->getStr("platform").c_str();
QString version = obj->getStr("version").c_str();
QString readableVersion = getVersionString(platform,version);
QString hostOS = obj->getStr("host_OS").c_str();
str << platform << "(" << readableVersion << ") / " << hostOS;
} else if (Host::isA(obj))
{
const InetAddr *addr = Address::cast(obj)->getAddressPtr();
if (addr)
str << addr->toString().c_str();
else
str << "(no ip address)";
} else if (Network::isA(obj))
{
Network *n=Network::cast(obj);
str << n->getAddressPtr()->toString().c_str();
str << "/";
str << n->getNetmaskPtr()->toString().c_str();
} else if (NetworkIPv6::isA(obj))
{
NetworkIPv6 *n=NetworkIPv6::cast(obj);
str << n->getAddressPtr()->toString().c_str();
str << "/";
str << QString("%1").arg(n->getNetmaskPtr()->getLength());
} else if (ClusterGroup::cast(obj)!=NULL)
{
ClusterGroup *g = ClusterGroup::cast(obj);
str << QObject::tr("type: ") << g->getStr("type").c_str();
} else if (Group::cast(obj)!=NULL) // just any group
{
Group *g=Group::cast(obj);
str << g->size() << " " << QObject::tr(" objects");
} else if (Interface::isA(obj))
{
Interface *intf = Interface::cast(obj);
// trigger late initialization of options object
// if its read-only or part of the read-only tree, I can't help it.
if (!obj->isReadOnly()) intf->getOptionsObject();
str << intf->getLabel().c_str();
QString q;
if (intf->isDyn()) q =" dyn";
if (intf->isUnnumbered()) q =" unnum";
if (intf->isBridgePort()) q =" bridge port";
if (intf->isSlave()) q =" slave";
if (intf->isUnprotected()) q = q + " unp";
if (q!="") str << " (" + q + ")";
} else if (IPService::isA(obj))
{
str << QObject::tr("protocol: %1").arg(obj->getStr("protocol_num").c_str());
} else if (ICMPService::isA(obj) || ICMP6Service::isA(obj))
{
str << QObject::tr("type: %1").arg(obj->getStr("type").c_str())
<< " "
<< QObject::tr("code: %1").arg(obj->getStr("code").c_str());
} else if (TCPService::isA(obj) || UDPService::isA(obj))
{
int sps,spe,dps,dpe;
sps=TCPUDPService::cast(obj)->getSrcRangeStart();
spe=TCPUDPService::cast(obj)->getSrcRangeEnd();
dps=TCPUDPService::cast(obj)->getDstRangeStart();
dpe=TCPUDPService::cast(obj)->getDstRangeEnd();
str << sps << ":" << spe << " / ";
str << dps << ":" << dpe;
} else if (TagService::isA(obj))
{
str << "Pattern: \"" << obj->getStr("tagcode").c_str() << "\"" ;
} else if (UserService::isA(obj))
{
const UserService* user_srv = UserService::constcast(obj);
str << "User id: \"" << user_srv->getUserId().c_str() << "\"" ;
} else if (Interval::isA(obj))
{
}
} catch (FWException &ex)
{
cerr << ex.toString() << endl;
}
return res;
}
QString FWObjectPropertiesFactory::getObjectProperties(FWObject *obj)
{
QString res;

View File

@ -42,6 +42,8 @@ class FWObjectPropertiesFactory {
* returns a one line property of the object for the second column of
* the tree view
*/
static QString getObjectPropertiesBrief(libfwbuilder::FWObject *obj);
static QString getObjectProperties(libfwbuilder::FWObject *obj);
static QString getObjectPropertiesDetailed(libfwbuilder::FWObject *obj,

View File

@ -243,39 +243,16 @@ ObjectManipulator::ObjectManipulator( QWidget *parent):
m_objectManipulator->newButton->setMenu( newObjectPopup );
}
/*
* This method decides what should be shown in the column #1 of the
* tree for the given object
*/
QString ObjectManipulator::getTreeLabel( FWObject *obj )
{
QString name = QString::fromUtf8(obj->getName().c_str());
if (RuleSet::isA(obj))
{
return name ;
}
if (Interface::isA(obj))
{
// trigger late initialization of options object
// if its read-only or part of the read-only tree, I can't help it.
if (!obj->isReadOnly()) Interface::cast(obj)->getOptionsObject();
name =Interface::constcast(obj)->getLabel().c_str();
if (name=="") name=QString::fromUtf8(obj->getName().c_str());
QString q;
if (Interface::constcast(obj)->isDyn()) q =" dyn";
if (Interface::constcast(obj)->isUnnumbered()) q =" unnum";
if (Interface::constcast(obj)->isBridgePort()) q =" bridge port";
if (Interface::constcast(obj)->isSlave()) q =" slave";
if (Interface::constcast(obj)->isUnprotected()) q = q + " unp";
if (q!="") name = name+" (" + q + ")";
return name;
}
if (Firewall::isA(obj))
{
Firewall *fw = Firewall::cast(obj);
if (fw->needsInstall()) name += " *";
return name;
}
if (Library::isA(obj) && obj->isReadOnly())
name += QObject::tr(" ( read only )");
QString name;
if (RuleSet::cast(obj)) return "";
return name;
return FWObjectPropertiesFactory::getObjectPropertiesBrief(obj);
}
void ObjectManipulator::refreshSubtree(QTreeWidgetItem *itm)
@ -330,6 +307,7 @@ void ObjectManipulator::refreshSubtree(QTreeWidgetItem *itm)
*/
parent->setExpanded(false);
parent->setExpanded(true);
//getCurrentObjectTree()->header()->resizeSections(QHeaderView::ResizeToContents);
getCurrentObjectTree()->scrollToItem(itm, QAbstractItemView::EnsureVisible);
getCurrentObjectTree()->update();
}
@ -357,13 +335,14 @@ ObjectTreeViewItem* ObjectManipulator::insertObject(ObjectTreeViewItem *itm,
nitm = new ObjectTreeViewItem( itm );
nitm->setLib("");
nitm->setText( 0, getTreeLabel(obj) );
nitm->setText( 0, obj->getName().c_str() );
nitm->setText( 1, getTreeLabel(obj) );
QPixmap pm;
setObjectIcon(obj, &pm);
nitm->setIcon( 0, QIcon(pm) );
nitm->setIcon( 1, QIcon(pm) );
// nitm->setIcon( 1, QIcon(pm) );
nitm->setFlags(nitm->flags() | Qt::ItemIsDragEnabled);
nitm->setProperty("type", obj->getTypeName().c_str() );
@ -385,7 +364,7 @@ void ObjectManipulator::insertSubtree(ObjectTreeViewItem *itm, FWObject *obj)
ObjectTreeViewItem *nitm = insertObject(itm, obj);
if (nitm==NULL) return;
if ( FWBTree().isStandardFolder(obj) ) nitm->setExpanded( st->getExpandTree() );
if (FWBTree().isStandardFolder(obj)) nitm->setExpanded( st->getExpandTree());
if (Cluster::isA(obj))
{
@ -550,7 +529,9 @@ void ObjectManipulator::updateObjectInTree(FWObject *obj, bool subtree)
assert(itm!=NULL);
QString old_itm_text = itm->text(0);
itm->setText(0, getTreeLabel(obj));
itm->setText( 0, obj->getName().c_str() );
itm->setText( 1, getTreeLabel(obj) );
getCurrentObjectTree()->updateTreeIcons();
if (subtree)
@ -917,12 +898,7 @@ void ObjectManipulator::addTreePage( FWObject *lib)
m_objectManipulator->widgetStack->show();
objTreeView->show();
// objTreeView->setSelectionMode( QListView::Extended );
updateLibColor( lib );
// updateLibName( lib );
//objTreeView->setContextMenuPolicy( Qt::CustomContextMenu );
connect(m_objectManipulator->widgetStack, SIGNAL( currentChanged(int) ),
this, SLOT( currentTreePageChanged(int) ) );
@ -930,9 +906,6 @@ void ObjectManipulator::addTreePage( FWObject *lib)
connect(objTreeView, SIGNAL( editCurrentObject_sign() ),
this, SLOT( editSelectedObject()) );
// connect(objTreeView,SIGNAL( editCurrentObject_sign() ),
// this, SLOT( editSelectedObject()) );
connect(objTreeView,
SIGNAL( switchObjectInEditor_sign(libfwbuilder::FWObject*) ),
this, SLOT( switchObjectInEditor(libfwbuilder::FWObject*)) );
@ -961,7 +934,8 @@ void ObjectManipulator::addTreePage( FWObject *lib)
itm1->setFlags(itm1->flags() | Qt::ItemIsDragEnabled);
itm1->setText(0, getTreeLabel(lib));
itm1->setText( 0, lib->getName().c_str() );
itm1->setText( 1, getTreeLabel(lib) );
QPixmap pm;
setObjectIcon(lib, &pm);
@ -977,6 +951,7 @@ void ObjectManipulator::addTreePage( FWObject *lib)
objTreeView->updateTreeIcons();
// apparently sortByColumn does not work in QT 4.5, use sortItems
objTreeView->sortItems(0, Qt::AscendingOrder);
objTreeView->header()->resizeSections(QHeaderView::ResizeToContents);
}
void ObjectManipulator::removeLib(FWObject* lib)
@ -3947,6 +3922,40 @@ void ObjectManipulator::reopenCurrentItemParent()
getCurrentObjectTree()->update();
}
void ObjectManipulator::loadSectionSizes()
{
for (int i=0; i<m_objectManipulator->libs->count(); i++)
{
ObjectTreeView *objTreeView =
dynamic_cast<ObjectTreeView*>(idxToTrees[i]);
FWObject *lib = idxToLibs[i];
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<m_objectManipulator->libs->count(); i++)
{
ObjectTreeView *objTreeView =
dynamic_cast<ObjectTreeView*>(idxToTrees[i]);
FWObject *lib = idxToLibs[i];
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()
{
for (int i=0; i<m_objectManipulator->libs->count(); i++)
@ -3959,6 +3968,9 @@ void ObjectManipulator::loadExpandedTreeItems()
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);
}
}
@ -3975,6 +3987,16 @@ void ObjectManipulator::saveExpandedTreeItems()
}
}
void ObjectManipulator::setAttributesColumnEnabled(bool f)
{
for (int i=0; i<m_objectManipulator->libs->count(); i++)
{
ObjectTreeView *objTreeView =
dynamic_cast<ObjectTreeView*>(idxToTrees[i]);
objTreeView->showOrHideAttributesColumn();
}
}
/*
* This method tries to guess appropriate interface type and some other
* attributes for subinterfaces.

View File

@ -398,6 +398,11 @@ public:
void loadExpandedTreeItems();
void saveExpandedTreeItems();
void loadSectionSizes();
void saveSectionSizes();
void setAttributesColumnEnabled(bool f);
signals:
/**
* the dialog class should have a slot that can load object's data

View File

@ -84,7 +84,7 @@ ObjectTreeView::ObjectTreeView(ProjectPanel* project,
{
setObjectName(name);
this->setParent(parent, f);
setFont (st->getTreeFont());
setFont(st->getTreeFont());
// setAcceptDrops( TRUE );
item_before_drag_started=NULL;
lastSelected = NULL;
@ -124,13 +124,16 @@ ObjectTreeView::ObjectTreeView(ProjectPanel* project,
connect(this, SIGNAL(itemExpanded(QTreeWidgetItem*)),
this, SLOT(itemExpanded(QTreeWidgetItem*)));
setColumnCount(1);
QStringList qsl;
qsl.push_back(tr("Object"));
qsl.push_back(tr("Attributes"));
setHeaderLabels(qsl);
header()->hide();
//header()->hide();
header()->setResizeMode(QHeaderView::Interactive);
showOrHideAttributesColumn();
setMinimumSize( QSize( 100, 0 ) );
@ -851,3 +854,11 @@ void ObjectTreeView::ExpandTreeItems(const set<int> &ids)
}
}
void ObjectTreeView::showOrHideAttributesColumn()
{
if (st->getBool("UI/ShowObjectsAttributesInTree"))
setColumnCount(2);
else
setColumnCount(1);
}

View File

@ -140,6 +140,8 @@ protected:
void ExpandTreeItems(const std::set<int> &ids);
const std::set<int>& getListOfExpandedObjectIds() { return expanded_objects; }
void showOrHideAttributesColumn();
public slots:
void itemSelectionChanged();

View File

@ -35,6 +35,7 @@
#include "PrefsDialog.h"
#include "FWBSettings.h"
#include "FWWindow.h"
#include "ProjectPanel.h"
#include "HttpGet.h"
#include "fwbuilder/Resources.h"
@ -115,6 +116,7 @@ PrefsDialog::PrefsDialog(QWidget *parent) : QDialog(parent)
m_dialog->tooltipDelay->setValue( st->getTooltipDelay() );
m_dialog->deletedObj->setChecked( st->getBool("UI/ShowDeletedObjects") );
m_dialog->attributesInTree->setChecked( st->getBool("UI/ShowObjectsAttributesInTree") );
m_dialog->emptyRCSLog->setChecked( st->getRCSLogState() );
m_dialog->autosave->setChecked( st->getAutoSave() );
@ -389,7 +391,13 @@ void PrefsDialog::accept()
st->setObjTooltips( m_dialog->objTooltips->isChecked() );
st->setTooltipDelay( m_dialog->tooltipDelay->value() );
st->setBool("UI/ShowDeletedObjects", m_dialog->deletedObj->isChecked() );
st->setBool("UI/ShowDeletedObjects", m_dialog->deletedObj->isChecked());
st->setBool("UI/ShowObjectsAttributesInTree", m_dialog->attributesInTree->isChecked());
ProjectPanel *pp = mw->activeProject();
if (pp)
pp->m_panel->om->setAttributesColumnEnabled(
m_dialog->attributesInTree->isChecked());
// QToolTip::setWakeUpDelay( st->getTooltipDelay()*1000 );

View File

@ -105,6 +105,7 @@ void ProjectPanel::saveState()
st->setStr("Window/" + FileName + "/ObjInfoSplitter", arg );
m_panel->om->saveExpandedTreeItems();
m_panel->om->saveSectionSizes();
saveLastOpenedLib();
saveOpenedRuleSet();
@ -189,6 +190,7 @@ void ProjectPanel::loadState(bool)
setObjInfoSplitterPosition(w1, w2);
m_panel->om->loadExpandedTreeItems();
m_panel->om->loadSectionSizes();
loadLastOpenedLib();
loadOpenedRuleSet();

View File

@ -22,7 +22,7 @@
<item row="0" column="0" >
<widget class="QTabWidget" name="tabWidget" >
<property name="currentIndex" >
<number>5</number>
<number>1</number>
</property>
<widget class="QWidget" name="tabGeneral" >
<attribute name="title" >
@ -296,13 +296,20 @@
</widget>
</item>
<item row="4" column="0" colspan="5" >
<widget class="QCheckBox" name="attributesInTree" >
<property name="text" >
<string>Show object attributes in the tree</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="5" >
<widget class="QCheckBox" name="chClipComment" >
<property name="text" >
<string>Clip comments in rules</string>
</property>
</widget>
</item>
<item row="5" column="2" >
<item row="6" column="2" >
<spacer name="verticalSpacer" >
<property name="orientation" >
<enum>Qt::Vertical</enum>

View File

@ -83,14 +83,17 @@
<Management>
<description>Management</description>
<hidden>true</hidden>
</Management>
<SNMPManagement>
<description>Management</description>
<hidden>true</hidden>
</SNMPManagement>
<FWBDManagement>
<description>Management</description>
<hidden>true</hidden>
</FWBDManagement>
<IPService>