From b1e4782a957d4dc96b9f2c5c25f892d0e8e9c671 Mon Sep 17 00:00:00 2001 From: caremoli Date: Wed, 7 Jul 2010 16:21:58 +0000 Subject: [PATCH] CCAR: various optimisations in object browser and synchronisation with V5_1_main branch --- src/Qtx/Makefile.am | 3 + src/Qtx/QtxPagePrefMgr.cxx | 107 ++++++++ src/Qtx/QtxPagePrefMgr.h | 30 +++ src/Qtx/QtxResourceMgr.cxx | 17 +- src/Qtx/QtxResourceMgr.h | 1 + src/Qtx/QtxShortcutEdit.cxx | 331 +++++++++++++++++++++++++ src/Qtx/QtxShortcutEdit.h | 84 +++++++ src/SOCC/SOCC_ViewModel.cxx | 5 +- src/SUIT/SUIT_DataObject.cxx | 20 +- src/SUIT/SUIT_DataObject.h | 1 + src/SUIT/SUIT_PreferenceMgr.cxx | 7 + src/SUIT/SUIT_PreferenceMgr.h | 2 +- src/SUIT/SUIT_TreeModel.cxx | 141 ++++++++--- src/SUIT/SUIT_TreeModel.h | 2 + src/SalomeApp/SalomeApp_DataObject.cxx | 22 +- src/SalomeApp/SalomeApp_DataObject.h | 2 + src/SalomeApp/SalomeApp_Study.cxx | 75 +++--- 17 files changed, 751 insertions(+), 99 deletions(-) create mode 100755 src/Qtx/QtxShortcutEdit.cxx create mode 100755 src/Qtx/QtxShortcutEdit.h diff --git a/src/Qtx/Makefile.am b/src/Qtx/Makefile.am index 633d33df9..771008a03 100755 --- a/src/Qtx/Makefile.am +++ b/src/Qtx/Makefile.am @@ -67,6 +67,7 @@ salomeinclude_HEADERS = \ QtxResourceMgr.h \ QtxRubberBand.h \ QtxSearchTool.h \ + QtxShortcutEdit.h \ QtxSplash.h \ QtxToolBar.h \ QtxToolTip.h \ @@ -123,6 +124,7 @@ dist_libqtx_la_SOURCES = \ QtxResourceMgr.cxx \ QtxRubberBand.cxx \ QtxSearchTool.cxx \ + QtxShortcutEdit.cxx \ QtxSplash.cxx \ QtxToolBar.cxx \ QtxToolTip.cxx \ @@ -171,6 +173,7 @@ MOC_FILES = \ QtxPopupMgr_moc.cxx \ QtxRubberBand_moc.cxx \ QtxSearchTool_moc.cxx \ + QtxShortcutEdit_moc.cxx \ QtxSplash_moc.cxx \ QtxToolBar_moc.cxx \ QtxToolTip_moc.cxx \ diff --git a/src/Qtx/QtxPagePrefMgr.cxx b/src/Qtx/QtxPagePrefMgr.cxx index 98940ab20..28a9db0d8 100644 --- a/src/Qtx/QtxPagePrefMgr.cxx +++ b/src/Qtx/QtxPagePrefMgr.cxx @@ -29,6 +29,8 @@ #include "QtxIntSpinBox.h" #include "QtxColorButton.h" #include "QtxDoubleSpinBox.h" +#include "QtxShortcutEdit.h" +#include "QtxResourceMgr.h" #include #include @@ -4190,3 +4192,108 @@ void QtxPagePrefDateTimeItem::updateDateTime() myDateTime->setDisplayFormat( dispFmt ); } + +/*! + \brief Constructor. + \param title preference item title + \param parent parent preference item + \param sect resource file section associated with the preference item + \param param resource file parameter associated with the preference item +*/ +QtxPagePrefShortcutBtnsItem::QtxPagePrefShortcutBtnsItem( const QString& title, QtxPreferenceItem* parent, const QString& sect, + const QString& param ): QtxPageNamedPrefItem( title, parent, sect, param ) +{ + setControl( myShortcut = new QtxShortcutEdit() ); +} + +/*! + \brief Destructor. +*/ +QtxPagePrefShortcutBtnsItem::~QtxPagePrefShortcutBtnsItem() +{ +} + +/*! + \brief Store preference item to the resource manager. + \sa retrieve() +*/ +void QtxPagePrefShortcutBtnsItem::store() +{ + setString( myShortcut->shortcut().toString() ); +} + +/*! + \brief Retrieve preference item from the resource manager. + \sa store() +*/ +void QtxPagePrefShortcutBtnsItem::retrieve() +{ + myShortcut->setShortcut( QKeySequence::fromString( getString() ) ); +} + +/*! + \brief Constructor. + + Creates preference item for editing of key bindings + + \param title preference item title + \param parent parent preference item + \param sect resource file section associated with the preference item + \param param resource file parameter associated with the preference item +*/ +QtxPagePrefShortcutTreeItem::QtxPagePrefShortcutTreeItem( const QString& title, QtxPreferenceItem* parent, const QString& sect, + const QString& param ): QtxPageNamedPrefItem( title, parent, sect, "" ) +{ + mySection = sect; + myShortcutTree = new QtxShortcutTree(); + setControl( myShortcutTree ); +} + +/*! + \brief Destructor. +*/ +QtxPagePrefShortcutTreeItem::~QtxPagePrefShortcutTreeItem() +{ +} + +/*! + \brief Retrieve preference item from the resource manager. + \sa store() +*/ +void QtxPagePrefShortcutTreeItem::retrieve() +{ + QtxResourceMgr* resMgr = resourceMgr(); + if ( resMgr ){ + QStringList secLst = resMgr->subSections( mySection, false ); + ShortcutMap aMap; QStringList paramLst; + for( int i = 0; i < secLst.size(); i++ ) { + paramLst = resMgr->parameters( QStringList() << mySection << secLst.at( i ) ); + for( int j = 0; j < paramLst.size(); j++ ) + resMgr->value( mySection + resMgr->sectionsToken() + secLst.at( i ), paramLst.at( j ),aMap[ paramLst.at( j ) ], false ); + myShortcutTree->setBindings( secLst.at( i ), aMap ); + aMap.clear(); + } + } +} + +/*! + \brief Store preference item to the resource manager. + \sa retrieve() +*/ +void QtxPagePrefShortcutTreeItem::store() +{ + QStringList lst = myShortcutTree->sections(); + QString aSection; + QtxResourceMgr* resMgr = resourceMgr(); + + if ( resMgr ) { + for( int i = 0; i < lst.size(); i++ ) { + ShortcutMap* aMap( myShortcutTree->bindings( lst.at( i ) ) ); + aSection = mySection + resMgr->sectionsToken() + lst.at( i ); + for( ShortcutMap::const_iterator it = aMap->constBegin(); it != aMap->constEnd(); ++it ) + resMgr->setValue( aSection, it.key(), it.value() ); + } + } +} + + diff --git a/src/Qtx/QtxPagePrefMgr.h b/src/Qtx/QtxPagePrefMgr.h index 5501fdf23..d824a3f33 100644 --- a/src/Qtx/QtxPagePrefMgr.h +++ b/src/Qtx/QtxPagePrefMgr.h @@ -38,6 +38,8 @@ class QtxFontEdit; class QtxGroupBox; class QtxComboBox; class QtxColorButton; +class QtxShortcutEdit; +class QtxShortcutTree; class QToolBox; class QLineEdit; @@ -50,6 +52,7 @@ class QFileDialog; class QDateTimeEdit; class QStackedWidget; class QSlider; +class QTreeWidget; class QTX_EXPORT QtxPagePrefMgr : public QFrame, public QtxPreferenceMgr { @@ -704,4 +707,31 @@ private: QDateTimeEdit* myDateTime; }; +class QTX_EXPORT QtxPagePrefShortcutBtnsItem : public QtxPageNamedPrefItem +{ +public: + QtxPagePrefShortcutBtnsItem( const QString&, QtxPreferenceItem* = 0, + const QString& = QString(), const QString& = QString() ); + virtual ~QtxPagePrefShortcutBtnsItem(); + virtual void store(); + virtual void retrieve(); + +private: + QtxShortcutEdit* myShortcut; +}; + +class QTX_EXPORT QtxPagePrefShortcutTreeItem : public QtxPageNamedPrefItem +{ +public: + QtxPagePrefShortcutTreeItem( const QString&, QtxPreferenceItem* = 0, + const QString& = QString(), const QString& = QString() ); + virtual ~QtxPagePrefShortcutTreeItem(); + virtual void store(); + virtual void retrieve(); + +private: + QtxShortcutTree* myShortcutTree; + QString mySection; +}; + #endif diff --git a/src/Qtx/QtxResourceMgr.cxx b/src/Qtx/QtxResourceMgr.cxx index cc2189b11..0afcf7799 100644 --- a/src/Qtx/QtxResourceMgr.cxx +++ b/src/Qtx/QtxResourceMgr.cxx @@ -2140,7 +2140,7 @@ QStringList QtxResourceMgr::subSections(const QString& section, const bool full) QStringList names = sections( QStringList() << section ); QMutableListIterator it( names ); while ( it.hasNext() ) { - QString name = it.next().mid( section.size() ).trimmed(); + QString name = it.next().mid( section.size() + 1 ).trimmed(); if ( name.isEmpty() ) { it.remove(); continue; @@ -2189,6 +2189,21 @@ QStringList QtxResourceMgr::parameters( const QString& sec ) const return pmap.keys(); } +/*! + \brief Get all parameters name in specified + list of sub-sections names. + + Sub-sections are separated inside the section name by the sections + separator token, for example "splash:color:label". + + \param names parent sub-sections names + \return list of settings names +*/ +QStringList QtxResourceMgr::parameters( const QStringList& names ) const +{ + return parameters( names.join( sectionsToken() ) ); +} + /*! \brief Get absolute path to the file which name is defined by the parameter. diff --git a/src/Qtx/QtxResourceMgr.h b/src/Qtx/QtxResourceMgr.h index a15205bc2..9b5356369 100644 --- a/src/Qtx/QtxResourceMgr.h +++ b/src/Qtx/QtxResourceMgr.h @@ -166,6 +166,7 @@ public: QStringList sections(const QStringList&) const; QStringList subSections(const QString&, const bool = true) const; QStringList parameters( const QString& ) const; + QStringList parameters( const QStringList& ) const; void refresh(); diff --git a/src/Qtx/QtxShortcutEdit.cxx b/src/Qtx/QtxShortcutEdit.cxx new file mode 100755 index 000000000..c5aa6eaa7 --- /dev/null +++ b/src/Qtx/QtxShortcutEdit.cxx @@ -0,0 +1,331 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "QtxShortcutEdit.h" + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define COLUMN_SIZE 500 + +static const char* delete_icon[] = { +"16 16 3 1", +"` c #810000", +" c none", +"# c #ffffff", +" ", +" ", +" ``# ``# ", +" ````# ``# ", +" ````# ``# ", +" ```# `# ", +" `````# ", +" ```# ", +" `````# ", +" ```# ``# ", +" ```# ``# ", +" ```# `# ", +" ```# `# ", +" `# `# ", +" ", +" " +}; + +/*! + \brief Constructor + \param parent parent widget +*/ +QtxShortcutEdit::QtxShortcutEdit( QWidget* parent ) +: QFrame( parent ) +{ + initialize(); + myShortcut->installEventFilter(this); +} + +/*! + \brief Destructor +*/ +QtxShortcutEdit::~QtxShortcutEdit() +{ +} + +/*! + \brief Sets custom shortcut + \param seq a key sequence describes a combination of keys + \sa shortcut() +*/ +void QtxShortcutEdit::setShortcut( const QKeySequence& seq ) +{ + QString txt = seq.toString(); + myPrevShortcutText = txt; + myShortcut->setText( txt ); +} + +/*! + \brief Gets custom shortcut + \return a key sequence describes a combination of keys + \sa setShortcut() +*/ +QKeySequence QtxShortcutEdit::shortcut() +{ + return QKeySequence::fromString( myShortcut->text() ); +} + +/*! + \brief Gets the key sequence from keys that were pressed + \param e a key event + \return a string representation of the key sequence +*/ +QString QtxShortcutEdit::parseEvent( QKeyEvent* e ) +{ + bool isShiftPressed = e->modifiers() & Qt::ShiftModifier; + bool isControlPressed = e->modifiers() & Qt::ControlModifier; + bool isAltPressed = e->modifiers() & Qt::AltModifier; + bool isMetaPressed = e->modifiers() & Qt::MetaModifier; + bool isModifiersPressed = isShiftPressed || isControlPressed || isAltPressed || isMetaPressed; + int result=0; + if( isControlPressed ) + result += Qt::CTRL; + if( isAltPressed ) + result += Qt::ALT; + if( isShiftPressed ) + result += Qt::SHIFT; + if( isMetaPressed ) + result += Qt::META; + + int aKey = e->key(); + if ( ( isValidKey( aKey ) && isModifiersPressed ) || ( ( aKey >= Qt::Key_F1 ) && ( aKey <= Qt::Key_F12 ) ) ) + result += aKey; + + return QKeySequence( result ).toString(); +} + +/*! + \brief Check if the key event contains a 'valid' key + \param aKey the code of the key + \return \c true if the key is 'valid' +*/ + +bool QtxShortcutEdit::isValidKey( int aKey ) +{ + if ( aKey == Qt::Key_Underscore || aKey == Qt::Key_Escape || + ( aKey >= Qt::Key_Backspace && aKey <= Qt::Key_Delete ) || + ( aKey >= Qt::Key_Home && aKey <= Qt::Key_PageDown ) || + ( aKey >= Qt::Key_F1 && aKey <= Qt::Key_F12 ) || + ( aKey >= Qt::Key_Space && aKey <= Qt::Key_Asterisk ) || + ( aKey >= Qt::Key_Comma && aKey <= Qt::Key_Question ) || + ( aKey >= Qt::Key_A && aKey <= Qt::Key_AsciiTilde ) ) + return true; + return false; +} + +/*! + \brief Called when "Clear" button is clicked. +*/ +void QtxShortcutEdit::onCliked() +{ + myShortcut->setText( "" ); +} + +/*! + \brief Called when myShortcut loses focus. +*/ +void QtxShortcutEdit::onEditingFinished() +{ + if ( myShortcut->text().endsWith("+") ) + myShortcut->setText( myPrevShortcutText ); +} + +/*! + \brief Custom event filter. + \param obj event receiver object + \param event event + \return \c true if further event processing should be stopped +*/ +bool QtxShortcutEdit::eventFilter(QObject* obj, QEvent* event) +{ + if ( obj == myShortcut ) { + if (event->type() == QEvent::KeyPress ) { + QKeyEvent* keyEvent = static_cast(event); + QString text = parseEvent( keyEvent ); + if ( keyEvent->key() == Qt::Key_Delete || keyEvent->key() == Qt::Key_Backspace ) + onCliked(); + if ( text != "" ) + myShortcut->setText( text ); + return true; + } + if ( event->type() == QEvent::KeyRelease ) { + if ( myShortcut->text().endsWith("+") ) + myShortcut->setText( myPrevShortcutText ); + else myPrevShortcutText = myShortcut->text(); + + return true; + } + } + return false; +} + +/* + \brief Perform internal intialization. +*/ +void QtxShortcutEdit::initialize() +{ + myPrevShortcutText = QString(); + + QHBoxLayout* base = new QHBoxLayout( this ); + base->setMargin( 0 ); + base->setSpacing( 5 ); + + base->addWidget( myShortcut = new QLineEdit( this ) ); + + QToolButton* deleteBtn = new QToolButton(); + deleteBtn->setIcon( QPixmap( delete_icon ) ); + base->addWidget( deleteBtn ); + + myShortcut->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed ); + deleteBtn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); + + connect( deleteBtn, SIGNAL( clicked() ), this, SLOT( onCliked() ) ); + connect( myShortcut, SIGNAL( editingFinished() ), this, SLOT( onEditingFinished() ) ); +} + +/*! + \brief Constructor + \param parent parent widget +*/ +QtxShortcutTree::QtxShortcutTree( QWidget * parent ) : QTreeWidget( parent ) +{ + setColumnCount( 2 ); + setSelectionMode( QAbstractItemView::SingleSelection ); + setColumnWidth ( 0, COLUMN_SIZE); + setSortingEnabled(false); + headerItem()->setHidden ( true ); + + this->installEventFilter(this); + connect( this, SIGNAL( currentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem* ) ), this, SLOT( onCurrentItemChanged ( QTreeWidgetItem*, QTreeWidgetItem* ) ) ); + +} + +/*! + \brief Destructor +*/ +QtxShortcutTree::~QtxShortcutTree(){} + +/*! + \brief Custom event filter. + \param obj event receiver object + \param event event + \return \c true if further event processing should be stopped +*/ +bool QtxShortcutTree::eventFilter(QObject* obj, QEvent* event) +{ + if ( currentItem() && currentItem()->isSelected() ) { + + if (event->type() == QEvent::KeyPress ) { + QKeyEvent* keyEvent = static_cast(event); + QString text = QtxShortcutEdit::parseEvent( keyEvent ); + if ( keyEvent->key() == Qt::Key_Delete || keyEvent->key() == Qt::Key_Backspace ) + currentItem()->setText( 1, "" ); + if ( text != "" ) { + currentItem()->setText( 1, text ); + } + return true; + } + if ( event->type() == QEvent::KeyRelease ) { + if ( currentItem()->text( 1 ).endsWith( "+" ) ) + currentItem()->setText( 1, myPrevBindings[ currentItem()->parent()->text( 0 ) ][ currentItem()->text( 0 ) ] ); + else myPrevBindings[ currentItem()->parent()->text( 0 ) ][ currentItem()->text( 0 ) ] = currentItem()->text( 1 ); + + return true; + } + } + return false; +} + +/*! + \brief Called when the current item changes. + \param cur the current item + \param prev the previous current item +*/ +void QtxShortcutTree::onCurrentItemChanged( QTreeWidgetItem* cur, QTreeWidgetItem* prev ) +{ + if ( prev && prev->text( 1 ).endsWith( "+" ) ) + prev->setText( 1, myPrevBindings[ prev->parent()->text( 0 ) ][ prev->text( 0 ) ] ); +} + + +/*! + \brief Set key bindings to the tree + \param title the name of top-level item + \param theShortcutMap map of key bindings +*/ +void QtxShortcutTree::setBindings( const QString& title, const ShortcutMap& theShortcutMap ) +{ + QTreeWidgetItem* item= new QTreeWidgetItem(); + if ( findItems( title, Qt::MatchFixedString ).isEmpty() ) { + item->setText( 0, title ); + addTopLevelItem( item ); + item->setFlags( Qt::ItemIsEnabled ); + } else { + item = findItems( title, Qt::MatchFixedString ).first(); + item->takeChildren(); + } + for( ShortcutMap::const_iterator it = theShortcutMap.constBegin(); it != theShortcutMap.constEnd(); ++it ) + item->addChild( new QTreeWidgetItem( QStringList() << it.key() << it.value() ) ); + myPrevBindings.insert( title, theShortcutMap); +} + +/*! + \brief Get all sections names. + \return list of section names +*/ +QStringList QtxShortcutTree::sections() const +{ + QStringList lst; + for( int i = 0; i < topLevelItemCount(); i++ ) + lst << topLevelItem( i )->text( 0 ); + return lst; +} + +ShortcutMap* QtxShortcutTree::bindings( const QString& sec ) const +{ + ShortcutMap* aMap = new ShortcutMap(); + QTreeWidgetItem* item = findItems( sec, Qt::MatchFixedString ).first(); + QList< QTreeWidgetItem* > childLst = item->takeChildren(); + + for( int i = 0; i < childLst.size(); i++ ) + aMap->insert( childLst.at(i)->text( 0 ), childLst.at(i)->text(1) ); + + return aMap; +} + +void QtxShortcutTree::focusOutEvent ( QFocusEvent* event ) +{ + QWidget::focusOutEvent( event ); + if ( currentItem()->isSelected() ) + currentItem()->setText( 1, myPrevBindings[ currentItem()->parent()->text( 0 ) ][ currentItem()->text( 0 ) ] ); +} diff --git a/src/Qtx/QtxShortcutEdit.h b/src/Qtx/QtxShortcutEdit.h new file mode 100755 index 000000000..782402288 --- /dev/null +++ b/src/Qtx/QtxShortcutEdit.h @@ -0,0 +1,84 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef QTXSHORTCUTEDIT_H +#define QTXSHORTCUTEDIT_H + +#include "Qtx.h" + +#include +#include + +class QLineEdit; +class QPushButton; +class QTreeWidgetItem; + +typedef QMap< QString, QString > ShortcutMap; + +class QTX_EXPORT QtxShortcutEdit : public QFrame +{ + Q_OBJECT + +public: + QtxShortcutEdit( QWidget* = 0 ); + virtual ~QtxShortcutEdit(); + void setShortcut( const QKeySequence& ); + QKeySequence shortcut(); + static QString parseEvent( QKeyEvent* ); + static bool isValidKey( int ); + + +private slots: + void onCliked(); + void onEditingFinished(); + +protected: + virtual bool eventFilter( QObject*, QEvent* ); + +private: + void initialize(); + +private: + QLineEdit* myShortcut; + QString myPrevShortcutText; +}; + +class QTX_EXPORT QtxShortcutTree : public QTreeWidget +{ + Q_OBJECT + +public: + QtxShortcutTree( QWidget * parent = 0 ); + virtual ~QtxShortcutTree(); + void setBindings( const QString&, const ShortcutMap& ); + ShortcutMap* bindings( const QString& ) const; + QStringList sections() const; + +protected: + virtual bool eventFilter( QObject*, QEvent* ); + virtual void focusOutEvent( QFocusEvent* ); + +private slots: + void onCurrentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* ); + +private: + QMap< QString, ShortcutMap > myPrevBindings; +}; + +#endif // QTXSHORTCUTEDIT_H diff --git a/src/SOCC/SOCC_ViewModel.cxx b/src/SOCC/SOCC_ViewModel.cxx index aa6daf569..d7405c67f 100755 --- a/src/SOCC/SOCC_ViewModel.cxx +++ b/src/SOCC/SOCC_ViewModel.cxx @@ -453,9 +453,9 @@ std::cerr << "ais found in collector" << std::endl; aTrh->SetSize( aTrh == getTrihedron() ? aNewSize : 0.5 * aNewSize ); } - START_TIMING; + //START_TIMING; ic->Display( anAIS, false ); - END_TIMING(100); + //END_TIMING(100); // Set visibility flag // Temporarily commented to avoid awful dependecy on SALOMEDS @@ -484,7 +484,6 @@ std::cerr << "ais found in collector" << std::endl; */ void SOCC_Viewer::Erase( const SALOME_OCCPrs* prs, const bool forced ) { - //std::cerr << "SOCC_Viewer::Erase " << forced << std::endl; // try do downcast object const SOCC_Prs* anOCCPrs = dynamic_cast( prs ); if ( !anOCCPrs || anOCCPrs->IsNull() ) diff --git a/src/SUIT/SUIT_DataObject.cxx b/src/SUIT/SUIT_DataObject.cxx index db8e980c5..0474e12ea 100755 --- a/src/SUIT/SUIT_DataObject.cxx +++ b/src/SUIT/SUIT_DataObject.cxx @@ -283,18 +283,20 @@ void SUIT_DataObject::appendChild( SUIT_DataObject* obj ) */ void SUIT_DataObject::insertChild( SUIT_DataObject* obj, int position ) { - if ( !obj || myChildren.contains( obj ) ) + //std::cerr << "SUIT_DataObject::insertChild " << obj << ":" << position << std::endl; + //if ( !obj || myChildren.contains( obj ) ) + if ( !obj ) return; int pos = position < 0 ? myChildren.count() : position; myChildren.insert( qMin( pos, (int)myChildren.count() ), obj ); - obj->setParent( this ); - /* + obj->assignParent( this ); + if(pos == 0) signal()->emitInserted( obj, this ,0); else signal()->emitInserted( obj, this ,myChildren.at(pos-1)); - */ + } /*! @@ -304,7 +306,6 @@ void SUIT_DataObject::insertChild( SUIT_DataObject* obj, int position ) */ void SUIT_DataObject::removeChild( SUIT_DataObject* obj, const bool del ) { - //std::cerr << "removeChild " << del << std::endl; if ( !obj ) return; @@ -391,6 +392,13 @@ void SUIT_DataObject::setParent( SUIT_DataObject* p ) parent()->appendChild( this ); } +void SUIT_DataObject::assignParent( SUIT_DataObject* p ) +{ + if ( p == myParent ) + return; + myParent = p; +} + /*! \brief Get data object name. @@ -900,7 +908,7 @@ void SUIT_DataObject::updateItem() { if(modified())return; setModified(true); - signal()->emitUpdated(this); + //signal()->emitUpdated(this); } /*! diff --git a/src/SUIT/SUIT_DataObject.h b/src/SUIT/SUIT_DataObject.h index 263692542..8ef9c339c 100755 --- a/src/SUIT/SUIT_DataObject.h +++ b/src/SUIT/SUIT_DataObject.h @@ -95,6 +95,7 @@ public: virtual SUIT_DataObject* parent() const; virtual void setParent( SUIT_DataObject* ); + virtual void assignParent( SUIT_DataObject* ); virtual QString name() const; virtual QString text( const int = NameId ) const; diff --git a/src/SUIT/SUIT_PreferenceMgr.cxx b/src/SUIT/SUIT_PreferenceMgr.cxx index 3296f02b0..b3fca9844 100644 --- a/src/SUIT/SUIT_PreferenceMgr.cxx +++ b/src/SUIT/SUIT_PreferenceMgr.cxx @@ -151,6 +151,13 @@ int SUIT_PreferenceMgr::addItem( const QString& title, const int pId, case DirList: item = new QtxPagePrefPathListItem( Qtx::PT_Directory, title, parent, sect, param ); break; + case Shortcut: + item = new QtxPagePrefShortcutBtnsItem( title, parent, sect, param ); + break; + case ShortcutTree: + item = new QtxPagePrefShortcutTreeItem( title, parent, sect, param ); + break; + } return item ? item->id() : -1; diff --git a/src/SUIT/SUIT_PreferenceMgr.h b/src/SUIT/SUIT_PreferenceMgr.h index 37549ae93..eb8edb5e9 100644 --- a/src/SUIT/SUIT_PreferenceMgr.h +++ b/src/SUIT/SUIT_PreferenceMgr.h @@ -37,7 +37,7 @@ class SUIT_EXPORT SUIT_PreferenceMgr : public QtxPagePrefMgr public: typedef enum { Auto, Space, Bool, Color, String, Selector, DblSpin, IntSpin, Double, Integer, - GroupBox, Tab, Frame, Font, DirList, File, Slider } PrefItemType; + GroupBox, Tab, Frame, Font, DirList, File, Slider, Shortcut, ShortcutTree } PrefItemType; public: SUIT_PreferenceMgr( QtxResourceMgr*, QWidget* = 0 ); diff --git a/src/SUIT/SUIT_TreeModel.cxx b/src/SUIT/SUIT_TreeModel.cxx index 8291e6afa..2295972f0 100755 --- a/src/SUIT/SUIT_TreeModel.cxx +++ b/src/SUIT/SUIT_TreeModel.cxx @@ -29,11 +29,10 @@ #include #include -static long tt0; static long tcount=0; static long cumul; static timeval tv; -#define START_TIMING gettimeofday(&tv,0);tt0=tv.tv_usec+tv.tv_sec*1000000; +#define START_TIMING long tt0;gettimeofday(&tv,0);tt0=tv.tv_usec+tv.tv_sec*1000000; #define END_TIMING(NUMBER) \ tcount=tcount+1;gettimeofday(&tv,0);cumul=cumul+tv.tv_usec+tv.tv_sec*1000000 -tt0; \ if(tcount==NUMBER){ std::cerr < children() const; @@ -90,6 +90,7 @@ private: TreeItem* myParent; QList myChildren; SUIT_DataObject* myObj; + int _position; }; /*! @@ -138,7 +139,7 @@ void SUIT_TreeModel::TreeItem::insertChild( SUIT_TreeModel::TreeItem* child, if ( !child ) return; - int index = after ? myChildren.indexOf( after ) + 1 : 0; + int index = after ? after->position() + 1 : 0; myChildren.insert( index, child ); } @@ -181,7 +182,7 @@ SUIT_TreeModel::TreeItem* SUIT_TreeModel::TreeItem::parent() const */ int SUIT_TreeModel::TreeItem::position() const { - return myParent ? myParent->myChildren.indexOf( (TreeItem*)this ) : -1; + return _position; } /*! @@ -334,10 +335,8 @@ void SUIT_TreeModel::TreeSync::updateItem( const ObjPtr& obj, const ItemPtr& ite { if( obj ) obj->update(); - /* if ( item && needUpdate( item ) ) myModel->updateItem( item ); - */ } /*! @@ -409,7 +408,8 @@ bool SUIT_TreeModel::TreeSync::needUpdate( const ItemPtr& item ) const // - use "LastModified" time stamp in data objects and tree items - hardly possible, for sometimes data objects do not know that data changes... // ... update = true; // TEMPORARY!!! - update = obj->modified(); + //update = obj->modified(); + update = false; // 1. check text /* update = ( item->text( 0 ) != obj->name() ) || myBrowser->needToUpdateTexts( item ); @@ -670,12 +670,10 @@ void SUIT_TreeModel::setRoot( SUIT_DataObject* r ) */ QVariant SUIT_TreeModel::data( const QModelIndex& index, int role ) const { -// std::cerr << "SUIT_TreeModel::data " << role << std::endl; if ( !index.isValid() ) return QVariant(); SUIT_DataObject* obj = object( index ); - //obj->setModified(false); QColor c; QVariant val; @@ -909,7 +907,6 @@ QModelIndex SUIT_TreeModel::index( int row, int column, */ QModelIndex SUIT_TreeModel::parent( const QModelIndex& index ) const { - //std::cerr << "SUIT_TreeModel::parent " << index.row() << std::endl; if ( !index.isValid() ) return QModelIndex(); @@ -1095,6 +1092,82 @@ void SUIT_TreeModel::updateTree( const QModelIndex& index ) updateTree( object( index ) ); } + +void SUIT_TreeModel::updateTreeModel(SUIT_DataObject* obj,TreeItem* item) +{ + int kobj=0; + int kitem=0; + int nobjchild=obj->childCount(); + //std::cerr << "updateTreeModel " << nobjchild << std::endl; + SUIT_DataObject* sobj=obj->childObject(kobj); + TreeItem* sitem = item->child(kitem); + + while(kobj < nobjchild) + { + //START_TIMING; + //std::cerr << kitem << std::endl; + if(sitem==0) + { + //end of item list + //std::cerr << "new object " << kobj << std::endl; + if(kitem==0) + sitem=createItem(sobj,item,0); + else + sitem=createItem(sobj,item,item->child(kitem-1)); + updateTreeModel(sobj,sitem); + kobj++; + kitem++; + sobj=obj->childObject(kobj); + sitem = item->child(kitem); + } + else if(sitem->dataObject() != sobj) + { + if(treeItem(sobj)) + { + // item : to remove + //std::cerr << "remove object " << kitem << std::endl; + removeItem(sitem); + sitem = item->child(kitem); + } + else + { + // obj : new object + //std::cerr << "new object " << kobj << std::endl; + createItem(sobj,item,item->child(kitem-1)); + kobj++; + kitem++; + sobj=obj->childObject(kobj); + sitem = item->child(kitem); + } + } + else + { + //obj and item are synchronised : go to next ones + //std::cerr << "existing object " << kitem << ":" << kobj << std::endl; + updateTreeModel(sobj,sitem); + if(sobj->modified()) updateItem(sitem); + if( sobj ) sobj->update(); + kobj++; + kitem++; + sobj=obj->childObject(kobj); + sitem = item->child(kitem); + } + //END_TIMING(100); + } + //std::cerr << "end of updatetreemodel " << kobj << ":" << kitem << std::endl; + //std::cerr << "end of updateTreeModel " << obj->childCount() << ":" << item->childCount() << std::endl; + //remove remaining items + for(int i = item->childCount(); i > kitem;i--) + { + //std::cerr << "remove object " << i << std::endl; + sitem = item->child(i-1); + removeItem(sitem); + } +} + + + + /*! \brief Update tree model. @@ -1107,27 +1180,14 @@ void SUIT_TreeModel::updateTree( const QModelIndex& index ) */ void SUIT_TreeModel::updateTree( SUIT_DataObject* obj ) { - if(myAutoUpdate) - { - emit layoutAboutToBeChanged(); - emit layoutChanged(); - emit modelUpdated(); - return; - } - if ( !obj ) obj = root(); else if ( obj->root() != root() ) return; + updateTreeModel(obj,treeItem( obj )); - synchronize( obj, - treeItem( obj ), - SUIT_TreeModel::TreeSync( this ) ); - - emit layoutAboutToBeChanged(); - emit layoutChanged(); emit modelUpdated(); } @@ -1226,17 +1286,18 @@ SUIT_TreeModel::TreeItem* SUIT_TreeModel::createItem( SUIT_DataObject* obj, SUIT_DataObject* parentObj = object( parent ); QModelIndex parentIdx = index( parentObj ); - SUIT_DataObject* afterObj = after ? object( after ) : 0; - int row = afterObj ? afterObj->position() + 1 : 0; - //std::cerr << " SUIT_TreeModel::createItem " << row << ":" << afterObj << std::endl; + int row = after ? after->position() + 1 : 0; beginInsertRows( parentIdx, row, row ); myItems[ obj ] = new TreeItem( obj, parent, after ); + for(int pos=row;pos < parent->childCount();pos++) + parent->child(pos)->setPosition(pos); + endInsertRows(); - //obj->setModified(false); + obj->setModified(false); return myItems[ obj ]; } @@ -1268,7 +1329,7 @@ void SUIT_TreeModel::updateItem( SUIT_TreeModel::TreeItem* item ) QModelIndex firstIdx = index( obj, 0 ); QModelIndex lastIdx = index( obj, columnCount() - 1 ); emit dataChanged( firstIdx, lastIdx ); - //obj->setModified(false); + obj->setModified(false); } /*! @@ -1285,7 +1346,7 @@ void SUIT_TreeModel::updateItem( SUIT_DataObject* obj) QModelIndex firstIdx = index( obj, 0 ); QModelIndex lastIdx = index( obj, columnCount() - 1 ); emit dataChanged( firstIdx, lastIdx ); - //obj->setModified(false); + obj->setModified(false); } @@ -1309,7 +1370,8 @@ void SUIT_TreeModel::removeItem( SUIT_TreeModel::TreeItem* item ) // Warning! obj can be deleted at this point! - SUIT_DataObject* parentObj = object( item->parent() ); + TreeItem* parent=item->parent(); + SUIT_DataObject* parentObj = object( parent ); QModelIndex parentIdx = index( parentObj, 0 ); int row = item->position(); @@ -1318,8 +1380,12 @@ void SUIT_TreeModel::removeItem( SUIT_TreeModel::TreeItem* item ) if ( obj == root() ) setRoot( 0 ); - else if ( item->parent() ) - item->parent()->removeChild( item ); + else if ( parent ) + { + parent->removeChild( item ); + for(int pos=row;pos < parent->childCount();pos++) + parent->child(pos)->setPosition(pos); + } delete item; @@ -1329,6 +1395,7 @@ void SUIT_TreeModel::removeItem( SUIT_TreeModel::TreeItem* item ) void SUIT_TreeModel::onUpdated( SUIT_DataObject* object) { updateItem(object); + emit modelUpdated(); } /*! @@ -1341,10 +1408,6 @@ void SUIT_TreeModel::onInserted( SUIT_DataObject* object, SUIT_DataObject* paren //std::cerr << "SUIT_TreeModel::onInserted" << std::endl; createItem(object,parent,after); emit modelUpdated(); - /* - if ( autoUpdate() ) - updateTree( parent ); - */ } /*! @@ -1357,10 +1420,6 @@ void SUIT_TreeModel::onRemoved( SUIT_DataObject* object, SUIT_DataObject* parent //std::cerr << "onRemoved" << std::endl; removeItem( treeItem(object) ); emit modelUpdated(); - /* - if ( autoUpdate() ) - updateTree( parent ); - */ } /*! diff --git a/src/SUIT/SUIT_TreeModel.h b/src/SUIT/SUIT_TreeModel.h index 31c424351..dc960f553 100755 --- a/src/SUIT/SUIT_TreeModel.h +++ b/src/SUIT/SUIT_TreeModel.h @@ -145,6 +145,8 @@ public: QAbstractItemDelegate* delegate() const; + virtual void updateTreeModel(SUIT_DataObject*,TreeItem*); + public slots: virtual void updateTree( const QModelIndex& ); virtual void updateTree( SUIT_DataObject* = 0 ); diff --git a/src/SalomeApp/SalomeApp_DataObject.cxx b/src/SalomeApp/SalomeApp_DataObject.cxx index 987af4c46..88835d76a 100644 --- a/src/SalomeApp/SalomeApp_DataObject.cxx +++ b/src/SalomeApp/SalomeApp_DataObject.cxx @@ -171,7 +171,6 @@ QString SalomeApp_DataObject::text( const int id ) const */ QPixmap SalomeApp_DataObject::icon( const int id ) const { - //std::cerr << "SalomeApp_DataObject::icon " << pthread_self() << std::endl; // we display icon only for the first (NameId ) column if ( id == NameId ) { _PTR(GenericAttribute) anAttr; @@ -563,6 +562,27 @@ QString SalomeApp_DataObject::value( const _PTR(SObject)& obj ) const return val; } +void SalomeApp_DataObject::insertChildAtTag(SalomeApp_DataObject* obj,int tag) +{ + int pos=0; + int npos=std::min(tag-1,childCount()); + for (int i=npos;i>0;i--) + { + // std::cerr << (dynamic_cast(father->childObject(i-1)))->object()->GetID() << std::endl; + if((dynamic_cast(childObject(i-1)))->object()->Tag() < tag) + { + // std::cerr << "found" << std::endl; + pos=i-1; + break; + } + } + // std::cerr << "position after: " << pos << std::endl; + insertChild(obj,pos+1); +} + + + + /*! \class SalomeApp_ModuleObject \brief This class is used for optimized access to the SALOMEDS-based diff --git a/src/SalomeApp/SalomeApp_DataObject.h b/src/SalomeApp/SalomeApp_DataObject.h index 7e2fa1cb2..cd7bffa74 100644 --- a/src/SalomeApp/SalomeApp_DataObject.h +++ b/src/SalomeApp/SalomeApp_DataObject.h @@ -69,6 +69,8 @@ public: virtual bool customSorting( const int = NameId ) const; virtual bool compare( const QVariant&, const QVariant&, const int = NameId ) const; + virtual void insertChildAtTag( SalomeApp_DataObject*, int ); + private: QString ior( const _PTR(SObject)& ) const; QString entry( const _PTR(SObject)& ) const; diff --git a/src/SalomeApp/SalomeApp_Study.cxx b/src/SalomeApp/SalomeApp_Study.cxx index eb8c7e2a2..a3eec63ec 100644 --- a/src/SalomeApp/SalomeApp_Study.cxx +++ b/src/SalomeApp/SalomeApp_Study.cxx @@ -69,28 +69,27 @@ class Observer_i : public virtual POA_SALOME::Observer virtual void notifyObserver(const char* theID, const char* event) { - START_TIMING; //MESSAGE("I'm notified of " << event << " of ID = " << theID); - _PTR(SObject) obj = myStudyDS->FindObjectID( theID ); - //MESSAGE("Checking the ID from the sObj : " << obj->GetID()); + // START_TIMING; - std::string entry_str = theID; - int last2Pnt_pos = entry_str.rfind(":"); - std::string parent_id=entry_str.substr(0,last2Pnt_pos); - std::string pos_in_parent=entry_str.substr(last2Pnt_pos+1); - - - //MESSAGE("Parent id " << parent_id << " with position " << pos_in_parent); - //_PTR(SObject) obj_parent = myStudyDS->FindObjectID( parent_id ); - _PTR(SObject) obj_parent = obj->GetFather(); - //MESSAGE("Checking the ID from the sObj_parent : " << obj_parent->GetID()); - - SUIT_DataObject* suit_obj; + SalomeApp_DataObject* suit_obj; if (std::string(event) == "ADD") { + if (entry2SuitObject.count(theID)>0) + { + std::cerr << "entry " << theID << " is already added. Problem ??" << std::endl; + return; + } //MESSAGE("ADDING"); + _PTR(SObject) obj = myStudyDS->FindObjectID( theID ); + //MESSAGE("Checking the ID from the sObj : " << obj->GetID()); + std::string entry_str = theID; + int last2Pnt_pos = entry_str.rfind(":"); + std::string parent_id=entry_str.substr(0,last2Pnt_pos); + std::string pos_in_parent=entry_str.substr(last2Pnt_pos+1); + //MESSAGE("Parent id " << parent_id << " with position " << pos_in_parent); _PTR(SComponent) aSComp(obj); if( aSComp ) @@ -106,24 +105,9 @@ class Observer_i : public virtual POA_SALOME::Observer if (entry2SuitObject.count(parent_id)>0) { - SUIT_DataObject* father=entry2SuitObject[parent_id]; - SUIT_DataObject* after=0; - std::string after_id; - std::stringstream ss; - for (int i=atoi(pos_in_parent.c_str());i>0;i--) - { - ss << parent_id << ":" << i ; - after_id = ss.str(); - ss.str(""); - if (entry2SuitObject.count(after_id)>0) - { - after=entry2SuitObject[after_id]; - //MESSAGE("after_id " << after_id); - break; - } - } - int pos = after ? father->childPos( after ) : 0; - father->insertChild(suit_obj,pos+1); + SalomeApp_DataObject* father=entry2SuitObject[parent_id]; + int tag=atoi(pos_in_parent.c_str()); + father->insertChildAtTag(suit_obj,tag); /* if (LightApp_Application* myApp=dynamic_cast(myStudy->application())) if (SUIT_ProxyModel* myModel=dynamic_cast(myApp->objectBrowser()->model())) @@ -150,16 +134,9 @@ class Observer_i : public virtual POA_SALOME::Observer if (entry2SuitObject.count(theID)>0) { suit_obj= entry2SuitObject[theID]; - if (entry2SuitObject.count(parent_id)>0) - { - SUIT_DataObject* father=entry2SuitObject[parent_id]; - father->removeChild(suit_obj); - } - else - { - //MESSAGE("This should be for a module"); - myStudy->root()->removeChild(suit_obj); - } + SUIT_DataObject* father=suit_obj->parent(); + if(father) + father->removeChild(suit_obj); entry2SuitObject.erase(theID); } else @@ -174,20 +151,25 @@ class Observer_i : public virtual POA_SALOME::Observer { suit_obj= entry2SuitObject[theID]; suit_obj->updateItem(); + /* + if (LightApp_Application* myApp=dynamic_cast(myStudy->application())) + if (SUIT_ProxyModel* myModel=dynamic_cast(myApp->objectBrowser()->model())) + myModel->updateItem(suit_obj); + */ } else { MESSAGE("Want to modify an unknown object" << theID); } } - END_TIMING(100); + // END_TIMING(100); } private: _PTR(Study) myStudyDS; SalomeApp_Study* myStudy; - map entry2SuitObject; + map entry2SuitObject; }; @@ -269,7 +251,8 @@ bool SalomeApp_Study::createDocument( const QString& theStr ) emit created( this ); Observer_i* myObserver_i = new Observer_i(myStudyDS,this); - myStudyDS->attach(myObserver_i->_this()); + //attach an observer to the study without notification of modifications + myStudyDS->attach(myObserver_i->_this(),true); return aRet; } -- 2.39.2