예제 #1
0
 def _reset(self) -> None:
     self.__taxonomy_tree.set_items([])
     self.__selected_component = None
     self.__cmp_name_var.set('')
     change_controls_state(tk.DISABLED, self.__remove_button,
                           self.__remove_recursively_button,
                           self.__rename_button)
    def __on_select_tree_item(self, cmp_id: int) -> None:
        """Executed whenever a tree item is selected (by mouse click).
        
        :param cmp_id: Id of the selected component.
        """
        selected_cmp: Component = self.__state.model.get_component(id_=cmp_id)
        self.__selected_component = selected_cmp
        self.__cmp_label_var.set(trim_string(selected_cmp.name, length=LABEL_LENGTH))

        radiobutton_val = selected_cmp.exact if selected_cmp.exact is not None else True
        self.__exact_value_radiobutton_var.set(radiobutton_val)
        # Enable symmetry breaking checkbox & spinbox
        change_controls_state(tk.NORMAL,
                              self.__exact_minimum_spinbox,
                              self.__symm_breaking_checkbox,
                              self.__range_radiobutton,
                              self.__exact_value_radiobutton,
                              self.__exact_minimum_spinbox)
        if selected_cmp.is_leaf:
            # Set the spinbox values
            if selected_cmp.exact:
                set_spinbox_var_value(self.__exact_minimum_spinbox_var, selected_cmp.count)
            else:
                set_spinbox_var_value(self.__exact_minimum_spinbox_var, selected_cmp.min_count)
                set_spinbox_var_value(self.__max_spinbox_var, selected_cmp.max_count)

            self.__symm_breaking_checkbox_var.set(selected_cmp.symmetry_breaking)
            self.__apply_symmetry_breaking_to_all_children_button.grid_forget()
            self.__apply_count_to_all_children_button.grid_forget()
        else:
            # Show apply to all children
            self.__apply_symmetry_breaking_to_all_children_button.grid(row=3, column=2, columnspan=2, padx=CONTROL_PAD_X, pady=CONTROL_PAD_Y)
            self.__apply_count_to_all_children_button.grid(row=6, column=0, columnspan=4, sticky=tk.NSEW, padx=CONTROL_PAD_X, pady=CONTROL_PAD_Y)
            # Reset symmetry breaking for all components
            self.__symm_breaking_checkbox_var.set(False)
    def solve(self,
              input_path: Optional[str],
              on_solving_finished: Optional[Callable] = None) -> None:
        """Starts the solving thread and disables widgets.

        :param input_path: Input ASP encoding file path.
        :param on_solving_finished: Callback function executed when solving process finishes.
        """
        if not input_path:
            raise BGError('Input file path is not specified.')
        elif not self.__export_to_path_frame.path:
            raise BGError('Export path is not specified.')

        self.__input_path = input_path
        self.__stop_event = Event()
        self.__on_solving_finished = on_solving_finished
        self.__solve_thread = Thread(target=self.__solve,
                                     args=(self.__stop_event, ))
        self.__solve_thread.start()

        change_controls_state(tk.NORMAL,
                              self.__stop_button)  # Enable stop button
        change_controls_state(tk.DISABLED, self.__answer_sets_count_spinbox,
                              *self.__representation_radiobuttons,
                              self.__shown_predicates_only_checkbox)
        self.__export_to_path_frame.change_state(
            tk.DISABLED)  # Disable other widgets
예제 #4
0
    def __change_window_controls_state(self, state: str) -> None:
        """Changes widgets' state.

        :param state: Desired state of the widgets (tk.NORMAL or tk.DISABLED).
        """
        self.__generate_frame.change_frame_controls_state(state)
        change_controls_state(state, self.__ok_button, self.__cancel_button)
예제 #5
0
    def __on_combobox_changed(self, *_) -> None:
        """Executed whenever the __port_combobox value changes."""
        # Hide component-specific widgets
        self.__cmp_label.grid_forget()
        self.__amount_spinbox_label.grid_forget()
        self.__amount_spinbox.grid_forget()
        self.__all_children_amount_spinbox_label.grid_forget()
        self.__all_children_amount_spinbox.grid_forget()
        self.__apply_to_all_children_button.grid_forget()

        prt_name = self.__port_combobox_var.get()
        port = self.__state.model.get_port(name=prt_name)
        buttons_to_change_state_of = [
            self.__rename_port_button,
            self.__remove_port_button,
            self.__force_connection_checkbox,
            self.__compatible_with_edit_button,
        ]
        if port:
            self.__selected_port = port
            change_controls_state(tk.NORMAL, *buttons_to_change_state_of)
            compatible_ports = self.__state.model.get_ports_by_ids(port.compatible_with)
            self.__compatible_with_listbox.set_items(compatible_ports)  # Fill the 'compatible with' listbox
            self.__force_connection_checkbox_var.set(port.force_connection)

            self.__update_tree()    # Update tree values
            self.__taxonomy_tree.grid(row=0, column=1, sticky=tk.NSEW)  # Show tree
        else:
            self.__selected_port = None
            self.__force_connection_checkbox_var.set(False)
            self.__compatible_with_listbox.set_items([])    # Clear 'compatible with' listbox
            change_controls_state(tk.DISABLED,
                                  *buttons_to_change_state_of)
            self.__taxonomy_tree.grid_forget()     # Hide tree
