# Path: robot_designer_plugin/core/config.py
# PLUGIN_PREFIX = "robotdesigner"
# 
# EXCEPTION_MESSAGE = "\tException:\t%s\n\tMessages:\n\t\t%s\n%s\n%s"
# 
# Path: robot_designer_plugin/core/logfile.py
# def LogFunction(func):
#     def func_logger(self, context):
# def log_callstack(back_trace=False):
# def log_callstack_last(back_trace=False):
# 
# Path: robot_designer_plugin/core/conditions.py
# class Condition(object):
#     """
#     Base Class for conditions.
# 
#     Classes should implement a ``check()`` method which returns a tuple of (bool,str) stating whether
#     the condition's are met and an (potentially) empty error message.
# 
#     Using the :meth:`.operators.RDOperator.Preconditions` decorator, the conditions that should be met
#     when executing an operator (i.e., a subclass of :class:`.operators.RDOperator`) are added to the classes'
#     list of preconditions and :meth:`check_conditions` is called when Blender executes the
#     :meth:`.operators.RDOperator.poll` method.
# 
#     .. note::
# 
#         Instances of this type should never be created.
# 
#     For examples see :class:`robot_designer_plugin.operators.helpers.ModelSelected`.
#     """
# 
#     @staticmethod
#     def check_conditions(*conditions):
#         """
#         Checks whether the arguments are met.
# 
#         :param conditions: A an arbitrary number of conditions
#         :type conditions: :class:`Condition` sub classes.
#         :return: Tuple(bool, str), True and empty string if all conditions are met. False and sting with message of
#         unmet conditions.
#         """
#         try:
#             check = [i.check() for i in conditions]
#             return all([i[0] for i in check]), "\n".join([i[1] for i in check if not i[0]])
# 
#         except Exception as e:
#             logger.error("Exception in check precondition!\n {} \nConditions: {}  {} {}".format(EXCEPTION_MESSAGE,
#                          type(e).__name__, e, log_callstack(), log_callstack(True), conditions))
#             return False, "Exception raised"
# 
#     @staticmethod
#     def call():
#         '''
#         Needs to be overridden in sub classes
# 
#         :raises: NotImplementedError
#         '''
#         raise NotImplementedError("Must be overridden in subclasses")
# 
# Path: robot_designer_plugin/core/gui.py
# class InfoBox(object):
#     """
#     This class collects messages (e.g., from :meth:`.operators.operators.RDOperator.poll`) and displays them
#     with an info, either in a separated box or the current layout.
# 
#     See :ref:`gui_development` for an example.
#     """
# 
#     global_messages = []
# 
#     def __init__(self, layout):
#         """
#         Constructor.
# 
#         :param layout: Blender gui element as passed to the
#             :meth:`robot_designer_plugin.interface.main.UserInterface.draw` method.
#         """
#         self.messages = []
#         self.layout = layout
# 
#     def add_message(self, message):
#         """
#         Adds a string message to the info box.
# 
#         :param message: message
#         :type message: str
#         """
#         self.messages.append(message)
# 
#     def draw_info(self, additional_messages=[], icon=StringConstants.info):
#         """
#         Draws the info box onto the layout.
# 
#         :param additional_messages: Additional messages can be appended.
#         """
#         messages = self.messages + additional_messages
#         if messages:
# 
#             column = self.layout.column(align=True)
#             for text in set(messages):
#                 column.label(text=text, icon=icon)
# 
#     @classmethod
#     def draw_global_info(cls, layout):
# 
#         if cls.global_messages:
#             ib = InfoBox(layout)
#             ib.draw_info(additional_messages=cls.global_messages, icon=StringConstants.error)


