Пример #1
0
    def _map_variable_to_definition_node(self, variable_node):
        ''' creates a mapping between the variables (name, dataset) and it's definition node '''
        dataset, name = get_variable_dataset_and_name(variable_node)
        expression_lib_nodes = get_variable_nodes_per_dataset(self.project)

        # Before XML 2.0 there was no dataset associated with variable selections, so some converted
        # files might have an empty dataset (variable name starts with a . [dot]).
        # in these cases we try to guess wich variable in the expression lib to associate with.
        # Note that built-ins like 'constant' return None as dataset, not an empty string.
        if dataset == '':
            possible_datasets = []
            for dataset_name, variable_nodes in expression_lib_nodes.items():
                for variable_definition_node in variable_nodes:
                    def_variable_name = get_variable_name(
                        variable_definition_node)
                    if def_variable_name == name:
                        possible_datasets.append(dataset_name)
                        break
            if len(possible_datasets) == 1:
                dataset = possible_datasets[0]
                # update the variable node with the guessed dataset
                # variable_node.set('name', '%s.%s' %(dataset, name))

        if not dataset in expression_lib_nodes:
            self._names_to_definition_nodes[(name, dataset)] = None
        else:  # look through the dataset to find a variable with the same name
            for variable_definition_node in expression_lib_nodes[dataset]:
                def_variable_name = get_variable_name(variable_definition_node)
                if def_variable_name == name:
                    self._names_to_definition_nodes[(
                        name, dataset)] = variable_definition_node
                    break
            else:
                self._names_to_definition_nodes[(name, dataset)] = None
    def _update_available_variables(self):
        # populate the list of available variables while considering A) what dataset filter the user
        # has selected, an d B) what variables that have already been selected)
        self.lst_available_variables.clear()
        if self.cbo_dataset_filter.currentIndex() > 0:
            dataset_filter = str(self.cbo_dataset_filter.currentText())
        else:
            dataset_filter = None
        selected_variable_names = [node.get('name') for node in self.selector_table_model._variable_nodes]

        available_variable_nodes = []
        variable_nodes_per_dataset = get_variable_nodes_per_dataset(self.project)

        if not dataset_filter: # take all variables
            for variable_nodes in variable_nodes_per_dataset.values():
                available_variable_nodes.extend(variable_nodes)
        else:
            available_variable_nodes = variable_nodes_per_dataset[dataset_filter]
        available_variable_nodes.append(get_built_in_constant_node())
        
        # filter already selected variables and show the list of available variables
        not_selected_variables = [var_node for var_node in available_variable_nodes if
                                  not var_node.get('name') in selected_variable_names]
        for variable_node in not_selected_variables:
            item = QtGui.QListWidgetItem(self.lst_available_variables)
            item.setIcon(IconLibrary.icon('variable'))
            item.node = variable_node # monkey in the node for adding later
            item.setText(get_variable_name(variable_node))
            self.lst_available_variables.addItem(item)
        self.lst_available_variables.sortItems()
    def _create_add_variable_menu(self):
        # function to display variables in the popup menu
        def display_node(node, selected_nodes):
            if node in selected_nodes:
                return '(already selected) %s' % get_variable_name(node)
            return get_variable_name(node)
        # call back to only add unselected variables from the popup menu
        def add_if_unselected(node, selected_nodes):
            if not node in selected_nodes:
                self.add_variable(node)

        dataset_variable_nodes = get_variable_nodes_per_dataset(self.project)
        selected_names = map(get_variable_name, self.selector_table_model._variable_nodes)
        selected_nodes = []

        for variable_node_list in dataset_variable_nodes.values():
            for variable_node in variable_node_list:
                if get_variable_name(variable_node) in selected_names:
                    selected_nodes.append(variable_node)
            # sort by variable name
            variable_node_list.sort(lambda x, y: cmp(get_variable_name(x), get_variable_name(y)))
            # display selected items at the bottom
            for node in variable_node_list[:]:
                if node in selected_nodes:
                    variable_node_list.remove(node)
                    variable_node_list.insert(len(variable_node_list), node)

        display_func = lambda x, y = selected_nodes: display_node(x, y)
        callback = lambda x, y = selected_nodes: add_if_unselected(x, y)
        return dictionary_to_menu(source_dict = dataset_variable_nodes,
                                  callback = callback,
                                  display_func = display_func,
                                  parent_widget = self)
