From: jfa Date: Fri, 28 Oct 2011 12:09:53 +0000 (+0000) Subject: Mantis issue 0020136: EDF 933 DEV : Drag&Drop in OB X-Git-Tag: V6_4_0a1~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=f6033fb74302338d7940d5f3e46501061fcd7bac;p=modules%2Fgui.git Mantis issue 0020136: EDF 933 DEV : Drag&Drop in OB --- diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 626039899..828e31f81 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -89,7 +89,7 @@ #include #include #include -#include +#include #include @@ -175,6 +175,7 @@ #include #include #include +#include #include #include @@ -269,7 +270,7 @@ LightApp_Application::LightApp_Application() SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); QPixmap aLogo = aResMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false ); - + QtxWebBrowser::setData("browser:icon", aResMgr->loadPixmap( "LightApp", tr( "BROWSER_ICON" ) ) ); QtxWebBrowser::setData("browser:title", tr( "BROWSER_TITLE" ) ); QtxWebBrowser::setData("toolbar:title", tr( "BROWSER_TOOLBAR_TITLE" ) ); @@ -557,7 +558,7 @@ void LightApp_Application::createActions() if ( QFile::exists( indexFile ) ) helpData.insert( tr( "%1 module Users's Guide" ).arg( aModule ), indexFile ); } - + IMapConstIterator fileIt; for ( fileIt = helpData.begin(); fileIt != helpData.end(); fileIt++ ) { QString helpFileName = fileIt.key(); @@ -568,7 +569,7 @@ void LightApp_Application::createActions() a->setData( fileIt.value() ); if ( !helpSubMenu.isEmpty() ){ int helpSubMenuId = createMenu( helpSubMenu, helpMenu, -1, 0 ); - createMenu( a, helpSubMenuId, -1 ); + createMenu( a, helpSubMenuId, -1 ); } else createMenu( a, helpMenu, -1, 0 ); @@ -580,17 +581,17 @@ void LightApp_Application::createActions() static QtxMRUAction* mru = new QtxMRUAction( tr( "TOT_DESK_MRU" ), tr( "MEN_DESK_MRU" ), 0 ); connect( mru, SIGNAL( activated( const QString& ) ), this, SLOT( onMRUActivated( const QString& ) ) ); registerAction( MRUId, mru ); - + // default icon for neutral point ('SALOME' module) QPixmap defIcon = resMgr->loadPixmap( "LightApp", tr( "APP_DEFAULT_ICO" ), false ); if ( defIcon.isNull() ) defIcon = QPixmap( imageEmptyIcon ); - + //! default icon for any module QPixmap modIcon = resMgr->loadPixmap( "LightApp", tr( "APP_MODULE_ICO" ), false ); if ( modIcon.isNull() ) modIcon = QPixmap( imageEmptyIcon ); - + QStringList modList; modules( modList, false ); @@ -609,7 +610,7 @@ void LightApp_Application::createActions() { if ( !isLibExists( *it ) ) continue; - + QString modName = moduleName( *it ); if ( !isModuleAccessible( *it ) ) @@ -624,7 +625,7 @@ void LightApp_Application::createActions() { icon = modIcon; INFOS ( "****************************************************************" << std::endl - << "* Icon for " << (*it).toLatin1().constData() + << "* Icon for " << (*it).toLatin1().constData() << " not found. Using the default one." << std::endl << "****************************************************************" << std::endl ); } @@ -634,7 +635,7 @@ void LightApp_Application::createActions() moduleAction->insertModule( *it, icon ); } - connect( moduleAction, SIGNAL( moduleActivated( const QString& ) ), + connect( moduleAction, SIGNAL( moduleActivated( const QString& ) ), this, SLOT( onModuleActivation( const QString& ) ) ); registerAction( ModulesListId, moduleAction ); } @@ -689,7 +690,7 @@ void LightApp_Application::createActions() 0, desk, false, this, SLOT( onStylePreferences() ) ); createAction( FullScreenId, tr( "TOT_FULLSCREEN" ), QIcon(), tr( "MEN_DESK_FULLSCREEN" ), tr( "PRP_FULLSCREEN" ), - Qt::Key_F11, desk, false, this, SLOT( onFullScreen() ) ); + Qt::Key_F11, desk, false, this, SLOT( onFullScreen() ) ); int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1 ); @@ -992,20 +993,19 @@ void LightApp_Application::onHelpContentsModule() bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false ); if( useExtBrowser ) { - if ( !anApp.isEmpty() ) - { - RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile ); - rs->start(); - } - else - { - if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes ) - - showPreferences( tr( "PREF_APP" ) ); - } - } else { + if ( !anApp.isEmpty() ) { + RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile ); + rs->start(); + } + else { + if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes ) + + showPreferences( tr( "PREF_APP" ) ); + } + } + else { QtxWebBrowser::loadUrl(getFile() + helpFile); } } @@ -1045,23 +1045,22 @@ void LightApp_Application::onHelpContextModule( const QString& theComponentName, #endif bool useExtBrowser = resMgr->booleanValue("ExternalBrowser", "use_external_browser", false ); - - if(useExtBrowser) { + + if(useExtBrowser) { QString aParams = resMgr->stringValue("ExternalBrowser", "parameters"); - - if ( !anApp.isEmpty() ) - { - RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile, theContext ); - rs->start(); - } - else - { - if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes ) - showPreferences( tr( "PREF_APP" ) ); - } - } else { + + if ( !anApp.isEmpty() ) { + RunBrowser* rs = new RunBrowser( this, anApp, aParams, helpFile, theContext ); + rs->start(); + } + else { + if ( SUIT_MessageBox::question( desktop(), tr( "WRN_WARNING" ), tr( "DEFINE_EXTERNAL_BROWSER" ), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes ) + showPreferences( tr( "PREF_APP" ) ); + } + } + else { QtxWebBrowser::loadUrl(getFile() + helpFile, theContext ); } } @@ -1404,18 +1403,18 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType #else vm = new OCCViewer_Viewer( true ); #endif - vm->setBackgroundColor( OCCViewer_ViewFrame::TOP_LEFT, + vm->setBackgroundColor( OCCViewer_ViewFrame::TOP_LEFT, resMgr->colorValue( "OCCViewer", "xz_background", vm->backgroundColor() ) ); - vm->setBackgroundColor( OCCViewer_ViewFrame::TOP_RIGHT, - resMgr->colorValue( "OCCViewer", "yz_background", vm->backgroundColor() ) ); - + vm->setBackgroundColor( OCCViewer_ViewFrame::TOP_RIGHT, + resMgr->colorValue( "OCCViewer", "yz_background", vm->backgroundColor() ) ); + vm->setBackgroundColor( OCCViewer_ViewFrame::BOTTOM_LEFT, resMgr->colorValue( "OCCViewer", "xy_background", vm->backgroundColor() ) ); - vm->setBackgroundColor( OCCViewer_ViewFrame::BOTTOM_RIGHT, - resMgr->colorValue( "OCCViewer", "background", vm->backgroundColor() ) ); - - vm->setTrihedronSize( resMgr->doubleValue( "OCCViewer", "trihedron_size", vm->trihedronSize() ), - resMgr->booleanValue( "OCCViewer", "relative_size", vm->trihedronRelative() )); + vm->setBackgroundColor( OCCViewer_ViewFrame::BOTTOM_RIGHT, + resMgr->colorValue( "OCCViewer", "background", vm->backgroundColor() ) ); + + vm->setTrihedronSize( resMgr->doubleValue( "OCCViewer", "trihedron_size", vm->trihedronSize() ), + resMgr->booleanValue( "OCCViewer", "relative_size", vm->trihedronRelative() )); int u( 1 ), v( 1 ); vm->isos( u, v ); u = resMgr->integerValue( "OCCViewer", "iso_number_u", u ); @@ -1481,11 +1480,11 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType { SUIT_ResourceMgr* resMgr = resourceMgr(); - SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), - desktop(), - new LightApp_WgViewModel( vmType, w ) ); + SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), + desktop(), + new LightApp_WgViewModel( vmType, w ) ); vm->setTitle( QString( "%1: %M - viewer %V" ).arg( vmType ) ); - + addViewManager( vm ); SUIT_ViewWindow* vw = vm->createViewWindow(); if ( vw && desktop() ) { @@ -1667,6 +1666,60 @@ void LightApp_Application::onRefresh() updateObjectBrowser( true ); } +/*!Private SLOT. Support drag-and-drop operation.*/ +void LightApp_Application::onDropped (const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex& parent) +{ + if (action == Qt::IgnoreAction) + return; + + if (!data->hasFormat("application/vnd.text.list")) + return; + + if (column > 0) + return; + + if (!parent.isValid()) + // dropping into the top level of the model is not allowed + return; + + SUIT_AbstractModel* treeModel = dynamic_cast(objectBrowser()->model()); + + SUIT_DataObject* obj = treeModel->object(parent); + if (!obj) + return; + + LightApp_DataObject* parentObj = dynamic_cast(obj); + if (!parentObj) + return; + + // decode mime data + QByteArray encodedData = data->data("application/vnd.text.list"); + QDataStream stream (&encodedData, QIODevice::ReadOnly); + QStringList newItems; + + while (!stream.atEnd()) { + QString text; + stream >> text; + if (!text.isEmpty()) + newItems << text; + } + + DataObjectList listObjs; + foreach (QString text, newItems) { + SUIT_DataObject* anObji = findObject(text); + if (anObji) + listObjs.append(anObji); + } + + // tmp: clear selection to avoid problem with persistent data model indexes + //mySelMgr->clearSelected(); + + LightApp_Module* aModule = dynamic_cast(parentObj->module()); + if (aModule) + aModule->dropObjects(listObjs, action, parentObj, row); +} + /*!Private SLOT. On preferences.*/ void LightApp_Application::onPreferences() { @@ -1774,6 +1827,11 @@ QWidget* LightApp_Application::createWindow( const int flag ) treeModel->registerColumn( 0, EntryCol, LightApp_DataObject::EntryId ); treeModel->setAppropriate( EntryCol, Qtx::Toggled ); + // Mantis issue 0020136: Drag&Drop in OB + SUIT_ProxyModel* proxyModel = dynamic_cast(treeModel); + connect( proxyModel, SIGNAL(dropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&)), + this, SLOT(onDropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&)) ); + // temporary commented /* OB_ListView* ob_list = dynamic_cast( const_cast( ob->listView() ) ); @@ -1985,7 +2043,7 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "ascii_file" ); pref->addPreference( tr( "PREF_STORE_POS" ), studyGroup, LightApp_Preferences::Bool, "Study", "store_positions" ); - int autoSaveInterval = pref->addPreference( tr( "PREF_AUTO_SAVE" ), studyGroup, + int autoSaveInterval = pref->addPreference( tr( "PREF_AUTO_SAVE" ), studyGroup, LightApp_Preferences::IntSpin, "Study", "auto_save_interval" ); pref->setItemProperty( "min", 0, autoSaveInterval ); pref->setItemProperty( "max", 1440, autoSaveInterval ); @@ -2012,8 +2070,8 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) int genGroup = pref->addPreference( tr( "PREF_GROUP_COMMON" ), viewTab ); pref->addPreference( tr( "PREF_DROP_DOWN_BUTTONS" ), genGroup, - LightApp_Preferences::Bool, "viewers", "drop_down_buttons" ); - + LightApp_Preferences::Bool, "viewers", "drop_down_buttons" ); + int occGroup = pref->addPreference( tr( "PREF_GROUP_OCCVIEWER" ), viewTab ); int vtkGroup = pref->addPreference( tr( "PREF_GROUP_VTKVIEWER" ), viewTab ); @@ -2033,7 +2091,7 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) LightApp_Preferences::DblSpin, "OCCViewer", "trihedron_size" ); pref->setItemProperty( "min", 1.0E-06, occTS ); pref->setItemProperty( "max", 1000, occTS ); - + pref->addPreference( tr( "PREF_RELATIVE_SIZE" ), occGroup, LightApp_Preferences::Bool, "OCCViewer", "relative_size" ); int occStyleMode = pref->addPreference( tr( "PREF_NAVIGATION" ), occGroup, @@ -2360,14 +2418,14 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString if ( !resMgr ) return; - if ( sec == "viewers" && param == "drop_down_buttons" ) + if ( sec == "viewers" && param == "drop_down_buttons" ) { ViewManagerList vmlist = viewManagers(); foreach( SUIT_ViewManager* vm, vmlist ) { QVector vwlist = vm->getViews(); foreach( SUIT_ViewWindow* vw, vwlist ) - if ( vw ) vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) ); + if ( vw ) vw->setDropDownButtons( resMgr->booleanValue( "viewers", "drop_down_buttons", true ) ); } } @@ -2736,10 +2794,10 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString } if ( sec == "ExternalBrowser" && param == "use_external_browser" ) { - if ( resMgr->booleanValue("ExternalBrowser", "use_external_browser", false ) ) + if ( resMgr->booleanValue("ExternalBrowser", "use_external_browser", false ) ) { - if(QtxWebBrowser::webBrowser()) - QtxWebBrowser::webBrowser()->close(); + if(QtxWebBrowser::webBrowser()) + QtxWebBrowser::webBrowser()->close(); } } @@ -2812,7 +2870,7 @@ void LightApp_Application::loadPreferences() desktop()->setDockOptions( dopts ); desktop()->setOpaqueResize( opaqueResize ); if ( dynamic_cast( desktop() ) ) - dynamic_cast( desktop() )->workstack()->setOpaqueResize( opaqueResize ); + dynamic_cast( desktop() )->workstack()->setOpaqueResize( opaqueResize ); } } @@ -3222,7 +3280,7 @@ void LightApp_Application::moduleIconNames( QMap& iconMap ) co */ void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopup, QString& title ) { - //Add "Rename" item + //Add "Rename" item LightApp_SelectionMgr* selMgr = LightApp_Application::selectionMgr(); bool cacheIsOn = selMgr->isSelectionCacheEnabled(); selMgr->setSelectionCacheEnabled( true ); @@ -3237,7 +3295,7 @@ void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopu if ( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) ) a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) ); } - + if ( selMgr && ob ) { SALOME_ListIO selected; selMgr->selectedObjects( selected ); @@ -3245,14 +3303,14 @@ void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopu Handle(SALOME_InteractiveObject) anIObject = selected.First(); SUIT_DataObject* obj = findObject(anIObject->getEntry()); if(obj && obj->renameAllowed()) { - QAction* a = new QAction(tr("MEN_RENAME_OBJ"), thePopup); - connect( a, SIGNAL( triggered(bool) ), ob, SLOT( onStartEditing() ) ); - if ( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) ) - a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) ); - - QList acts = thePopup->actions(); - QAction* firstAction = acts.count() > 0 ? acts.first() : 0; - thePopup->insertAction(firstAction,a); + QAction* a = new QAction(tr("MEN_RENAME_OBJ"), thePopup); + connect( a, SIGNAL( triggered(bool) ), ob, SLOT( onStartEditing() ) ); + if ( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) ) + a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::RenameShortcut) ); + + QList acts = thePopup->actions(); + QAction* firstAction = acts.count() > 0 ? acts.first() : 0; + thePopup->insertAction(firstAction,a); } } } @@ -3269,7 +3327,7 @@ void LightApp_Application::createEmptyStudy() if ( objectBrowser() ) objectBrowser()->updateTree(); - + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); if ( aResMgr && activeStudy() ) { int autoSaveInterval = aResMgr->integerValue( "Study", "auto_save_interval", 0 ); @@ -3360,7 +3418,7 @@ void LightApp_Application::removeViewManager( SUIT_ViewManager* vm ) LightApp_Study* aStudy = dynamic_cast(activeStudy()); if (aStudy ) aStudy->removeViewMgr(vm->getGlobalId()); - + STD_Application::removeViewManager( vm ); delete vm; } @@ -3661,7 +3719,7 @@ void LightApp_Application::clearKnownViewManagers() } /*! - Copy of current selection + Copy of current selection */ void LightApp_Application::onCopy() { diff --git a/src/LightApp/LightApp_Application.h b/src/LightApp/LightApp_Application.h index 8ac894002..f758aad1d 100644 --- a/src/LightApp/LightApp_Application.h +++ b/src/LightApp/LightApp_Application.h @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: LightApp_Application.h // Created: 6/20/2005 18:39:25 PM // Author: OCC team -// + #ifndef LIGHTAPP_APPLICATION_H #define LIGHTAPP_APPLICATION_H @@ -85,7 +84,7 @@ public: CloseId, CloseAllId, GroupAllId, PreferencesId, MRUId, ModulesListId, NewGLViewId, NewPlot2dId, NewOCCViewId, NewVTKViewId, NewQxGraphViewId, - NewQxSceneViewId = NewQxGraphViewId, StyleId, FullScreenId, + NewQxSceneViewId = NewQxGraphViewId, StyleId, FullScreenId, UserID }; protected: @@ -238,6 +237,8 @@ protected slots: private slots: void onSelection(); void onRefresh(); + void onDropped( const QMimeData*, Qt::DropAction, + int, int, const QModelIndex& ); void onPreferences(); void onPreferenceChanged( QString&, QString&, QString& ); void onRenameWindow(); diff --git a/src/LightApp/LightApp_DataObject.cxx b/src/LightApp/LightApp_DataObject.cxx index 39a932e29..6dd9f06dc 100644 --- a/src/LightApp/LightApp_DataObject.cxx +++ b/src/LightApp/LightApp_DataObject.cxx @@ -18,11 +18,10 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : LightApp_DataObject.cxx // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #include "LightApp_DataObject.h" #include "LightApp_Study.h" #include "LightApp_DataModel.h" @@ -30,10 +29,12 @@ #include "LightApp_Application.h" #include -#include +#include #include +#include + /*! \class LightApp_DataObject::Key \brief Represents unique data object key for the LightApp_DataObject @@ -103,12 +104,12 @@ bool LightApp_DataObject::Key::isEqual( const SUIT_DataObjectKey* other ) const */ /*! - \brief Constructor. + \brief Constructor. \param parent parent data object */ LightApp_DataObject::LightApp_DataObject( SUIT_DataObject* parent ) -: CAM_DataObject( parent ), - myCompObject( 0 ), +: CAM_DataObject( parent ), + myCompObject( 0 ), myCompDataType( "" ) { } @@ -131,7 +132,7 @@ int LightApp_DataObject::groupId() const */ QVariant LightApp_DataObject::customData(Qtx::CustomDataType type) { switch(type) { - case Qtx::IdType: + case Qtx::IdType: return EntryId; break; default: @@ -150,6 +151,39 @@ bool LightApp_DataObject::isVisible() const return r && r->study() && componentDataType() != r->study()->getVisualComponentName(); } +/*! + \brief Check if the object is dragable. + + This method can be re-implemented in the subclasses. + + \return \c true if it is possible to drag this object +*/ +bool LightApp_DataObject::isDragable() const +{ + LightApp_Module* aModule = dynamic_cast(module()); + if (aModule) { + return aModule->isDragable(this); + } + return false; +} + +/*! + \brief Check if the drop operation fo this object is possible. + + This method can be re-implemented in the subclasses. + + \param obj object being dropped + \return \c true if it is possible to drop an object \c obj + to this object +*/ +bool LightApp_DataObject::isDropAccepted() +{ + LightApp_Module* aModule = dynamic_cast(module()); + if (aModule) { + return aModule->isDropAccepted(this); + } + return false; +} /*! \brief Check if this object is can't be renamed in place @@ -168,7 +202,7 @@ bool LightApp_DataObject::renameAllowed( const int id ) const LightApp_RootObject* r = dynamic_cast( root() ); if(r && r->study()) app = dynamic_cast(r->study()->application()); - + return ( m && m->renameAllowed( entry() ) ) || ( app && app->renameAllowed( entry() ) ); } @@ -188,7 +222,8 @@ bool LightApp_DataObject::setName(const QString& name) { LightApp_Module* m = dynamic_cast( module() ); LightApp_RootObject* r = dynamic_cast( root() ); - LightApp_Application* app = (r && r->study()) ? dynamic_cast(r->study()->application()) : 0; + LightApp_Application* app = + (r && r->study()) ? dynamic_cast(r->study()->application()) : 0; return ( m && m->renameObject( entry(), name ) ) || ( app && app->renameObject( entry(), name ) ); @@ -326,7 +361,7 @@ bool LightApp_DataObject::compare( const QVariant& left, const QVariant& right, } else { // both not integer ID - int r = QString::localeAwareCompare( idsLeft[i], idsRight[i] ); + int r = QString::localeAwareCompare( idsLeft[i], idsRight[i] ); if ( !calculated && r != 0 ) { result = r < 0; calculated = true; @@ -334,7 +369,7 @@ bool LightApp_DataObject::compare( const QVariant& left, const QVariant& right, } } // we should reach this if the entries are exactly equal - return result; + return result; } return QString::localeAwareCompare( leftStr, rightStr ) < 0; } @@ -408,9 +443,9 @@ QString LightApp_ModuleObject::toolTip( const int id ) const /*! \brief Insert new child object to the children list at specified position. - + Adds component in the study for this module object if it is not done yet. - + \param obj object to be inserted \param pos position at which data object should be inserted */ @@ -442,8 +477,8 @@ void LightApp_ModuleObject::insertChild( SUIT_DataObject* obj, int pos ) */ LightApp_RootObject::LightApp_RootObject( LightApp_Study* study ) : CAM_DataObject( 0 ), - LightApp_DataObject( 0 ), - myStudy( study ) + LightApp_DataObject( 0 ), + myStudy( study ) { } @@ -459,8 +494,8 @@ LightApp_RootObject::~LightApp_RootObject() \param study pointer to the study */ void LightApp_RootObject::setStudy( LightApp_Study* study ) -{ - myStudy = study; +{ + myStudy = study; } /* @@ -468,6 +503,6 @@ void LightApp_RootObject::setStudy( LightApp_Study* study ) \return pointer to the study */ LightApp_Study* LightApp_RootObject::study() const -{ - return myStudy; -} +{ + return myStudy; +} diff --git a/src/LightApp/LightApp_DataObject.h b/src/LightApp/LightApp_DataObject.h index f87d97d63..6af26dcc8 100644 --- a/src/LightApp/LightApp_DataObject.h +++ b/src/LightApp/LightApp_DataObject.h @@ -18,11 +18,10 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : LightApp_DataObject.h // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #ifndef LIGHTAPP_DATAOBJECT_H #define LIGHTAPP_DATAOBJECT_H @@ -38,7 +37,7 @@ class LIGHTAPP_EXPORT LightApp_DataObject : public virtual CAM_DataObject public: //! Column id - enum { + enum { EntryId = VisibilityId + 1 //!< entry column }; @@ -60,6 +59,8 @@ public: virtual QVariant customData(Qtx::CustomDataType type); virtual bool isVisible() const; + virtual bool isDragable() const; + virtual bool isDropAccepted(); virtual bool renameAllowed( const int = NameId ) const; virtual bool setName( const QString& ); @@ -90,10 +91,10 @@ public: LightApp_RootObject( LightApp_Study* ); virtual ~LightApp_RootObject(); - + void setStudy( LightApp_Study* ); LightApp_Study* study() const; - + private: LightApp_Study* myStudy; }; diff --git a/src/LightApp/LightApp_Module.cxx b/src/LightApp/LightApp_Module.cxx index cb662489b..857807f17 100644 --- a/src/LightApp/LightApp_Module.cxx +++ b/src/LightApp/LightApp_Module.cxx @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: LightApp_Module.cxx // Created: 6/20/2005 16:30:56 AM // Author: OCC team -// + #include "LightApp_Module.h" #include "CAM_Application.h" @@ -93,6 +92,7 @@ #include #include +#include /*!Constructor.*/ LightApp_Module::LightApp_Module( const QString& name ) @@ -703,6 +703,32 @@ void LightApp_Module::paste() { } +/*! + virtual method + \return true if module allows dragging the given object +*/ +bool LightApp_Module::isDragable(const SUIT_DataObject* /*what*/) const +{ + return false; +} + +/*! + virtual method + \return true if module allows dropping one or more objects (currently selected) on the object \c where +*/ +bool LightApp_Module::isDropAccepted(const SUIT_DataObject* /*where*/) const +{ + return false; +} + +/*! + virtual method +*/ +void LightApp_Module::dropObjects(const DataObjectList& what, Qt::DropAction action, + const SUIT_DataObject* parent, const int row) +{ +} + /*! \brief Return \c true if object can be renamed */ diff --git a/src/LightApp/LightApp_Module.h b/src/LightApp/LightApp_Module.h index b71e4622e..2d82ad2d6 100644 --- a/src/LightApp/LightApp_Module.h +++ b/src/LightApp/LightApp_Module.h @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: LightApp_Module.h // Created: 6/20/2005 16:25:06 AM // Author: OCC team -// + #ifndef LIGHTAPP_MODULE_H #define LIGHTAPP_MODULE_H @@ -31,6 +30,8 @@ #include "LightApp_Preferences.h" #include +#include + class LightApp_Application; class LightApp_Selection; class LightApp_Operation; @@ -39,7 +40,7 @@ class LightApp_Displayer; class LightApp_SelectionMgr; class SUIT_Study; -class SUIT_DataObject; +//class SUIT_DataObject; class SUIT_Operation; class SUIT_ViewManager; class CAM_Application; @@ -78,12 +79,11 @@ public: virtual void update( const int ); // Update viewer or/and object browser etc. in accordance with update flags - // ( see SalomeApp_UpdateFlags enumeration ). Derived modules can redefine this method + // (see SalomeApp_UpdateFlags enumeration). Derived modules can redefine this method // for their own purposes virtual void updateObjBrowser( bool = true, SUIT_DataObject* = 0 ); - // Update object bropwser ( for updating model or whole object browser use update() method - // can be used ) + // Update object browser (for updating model or whole object browser use update() method) virtual void selectionChanged(); virtual void preferencesChanged( const QString&, const QString& ); @@ -95,6 +95,10 @@ public: virtual bool canCopy() const; virtual bool canPaste() const; + virtual bool isDragable(const SUIT_DataObject* what) const; + virtual bool isDropAccepted(const SUIT_DataObject* where) const; + virtual void dropObjects(const DataObjectList& what, Qt::DropAction action, + const SUIT_DataObject* parent, const int row); virtual void copy(); virtual void paste(); virtual bool renameAllowed( const QString& ) const; @@ -133,7 +137,8 @@ protected: virtual bool reusableOperation( const int id ); int addPreference( const QString& label ); - int addPreference( const QString& label, const int pId, const int = LightApp_Preferences::Auto, + int addPreference( const QString& label, const int pId, + const int type = LightApp_Preferences::Auto, const QString& section = QString(), const QString& param = QString() ); QVariant preferenceProperty( const int, const QString& ) const; diff --git a/src/ObjBrowser/OB_Browser.cxx b/src/ObjBrowser/OB_Browser.cxx index ed0253003..0e9fa2a33 100755 --- a/src/ObjBrowser/OB_Browser.cxx +++ b/src/ObjBrowser/OB_Browser.cxx @@ -18,11 +18,10 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : OB_Browser.cxx // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #include "OB_Browser.h" //#include "OB_Filter.h" @@ -142,6 +141,13 @@ OB_Browser::OB_Browser( QWidget* parent, QAbstractItemModel* model ) myView->setSelectionMode( QAbstractItemView::ExtendedSelection ); myView->setAllColumnsShowFocus( true ); + // Mantis issue 0020136: Drag&Drop in OB + myView->setDragEnabled(TRUE); + myView->setAcceptDrops(TRUE); + myView->setDropIndicatorShown(TRUE); + myView->setDragDropMode(QAbstractItemView::DragDrop); + //myView->setDragDropMode(QAbstractItemView::InternalMove); + mySearchTool = new QtxSearchTool( this, myView ); mySearchTool->setFrameStyle( QFrame::NoFrame | QFrame::Plain ); mySearchTool->setActivators( QtxSearchTool::StandardKey | QtxSearchTool::SlashKey ); @@ -165,7 +171,6 @@ OB_Browser::OB_Browser( QWidget* parent, QAbstractItemModel* model ) connect( myView, SIGNAL( selectionChanged() ), this, SIGNAL( selectionChanged() ) ); - } /*! diff --git a/src/ObjBrowser/OB_Browser.h b/src/ObjBrowser/OB_Browser.h index 6713a9ac1..252914b4c 100755 --- a/src/ObjBrowser/OB_Browser.h +++ b/src/ObjBrowser/OB_Browser.h @@ -18,11 +18,10 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : OB_Browser.h // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #ifndef OB_BROWSER_H #define OB_BROWSER_H @@ -70,7 +69,7 @@ public: QtxSearchTool* searchTool() const; bool isSearchToolEnabled() const; void setSearchToolEnabled( const bool ); - + int autoOpenLevel() const; void setAutoOpenLevel( const int ); void openLevels( const int = -1 ); @@ -105,7 +104,7 @@ public: unsigned long getModifiedTime() const; void setModified(); - + // san - moved to SUIT_TreeModel //OB_Updater* getUpdater() const; //virtual void setUpdater( OB_Updater* theUpdate = 0 ); @@ -120,10 +119,10 @@ signals: private slots: void onExpandAll(); void onCollapseAll(); - //void onDestroyed( SUIT_DataObject* ); - //void onDoubleClicked ( QListViewItem* ); - //void onDropped( QPtrList, QListViewItem*, int ); - + //void onDestroyed( SUIT_DataObject* ); + //void onDoubleClicked ( QListViewItem* ); + //void onDropped( QPtrList, QListViewItem*, int ); + protected: //void adjustWidth( QListViewItem* ); //virtual void updateText(); diff --git a/src/SUIT/SUIT_DataObject.cxx b/src/SUIT/SUIT_DataObject.cxx index 1d1b4ec9e..aa6e2bd29 100755 --- a/src/SUIT/SUIT_DataObject.cxx +++ b/src/SUIT/SUIT_DataObject.cxx @@ -18,11 +18,9 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : SUIT_DataObject.cxx // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// #include @@ -579,17 +577,14 @@ bool SUIT_DataObject::isDragable() const } /*! - \brief Check if the drop operation fo this object is possible. + \brief Check if the drop operation for this object is possible. This method can be re-implemented in the subclasses. Default implementation returns \c false (drop operation is not allowed). - \param obj object being dropped - \return \c true if it is possible to drop an object \c obj - to this object + \return \c true if it is possible to drop one or more objects (currently selected) to this object */ - -bool SUIT_DataObject::isDropAccepted( SUIT_DataObject* /*obj*/ ) +bool SUIT_DataObject::isDropAccepted() { return false; } diff --git a/src/SUIT/SUIT_DataObject.h b/src/SUIT/SUIT_DataObject.h index 62e95bc71..8f35fb66e 100755 --- a/src/SUIT/SUIT_DataObject.h +++ b/src/SUIT/SUIT_DataObject.h @@ -18,11 +18,10 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : SUIT_DataObject.h // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #ifndef SUIT_DATAOBJECT_H #define SUIT_DATAOBJECT_H @@ -45,13 +44,13 @@ typedef QList DataObjectList; #pragma warning( disable:4251 ) #endif -class SUIT_EXPORT SUIT_DataObject +class SUIT_EXPORT SUIT_DataObject { public: class Signal; //! Color role - typedef enum { + typedef enum { Text, //!< editor foreground (text) color Base, //!< editor background color Foreground, //!< foreground (text) color @@ -62,7 +61,7 @@ public: //! Column id enum - { + { NameId, //!< name column VisibilityId //!< visibility state column }; @@ -88,7 +87,7 @@ public: virtual void children( DataObjectList&, const bool = false ) const; virtual DataObjectList children( const bool = false ); - + void appendChild( SUIT_DataObject* ); virtual void insertChild( SUIT_DataObject*, int ); virtual void removeChild( SUIT_DataObject*, const bool = false ); @@ -116,7 +115,7 @@ public: virtual bool expandable() const; virtual bool isVisible() const; virtual bool isDragable() const; - virtual bool isDropAccepted( SUIT_DataObject* obj ); + virtual bool isDropAccepted(); virtual bool isEnabled() const; virtual bool isSelectable() const; @@ -135,7 +134,7 @@ public: virtual bool compare( const QVariant&, const QVariant&, const int = NameId ) const; virtual SUIT_DataObjectKey* key() const; - virtual int groupId() const; + virtual int groupId() const; virtual QVariant customData(Qtx::CustomDataType /*type*/); static Signal* signal(); diff --git a/src/SUIT/SUIT_TreeModel.cxx b/src/SUIT/SUIT_TreeModel.cxx index 6ee08e2b0..a6ff0c455 100755 --- a/src/SUIT/SUIT_TreeModel.cxx +++ b/src/SUIT/SUIT_TreeModel.cxx @@ -15,20 +15,19 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: SUIT_TreeModel.cxx // Author: Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #include "SUIT_Session.h" #include "SUIT_TreeModel.h" #include "SUIT_TreeSync.h" #include "SUIT_DataObject.h" #include "SUIT_ResourceMgr.h" - #include #include +#include SUIT_AbstractModel::SUIT_AbstractModel() : mySearcher( 0 ) { @@ -798,6 +797,8 @@ QVariant SUIT_TreeModel::data( const QModelIndex& index, int role ) const return QVariant(); SUIT_DataObject* obj = object( index ); + if ( !obj ) + return QVariant(); QColor c; QVariant val; @@ -970,6 +971,7 @@ bool SUIT_TreeModel::setData( const QModelIndex& index, */ Qt::ItemFlags SUIT_TreeModel::flags( const QModelIndex& index ) const { + /* if ( !index.isValid() ) return 0; @@ -993,7 +995,67 @@ Qt::ItemFlags SUIT_TreeModel::flags( const QModelIndex& index ) const if ( obj->renameAllowed( index.column() ) ) f = f | Qt::ItemIsEditable; } + return f; + */ + + Qt::ItemFlags f = 0; + + if (!index.isValid()) + //return Qt::ItemIsDropEnabled; // items can be dropped into the top level of the model + return f; + + SUIT_DataObject* obj = object(index); + + if (obj) { + // data object is enabled + if (obj->isEnabled()) + f = f | Qt::ItemIsEnabled; + + // data object is selectable + if (obj->isSelectable()) + f = f | Qt::ItemIsSelectable; + + // data object is checkable + if (obj->isCheckable(index.column())) + f = f | Qt::ItemIsUserCheckable; + + // data object can be renamed + if (obj->renameAllowed(index.column())) + f = f | Qt::ItemIsEditable; + + // data object can be dragged + if (obj->isDragable()) + f = f | Qt::ItemIsDragEnabled; + + // another data object(s) can be dropped on this one + if (obj->isDropAccepted()) + f = f | Qt::ItemIsDropEnabled; + } + + return f; +} + +Qt::DropActions SUIT_TreeModel::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +//This function is never called +bool SUIT_TreeModel::removeRows(int row, int count, const QModelIndex &parent) +{ + qDebug("Remove"); + if (parent.isValid()) + return FALSE; + + beginRemoveRows(parent, row, row + count - 1); + + for (int i = 0; i < count; ++i){ + //delete m_pAllData->takeAt(row); + } + + endRemoveRows(); + return TRUE; } /*! @@ -1612,9 +1674,52 @@ void SUIT_TreeModel::onRemoved( SUIT_DataObject* /*object*/, SUIT_DataObject* pa updateTree( parent ); } +/*! + \brief Drag and Drop support. +*/ +QStringList SUIT_TreeModel::mimeTypes() const +{ + QStringList types; + types << "application/vnd.text.list"; + return types; +} + +/*! + \brief Called when the data objects are exported(dragged) from the tree. + \param indexes the list of exported objects +*/ +QMimeData* SUIT_TreeModel::mimeData (const QModelIndexList &indexes) const +{ + QMimeData *mimeData = new QMimeData(); + QByteArray encodedData; + + QDataStream stream (&encodedData, QIODevice::WriteOnly); + + foreach (QModelIndex index, indexes) { + if (index.isValid()) { + if (index.column() == 0) { + SUIT_DataObject* aDObj = object(index); + QString anEntry = aDObj->text(SUIT_DataObject::VisibilityId + 1); + stream << anEntry; + } + } + } + + mimeData->setData("application/vnd.text.list", encodedData); + return mimeData; +} + +bool SUIT_TreeModel::dropMimeData (const QMimeData* data, Qt::DropAction action, + int row, int column, const QModelIndex& parent) +{ + emit dropped(data, action, row, column, parent); + + return true; +} + /*! \class SUIT_ProxyModel - \brief Proxy model which can be used above the SUIT_TreeMovel class + \brief Proxy model which can be used above the SUIT_TreeModel class to enable custom sorting/filtering of the data. The SUIT_TreeModel class does not support custom sorting/filtering of the data. @@ -1633,6 +1738,9 @@ SUIT_ProxyModel::SUIT_ProxyModel( QObject* parent ) SUIT_TreeModel* model = new SUIT_TreeModel( this ); connect( model, SIGNAL( modelUpdated() ), this, SIGNAL( modelUpdated() ) ); connect( model, SIGNAL( clicked(SUIT_DataObject*, int) ), this, SIGNAL(clicked(SUIT_DataObject*, int) ) ); + connect( model, SIGNAL( dropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&) ), + //this, SIGNAL( dropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&) )); + this, SLOT( onDropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&) )); setSourceModel( model ); setDynamicSortFilter( true ); } @@ -1649,6 +1757,9 @@ SUIT_ProxyModel::SUIT_ProxyModel( SUIT_DataObject* root, QObject* parent ) SUIT_TreeModel* model = new SUIT_TreeModel( root, this ); connect( model, SIGNAL( modelUpdated() ), this, SIGNAL( modelUpdated() ) ); connect( model, SIGNAL( clicked(SUIT_DataObject*, int) ), this, SIGNAL(clicked(SUIT_DataObject*, int) ) ); + connect( model, SIGNAL( dropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&) ), + //this, SIGNAL( dropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&) )); + this, SLOT( onDropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&) )); setSourceModel( model ); setDynamicSortFilter( true ); } @@ -1664,6 +1775,9 @@ SUIT_ProxyModel::SUIT_ProxyModel( SUIT_AbstractModel* model, QObject* parent ) { connect( *model, SIGNAL( modelUpdated() ), this, SIGNAL( modelUpdated() ) ); connect( *model, SIGNAL( clicked(SUIT_DataObject*, int) ), this, SIGNAL(clicked(SUIT_DataObject*, int) ) ); + connect( *model, SIGNAL( dropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&) ), + //this, SIGNAL( dropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&) )); + this, SLOT( onDropped(const QMimeData*, Qt::DropAction, int, int, const QModelIndex&) )); setSourceModel( *model ); setDynamicSortFilter( true ); } @@ -2061,6 +2175,12 @@ void SUIT_ProxyModel::emitClicked( SUIT_DataObject* obj, const QModelIndex& inde treeModel()->emitClicked(obj,index); } +void SUIT_ProxyModel::onDropped (const QMimeData* data, Qt::DropAction action, + int row, int column, const QModelIndex& parent) +{ + emit dropped(data, action, row, column, mapFromSource(parent)); +} + /*! \class SUIT_ItemDelegate \brief An SUIT_DataObject-based item delegate class. diff --git a/src/SUIT/SUIT_TreeModel.h b/src/SUIT/SUIT_TreeModel.h index 0a54db529..8a259da3b 100755 --- a/src/SUIT/SUIT_TreeModel.h +++ b/src/SUIT/SUIT_TreeModel.h @@ -15,11 +15,10 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: SUIT_TreeModel.h // Author: Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #ifndef SUIT_TREEMODEL_H #define SUIT_TREEMODEL_H @@ -40,6 +39,7 @@ class SUIT_DataObject; class SUIT_TreeModel; +class QMimeData; class SUIT_EXPORT SUIT_DataSearcher { @@ -137,6 +137,9 @@ public: virtual Qt::ItemFlags flags( const QModelIndex& ) const; virtual QVariant headerData( int, Qt::Orientation, int = Qt::DisplayRole ) const; + virtual Qt::DropActions supportedDropActions() const; + virtual bool removeRows(int row, int count, const QModelIndex &parent); + virtual QModelIndex index( int, int, const QModelIndex& = QModelIndex() ) const; virtual QModelIndex parent( const QModelIndex& ) const; @@ -176,6 +179,11 @@ public: virtual void updateTreeModel(SUIT_DataObject*,TreeItem*); + virtual QStringList mimeTypes() const; + virtual QMimeData* mimeData (const QModelIndexList& indexes) const; + virtual bool dropMimeData (const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent); + public slots: virtual void updateTree( const QModelIndex& ); virtual void updateTree( SUIT_DataObject* = 0 ); @@ -183,6 +191,7 @@ public slots: signals: void modelUpdated(); void clicked( SUIT_DataObject*, int ); + void dropped( const QMimeData*, Qt::DropAction, int, int, const QModelIndex& ); private: void initialize(); @@ -278,10 +287,12 @@ public slots: virtual void updateTree( const QModelIndex& ); virtual void updateTree( SUIT_DataObject* = 0 ); void setSortingEnabled( bool ); + void onDropped( const QMimeData*, Qt::DropAction, int, int, const QModelIndex& ); signals: void modelUpdated(); void clicked( SUIT_DataObject*, int ); + void dropped( const QMimeData*, Qt::DropAction, int, int, const QModelIndex& ); protected: SUIT_AbstractModel* treeModel() const; diff --git a/src/SalomeApp/SalomeApp_DataModel.cxx b/src/SalomeApp/SalomeApp_DataModel.cxx index 55d570084..351de88dc 100644 --- a/src/SalomeApp/SalomeApp_DataModel.cxx +++ b/src/SalomeApp/SalomeApp_DataModel.cxx @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: SalomeApp_DataModel.cxx // Created: 10/25/2004 10:36:06 AM // Author: Sergey LITONIN -// + #include "SalomeApp_DataModel.h" #include "SalomeApp_Study.h" #include "SalomeApp_DataObject.h" @@ -191,11 +190,20 @@ QList SalomeApp_DataModelSync::children( const kerPtr& obj ) const _PTR(AttributeExpandable) aAttrExp = anAttr; expandable = aAttrExp->IsExpandable(); } - + if ( expandable ) { - _PTR(ChildIterator) it ( myStudy->NewChildIterator( obj ) ); - for ( ; it->More(); it->Next() ) - ch.append( it->Value() ); + // tmp?? + _PTR(UseCaseBuilder) aUseCaseBuilder = myStudy->GetUseCaseBuilder(); + if (aUseCaseBuilder->HasChildren(obj)) { + _PTR(UseCaseIterator) it ( aUseCaseBuilder->GetUseCaseIterator( obj ) ); + for ( ; it->More(); it->Next() ) + ch.append( it->Value() ); + } + else { + _PTR(ChildIterator) it ( myStudy->NewChildIterator( obj ) ); + for ( ; it->More(); it->Next() ) + ch.append( it->Value() ); + } } return ch; diff --git a/src/SalomeApp/SalomeApp_DataObject.cxx b/src/SalomeApp/SalomeApp_DataObject.cxx index e04a29232..fa5cd5a52 100644 --- a/src/SalomeApp/SalomeApp_DataObject.cxx +++ b/src/SalomeApp/SalomeApp_DataObject.cxx @@ -365,13 +365,22 @@ _PTR(SObject) SalomeApp_DataObject::referencedObject() const bool SalomeApp_DataObject::hasChildren() const { bool ok = false; - _PTR(ChildIterator) it ( myObject->GetStudy()->NewChildIterator( myObject ) ); - for ( ; it->More() && !ok; it->Next() ) { - _PTR(SObject) obj = it->Value(); - if ( obj ) { - _PTR(SObject) refObj; - //if ( obj->ReferencedObject( refObj ) ) continue; // omit references - if ( obj->GetName() != "" ) ok = true; + + // tmp?? + _PTR(UseCaseBuilder) aUseCaseBuilder = myObject->GetStudy()->GetUseCaseBuilder(); + if (aUseCaseBuilder->IsUseCaseNode(myObject)) { + ok = aUseCaseBuilder->HasChildren(myObject); + // TODO: check name as below? + } + else { + _PTR(ChildIterator) it ( myObject->GetStudy()->NewChildIterator( myObject ) ); + for ( ; it->More() && !ok; it->Next() ) { + _PTR(SObject) obj = it->Value(); + if ( obj ) { + _PTR(SObject) refObj; + //if ( obj->ReferencedObject( refObj ) ) continue; // omit references + if ( obj->GetName() != "" ) ok = true; + } } } return ok; diff --git a/src/SalomeApp/SalomeApp_DataObject.h b/src/SalomeApp/SalomeApp_DataObject.h index c9e23bc3d..dc4f28984 100644 --- a/src/SalomeApp/SalomeApp_DataObject.h +++ b/src/SalomeApp/SalomeApp_DataObject.h @@ -18,11 +18,10 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File : SalomeApp_DataObject.h // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// + #ifndef SALOMEAPP_DATAOBJECT_H #define SALOMEAPP_DATAOBJECT_H diff --git a/src/SalomeApp/SalomeApp_Module.cxx b/src/SalomeApp/SalomeApp_Module.cxx index cd88200d8..59efa951b 100644 --- a/src/SalomeApp/SalomeApp_Module.cxx +++ b/src/SalomeApp/SalomeApp_Module.cxx @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: SalomeApp_Module.cxx // Created: 10/25/2004 11:39:56 AM // Author: Sergey LITONIN -// + #include "SalomeApp_Module.h" #include "SalomeApp_DataModel.h" #include "SalomeApp_Application.h" @@ -294,4 +293,4 @@ void SalomeApp_Module::updateModuleVisibilityState() { if ( SUIT_ViewManager* vman = app->activeViewManager() ) vmod = vman->getViewModel(); app->updateVisibilityState( listObj, vmod ); -} \ No newline at end of file +} diff --git a/src/SalomeApp/SalomeApp_Module.h b/src/SalomeApp/SalomeApp_Module.h index cfe8f0933..307bf04c1 100644 --- a/src/SalomeApp/SalomeApp_Module.h +++ b/src/SalomeApp/SalomeApp_Module.h @@ -18,12 +18,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// // File: SalomeApp_Module.h // Created: 10/25/2004 11:33:06 AM // Author: Sergey LITONIN -// + #ifndef SALOMEAPP_MODULE_H #define SALOMEAPP_MODULE_H diff --git a/src/SalomeApp/SalomeApp_Study.cxx b/src/SalomeApp/SalomeApp_Study.cxx index 6f11cdaf5..c0bd439b4 100644 --- a/src/SalomeApp/SalomeApp_Study.cxx +++ b/src/SalomeApp/SalomeApp_Study.cxx @@ -18,7 +18,6 @@ // 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 "SalomeApp_Study.h" @@ -80,7 +79,7 @@ public: myStudy=aStudy; fillEntryMap(); } - + SUIT_DataObject* findObject( const char* theID ) const { EntryMap::const_iterator it = entry2SuitObject.find( theID ); @@ -98,7 +97,7 @@ public: virtual bool event(QEvent *event) { - if (event->type() == QEvent::User ) + if (event->type() == QEvent::User ) { //START_TIMING(notify); notifyObserverID_real(static_cast(event)->_anID.c_str(),static_cast(event)->_event); @@ -110,96 +109,164 @@ public: void notifyObserverID_real(const std::string& theID, long event) { SalomeApp_DataObject* suit_obj = 0; - - switch(event) { - case 1: + + switch(event) { + case 1: { //Add sobject - EntryMapIter it = entry2SuitObject.find( theID ); - if ( it != entry2SuitObject.end() ) - { - MESSAGE("Entry " << theID << " is already added. Problem ??"); + _PTR(SObject) aSObj = myStudyDS->FindObjectID(theID); + _PTR(SComponent) aSComp = aSObj->GetFatherComponent(); + + if (!aSComp || aSComp->IsNull()) { + MESSAGE("Entry " << theID << " has not father component. Problem ??"); return; } - _PTR(SObject) obj = myStudyDS->FindObjectID( theID ); - int last2Pnt_pos = theID.rfind( ":" ); - std::string parent_id = theID.substr( 0, last2Pnt_pos ); - int tag = atoi( theID.substr( last2Pnt_pos+1 ).c_str() ); - - if ( parent_id.length() == 3 ) // "0:1" - root item? - { - // It's probably a SComponent - _PTR(SComponent) aSComp = obj->GetFatherComponent(); - if ( aSComp && !aSComp->IsNull() && aSComp->GetID() == theID ) - suit_obj = new SalomeApp_ModuleObject( aSComp ); - else - suit_obj = new SalomeApp_DataObject( obj ); - } - else - { - suit_obj = new SalomeApp_DataObject( obj ); - } - - it = entry2SuitObject.find( parent_id ); - if ( it != entry2SuitObject.end() ) - { - SalomeApp_DataObject* father = it->second; - father->insertChildAtTag( suit_obj, tag ); - } - else - { + + // Mantis issue 0020136: Drag&Drop in OB + _PTR(UseCaseBuilder) aUseCaseBuilder = myStudyDS->GetUseCaseBuilder(); + if (aUseCaseBuilder->IsUseCaseNode(aSComp)) { // BEGIN: work with tree nodes structure + if (!aUseCaseBuilder->IsUseCaseNode(aSObj)) { + // tree node is not yet set, it is a normal situation + return; + } + + _PTR(SObject) aFatherSO = aUseCaseBuilder->GetFather(aSObj); + if (!aFatherSO || aFatherSO->IsNull()) { + MESSAGE("Father SObject is not found. Problem ??"); + return; + } + + std::string parent_id = aFatherSO->GetID(); + EntryMapIter it = entry2SuitObject.find(parent_id.c_str()); + + if (it == entry2SuitObject.end()) { + MESSAGE("Father data object is not found. Problem ??"); + return; + } + + SalomeApp_DataObject* aFatherDO = it->second; + + it = entry2SuitObject.find(theID); + if (it != entry2SuitObject.end()) { // this SOobject is already added somethere + // tmp?? + suit_obj = it->second; + SUIT_DataObject* oldFather = suit_obj->parent(); + if (oldFather) { + oldFather->removeChild(suit_obj, false); + + suit_obj->updateItem(); // tmp?? + if (SalomeApp_DataObject* oldFatherSA = dynamic_cast(oldFather)) { + oldFatherSA->updateItem(); // tmp?? + } + + //entry2SuitObject.erase(it); + ////delete suit_obj; + //suit_obj = new SalomeApp_DataObject(aSObj); + //entry2SuitObject[theID] = suit_obj; + } + } + else { + suit_obj = new SalomeApp_DataObject(aSObj); + entry2SuitObject[theID] = suit_obj; + } + + // define position in the data tree (in aFatherDO) to insert the aSObj + int pos = -1; + //int childDataObjCount = aFatherDO->childCount(); + _PTR(UseCaseIterator) aUseCaseIter = aUseCaseBuilder->GetUseCaseIterator(aFatherSO); + for (int cur = 0; aUseCaseIter->More() && pos < 0; cur++, aUseCaseIter->Next()) { + if (aUseCaseIter->Value()->GetID() == theID) { + pos = cur; + break; + } + } + + //aFatherDO->insertChildAtPos(suit_obj, pos); + aFatherDO->insertChild(suit_obj, pos); + aFatherDO->updateItem(); // tmp?? + + } // END: work with tree nodes structure + else { // BEGIN: work with study structure + EntryMapIter it = entry2SuitObject.find( theID ); + if ( it != entry2SuitObject.end() ) { + MESSAGE("Entry " << theID << " is already added. Problem ??"); + return; + } + + int last2Pnt_pos = theID.rfind( ":" ); + std::string parent_id = theID.substr( 0, last2Pnt_pos ); + int tag = atoi( theID.substr( last2Pnt_pos+1 ).c_str() ); + if ( parent_id.length() == 3 ) // "0:1" - root item? { - // This should be for a module - SUIT_DataObject* father=myStudy->root(); - father->appendChild(suit_obj); + // It's probably a SComponent + if ( theID == aSComp->GetID() ) + suit_obj = new SalomeApp_ModuleObject( aSComp ); + else + suit_obj = new SalomeApp_DataObject( aSObj ); } else { - MESSAGE("SHOULD NEGER GET HERE!!!"); - - //Try to find the SalomeApp_DataObject object parent - std::string root_id = parent_id.substr( 0, 4 ); - std::string obj_id = parent_id.substr( 4 ); - - std::string anID; - std::string::size_type debut = 0; - std::string::size_type fin; - SalomeApp_DataObject* anObj = dynamic_cast( myStudy->root() ); - while ( 1 ) + suit_obj = new SalomeApp_DataObject( aSObj ); + } + + it = entry2SuitObject.find( parent_id ); + if ( it != entry2SuitObject.end() ) { + SalomeApp_DataObject* father = it->second; + father->insertChildAtTag( suit_obj, tag ); + } + else { + if ( parent_id.length() == 3 ) // "0:1" - root item? { - fin = obj_id.find_first_of( ':', debut ); - if ( fin == std::string::npos ) - { - //last id - anObj = dynamic_cast( anObj->childObject( atoi( obj_id.substr( debut ).c_str() )-1 ) ); - entry2SuitObject[parent_id] = anObj; - break; - } - anID = root_id + obj_id.substr( 0, fin ); - EntryMapIter it2 = entry2SuitObject.find( anID ); - if ( it2 == entry2SuitObject.end() ) - { - //the ID is not known in entry2SuitObject - anObj = dynamic_cast( anObj->childObject( atoi( obj_id.substr( debut, fin-debut ).c_str() )-1 ) ); - entry2SuitObject[anID] = anObj; + // This should be for a module + SUIT_DataObject* father=myStudy->root(); + father->appendChild(suit_obj); + } + else + { + MESSAGE("SHOULD NEVER GET HERE!!!"); + + //Try to find the SalomeApp_DataObject object parent + std::string root_id = parent_id.substr( 0, 4 ); + std::string obj_id = parent_id.substr( 4 ); + + std::string anID; + std::string::size_type debut = 0; + std::string::size_type fin; + SalomeApp_DataObject* anObj = dynamic_cast( myStudy->root() ); + while ( 1 ) { + fin = obj_id.find_first_of( ':', debut ); + if ( fin == std::string::npos ) { + //last id + anObj = dynamic_cast(anObj->childObject(atoi(obj_id.substr(debut).c_str())-1)); + entry2SuitObject[parent_id] = anObj; + break; + } + anID = root_id + obj_id.substr( 0, fin ); + EntryMapIter it2 = entry2SuitObject.find( anID ); + if ( it2 == entry2SuitObject.end() ) { + //the ID is not known in entry2SuitObject + anObj = dynamic_cast(anObj->childObject(atoi(obj_id.substr(debut, fin-debut).c_str())-1)); + entry2SuitObject[anID] = anObj; + } + else + anObj = it2->second; + debut = fin+1; } - else - anObj = it2->second; - debut = fin+1; + anObj->insertChildAtTag( suit_obj, tag ); } - anObj->insertChildAtTag( suit_obj, tag ); } - } - entry2SuitObject[theID] = suit_obj; + entry2SuitObject[theID] = suit_obj; + } // END: work with study structure break; - } - case 2: + } + case 2: { // Remove sobject EntryMapIter it = entry2SuitObject.find( theID ); if ( it != entry2SuitObject.end() ) { suit_obj = it->second; - // VSR: object is not removed, since SALOMEDS::SObject is not actually removed, only its attributes are cleared; + // VSR: object is not removed, since SALOMEDS::SObject is not actually removed, + // only its attributes are cleared; // thus, the object can be later reused suit_obj->updateItem(); //SUIT_DataObject* father=suit_obj->parent(); @@ -213,7 +280,7 @@ public: } break; } - case 0: + case 0: { //modify sobject //MESSAGE("Want to modify an object " << theID); EntryMapIter it = entry2SuitObject.find( theID ); @@ -231,20 +298,21 @@ public: case 5: //IOR of the object modified { EntryMapIter it = entry2SuitObject.find( theID ); - if ( it != entry2SuitObject.end() ) + if ( it != entry2SuitObject.end() ) suit_obj = it->second; - + /* Define visibility state */ - bool isComponent = dynamic_cast( suit_obj ) != 0; + bool isComponent = dynamic_cast( suit_obj ) != 0; if ( suit_obj && !isComponent ) { QString moduleTitle = ((CAM_Application*)myStudy->application())->moduleTitle(suit_obj->componentDataType()); if (!moduleTitle.isEmpty()) { LightApp_Displayer* aDisplayer = LightApp_Displayer::FindDisplayer(moduleTitle,false); - if(aDisplayer) { + if (aDisplayer) { if(aDisplayer->canBeDisplayed(theID.c_str())) { myStudy->setVisibilityState( theID.c_str(), Qtx::HiddenState ); //MESSAGE("Object with entry : "<< theID <<" CAN be displayed !!!"); - } else + } + else MESSAGE("Object with entry : "<< theID <<" CAN'T be displayed !!!"); } } @@ -253,9 +321,9 @@ public: } default:MESSAGE("Unknown event: " << event);break; } //switch - } //notifyObserverID + } //notifyObserverID_real -private: +private: void fillEntryMap() { entry2SuitObject.clear(); @@ -287,7 +355,7 @@ private: } } } - + private: _PTR(Study) myStudyDS; SalomeApp_Study* myStudy; @@ -301,7 +369,7 @@ private: SalomeApp_Study::SalomeApp_Study( SUIT_Application* app ) : LightApp_Study( app ), myObserver( 0 ) { -} +} /*! Destructor. @@ -376,10 +444,10 @@ bool SalomeApp_Study::createDocument( const QString& theStr ) #ifdef WITH_SALOMEDS_OBSERVER myObserver = new Observer_i(myStudyDS,this); - //attach an observer to the study with notification of modifications + //attach an observer to the study with notification of modifications myStudyDS->attach(myObserver->_this(),true); #endif - + return aRet; } @@ -404,23 +472,23 @@ bool SalomeApp_Study::openDocument( const QString& theFileName ) ModelList dm_s; dataModels( dm_s ); QListIterator it( dm_s ); - while ( it.hasNext() ) + while ( it.hasNext() ) openDataModel( studyName(), it.next() ); - + // this will build a SUIT_DataObject-s tree under myRoot member field // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step - // but tree that corresponds to not-loaded data models will be updated any way. - ((SalomeApp_Application*)application())->updateObjectBrowser( false ); + // but tree that corresponds to not-loaded data models will be updated any way. + ((SalomeApp_Application*)application())->updateObjectBrowser( false ); #ifdef WITH_SALOMEDS_OBSERVER dynamic_cast( root() )->setToSynchronize(false); myObserver = new Observer_i(myStudyDS,this); - //attach an observer to the study with notification of modifications + //attach an observer to the study with notification of modifications myStudyDS->attach(myObserver->_this(),true); #endif bool res = CAM_Study::openDocument( theFileName ); - + emit opened( this ); study->IsSaved(true); @@ -431,7 +499,7 @@ bool SalomeApp_Study::openDocument( const QString& theFileName ) SalomeApp_VisualState( (SalomeApp_Application*)application() ).restoreState( savePoints[savePoints.size()-1] ); } - ((SalomeApp_Application*)application())->updateObjectBrowser( true ); + ((SalomeApp_Application*)application())->updateObjectBrowser( true ); return res; } @@ -464,13 +532,13 @@ bool SalomeApp_Study::loadDocument( const QString& theStudyName ) // this will build a SUIT_DataObject-s tree under myRoot member field // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step - // but tree that corresponds to not-loaded data models will be updated any way. - ((SalomeApp_Application*)application())->updateObjectBrowser( false ); + // but tree that corresponds to not-loaded data models will be updated any way. + ((SalomeApp_Application*)application())->updateObjectBrowser( false ); #ifdef WITH_SALOMEDS_OBSERVER dynamic_cast( root() )->setToSynchronize(false); myObserver = new Observer_i(myStudyDS,this); - //attach an observer to the study with notification of modifications + //attach an observer to the study with notification of modifications myStudyDS->attach(myObserver->_this(),true); #endif @@ -497,7 +565,7 @@ bool SalomeApp_Study::saveDocumentAs( const QString& theFileName ) bool store = application()->resourceMgr()->booleanValue( "Study", "store_visual_state", false ); if ( store ) SalomeApp_VisualState( (SalomeApp_Application*)application() ).storeState(); - + ModelList list; dataModels( list ); QListIterator it( list ); @@ -518,11 +586,11 @@ bool SalomeApp_Study::saveDocumentAs( const QString& theFileName ) bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ); bool isAscii = resMgr->booleanValue( "Study", "ascii_file", false ); - bool res = (isAscii ? + bool res = (isAscii ? SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.toStdString(), studyDS(), isMultiFile ) : SalomeApp_Application::studyMgr()->SaveAs ( theFileName.toStdString(), studyDS(), isMultiFile )) && CAM_Study::saveDocumentAs( theFileName ); - + res = res && saveStudyData(theFileName); if ( res ) @@ -548,7 +616,7 @@ bool SalomeApp_Study::saveDocument() if ( SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)it.next() ) { listOfFiles.clear(); aModel->save(listOfFiles); - if ( !listOfFiles.isEmpty() ) + if ( !listOfFiles.isEmpty() ) saveModuleData(aModel->module()->name(), listOfFiles); } } @@ -560,13 +628,13 @@ bool SalomeApp_Study::saveDocument() bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ); bool isAscii = resMgr->booleanValue( "Study", "ascii_file", false ); - bool res = (isAscii ? + bool res = (isAscii ? SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) : SalomeApp_Application::studyMgr()->Save ( studyDS(), isMultiFile )) && CAM_Study::saveDocument(); res = res && saveStudyData(studyName()); if ( res ) - emit saved( this ); + emit saved( this ); return res; } @@ -599,7 +667,7 @@ bool SalomeApp_Study::isModified() const if (!isAnyChanged) isAnyChanged = LightApp_Study::isModified(); - return isAnyChanged; + return isAnyChanged; } /*! @@ -621,7 +689,7 @@ bool SalomeApp_Study::isSaved() const if (!isAllSaved) isAllSaved = LightApp_Study::isSaved(); - return isAllSaved; + return isAllSaved; } /*! @@ -718,7 +786,7 @@ void SalomeApp_Study::addComponent(const CAM_DataModel* dm) if (!aModule) { // Check SComponent existance _PTR(Study) aStudy = studyDS(); - if (!aStudy) + if (!aStudy) return; _PTR(SComponent) aComp = aStudy->FindComponent(dm->module()->name().toStdString()); if (!aComp) { @@ -977,7 +1045,7 @@ void SalomeApp_Study::children( const QString& entry, QStringList& child_entries */ void SalomeApp_Study::components( QStringList& comps ) const { - for( _PTR(SComponentIterator) it ( studyDS()->NewComponentIterator() ); it->More(); it->Next() ) + for( _PTR(SComponentIterator) it ( studyDS()->NewComponentIterator() ); it->More(); it->Next() ) { _PTR(SComponent) aComponent ( it->Value() ); // skip the magic "Interface Applicative" component @@ -994,7 +1062,7 @@ void SalomeApp_Study::components( QStringList& comps ) const QString SalomeApp_Study::centry( const QString& comp ) const { QString e; - for( _PTR(SComponentIterator) it ( studyDS()->NewComponentIterator() ); it->More() && e.isEmpty(); it->Next() ) + for( _PTR(SComponentIterator) it ( studyDS()->NewComponentIterator() ); it->More() && e.isEmpty(); it->Next() ) { _PTR(SComponent) aComponent ( it->Value() ); if ( aComponent && comp == aComponent->ComponentDataType().c_str() ) diff --git a/src/Session/SALOME_Session_Server.cxx b/src/Session/SALOME_Session_Server.cxx index 84bf89adb..3dd788625 100755 --- a/src/Session/SALOME_Session_Server.cxx +++ b/src/Session/SALOME_Session_Server.cxx @@ -277,6 +277,14 @@ public: catch (std::exception& e) { std::cerr << e.what() << std::endl; } + catch (CORBA::Exception& e) { + std::cerr << "Caught CORBA::Exception" << std::endl; + CORBA::Any tmp; + tmp<<= e; + CORBA::TypeCode_var tc = tmp.type(); + const char *p = tc->name(); + std::cerr << "notify(): CORBA exception of the kind : " << p << " is caught" << std::endl; + } catch (...) { std::cerr << "Unknown exception caught in Qt handler: it's probably a bug in SALOME platform" << std::endl; }