import inspect
import bpy
from .config import PLUGIN_PREFIX, EXCEPTION_MESSAGE
from .logfile import log_callstack, log_callstack_last, operator_logger as logger
from .conditions import Condition
from .gui import InfoBox
    .. literalinclude:: ../../../resources/templates/operator.py
        :emphasize-lines: 7-11,16-18, 31-33, 60-62
        :lines: 50-111
        :linenos:

    A template is located in ``<RobotDesignerDirectory>/resources/templates/operator.py`` (where you should insert
    the path to the repository) that can be used to quickly write new operators.
    """

    _pre_conditions = {}
    """Dictionary set by the :meth:`PreConditions` decorator. Stores the :class:`.conditions.Condition` that are
    checked for each :class:`RDOperator` -based operator"""

    logger = logger
    """For convenience, every the operators share a logging instance."""

    @classmethod
    def poll(cls, context):
        """
        The :meth:`bpy.types.Operator.poll` class method is called every time, an operator is to be executed, but
        also when it is placed in a guy (it becomes greyed out). This method is defined in this base class and
        the checks are defined by a list of :class:`.conditions.Condition` derived classes that are given by
        the :meth:`Preconditions` decorator. Derived classes do not need to override this method and should
        call the parent's method otherwise.

        :param context: The actual Blender :term:`context`.
        :type context: :class:`bpy.types.Context`
        :return:
        """
        if cls in cls._pre_conditions:

# Path: robot_designer_plugin/core/config.py
# PLUGIN_PREFIX = "robotdesigner"
# 
# EXCEPTION_MESSAGE = "\tException:\t%s\n\tMessages:\n\t\t%s\n%s\n%s"
# 
# Path: robot_designer_plugin/core/logfile.py
# def LogFunction(func):
#     def func_logger(self, context):
# def log_callstack(back_trace=False):
# def log_callstack_last(back_trace=False):
# 
# Path: robot_designer_plugin/core/conditions.py
# class Condition(object):
#     """
#     Base Class for conditions.
# 
#     Classes should implement a ``check()`` method which returns a tuple of (bool,str) stating whether
#     the condition's are met and an (potentially) empty error message.
# 
#     Using the :meth:`.operators.RDOperator.Preconditions` decorator, the conditions that should be met
#     when executing an operator (i.e., a subclass of :class:`.operators.RDOperator`) are added to the classes'
#     list of preconditions and :meth:`check_conditions` is called when Blender executes the
#     :meth:`.operators.RDOperator.poll` method.
# 
#     .. note::
# 
#         Instances of this type should never be created.
# 
#     For examples see :class:`robot_designer_plugin.operators.helpers.ModelSelected`.
#     """
# 
#     @staticmethod
#     def check_conditions(*conditions):
#         """
#         Checks whether the arguments are met.
# 
#         :param conditions: A an arbitrary number of conditions
#         :type conditions: :class:`Condition` sub classes.
#         :return: Tuple(bool, str), True and empty string if all conditions are met. False and sting with message of
#         unmet conditions.
#         """
#         try:
#             check = [i.check() for i in conditions]
#             return all([i[0] for i in check]), "\n".join([i[1] for i in check if not i[0]])
# 
#         except Exception as e:
#             logger.error("Exception in check precondition!\n {} \nConditions: {}  {} {}".format(EXCEPTION_MESSAGE,
#                          type(e).__name__, e, log_callstack(), log_callstack(True), conditions))
#             return False, "Exception raised"
# 
#     @staticmethod
#     def call():
#         '''
#         Needs to be overridden in sub classes
# 
#         :raises: NotImplementedError
#         '''
#         raise NotImplementedError("Must be overridden in subclasses")
# 
# Path: robot_designer_plugin/core/gui.py
# class InfoBox(object):
#     """
#     This class collects messages (e.g., from :meth:`.operators.operators.RDOperator.poll`) and displays them
#     with an info, either in a separated box or the current layout.
# 
#     See :ref:`gui_development` for an example.
#     """
# 
#     global_messages = []
# 
#     def __init__(self, layout):
#         """
#         Constructor.
# 
#         :param layout: Blender gui element as passed to the
#             :meth:`robot_designer_plugin.interface.main.UserInterface.draw` method.
#         """
#         self.messages = []
#         self.layout = layout
# 
#     def add_message(self, message):
#         """
#         Adds a string message to the info box.
# 
#         :param message: message
#         :type message: str
#         """
#         self.messages.append(message)
# 
#     def draw_info(self, additional_messages=[], icon=StringConstants.info):
#         """
#         Draws the info box onto the layout.
# 
#         :param additional_messages: Additional messages can be appended.
#         """
#         messages = self.messages + additional_messages
#         if messages:
# 
#             column = self.layout.column(align=True)
#             for text in set(messages):
#                 column.label(text=text, icon=icon)
# 
#     @classmethod
#     def draw_global_info(cls, layout):
# 
#         if cls.global_messages:
#             ib = InfoBox(layout)
#             ib.draw_info(additional_messages=cls.global_messages, icon=StringConstants.error)


# Path: robot_designer_plugin/core/operators.py
import inspect
import bpy
from .config import PLUGIN_PREFIX, EXCEPTION_MESSAGE
from .logfile import log_callstack, log_callstack_last, operator_logger as logger
from .conditions import Condition
from .gui import InfoBox

    .. literalinclude:: ../../../resources/templates/operator.py
        :emphasize-lines: 7-11,16-18, 31-33, 60-62
        :lines: 50-111
        :linenos:

    A template is located in ``<RobotDesignerDirectory>/resources/templates/operator.py`` (where you should insert
    the path to the repository) that can be used to quickly write new operators.
    """

    _pre_conditions = {}
    """Dictionary set by the :meth:`PreConditions` decorator. Stores the :class:`.conditions.Condition` that are
    checked for each :class:`RDOperator` -based operator"""

    logger = logger
    """For convenience, every the operators share a logging instance."""

    @classmethod
    def poll(cls, context):
        """
        The :meth:`bpy.types.Operator.poll` class method is called every time, an operator is to be executed, but
        also when it is placed in a guy (it becomes greyed out). This method is defined in this base class and
        the checks are defined by a list of :class:`.conditions.Condition` derived classes that are given by
        the :meth:`Preconditions` decorator. Derived classes do not need to override this method and should
        call the parent's method otherwise.

        :param context: The actual Blender :term:`context`.
        :type context: :class:`bpy.types.Context`
        :return:
        """
        if cls in cls._pre_conditions:

            check, messages = Condition.check_conditions(*cls._pre_conditions[cls])