347 changes: 200 additions & 147 deletions python/plugins/sextante/modeler/ModelerDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,158 +25,206 @@

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore, QtGui

import codecs
import pickle

from sextante.core.SextanteUtils import SextanteUtils

from sextante.gui.HelpEditionDialog import HelpEditionDialog
from sextante.gui.ParametersDialog import ParametersDialog

from sextante.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
from sextante.modeler.ModelerAlgorithm import ModelerAlgorithm
from sextante.modeler.ModelerParametersDialog import ModelerParametersDialog
from sextante.modeler.ModelerUtils import ModelerUtils
from sextante.modeler.WrongModelException import WrongModelException
from sextante.modeler.ModelerScene import ModelerScene
from sextante.modeler.Providers import Providers
from sextante.gui.HelpEditionDialog import HelpEditionDialog
import pickle
from sextante.gui.ParametersDialog import ParametersDialog
from sextante.core.SextanteUtils import SextanteUtils
import codecs

class ModelerDialog(QtGui.QDialog):
from sextante.ui.ui_DlgModeler import Ui_DlgModeler

class ModelerDialog(QDialog, Ui_DlgModeler):
def __init__(self, alg=None):
QtGui.QDialog.__init__(self)
self.setupUi()
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint |
QtCore.Qt.WindowMinMaxButtonsHint)
QDialog.__init__(self)

self.setupUi(self)

self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint |
Qt.WindowMinMaxButtonsHint)

self.tabWidget.setCurrentIndex(0)

self.scene = ModelerScene(self)
self.scene.setSceneRect(QRectF(0, 0, 4000, 4000))
self.view.setScene(self.scene)
self.view.ensureVisible(0, 0, 10, 10)

# additional buttons
self.editHelpButton = QPushButton(self.tr("Edit model help"))
self.buttonBox.addButton(self.editHelpButton, QDialogButtonBox.ActionRole)
self.runButton = QPushButton(self.tr("Run"))
self.runButton.setToolTip(self.tr("Execute current model"))
self.buttonBox.addButton(self.runButton, QDialogButtonBox.ActionRole)
self.openButton = QPushButton(self.tr("Open"))
self.openButton.setToolTip(self.tr("Open existing model"))
self.buttonBox.addButton(self.openButton, QDialogButtonBox.ActionRole)
self.saveButton = QPushButton(self.tr("Save"))
self.saveButton.setToolTip(self.tr("Save current model"))
self.buttonBox.addButton(self.saveButton, QDialogButtonBox.ActionRole)

# fill trees with inputs and algorithms
self.fillInputsTree()
self.fillAlgorithmTree()

if hasattr(self.searchBox, 'setPlaceholderText'):
self.searchBox.setPlaceholderText(self.tr("Search..."))
if hasattr(self.textName, 'setPlaceholderText'):
self.textName.setPlaceholderText("[Enter model name here]")
if hasattr(self.textGroup, 'setPlaceholderText'):
self.textGroup.setPlaceholderText("[Enter group name here]")

# connect signals and slots
self.inputsTree.doubleClicked.connect(self.addInput)

self.searchBox.textChanged.connect(self.fillAlgorithmTree)
self.algorithmTree.doubleClicked.connect(self.addAlgorithm)

self.openButton.clicked.connect(self.openModel)
self.saveButton.clicked.connect(self.saveModel)
self.runButton.clicked.connect(self.runModel)
self.editHelpButton.clicked.connect(self.editHelp)

if alg is not None:
self.alg = alg
self.textGroup.setText(alg.group)
self.textName.setText(alg.name)
self.repaintModel()
else:
self.alg = ModelerAlgorithm()

self.view.centerOn(0, 0)
self.alg.setModelerView(self)
self.help = None
self.update = False #indicates whether to update or not the toolbox after closing this dialog

def setupUi(self):
self.resize(1000, 600)
self.setWindowTitle("SEXTANTE Modeler")
self.tabWidget = QtGui.QTabWidget()
self.tabWidget.setMaximumSize(QtCore.QSize(350, 10000))
self.tabWidget.setMinimumWidth(300)

#left hand side part
#==================================
self.inputsTree = QtGui.QTreeWidget()
self.inputsTree.setHeaderHidden(True)
self.fillInputsTree()
self.inputsTree.doubleClicked.connect(self.addInput)
self.tabWidget.addTab(self.inputsTree, "Inputs")

self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setSpacing(2)
self.verticalLayout.setMargin(0)
self.searchBox = QtGui.QLineEdit()
self.searchBox.textChanged.connect(self.fillAlgorithmTree)
self.verticalLayout.addWidget(self.searchBox)
self.algorithmTree = QtGui.QTreeWidget()
self.algorithmTree.setHeaderHidden(True)
self.fillAlgorithmTree()
self.verticalLayout.addWidget(self.algorithmTree)
self.algorithmTree.doubleClicked.connect(self.addAlgorithm)

self.algorithmsTab = QtGui.QWidget()
self.algorithmsTab.setLayout(self.verticalLayout)
self.tabWidget.addTab(self.algorithmsTab, "Algorithms")

#right hand side part
#==================================
self.textName = QtGui.QLineEdit()
if hasattr(self.textName, 'setPlaceholderText'):
self.textName.setPlaceholderText("[Enter model name here]")
self.textGroup = QtGui.QLineEdit()
if hasattr(self.textGroup, 'setPlaceholderText'):
self.textGroup.setPlaceholderText("[Enter group name here]")
self.horizontalLayoutNames = QtGui.QHBoxLayout()
self.horizontalLayoutNames.setSpacing(2)
self.horizontalLayoutNames.setMargin(0)
self.horizontalLayoutNames.addWidget(self.textName)
self.horizontalLayoutNames.addWidget(self.textGroup)

self.scene = ModelerScene(self)
self.scene.setSceneRect(QtCore.QRectF(0, 0, 4000, 4000))

self.canvasTabWidget = QtGui.QTabWidget()
self.canvasTabWidget.setMinimumWidth(300)
self.view = QtGui.QGraphicsView(self.scene)

#=======================================================================
# self.canvasTabWidget.addTab(self.view, "Design")
# self.pythonText = QtGui.QTextEdit()
# self.createScriptButton = QtGui.QPushButton()
# self.createScriptButton.setText("Create script from model code")
# self.createScriptButton.clicked.connect(self.createScript)
# self.verticalLayoutPython = QtGui.QVBoxLayout()
# self.verticalLayoutPython.setSpacing(2)
# self.verticalLayoutPython.setMargin(0)
# self.verticalLayoutPython.addWidget(self.pythonText)
# self.verticalLayoutPython.addWidget(self.createScriptButton)
# self.pythonWidget = QtGui.QWidget()
# self.pythonWidget.setLayout(self.verticalLayoutPython)
# self.canvasTabWidget.addTab(self.pythonWidget, "Python code")
#=======================================================================

self.canvasLayout = QtGui.QVBoxLayout()
self.canvasLayout.setSpacing(2)
self.canvasLayout.setMargin(0)
self.canvasLayout.addLayout(self.horizontalLayoutNames)
self.canvasLayout.addWidget(self.view)#canvasTabWidget)

#upper part, putting the two previous parts together
#===================================================
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setSpacing(2)
self.horizontalLayout.setMargin(0)
self.horizontalLayout.addWidget(self.tabWidget)
self.horizontalLayout.addLayout(self.canvasLayout)

#And the whole layout
#==========================

self.buttonBox = QtGui.QDialogButtonBox()
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.editHelpButton = QtGui.QPushButton()
self.editHelpButton.setText("Edit model help")
self.buttonBox.addButton(self.editHelpButton, QtGui.QDialogButtonBox.ActionRole)
self.runButton = QtGui.QPushButton()
self.runButton.setText("Run")
self.buttonBox.addButton(self.runButton, QtGui.QDialogButtonBox.ActionRole)
self.openButton = QtGui.QPushButton()
self.openButton.setText("Open")
self.buttonBox.addButton(self.openButton, QtGui.QDialogButtonBox.ActionRole)
self.saveButton = QtGui.QPushButton()
self.saveButton.setText("Save")
self.buttonBox.addButton(self.saveButton, QtGui.QDialogButtonBox.ActionRole)
self.closeButton = QtGui.QPushButton()
self.closeButton.setText("Close")
self.buttonBox.addButton(self.closeButton, QtGui.QDialogButtonBox.ActionRole)
QObject.connect(self.openButton, QtCore.SIGNAL("clicked()"), self.openModel)
QObject.connect(self.saveButton, QtCore.SIGNAL("clicked()"), self.saveModel)
QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), self.closeWindow)
QObject.connect(self.runButton, QtCore.SIGNAL("clicked()"), self.runModel)
QObject.connect(self.editHelpButton, QtCore.SIGNAL("clicked()"), self.editHelp)

self.globalLayout = QtGui.QVBoxLayout()
self.globalLayout.setSpacing(2)
self.globalLayout.setMargin(0)
self.globalLayout.addLayout(self.horizontalLayout)
self.globalLayout.addWidget(self.buttonBox)
self.setLayout(self.globalLayout)
QtCore.QMetaObject.connectSlotsByName(self)

self.view.ensureVisible(0, 0, 10, 10)

def closeWindow(self):
self.close()
#~ def setupUi(self):
#~ self.resize(1000, 600)
#~ self.setWindowTitle("SEXTANTE Modeler")
#~ self.tabWidget = QtGui.QTabWidget()
#~ self.tabWidget.setMaximumSize(QtCore.QSize(350, 10000))
#~ self.tabWidget.setMinimumWidth(300)
#~
#~ #left hand side part
#~ #==================================
#~ self.inputsTree = QtGui.QTreeWidget()
#~ self.inputsTree.setHeaderHidden(True)
#~ self.fillInputsTree()
#~ self.inputsTree.doubleClicked.connect(self.addInput)
#~ self.tabWidget.addTab(self.inputsTree, "Inputs")
#~
#~ self.verticalLayout = QtGui.QVBoxLayout()
#~ self.verticalLayout.setSpacing(2)
#~ self.verticalLayout.setMargin(0)
#~ self.searchBox = QtGui.QLineEdit()
#~ self.searchBox.textChanged.connect(self.fillAlgorithmTree)
#~ self.verticalLayout.addWidget(self.searchBox)
#~ self.algorithmTree = QtGui.QTreeWidget()
#~ self.algorithmTree.setHeaderHidden(True)
#~ self.fillAlgorithmTree()
#~ self.verticalLayout.addWidget(self.algorithmTree)
#~ self.algorithmTree.doubleClicked.connect(self.addAlgorithm)
#~
#~ self.algorithmsTab = QtGui.QWidget()
#~ self.algorithmsTab.setLayout(self.verticalLayout)
#~ self.tabWidget.addTab(self.algorithmsTab, "Algorithms")
#~
#~ #right hand side part
#~ #==================================
#~ self.textName = QtGui.QLineEdit()
#~ if hasattr(self.textName, 'setPlaceholderText'):
#~ self.textName.setPlaceholderText("[Enter model name here]")
#~ self.textGroup = QtGui.QLineEdit()
#~ if hasattr(self.textGroup, 'setPlaceholderText'):
#~ self.textGroup.setPlaceholderText("[Enter group name here]")
#~ self.horizontalLayoutNames = QtGui.QHBoxLayout()
#~ self.horizontalLayoutNames.setSpacing(2)
#~ self.horizontalLayoutNames.setMargin(0)
#~ self.horizontalLayoutNames.addWidget(self.textName)
#~ self.horizontalLayoutNames.addWidget(self.textGroup)
#~
#~ self.scene = ModelerScene(self)
#~ self.scene.setSceneRect(QtCore.QRectF(0, 0, 4000, 4000))
#~
#~ self.canvasTabWidget = QtGui.QTabWidget()
#~ self.canvasTabWidget.setMinimumWidth(300)
#~ self.view = QtGui.QGraphicsView(self.scene)
#~
#~ #=======================================================================
#~ # self.canvasTabWidget.addTab(self.view, "Design")
#~ # self.pythonText = QtGui.QTextEdit()
#~ # self.createScriptButton = QtGui.QPushButton()
#~ # self.createScriptButton.setText("Create script from model code")
#~ # self.createScriptButton.clicked.connect(self.createScript)
#~ # self.verticalLayoutPython = QtGui.QVBoxLayout()
#~ # self.verticalLayoutPython.setSpacing(2)
#~ # self.verticalLayoutPython.setMargin(0)
#~ # self.verticalLayoutPython.addWidget(self.pythonText)
#~ # self.verticalLayoutPython.addWidget(self.createScriptButton)
#~ # self.pythonWidget = QtGui.QWidget()
#~ # self.pythonWidget.setLayout(self.verticalLayoutPython)
#~ # self.canvasTabWidget.addTab(self.pythonWidget, "Python code")
#~ #=======================================================================
#~
#~ self.canvasLayout = QtGui.QVBoxLayout()
#~ self.canvasLayout.setSpacing(2)
#~ self.canvasLayout.setMargin(0)
#~ self.canvasLayout.addLayout(self.horizontalLayoutNames)
#~ self.canvasLayout.addWidget(self.view)#canvasTabWidget)
#~
#~ #upper part, putting the two previous parts together
#~ #===================================================
#~ self.horizontalLayout = QtGui.QHBoxLayout()
#~ self.horizontalLayout.setSpacing(2)
#~ self.horizontalLayout.setMargin(0)
#~ self.horizontalLayout.addWidget(self.tabWidget)
#~ self.horizontalLayout.addLayout(self.canvasLayout)
#~
#~ #And the whole layout
#~ #==========================
#~
#~ self.buttonBox = QtGui.QDialogButtonBox()
#~ self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
#~ self.editHelpButton = QtGui.QPushButton()
#~ self.editHelpButton.setText("Edit model help")
#~ self.buttonBox.addButton(self.editHelpButton, QtGui.QDialogButtonBox.ActionRole)
#~ self.runButton = QtGui.QPushButton()
#~ self.runButton.setText("Run")
#~ self.buttonBox.addButton(self.runButton, QtGui.QDialogButtonBox.ActionRole)
#~ self.openButton = QtGui.QPushButton()
#~ self.openButton.setText("Open")
#~ self.buttonBox.addButton(self.openButton, QtGui.QDialogButtonBox.ActionRole)
#~ self.saveButton = QtGui.QPushButton()
#~ self.saveButton.setText("Save")
#~ self.buttonBox.addButton(self.saveButton, QtGui.QDialogButtonBox.ActionRole)
#~ self.closeButton = QtGui.QPushButton()
#~ self.closeButton.setText("Close")
#~ self.buttonBox.addButton(self.closeButton, QtGui.QDialogButtonBox.ActionRole)
#~ QObject.connect(self.openButton, QtCore.SIGNAL("clicked()"), self.openModel)
#~ QObject.connect(self.saveButton, QtCore.SIGNAL("clicked()"), self.saveModel)
#~ QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), self.closeWindow)
#~ QObject.connect(self.runButton, QtCore.SIGNAL("clicked()"), self.runModel)
#~ QObject.connect(self.editHelpButton, QtCore.SIGNAL("clicked()"), self.editHelp)
#~
#~ self.globalLayout = QtGui.QVBoxLayout()
#~ self.globalLayout.setSpacing(2)
#~ self.globalLayout.setMargin(0)
#~ self.globalLayout.addLayout(self.horizontalLayout)
#~ self.globalLayout.addWidget(self.buttonBox)
#~ self.setLayout(self.globalLayout)
#~ QtCore.QMetaObject.connectSlotsByName(self)
#~
#~ self.view.ensureVisible(0, 0, 10, 10)

def editHelp(self):
dlg = HelpEditionDialog(self.alg)
Expand Down Expand Up @@ -223,15 +271,18 @@ def runModel(self):

def saveModel(self):
if unicode(self.textGroup.text()).strip() == "" or unicode(self.textName.text()).strip() == "":
QMessageBox.warning(self, "Warning", "Please enter group and model names before saving")
QMessageBox.warning(self,
self.tr("Warning"),
self.tr("Please enter group and model names before saving")
)
return
self.alg.setPositions(self.scene.getParameterPositions(), self.scene.getAlgorithmPositions())
self.alg.name = unicode(self.textName.text())
self.alg.group = unicode(self.textGroup.text())
if self.alg.descriptionFile != None:
filename = self.alg.descriptionFile
else:
filename = str(QtGui.QFileDialog.getSaveFileName(self, "Save Model", ModelerUtils.modelsFolder(), "SEXTANTE models (*.model)"))
filename = unicode(QFileDialog.getSaveFileName(self, self.tr("Save Model"), ModelerUtils.modelsFolder(), self.tr("SEXTANTE models (*.model)")))
if filename:
if not filename.endswith(".model"):
filename += ".model"
Expand All @@ -249,10 +300,13 @@ def saveModel(self):
pickle.dump(self.help, f)
f.close()
self.help = None
QtGui.QMessageBox.information(self, "Model saving", "Model was correctly saved.")
QMessageBox.information(self,
self.tr("Model saving"),
self.tr("Model was correctly saved.")
)