Пример #4
0
    def _map_variable_to_definition_node(self, variable_node):
        ''' creates a mapping between the variables (name, dataset) and it's definition node '''
        dataset, name = get_variable_dataset_and_name(variable_node)
        expression_lib_nodes = get_variable_nodes_per_dataset(self.project)

        # Before XML 2.0 there was no dataset associated with variable selections, so some converted
        # files might have an empty dataset (variable name starts with a . [dot]).
        # in these cases we try to guess wich variable in the expression lib to associate with.
        # Note that built-ins like 'constant' return None as dataset, not an empty string.
        if dataset == '':
            possible_datasets = []
            for dataset_name, variable_nodes in expression_lib_nodes.items():
                for variable_definition_node in variable_nodes:
                    def_variable_name = get_variable_name(variable_definition_node)
                    if def_variable_name == name:
                        possible_datasets.append(dataset_name)
                        break
            if len(possible_datasets) == 1:
                dataset = possible_datasets[0]
                # update the variable node with the guessed dataset
                # variable_node.set('name', '%s.%s' %(dataset, name))

        if not dataset in expression_lib_nodes:
            self._names_to_definition_nodes[(name, dataset)] = None
        else: # look through the dataset to find a variable with the same name
            for variable_definition_node in expression_lib_nodes[dataset]:
                def_variable_name = get_variable_name(variable_definition_node)
                if def_variable_name == name:
                    self._names_to_definition_nodes[(name, dataset)] = variable_definition_node
                    break
            else:
                self._names_to_definition_nodes[(name, dataset)] = None
    def _widget_and_method_from_field_data_type(self, template_node):
        '''
        Fetch the widget and the data-method for a given node based in it's field_data_type
        argument. If the node doesn't have a field_data_type, or it's value is unknown, return None
        '''
        data_type = template_node.get('field_data_type')
        if not data_type:
            return None

        # Helper function to get a string based on the model name.
        # both the name and the type of the model node are updated before this method is called.
        def get_model_name_based_string(node=template_node,
                                        prefix='',
                                        suffix=''):
            while node is not None and node.tag != 'model':
                node = node.getparent()
            if node is None:
                raise LookupError(
                    'Could not locate the parent <model> node for %s' %
                    str(node))
            return '%s%s%s' % (prefix, node.get('name'), suffix)

        # dataset
        if data_type == 'dataset':
            widget = QtGui.QComboBox()
            for dataset_name in get_available_dataset_names(self.project):
                widget.addItem(dataset_name)
            return (widget, widget.currentText)

        # model variable
        if data_type == 'model_variable':
            variables_per_dataset = get_variable_nodes_per_dataset(
                self.project)
            widget = QtGui.QComboBox()
            for dataset, variables in variables_per_dataset.items():
                for variable in variables:
                    widget.addItem('%s: %s' % (dataset, variable.get('name')))
            # return a method that only gives the name of the variable, and skips the dataset
            return (widget,
                    lambda x=widget: widget.currentText().split(':')[1])

        # specification table
        # data-method should return a table name based on the models name
        if data_type == 'specification_table':
            return (None, lambda x='_specification':
                    get_model_name_based_string(suffix=x))
        # coefficients table
        if data_type == 'coefficients_table':
            return (None, lambda x='_coefficients':
                    get_model_name_based_string(suffix=x))

        if data_type == 'choice_set':  # No special handling
            return None
        # unknown, notify with a warning
        print(
            'Warning: <%s name=%s> has a field_data_type of unknown value (%s) and is ignored.'
            % (template_node.tag, template_node.get('name'), data_type))
        return None
 def _update_dataset_filter_list(self):
     # update the combo box list (keeping selection)
     variable_nodes_per_dataset = get_variable_nodes_per_dataset(self.project)
     pre_update_dataset_name = self.cbo_dataset_filter.currentText()
     self.cbo_dataset_filter.clear()
     self.cbo_dataset_filter.addItem('[All datasets]')
     for dataset_name in variable_nodes_per_dataset:
         if dataset_name is not None: # built ins are manually added
             self.cbo_dataset_filter.addItem(dataset_name)
     post_update_index = self.cbo_dataset_filter.findText(pre_update_dataset_name)
     if post_update_index > -1:
         self.cbo_dataset_filter.setCurrentIndex(post_update_index)