예제 #6
0
    def __remove(self) -> None:
        """Executed whenever the __remove_port_button is pressed.
        Removes __selected_port from model.
        """
        if self.__selected_port:
            removed_prt = self.__state.model.remove_port(self.__selected_port)
            updated_combobox_values = [val for val in [*self.__port_combobox['values']] if val != removed_prt.name]
            self.__port_combobox['values'] = updated_combobox_values
            self.__selected_port = None
            self.__port_combobox_var.set(SELECT_PORT)
            self.__compatible_with_listbox.set_items([])    # Clear the compatible with
            change_controls_state(tk.DISABLED,
                                  self.__rename_port_button,
                                  self.__remove_port_button,
                                  self.__force_connection_checkbox,
                                  self.__compatible_with_edit_button)

            # Hide component-specific widgets
            self.__cmp_label.grid_forget()
            self.__amount_spinbox_label.grid_forget()
            self.__amount_spinbox.grid_forget()
            self.__all_children_amount_spinbox_label.grid_forget()
            self.__all_children_amount_spinbox.grid_forget()
            self.__apply_to_all_children_button.grid_forget()

            self.__update_tree()
 def __remove_consequent(self) -> None:
     if self.__selected_consequent:
         self.__consequent.remove(self.__selected_consequent)
         self.__consequent_listbox.remove_item_recursively(
             self.__selected_consequent)
         self.__selected_consequent = None
         change_controls_state(tk.DISABLED, self.__edit_consequent_button,
                               self.__remove_consequent_button)
 def __on_model_changed(self):
     """Executed whenever a model is loaded from file or taxonomy changes."""
     ctrs = self.__state.model.get_all_constraints()
     self.__constraints_listbox.set_items(ctrs)
     self.__selected_constraint = None
     self.__ctr_label_var.set('')
     change_controls_state(tk.DISABLED, self.__edit_constraint_button,
                           self.__remove_constraint_button)
예제 #9
0
    def __change_window_controls_state(self, state) -> None:
        """Changes the state of specific widgets to that stated in "state".

        :param state: State to change the widgets to.
        """
        change_controls_state(state,
                              self.__ok_button,
                              self.__cancel_button)
        self.__solve_file_path_frame.change_state(state)
 def __remove_antecedent(self) -> None:
     """Executes whenever __remove_antecedent_button is pressed. Removes item from antecedent."""
     if self.__selected_antecedent:
         self.__antecedent.remove(self.__selected_antecedent)
         self.__antecedent_listbox.remove_item_recursively(
             self.__selected_antecedent)
         self.__selected_antecedent = None
         # Disable widgets
         change_controls_state(tk.DISABLED, self.__edit_antecedent_button,
                               self.__remove_antecedent_button)
    def __on_select_consequent(self, id_: int) -> None:
        """Executed whenever a __consequent_listbox item is selected (by mouse click).

        :param id_: Id of the selected consequent item.
        """
        self.__selected_consequent = next(
            (c for c in self.__consequent if c.id_ == id_), None)
        # Enable widgets
        change_controls_state(tk.NORMAL, self.__edit_consequent_button,
                              self.__remove_consequent_button)
