1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-21 10:47:16 +01:00

fixed #1660 "Crash when

cut-and-pasting firewall between libraries". GUI crashed if user
performed the following sequence: cut an object, switch to a
different object library, try to paste using keyboard shortcut
Ctrl-V while library object was selected in the tree.
This commit is contained in:
Vadim Kurland 2010-08-05 23:51:14 +00:00
parent 2695e28087
commit e7b0304560
11 changed files with 208 additions and 109 deletions

View File

@ -1 +1 @@
#define BUILD_NUM 3205
#define BUILD_NUM 3211

View File

@ -1,3 +1,11 @@
2010-08-05 Vadim Kurland <vadim@vk.crocodile.org>
* ProjectPanel_events.cpp (event): fixed #1660 "Crash when
cut-and-pasting firewall between libraries". GUI crashed if user
performed the following sequence: cut an object, switch to a
different object library, try to paste using keyboard shortcut
Ctrl-V while library object was selected in the tree.
2010-08-04 Vadim Kurland <vadim@vk.crocodile.org>
* IPTImporter.cpp (IPTImporter::finalize): fixed #1664 "Policy

View File

@ -484,7 +484,8 @@ void FWBTree::getStandardSlotForObject(const QString &objType,
* this method finds standard system folder for an object of a given
* type in a given library. This method implemented our standard tree
* structure (the one that is created in the method createNewLibrary)
*/FWObject* FWBTree::getStandardSlotForObject(FWObject* lib,const QString &objType)
*/
FWObject* FWBTree::getStandardSlotForObject(FWObject* lib,const QString &objType)
{
QString path = systemGroupPaths[objType];

View File

@ -539,8 +539,10 @@ void FWWindow::startupLoad()
stdlg->run();
}
prepareFileMenu();
updateGlobalToolbar();
QCoreApplication::postEvent(mw, new updateGUIStateEvent());
//prepareFileMenu();
//updateGlobalToolbar();
//prepareRulesMenu();
}
@ -573,8 +575,10 @@ void FWWindow::fileNew()
if (proj->fileNew())
{
showSub(proj.get());
prepareFileMenu();
updateGlobalToolbar();
QCoreApplication::postEvent(mw, new updateGUIStateEvent());
//prepareFileMenu();
//updateGlobalToolbar();
//prepareRulesMenu();
proj.release();
}
@ -650,9 +654,11 @@ void FWWindow::fileOpen()
updateOpenRecentMenu(file_name);
// reset actions, including Save() which should now
// be inactive
prepareFileMenu();
QCoreApplication::postEvent(mw, new updateGUIStateEvent());
//prepareFileMenu();
//prepareRulesMenu();
updateGlobalToolbar();
//updateGlobalToolbar();
QCoreApplication::postEvent(this, new updateSubWindowTitlesEvent());
} else
@ -726,9 +732,11 @@ void FWWindow::fileClose()
// reset actions, including Save() which should now
// be inactive
prepareFileMenu();
QCoreApplication::postEvent(mw, new updateGUIStateEvent());
//prepareFileMenu();
//prepareRulesMenu();
updateGlobalToolbar();
//updateGlobalToolbar();
}
if (fwbdebug) qDebug("subWindowList().size()=%d",
@ -1037,9 +1045,11 @@ void FWWindow::subWindowActivated(QMdiSubWindow *subwindow)
ProjectPanel *pp = dynamic_cast<ProjectPanel*>(subwindow->widget());
if (pp)
{
prepareFileMenu();
QCoreApplication::postEvent(mw, new updateGUIStateEvent());
//prepareFileMenu();
//prepareRulesMenu();
updateGlobalToolbar();
//updateGlobalToolbar();
pp->setActive();
if (isEditorVisible()) openEditor(pp->getSelectedObject());
@ -1125,80 +1135,87 @@ bool FWWindow::event(QEvent *event)
switch (event->type() - QEvent::User)
{
case OPEN_OBJECT_IN_EDITOR_EVENT:
case UPDATE_GUI_STATE_EVENT:
prepareFileMenu();
prepareEditMenu();
updateGlobalToolbar();
// do not return, let ProjectPanel process the same event as well
break;
case OPEN_OBJECT_IN_EDITOR_EVENT:
{
if (pp && obj)
{
if (pp && obj)
openEditor(obj);
// pp->editObject(obj);
pp->mdiWindow->update();
}
ev->accept();
return true;
}
case OPEN_OPT_OBJECT_IN_EDITOR_EVENT:
{
if (pp && obj)
{
openOptEditor(
obj,
dynamic_cast<openOptObjectInEditorEvent*>(event)->opt_code);
// pp->editObject(obj);
pp->mdiWindow->update();
}
ev->accept();
return true;
}
case UPDATE_SUBWINDOW_TITLES_EVENT:
{
QMap<QString, int> short_name_counters;
QMap<QMdiSubWindow*, QString> short_titles;
QMap<QMdiSubWindow*, QString> long_titles;
foreach(QMdiSubWindow* sw, m_mainWindow->m_space->subWindowList())
{
ProjectPanel * pp = dynamic_cast<ProjectPanel *>(sw->widget());
if (pp!=NULL)
{
openEditor(obj);
// pp->editObject(obj);
pp->mdiWindow->update();
// string returned by getPageTitle() may also
// include RCS revision number. Compare only
// file name, without the path and rev number
// to make sure we show long paths for two
// subwindows where file names are identical,
// regardless of the RCS revision number.
QString file_name = pp->getFileName(); // full path
QFileInfo fi(file_name);
QString short_name = fi.fileName();
int c = short_name_counters[short_name];
short_name_counters[short_name] = c + 1;
short_titles[sw] = pp->getPageTitle(false);
long_titles[sw] = pp->getPageTitle(true);
if (fwbdebug)
qDebug() << "Subwindow " << sw
<< "file_name " << file_name
<< "short_name " << short_name
<< "short_name_counter " << c
<< "short_title " << short_titles[sw]
<< "long_title " << long_titles[sw];
}
ev->accept();
return true;
}
case OPEN_OPT_OBJECT_IN_EDITOR_EVENT:
foreach(QMdiSubWindow* sw, m_mainWindow->m_space->subWindowList())
{
if (pp && obj)
{
openOptEditor(
obj,
dynamic_cast<openOptObjectInEditorEvent*>(event)->opt_code);
// pp->editObject(obj);
pp->mdiWindow->update();
}
ev->accept();
return true;
}
case UPDATE_SUBWINDOW_TITLES_EVENT:
{
QMap<QString, int> short_name_counters;
QMap<QMdiSubWindow*, QString> short_titles;
QMap<QMdiSubWindow*, QString> long_titles;
foreach(QMdiSubWindow* sw, m_mainWindow->m_space->subWindowList())
{
ProjectPanel * pp = dynamic_cast<ProjectPanel *>(sw->widget());
if (pp!=NULL)
{
// string returned by getPageTitle() may also
// include RCS revision number. Compare only
// file name, without the path and rev number
// to make sure we show long paths for two
// subwindows where file names are identical,
// regardless of the RCS revision number.
QString file_name = pp->getFileName(); // full path
QFileInfo fi(file_name);
QString short_name = fi.fileName();
int c = short_name_counters[short_name];
short_name_counters[short_name] = c + 1;
short_titles[sw] = pp->getPageTitle(false);
long_titles[sw] = pp->getPageTitle(true);
if (fwbdebug)
qDebug() << "Subwindow " << sw
<< "file_name " << file_name
<< "short_name " << short_name
<< "short_name_counter " << c
<< "short_title " << short_titles[sw]
<< "long_title " << long_titles[sw];
}
}
foreach(QMdiSubWindow* sw, m_mainWindow->m_space->subWindowList())
{
QString short_name = short_titles[sw];
if (short_name_counters[short_name] > 1)
sw->setWindowTitle(long_titles[sw]);
else
sw->setWindowTitle(short_titles[sw]);
}
ev->accept();
return true;
QString short_name = short_titles[sw];
if (short_name_counters[short_name] > 1)
sw->setWindowTitle(long_titles[sw]);
else
sw->setWindowTitle(short_titles[sw]);
}
ev->accept();
return true;
}
}
// dispatch event to all projectpanel windows

View File

@ -95,7 +95,9 @@ void FWWindow::fileSave()
if (activeProject())
{
activeProject()->fileSave();
prepareFileMenu();
QCoreApplication::postEvent(this, new updateGUIStateEvent());
//prepareFileMenu();
}
}
@ -104,7 +106,9 @@ void FWWindow::fileSaveAs()
if (activeProject())
{
activeProject()->fileSaveAs();
prepareFileMenu();
QCoreApplication::postEvent(this, new updateGUIStateEvent());
//prepareFileMenu();
}
}
@ -115,7 +119,9 @@ void FWWindow::fileCommit()
activeProject()->fileCommit();
// reset actions, including Save() which should now
// be inactive
prepareFileMenu();
QCoreApplication::postEvent(this, new updateGUIStateEvent());
//prepareFileMenu();
}
}
@ -128,9 +134,11 @@ void FWWindow::fileDiscard()
if (activeProject())
{
activeProject()->fileDiscard();
prepareFileMenu();
QCoreApplication::postEvent(this, new updateGUIStateEvent());
//prepareFileMenu();
//prepareRulesMenu();
updateGlobalToolbar();
//updateGlobalToolbar();
}
}
@ -139,7 +147,9 @@ void FWWindow::fileAddToRCS()
if (activeProject())
{
activeProject()->fileAddToRCS();
prepareFileMenu();
QCoreApplication::postEvent(this, new updateGUIStateEvent());
//prepareFileMenu();
}
}
@ -168,9 +178,11 @@ void FWWindow::fileImport()
if (activeProject())
{
activeProject()->fileImport();
prepareFileMenu();
QCoreApplication::postEvent(this, new updateGUIStateEvent());
//prepareFileMenu();
//prepareRulesMenu();
updateGlobalToolbar();
//updateGlobalToolbar();
}
}

