QtxResourceMgr.h \
QtxRubberBand.h \
QtxSearchTool.h \
+ QtxShortcutEdit.h \
QtxSplash.h \
QtxToolBar.h \
QtxToolTip.h \
QtxResourceMgr.cxx \
QtxRubberBand.cxx \
QtxSearchTool.cxx \
+ QtxShortcutEdit.cxx \
QtxSplash.cxx \
QtxToolBar.cxx \
QtxToolTip.cxx \
QtxPopupMgr_moc.cxx \
QtxRubberBand_moc.cxx \
QtxSearchTool_moc.cxx \
+ QtxShortcutEdit_moc.cxx \
QtxSplash_moc.cxx \
QtxToolBar_moc.cxx \
QtxToolTip_moc.cxx \
#include "QtxIntSpinBox.h"
#include "QtxColorButton.h"
#include "QtxDoubleSpinBox.h"
+#include "QtxShortcutEdit.h"
+#include "QtxResourceMgr.h"
#include <QEvent>
#include <QLayout>
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() );
+ }
+ }
+}
+
+
class QtxGroupBox;
class QtxComboBox;
class QtxColorButton;
+class QtxShortcutEdit;
+class QtxShortcutTree;
class QToolBox;
class QLineEdit;
class QDateTimeEdit;
class QStackedWidget;
class QSlider;
+class QTreeWidget;
class QTX_EXPORT QtxPagePrefMgr : public QFrame, public QtxPreferenceMgr
{
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
QStringList names = sections( QStringList() << section );
QMutableListIterator<QString> 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;
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.
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();
--- /dev/null
+// 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 <QWidget>
+#include <QLayout>
+#include <QList>
+
+#include <QToolButton>
+#include <QLineEdit>
+#include <QTableWidgetItem>
+
+#include <QKeyEvent>
+#include <QKeySequence>
+
+#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<QKeyEvent*>(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<QKeyEvent*>(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 ) ] );
+}
--- /dev/null
+// 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 <QFrame>
+#include <QTreeWidget>
+
+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
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
*/
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<const SOCC_Prs*>( prs );
if ( !anOCCPrs || anOCCPrs->IsNull() )
*/
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));
- */
+
}
/*!
*/
void SUIT_DataObject::removeChild( SUIT_DataObject* obj, const bool del )
{
- //std::cerr << "removeChild " << del << std::endl;
if ( !obj )
return;
parent()->appendChild( this );
}
+void SUIT_DataObject::assignParent( SUIT_DataObject* p )
+{
+ if ( p == myParent )
+ return;
+ myParent = p;
+}
+
/*!
\brief Get data object name.
{
if(modified())return;
setModified(true);
- signal()->emitUpdated(this);
+ //signal()->emitUpdated(this);
}
/*!
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;
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;
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 );
#include <QHash>
#include <sys/time.h>
-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 <<pthread_self()<<":"<<__FILE__<<":"<<__LINE__<<" temps CPU(mus): "<<cumul<< std::endl; tcount=0;cumul=0; }
SUIT_DataObject* dataObject() const;
TreeItem* parent() const;
int position() const;
+ void setPosition(int position) {_position=position;};
int childCount() const;
TreeItem* child( const int i );
QList<TreeItem*> children() const;
TreeItem* myParent;
QList<TreeItem*> myChildren;
SUIT_DataObject* myObj;
+ int _position;
};
/*!
if ( !child )
return;
- int index = after ? myChildren.indexOf( after ) + 1 : 0;
+ int index = after ? after->position() + 1 : 0;
myChildren.insert( index, child );
}
*/
int SUIT_TreeModel::TreeItem::position() const
{
- return myParent ? myParent->myChildren.indexOf( (TreeItem*)this ) : -1;
+ return _position;
}
/*!
{
if( obj )
obj->update();
- /*
if ( item && needUpdate( item ) )
myModel->updateItem( item );
- */
}
/*!
// - 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 );
*/
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;
*/
QModelIndex SUIT_TreeModel::parent( const QModelIndex& index ) const
{
- //std::cerr << "SUIT_TreeModel::parent " << index.row() << std::endl;
if ( !index.isValid() )
return QModelIndex();
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.
*/
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<ObjPtr,ItemPtr,SUIT_TreeModel::TreeSync>( obj,
- treeItem( obj ),
- SUIT_TreeModel::TreeSync( this ) );
-
- emit layoutAboutToBeChanged();
- emit layoutChanged();
emit modelUpdated();
}
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 ];
}
QModelIndex firstIdx = index( obj, 0 );
QModelIndex lastIdx = index( obj, columnCount() - 1 );
emit dataChanged( firstIdx, lastIdx );
- //obj->setModified(false);
+ obj->setModified(false);
}
/*!
QModelIndex firstIdx = index( obj, 0 );
QModelIndex lastIdx = index( obj, columnCount() - 1 );
emit dataChanged( firstIdx, lastIdx );
- //obj->setModified(false);
+ obj->setModified(false);
}
// 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();
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;
void SUIT_TreeModel::onUpdated( SUIT_DataObject* object)
{
updateItem(object);
+ emit modelUpdated();
}
/*!
//std::cerr << "SUIT_TreeModel::onInserted" << std::endl;
createItem(object,parent,after);
emit modelUpdated();
- /*
- if ( autoUpdate() )
- updateTree( parent );
- */
}
/*!
//std::cerr << "onRemoved" << std::endl;
removeItem( treeItem(object) );
emit modelUpdated();
- /*
- if ( autoUpdate() )
- updateTree( parent );
- */
}
/*!
QAbstractItemDelegate* delegate() const;
+ virtual void updateTreeModel(SUIT_DataObject*,TreeItem*);
+
public slots:
virtual void updateTree( const QModelIndex& );
virtual void updateTree( SUIT_DataObject* = 0 );
*/
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;
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<SalomeApp_DataObject*>(father->childObject(i-1)))->object()->GetID() << std::endl;
+ if((dynamic_cast<SalomeApp_DataObject*>(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
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;
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 )
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<LightApp_Application*>(myStudy->application()))
if (SUIT_ProxyModel* myModel=dynamic_cast<SUIT_ProxyModel*>(myApp->objectBrowser()->model()))
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
{
suit_obj= entry2SuitObject[theID];
suit_obj->updateItem();
+ /*
+ if (LightApp_Application* myApp=dynamic_cast<LightApp_Application*>(myStudy->application()))
+ if (SUIT_ProxyModel* myModel=dynamic_cast<SUIT_ProxyModel*>(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<string,SUIT_DataObject*> entry2SuitObject;
+ map<string,SalomeApp_DataObject*> entry2SuitObject;
};
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;
}