예제 #12
0
    def __on_select_tree_item(self, cmp_id: int) -> None:
        """Executed whenever a tree item is selected (by mouse click).

        :param cmp_id: Id of the selected component.
        """
        selected_cmp: Component = self.__state.model.get_component(id_=cmp_id)
        self.__selected_component = selected_cmp
        self.__cmp_name_var.set(trim_string(selected_cmp.name, length=22))
        change_controls_state(tk.NORMAL, self.__remove_button,
                              self.__remove_recursively_button,
                              self.__rename_button)
    def change_frame_controls_state(self, state) -> None:
        """Changes widgets' state.

        :param state: Desired state of the widgets (tk.NORMAL or tk.DISABLED).
        """
        change_controls_state(
            state, *[
                checkbox for (_0, _1, checkbox) in
                self.__show_predicates_checkbox_widgets_dict.values()
            ], self.__show_all_predicates_checkbox)
        self.__export_to_path_frame.change_state(state)
 def __remove_constraint(self):
     """Executed whenever the __remove_constraint_button is pressed.
     Removes selected constraint from model.
     """
     if self.__selected_constraint:
         self.__state.model.remove_constraint(self.__selected_constraint)
         self.__constraints_listbox.remove_item_recursively(
             self.__selected_constraint)
         self.__selected_constraint = None
         # Hide widgets
         self.__ctr_label_var.set('')
         change_controls_state(tk.DISABLED, self.__edit_constraint_button,
                               self.__remove_constraint_button)
    def __on_select_callback(self, ctr_id: int):
        """Executed whenever a constraints listview item is selected (by mouse click).

        :param ctr_id: Id of the selected constraint.
        """
        selected_ctr = self.__state.model.get_constraint(id_=ctr_id)
        if selected_ctr:
            self.__selected_constraint = selected_ctr
            self.__ctr_label_var.set(
                trim_string(selected_ctr.name, length=LABEL_LENGTH))
            # Enable buttons
            change_controls_state(tk.NORMAL, self.__edit_constraint_button,
                                  self.__remove_constraint_button)
    def __add_consequent(self, con: SimpleConstraint) -> None:
        """Executed whenever an item is added to consequent.

        :param con: Item to add to consequent.
        """
        con, index = self.__validate_constraint(con,
                                                antecedent=False,
                                                added=True)
        self.__consequent.append(con)
        self.__consequent_listbox.add_item(con, index=index)
        self.__selected_consequent = con
        # Enable controls
        change_controls_state(tk.NORMAL, self.__edit_consequent_button,
                              self.__remove_consequent_button)
    def __add_antecedent(self, ant: SimpleConstraint) -> None:
        """Executed whenever an item is added to antecedent.

        :param ant: Item to add to antecedent.
        """
        ant, index = self.__validate_constraint(ant,
                                                antecedent=True,
                                                added=True)
        self.__antecedent.append(ant)
        self.__antecedent_listbox.add_item(ant, index=index)
        self.__selected_antecedent = ant
        # Enable controls
        change_controls_state(tk.NORMAL, self.__edit_antecedent_button,
                              self.__remove_antecedent_button)
    def __add(self, ctr: Any) -> None:
        """Executed after adding a new constraint in SimpleConstraintWindow or ComplexConstraintWindow.

        :param ctr: New SimpleConstraint or ComplexConstraint obtained from SimpleConstraintWindow
            or ComplexConstraintWindow.
        """
        _, index = self.__state.model.add_constraint(ctr)
        self.__constraints_listbox.add_item(ctr, index=index)
        # Set selected constraint to the newly created constraint
        self.__selected_constraint = ctr
        self.__ctr_label_var.set(trim_string(ctr.name, length=LABEL_LENGTH))
        # Enable buttons
        change_controls_state(tk.NORMAL, self.__edit_constraint_button,
                              self.__remove_constraint_button)
 def _reset(self) -> None:
     self.__taxonomy_tree.set_items([])
     self.__selected_component = None
     # Set entries to default
     self.__has_association_checkbox_var.set(False)
     self.__has_min_checkbox_var.set(False)
     self.__has_max_checkbox_var.set(False)
     self.__min_spinbox_var.set('')
     self.__max_spinbox_var.set('')
     self.__cmp_label_var.set('')
     # Disable items
     change_controls_state(tk.DISABLED, self.__has_association_checkbox,
                           self.__has_min_checkbox, self.__has_max_checkbox,
                           self.__min_spinbox, self.__max_spinbox)
예제 #20
0
    def __add(self, name: str) -> None:
        """Executed after creating of a new port.

        :param name: Name of a new port.
        """
        prt = Port(name)
        self.__state.model.add_port(prt)
        self.__selected_port = prt
        self.__port_combobox['values'] = sorted(self.__state.model.get_all_ports_names())
        self.__port_combobox_var.set(prt.name)
        change_controls_state(tk.NORMAL,
                              self.__rename_port_button,
                              self.__remove_port_button,
                              self.__force_connection_checkbox,
                              self.__compatible_with_edit_button)
 def __on_has_min_changed(self, *_):
     """Executed whenever the __has_min_checkbox is toggled"""
     if self.__selected_component:
         has_min = self.__has_min_checkbox_var.get()
         if has_min:
             change_controls_state(tk.NORMAL, self.__min_spinbox)
             if self.__selected_component.association and self.__selected_component.association.min_ is not None:
                 self.__min_spinbox_var.set(
                     self.__selected_component.association.min_)
             else:
                 self.__min_spinbox_var.set(0)
                 self.__selected_component.association.min_ = 0
         else:
             if self.__selected_component.association:
                 self.__selected_component.association.min_ = None
             change_controls_state(tk.DISABLED, self.__min_spinbox)
             self.__min_spinbox_var.set('')