View File

@ -518,13 +518,29 @@ void GroupObjectDialog::validate(bool *res)
void GroupObjectDialog::applyChanges()
{
if (fwbdebug) qDebug("GroupObjectDialog::applyChanges");
if (fwbdebug)
qDebug() << "GroupObjectDialog::applyChanges"
<< "checkpoint 1"
<< "root->isDirty()=" << obj->getRoot()->isDirty();
std::auto_ptr<FWCmdChange> cmd( new FWCmdChange(m_project, obj));
FWObject* new_state = cmd->getNewState();
string oldname = obj->getName();
new_state->setName( string(m_dialog->obj_name->text().toUtf8().constData()) );
string newname = string(m_dialog->obj_name->text().toUtf8().constData());
if (oldname != newname)
{
if (fwbdebug)
qDebug() << "oldname=" << oldname.c_str()
<< "newname=" << newname.c_str();
new_state->setName(newname);
}
if (fwbdebug)
qDebug() << "GroupObjectDialog::applyChanges"
<< "checkpoint 2"
<< "root->isDirty()=" << obj->getRoot()->isDirty();
new_state->setComment(
string(m_dialog->comment->toPlainText().toUtf8().constData()) );

View File

@ -827,6 +827,19 @@ void ObjectManipulator::getMenuState(bool haveMoveTargets,
{
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;
@ -834,8 +847,6 @@ void ObjectManipulator::getMenuState(bool haveMoveTargets,
delMenuItem = true;
newMenuItem = true;
inDeletedObjects = false;
FWObject *del_obj_library =
m_project->db()->findInIndex( FWObjectDatabase::DELETED_OBJECTS_ID);
@ -1000,6 +1011,11 @@ FWObject* ObjectManipulator::prepareForInsertion(FWObject *target, FWObject *obj
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))
{
@ -1275,6 +1291,8 @@ void ObjectManipulator::changeFirstNotSystemLib()
void ObjectManipulator::libChanged(int ln)
{
if (fwbdebug) qDebug() << "ObjectManipulator::libChanged ln=" << ln;
previous_lib_index = ln;
QTreeWidget *lv = idxToTrees[ln];
@ -1289,29 +1307,33 @@ void ObjectManipulator::libChanged(int ln)
else
assert(FALSE);
}
//currentObj = otvi->getFWObject();
showObjectInTree( otvi );
// Experiment: switching libraries does not open new lib in the editor
// switching libraries does not open new lib in the editor
// if (mw->isEditorVisible()) mw->openEditor(getSelectedObject());
updateCreateObjectMenu( idxToLibs[ln] );
//updateCreateObjectMenu( idxToLibs[ln] );
QCoreApplication::postEvent(mw, new updateGUIStateEvent());
return;
}
void ObjectManipulator::updateCreateObjectMenu(FWObject* lib)
{
bool f =
bool f = lib == NULL ||
lib->getId()==FWObjectDatabase::TEMPLATE_LIB_ID ||
lib->getId()==FWObjectDatabase::DELETED_OBJECTS_ID ||
lib->isReadOnly();
emit libraryAccessChanged(!f);
m_objectManipulator->newButton->setEnabled( !f );
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( !f );
noa->setEnabled(new_object_op_possible);
}
FWObject* ObjectManipulator::getCurrentLib()
FWObject* ObjectManipulator::getCurrentLib()
{
int idx = m_objectManipulator->libs->currentIndex();
if (idx == -1 ) return NULL;

View File

@ -126,7 +126,6 @@ class ObjectManipulator : public QWidget
int getIdxForLib(libfwbuilder::FWObject*);
void removeLib(int idx);
void updateCreateObjectMenu(libfwbuilder::FWObject* lib);
void makeNameUnique(libfwbuilder::FWObject* p,libfwbuilder::FWObject* obj);
@ -325,8 +324,10 @@ public:
void autoRenameChildren(libfwbuilder::FWObject *obj,
const QString &oldName);
void updateObjectInTree(libfwbuilder::FWObject *obj, bool subtree=false);
void updateObjectInTree(libfwbuilder::FWObject *obj, bool subtree=false);
void updateCreateObjectMenu(libfwbuilder::FWObject* lib);
ObjectTreeView* getCurrentObjectTree();
libfwbuilder::FWObject* getSelectedObject();

View File

@ -75,6 +75,13 @@ bool ProjectPanel::event(QEvent *event)
<< "object:"
<< ((obj!=NULL) ? QString::fromUtf8(obj->getName().c_str()) : "");
if (event_code == UPDATE_GUI_STATE_EVENT && mdiWindow != NULL)
{
m_panel->om->updateCreateObjectMenu(getCurrentLib());
ev->accept();
return true;
}
if ((rcs && rcs->getFileName() == data_file) ||
(!rcs && data_file.isEmpty()))
{
@ -115,10 +122,6 @@ bool ProjectPanel::event(QEvent *event)
// This event does not trigger any updates in the UI,
// this purely data structure update event.
mw->prepareFileMenu();
mw->prepareEditMenu();
mw->updateGlobalToolbar();
FWObject *p = obj;
while (p && Firewall::cast(p)==NULL) p = p->getParent();
Firewall *f = Firewall::cast(p);
@ -129,10 +132,12 @@ bool ProjectPanel::event(QEvent *event)
{
f->updateLastModifiedTimestamp();
QCoreApplication::postEvent(
mw, new updateObjectInTreeEvent(data_file,
f->getId()));
mw, new updateObjectInTreeEvent(data_file, f->getId()));
}
registerModifiedObject(obj);
QCoreApplication::postEvent(mw, new updateGUIStateEvent());
ev->accept();
return true;
}
@ -405,6 +410,7 @@ bool ProjectPanel::event(QEvent *event)
}
ev->accept();
return true;
}
}
return false;

View File

@ -1436,7 +1436,9 @@ void ProjectPanel::save()
db()->setDirty(false);
// and reset actions, including Save() which should now
// be inactive
mw->prepareFileMenu();
QCoreApplication::postEvent(mw, new updateGUIStateEvent());
//mw->prepareFileMenu();
} else
{
QApplication::setOverrideCursor(QCursor( Qt::WaitCursor));

View File

@ -65,7 +65,8 @@ enum EVENT_CODES {
CLOSE_OBJECT_EVENT ,
OBJECT_NAME_CHANGED_EVENT,
OPEN_LIBRARY_FOR_OBJECT_EVENT,
UPDATE_SUBWINDOW_TITLES_EVENT
UPDATE_SUBWINDOW_TITLES_EVENT,
UPDATE_GUI_STATE_EVENT
};
@ -358,6 +359,19 @@ public:
{}
};
/*
* This event is processed by FWWindow class and updates all menus and
* toolbar buttins
*/
class updateGUIStateEvent : public fwbUpdateEvent {
public:
updateGUIStateEvent() :
fwbUpdateEvent("", -1,
QEvent::Type(QEvent::User + UPDATE_GUI_STATE_EVENT),
"updateGUIStateEvent")
{}
};