Пример #7
0
 def _update_dataset_filter_list(self):
     # update the combo box list (keeping selection)
     variable_nodes_per_dataset = get_variable_nodes_per_dataset(
         self.project)
     pre_update_dataset_name = self.cbo_dataset_filter.currentText()
     self.cbo_dataset_filter.clear()
     self.cbo_dataset_filter.addItem('[All datasets]')
     for dataset_name in variable_nodes_per_dataset:
         if dataset_name is not None:  # built ins are manually added
             self.cbo_dataset_filter.addItem(dataset_name)
     post_update_index = self.cbo_dataset_filter.findText(
         pre_update_dataset_name)
     if post_update_index > -1:
         self.cbo_dataset_filter.setCurrentIndex(post_update_index)
    def _widget_and_method_from_field_data_type(self, template_node):
        '''
        Fetch the widget and the data-method for a given node based in it's field_data_type
        argument. If the node doesn't have a field_data_type, or it's value is unknown, return None
        '''
        data_type = template_node.get('field_data_type')
        if not data_type:
            return None

        # Helper function to get a string based on the model name.
        # both the name and the type of the model node are updated before this method is called.
        def get_model_name_based_string(node = template_node, prefix = '', suffix = ''):
            while node is not None and node.tag != 'model':
                node = node.getparent()
            if node is None:
                raise LookupError('Could not locate the parent <model> node for %s' % str(node))
            return '%s%s%s' %(prefix, node.get('name'), suffix)

        # dataset
        if data_type == 'dataset':
            widget = QtGui.QComboBox()
            for dataset_name in get_available_dataset_names(self.project):
                widget.addItem(dataset_name)
            return (widget, widget.currentText)

        # model variable
        if data_type == 'model_variable':
            variables_per_dataset = get_variable_nodes_per_dataset(self.project)
            widget = QtGui.QComboBox()
            for dataset, variables in variables_per_dataset.items():
                for variable in variables:
                    widget.addItem('%s: %s' % (dataset, variable.get('name')))
            # return a method that only gives the name of the variable, and skips the dataset
            return (widget, lambda x = widget: widget.currentText().split(':')[1])

        # specification table
        # data-method should return a table name based on the models name
        if data_type == 'specification_table':
            return (None, lambda x = '_specification' : get_model_name_based_string(suffix = x))
        # coefficients table
        if data_type == 'coefficients_table':
            return (None, lambda x = '_coefficients': get_model_name_based_string(suffix = x))

        if data_type == 'choice_set': # No special handling
            return None
        # unknown, notify with a warning
        print ('Warning: <%s name=%s> has a field_data_type of unknown value (%s) and is ignored.' %
               (template_node.tag, template_node.get('name'), data_type))
        return None
Пример #9
0
    def initialize(self):
        # reset the variable library to reflect the current state of expression library in xml
        nodes_per_dataset = get_variable_nodes_per_dataset(self.project)
        variables = []
        all_original_nodes = set()
        for dataset in nodes_per_dataset:
            for variable_node in nodes_per_dataset[dataset]:
                new_variable = variable_from_node(variable_node)
                new_variable['originalnode'] = variable_node
                variables.append(new_variable)
                all_original_nodes.add(
                    variable_node)  # save original values for comparison
        self.original_nodes = all_original_nodes
        self.cancel_validation_flag = {'value': False}

        # to avoid quirky behavior when applying changes, store the column widths and restore them
        # after the model update
        col_widths = [
            self.variables_table.columnWidth(col) for col in range(5)
        ]

        # bind to self to prevent PyQt from "losing" the object ref
        self.model = VariablesTableModel(project=self.project,
                                         variables=variables,
                                         parent_widget=self.variables_table)
        self.variables_table.setModel(self.model)
        self.model.re_sort()
        self.connect(self.model, SIGNAL('layoutChanged()'),
                     self.variables_table.resizeRowsToContents)
        self._update_apply_button()

        self.group_progress.setVisible(False)
        self.pb_problems.setIcon(IconLibrary.icon('warning_small'))
        self.pb_problems.setAttribute(Qt.WA_AlwaysShowToolTips)
        self._set_problem_variables([])
        self._update_dataset_filter()

        # use the inital size if the column widths is all zeroes
        if sum(abs(w) for w in col_widths) == 0:
            col_widths = [195, 80, 45, 50, -1]
        for col in range(5):
            if col_widths[col] > 0:
                self.variables_table.setColumnWidth(col, col_widths[col])
        self.variables_table.resizeRowsToContents()