예제 #22
0
    def __add(self, name: str):
        """Executed after creating of a new resource.

        :param name: Name of a new resource.
        """
        res = Resource(name)
        self.__state.model.add_resource(res)
        self.__selected_resource = res
        self.__resource_combobox['values'] = sorted(
            self.__state.model.get_all_resources_names())
        self.__resource_combobox_var.set(res.name)
        # Enable buttons
        change_controls_state(tk.NORMAL, self.__rename_resource_button,
                              self.__remove_resource_button)
        # Show the taxonomy tree
        self.__taxonomy_tree.grid(row=0, column=1, sticky=tk.NSEW)
        self.__update_tree()
예제 #23
0
 def _reset(self) -> None:
     self.__selected_component = None
     self.__selected_resource = None
     # Hide widgets
     self.__produces_spinbox_label.grid_forget()
     self.__produces_spinbox.grid_forget()
     self.__all_children_produce_spinbox_label.grid_forget()
     self.__all_children_produce_spinbox.grid_forget()
     self.__apply_to_all_children_button.grid_forget()
     # Set entries to default
     self.__resource_combobox['values'] = ()
     self.__resource_combobox_var.set(SELECT_RESOURCE)
     self.__produces_spinbox_var.set('')
     self.__all_children_produce_spinbox_var.set('')
     self.__cmp_label_var.set('')
     # Disable buttons
     change_controls_state(tk.DISABLED, self.__rename_resource_button,
                           self.__remove_resource_button)
     self.__taxonomy_tree.set_items([])
     self.__taxonomy_tree.grid_forget()
 def __on_has_association_changed(self, *_):
     """Executed whenever the __has_association_checkbox is toggled"""
     if self.__selected_component:
         has_association = self.__has_association_checkbox_var.get()
         if has_association:
             if not self.__selected_component.association:
                 self.__selected_component.association = Association()
             change_controls_state(tk.NORMAL, self.__has_min_checkbox,
                                   self.__has_max_checkbox)
         else:
             self.__has_min_checkbox_var.set(
                 False)  # Reset and block controls
             self.__has_max_checkbox_var.set(False)
             self.__min_spinbox_var.set('')
             self.__max_spinbox_var.set('')
             change_controls_state(tk.DISABLED, self.__has_max_checkbox,
                                   self.__has_min_checkbox,
                                   self.__max_spinbox, self.__min_spinbox)
             self.__selected_component.association = None
         self.__taxonomy_tree.update_values(self.__selected_component)
예제 #25
0
    def __add(self, cmp_name: str, level: int,
              parent_id: Optional[int]) -> None:
        """Executed after creating of a new component.

        :param cmp_name: Name of a new component
        :param level: Level of the new component.
        :param parent_id: Id of the parent of the new component.
        """
        cmp = Component(cmp_name,
                        level,
                        parent_id=parent_id,
                        is_leaf=True,
                        symmetry_breaking=True)
        self.__state.model.add_component(cmp)
        self.__taxonomy_tree.add_item(cmp)
        self.__selected_component = cmp
        self.__cmp_name_var.set(trim_string(cmp.name, length=22))
        change_controls_state(tk.NORMAL, self.__remove_button,
                              self.__remove_recursively_button,
                              self.__rename_button)
        pub.sendMessage(actions.TAXONOMY_EDITED)
