Drag and Drop provides a simple visual mechanism to transfer information between and within applications.
In some aspects Drag and drop operates similarly to the clipboard copy/cut/paste mechanism.
Since SALOME GUI is implemented on Qt, the drag and drop functionality support is provided by means of the corresponding Qt mechanisms.
Currently dragging and dropping of the items can be done within Object browser only, however this functionality can be extended to other GUI elements as well.
The Drag and drop functionality is enabled by default in the Object browser. However, to allow dragging of a data object or dropping data on it, it is necessary to redefine isDraggable()
and isDropAccepted()
methods of the corresponding class, a successor of the SUIT_DataObject
. These methods are defined in the base class SUIT_DataObject
and default implementation of both functions returns false
, which prevents dragging and dropping:
If your data model is based on the SUIT_DataObject
and SUIT_TreeModel
, just re-implement these functions in your successor data object class and return true
when it is needed (for example, depending on the data object type, state, etc).
Another alternative is available if your module is directly inherited from LightApp_Module
or SalomeApp_Module
class (as the majority of existing SALOME modules). The class LightApp_Module
(and thus SalomeApp_Module
also) already provides high-level API that can be used for enabling drag and drop functionality.
To enable dragging, redefine isDraggable()
method of your module class. In this method you can analyze the data object subject to the drag operation and decide if it is necessary to enable or prevent its dragging:
Note, that you should not invoke here method isDragEnabled()
of your data object class (in case if it inherits LightApp_DataObject
or SalomeApp_DataObject
), unless you redefine methods isDraggable()
and isDropAccepted()
in your data object class. The reason is that the implementation of these methods in LightApp_DataObject
class redirects calls to the LightApp_Module
- be careful to avoid entering endless recursion loop.
To allow data dropping to an object (the object under the mouse cursor in the Object browser during the drag operation) redefine isDropAccepted()
method of your module class:
The caution about avoiding recursive loop mentioned above is also valid for isDropAccepted()
method.
When dragging operation is completed (the data is dropped to an object) the module owning the item on which the data is dropped is notified by invoking its dropObjects()
method:
The default implementation does nothing. However, this method can be redifined in the successor class and handle the operation properly. The list of dropped data objects is passed via what
parameter. The data object on which the data is dropped is passed via where
parameter. The parameter row
specifies in the children list the position of object where data is dropped; if this parameter is equal to -1, the data is dropped to the end of the children list. Performed drop action is passed via action
parameter; possible values are Qt::CopyAction
and Qt::MoveAction
(other actions are currently unsupported).
The method dropObjects()
should analyze the parameters and apply the corresponding actions for rearrangement of the data tree, copying or moving the data items depending on the operation performed. For example:
In the above code the function copyOrMove()
performs actual data tree rearrangement.
The data model of the light (not having CORBA engine) SALOME module is usually based on the custom tree of data objects. The general approach is to inherit a custom data object class from the LightApp_DataObject
and a custom data model from the LightApp_DataModel
class. The data model class is responsible for building the appropriate presentation of the data tree in the Object browser.
Thus, the implementation of the drag and drop functionality in a light module (more precisely, the method dropObjects() as described above), consists in copying data entities (by creating new instances of the corresponding data object class) or moving existing data objects to the new position in a tree. The Object browser will update the tree representation automatically, as soon as updateObjectBrowser()
function is called.
Drag and drop operation requires underlying data model to allow flexible re-arrangement of the data entities inside the data tree. In a full (CORBA engine based) SALOME module, which data model is usually based on the hierarchy of SALOMEDS::SObject
entities provided by the data server functionality, re-arrangement of the data tree is not a trivial task.
However, SALOME data server (SALOMEDS
) CORBA module proposes a mechanism that can be used to customize data tree representation in a simple and flexible way - use case builder.
With use case builder, the dropObjects()
function can be easily implemented. For example: