def __init__(self, iface, layer, project_definition):
        self.iface = iface
        QDialog.__init__(self)

        # Set up the user interface from Designer.
        self.ui = Ui_CreateWeightTreeDialog()
        self.ui.setupUi(self)
        self.ok_button = self.ui.buttonBox.button(QDialogButtonBox.Ok)

        self.project_definition = project_definition
        self.layer = layer
        self.theme_boxes = None
        self.themes = None

        self.generate_gui()
        self.ui.buttonBox.button(QDialogButtonBox.Reset).clicked.connect(
            self.reset)
class CreateWeightTreeDialog(QDialog):
    """
    Modal dialog allowing to select a raster or vector layer
    containing loss data points and a vector layer containing polygons
    that define the zones for which data need to be aggregated. When
    both are selected and are valid files, they can be loaded by clicking OK
    """

    def __init__(self, iface, layer, project_definition):
        self.iface = iface
        QDialog.__init__(self)

        # Set up the user interface from Designer.
        self.ui = Ui_CreateWeightTreeDialog()
        self.ui.setupUi(self)
        self.ok_button = self.ui.buttonBox.button(QDialogButtonBox.Ok)

        self.project_definition = project_definition
        self.layer = layer
        self.theme_boxes = None
        self.themes = None

        self.generate_gui()
        self.ui.buttonBox.button(QDialogButtonBox.Reset).clicked.connect(
            self.reset)

    def generate_gui(self):
        self.theme_boxes = []
        self.themes = set([''])
        dp = self.layer.dataProvider()
        fields = list(dp.fields())
        numeric_fields = [field for field in fields
                          if field.typeName() in NUMERIC_FIELD_TYPES]

        themes_list = []
        indicators_list = {}
        if self.project_definition:
            themes = self.project_definition['children'][1]['children']
            for theme in themes:
                themes_list.append(theme['name'])
                for indicator in theme['children']:
                    indicators_list[indicator['field']] = (theme['name'],
                                                           indicator['name'])

            # remove duplicates
            themes_list = list(set(themes_list))
            themes_list.sort()
        themes_list.insert(0, '')

        attribute_label = QLabel('Attribute')
        theme_label = QLabel('Theme')
        name_label = QLabel('Name')

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(5)
        theme_label.setSizePolicy(sizePolicy)
        name_label.setSizePolicy(sizePolicy)
        self.ui.grid_layout.addWidget(attribute_label, 0, 0)
        self.ui.grid_layout.addWidget(theme_label, 0, 1)
        self.ui.grid_layout.addWidget(name_label, 0, 2)

        for i, field in enumerate(numeric_fields, start=1):
            theme_name = ''
            indicator_name = ''
            if field.name() in indicators_list:
                theme_name = indicators_list[field.name()][0]
                indicator_name = indicators_list[field.name()][1]

            attribute_label = QLabel(field.name())
            attribute_label.setTextInteractionFlags(Qt.TextSelectableByMouse)

            theme = QComboBox()
            theme.setEditable(True)
            theme.setDuplicatesEnabled(False)
            theme.setInsertPolicy(QComboBox.InsertAlphabetically)
            theme.addItems(themes_list)
            current_index = theme.findText(theme_name)
            current_index = current_index if current_index != -1 else 0
            theme.setCurrentIndex(current_index)
            theme.currentIndexChanged.connect(self.check_status)
            theme.lineEdit().editingFinished.connect(self.update_themes)
            self.theme_boxes.append(theme)

            name = QLineEdit(indicator_name)
            name.textChanged.connect(self.check_status)

            self.ui.grid_layout.addWidget(attribute_label, i, 0)
            self.ui.grid_layout.addWidget(theme, i, 1)
            self.ui.grid_layout.addWidget(name, i, 2)

        self.check_status()

    def update_themes(self):
        new_theme = self.sender().text()
        if new_theme not in self.themes:
            self.themes.update([new_theme])
            for theme_box in self.theme_boxes:
                # needed to avoid a strange behaviour when generating_gui
                if theme_box.findText(new_theme) == -1:
                    theme_box.addItem(new_theme)
            self.check_status()

    def indicators(self):
        indicators = []
        for i in range(1, self.ui.grid_layout.rowCount()):
            label = self.ui.grid_layout.itemAtPosition(i, 0).widget().text()
            theme = \
                self.ui.grid_layout.itemAtPosition(i, 1).widget().currentText()
            name = self.ui.grid_layout.itemAtPosition(i, 2).widget().text()
            if name:
                theme = theme if theme else ''
                indicators.append({'field': label,
                                   'theme': theme,
                                   'name': name})
        return indicators

    def check_status(self):
        valid_with_theme = True
        valid_without_theme = True
        enough_indicators = False

        for i in range(1, self.ui.grid_layout.rowCount()):
            theme = self.ui.grid_layout.itemAtPosition(
                i, 1).widget().currentText()
            name_field = self.ui.grid_layout.itemAtPosition(i, 2).widget()
            name = name_field.text()
            label = self.ui.grid_layout.itemAtPosition(i, 0).widget().text()

            if theme:
                valid_without_theme = False
                if name == '':
                    name_field.setText(label)
                    name = label

            if name:
                enough_indicators = True

            #either both or none are set
            if theme and name or (not theme and not name):
                continue
            else:
                valid_with_theme = False

        if valid_with_theme or valid_without_theme:
            if enough_indicators:
                self.ok_button.setEnabled(True)
            else:
                self.ok_button.setEnabled(False)
        else:
            self.ok_button.setDisabled(True)

    def reset(self):
        layout = self.ui.grid_layout
        # clear the layout as per
        # http://stackoverflow.com/questions/4528347/clear-all-widgets-in-a-layout-in-pyqt#answer-13103617
        for i in reversed(range(layout.count())):
            layout.itemAt(i).widget().setParent(None)
        self.generate_gui()