Пример #10
0
    def initialize(self):
        # reset the variable library to reflect the current state of expression library in xml
        nodes_per_dataset = get_variable_nodes_per_dataset(self.project)
        variables = []
        all_original_nodes = set()
        for dataset in nodes_per_dataset:
            for variable_node in nodes_per_dataset[dataset]:
                new_variable = variable_from_node(variable_node)
                new_variable['originalnode'] = variable_node
                variables.append(new_variable)
                all_original_nodes.add(variable_node) # save original values for comparison
        self.original_nodes = all_original_nodes
        self.cancel_validation_flag = {'value': False}

        # to avoid quirky behavior when applying changes, store the column widths and restore them
        # after the model update
        col_widths = [self.variables_table.columnWidth(col) for col in range(5)]

        # bind to self to prevent PyQt from "losing" the object ref
        self.model = VariablesTableModel(project = self.project, variables = variables,
                                         parent_widget = self.variables_table)
        self.variables_table.setModel(self.model)
        self.model.re_sort()
        self.connect(self.model, SIGNAL('layoutChanged()'), self.variables_table.resizeRowsToContents)
        self._update_apply_button()

        self.group_progress.setVisible(False)
        self.pb_problems.setIcon(IconLibrary.icon('warning_small'))
        self.pb_problems.setAttribute(Qt.WA_AlwaysShowToolTips)
        self._set_problem_variables([])
        self._update_dataset_filter()

        # use the inital size if the column widths is all zeroes
        if sum(abs(w) for w in col_widths) == 0:
            col_widths = [195, 80, 45, 50, -1]
        for col in range(5):
            if col_widths[col] > 0:
                self.variables_table.setColumnWidth(col, col_widths[col])
        self.variables_table.resizeRowsToContents()
Пример #11
0
    def _update_available_variables(self):
        # populate the list of available variables while considering A) what dataset filter the user
        # has selected, an d B) what variables that have already been selected)
        self.lst_available_variables.clear()
        if self.cbo_dataset_filter.currentIndex() > 0:
            dataset_filter = str(self.cbo_dataset_filter.currentText())
        else:
            dataset_filter = None
        selected_variable_names = [
            node.get('name')
            for node in self.selector_table_model._variable_nodes
        ]

        available_variable_nodes = []
        variable_nodes_per_dataset = get_variable_nodes_per_dataset(
            self.project)

        if not dataset_filter:  # take all variables
            for variable_nodes in variable_nodes_per_dataset.values():
                available_variable_nodes.extend(variable_nodes)
        else:
            available_variable_nodes = variable_nodes_per_dataset[
                dataset_filter]
        available_variable_nodes.append(get_built_in_constant_node())

        # filter already selected variables and show the list of available variables
        not_selected_variables = [
            var_node for var_node in available_variable_nodes
            if not var_node.get('name') in selected_variable_names
        ]
        for variable_node in not_selected_variables:
            item = QtGui.QListWidgetItem(self.lst_available_variables)
            item.setIcon(IconLibrary.icon('variable'))
            item.node = variable_node  # monkey in the node for adding later
            item.setText(get_variable_name(variable_node))
            self.lst_available_variables.addItem(item)
        self.lst_available_variables.sortItems()
Пример #12
0
    def _create_add_variable_menu(self):
        # function to display variables in the popup menu
        def display_node(node, selected_nodes):
            if node in selected_nodes:
                return '(already selected) %s' % get_variable_name(node)
            return get_variable_name(node)

        # call back to only add unselected variables from the popup menu
        def add_if_unselected(node, selected_nodes):
            if not node in selected_nodes:
                self.add_variable(node)

        dataset_variable_nodes = get_variable_nodes_per_dataset(self.project)
        selected_names = map(get_variable_name,
                             self.selector_table_model._variable_nodes)
        selected_nodes = []

        for variable_node_list in dataset_variable_nodes.values():
            for variable_node in variable_node_list:
                if get_variable_name(variable_node) in selected_names:
                    selected_nodes.append(variable_node)
            # sort by variable name
            variable_node_list.sort(
                lambda x, y: cmp(get_variable_name(x), get_variable_name(y)))
            # display selected items at the bottom
            for node in variable_node_list[:]:
                if node in selected_nodes:
                    variable_node_list.remove(node)
                    variable_node_list.insert(len(variable_node_list), node)

        display_func = lambda x, y=selected_nodes: display_node(x, y)
        callback = lambda x, y=selected_nodes: add_if_unselected(x, y)
        return dictionary_to_menu(source_dict=dataset_variable_nodes,
                                  callback=callback,
                                  display_func=display_func,
                                  parent_widget=self)