예제 #26
0
    def __on_combobox_changed(self, *_):
        """Executed whenever the __resource_combobox value changes."""
        res_name = self.__resource_combobox_var.get()
        resource = self.__state.model.get_resource(name=res_name)
        if resource:
            # Enable buttons
            change_controls_state(tk.NORMAL, self.__rename_resource_button,
                                  self.__remove_resource_button)
            self.__selected_resource = resource
            if self.__selected_component:
                if self.__selected_component.is_leaf:
                    produced = 0
                    if resource.id_ in self.__selected_component.produces:
                        produced = self.__selected_component.produces[
                            self.__selected_resource.id_]
                    self.__produces_spinbox_var.set(produced)
                else:
                    self.__all_children_produce_spinbox_var.set('')

            # Show the taxonomy tree
            self.__taxonomy_tree.grid(row=0, column=1, sticky=tk.NSEW)
            self.__update_tree()
    def __on_show_all_predicates_changed(self, *_):
        """Executes whenever __show_all_predicates_checkbox is toggled."""
        show_all = self.__show_all_predicates_checkbox_var.get()
        if show_all:
            state = tk.DISABLED
            # Set all specific predicate checkboxes to unchecked
            for (var, _0,
                 _1) in self.__show_predicates_checkbox_widgets_dict.values():
                var.set(False)
        else:
            state = tk.NORMAL
            # Restore values of specific predicate checkboxes
            for predicate_symbol, show in self.__settings.shown_predicates_dict.items(
            ):
                self.__show_predicates_checkbox_widgets_dict[predicate_symbol][
                    0].set(show)

        # Block / unblock specific predicate checkboxes
        change_controls_state(
            state, *[
                checkbox for (_0, _1, checkbox) in
                self.__show_predicates_checkbox_widgets_dict.values()
            ])
예제 #28
0
    def __remove(self):
        """Executed whenever the __remove_resource_button is pressed.
        Removes __selected_resource from model.
        """
        if self.__selected_resource:
            self.__state.model.remove_resource(self.__selected_resource)
            self.__resource_combobox['values'] = sorted(
                self.__state.model.get_all_resources_names())
            self.__selected_resource = None

            self.__resource_combobox_var.set(SELECT_RESOURCE)
            # Disable buttons
            change_controls_state(tk.DISABLED, self.__rename_resource_button,
                                  self.__remove_resource_button)
            # Hide widgets
            self.__cmp_label.grid_forget()
            self.__produces_spinbox_label.grid_forget()
            self.__produces_spinbox.grid_forget()
            self.__all_children_produce_spinbox_label.grid_forget()
            self.__all_children_produce_spinbox.grid_forget()
            self.__apply_to_all_children_button.grid_forget()
            # Hide the taxonomy tree
            self.__taxonomy_tree.grid_forget()
    def _reset(self) -> None:
        self.__selected_component = None
        # Disable widgets
        change_controls_state(tk.DISABLED,
                              self.__exact_minimum_spinbox,
                              self.__symm_breaking_checkbox,
                              self.__range_radiobutton,
                              self.__exact_value_radiobutton,
                              self.__exact_minimum_spinbox)

        # Hide 'for all children' widgets
        self.__apply_symmetry_breaking_to_all_children_button.grid_forget()
        self.__max_spinbox_label.grid_forget()
        self.__max_spinbox.grid_forget()
        self.__apply_count_to_all_children_button.grid_forget()

        # Set entries to default
        self.__exact_minimum_spinbox_var.set('')
        self.__max_spinbox_var.set('')
        self.__cmp_label_var.set('')
        self.__symm_breaking_checkbox_var.set(False)
        self.__global_symmetry_breaking_checkbox_var.set(False)
        # Clear the tree
        self.__taxonomy_tree.set_items([])
예제 #30
0
    def __remove(self, recursively=False) -> None:
        """Executed whenever the __rename_button or __remove_recursively_button is pressed.

        :param recursively: True if __remove_recursively_button is pressed. Removes the selected component and all of
            its children; Otherwise set to False and removes only the __selected_component, setting the
            parent_id of its children to __selected_component.parent_id.
        """
        if self.__selected_component:
            if recursively:
                _, removed_ctrs = self.__state.model.remove_component_recursively(
                    self.__selected_component)
                self.__taxonomy_tree.remove_item_recursively(
                    self.__selected_component)
            else:
                _, removed_ctrs = self.__state.model.remove_component_preserve_children(
                    self.__selected_component)
                self.__taxonomy_tree.remove_item_preserve_children(
                    self.__selected_component)
            # Prompt about removing the constraints
            if removed_ctrs:
                removed_ctrs_names_list_string = f'    {PUNCTUATOR_SYMBOL} '
                removed_ctrs_names_list_string += f"\n    {PUNCTUATOR_SYMBOL} ".join(
                    [ctr.name for ctr in removed_ctrs])
                messagebox.showwarning(
                    message=f'Removed component was present in constraints.'
                    f'\nThe following constraints were thus removed:'
                    f'\n{removed_ctrs_names_list_string}',
                    parent=self)

            # Disable constrols
            change_controls_state(tk.DISABLED, self.__remove_button,
                                  self.__remove_recursively_button,
                                  self.__rename_button)
            self.__selected_component = None
            self.__cmp_name_var.set('')
            pub.sendMessage(actions.TAXONOMY_EDITED)