diff --git a/build_num b/build_num index 3d4720892..882ce90a0 100644 --- a/build_num +++ b/build_num @@ -1 +1 @@ -#define BUILD_NUM 968 +#define BUILD_NUM 970 diff --git a/doc/ChangeLog b/doc/ChangeLog index d0c10cff5..f6672538e 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,19 @@ 2009-05-27 vadim + * RCSFilePreview.cpp (RCSViewItem::operator<): implemented feature + req. #2796238 "3.0.4 - FEAT REQ: Sort order for RCSFilePreview". + RCS file preview dialog (the one that shows RCS revisions and RCS + log records) can display revisions in the tree or list view style, + controlled by radio-buttons. Style setting is saved in user + preferences and persists from session to session. In both cases + the view can be sorted by revision number or data. Sort column + choice is also saved in preferences. By default program sorts by + date and selects the latest revision. + + * ObjectManipulator.cpp (ObjectManipulator::actuallyPasteTo): + fixed bug (no #): the GUI did not allow to copy/paste an address + from one interface to another. This should be possible. + * PolicyCompiler_pf_writers.cpp (PrintRule::_printAddr): fixed bug (no #): policy compiler for pf crashed when dynamic interface was used in source or destination of a policy rule. diff --git a/src/gui/FWBSettings.cpp b/src/gui/FWBSettings.cpp index 2a6e20bab..fe1bf36f5 100644 --- a/src/gui/FWBSettings.cpp +++ b/src/gui/FWBSettings.cpp @@ -79,6 +79,9 @@ const char* objTooltips = SETTINGS_PATH_PREFIX "/UI/objTooltips"; const char* tooltipDelay = SETTINGS_PATH_PREFIX "/UI/tooltipDelay"; const char* emptyRCSLog = SETTINGS_PATH_PREFIX "/RCS/emptyLog"; +const char* rcsFilePreviewStyle = SETTINGS_PATH_PREFIX "/RCS/FilePreviewStyle"; +const char* rcsFilePreviewSortColumn = SETTINGS_PATH_PREFIX "/RCS/FilePreviewSortColumn"; + const char* dontSaveStdLib = SETTINGS_PATH_PREFIX "/DataFormat/dontSaveStdLib"; const char* WindowGeometrySetpath= SETTINGS_PATH_PREFIX "/Layout/"; const char* screenPositionSetpath= SETTINGS_PATH_PREFIX "/ScreenPos/"; @@ -119,7 +122,11 @@ void FWBSettings::init() ok = contains(appGUID); if (!ok) setValue(appGUID, QUuid::createUuid().toString() ); - + + // By default sort RCS File preview by date, which is column 1 + ok = contains(rcsFilePreviewSortColumn); + if (!ok) setRCSFilePreviewSortColumn(1); + ok = contains(infoStyleSetpath); if (!ok) setValue(infoStyleSetpath,2); @@ -313,7 +320,6 @@ void FWBSettings::setSaveFileDir( const QString &d ) setValue(sfdirSetpath,d); } - void FWBSettings::save() { if (mw->db()!=NULL) @@ -323,6 +329,26 @@ void FWBSettings::save() bool FWBSettings::getRCSLogState() { return value( emptyRCSLog ).toBool(); } void FWBSettings::setRCSLogState(bool f) { setValue( emptyRCSLog , f ); } +int FWBSettings::getRCSFilePreviewStyle() +{ + return value(rcsFilePreviewStyle).toInt(); +} + +void FWBSettings::setRCSFilePreviewStyle(int style) +{ + setValue(rcsFilePreviewStyle, style); +} + +int FWBSettings::getRCSFilePreviewSortColumn() +{ + return value(rcsFilePreviewSortColumn).toInt(); +} + +void FWBSettings::setRCSFilePreviewSortColumn(int col) +{ + setValue(rcsFilePreviewSortColumn, col); +} + bool FWBSettings::getAutoSave() { return value( autoSave ).toBool(); } void FWBSettings::setAutoSave(bool f) { setValue( autoSave, f); } diff --git a/src/gui/FWBSettings.h b/src/gui/FWBSettings.h index dd024eae9..675177751 100644 --- a/src/gui/FWBSettings.h +++ b/src/gui/FWBSettings.h @@ -105,6 +105,12 @@ class FWBSettings : public QSettings { bool getRCSLogState(); void setRCSLogState(bool f); + int getRCSFilePreviewStyle(); + void setRCSFilePreviewStyle(int style); + + int getRCSFilePreviewSortColumn(); + void setRCSFilePreviewSortColumn(int col); + bool getAutoSave(); void setAutoSave(bool f); diff --git a/src/gui/ObjectManipulator.cpp b/src/gui/ObjectManipulator.cpp index c87363e33..e830d42e9 100644 --- a/src/gui/ObjectManipulator.cpp +++ b/src/gui/ObjectManipulator.cpp @@ -1747,13 +1747,16 @@ FWObject* ObjectManipulator::actuallyPasteTo(FWObject *target, } if ( m_project->isSystem(ta) || - (Firewall::isA(ta) && RuleSet::cast(obj)!=NULL)) + (Firewall::isA(ta) && RuleSet::cast(obj)!=NULL) || + (Interface::isA(ta) && (IPv4::cast(obj) || IPv6::cast(obj))) + ) { /* add a copy of the object to system group , or * add ruleset object to a firewall. */ - if (fwbdebug) qDebug("Copy object %s (%d) to a system group, firewall or ruleset", - obj->getName().c_str(), obj->getId()); + if (fwbdebug) + qDebug("Copy object %s (%d) to a system group, a ruleset to a firewall or an address to an interface", + obj->getName().c_str(), obj->getId()); FWObject *nobj= m_project->db()->create(obj->getTypeName()); assert (nobj!=NULL); nobj->ref(); @@ -1775,7 +1778,7 @@ FWObject* ObjectManipulator::actuallyPasteTo(FWObject *target, /* check for duplicates. We just won't add an object if it is already there */ int cp_id = obj->getId(); list::iterator j; - for(j=grp->begin(); j!=grp->end(); ++j) + for (j=grp->begin(); j!=grp->end(); ++j) { FWObject *o1=*j; if(cp_id==o1->getId()) return o1; @@ -1787,6 +1790,7 @@ FWObject* ObjectManipulator::actuallyPasteTo(FWObject *target, grp->addRef(obj); } + } catch(FWException &ex) { diff --git a/src/gui/RCSFilePreview.cpp b/src/gui/RCSFilePreview.cpp index e3105d05e..86c42d9a4 100644 --- a/src/gui/RCSFilePreview.cpp +++ b/src/gui/RCSFilePreview.cpp @@ -28,9 +28,11 @@ #include "RCS.h" #include "RCSFilePreview.h" +#include "FWBSettings.h" #include "fwbuilder/libfwbuilder-config.h" #include "fwbuilder/FWException.h" +#include "fwbuilder/XMLTools.h" #include #include @@ -43,24 +45,18 @@ using namespace std; using namespace libfwbuilder; -int RCSViewItem::compare(QTreeWidgetItem *itm, int col, bool ) const +bool RCSViewItem::operator<(const QTreeWidgetItem &other) const { - QString rev1 = text(col); - QString rev2 = itm->text(col); + int col = treeWidget()->sortColumn(); - for(int i=1; ; i++) - { - QString v1 = rev1.section(".",i,i); - QString v2 = rev2.section(".",i,i); - if (v1=="" && v2=="") return 0; - if (v1==v2) continue; - if (v1=="" && v2!="") return -1; - if (v1!="" && v2=="") return 1; - if (v1.toInt()>v2.toInt()) return 1; - if (v1.toInt()getRCSFilePreviewStyle()==1) + m_widget->list_view->setChecked(true); + else + m_widget->tree_view->setChecked(true); + m_widget->RCSTreeView->setAllColumnsShowFocus( true ); - m_widget->RCSTreeView->setSelectionMode( - QAbstractItemView::SingleSelection ); + m_widget->RCSTreeView->setSelectionMode(QAbstractItemView::SingleSelection ); m_widget->RCSTreeView->setRootIsDecorated( FALSE ); + // m_widget->RCSTreeView->sortByColumn( 0, Qt::AscendingOrder ); if (fwbdebug) qDebug("RCSFilePreview: constructor done"); @@ -92,6 +93,7 @@ RCSFilePreview::~RCSFilePreview() { if (fwbdebug) qDebug("~RCSFilePreview() rcs=%p", rcs); // if (rcs!=NULL) delete rcs; + st->setRCSFilePreviewSortColumn(m_widget->RCSTreeView->sortColumn()); } void RCSFilePreview::openReadOnly() @@ -124,6 +126,11 @@ bool RCSFilePreview::showFileRLog( const QString &filename ) if (fwbdebug) qDebug("RCSFilePreview::showFileRLog filename=%s rcs=%p", filename.toLocal8Bit().constData(),rcs); + current_file = filename; + + m_widget->RCSTreeView->disconnect( + SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); + m_widget->RCSTreeView->clear(); if (rcs!=NULL) delete rcs; @@ -150,56 +157,120 @@ bool RCSFilePreview::showFileRLog( const QString &filename ) QList::iterator i; QList itemList; QList::iterator ili; - RCSViewItem* lastItem = NULL; + RCSViewItem* latest_revision_item = NULL; + RCSViewItem* latest_date_item = NULL; + string latest_revision = "1.0"; + QString latest_date = ""; for (i=rcs->revisions.begin(); i!=rcs->revisions.end(); ++i) { - rcsComments[(*i).rev]=(*i).log; + rcsComments[(*i).rev] = (*i).log; - if ((*i).rev.indexOf(QRegExp("^[0-9]+\\.[0-9]+$"))!=-1) + RCSViewItem *itm; + if (st->getRCSFilePreviewStyle()==1) { - RCSViewItem *itm = new RCSViewItem( rootItm ); - itm->setText( 0, (*i).rev ); - itm->setText( 1, (*i).date ); - itm->setText( 2, (*i).author ); - itm->setText( 3, QString(" ")+(*i).locked_by ); - + // List style + itm = addRevision(*i, rootItm); itemList.push_back(itm); - lastItem = itm; - } - - if ((*i).rev.indexOf(QRegExp("^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"))!=-1) + } else { - QString branch_root = (*i).rev.section(".",0,1); - for (ili=itemList.begin(); ili!=itemList.end(); ++ili) - if ((*ili)->text(0) == branch_root) + // tree style + if ((*i).rev.indexOf(QRegExp("^[0-9]+\\.[0-9]+$"))!=-1) + { + itm = addRevision(*i, rootItm); + itemList.push_back(itm); + } + + if ((*i).rev.indexOf(QRegExp("^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"))!=-1) + { + QString branch_root = (*i).rev.section(".",0,1); + for (ili=itemList.begin(); ili!=itemList.end(); ++ili) { - QTreeWidgetItem *br = *ili; - if (br!=NULL) + if ((*ili)->text(0) == branch_root) { - RCSViewItem *itm=new RCSViewItem(br); - itm->setText( 0, (*i).rev ); - itm->setText( 1, (*i).date ); - itm->setText( 2, (*i).author ); - itm->setText( 3, QString(" ")+(*i).locked_by ); + QTreeWidgetItem *br = *ili; + if (br!=NULL) itm = addRevision((*i), br); } } + } + } + + string itm_revision = (*i).rev.toStdString(); + + if (XMLTools::version_compare(itm_revision, latest_revision) > 0) + { + latest_revision = itm_revision; + latest_revision_item = itm; + } + + // This relies on the date string in the rcslog output + // being in sortable format. This is so for the "C" or "en_US" + // locale, but I am not sure about other locales. + if ((*i).date > latest_date) + { + latest_date = (*i).date; + latest_date_item = itm; } } - m_widget->RCSTreeView->scrollToItem( lastItem ); - m_widget->RCSTreeView->expandAll(); -// m_widget->RCSTreeView->sortByColumn(0, Qt::AscendingOrder); + + m_widget->RCSTreeView->sortByColumn(st->getRCSFilePreviewSortColumn(), + Qt::AscendingOrder); + + // connect signal before setting current item so that + // selectedRevision gets control and updates rcs log panel + connect( m_widget->RCSTreeView, + SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), + this, SLOT(selectedRevision(QTreeWidgetItem*))); + + RCSViewItem* show_item = NULL; + + if (m_widget->RCSTreeView->sortColumn()==0 && latest_revision_item) + show_item = latest_revision_item; + + if (m_widget->RCSTreeView->sortColumn()==1 && latest_date_item) + show_item = latest_date_item; + + if (show_item) + { + show_item->setSelected(true); + m_widget->RCSTreeView->expandItem(show_item->parent()); + m_widget->RCSTreeView->setCurrentItem(show_item); + m_widget->RCSTreeView->scrollToItem(show_item); + } + + // resize after parent of the current item was expanded m_widget->RCSTreeView->resizeColumnToContents ( 0 ); m_widget->RCSTreeView->resizeColumnToContents ( 1 ); - lastItem->setSelected( true ); - m_widget->RCSTreeView->setCurrentItem( lastItem ); return true; } +RCSViewItem* RCSFilePreview::addRevision(Revision &rev, + QTreeWidgetItem *parent_item) +{ + RCSViewItem *itm = new RCSViewItem(parent_item); + itm->setText(0, rev.rev); + itm->setText(1, rev.date); + itm->setText(2, rev.author); + itm->setText(3, QString(" ") + rev.locked_by); + return itm; +} + +void RCSFilePreview::switchToTreeView() +{ + st->setRCSFilePreviewStyle(0); // 0 for backward compatibility + if (!current_file.isEmpty()) showFileRLog(current_file); +} + +void RCSFilePreview::switchToListView() +{ + st->setRCSFilePreviewStyle(1); + if (!current_file.isEmpty()) showFileRLog(current_file); +} + RCS* RCSFilePreview::getSelectedRev() { @@ -209,6 +280,10 @@ RCS* RCSFilePreview::getSelectedRev() } - - - +void RCSFilePreview::closeEvent(QCloseEvent *event) +{ + if (fwbdebug) + qDebug("RCSFilePreview::closeEvent"); + st->setRCSFilePreviewSortColumn(m_widget->RCSTreeView->sortColumn()); + QDialog::closeEvent(event); +} diff --git a/src/gui/RCSFilePreview.h b/src/gui/RCSFilePreview.h index b84998dd0..663d58605 100644 --- a/src/gui/RCSFilePreview.h +++ b/src/gui/RCSFilePreview.h @@ -41,8 +41,8 @@ class RCSViewItem : public QTreeWidgetItem { RCSViewItem(QTreeWidget *parent) : QTreeWidgetItem(parent) {} RCSViewItem(QTreeWidgetItem *parent) : QTreeWidgetItem(parent) {} - virtual int compare(QTreeWidgetItem *i, int col, bool ascending) const; + virtual bool operator<(const QTreeWidgetItem &other) const; }; class RCSFilePreview : public QDialog @@ -54,18 +54,25 @@ class RCSFilePreview : public QDialog QString current_file; std::map rcsComments; bool RO; - + + RCSViewItem* addRevision(Revision &rev, QTreeWidgetItem *parent_item); + public: RCSFilePreview(QWidget *parent); ~RCSFilePreview(); RCS* getSelectedRev(); bool showFileRLog( const QString &filename ); + public slots: - virtual void openReadOnly(); - virtual void selectedRevision(QTreeWidgetItem *itm); - virtual void openFile(); + virtual void openReadOnly(); + virtual void selectedRevision(QTreeWidgetItem *itm); + virtual void openFile(); + virtual void switchToTreeView(); + virtual void switchToListView(); + virtual void closeEvent(QCloseEvent *event); + }; diff --git a/src/gui/rcsfilepreview_q.ui b/src/gui/rcsfilepreview_q.ui index 427607b78..f4e98bae3 100644 --- a/src/gui/rcsfilepreview_q.ui +++ b/src/gui/rcsfilepreview_q.ui @@ -30,8 +30,8 @@ true - - + + @@ -51,6 +51,9 @@ false + + true + true @@ -76,7 +79,46 @@ - + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + Tree View + + + + + + + List View + + + + + + + Qt::Horizontal + + + + 267 + 20 + + + + + + + + QFrame::HLine @@ -89,7 +131,7 @@ - + 0 @@ -140,7 +182,7 @@ - + @@ -150,7 +192,7 @@ QSizePolicy::Expanding - + 111 30 @@ -210,7 +252,6 @@ comment openButton - @@ -229,22 +270,6 @@ - - RCSTreeView - currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*) - RCSFilePreview_q - selectedRevision(QTreeWidgetItem*) - - - 20 - 20 - - - 20 - 20 - - - openButton clicked() @@ -261,5 +286,41 @@ + + tree_view + clicked() + RCSFilePreview_q + switchToTreeView() + + + 66 + 301 + + + 253 + 243 + + + + + list_view + clicked() + RCSFilePreview_q + switchToListView() + + + 160 + 301 + + + 253 + 243 + + + + + switchToTreeView() + switchToListView() + diff --git a/test/ipt/objects-for-regression-tests.fwb b/test/ipt/objects-for-regression-tests.fwb index 40650ca47..fe2eb5ff9 100644 --- a/test/ipt/objects-for-regression-tests.fwb +++ b/test/ipt/objects-for-regression-tests.fwb @@ -1,6 +1,6 @@ - + @@ -810,6 +810,7 @@ + @@ -1641,6 +1642,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -36064,7 +36091,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36227,7 +36254,47 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -36247,7 +36314,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36267,7 +36334,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36287,7 +36354,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36307,7 +36374,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36327,7 +36394,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36347,7 +36414,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36367,7 +36434,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36387,7 +36454,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36407,7 +36474,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36428,7 +36495,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36448,7 +36515,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36468,7 +36535,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36488,7 +36555,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36508,7 +36575,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36528,7 +36595,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36548,7 +36615,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36568,7 +36635,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36588,7 +36655,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36608,7 +36675,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36628,7 +36695,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36648,7 +36715,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - + @@ -36668,7 +36735,7 @@ echo '%FWBPROMPT%'; sh /tmp/%FWSCRIPT% - +