def openModel(self):
filename = unicode(QtGui.QFileDialog.getOpenFileName(self, "Open Model", ModelerUtils.modelsFolder(), "SEXTANTE models (*.model)"))
filename = unicode(QFileDialog.getOpenFileName(self, self.tr("Open Model"), ModelerUtils.modelsFolder(), self.tr("SEXTANTE models (*.model)")))
if filename:
try:
alg = ModelerAlgorithm()
Expand All @@ -265,17 +319,18 @@ def openModel(self):
self.view.ensureVisible(self.scene.getLastAlgorithmItem())
self.view.centerOn(0,0)
except WrongModelException, e:
QMessageBox.critical(self, "Could not open model", "The selected model could not be loaded\nWrong line:" + e.msg)

QMessageBox.critical(self,
self.tr("Could not open model"),
self.tr("The selected model could not be loaded.\nWrong line: %1").arg(e.msg)
)

def repaintModel(self):
self.scene = ModelerScene()
self.scene.setSceneRect(QtCore.QRectF(0, 0, ModelerAlgorithm.CANVAS_SIZE, ModelerAlgorithm.CANVAS_SIZE))
self.scene.setSceneRect(QRectF(0, 0, ModelerAlgorithm.CANVAS_SIZE, ModelerAlgorithm.CANVAS_SIZE))
self.scene.paintModel(self.alg)
self.view.setScene(self.scene)
#self.pythonText.setText(self.alg.getAsPythonCode())


def addInput(self):
item = self.inputsTree.currentItem()
paramType = str(item.text(0))
Expand All @@ -288,18 +343,16 @@ def addInput(self):
self.repaintModel()
self.view.ensureVisible(self.scene.getLastParameterItem())


def fillInputsTree(self):
parametersItem = QtGui.QTreeWidgetItem()
parametersItem.setText(0, "Parameters")
parametersItem = QTreeWidgetItem()
parametersItem.setText(0, self.tr("Parameters"))
for paramType in ModelerParameterDefinitionDialog.paramTypes:
paramItem = QtGui.QTreeWidgetItem()
paramItem = QTreeWidgetItem()
paramItem.setText(0, paramType)
parametersItem.addChild(paramItem)
self.inputsTree.addTopLevelItem(parametersItem)
parametersItem.setExpanded(True)


def addAlgorithm(self):
item = self.algorithmTree.currentItem()
if isinstance(item, TreeAlgorithmItem):
Expand Down Expand Up @@ -331,15 +384,15 @@ def fillAlgorithmTree(self):
if alg.group in groups:
groupItem = groups[alg.group]
else:
groupItem = QtGui.QTreeWidgetItem()
groupItem = QTreeWidgetItem()
groupItem.setText(0, alg.group)
groupItem.setToolTip(0, alg.group)
groups[alg.group] = groupItem
algItem = TreeAlgorithmItem(alg)
groupItem.addChild(algItem)

if len(groups) > 0:
providerItem = QtGui.QTreeWidgetItem()
providerItem = QTreeWidgetItem()
providerItem.setText(0, Providers.providers[providerName].getDescription())
providerItem.setToolTip(0, Providers.providers[providerName].getDescription())
providerItem.setIcon(0, Providers.providers[providerName].getIcon())
Expand All @@ -353,7 +406,7 @@ def fillAlgorithmTree(self):

self.algorithmTree.sortItems(0, Qt.AscendingOrder)

class TreeAlgorithmItem(QtGui.QTreeWidgetItem):
class TreeAlgorithmItem(QTreeWidgetItem):

def __init__(self, alg):
QTreeWidgetItem.__init__(self)
Expand Down
166 changes: 166 additions & 0 deletions python/plugins/sextante/ui/DlgModeler.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgModeler</class>
<widget class="QDialog" name="DlgModeler">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1000</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>SEXTANTE modeler</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>2</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Inputs</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QTreeWidget" name="inputsTree">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Algorithms</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QgsFilterLineEdit" name="searchBox">
<property name="toolTip">
<string>Enter algorithm name to filter list</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="algorithmTree">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QWidget" name="">
<layout class="QGridLayout" name="gridLayout">
<property name="spacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLineEdit" name="textName">
<property name="toolTip">
<string>Enter model name here</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="textGroup">
<property name="toolTip">
<string>Enter group name here</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGraphicsView" name="view"/>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsFilterLineEdit</class>
<extends>QLineEdit</extends>
<header>qgis.gui</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>DlgModeler</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DlgModeler</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>