class PinguinoConfig(object):

    #----------------------------------------------------------------------
    @classmethod
    def set_environ_vars(cls):
        """Configure some environ variables about OS and architecture.
        """

        #if not os.path.exists(os.path.join(os.getenv("PINGUINO_LIB"), "paths.cfg")):
            #logging.error("Missing: "+os.path.join(os.getenv("PINGUINO_LIB"), "paths.cfg"))
            #sys.exit()

        #config_paths = RawConfigParser()
        #config_paths.readfp(open(os.path.join(os.getenv("PINGUINO_LIB"), "paths.cfg"), "r")


        #RB20141116 : get the “bitness” of the current OS
        bitness, linkage = platform.architecture()
        os.environ["PINGUINO_OS_ARCH"] = bitness

        if os.name == "posix": #GNU/Linux
            os.environ["PINGUINO_OS_NAME"] = "linux"

        #Mac could return posix :/
        elif os.name == "os2":  #Mac OS X
            os.environ["PINGUINO_OS_NAME"] = "macosx"

        elif os.name == "nt":  #Windows
            os.environ["PINGUINO_OS_NAME"] = "windows"

        config_paths = RawConfigParser()
        config_paths.readfp(open(os.path.join(os.getenv("PINGUINO_LIB"), "qtgui", "config", "pinguino.{PINGUINO_OS_NAME}.conf".format(**os.environ)), "r"))

        #load path from paths.conf
        os.environ["PINGUINO_USER_PATH"] = os.path.expandvars(os.path.expanduser(config_paths.get("Paths", "user_path")))
        os.environ["PINGUINO_INSTALL_PATH"] = os.path.expandvars(os.path.expanduser(config_paths.get("Paths", "install_path")))
        os.environ["PINGUINO_USERLIBS_PATH"] = os.path.expandvars(os.path.expanduser(config_paths.get("Paths", "user_libs")))

        os.environ["PINGUINO_LIBS_PATH"] = os.path.expandvars(os.path.expanduser(os.path.dirname(config_paths.get("Paths", "pinguino_8_libs"))))

        os.environ["PINGUINO_8_LIBS_PATH"] = os.path.expandvars(os.path.expanduser(config_paths.get("Paths", "pinguino_8_libs")))
        os.environ["PINGUINO_32_LIBS_PATH"] = os.path.expandvars(os.path.expanduser(config_paths.get("Paths", "pinguino_32_libs")))

        # os.environ["PINGUINO_USERLIBS_PATH"] = os.path.expandvars(os.path.join(os.getenv("PINGUINO_USER_PATH"), "libraries"))
        os.environ["PINGUINO_DEFAULT_FILES"] = os.path.join(os.getenv("PINGUINO_USER_PATH"), "local")


    #----------------------------------------------------------------------
    @classmethod
    def check_user_files(cls):
        """Check existence of depends directories and created if missed."""

        #check instalation path
        if not os.path.exists(os.getenv("PINGUINO_INSTALL_PATH")):
            logging.warning("Missing Pinguino libraries instalation. "
                            "Make sure the paths in %s are correct."%os.path.join(os.getenv("PINGUINO_LIB"), "paths.conf"))

        #create ~/.pinguino
        if not os.path.exists(os.getenv("PINGUINO_USER_PATH")):
            makedirs(os.getenv("PINGUINO_USER_PATH"), exist_ok=True)
                
        #create ~/.pinguino/user
        if not os.path.exists(os.getenv("PINGUINO_DEFAULT_FILES")):
            makedirs(os.getenv("PINGUINO_DEFAULT_FILES"), exist_ok=True)
                
        #Check files and directories
        cls.check_locations()


    #----------------------------------------------------------------------
    @classmethod
    def check_locations(cls):
        """If not exist some directory then copy them from installation path."""

        cls.if_not_exist_then_copy(src=os.path.join(os.getenv("PINGUINO_LIBS_PATH"), "examples"),
                                   dst=os.path.join(os.getenv("PINGUINO_USER_PATH"), "examples"))

        cls.if_not_exist_then_copy(src=os.path.join(os.getenv("PINGUINO_LIBS_PATH"), "graphical_examples"),
                                   dst=os.path.join(os.getenv("PINGUINO_USER_PATH"), "graphical_examples"))

        cls.if_not_exist_then_copy(src=os.path.join(os.getenv("PINGUINO_LIBS_PATH"), "source"),
                                   dst=os.path.join(os.getenv("PINGUINO_USER_PATH"), "source"))

        cls.if_not_exist_then_copy(src=os.path.join(os.getenv("PINGUINO_INSTALL_PATH"), "p32", "obj"),
                                   dst=os.path.join(os.getenv("PINGUINO_USER_PATH"), "source", "obj"))

        cls.if_not_exist_then_copy(src=os.path.join(os.getenv("PINGUINO_LIB"), "qtgui", "config", "pinguino.%s.conf"%os.getenv("PINGUINO_OS_NAME")),
                                   dst=os.path.join(os.getenv("PINGUINO_USER_PATH"), "pinguino.conf"))


        if os.path.exists(os.getenv("PINGUINO_USERLIBS_PATH")):
            for lib in os.listdir(os.getenv("PINGUINO_USERLIBS_PATH")):
                src = os.path.join(os.getenv("PINGUINO_USERLIBS_PATH"), lib, "examples")
                if os.path.exists(src):
                    cls.if_not_exist_then_copy(src=src,
                                               dst=os.path.join(os.getenv("PINGUINO_USER_PATH"), "examples_libs", lib))


    #----------------------------------------------------------------------
    @classmethod
    def if_not_exist_then_copy(cls, src, dst):
        """The method name say all.

        Parameters
        ----------
        src: str
            Source file or directory.

        dst: str
            Destiny file or directory.
        """
        if not os.path.exists(src):
            return


        #When src is a file
        if os.path.isfile(src):
            if not os.path.exists(src): logging.warning("Missing: " + src)
            else:
                if not os.path.exists(dst): shutil.copy(src, dst)
            return

        #Create parent directories
        def prepare_directory(file_path):
            dir_, filename = os.path.split(file_path)
            all_dirs = []
            while not os.path.exists(dir_):
                all_dirs.append(dir_)
                dir_, dir2 = os.path.split(dir_)
            all_dirs.reverse()
            for dir_ in all_dirs: makedirs(dir_, exist_ok=True)

        #When src is a directory, copy file by file
        all_files = []
        for path, dirs, files in os.walk(src):
            for f in files:
                file_path_src = os.path.join(path, f)
                file_path_dst = dst + os.path.join(path, f).replace(src, "")

                if not os.path.exists(file_path_dst):
                    logging.warning("Copying: " + file_path_dst)
                    prepare_directory(file_path_dst)
                    shutil.copy(file_path_src, file_path_dst)


    #----------------------------------------------------------------------
    @classmethod
    def update_pinguino_extra_options(self, config, pinguino_object):
        """Load on Pinguino Object the advance configuration for 32 bit.

        Parameters
        ----------
        config: RawConfigParser
            Config file.
        pinguino_object: Pinguino()
            Pinguino
        """

        pinguino_object.MIPS16 = str(config.config("Board", "mips16", True)).lower()
        pinguino_object.HEAPSIZE = str(config.config("Board", "heapsize", 512))
        pinguino_object.OPTIMIZATION = config.config("Board", "optimization", "-O3")


    #----------------------------------------------------------------------
    @classmethod
    def update_pinguino_paths(cls, config, pinguino_object, prefix=None, workspace=None):
        """Load paths of libraries and compilers.

        Parameters
        ----------
        config: RawConfigParser
            Config file.
        pinguino_object: Pinguino()
            Pinguino
        prefix: str, optional
            Path for search libraries and compilers, default is absolute path from root.
        workspace: str,optional
            Path for makefiles and temp files, default is ~/.pinguino/source

        """

        user_sdcc_bin = config.get_path("sdcc_bin", prefix)
        if user_sdcc_bin: pinguino_object.P8_SDCC_BIN = user_sdcc_bin
        #else: logging.warning("Missing path to 'sdcc_bin': '%s'"%user_sdcc_bin)

        user_sdcc_bin = config.get_path("xc8_bin", prefix)
        if user_sdcc_bin: pinguino_object.P8_XC8_BIN = user_sdcc_bin
        #else: logging.warning("Missing path to 'xc8_bin': '%s'"%user_sdcc_bin)

        user_gcc_bin = config.get_path("gcc_bin", prefix)
        if user_gcc_bin: pinguino_object.P32_GCC_BIN = user_gcc_bin
        #else: logging.warning("Missing path to 'gcc_bin': '%s'"%user_gcc_bin)

        if workspace:
            pinguino_object.SOURCE_DIR = workspace
        else:
            pinguino_source = os.path.join(os.getenv("PINGUINO_USER_PATH"), "source")
            #pinguino_source = os.path.join(os.path.dirname(os.getenv("PINGUINO_8_LIBS_PATH")), "source")
            if pinguino_source: pinguino_object.SOURCE_DIR = pinguino_source
            else: logging.warning("Missing path to 'source': '%s'"%pinguino_source)

        pinguino_8_libs = config.get_path("pinguino_8_libs", prefix)
        if pinguino_8_libs: pinguino_object.P8_DIR = pinguino_8_libs
        else: logging.warning("Missing path to '8_libs': '%s'"%pinguino_8_libs)

        pinguino_32_libs = config.get_path("pinguino_32_libs", prefix)
        if pinguino_32_libs: pinguino_object.P32_DIR = pinguino_32_libs
        else: logging.warning("Missing path to '32_libs': '%s'"%pinguino_32_libs)


    #----------------------------------------------------------------------
    @classmethod
    def update_user_libs(cls, pinguino_object, p8=[], p32=[], pdl=[]):
        """Reload paths for user installed libraries.

        Parameters
        ----------
        pinguino_object: Pinguino()
            Pinguino
        """

        pinguino_object.USER_P8_LIBS = cls.get_p8_libraries() + p8
        pinguino_object.USER_P32_LIBS = cls.get_p32_libraries() + p32
        pinguino_object.USER_PDL = cls.get_pdl_libraries() + pdl


    #----------------------------------------------------------------------
    @classmethod
    def get_p8_libraries(cls):
        """
        This is path where are .c files.

        """
        p8_libs = []
        if os.path.exists(os.getenv("PINGUINO_USERLIBS_PATH")):
            for lib in os.listdir(os.getenv("PINGUINO_USERLIBS_PATH")):
                p8 = os.path.join(os.getenv("PINGUINO_USERLIBS_PATH"), lib, "p8")
                if os.path.exists(p8):
                    p8_libs.append(p8)

        os_name = os.getenv("PINGUINO_OS_NAME")
        if os.getenv("PINGUINO_P8", False):
            if os_name == "windows":
                p8_libs.extend(os.getenv("PINGUINO_P8").split(";"))
            elif os_name == "linux":
                p8_libs.extend(os.getenv("PINGUINO_P8").split(":"))
            #FIXME_OSX
            # elif os_name == "macosx":
                # p32_libs.extend(os.getenv(PINGUINO_P32).aplit(":"))


        return p8_libs


    #----------------------------------------------------------------------
    @classmethod
    def get_p32_libraries(cls):
        """

        This is path where are .c files.

        """
        p32_libs = []
        if os.path.exists(os.getenv("PINGUINO_USERLIBS_PATH")):
            for lib in os.listdir(os.getenv("PINGUINO_USERLIBS_PATH")):
                p32 = os.path.join(os.getenv("PINGUINO_USERLIBS_PATH"), lib, "p32")
                if os.path.exists(p32):
                    p32_libs.append(p32)

        os_name = os.getenv("PINGUINO_OS_NAME")
        if os.getenv("PINGUINO_P32", False):
            if os_name == "windows":
                p32_libs.extend(os.getenv("PINGUINO_P32").split(";"))
            elif os_name == "linux":
                p32_libs.extend(os.getenv("PINGUINO_P32").split(":"))
            #FIXME_OSX
            # elif os_name == "macosx":
                # p32_libs.extend(os.getenv(PINGUINO_P32).aplit(":"))

        return p32_libs


    #----------------------------------------------------------------------
    @classmethod
    def get_pdl_libraries(cls):
        """

        This is individual paths for each .pdl or pdl32.

        """

        pdl_libs = []
        if os.path.exists(os.getenv("PINGUINO_USERLIBS_PATH")):
            for lib in os.listdir(os.getenv("PINGUINO_USERLIBS_PATH")):
                pdls = os.path.join(os.getenv("PINGUINO_USERLIBS_PATH"), lib, "pdl")
                if os.path.exists(pdls):
                    for pdl in os.listdir(pdls):
                        if pdl.endswith(".pdl") or pdl.endswith(".pdl32"):
                            pdl_libs.append(os.path.join(os.getenv("PINGUINO_USERLIBS_PATH"), lib, "pdl", pdl))

        os_name = os.getenv("PINGUINO_OS_NAME")
        if os.getenv("PINGUINO_PDL", False):
            if os_name == "windows":
                pdl_libs.extend(os.getenv("PINGUINO_PDL").split(";"))
            elif os_name == "linux":
                pdl_libs.extend(os.getenv("PINGUINO_PDL").split(":"))
            #FIXME_OSX
            # elif os_name == "macosx":
                # pdl_libs.extend(os.getenv(PINGUINO_P32).aplit(":"))


        return pdl_libs class UpdateAutocompleter(QtCore.QThread):
    """"""
    signal_add_autocompleter = QtCore.Signal(str, str, str)
    signal_rm_autocompleter = QtCore.Signal(str)

    signal_set_variables = QtCore.Signal(list)
    signal_set_directives = QtCore.Signal(list)
    signal_set_functions = QtCore.Signal(list)


    #----------------------------------------------------------------------
    def __init__(self, parent=None):
        """Constructor"""

        # Python3 compatibility
        if os.getenv("PINGUINO_PYTHON") is "3":
            #Python3
            super().__init__(parent)
        else:
            #Python2
            super(UpdateAutocompleter, self).__init__(parent)


    #----------------------------------------------------------------------
    def set_files(self, files):
        """"""
        self.parser = PinguinoParser(files)


    #----------------------------------------------------------------------
    def run(self):

        self.completer_functions = []
        self.functions_args = {}
        functions_parse = self.parser.get_functions()
        self.signal_set_functions.emit(functions_parse)

        for funtion in functions_parse:
            self.completer_functions.append(funtion["name"])
            self.functions_args[funtion["name"]] = "{name}({{{{{args}}}}});".format(**funtion)

        self.completer_variables = []
        variables_parse = self.parser.get_variables()
        self.signal_set_variables.emit(variables_parse)

        for variable in variables_parse:
            self.completer_variables.append([variable["name"], variable["type"]])

        self.completer_directives = []
        directives_parse = self.parser.get_directives()
        self.signal_set_directives.emit(directives_parse)

        for directive in directives_parse:
            self.completer_directives.append(directive["name"])

        self.signal_rm_autocompleter.emit("directives")
        self.signal_rm_autocompleter.emit("variables")
        self.signal_rm_autocompleter.emit("functions")

        #for item in self.completer_directives:
            #self.signal_add_autocompleter.emit("directives", item, "iconDirectives")
        self.signal_add_autocompleter.emit("directives", self.completer_directives, "iconDirectives")

        #for item in self.completer_functions:
            #self.signal_add_autocompleter.emit("functions", item, "iconFunction")
        self.signal_add_autocompleter.emit("functions", self.completer_functions, "iconFunction")

        for item, type_ in self.completer_variables:
            type_ = type_.split()[-1]
            if type_ in "int float bool byte bool double struct union".split():
                icon = "icon{}".format(type_.capitalize())
            else:
                icon = ""

            self.signal_add_autocompleter.emit("variables", item, icon) class PinguinoParser(object):
    """"""
    #----------------------------------------------------------------------
    def __init__(self, files):
        """"""
        self.files = files


    #----------------------------------------------------------------------
    def get_variables(self):
        """"""
        regex_variables = "[\s]*(volatile|register|static|extern)*[\s]*(unsigned|signed)*[\s]*(" + "|".join(data_types) + ")+[\s]*( \* )*[\s]*([ \w\[\]=,.{}\"']*);"
        # regex_variables = "[\s]*(volatile|register|static|extern)*[\s]*(unsigned|signed)*[\s]*(short|long)*[\s]*(" + "|".join(data_types) + ")[\s]*+([*])*([ \w\[\]=,.{}\"'\*]*);"

        variables = []

        # self.signal_set_variables.emit(variables)

        # # if files is None:
        # files = self.ide.get_files_to_explore()

        for file_ in self.files:

            filename = file_["filename"]
            content = file_["content"]

            content = remove_comments(content)
            content = content.split("\n")

            for line in range(len(content)):
                match = re.match(regex_variables, content[line])
                if match:
                    args = match.groups()[4]
                    l = []
                    index = 0
                    while index < len(args):
                        if args[index] == "{":
                            start = index
                            bracket = 1

                            while bracket != 0:
                                index += 1
                                if args[index] == "{": bracket += 1
                                if args[index] == "}": bracket -= 1
                            end = index

                            l.append(args[start:end+1])

                        else: index += 1

                    for j in l: args = args.replace(j, "", 1)
                    args = args.split(",")
                    args = map(lambda a:a[:a.find("=")] if "=" in a else a, args)

                    type_ = " ".join([("" if not match.groups()[3] else "pointer to "),
                                    ("" if not match.groups()[0] else match.groups()[0]),
                                    ("" if not match.groups()[1] else match.groups()[1]),
                                    (match.groups()[2]),
                                    # match.groups()[3]
                                    ])

                    while type_.startswith(" "): type_ = type_[1:]

                    for arg in args:
                        this_variable = {}
                        this_variable["type"] = type_
                        if re.match("(.*)(\[.*\])", arg):
                            this_variable["name"] = re.match("(.*)(\[.*\])", arg).groups()[0]
                        else:
                            this_variable["name"] = arg
                        #this_variable["value"] = match.groups()[6]
                        this_variable["line"] = line + 1
                        this_variable["filename"] = filename
                        variables.append(this_variable)


        return variables


    #----------------------------------------------------------------------
    def get_directives(self):

        regex_directive = "[\s]*#(" + "|".join(preprocessor_commands)+ ")[\s]+<?[\s]*([\w.]*)[\s]*>?[\s]*([\S]*)"

        directives = []

        # files = self.ide.get_files_to_explore()

        for file_ in self.files:

            filename = file_["filename"]
            content = file_["content"]

            content = remove_comments(content)
            content = content.split("\n")

            for line in range(len(content)):
                match = re.match(regex_directive, content[line])
                this_directive = {}
                if match:
                    this_directive["type"] = "#" + match.groups()[0]
                    this_directive["name"] = match.groups()[1]
                    this_directive["value"] = match.groups()[2]
                    this_directive["line"] = line + 1
                    this_directive["filename"] = filename
                    directives.append(this_directive)

        return directives


    #----------------------------------------------------------------------
    def get_functions(self):

        regex_function = "[\s]*(unsigned|signed|static|long|PUBLIC)*[\s]*(" + "|".join(data_types) + ")[\s]+(\*?)[\s]*([*\w]+)[\s]*\(([\w ,*.\[\]]*)\)[\s]*"
        # regex_function = "[\s]*(unsigned|signed|long|PUBLIC)*[\s]*(" + "|".join(data_types) + ")[\s]*(\*?)[\s]*([*\w]+)[\s]*\(([\s\w ,*.\[\]]*)\)[\s]*"
        #regex_function_content = "[\s]*{}[\s]*\{[\s\S]*\}[\s]*

        functions = []
        # files = self.ide.get_files_to_explore()
        ignore_spaces = bool(len(self.files) > 1)

        for file_ in self.files:

            filename = file_["filename"]
            content = file_["content"]


            # content_comments = content

            content_no_comments = remove_comments(content, ignore_spaces=ignore_spaces)
            content_list = remove_comments(content).split("\n")

            for line in range(len(content_list)):

                match = re.match(regex_function, content_list[line])
                if match:
                    this_function = {}

                    # content_no_comments = editor.text_edit.toPlainText()
                    index =  content_no_comments.find(content_list[line])
                    index_start = index
                    index_end = index
                    bracket = 1

                    try:
                        while  content_no_comments[index_end] != "{": index_end += 1
                    except IndexError:
                        bracket = 0

                    while bracket != 0:
                        index_end += 1
                        try:
                            if  content_no_comments[index_end] == "{": bracket += 1
                            elif  content_no_comments[index_end] == "}": bracket -= 1
                        except IndexError:
                            index_end = index_start - 1
                            break

                    count =  content_no_comments[index_start:index_end+1].count("\n")

                    # this_function["content"] = content_comments[index_start:index_end+1]
                    # this_function["line"] = (str(line + 1), str(line + 1 + count))
                    this_function["line"] = line + 1
                    this_function["name"] = match.groups()[2] + match.groups()[3]
                    this_function["return"] = ("" if not match.groups()[2] else "pointer to ") + ((match.groups()[0] + " " + match.groups()[1]) if match.groups()[0] else match.groups()[1])
                    this_function["return_true"] = ((match.groups()[0] + " " + match.groups()[1]) if match.groups()[0] else match.groups()[1])
                    this_function["return_true"] = this_function["return_true"].replace("PUBLIC ", "")
                    this_function["args"] = match.groups()[4]
                    this_function["filename"] = filename
                    functions.append(this_function)

        return functions class PinguinoCodeEditor(QWidget):

    #----------------------------------------------------------------------
    def __init__(self, highlighter):

        super(PinguinoCodeEditor, self).__init__()

        self.setObjectName("PinguinoCodeEditor")

        self.gridLayout_0 = QtWidgets.QGridLayout(self)
        self.gridLayout_0.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_0.setSpacing(0)

        self.line_number = LineNumber(self)
        self.line_number.setMinimumSize(QtCore.QSize(41, 0))
        self.line_number.setMaximumSize(QtCore.QSize(41, 16777215))
        self.gridLayout_0.addWidget(self.line_number, 0, 0, 1, 1)

        self.text_edit = CustomTextEdit(self, self.line_number, highlighter)
        self.text_edit.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.gridLayout_0.addWidget(self.text_edit, 0, 3, 1, 1)

        self.widget = QtWidgets.QWidget(self)
        self.widget.setMinimumSize(QtCore.QSize(10, 0))
        self.gridLayout_0.addWidget(self.widget, 0, 2, 1, 1)


        palette = QtGui.QPalette(self.widget.palette())
        self.widget.setAutoFillBackground(True)
        palette.setColor(QtGui.QPalette.Window, QtGui.QColor("#F0F0F0"))
        self.widget.setPalette(palette)

        #palette = QtGui.QPalette(self.palette())
        #self.setAutoFillBackground(True)
        #palette.setColor(QtGui.QPalette.Base, QtGui.QColor("#FFFFFF"))
        #self.setPalette(palette)

        self.line_number.setTextEdit(self.text_edit)
        self.text_edit.viewport().installEventFilter(self)


    #----------------------------------------------------------------------
    def set_autocompleter(self, autocompleter):
        """"""
        self.text_edit.set_autocompleter(autocompleter)

    #----------------------------------------------------------------------
    def eventFilter(self, object_, event):

        self.line_number.update()
        self.text_edit.brace_match()
        return False


    #----------------------------------------------------------------------
    def set_font_size(self, font_size):

        font = self.text_edit.font()
        font.setPointSize(font_size)
        self.text_edit.setFont(font)


    #----------------------------------------------------------------------
    def set_font_family(self, font_family, fixed_pitch=True):

        font = self.text_edit.font()
        font.setFamily(font_family)
        font.setFixedPitch = fixed_pitch
        self.text_edit.setFont(font) class Decorator(object):

    #----------------------------------------------------------------------
    @classmethod
    def requiere_open_files(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                if Pinguino.get_tab().count():
                    return fn(Pinguino, *args, **kwargs)
                else:
                    #print("No files are open.")
                    return None
            return wrapped
        return actualdecorator

    #----------------------------------------------------------------------
    @classmethod
    def timer(cls, time_):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                name = "timer_" + fn.__name__
                setattr(Pinguino, name, QtCore.QTimer())
                atr = getattr(Pinguino, name)
                QtCore.QObject.connect(atr, QtCore.SIGNAL("timeout()"), lambda :fn(Pinguino, *args, **kwargs))
                atr.start(time_)
                return name, atr
            return wrapped
        return actualdecorator

    #----------------------------------------------------------------------
    @classmethod
    def call_later(cls, time_=100):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                QtCore.QTimer.singleShot(time_, lambda :fn(Pinguino, *args, **kwargs))
            return wrapped
        return actualdecorator

    #----------------------------------------------------------------------
    @classmethod
    def requiere_browser_tab(cls, name):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                current_tab_name = Pinguino.main.tabWidget_browser.currentWidget().objectName()
                Pinguino.main.tabWidget_browser.accessibleName
                if current_tab_name == name:
                    return fn(Pinguino, *args, **kwargs)
                else:
                    #print(name + " not in focus.")
                    return None
            return wrapped
        return actualdecorator


    #----------------------------------------------------------------------
    @classmethod
    def requiere_tools_tab(cls, name):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                current_tab_name = Pinguino.main.tabWidget_tools.currentWidget().objectName()
                if current_tab_name == name:
                    return fn(Pinguino, *args, **kwargs)
                else:
                    #print(name + " not in focus.")
                    return None
            return wrapped
        return actualdecorator


    #----------------------------------------------------------------------
    @classmethod
    def requiere_text_mode(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                if (Pinguino.is_graphical() is False) and (not Pinguino.is_widget()):
                    # editor = Pinguino.get_tab().currentWidget()
                    # if editor.objectName() == "PinguinoCodeEditor":
                        # return fn(Pinguino, *args, **kwargs)
                    # else: return None
                    if Pinguino.is_graphical() is False:
                        return fn(Pinguino, *args, **kwargs)
                    elif Pinguino.is_graphical() is True:
                        return None
                else: return None
            return wrapped
        return actualdecorator

    #----------------------------------------------------------------------
    @classmethod
    def requiere_graphical_mode(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                if Pinguino.is_graphical() is True:
                    return fn(Pinguino, *args, **kwargs)
                elif Pinguino.is_graphical() is False:
                    return None
            return wrapped
        return actualdecorator

    #----------------------------------------------------------------------
    @classmethod
    def requiere_main_focus(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                if Pinguino.isActiveWindow():
                    return fn(Pinguino, *args, **kwargs)
                else:
                    #print("Main inactive.")
                    return None
            return wrapped
        return actualdecorator

    #----------------------------------------------------------------------
    @classmethod
    def requiere_line_edit_content(cls, line_edit):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                if getattr(getattr(Pinguino, line_edit.split(".")[0]), line_edit.split(".")[1]).text():
                    return fn(Pinguino, *args, **kwargs)
                else:
                    return None
            return wrapped
        return actualdecorator

    #----------------------------------------------------------------------
    @classmethod
    def requiere_file_saved(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                if Pinguino.is_graphical() is True:
                    saved = Pinguino.PinguinoKIT.ide_save_file(*args, **kwargs)
                    if saved: fn(Pinguino, *args, **kwargs)
                    else: Dialogs.save_before_compile(Pinguino)
                elif Pinguino.is_graphical() is False:
                    saved = Pinguino.ide_save_file(*args, **kwargs)
                    if saved: fn(Pinguino, *args, **kwargs)
                    else: Dialogs.save_before_compile(Pinguino)
            return wrapped
        return actualdecorator


    #----------------------------------------------------------------------
    @classmethod
    def requiere_can_compile(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                if os.getenv("PINGUINO_CAN_COMPILE") == "True":
                    return fn(Pinguino, *args, **kwargs)
                else:
                    #print("Missing libraries and/or compiler")
                    Dialogs.warning_message(Pinguino, QtWidgets.QApplication.translate("Dialogs", "Impossible to compile this file, missing libraries and/or compiler."))
                    return None
            return wrapped
        return actualdecorator


    #----------------------------------------------------------------------
    @classmethod
    def update_toolbar(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                count = Pinguino.get_tab().count()
                Pinguino.main.actionCompile.setEnabled(bool(count))
                Pinguino.main.actionClose_file.setEnabled(bool(count))
                Pinguino.main.actionSearch.setEnabled(bool(count))
                Pinguino.main.actionSearch_and_replace.setEnabled(bool(count))
                Pinguino.main.actionPaste.setEnabled(bool(count))

                if not count:
                    Pinguino.main.actionUpload.setEnabled(False)


                if Pinguino.is_graphical() is False:
                    editor = Pinguino.get_current_editor()
                    textcursor = editor.text_edit.textCursor()
                    Pinguino.main.actionCut.setEnabled(bool(textcursor.selectedText()))
                    Pinguino.main.actionCopy.setEnabled(bool(textcursor.selectedText()))

                else:
                    Pinguino.main.actionCut.setEnabled(False)
                    Pinguino.main.actionCopy.setEnabled(False)
                    Pinguino.main.actionUndo.setEnabled(False)
                    Pinguino.main.actionRedo.setEnabled(False)


                return fn(Pinguino, *args, **kwargs)
            return wrapped
        return actualdecorator


    #----------------------------------------------------------------------
    @classmethod
    def connect_features(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                if Pinguino.is_graphical() is True:
                    return getattr(Pinguino.PinguinoKIT, fn.__name__)(Pinguino, *args, **kwargs)
                elif Pinguino.is_graphical() is False:
                    return fn(Pinguino, *args, **kwargs)
            return wrapped
        return actualdecorator


    #----------------------------------------------------------------------
    @classmethod
    def if_autocomplete_is_enable(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                if Pinguino.main.actionAutocomplete.isChecked():
                    return fn(Pinguino, *args, **kwargs)
                #else: return None
            return wrapped
        return actualdecorator


    # #----------------------------------------------------------------------
    # @classmethod
    # def debug_time(cls):
        # def actualdecorator(fn):
            # @functools.wraps(fn)
            # def wrapped(Pinguino, *args, **kwargs):
                # inicio = time.time()
                # retorno = fn(Pinguino, *args, **kwargs)
                # fin = time.time()
                # Pinguino.write_log("debug: " + fn.__name__ + "\nTime: %.7fs\n" %(fin - inicio))
                # return retorno
            # return wrapped
        # return actualdecorator


    #----------------------------------------------------------------------
    @classmethod
    def clear_highlighted_lines(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):
                Pinguino.editor_clear_highlighted_lines()
                return fn(Pinguino, *args, **kwargs)
            return wrapped
        return actualdecorator



    #----------------------------------------------------------------------
    @classmethod
    def debug_method(cls):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):

                try:
                    return fn(Pinguino, *args, **kwargs)
                except:
                    error = traceback.format_exc()
                    logging.debug(error)
                    cls.submmit_bug = SubmitBug(Pinguino, error)
                    cls.submmit_bug.show()
                    return

            return wrapped
        return actualdecorator


    #----------------------------------------------------------------------
    @classmethod
    def alert_tab(cls, widget_name):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):

                widget = getattr(Pinguino.main, widget_name)

                tab = widget.parent().parent()
                index = tab.indexOf(widget)
                tabbar = tab.tabBar()
                orig_c = tabbar.tabTextColor(0)

                for i in range(0, 8, 2):
                    QtCore.QTimer.singleShot(300*i, lambda :tabbar.setTabTextColor(index, orig_c))
                    QtCore.QTimer.singleShot((300*i)+300, lambda :tabbar.setTabTextColor(index, QtCore.Qt.red))
                QtCore.QTimer.singleShot(500*20, lambda :tabbar.setTabTextColor(index, orig_c))
                return fn(Pinguino, *args, **kwargs)

            return wrapped
        return actualdecorator

    #----------------------------------------------------------------------
    @classmethod
    def show_tab(cls, widget_name):
        def actualdecorator(fn):
            @functools.wraps(fn)
            def wrapped(Pinguino, *args, **kwargs):

                widget = getattr(Pinguino.main, widget_name)

                tab = widget.parent().parent()
                index = tab.indexOf(widget)
                tab.setCurrentIndex(index)

                return fn(Pinguino, *args, **kwargs)

            return wrapped
        return actualdecorator

    # #----------------------------------------------------------------------
    # @classmethod
    # def reload_project(cls):
        # def actualdecorator(fn):
            # @functools.wraps(fn)
            # def wrapped(Pinguino, *args, **kwargs):

                # if Pinguino.is_project():
                    # Pinguino.reload_project()

                # return fn(Pinguino, *args, **kwargs)

            # return wrapped
        # return actualdecorator class Dialogs(object):

    #----------------------------------------------------------------------
    @classmethod
    def set_save_file(cls, parent, filename, dirpath=None):

        if dirpath is None: dirpath = parent.get_default_dir()
        if filename.endswith("*"): filename = filename[:-1]
        ext = os.path.splitext(os.path.split(filename)[1])[1]
        save_filename = QtWidgets.QFileDialog.getSaveFileName(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Save"),
                os.path.join(dirpath, filename),
                QtWidgets.QApplication.translate("Dialogs", "Pinguino files (*{});;All Files (*)".format(ext)))
        if save_filename: return save_filename[0], os.path.split(save_filename[0])[1]
        else: return None, None


    #----------------------------------------------------------------------
    @classmethod
    def set_open_file(cls, parent, exts="*.pde *.gpde *.ppde", dirpath=None):

        if dirpath is None:dirpath = parent.get_default_dir()
        open_file = QtWidgets.QFileDialog.getOpenFileName(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Open"),
                dirpath,
                QtWidgets.QApplication.translate("Dialogs", "Pinguino Files ({});;All Files (*)".format(exts)))
        if open_file[0]:
            return open_file[0]
        else: return None

    #----------------------------------------------------------------------
    @classmethod
    def set_open_files(cls, parent, exts="*.pde *.gpde *.ppde", dirpath=None):

        if dirpath is None:dirpath = parent.get_default_dir()
        open_files = QtWidgets.QFileDialog.getOpenFileNames(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Open"),
                dirpath,
                QtWidgets.QApplication.translate("Dialogs", "Pinguino Files ({});;All Files (*)".format(exts)))
        if open_files[0]:
            return open_files[0]
        else: return None


    #----------------------------------------------------------------------
    @classmethod
    def set_open_hex(cls, parent, dirpath=None):

        if dirpath is None:dirpath = parent.get_default_dir()
        open_file = QtWidgets.QFileDialog.getOpenFileName(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Select"),
                dirpath,
                QtWidgets.QApplication.translate("Dialogs", "Hex Files (*.hex);;All Files (*)"))
        if open_file: return open_file[0]
        else: return None


    #----------------------------------------------------------------------
    @classmethod
    def set_no_saved_file(cls, parent, filename):

        options = QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Discard | QtWidgets.QMessageBox.Cancel
        reply = QtWidgets.QMessageBox.question(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Save"),
                QtWidgets.QApplication.translate("Dialogs", "This file has not been saved,\nWould you like to do?\n\n")+filename[:-1],
                options)

        if reply == QtWidgets.QMessageBox.Yes: return True
        elif reply == QtWidgets.QMessageBox.Discard: return False
        else: return None


    #----------------------------------------------------------------------
    @classmethod
    def set_open_dir(cls, parent, dirpath=None):

        if dirpath is None:dirpath = parent.get_default_dir()
        open_dir = QtWidgets.QFileDialog.getExistingDirectory(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Open directory"),
                dirpath)

        if open_dir: return open_dir
        else: return None


    #----------------------------------------------------------------------
    @classmethod
    def file_duplicated(cls, parent, filename):

        QtWidgets.QMessageBox.information(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - File already open"),
                QtWidgets.QApplication.translate("Dialogs", "This file is already open in other tab.\n{}".format(filename)))
        return True


    #----------------------------------------------------------------------
    @classmethod
    def error_message(cls, parent, message):

        QtWidgets.QMessageBox.warning(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Error"),
                message)
        return True


    #----------------------------------------------------------------------
    @classmethod
    def confirm_message(cls, parent, message):

        options = QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel
        reply = QtWidgets.QMessageBox.question(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Confirmation"),
                message,
                options)

        if reply == QtWidgets.QMessageBox.Yes: return True
        elif reply == QtWidgets.QMessageBox.Discard: return False
        else: return None


    #----------------------------------------------------------------------
    @classmethod
    def info_message(cls, parent, message):

        QtWidgets.QMessageBox.information(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Information"),
                message)
        return True


    #----------------------------------------------------------------------
    @classmethod
    def warning_message(cls, parent, message):

        QtWidgets.QMessageBox.warning(parent,
                                  os.getenv("PINGUINO_NAME") + QtWidgets.QApplication.translate("Dialogs", " - Warning"),
                                  message)

        return True


    #----------------------------------------------------------------------
    @classmethod
    def save_before_compile(cls, parent):

        QtWidgets.QMessageBox.information(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Save file first."),
                QtWidgets.QApplication.translate("Dialogs", "You must save the file before compiling."))
        return True


    #----------------------------------------------------------------------
    @classmethod
    def add_files_to_project(cls, parent):

        QtWidgets.QMessageBox.information(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Save file first."),
                QtWidgets.QApplication.translate("Dialogs", "You must add files to project before compiling."))
        return True


    #----------------------------------------------------------------------
    @classmethod
    def overwrite_file(cls, parent, filename, exist):

        msg_box = QtWidgets.QMessageBox(parent)
        msg_box.setIcon(QtWidgets.QMessageBox.Warning)
        msg_box.setWindowTitle(os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Error"))
        if exist:
            msg_box.setText(QtWidgets.QApplication.translate("Dialogs", "This file has changed on disk.")+"\n"+filename)
        else:
            msg_box.setText(QtWidgets.QApplication.translate("Dialogs", "This file has deleted/moved on disk.")+"\n"+filename)

        stdout = QtWidgets.QPushButton()
        stdout.setText(QtWidgets.QApplication.translate("Dialogs", "Overwrite"))

        if exist:
            ok = QtWidgets.QPushButton()
            ok.setText(QtWidgets.QApplication.translate("Dialogs", "Reload"))

        msg_box.addButton(stdout, QtWidgets.QMessageBox.RejectRole)
        if exist: msg_box.addButton(ok, QtWidgets.QMessageBox.NoRole)

        if exist: msg_box.setDefaultButton(ok)
        else: msg_box.setDefaultButton(stdout)

        msg_box.setStyleSheet("""
        font-family: inherit;
        font-weight: normal;

        """)

        reply = msg_box.exec_()


    #----------------------------------------------------------------------
    @classmethod
    def compilation_done(cls, parent):

        msg_box = QtWidgets.QMessageBox(parent)
        msg_box.setIcon(QtWidgets.QMessageBox.Information)
        msg_box.setWindowTitle(os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Compiled"))
        msg_box.setText(QtWidgets.QApplication.translate("Dialogs", "Compilation done!"))

        upload = QtWidgets.QPushButton()
        upload.setText(QtWidgets.QApplication.translate("Dialogs", "Upload now!"))

        ok = QtWidgets.QPushButton()
        ok.setText(QtWidgets.QApplication.translate("Dialogs", "Ok"))

        msg_box.addButton(upload, QtWidgets.QMessageBox.AcceptRole)
        msg_box.addButton(ok, QtWidgets.QMessageBox.NoRole)

        msg_box.setDefaultButton(ok)

        msg_box.setStyleSheet("""
        font-family: inherit;
        font-weight: normal;

        """)

        reply = msg_box.exec_()

        if reply == 0: return True
        elif reply == 1: return False


    #----------------------------------------------------------------------
    @classmethod
    def upload_done(cls, parent):

        QtWidgets.QMessageBox.information(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Upload done"),
                QtWidgets.QApplication.translate("Dialogs", "File sucessfully uploaded to Pinguino."))
        return True


    #----------------------------------------------------------------------
    @classmethod
    def upload_fail(cls, parent, message):

        msg_box = QtWidgets.QMessageBox(parent)
        msg_box.setIcon(QtWidgets.QMessageBox.Information)
        msg_box.setWindowTitle(os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Upload fail"))
        msg_box.setText(message)

        upload = QtWidgets.QPushButton()
        upload.setText(QtWidgets.QApplication.translate("Dialogs", "Try again!"))

        ok = QtWidgets.QPushButton()
        ok.setText(QtWidgets.QApplication.translate("Dialogs", "Cancel"))

        msg_box.addButton(upload, QtWidgets.QMessageBox.AcceptRole)
        msg_box.addButton(ok, QtWidgets.QMessageBox.NoRole)

        msg_box.setDefaultButton(upload)

        msg_box.setStyleSheet("""
        font-family: inherit;
        font-weight: normal;

        """)

        reply = msg_box.exec_()

        if reply == 0: return True
        elif reply == 1: return False


    #----------------------------------------------------------------------
    @classmethod
    def set_save_image(cls, parent, filename, dirpath=None):

        if dirpath is None:dirpath = parent.get_default_dir()
        file_name = QtWidgets.QFileDialog.getSaveFileName(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Save image"),
                os.path.join(dirpath, filename),
                QtWidgets.QApplication.translate("Dialogs", "Png files (*.png);;All Files (*)"))

        if file_name: return file_name[0]
        else: return None


    #----------------------------------------------------------------------
    @classmethod
    def get_text(self, parent, name, default=""):

        text, ok = QtGui.QInputDialog.getText(parent,
                os.getenv("PINGUINO_NAME")+QtWidgets.QApplication.translate("Dialogs", " - Input text"),
                name+":", QtWidgets.QLineEdit.Normal,
                default)
        if ok and text != '': return text
        else: return False class Files(object):

    #----------------------------------------------------------------------
    def __init__(self):
        """"""
        self.connect(self.main.comboBox_files, QtCore.SIGNAL("currentIndexChanged(int)"), self.change_dir_files)
        self.connect(self.main.treeWidget_explorer, QtCore.SIGNAL("itemExpanded(QTreeWidgetItem*)"), self.expand_tree)
        self.connect(self.main.treeWidget_explorer, QtCore.SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.open_from_tree)


    #----------------------------------------------------------------------
    def update_path_files(self, path):

        if not type(path) is list: path = [path]

        flags = QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled
        self.main.treeWidget_explorer.clear()
        for dir_project in path:
            if os.path.exists(dir_project):
                if os.listdir(dir_project):
                    parent = self.add_new_tree(os.path.basename(dir_project), self.main.treeWidget_explorer, dir_project, flags)
                    self.generate_tree(dir_project, parent, levels=1, flags=flags)
                    parent.setExpanded(True)


    #----------------------------------------------------------------------
    def generate_tree(self, path, parent, levels=0, currentlevel=1, flags=None, to_ignore=[], inherits_status=dict(), library=False):

        if currentlevel > levels:
            if os.listdir(path):
                self.add_new_file_item("empty", parent, "empty", flags=None)
            return

        if not os.path.exists(path):
            return

        lisdir = os.listdir(path)

        # Filters
        lisdir = filter(lambda f:not f.startswith("."), lisdir)
        lisdir = filter(lambda f:not f.endswith(".ppde"), lisdir)
        lisdir = filter(lambda f:not f.endswith(".hex"), lisdir)
        lisdir = filter(lambda f:not f.endswith("~"), lisdir)

        list_dirs = []
        list_files = []

        for item in lisdir:
            fullpath = os.path.join(path, item)

            if fullpath in to_ignore: continue
            # print path in to_ignore, path, to_ignore

            if os.path.isdir(fullpath):
                list_dirs.append(fullpath)
            elif os.path.isfile(fullpath):
                list_files.append(fullpath)

        list_dirs.sort()
        list_files.sort()

        files_from_tree = []
        for dir_ in list_dirs:
            dir_name = os.path.basename(dir_)
            ft = self.generate_tree(dir_, self.add_new_tree(dir_name, parent, dir_, flags), currentlevel=currentlevel+1, levels=levels, to_ignore=to_ignore, inherits_status=inherits_status, library=library, flags=flags)
            if ft: files_from_tree.extend(ft)

        for file_ in list_files:
            file_name = os.path.basename(file_)
            if inherits_status and type(inherits_status) == dict:
                if file_ in inherits_status: check = inherits_status[file_]
                else: check = False
            elif type(inherits_status) == bool:
                check = inherits_status
            else:
                check = None

            if (file_name.endswith(".pde") or file_name.endswith(".h") or file_name.endswith(".c") or file_name.endswith(".cpp")) and (library is False):
                self.add_new_file_item(file_name, parent, file_, flags, check)
            elif library:
                self.add_new_file_item(file_name, parent, file_, None, None)
            else:
                self.add_new_file_item(file_name, parent, file_, flags, None)


        list_files.extend(files_from_tree)
        list_files.sort()

        return list_files


    #----------------------------------------------------------------------
    def add_new_file_item(self, filename, parent, fullpath, flags=None, check=None):
        """"""
        file_item = QtWidgets.QTreeWidgetItem(parent)

        file_item.setText(0, filename)
        file_item.path = fullpath


        if filename.endswith(".py"):
            file_item.setIcon(0, QtGui.QIcon.fromTheme("file-python"))
        elif filename.endswith(".pde"):
            file_item.setIcon(0, QtGui.QIcon.fromTheme("file-csrc"))
        elif filename.endswith(".h"):
            file_item.setIcon(0, QtGui.QIcon.fromTheme("file-chdr"))
        else:
            file_item.setIcon(0, QtGui.QIcon.fromTheme("document-new"))

        if flags:
            file_item.setFlags(flags)

        if not check is None:
            if check:
                file_item.setCheckState(0, QtCore.Qt.Checked)
            else:
                file_item.setCheckState(0, QtCore.Qt.Unchecked)



    #----------------------------------------------------------------------
    def add_new_tree(self, name, parent, fullpath, flags=None):
        """"""
        tree = QtWidgets.QTreeWidgetItem(parent)
        tree.setText(0, name)
        tree.path = fullpath
        # icon_dir = QtGui.QIcon()
        # icon_dir.addPixmap(QtGui.QPixmap(":/icons/icons/icon_dir.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        icon_dir = QtGui.QIcon.fromTheme("document-open")

        tree.setIcon(0, icon_dir)

        if flags:
            tree.setFlags(flags)

        return tree


    #----------------------------------------------------------------------
    def expand_tree(self, item):
        """"""
        dir_name = item.text(0)
        dir_ = item.path
        parent = item

        if item.child(0) and item.child(0).path == "empty":
            self.generate_tree(dir_, parent, levels=1)
            item.removeChild(item.child(0))


    #----------------------------------------------------------------------
    def open_from_tree(self, event, int_):

        if os.path.isfile(event.path):
            self.ide_open_file_from_path(filename=event.path)


    #----------------------------------------------------------------------
    def jump_dir_files(self, list_widget_item):
        if getattr(list_widget_item, "type_file") == "dir":
            self.update_path_files(getattr(list_widget_item, "path_file"))
        if getattr(list_widget_item, "type_file") == "file":
            self.ide_open_file_from_path(filename=getattr(list_widget_item, "path_file"))


    #----------------------------------------------------------------------
    def change_dir_files(self, index):
        to_dir = ["Examples", "Dir", "Home", "Other"][index]

        if to_dir == "Examples":
            self.update_path_files([os.path.join(os.getenv("PINGUINO_USER_PATH"), "examples"),
                                    os.path.join(os.getenv("PINGUINO_USER_PATH"), "graphical_examples"),
                                    os.path.join(os.getenv("PINGUINO_USER_PATH"), "examples_libs"),
                                    ])

        elif to_dir == "Home":
            self.update_path_files(QtCore.QDir.home().path())

        elif to_dir == "Dir":
            editor = self.get_current_editor()
            dir_ = getattr(editor, "path", None)
            if dir_: self.update_path_files(os.path.split(dir_)[0])

        # elif to_dir == "Third":
            # path = os.path.join(os.getenv("PINGUINO_USERLIBS_PATH"), "examples")
            # if os.path.exists(path): self.update_path_files(path)

        elif to_dir == "Other":
            open_dir = Dialogs.set_open_dir(self)
            if open_dir:
                self.update_path_files(open_dir) class Search(object):

    #----------------------------------------------------------------------
    def __init__(self):

        self.connect(self.main.actionSearch, QtCore.SIGNAL("triggered()"), lambda :self.set_tab_search("search"))
        self.connect(self.main.actionSearch_and_replace, QtCore.SIGNAL("triggered()"), lambda :self.set_tab_search("replace"))

        self.connect(self.main.pushButton_search_previous, QtCore.SIGNAL("clicked()"), self.search_previous)
        self.connect(self.main.pushButton_search_next, QtCore.SIGNAL("clicked()"), self.search_next)
        self.connect(self.main.pushButton_replace, QtCore.SIGNAL("clicked()"), self.replace)
        self.connect(self.main.pushButton_replace_all, QtCore.SIGNAL("clicked()"), self.replaceall)
        self.connect(self.main.lineEdit_search, QtCore.SIGNAL("textChanged(QString)"), self.search_instantaneous)
        self.connect(self.main.lineEdit_replace, QtCore.SIGNAL("textChanged(QString)"), self.replace_instantaneous)

        self.main.pushButton_search_next.setIcon(QtGui.QIcon.fromTheme("go-down"))
        self.main.pushButton_search_previous.setIcon(QtGui.QIcon.fromTheme("go-top"))

        # icon = QtGui.QIcon()
        # icon.addPixmap(QtGui.QIcon.fromTheme("insert-text").pixmap(size), QtGui.QIcon.Normal, QtGui.QIcon.On)
        # icon.addPixmap(QtGui.QIcon.fromTheme("insert-object").pixmap(size), QtGui.QIcon.Normal, QtGui.QIcon.Off)



    #----------------------------------------------------------------------
    @Decorator.requiere_open_files()
    @Decorator.requiere_text_mode()
    @Decorator.requiere_line_edit_content("main.lineEdit_replace")
    def replace_instantaneous(self, text_to_replace):
        empty = not text_to_replace == QtWidgets.QApplication.translate("Frame", "Replace...")
        self.main.pushButton_replace.setEnabled(empty)
        self.main.pushButton_replace_all.setEnabled(empty)
        if empty: return


    #----------------------------------------------------------------------
    @Decorator.requiere_open_files()
    @Decorator.requiere_text_mode()
    @Decorator.requiere_line_edit_content("main.lineEdit_search")
    def search_instantaneous(self, text_to_search):
        empty = not text_to_search == QtWidgets.QApplication.translate("Frame", "Search...")
        self.main.pushButton_search_previous.setEnabled(empty)
        self.main.pushButton_search_next.setEnabled(empty)

        editor = self.get_current_editor()
        editor.text_edit.setExtraSelections([])
        if not empty: return

        if self.main.checkBox_case_sensitive.isChecked():
            content = editor.text_edit.toPlainText()
            count = content.count(text_to_search)
        else:
            content = editor.text_edit.toPlainText().lower()
            count = content.count(text_to_search.lower())

        if count == 0: message = QtWidgets.QApplication.translate("Frame", "No words were found.")
        elif  count == 1: message = QtWidgets.QApplication.translate("Frame", "One word were found.")
        else: message = QtWidgets.QApplication.translate("Frame", "{} words were found.".format(count))
        self.main.label_replace_info.setText(message)

        #for i in range(count): self.search_next()

        text_cur = editor.text_edit.textCursor()
        editor.text_edit.moveCursor(text_cur.Start)
        self.__search__(text_to_search)



    #----------------------------------------------------------------------
    @Decorator.requiere_open_files()
    @Decorator.requiere_line_edit_content("main.lineEdit_search")
    def __search__(self, text_to_search):
        if text_to_search == QtWidgets.QApplication.translate("Frame", "Search..."): return


        self.find_match(word=text_to_search,
                        back=False,
                        sensitive=self.main.checkBox_case_sensitive.isChecked(),
                        whole=False)

    #----------------------------------------------------------------------
    @Decorator.requiere_open_files()
    @Decorator.requiere_text_mode()
    @Decorator.requiere_line_edit_content("main.lineEdit_search")
    def search_previous(self):
        self.find_match(word=self.main.lineEdit_search.text(),
                        back=True,
                        sensitive=self.main.checkBox_case_sensitive.isChecked(),
                        whole=False)

    #----------------------------------------------------------------------
    @Decorator.requiere_open_files()
    @Decorator.requiere_text_mode()
    @Decorator.requiere_line_edit_content("main.lineEdit_search")
    def search_next(self):
        self.find_match(word=self.main.lineEdit_search.text(),
                        back=False,
                        sensitive=self.main.checkBox_case_sensitive.isChecked(),
                        whole=False)

    #----------------------------------------------------------------------
    @Decorator.requiere_open_files()
    @Decorator.requiere_text_mode()
    @Decorator.requiere_line_edit_content("main.lineEdit_search")
    @Decorator.requiere_line_edit_content("main.lineEdit_replace")
    def replace(self):
        editor = self.get_current_editor()
        text_cur = editor.text_edit.textCursor()
        if text_cur.selectedText() == self.main.lineEdit_search.text():
            text_cur.removeSelectedText()
            text_cur.insertText(self.main.lineEdit_replace.text())
            text_cur.clearSelection()
            self.editor_highligh_line(line=None, color="#ffff7f")

    #----------------------------------------------------------------------
    @Decorator.requiere_open_files()
    @Decorator.requiere_text_mode()
    @Decorator.requiere_line_edit_content("main.lineEdit_search")
    @Decorator.requiere_line_edit_content("main.lineEdit_replace")
    def replaceall(self):
        self.replace_all_match(wordOld=self.main.lineEdit_search.text(),
                               wordNew=self.main.lineEdit_replace.text(),
                               sensitive=self.main.checkBox_case_sensitive.isChecked(),
                               whole=False)

    #----------------------------------------------------------------------
    def replace_all_match(self, wordOld, wordNew, sensitive=False, whole=False):
        editor = self.get_current_editor()
        text_doc = editor.text_edit.document()
        text_cur = editor.text_edit.textCursor()
        s = text_doc.FindCaseSensitively if sensitive else 0
        w = text_doc.FindWholeWords if whole else 0
        # editor.text_edit.moveCursor(text_cur.NoMove, text_cur.KeepAnchor)
        text_cur.beginEditBlock()
        editor.text_edit.moveCursor(text_cur.Start)
        count = 0
        while True:
            result = False
            if sensitive or whole: result = editor.text_edit.find(wordOld, s | w)
            else: result = editor.text_edit.find(wordOld)
            if result:
                tc = editor.text_edit.textCursor()
                if tc.hasSelection(): tc.insertText(wordNew)
                count += 1
            else: break
            #replace = False
        text_cur.endEditBlock()
        self.main.label_replace_info.setText("{} words were replaced.".format(count))

    #----------------------------------------------------------------------
    def find_match(self, word, back, sensitive, whole):
        editor = self.get_current_editor()
        text_doc = editor.text_edit.document()
        text_cur = editor.text_edit.textCursor()
        b = text_doc.FindBackward if back else 0
        s = text_doc.FindCaseSensitively if sensitive else 0
        w = text_doc.FindWholeWords if whole else 0
        # editor.text_edit.moveCursor(text_cur.NoMove, text_cur.KeepAnchor)
        if back or sensitive or whole: editor.text_edit.find(word, b | s | w)
        else:  editor.text_edit.find(word)
        self.editor_highligh_line(line=None, color="#ffff7f", text_cursor=editor.text_edit.textCursor()) class Project(object):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """"""
        self.connect(self.main.actionAdd_existing_directory, QtCore.SIGNAL("triggered()"), self.select_existing_directory)
        self.connect(self.main.actionNew_project, QtCore.SIGNAL("triggered()"), self.new_project)
        self.connect(self.main.actionNew_library, QtCore.SIGNAL("triggered()"), self.__show_library_template__)
        # self.connect(self.main.actionImport_library_project, QtCore.SIGNAL("triggered()"), self.import_library)
        self.connect(self.main.pushButton_newproject, QtCore.SIGNAL("clicked()"), self.new_project)
        self.connect(self.main.pushButton_openproject, QtCore.SIGNAL("clicked()"), self.open_project)
        self.connect(self.main.pushButton_newlibrary, QtCore.SIGNAL("clicked()"), self.__show_library_template__)
        self.connect(self.main.actionClose_project, QtCore.SIGNAL("triggered()"), self.close_project)
        self.connect(self.main.actionSave_project, QtCore.SIGNAL("triggered()"), self.save_project)
        self.connect(self.main.actionSave_project_as, QtCore.SIGNAL("triggered()"), self.save_project_as)
        self.connect(self.main.actionAdd_current_file, QtCore.SIGNAL("triggered()"), self.add_current_file)
        self.connect(self.main.actionOpen_project, QtCore.SIGNAL("triggered()"), self.open_project)
        self.connect(self.main.actionAdd_existing_file, QtCore.SIGNAL("triggered()"), self.select_existing_file)
        self.connect(self.main.treeWidget_projects, QtCore.SIGNAL("itemExpanded(QTreeWidgetItem*)"), self.expand_tree)
        self.connect(self.main.treeWidget_projects, QtCore.SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.open_from_tree)

        self.connect(self.main.pushButton_compilelibrary, QtCore.SIGNAL("clicked()"), self.compile_library)
        self.connect(self.main.pushButton_packagelibrary, QtCore.SIGNAL("clicked()"), self.package_library)

        self.connect(self.main.treeWidget_projects, QtCore.SIGNAL("itemChanged(QTreeWidgetItem*,int)"), self.update_check_status)
        # self.connect(self.main.treeWidget_projects, QtCore.SIGNAL("itemClicked(QTreeWidgetItem*,int)"), self.update_check_status)


    #----------------------------------------------------------------------
    @Decorator.show_tab("Project")
    @Decorator.alert_tab("Project")
    def open_project(self):

        self.project_saved = True
        file_project = Dialogs.set_open_file(self, exts="*.ppde PINGUINO")
        if file_project is None: return

        if file_project.endswith("PINGUINO"):
            self.import_library(file_project)
            return

        elif file_project.endswith(".ppde"):
            self.open_project_from_path(file_project)
            self.update_project_status()


    #----------------------------------------------------------------------
    @Decorator.show_tab("Project")
    @Decorator.alert_tab("Project")
    def open_project_from_path(self, filename):
        """"""
        try:
            self.project_saved = True
            self.ConfigProject = RawConfigParser()
            self.ConfigProject.readfp(open(filename, "r"))
            self.ConfigProject.filename = filename

            os.environ["PINGUINO_PROJECT"] = self.ConfigProject.get("Main", "name")

            project_name = self.reload_project(open_=True)


            if self.is_library():
                logging.debug("Opening \"{}\" library.".format(project_name))
            else:
                logging.debug("Opening \"{}\" project.".format(project_name))


            self.update_recents_projects(self.ConfigProject.filename)


            self.ide_close_all()
            if self.is_library():
                for path in self.get_libs_file():
                    self.ide_open_file_from_path(filename=path)

        except:
            Dialogs.error_message(self, "File seems to be corrupted!")

        self.save_recents()



    #----------------------------------------------------------------------
    def reload_project(self, open_=False):
        """"""

        if (not self.is_project()) and (not open_): return

        self.main.treeWidget_projects.clear()

        project_name = self.ConfigProject.get("Main", "name")
        self.main.treeWidget_projects.setHeaderLabel(project_name)

        if not self.ConfigProject.has_section("Ignore"):
            to_ignore = []
        elif not self.ConfigProject.options("Ignore"):
            to_ignore = []
        else:
            to_ignore = [self.ConfigProject.get("Ignore", option) for option in self.ConfigProject.options("Ignore")]

        inherits_status = self.get_inherits_from_project()

        for option in self.ConfigProject.options("Dirs"):
            if not self.ConfigProject.get("Dirs", option) in to_ignore:
                self.add_existing_directory(self.ConfigProject.get("Dirs", option), to_ignore, check_duplicated=False, inherits_status=inherits_status, open_=True, library=self.is_library())

        for path, checked in self.get_files_from_project().items():
            if path in to_ignore: continue
            self.add_existing_file(path, check_duplicated=False, check=checked, open_=True)

        self.update_project_status(project_name)
        return project_name


    #----------------------------------------------------------------------
    def select_existing_directory(self):
        """"""
        dir_project = Dialogs.set_open_dir(self)
        if dir_project in self.get_dirs_from_project(): return False

        if dir_project == self.get_default_project_dir():
            dir_project_tmp = os.path.join(dir_project, self.get_project_name())

            i = 1
            while os.path.exists(dir_project_tmp):
                dir_project_tmp = os.path.join(dir_project, self.get_project_name() + "-{}".format(i))
                i += 1

            dir_project = dir_project_tmp
            os.mkdir(dir_project)

        self.add_existing_directory(dir_project, inherits_status=True)
        return dir_project



    #----------------------------------------------------------------------
    def add_existing_directory(self, dir_project, to_ignore=[], check_duplicated=True, inherits_status=dict(), open_=False, library=False):
        """"""

        self.take_from_ignore(dir_project)
        if check_duplicated:
            if dir_project in self.get_dirs_from_project(): return

        # flags = QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEditable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled
        # flags = QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled

        if library is True:
            flags = QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsEnabled
        else:
            flags = QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled


        parent = self.add_new_tree(os.path.basename(dir_project), self.main.treeWidget_projects, dir_project, flags)
        inherits = self.generate_tree(dir_project, parent, levels=50, flags=flags, to_ignore=to_ignore, inherits_status=inherits_status, library=library)
        parent.setExpanded(True)

        if not open_:
            self.add_dir_to_config(dir_project)
            self.add_inherits_to_config(inherits)


    #----------------------------------------------------------------------
    def add_current_file(self):
        """"""
        editor = self.get_tab().currentWidget()
        self.add_existing_file(editor.path)


    #----------------------------------------------------------------------
    def select_existing_file(self):
        """"""
        new_file = Dialogs.set_open_file(self)
        if new_file in self.get_files_from_project(): return
        self.add_existing_file(new_file)


    #----------------------------------------------------------------------
    def add_existing_file(self, path, check_duplicated=True, check=True, open_=False):
        """"""
        self.take_from_ignore(path)
        if check_duplicated:
            if path in self.get_files_from_project(): return

        filename = os.path.split(path)[1]
        parent = self.main.treeWidget_projects
        # flags = QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled
        flags = QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled

        self.add_new_file_item(filename, parent, path, flags, check=check)

        if not open_:
            self.add_file_to_config(path)



    #----------------------------------------------------------------------
    def set_project_name(self):
        """"""
        project_name = Dialogs.get_text(self, "Project name", default="untitled_project")

        if project_name is False:
            return

        self.main.treeWidget_projects.setHeaderLabel(project_name)

        if not self.ConfigProject.has_section("Main"): self.ConfigProject.add_section("Main")
        options = self.ConfigProject.options("Main")
        self.ConfigProject.set("Main", "name", project_name)
        self.ConfigProject.set("Main", "library", False)

        self.main.widget_library.setVisible(False)

        self.save_project(default=True)

        logging.debug("Created \"{}\" project.".format(project_name))

        #os.environ["PINGUINO_PROJECT"] = project_name
        return project_name
        # self.main.treeWidget_projects.setHeaderLabel(project_name)


    #----------------------------------------------------------------------
    def set_library_name(self, project_name):
        """"""
        self.main.treeWidget_projects.setHeaderLabel(project_name)

        if not self.ConfigProject.has_section("Main"): self.ConfigProject.add_section("Main")
        options = self.ConfigProject.options("Main")
        self.ConfigProject.set("Main", "name", project_name)
        self.ConfigProject.set("Main", "library", True)

        self.main.widget_library.setVisible(True)

        self.save_project(default=True)

        logging.debug("Created \"{}\" library.".format(project_name))

        return project_name


    #----------------------------------------------------------------------
    def is_project(self):
        """"""
        if "PINGUINO_PROJECT" in os.environ:
            return bool(os.environ["PINGUINO_PROJECT"])
        else:
            return False


    #----------------------------------------------------------------------
    def is_library(self):
        """"""
        if os.environ.get("PINGUINO_PROJECT", False):
            if self.ConfigProject.has_option("Main", "library"):
                r = self.ConfigProject.get("Main", "library")
                if type(r) == str:
                    return r == "True"
                elif type(r) == bool:
                    return r
            else:
                self.ConfigProject.set("Main", "library", False)
                return False
        else:
            return False


    #----------------------------------------------------------------------
    def get_libs_file(self):
        """"""
        libs = []
        if self.ConfigProject.has_option("Main", "lib"):
            libs.append(self.ConfigProject.get("Main", "lib"))
        if self.ConfigProject.has_option("Main", "lib32"):
            libs.append(self.ConfigProject.get("Main", "lib32"))
        return libs


    #----------------------------------------------------------------------
    def get_project_name(self):
        """"""
        return self.ConfigProject.get("Main", "name")


    #----------------------------------------------------------------------
    def get_project_files(self):
        """"""
        #files = [file_ for file_, checked in self.get_files_from_project().iteritems() if checked]
        #files.extend([file_ for file_, checked in self.get_inherits_from_project().iteritems() if checked])
        files = [file_ for file_, checked in self.get_files_from_project().items() if checked]
        files.extend([file_ for file_, checked in self.get_inherits_from_project().items() if checked])
        return files


    # #----------------------------------------------------------------------
    # def get_main_upload(self):
        # """"""
        # header = self.main.treeWidget_projects.header()
        # filename = self.get_tab().currentWidget().path
        # return getattr(header, "main_upload", filename)


    #----------------------------------------------------------------------
    @Decorator.show_tab("Project")
    @Decorator.alert_tab("Project")
    def new_project(self):
        """"""
        self.project_saved = False
        self.ConfigProject = RawConfigParser()
        project_name = self.set_project_name()

        if project_name:
            Dialogs.info_message(self, QtWidgets.QApplication.translate("Dialogs", "Create or add an existing directory for project."))
            dirname = self.select_existing_directory()
            if dirname:
                self.create_project_template(dirname)
            self.update_project_status(project_name)

            self.reload_project()
            self.reload_project()


    #----------------------------------------------------------------------
    def create_project_template(self, dirname):
        """"""

        main_filename = os.path.join(dirname, 'main.pde')
        main_code = """/*-----------------------------------------------------
    Author: --<>
    Project: {}
    Date: {}
    Description:

    -----------------------------------------------------*/


    void setup(){{

    }}

    void loop(){{

        my_function();

    }}
    """.format(self.get_project_name(), datetime.now().strftime("%Y-%m-%d %H:%M:%S"))



        func_filename = os.path.join(dirname, 'functions.pde')
        func_code = """/*-----------------------------------------------------
    Author: --<>
    Project: {}
    Date: {}
    Description:

    -----------------------------------------------------*/


    void my_function(){{

    }}


    """.format(self.get_project_name(), datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

        main_file = open(main_filename, mode="w")
        main_file.write(main_code)
        main_file.close()

        main_file = open(func_filename, mode="w")
        main_file.write(func_code)
        main_file.close()

        self.ide_open_file_from_path(filename=func_filename)
        self.ide_open_file_from_path(filename=main_filename)




    #----------------------------------------------------------------------
    def save_project_as(self):
        """"""
        self.project_saved = False
        self.save_project(silent=False)



    #----------------------------------------------------------------------
    def save_project(self, silent=False, default=False):
        """"""

        if default:
            default_path = os.path.join(os.getenv("PINGUINO_USER_PATH"), "projects")

            if not os.path.exists(default_path):
                makedirs(default_path, exist_ok=True)
            self.ConfigProject.filename = os.path.join(default_path, self.get_project_name()) + ".ppde"
            self.ConfigProject.write(open(self.ConfigProject.filename, "w"))
            self.project_saved = True
            return

        if self.project_saved:
            self.ConfigProject.write(open(self.ConfigProject.filename, "w"))

        elif not silent:
            save = Dialogs.set_save_file(self, self.get_project_name()+".ppde")
            if save[0]:
                path, filename = save
                self.ConfigProject.filename = path
                self.ConfigProject.write(open(self.ConfigProject.filename, "w"))
                self.project_saved = True

        self.update_recents_projects(self.ConfigProject.filename)


    #----------------------------------------------------------------------
    def add_dir_to_config(self, dirpath):
        """"""
        if not self.ConfigProject.has_section("Dirs"): self.ConfigProject.add_section("Dirs")
        options = self.ConfigProject.options("Dirs")

        if dirpath in self.get_dirs_from_project(): return

        index = 0
        while "dir_%d"%index in options:
            index += 1

        self.ConfigProject.set("Dirs", "dir_%d"%index, dirpath)
        self.save_project(silent=True)


    #----------------------------------------------------------------------
    def add_inherits_to_config(self, inherits):
        """"""
        if not self.ConfigProject.has_section("Inherits"): self.ConfigProject.add_section("Inherits")
        options = self.ConfigProject.options("Inherits")

        index = 0
        while "inherit__%d"%index in options:
            index += 1

        for path in inherits:
            if path in self.get_inherits_from_project(): continue
            self.ConfigProject.set("Inherits", "inherit_%d"%index, path)
            self.ConfigProject.set("Inherits", "inherit_%d_checked"%index, "1")
            index += 1
        self.save_project(silent=True)


    #----------------------------------------------------------------------
    def add_file_to_config(self, filepath):
        """"""
        if not self.ConfigProject.has_section("Files"): self.ConfigProject.add_section("Files")
        options = self.ConfigProject.options("Files")

        if filepath in self.get_files_from_project(): return

        index = 0
        while "file_%d"%index in options:
            index += 1

        self.ConfigProject.set("Files", "file_%d"%index, filepath)
        self.ConfigProject.set("Files", "file_%d_checked"%index, "1")

        self.save_project(silent=True)


    #----------------------------------------------------------------------
    def hide_element_to_config(self, path):
        """"""
        if not self.ConfigProject.has_section("Ignore"): self.ConfigProject.add_section("Ignore")
        options = self.ConfigProject.options("Ignore")

        index = 0
        while "ignore_%d"%index in options:
            index += 1

        self.ConfigProject.set("Ignore", "ignore_%d"%index, path)


        logging.debug("Removing \"{}\" from project.".format(path))
        for path_inherit, option in self.get_inherits_option_from_project().items():
            if path_inherit.startswith(path):
                self.ConfigProject.remove_option("Inherits", option)
                self.ConfigProject.remove_option("Inherits", option+"_checked")
                logging.debug("Removing \"{}\" from project.".format(path_inherit))


        for path_files, option in self.get_files_option_from_project().items():
            if path_files.startswith(path):
                self.ConfigProject.remove_option("Files", option)
                self.ConfigProject.remove_option("Files", option+"_checked")
                logging.debug("Removing \"{}\" from project.".format(path_files))




        self.save_project(silent=True)


    #----------------------------------------------------------------------
    def update_project_status(self, project="reload"):
        """"""
        if project == "reload":
            pass
        elif project:
            os.environ["PINGUINO_PROJECT"] = project
        else:
            os.environ["PINGUINO_PROJECT"] = ""

        self.main.treeWidget_projects.setVisible(bool(project))
        self.main.widget_noproject.setVisible(not bool(project))
        self.main.widget_library.setVisible(self.is_library())

        self.main.treeWidget_projects.contextMenuEvent = self.project_context_menu
        Decorator.update_toolbar()

        open_project = bool(os.environ["PINGUINO_PROJECT"])
        self.main.actionNew_project.setEnabled(not open_project)
        self.main.actionOpen_project.setEnabled(not open_project)
        self.main.actionSave_project.setEnabled(open_project)
        self.main.actionSave_project_as.setEnabled(open_project)
        self.main.actionClose_project.setEnabled(open_project)
        self.main.actionAdd_existing_directory.setEnabled(open_project)
        self.main.actionAdd_current_file.setEnabled(open_project)
        self.main.actionAdd_existing_file.setEnabled(open_project)
        self.main.actionAdd_new_file.setEnabled(open_project)
        self.main.actionAdd_new_blocks_file.setEnabled(open_project)
        # self.main.actionSet_current_file_as_main_upload.setEnabled(open_project)



    #----------------------------------------------------------------------
    def get_current_item(self):
        """"""
        return self.main.treeWidget_projects.currentItem()




    #----------------------------------------------------------------------
    def project_context_menu(self, event):
        menu = QtWidgets.QMenu()

        if hasattr(self.get_current_item(), "path"):
            if os.path.isfile(self.get_current_item().path):
                # option for files
                # menu.addAction("Set as main upload file", self.set_as_main_upload)
                menu.addAction("Remove file", self.remove_file)
            else:
                # option for dirs
                menu.addAction("Remove directory", self.remove_directory)

            # option for files and dirs
            menu.addAction("Remove exclude from project", self.remove_from_tree)

        # general options
        menu.addAction("Rename...", self.rename)
        menu.addSeparator()
        menu.addAction("Add existing directory...", self.select_existing_directory)
        menu.addAction("Add existing file...", self.select_existing_file)
        menu.addSeparator()
        if hasattr(self.get_current_item(), "path"):
            menu.addAction("Add new file...", self.add_new_file)
            menu.addAction("Add new blocks file...", self.add_new_blocks_file)
            menu.addAction("Add new directory...", self.add_new_directory)
        menu.addAction("Close project", self.close_project)
        menu.addAction("Open project...", self.open_project)
        menu.addSeparator()
        menu.addAction("Reload project", self.reload_project)

        menu.setStyleSheet("""
        QMenu {
            font-family: inherit;
            font-weight: normal;
            }

        """)

        menu.exec_(event.globalPos())


    # #----------------------------------------------------------------------
    # def set_as_main_upload(self):
        # """"""
        # item = self.get_current_item()
        # item.setForeground(0, QtGui.QColor("#FF0000"))

        # item.setText(0, "{} [main upload file]".format(item.text(0)))

        # if not self.ConfigProject.has_section("Main"): self.ConfigProject.add_section("Main")
        # self.ConfigProject.set("Main", "main_upload", item.path)
        # self.save_project(True)

        # header = self.main.treeWidget_projects.header()
        # header.main_upload = item.path


    #----------------------------------------------------------------------
    def remove_file(self):
        """"""
        item = self.get_current_item()
        os.remove(item.path)
        item.removeChild(item)


    #----------------------------------------------------------------------
    def remove_directory(self):
        """"""
        item = self.get_current_item()
        shutil.rmtree(item.path)
        item.removeChild(item)


    #----------------------------------------------------------------------
    def remove_from_tree(self):
        """"""
        item = self.get_current_item()
        self.hide_element_to_config(item.path)
        item.removeChild(item)


    #----------------------------------------------------------------------
    def take_from_ignore(self, path):
        """"""
        if self.ConfigProject.has_section("Ignore"):
            options = self.ConfigProject.options("Ignore")
            for option in options:
                if self.ConfigProject.get("Ignore", option) == path:
                    self.ConfigProject.remove_option("Ignore", option)


    #----------------------------------------------------------------------
    def get_default_project_dir(self):
        """"""
        dirs = self.get_dirs_from_project()
        if dirs:  return dirs[0]

        files = self.get_files_from_project().keys()
        if files: return files[0]

        # return QtCore.QDir.home().path()
        return os.getenv("PINGUINO_DEFAULT_FILES")


    #----------------------------------------------------------------------
    def get_dirs_from_project(self):
        """"""
        if not self.ConfigProject.has_section("Dirs"): return []
        if not self.ConfigProject.options("Dirs"): return []
        return [self.ConfigProject.get("Dirs", option) for option in self.ConfigProject.options("Dirs")]


    #----------------------------------------------------------------------
    def get_ignore_from_project(self):
        """"""
        if not self.ConfigProject.has_section("Ignore"): return []
        if not self.ConfigProject.options("Ignore"): return []
        return [self.ConfigProject.get("Ignore", option) for option in self.ConfigProject.options("Ignore")]


    #----------------------------------------------------------------------
    def get_files_from_project(self):
        """"""
        if not self.ConfigProject.has_section("Files"): return {}
        if not self.ConfigProject.options("Files"): return {}
        return {self.ConfigProject.get("Files", option):bool(int(self.ConfigProject.get("Files", "{}_checked".format(option))))
                for option in filter(lambda f:not f.endswith("_checked"), self.ConfigProject.options("Files"))}


    #----------------------------------------------------------------------
    def get_inherits_from_project(self):
        """"""
        if not self.ConfigProject.has_section("Inherits"): return {}
        if not self.ConfigProject.options("Inherits"): return {}
        return {self.ConfigProject.get("Inherits", option):bool(int(self.ConfigProject.get("Inherits", "{}_checked".format(option))))
                for option in filter(lambda f:not f.endswith("_checked"), self.ConfigProject.options("Inherits"))}


    #----------------------------------------------------------------------
    def get_files_option_from_project(self):
        """"""
        if not self.ConfigProject.has_section("Files"): return {}
        if not self.ConfigProject.options("Files"): return {}
        return {self.ConfigProject.get("Files", option):option
                for option in filter(lambda f:not f.endswith("_checked"), self.ConfigProject.options("Files"))}


    #----------------------------------------------------------------------
    def get_inherits_option_from_project(self):
        """"""
        if not self.ConfigProject.has_section("Inherits"): return {}
        if not self.ConfigProject.options("Inherits"): return {}
        return {self.ConfigProject.get("Inherits", option):option
                for option in filter(lambda f:not f.endswith("_checked"), self.ConfigProject.options("Inherits"))}



    #----------------------------------------------------------------------
    def update_check_status(self, item, int_):
        """"""
        status = item.checkState(int_)
        if status: status = "1"
        else: status = "0"

        if hasattr(item, "path"):

            path = item.path

            if not os.path.isfile(path):
                return

            if not path.endswith(".pde"):
                return

            inherits = self.get_inherits_option_from_project()
            files = self.get_files_option_from_project()

            if path in inherits:
                self.ConfigProject.set("Inherits", inherits[path]+"_checked", status)

            elif path in files:
                    self.ConfigProject.set("Files", files[path]+"_checked", status)

            else:
                self.update_new_file(path, status)
                # files = self.get_files_option_from_project()
                # self.ConfigProject.set("Files", files[path]+"_checked", status)

            self.save_project(silent=True)


    #----------------------------------------------------------------------
    def update_new_file(self, path, status):
        """
        Add new file and define their status.
        """
        dirs = self.get_dirs_from_project()
        for dir_ in dirs:
            if path.startswith(dir_):
                # add as inherits
                inherits = self.get_inherits_option_from_project()

                x = 0
                while "inherit_{}".format(x) in inherits.values():
                    x += 1

                self.ConfigProject.set("Inherits", "inherit_{}".format(x), path)
                self.ConfigProject.set("Inherits", "inherit_{}_checked".format(x), status)
                return

        files = self.get_files_option_from_project()
        x = 0
        while "files_{}".format(x) in files.values():
            x += 1
            self.ConfigProject.set("Files", "files_{}".format(x), path)
            self.ConfigProject.set("Files", "files_{}_checked".format(x), status)


        # add as file



    #----------------------------------------------------------------------
    def close_project(self):
        """"""
        name = self.get_project_name()
        self.project_saved = False
        self.main.treeWidget_projects.clear()
        self.update_project_status("")
        logging.debug("Closing \"{}\" project.".format(name))


    #----------------------------------------------------------------------
    def add_new_file(self):
        """"""
        path = self.get_current_item().path
        if os.path.isfile(path):
            path = os.path.dirname(self.get_current_item().path)

        filename = Dialogs.get_text(self, "New file", default=self.get_untitled_name(ext=".pde")[:-1])
        new_file = os.path.join(path, filename)
        nf = open(new_file, "w")
        nf.close()

        self.ide_open_file_from_path(filename=new_file)

        if new_file in self.get_files_option_from_project():
            self.add_existing_file(new_file)

        if self.is_project():
            self.reload_project()

    #----------------------------------------------------------------------
    def add_new_blocks_file(self):
        """"""
        path = self.get_current_item().path
        if os.path.isfile(path):
            path = os.path.dirname(self.get_current_item().path)


        filename = Dialogs.get_text(self, "New blocks file", default=self.get_untitled_name(ext=".gpde")[:-1])
        new_file = os.path.join(path, filename)
        nf = open(new_file, "w")
        nf.close()

        if self.get_current_item().path in self.get_files_option_from_project():
            self.add_existing_file(new_file)

        if self.is_project():
            self.reload_project()


    #----------------------------------------------------------------------
    def add_new_directory(self):
        """"""
        path = self.get_current_item().path
        if os.path.isfile(path):
            path = os.path.dirname(self.get_current_item().path)

        dirname = Dialogs.get_text(self, "New directory", default="untitled-dir")
        new_dir = os.path.join(path, dirname)
        makedirs(new_dir, exist_ok=True)

        if self.get_current_item().path in self.get_files_option_from_project():
            self.add_existing_directory(new_dir)

        if self.is_project():
            self.reload_project()

    #----------------------------------------------------------------------
    def rename(self):
        """"""
        # path = self.get_current_item().path
        path = getattr(self.get_current_item(), "path", "")
        name = Dialogs.get_text(self, "New name", default=os.path.basename(path))
        if not name: return

        new_name = os.path.join(os.path.dirname(path), name)
        files = self.get_files_option_from_project()
        os.rename(path, new_name)

        if path in files:
            self.ConfigProject.set("Files", files[path], new_name)

        if self.is_project():
            self.reload_project()


    #----------------------------------------------------------------------
    def update_recents_projects(self, filename):

        if filename in self.recent_projects:
            self.recent_projects.remove(filename)
        self.recent_projects.insert(0, filename)
        self.recent_projects = self.recent_projects[:10]

        self.update_recents_menu_project()


    #----------------------------------------------------------------------
    def update_recents_menu_project(self):

        self.main.menuRecentProjects.clear()
        for file_ in self.recent_projects:
            action = QtWidgets.QAction(self)
            filename = os.path.split(file_)[1]

            len_ = 40
            if len(file_) > len_:
                file_path_1 = file_[:int(len_/2)]
                file_path_2 = file_[int(-len_/2):]
                file_path = file_path_1 + "..." + file_path_2
            else: file_path = file_

            if os.path.isfile(file_):
                action.setText(filename+" ("+file_path+")")
                self.connect(action, QtCore.SIGNAL("triggered()"), self.ide_menu_recent_event(file_))
                action.ActionEvent = self.ide_menu_recent_event

                self.main.menuRecentProjects.addAction(action)

        self.main.menuRecentProjects.addSeparator()
        self.main.menuRecentProjects.addAction(QtWidgets.QApplication.translate("Dialogs", "Clear recent files"), self.clear_recents_projects)


    #----------------------------------------------------------------------
    def clear_recents_projects(self):

        self.main.menuRecentProjects.clear()
        self.main.menuRecentProjects.addSeparator()
        self.main.menuRecentProjects.addAction(QtWidgets.QApplication.translate("Dialogs", "Clear recent files"), self.clear_recents_projects)
        self.recent_projects = []


    #----------------------------------------------------------------------
    @Decorator.show_tab("Project")
    @Decorator.alert_tab("Project")
    def new_library(self, **kwargs):
        """"""
        library_name = kwargs["libname"]
        library_dir = kwargs["libpath"]

        self.project_saved = False
        self.ConfigProject = RawConfigParser()
        self.set_library_name(library_name)

        if library_dir:  #FIXME no necesario
            self.create_library_template(**kwargs)
        else:
            self.close_project()

        self.add_existing_directory(os.path.join(library_dir, library_name), inherits_status=True)
        self.update_project_status(library_name)

        if self.is_project():
            self.reload_project()

    #----------------------------------------------------------------------
    def create_library_template(self, libpath, libname, author, description, _8bit, _32bit):
        """"""
        library_dir = os.path.join(libpath, libname)
        example_dir = os.path.join(library_dir, "examples")
        # tests_dir = os.path.join(library_dir, "tests")
        pinguino_file = os.path.join(library_dir, "PINGUINO")
        # lib = os.path.join(library_dir, "{}.lib".format(libname))
        # self.ConfigProject.set("Main", "lib", lib)

        makedirs(library_dir, exist_ok=True)
        makedirs(example_dir, exist_ok=True)
        # makedirs(tests_dir, exist_ok=True)

        self.add_existing_directory(library_dir, inherits_status=True)

        lib_template = """/*-----------------------------------------------------
Author: {}--<>
Date: {}
Description:

-----------------------------------------------------*/


void my_private_function(){{


}}

PUBLIC u8 my_function(){{
    // This function could be used as {}.my_function

}}
""".format(author, datetime.now().strftime("%Y-%m-%d %H:%M:%S"), libname)

        if _8bit:
            lib = os.path.join(library_dir, "{}.lib".format(libname))
            self.ConfigProject.set("Main", "lib", lib)
            lib_file = open(lib, mode="w")
            lib_file.write(lib_template)
            lib_file.close()

        if _32bit:
            lib32 = os.path.join(library_dir, "{}.lib32".format(libname))
            self.ConfigProject.set("Main", "lib32", lib32)
            lib_file = open(lib32, mode="w")
            lib_file.write(lib_template)
            lib_file.close()

        example_file = open(os.path.join(example_dir, "example.pde"), mode="w")
        example_file.close()

        example_file = open(os.path.join(example_dir, "example.gpde"), mode="w")
        example_file.close()

        # test_file = open(os.path.join(tests_dir, "test.pde"), mode="w")
        # test_file.close()

        archs = []
        if _8bit: archs.append("8bit")
        if _32bit: archs.append("32bit")
        parse_lib = RawConfigParser()
        parse_lib.add_section("PINGUINO")
        parse_lib.set("PINGUINO", "name", libname)
        parse_lib.set("PINGUINO", "author", author)
        parse_lib.set("PINGUINO", "author_email", "")
        parse_lib.set("PINGUINO", "arch", ", ".join(archs))
        parse_lib.set("PINGUINO", "repository", "")
        parse_lib.set("PINGUINO", "description", description)
        parse_lib.set("PINGUINO", "url", "")
        parse_lib.set("PINGUINO", "version", "0.1")
        parse_lib.write(open(pinguino_file, "w"))

        self.ide_open_file_from_path(filename=lib)



    #----------------------------------------------------------------------
    def compile_library(self):
        """"""
        self.ide_save_all()
        self.update_library_project()

        lib_name = self.get_project_name()
        lib = self.ConfigProject.get("Main", "lib")

        archs = self.get_library_archs()
        filenames = []

        for arch in archs:

            lib_dir = os.path.dirname(lib)
            if not os.path.isdir(os.path.join(lib_dir, arch)):
                makedirs(os.path.join(lib_dir, arch), exist_ok=True)
            if not os.path.isdir(os.path.join(lib_dir, "pdl")):
                makedirs(os.path.join(lib_dir, "pdl"), exist_ok=True)

            define = os.path.join(lib_dir, arch, "{}.h".format(lib_name))
            userc = os.path.join(lib_dir, arch, "{}.c".format(lib_name))
            pdl = os.path.join(lib_dir, "pdl", "{}.pdl{}".format(lib_name, "" if arch=="p8" else "32"))

            filenames.append(define)
            filenames.append(userc)
            filenames.append(pdl)

            if arch == "p8":
                arch_num = 8
            elif arch == "p32":
                arch_num = 32

            libinstructions = self.pinguinoAPI.get_regobject_libinstructions(arch_num)
            self.pinguinoAPI.preprocess([lib], define_output=define, userc_output=userc, ignore_spaces=self.is_project(), libinstructions=libinstructions)
            # self.pinguinoAPI.preprocess([lib], libinstructions=libinstructions)

            userc_file = open(userc, mode="r")
            userc_content = userc_file.read()
            userc_file.close()

            include = "#include <{}.h>".format(lib_name)

            parser = PinguinoParser([{"filename":userc, "content":userc_content}])

            # functions = self.get_functions([{"filename":userc, "content":userc_content}])
            functions = parser.get_functions()
            userc_content = userc_content.split("\n")

            pdl_content = []

            for function in functions:
                if function["return"].startswith("PUBLIC"):
                    userc_content[function["line"]-1] = userc_content[function["line"]-1].replace("PUBLIC ", "", 1)
                    userc_content[function["line"]-1] = userc_content[function["line"]-1].replace(function["name"], "{}_{}".format(lib_name, function["name"]), 1)
                    pdl_content.append("{} {}#include <{}.c>\n".format("{}.{}".format(lib_name, function["name"]), "{}_{}".format(lib_name, function["name"]), lib_name))
                # else:
                    # userc_content[function["line"]-1] = userc_content[function["line"]-1].replace(function["name"], "{}_{}".format(lib_name, function["name"]), 1)


            header_content = """//------------------------------------------------------------------
// Pinguino Library source code generated automatically.
//
// {} for {}bit
//
// Created: {}
// by: {}
//
//  WARNING! All changes made in this file will be lost!
//------------------------------------------------------------------\n
""".format(lib_name, arch_num, datetime.now().strftime("%Y-%m-%d %H:%M:%S"), os.getenv("PINGUINO_FULLNAME"))


            userc_file = open(userc, mode="w")
            userc_file.writelines([header_content] + [include] + ["\n".join(userc_content)])
            userc_file.close()

            pdl_file = open(pdl, mode="w")
            pdl_file.writelines([header_content] + pdl_content + ["\n"])
            pdl_file.close()

        if self.is_project():
            self.reload_project()

        self.add_library_to_env(lib_dir)
        Dialogs.info_message(self, "Library \"{}\" compiled.".format(lib_name))

        for filename in filenames:
            logging.debug("Generated: \"{}\"".format(filename))




    #----------------------------------------------------------------------
    def add_library_to_env(self, lib_dir):
        """"""
        os_name = os.getenv("PINGUINO_OS_NAME")
        if os_name == "windows":
            separator = ";"
        elif os_name == "linux":
            separator = ":"
        #FIXME_OSX
        # elif os_name == "macosx":
            # separator = ":"


        if os.path.exists(os.path.join(lib_dir, "p32")):
            os.environ["PINGUINO_P32"] = os.path.join(lib_dir, "p32")

        if os.path.exists(os.path.join(lib_dir, "p8")):
            os.environ["PINGUINO_P8"] = os.path.join(lib_dir, "p8")

        if os.path.exists(os.path.join(lib_dir, "pdl")):
            # os.environ["PINGUINO_PDL"] = os.listdir(os.path.join(lib_dir, "pdl"))
            os.environ["PINGUINO_PDL"] = separator.join([os.path.join(lib_dir, "pdl", filename) for filename in os.listdir(os.path.join(lib_dir, "pdl")) if filename.endswith(".pdl") or filename.endswith(".pdl32")])


    #----------------------------------------------------------------------
    def get_library_archs(self):
        """"""
        archs = []
        if self.ConfigProject.has_option("Main", "lib"):
            archs.append("p8")
        if self.ConfigProject.has_option("Main", "lib32"):
            archs.append("p32")

        return archs


    #----------------------------------------------------------------------
    def get_library_version(self):
        """"""
        parse_lib = RawConfigParser()
        parse_lib.readfp(open(os.path.join(self.get_library_path(), "PINGUINO"), "r"))
        return parse_lib.get("PINGUINO", "version")


    #----------------------------------------------------------------------
    def get_library_path(self):
        """"""
        return os.path.dirname(self.get_library_libs()[0])


    #----------------------------------------------------------------------
    def get_library_libs(self):
        """"""
        libs = []
        if self.ConfigProject.has_option("Main", "lib"):
            libs.append(self.ConfigProject.get("Main", "lib"))
        if self.ConfigProject.has_option("Main", "lib32"):
            libs.append(self.ConfigProject.get("Main", "lib32"))

        return libs


    #----------------------------------------------------------------------
    def set_library_libs(self, lib=None, lib32=None):
        """"""
        if lib:
            self.ConfigProject.set("Main", "lib", lib)

        if lib32:
            self.ConfigProject.set("Main", "lib32", lib32)


    #----------------------------------------------------------------------
    def package_library(self):
        """"""
        cwd = os.getcwd()
        os.chdir(self.get_library_path())


        try:
            manifest = open(os.path.join(self.get_library_path(), "MANIFEST.in"), "w+")
            manifest.write(PinguinoLib.get_manifest_template())
            manifest.close()

            setup = open(os.path.join(self.get_library_path(), "setup.py"), "w+")
            setup.write(PinguinoLib.get_setup_template())
            setup.close()

            dest = "-d{}".format(os.path.join(self.get_library_path(), "packages"))
            p = subprocess.Popen([sys.executable, "setup.py", "sdist", dest, "--formats=zip"],
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            out, err = p.communicate()
            self.write_log(out.decode())
            # self.write_log(err.decode())

            # if err:
                # raise Exception(err.decode())

            os.remove(os.path.join(self.get_library_path(), "MANIFEST.in"))
            os.remove(os.path.join(self.get_library_path(), "setup.py"))

            info = list(filter(lambda f:f.endswith(".egg-info"), os.listdir(self.get_library_path())))
            if info:
                try:
                    os.remove(os.path.join(self.get_library_path(), info[0]))
                except:
                    shutil.rmtree(os.path.join(self.get_library_path(), info[0]))

            if self.is_project():
                self.reload_project()
            Dialogs.info_message(self, "Package created in '{}'".format(os.path.join(self.get_library_path(), "packages")))


        except Exception as err:
            logging.error(err)

        os.chdir(cwd)

    # #----------------------------------------------------------------------
    # def package_library(self):
        # """"""
        # library_dir = self.get_library_path()
        # library_versioned_name = "{}-{}".format(self.get_project_name(), self.get_library_version())
        # package_name = "{}.zip".format(library_versioned_name)
        # package = ZipFile(os.path.join(library_dir, package_name), "w")

        # files = [
            # "pdl",
            # "examples",
            # # "{}.lib".format(self.get_project_name()),
            # # "{}.lib32".format(self.get_project_name()),
            # "p8",
            # "p32",
            # "PINGUINO",
            # "README.md",
            # "README",
        # ]

        # for target in files:
            # if os.path.exists(os.path.join(library_dir, target)):
                # package.write(os.path.join(library_dir, target), arcname=os.path.join(library_versioned_name, target))
                # logging.debug("Adding {} to {}".format(target, package_name))

                # if os.path.isdir(os.path.join(library_dir, target)):

                    # for root, dirs, files in os.walk(os.path.join(library_dir, target)):
                        # for file in files:
                            # package.write(os.path.join(root, file), arcname=os.path.join(library_versioned_name, os.path.split(root)[1], file))
                            # logging.debug("Adding {} to {}".format(os.path.join(root, file), package_name))


        # package.close()


    #----------------------------------------------------------------------
    def import_library(self, filename):
        """"""
        logging.debug("Loading library.")
        parce_pinguino = RawConfigParser()
        parce_pinguino.readfp(open(filename, "r"))

        library_dir = os.path.dirname(filename)
        library_name = parce_pinguino.get("PINGUINO", "name")

        self.project_saved = False
        self.ConfigProject = RawConfigParser()
        self.set_library_name(library_name)


        if "{}.lib".format(library_name) in os.listdir(library_dir):
            self.ConfigProject.set("Main", "lib", os.path.join(library_dir, "{}.lib".format(library_name)))
            self.ide_open_file_from_path(filename=os.path.join(library_dir, "{}.lib".format(library_name)))

        if "{}.lib32".format(library_name) in os.listdir(library_dir):
            self.ConfigProject.set("Main", "lib32", os.path.join(library_dir, "{}.lib32".format(library_name)))
            self.ide_open_file_from_path(filename=os.path.join(library_dir, "{}.lib32".format(library_name)))

        self.add_existing_directory(library_dir, inherits_status=True, library=True)
        self.update_project_status(library_name)

        #self.update_recents_projects(filename)

        #self.ide_open_file_from_path(filename=filename)


    #----------------------------------------------------------------------
    def update_library_project(self):
        """"""
        libs = []
        path = self.get_library_path()
        for file_ in os.listdir(path):
            if file_.endswith(".lib"):
                self.set_library_libs(lib=os.path.join(path, file_))
                libs.append("8bit")
            elif file_.endswith(".lib32"):
                self.set_library_libs(lib32=os.path.join(path, file_))
                libs.append("32bit")

        parse_lib = RawConfigParser()
        parse_lib.readfp(open(os.path.join(self.get_library_path(), "PINGUINO"), "r"))
        parse_lib.set("PINGUINO", "arch", ", ".join(set(libs)))
        self.ConfigProject.set("Main", "name", parse_lib.get("PINGUINO", "name"))
        # self.save_project(silent=False, default=False)
        parse_lib.write(open(os.path.join(self.get_library_path(), "PINGUINO"), "w"))




    #----------------------------------------------------------------------
    def get_library_kwargs(self):
        """"""
        path = self.get_default_project_dir()
        k = {}

        if os.path.exists(os.path.join(path, "p8")):
            k["p8"] = [os.path.join(path, "p8")]

        if os.path.exists(os.path.join(path, "p32")):
            k["p32"] = [os.path.join(path, "p32")]
        pdl = []
        for f in os.listdir(os.path.join(path, "pdl")):
            if f.endswith(".pdl") or  f.endswith(".pdl32"):
                pdl.append(os.path.join(path, "pdl", f))

        k["pdl"] = pdl

        return k class Boards(object):

    def __init__(self):

        self.build_devices_arch()

        all_groups = [self.main.frame_arch,
                      self.main.frame_prgmode,
                      # self.main.frame_bootloader,
                      self.main.frame_devices_8,
                      self.main.frame_devices_32]

        #self.HEAPSIZE = self.get_heapsize()

        #self.main.spinBox_heapsize.clear()
        #self.main.comboBox_heapsize.addItems(list(self.HEAPSIZE.keys()))

        self.OPTIMIZATION = "-O2 -O3 -Os".split()
        self.main.comboBox_optimization.clear()
        self.main.comboBox_optimization.addItems(self.OPTIMIZATION)
        self.init_groups()

        self.connect(self.main.radioButton_mode_usb, QtCore.SIGNAL("clicked()"), self.update_config)
        self.connect(self.main.radioButton_mode_icsp, QtCore.SIGNAL("clicked()"), self.update_config)
        self.connect(self.main.radioButton_mode_bt, QtCore.SIGNAL("clicked()"), self.update_config)

        self.connect(self.main.radioButton_compiler_sdcc, QtCore.SIGNAL("clicked()"), self.update_config)
        self.connect(self.main.radioButton_compiler_xc8, QtCore.SIGNAL("clicked()"), self.update_config)

        self.connect(self.main.radioButton_arch_8, QtCore.SIGNAL("clicked()"), self.update_config)
        self.connect(self.main.radioButton_arch_32, QtCore.SIGNAL("clicked()"), self.update_config)

        self.connect(self.main.checkBox_mips16, QtCore.SIGNAL("clicked()"), self.save_config)
        self.connect(self.main.spinBox_heapsize, QtCore.SIGNAL("valueChanged(QString)"), self.save_config)
        self.connect(self.main.comboBox_optimization, QtCore.SIGNAL("currentIndexChanged(QString)"), self.save_config)



        # self.connect(self.main.radioButton_bootloader_v1_v2, QtCore.SIGNAL("clicked()"), self.update_config)
        # self.connect(self.main.radioButton_bootloader_v4, QtCore.SIGNAL("clicked()"), self.update_config)

        self.load_config()

    ##----------------------------------------------------------------------
    #def update_mips16(self):
        #""""""
        #self.configIDE.set("Board", "mips16", self.main.checkBox_mips16.isChecked())
        #self.save_config()


    ##----------------------------------------------------------------------
    #def update_heapsize(self):
        #""""""
        #self.configIDE.set("Board", "heapsize", self.main.comboBox_heapsize.currentText())
        #self.save_config()


    ##----------------------------------------------------------------------
    #def update_optimization(self):
        #""""""
        #self.configIDE.set("Board", "optimization", self.main.comboBox_optimization.currentText())
        #self.save_config()


    ##----------------------------------------------------------------------
    #def get_heapsize(self):
        #""""""
        #heapsize = OrderedDict()
        #for b in range(0, 8000+512, 512):
            #heapsize["{} bytes".format(b)] = b

        #return heapsize

    #----------------------------------------------------------------------
    def load_config(self):

        self.configIDE.load_config()

        arch = self.configIDE.config("Board", "arch", 8)
        self.main.radioButton_arch_8.setChecked(arch == 8)
        self.main.radioButton_arch_32.setChecked(arch == 32)
        self.main.frame_advance.setVisible(arch == 32)

        compiler = self.configIDE.config("Board", "compiler", "SDCC")  #SDCC default compiler
        self.main.radioButton_compiler_sdcc.setChecked(compiler=="SDCC")
        self.main.radioButton_compiler_xc8.setChecked(compiler=="XC8")

        mode = self.configIDE.config("Board", "mode", "usb")
        self.main.radioButton_mode_usb.setChecked(mode == "usb")
        self.main.radioButton_mode_icsp.setChecked(mode == "icsp")
        self.main.radioButton_mode_bt.setChecked(mode == "bt")

        # bootloader = self.configIDE.config("Board", "bootloader", "v1_v2")
        # self.main.radioButton_bootloader_v1_v2.setChecked(bootloader == "v1_v2")
        # self.main.radioButton_bootloader_v4.setChecked(bootloader == "v4")

        mips16 = self.configIDE.config("Board", "mips16", True)
        self.main.checkBox_mips16.setChecked(mips16)

        heapsize = self.configIDE.config("Board", "heapsize", 0)
        #heapsize_values = list(self.HEAPSIZE.values())
        #index = heapsize_values.index(heapsize)
        self.main.spinBox_heapsize.setValue(heapsize)

        optimization = self.configIDE.config("Board", "optimization", "-O3")
        index = self.OPTIMIZATION.index(optimization)
        self.main.comboBox_optimization.setCurrentIndex(index)

        self.update_config()


    #----------------------------------------------------------------------
    def save_config(self, *args, **kwargs):

        if self.main.radioButton_arch_8.isChecked(): arch = 8
        else: arch = 32
        self.configIDE.set("Board", "arch", arch)

        if self.main.radioButton_compiler_sdcc.isChecked(): compiler = "SDCC"
        else: compiler = "XC8"
        self.configIDE.set("Board", "compiler", compiler)

        if self.main.radioButton_mode_usb.isChecked(): mode = "usb"
        if self.main.radioButton_mode_icsp.isChecked(): mode = "icsp"
        if self.main.radioButton_mode_bt.isChecked(): mode = "bt"
        self.configIDE.set("Board", "mode", mode)

        # if self.main.radioButton_bootloader_v1_v2.isChecked(): bootloader = "v1_v2"
        # else: bootloader = "v4"
        # self.configIDE.set("Board", "bootloader", bootloader)

        name = self.configIDE.config("Board", "board_"+str(arch), None)
        self.configIDE.set("Board", "board", name)

        self.configIDE.set("Board", "mips16", self.main.checkBox_mips16.isChecked())
        heapsize = self.main.spinBox_heapsize.value()
        self.configIDE.set("Board", "heapsize", heapsize)
        self.configIDE.set("Board", "optimization", self.main.comboBox_optimization.currentText())

        self.configIDE.save_config()


    #----------------------------------------------------------------------
    def update_config(self):

        mode_prog = self.main.radioButton_mode_usb.isChecked()
        arch_8 = self.main.radioButton_arch_8.isChecked()
        # self.main.frame_bootloader.setVisible(mode_prog and arch_8)

        self.main.frame_devices_32.setVisible(not arch_8)
        self.main.frame_devices_8.setVisible(arch_8)
        self.main.frame_compiler.setVisible(arch_8)

        self.main.frame_advance.setVisible(not arch_8)
        self.save_config()
        self.status_info.setText(self.get_status_board())


    #----------------------------------------------------------------------
    def init_groups(self):

        arch_8 = self.main.radioButton_arch_8.isChecked()
        self.main.frame_devices_32.setVisible(not arch_8)
        self.main.frame_devices_8.setVisible(arch_8)


    #----------------------------------------------------------------------
    def set_board_name(self, name, arch):

        def dummy():
            self.configIDE.set("Board", "board_"+arch, name)
            self.update_config()
        return dummy


    #----------------------------------------------------------------------
    def build_devices_arch(self):

        #8bits
        name_checked = self.configIDE.config("Board", "board_8", "Pinguino 45k50")  #Pinguino 45k50 default board
        arch_8 = list(filter(lambda board:board.arch==8, self.pinguinoAPI._boards_))
        # arch_8.sort()

        count = 0
        side = 0  #left
        for board in arch_8:
            if arch_8.index(board) == (len(arch_8) // 2) + 1:
                count = 0
                side = 1  #rigth

            radio = QtWidgets.QRadioButton(self.main.frame_devices_8)
            self.main.gridLayout_device_8.addWidget(radio, count, side, 1, 1)
            radio.setText(board.name)
            radio.setToolTip(board.proc)
            if name_checked == board.name: radio.setChecked(True)
            self.connect(radio, QtCore.SIGNAL("clicked()"), self.set_board_name(board.name, "8"))
            count += 1


        #32bits
        name_checked = self.configIDE.config("Board", "board_32", "PIC32 Pinguino OTG")
        arch_32 = list(filter(lambda board:board.arch==32, self.pinguinoAPI._boards_))
        # arch_32.sort()

        count = 0
        side = 0  #left
        for board in arch_32:
            if arch_32.index(board) == (len(arch_32) // 2) + 1:
                count = 0
                side = 1  #rigth

            radio = QtWidgets.QRadioButton(self.main.frame_devices_32)
            self.main.gridLayout_device_32.addWidget(radio, count, side, 1, 1)
            radio.setText(board.name)
            radio.setToolTip(board.proc)
            if name_checked == board.name: radio.setChecked(True)
            self.connect(radio, QtCore.SIGNAL("clicked()"), self.set_board_name(board.name, "32"))
            count += 1 class SourceBrowser(object):

    #----------------------------------------------------------------------
    def __init__(self):

        self.connect(self.main.tableWidget_functions, QtCore.SIGNAL("doubleClicked(QModelIndex)"), self.jump_function)
        self.connect(self.main.tableWidget_directives, QtCore.SIGNAL("doubleClicked(QModelIndex)"), self.jump_directive)
        self.connect(self.main.tableWidget_variables, QtCore.SIGNAL("doubleClicked(QModelIndex)"), self.jump_variable)
        self.connect(self.main.tableWidget_functions.verticalHeader(), QtCore.SIGNAL("sectionClicked(int)"), self.jump_function)
        self.connect(self.main.tableWidget_directives.verticalHeader(), QtCore.SIGNAL("sectionClicked(int)"), self.jump_directive)
        self.connect(self.main.tableWidget_variables.verticalHeader(), QtCore.SIGNAL("sectionClicked(int)"), self.jump_variable)

        self.connect(self.main.label_library_edit, QtCore.SIGNAL("linkActivated(QString)"), self.open_file_from_link)
        # self.connect(self.main.label_headers_edit, QtCore.SIGNAL("linkActivated(QString)"), self.open_file_from_link)


    #----------------------------------------------------------------------
    def set_functions(self, functions):

        self.functions = functions
        # self.update_functions()


    #----------------------------------------------------------------------
    def get_functions(self):

        if hasattr(self, "functions"): return self.functions
        else: return []


    #----------------------------------------------------------------------
    def set_directives(self, directives):

        self.directives = directives
        # self.update_directives()


    #----------------------------------------------------------------------
    def get_directives(self):

        if hasattr(self, "directives"): return self.directives
        else: return []


    #----------------------------------------------------------------------
    def set_variables(self, variables):

        self.variables = variables
        # self.update_variables()


    #----------------------------------------------------------------------
    def get_variables(self):

        if hasattr(self, "variables"): return self.variables
        else: return []


    #----------------------------------------------------------------------
    @Decorator.clear_highlighted_lines()
    def jump_function(self, row):

        if type(row) == int:
            item = self.main.tableWidget_functions.verticalHeaderItem(row)
        else:
            item = self.main.tableWidget_functions.verticalHeaderItem(row.column())

        if getattr(item, "filename", False):
            self.ide_open_file_from_path(filename=item.filename)
        self.editor_highligh_line(item.line, "#DBFFE3")


    #----------------------------------------------------------------------
    @Decorator.clear_highlighted_lines()
    def jump_variable(self, row):

        if type(row) == int:
            item = self.main.tableWidget_variables.verticalHeaderItem(row)
        else:
            item = self.main.tableWidget_variables.verticalHeaderItem(row.column())

        if getattr(item, "filename", False):
            self.ide_open_file_from_path(filename=item.filename)
        self.editor_highligh_line(item.line, "#DBFFE3")


    #----------------------------------------------------------------------
    @Decorator.clear_highlighted_lines()
    def jump_directive(self, row):

        if type(row) == int:
            item = self.main.tableWidget_directives.verticalHeaderItem(row)
        else:
            item = self.main.tableWidget_directives.verticalHeaderItem(row.column())

        if getattr(item, "filename", False):
            self.ide_open_file_from_path(filename=item.filename)
        self.editor_highligh_line(item.line, "#DBFFE3")


    #----------------------------------------------------------------------
    def get_files_to_explore(self):
        """"""
        if self.is_project() and not self.is_library():
            """"""
            # files = self.get_files_from_project()

            filenames = [s[0] for s in filter(lambda l:l[1], self.get_files_from_project().items())]
            filenames.extend([s[0] for s in filter(lambda l:l[1], self.get_inherits_from_project().items())])

            files = [{"filename": filename, "content": str(codecs.open(filename, encoding="utf-8").read()),} for filename in filenames]
            return files

        else:
            if self.is_graphical() is False:
                return [{"filename": "",
                         "content": str(self.get_current_editor().text_edit.toPlainText())}]
            else:
                return []



    #----------------------------------------------------------------------
    def update_assistant(self, name):
        """"""
        if not hasattr(self, "assistant"): self.set_assistant()

        if name in self.assistant:

            link = "<a href='{text}'><span style='text-decoration: none; color:#2980b9;'>{text}</span></a>"
            html = "<html><head/><body><p>{links}</p></body></html>"

            self.main.label_name_edit.setText("{} ({name})".format(name, **self.assistant[name]))
            self.main.label_args_edit.setText("({args})".format(**self.assistant[name]))
            self.main.label_library_edit.setText(html.format(links=link.format(text=self.assistant[name]["filename"])))

            return_ = self.assistant[name]["return"]
            if return_ == "void": return_ = "None"
            self.main.label_return_edit.setText("{}".format(return_))

            # return True
            self.main.label_source_browser.setVisible(False)


    #----------------------------------------------------------------------
    def set_assistant(self):
        """"""
        with open(os.path.join(os.getenv("PINGUINO_USER_PATH"), "reserved.pickle"), "rb") as file_reserved:
            self.assistant = pickle.load(file_reserved).get("assistant", {})


    #----------------------------------------------------------------------
    def open_file_from_link(self, name):
        """"""
        core = os.path.join(os.getenv("PINGUINO_INSTALL_PATH"), "p8", "include", "pinguino", "core")
        libraries = os.path.join(os.getenv("PINGUINO_INSTALL_PATH"), "p8", "include", "pinguino", "libraries")

        path = None
        if name in os.listdir(core):
            path =  os.path.join(core, name)
        elif name in os.listdir(libraries):
            path =  os.path.join(libraries, name)

        if path is None:
            for path_ in PinguinoConfig.get_p8_libraries() + PinguinoConfig.get_p32_libraries():
                if name in os.listdir(path_):
                    path = os.path.join(path_, name)
                    break

        if os.path.exists(path):
            self.ide_open_file_from_path(filename=path, readonly=True)



    # #----------------------------------------------------------------------
    # def update_code_navigator(self):
        # """"""
        # self.update_variables()
        # self.update_functions()
        # self.update_directives() class Paths(object):

    def __init__(self):
        """"""

        self.load_paths()

        self.connect(self.main.lineEdit_path_sdcc_bin, QtCore.SIGNAL("editingFinished()"), self.save_paths)
        self.connect(self.main.lineEdit_path_gcc_bin, QtCore.SIGNAL("editingFinished()"), self.save_paths)
        self.connect(self.main.lineEdit_path_xc8_bin, QtCore.SIGNAL("editingFinished()"), self.save_paths)
        self.connect(self.main.lineEdit_path_8_libs, QtCore.SIGNAL("editingFinished()"), self.save_paths)
        self.connect(self.main.lineEdit_path_32_libs, QtCore.SIGNAL("editingFinished()"), self.save_paths)

        self.connect(self.main.pushButton_dir_sdcc, QtCore.SIGNAL("clicked()"), lambda :self.open_path_for(self.main.lineEdit_path_sdcc_bin))
        self.connect(self.main.pushButton_dir_gcc, QtCore.SIGNAL("clicked()"), lambda :self.open_path_for(self.main.lineEdit_path_gcc_bin))
        self.connect(self.main.pushButton_dir_xc8, QtCore.SIGNAL("clicked()"), lambda :self.open_path_for(self.main.lineEdit_path_xc8_bin))
        self.connect(self.main.pushButton_dir_8bit, QtCore.SIGNAL("clicked()"), lambda :self.open_path_for(self.main.lineEdit_path_8_libs))
        self.connect(self.main.pushButton_dir_32bit, QtCore.SIGNAL("clicked()"), lambda :self.open_path_for(self.main.lineEdit_path_32_libs))
        self.connect(self.main.pushButton_dir_libs, QtCore.SIGNAL("clicked()"), lambda :self.open_path_for(self.main.lineEdit_path_custom_libs))
        self.connect(self.main.pushButton_dir_mplab, QtCore.SIGNAL("clicked()"), lambda :self.open_path_for(self.main.lineEdit_path_mplab))

        self.connect(self.main.checkBox_paths_default, QtCore.SIGNAL("toggled(bool)"), self.set_default_values)


    #----------------------------------------------------------------------
    def open_path_for(self, lineedit):
        """"""
        dir_path = Dialogs.set_open_dir(self)
        if dir_path:
            lineedit.setText(dir_path)
            self.save_paths()


    #----------------------------------------------------------------------
    def save_paths(self):
        """"""
        sdcc_bin = self.main.lineEdit_path_sdcc_bin.text()
        gcc_bin = self.main.lineEdit_path_gcc_bin.text()
        xc8_bin = self.main.lineEdit_path_xc8_bin.text()
        p8libs = self.main.lineEdit_path_8_libs.text()
        p32libs = self.main.lineEdit_path_32_libs.text()

        #self.configIDE.set("Paths", "sdcc_bin", sdcc_bin)
        #self.configIDE.set("Paths", "gcc_bin", gcc_bin)
        #self.configIDE.set("Paths", "xc8_bin", xc8_bin)
        #self.configIDE.set("Paths", "pinguino_8_libs", p8libs)
        #self.configIDE.set("Paths", "pinguino_32_libs", p32libs)

        self.configIDE.set("PathsCustom", "sdcc_bin", sdcc_bin)
        self.configIDE.set("PathsCustom", "gcc_bin", gcc_bin)
        self.configIDE.set("PathsCustom", "xc8_bin", xc8_bin)
        self.configIDE.set("PathsCustom", "pinguino_8_libs", p8libs)
        self.configIDE.set("PathsCustom", "pinguino_32_libs", p32libs)

        self.configIDE.save_config()



    #----------------------------------------------------------------------
    def load_paths(self, section=None):
        """"""
        self.configIDE.load_config()
        if section is None:
            section = self.configIDE.config("Features", "pathstouse", "Paths")

        self.main.checkBox_paths_default.setChecked(section=="Paths")

        def short(section, option):
            if section == "Paths":
                return self.configIDE.get(section, option)
            elif section == "PathsCustom":
                return self.configIDE.config(section, option, self.configIDE.get("Paths", option))

        sdcc_bin = short(section, "sdcc_bin")
        gcc_bin = short(section, "gcc_bin")
        xc8_bin = short(section, "xc8_bin")
        p8libs = short(section, "pinguino_8_libs")
        p32libs = short(section, "pinguino_32_libs")

        self.main.lineEdit_path_sdcc_bin.setText(sdcc_bin)
        self.main.lineEdit_path_gcc_bin.setText(gcc_bin)
        self.main.lineEdit_path_xc8_bin.setText(xc8_bin)
        self.main.lineEdit_path_8_libs.setText(p8libs)
        self.main.lineEdit_path_32_libs.setText(p32libs)



    #----------------------------------------------------------------------
    def set_default_values(self, default):
        """"""

        self.configIDE.load_config()

        if default:
            self.load_paths(section="Paths")
            self.configIDE.set("Features", "pathstouse", "Paths")

        else:
            self.load_paths(section="PathsCustom")
            self.configIDE.set("Features", "pathstouse", "PathsCustom")


        self.main.groupBox_compilers.setEnabled(not default)
        self.main.groupBox_libraries.setEnabled(not default)
        self.main.groupBox_icsp.setEnabled(not default)

        self.configIDE.save_config() class TimedMethods(object):



    #----------------------------------------------------------------------
    @Decorator.timer(1500)
    @Decorator.requiere_open_files()
    @Decorator.requiere_browser_tab("Functions")
    @Decorator.requiere_tools_tab("SourceBrowser")
    @Decorator.requiere_main_focus()
    def timer_update_functions(self):

        functions_parse = self.get_functions()

        index = 0
        self.main.tableWidget_functions.setRowCount(len(functions_parse))
        self.completer_funtions = []
        for funtion in functions_parse:
            item = QtGui.QTableWidgetItem()
            self.main.tableWidget_functions.setVerticalHeaderItem(index, item)
            item.setText(funtion["name"])
            self.completer_funtions.append(funtion["name"])

            self.main.tableWidget_functions.setItem(index, 0, QtGui.QTableWidgetItem())
            self.main.tableWidget_functions.setItem(index, 1, QtGui.QTableWidgetItem())
            self.main.tableWidget_functions.setItem(index, 2, QtGui.QTableWidgetItem())

            if funtion["filename"]:
                self.main.tableWidget_functions.item(index, 0).setText(os.path.split(funtion["filename"])[1])
            else:
                self.main.tableWidget_functions.item(index, 0).setText(self.get_current_filename())


            self.main.tableWidget_functions.item(index, 1).setText(funtion["return"])
            self.main.tableWidget_functions.item(index, 2).setText(funtion["args"])

            setattr(item, "filename", funtion["filename"])
            setattr(item, "line", funtion["line"])

            index += 1


    #----------------------------------------------------------------------
    @Decorator.timer(1500)
    @Decorator.requiere_open_files()
    @Decorator.requiere_browser_tab("Directives")
    @Decorator.requiere_tools_tab("SourceBrowser")
    @Decorator.requiere_main_focus()
    def timer_update_directives(self):
        """"""

        directives_parse = self.get_directives()

        index = 0
        self.main.tableWidget_directives.setRowCount(len(directives_parse))
        self.completer_directives = []
        for directive in directives_parse:
            item = QtGui.QTableWidgetItem()
            self.main.tableWidget_directives.setVerticalHeaderItem(index, item)
            item.setText(directive["name"])
            self.completer_directives.append(directive["name"])

            self.main.tableWidget_directives.setItem(index, 0, QtGui.QTableWidgetItem())
            self.main.tableWidget_directives.setItem(index, 1, QtGui.QTableWidgetItem())
            self.main.tableWidget_directives.setItem(index, 2, QtGui.QTableWidgetItem())

            if directive["filename"]:
                self.main.tableWidget_directives.item(index, 0).setText(os.path.split(directive["filename"])[1])
            else:
                self.main.tableWidget_directives.item(index, 0).setText(self.get_current_filename())

            self.main.tableWidget_directives.item(index, 1).setText(directive["type"])
            self.main.tableWidget_directives.item(index, 2).setText(directive["value"])

            setattr(item, "filename", directive["filename"])
            setattr(item, "line", directive["line"])
            index += 1



    #----------------------------------------------------------------------
    @Decorator.timer(1500)
    @Decorator.requiere_open_files()
    @Decorator.requiere_browser_tab("Variables")
    @Decorator.requiere_tools_tab("SourceBrowser")
    @Decorator.requiere_main_focus()
    def timer_update_variables(self):

        variables_parse = self.get_variables()

        index = 0
        self.main.tableWidget_variables.setRowCount(len(variables_parse))
        self.completer_variables = []
        for variable in variables_parse:
            item = QtGui.QTableWidgetItem()
            self.main.tableWidget_variables.setVerticalHeaderItem(index, item)
            item.setText(variable["name"])
            self.completer_variables.append([variable["name"], variable["type"]])

            self.main.tableWidget_variables.setItem(index, 0, QtGui.QTableWidgetItem())
            self.main.tableWidget_variables.setItem(index, 1, QtGui.QTableWidgetItem())

            if variable["filename"]:
                self.main.tableWidget_variables.item(index, 0).setText(os.path.split(variable["filename"])[1])
            else:
                self.main.tableWidget_variables.item(index, 0).setText(self.get_current_filename())

            self.main.tableWidget_variables.item(index, 1).setText(variable["type"])

            setattr(item, "filename", variable["filename"])
            setattr(item, "line", variable["line"])
            index += 1


    #----------------------------------------------------------------------
    @Decorator.timer(3000)
    @Decorator.requiere_open_files()
    @Decorator.requiere_text_mode()
    @Decorator.requiere_main_focus()
    def timer_check_changes(self):

        editor = self.get_current_editor()
        filename = getattr(editor, "path", None)
        if not filename:
            return

        if os.path.exists(filename):
            file_ = codecs.open(filename, "r", encoding="utf-8")
            content_file = "".join(file_.readlines())
            file_.close()
            exist = True
        else:
            content_file = ""
            exist = False

        last_saved = getattr(editor, "last_saved")

        # if content_file != last_saved:
            # self.thread_variables()

        if self.get_current_filename().endswith("(r/o)"):
            if content_file != last_saved:
                self.editor_reload_file()
            self.ide_save_file()
            return

        if self.is_library():
            name = self.get_project_name()
            if self.get_current_filename().startswith(name) and (self.get_current_filename().endswith(".c")\
                                                                 or self.get_current_filename().endswith(".h")\
                                                                 or self.get_current_filename().endswith(".pdl")\
                                                                 or self.get_current_filename().endswith(".pdl32")):
                if content_file != last_saved:
                    self.editor_reload_file()
                self.ide_save_file()
                return




        if content_file != last_saved:
            reload_ = Dialogs.overwrite_file(self, filename, exist)

            if reload_:
                self.ide_save_file()
            else:
                self.editor_reload_file()


    #----------------------------------------------------------------------
    @Decorator.timer(3000)
    @Decorator.requiere_open_files()
    # @Decorator.requiere_text_mode()
    @Decorator.requiere_main_focus()
    def timer_backup_file(self):

        editor = self.get_current_editor()
        # index = self.main.tabWidget_files.indexOf(editor)
        # filename_tab = self.main.tabWidget_files.tabText(index)
        filename = getattr(editor, "path", None)
        if not filename:
            return
        content_saved = getattr(editor, "last_saved", None)

        if self.is_graphical() is True:
            content = self.PinguinoKIT.get_gpde()
            self.PinguinoKIT.save_raw_parser(content, editor.path+"~")

        elif self.is_graphical() is False:
            content = editor.text_edit.toPlainText()
            filename_backup = filename + "~"
            #if os.path.exists(filename) and filename_tab.endswith("*"):
            if os.path.exists(filename) and (content_saved != content):
                file_ = codecs.open(filename_backup, "w", encoding="utf-8")
                file_.write(content)
                file_.close()

        elif content_saved == content and os.path.exists(filename_backup):
            os.remove(filename_backup)


    #----------------------------------------------------------------------
    @Decorator.timer(1000)
    @Decorator.requiere_open_files()
    @Decorator.requiere_tools_tab("SourceBrowser")
    @Decorator.requiere_main_focus()
    def timer_update_assiatant(self):

        if not self.is_graphical() is None:
            editor = self.get_current_editor()
            if not hasattr(editor, "text_edit"): return
            tc = editor.text_edit.textCursor()
            tc.movePosition(tc.EndOfWord, tc.MoveAnchor)
            editor.text_edit.smart_under_selection(tc)
            selected = tc.selectedText()
            self.update_assistant(selected)


    #----------------------------------------------------------------------
    @Decorator.timer(3000)
    @Decorator.requiere_open_files()
    @Decorator.requiere_text_mode()
    @Decorator.if_autocomplete_is_enable()
    @Decorator.requiere_main_focus()
    def timer_update_autocompleter(self):
        """"""

        if not self.is_graphical() is False: return

        editor = self.get_current_editor()

        if (not hasattr(self, "thread_autocompleter")) and hasattr(editor.text_edit, "completer"):
            self.thread_autocompleter = UpdateAutocompleter()
            self.thread_autocompleter.signal_set_variables.connect(self.set_variables)
            self.thread_autocompleter.signal_set_directives.connect(self.set_directives)
            self.thread_autocompleter.signal_set_functions.connect(self.set_functions)
            self.thread_autocompleter.signal_add_autocompleter.connect(editor.text_edit.completer.addTemporalItem)
            self.thread_autocompleter.signal_rm_autocompleter.connect(editor.text_edit.completer.removeTemporalItems)

        if not hasattr(self, "thread_autocompleter"):
            return

        if not self.thread_autocompleter.isRunning():
            self.thread_autocompleter.set_files(self.get_files_to_explore())
            self.thread_autocompleter.setTerminationEnabled(True)
            self.thread_autocompleter.start()
        ##else:
            ##logging.debug("Working...")
            ##self.thread_autocompleter.terminate()
            ##self.thread_autocompleter.set_files(self.get_files_to_explore())
            ##self.thread_autocompleter.setTerminationEnabled(True)
            ##self.thread_autocompleter.start() class About(QtWidgets.QDialog):

    def __init__(self):
        super(About, self).__init__()
        self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint |
                            QtCore.Qt.WindowSystemMenuHint |
                            QtCore.Qt.WindowStaysOnTopHint |
                            QtCore.Qt.Tool)

        self.about = Ui_About()
        self.about.setupUi(self)

        self.setWindowTitle(os.getenv("PINGUINO_NAME")+" - "+self.windowTitle())

        self.about.label_name.setText(os.getenv("PINGUINO_FULLNAME"))

        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/logo/art/windowIcon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)

        self.connect(self.about.pushButton_credits, QtCore.SIGNAL("clicked()"), lambda :self.about.stackedWidget.setCurrentIndex(1))
        self.connect(self.about.pushButton_license, QtCore.SIGNAL("clicked()"), lambda :self.about.stackedWidget.setCurrentIndex(2))
        self.connect(self.about.pushButton_about, QtCore.SIGNAL("clicked()"), lambda :self.about.stackedWidget.setCurrentIndex(0))
        self.connect(self.about.pushButton_close, QtCore.SIGNAL("clicked()"), self.close)
        self.connect(self.about.pushButton_close_2, QtCore.SIGNAL("clicked()"), self.close)
        self.connect(self.about.pushButton_close_3, QtCore.SIGNAL("clicked()"), self.close)

        self.about.stackedWidget.setCurrentIndex(0)
        self.about.tabWidget.setCurrentIndex(0)

        self.setStyleSheet("""
        font-family: inherit;
        font-weight: normal;

        """)

        self.center_on_screen()

    #----------------------------------------------------------------------
    def center_on_screen(self):

        screen = QtGui.QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2) class InsertBlock(QtWidgets.QDialog):

    def __init__(self, KIT):
        super(InsertBlock, self).__init__()

        self.insert = Ui_InsertBlock()
        self.insert.setupUi(self)

        self.setWindowTitle(os.getenv("PINGUINO_NAME")+" - "+self.windowTitle())

        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/logo/art/windowIcon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)

        self.graphical = KIT

        self.connect(self.insert.lineEdit, QtCore.SIGNAL("textChanged(QString)"), self.update_blocks)
        self.connect(self.insert.listWidget, QtCore.SIGNAL("itemActivated(QListWidgetItem*)"), self.insert_block)
        #self.connect(self.insert.listWidget, QtCore.SIGNAL("itemEntered(QListWidgetItem*)"), self.insert_block)

        self.insert.lineEdit.keyPressEvent = self.line_edit_key
        self.insert.listWidget.keyPressEvent = self.list_key

        self.insert.lineEdit.setText(QtWidgets.QApplication.translate("Dialogs", "search block..."))
        self.insert.lineEdit.selectAll()

        self.setStyleSheet("""
        font-family: inherit;
        font-weight: normal;

        """)

        self.center_on_screen()


    #----------------------------------------------------------------------
    def center_on_screen(self):

        screen = QtGui.QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)

    #----------------------------------------------------------------------
    def line_edit_key(self, event):

        key = event.key()
        if key in (QtCore.Qt.Key_Down, ):
            self.insert.listWidget.setFocus()
            self.insert.listWidget.setCurrentRow(0)

        if key in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Enter - 1):
            if self.insert.listWidget.count() == 1:
                self.insert_block(self.insert.listWidget.item(0))

        QtWidgets.QLineEdit.keyPressEvent(self.insert.lineEdit, event)


    #----------------------------------------------------------------------
    def list_key(self, event):

        key = event.key()
        if key in (QtCore.Qt.Key_Down,
                   QtCore.Qt.Key_Up,
                   QtCore.Qt.Key_Enter,
                   QtCore.Qt.Key_Enter - 1,
                   ):
            QtGui.QListWidget.keyPressEvent(self.insert.listWidget, event)
            return
        QtWidgets.QLineEdit.keyPressEvent(self.insert.lineEdit, event)


    #----------------------------------------------------------------------
    def update_blocks(self, text):

        bloques = []
        self.items = {}
        self.all_sets = self.graphical.get_all_sets()
        for key in self.all_sets.keys():
            if self.all_sets[key][2][0] in ["label", "decorator"]:
                label = self.all_sets[key][2][1]
                if label.lower().startswith(text.lower()):
                    bloques.append([key, self.all_sets[key]])
                    self.items[label] = [key, self.all_sets[key]]
        self.insert.listWidget.clear()
        self.insert.listWidget.addItems(self.items.keys())


    #----------------------------------------------------------------------
    def insert_block(self, list_widget):

        self.hide()
        work_area = self.graphical.get_work_area()
        block = self.items[list_widget.text()]
        name = block[1][0]
        args = block[1][:]
        baseName = list_widget.text()
        args[0] = ""
        args[1] = ""
        pos = self.cursor().pos() - QtCore.QPoint(10, 10)
        if name: work_area.new_bloq(name, args, pos, baseName)
        self.close() class SubmitBug(QtWidgets.QDialog):

    def __init__(self, parent, details=""):
        super(SubmitBug, self).__init__()
        self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint |
                            QtCore.Qt.WindowSystemMenuHint |
                            QtCore.Qt.WindowStaysOnTopHint |
                            QtCore.Qt.Tool)

        self.submit = Ui_SubmitBug()
        self.submit.setupUi(self)
        self.main = parent

        username, password = self.get_auth()
        self.submit.lineEdit_username.setText(username)
        self.submit.lineEdit_password.setText(password)

        self.submit.plainTextEdit_details.insertPlainText(details)

        self.setWindowTitle(os.getenv("PINGUINO_NAME")+" - "+self.windowTitle())

        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/logo/art/windowIcon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)

        self.connect(self.submit.pushButton_submit, QtCore.SIGNAL("clicked()"), self.submit_now)
        self.connect(self.submit.pushButton_cancel, QtCore.SIGNAL("clicked()"), self.close)
        self.connect(self.submit.checkBox_show_this_dialog, QtCore.SIGNAL("clicked()"), self.update_submit_dialog)

        self.setStyleSheet("""
        font-family: inherit;
        font-weight: normal;

        """)

        self.center_on_screen()

    #----------------------------------------------------------------------
    def center_on_screen(self):

        screen = QtWidgets.QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)


    #----------------------------------------------------------------------
    def update_submit_dialog(self):

        self.main.configIDE.set("Features", "submmit_bugs", self.submit.checkBox_show_this_dialog.isChecked())


    #----------------------------------------------------------------------
    def submit_now(self):
        """"""

        summary = self.submit.lineEdit_summary.text().replace("\n", "<br>")
        details = self.submit.plainTextEdit_details.toPlainText()
        username = self.submit.lineEdit_username.text()
        password = self.submit.lineEdit_password.text()
        repo = self.submit.comboBox_repo.currentText()

        if not details:
            Dialogs.error_message(self, "No details!")
            return

        if not username:
            Dialogs.error_message(self, "No userbane!")
            return

        if not password:
            Dialogs.error_message(self, "No password!")
            return

        environ = self.get_systeminfo()
        logging.info("Submitting bug report.")
        maked = self.make_github_issue(summary, details, repo, environ, username, password)
        #response = urlopen(SUBMIT_SERVER, urlencode({"summary": summary, "details": details, "environ": environ,}).encode("utf-8"))
        #share_link = eval(response.read())["share"]
        self.hide()

        if not maked:
            if details and environ:
                self.save_for_later(summary, details, repo, environ, username, password)
            logging.error("ConnectionError")

        self.close()


    #----------------------------------------------------------------------
    def get_systeminfo(self):

        data = {}
        try: data["os.name"] = str(os.name)
        except: pass
        try: data["os.environ"] = str(os.environ)
        except: pass
        try: data["os.uname"] = str(os.uname())
        except: pass
        try: data["sys.argv"] = str(sys.argv)
        except: pass
        try: data["sys.flags"] = str(sys.flags)
        except: pass
        try: data["sys.platform"] = str(sys.platform)
        except: pass
        try: data["sys.version"] = str(sys.version)
        except: pass
        try: data["platform.architecture"] = str(platform.architecture())
        except: pass
        try: data["platform.dist"] = str(platform.dist())
        except: pass
        try: data["platform.linux_distribution"] = str(platform.linux_distribution())
        except: pass
        try: data["platform.mac_ver"] = str(platform.mac_ver())
        except: pass
        try: data["platform.system"] = str(platform.system())
        except: pass
        try: data["platform.win32_ver"] = str(platform.win32_ver())
        except: pass
        try: data["platform.libc_ver"] = str(platform.libc_ver())
        except: pass
        try: data["platform.machine"] = str(platform.machine())
        except: pass
        try: data["platform.platform"] = str(platform.platform())
        except: pass
        try: data["platform.release"] = str(platform.release())
        except: pass
        try: data["pyusb"] = str(usb.__version__)
        except: pass

        return "\n".join([": ".join(item) for item in data.items()])


    #----------------------------------------------------------------------
    def save_for_later(self, summary, details, repo, environ, username, password):
        """"""
        parser = RawConfigParser()
        parser.add_section("SUBMIT")
        parser.set("SUBMIT", "summary", summary)
        parser.set("SUBMIT", "details", details)
        parser.set("SUBMIT", "repo", repo)
        parser.set("SUBMIT", "environ", environ)
        parser.set("SUBMIT", "username", username)
        parser.set("SUBMIT", "password", password)

        filename = os.path.join(os.getenv("PINGUINO_USER_PATH"), "submit-{}".format(datetime.now()))
        parser.write(open(filename, "w"))


    #----------------------------------------------------------------------
    def save_auth(self, username, password):
        """"""
        parser = RawConfigParser()
        parser.add_section("AUTH")
        parser.set("AUTH", "username", username)
        parser.set("AUTH", "password", password)

        filename = os.path.join(os.getenv("PINGUINO_USER_PATH"), "submit-auth")
        parser.write(open(filename, "w"))


    #----------------------------------------------------------------------
    def get_auth(self):
        """"""
        if not os.path.exists(os.path.join(os.getenv("PINGUINO_USER_PATH"), "submit-auth")):
            return '', ''

        parser = RawConfigParser()
        filename = os.path.join(os.getenv("PINGUINO_USER_PATH"), "submit-auth")
        parser.readfp(open(filename, "r"))

        username = parser.get("AUTH", "username")
        password = parser.get("AUTH", "password")

        return username, password


    #----------------------------------------------------------------------
    def make_github_issue(self, summary, details, repo, environ, username, password):
        '''Create an issue on github.com using the given parameters.'''
        # Our url to create issues via POST
        url = 'https://api.github.com/repos/{}/{}/issues'.format('PinguinoIDE', repo)
        # Create an authenticated session to create the issue
        #session = requests.session(auth=(username, password))
        session = requests.Session()
        session.auth = (username, password)

        # Create our issue
        issue = {'title': summary,
                 'body': "{}\n\n{}".format(details, environ),
                 'labels': ['submitted-from-ide',
                            'bug',
                            'v{}'.format(os.environ["PINGUINO_VERSION"][:2]),
                            ],
                 }

        # Add the issue to our repository
        r = session.post(url, json.dumps(issue))
        if r.status_code == 201:
            logging.info('Successfully created Issue "{}"'.format(summary))
            self.save_auth(username, password)

        return r.status_code == 201 def send_old_submits():

    submits = filter(lambda s:s.startswith("submit-"), os.listdir(os.getenv("PINGUINO_USER_PATH")))
    for submit in submits:
        parser = RawConfigParser()
        filename = os.path.join(os.getenv("PINGUINO_USER_PATH"), submit)
        parser.readfp(open(filename, "r"))

        summary = parser.get("SUBMIT", "summary")
        details = parser.get("SUBMIT", "details")
        repo = parser.get("SUBMIT", "repo")
        environ = parser.get("SUBMIT", "environ")
        username = parser.get("SUBMIT", "username")
        password = parser.get("SUBMIT", "password")


        try:
            url = 'https://api.github.com/repos/{}/{}/issues'.form
            session = requests.Session()
            session.auth = (username, password)
            issue = {'title': summary,
                     'body': "{}\n\n{}".format(details, environ),
                     'labels': ['submitted-from-ide',
                                'bug',
                                'v{}'.format(os.environ["PINGUINO_VERSION"][:2]),
                                ],
                     }
            r = session.post(url, json.dumps(issue))
            os.remove(filename)
        except:
            pass class LibraryTemplate(QtWidgets.QDialog):

    def __init__(self, parent):
        super(LibraryTemplate, self).__init__()

        self.lib_template = Ui_LibraryTemplate()
        self.lib_template.setupUi(self)
        self.main = parent

        self.setWindowTitle(os.getenv("PINGUINO_NAME")+" - "+self.windowTitle())

        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/logo/art/windowIcon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)

        self.lib_template.lineEdit_lib_author.setText(os.environ.get("USER", ""))

        self.connect(self.lib_template.pushButton_accept, QtCore.SIGNAL("clicked()"), self.accept)
        self.connect(self.lib_template.pushButton_cancel, QtCore.SIGNAL("clicked()"), self.close)
        self.connect(self.lib_template.pushButton_lib_path, QtCore.SIGNAL("clicked()"), self.set_directory)
        self.connect(self.lib_template.checkBox_lib32, QtCore.SIGNAL("clicked(bool)"), self.can_generate)
        self.connect(self.lib_template.checkBox_lib8, QtCore.SIGNAL("clicked(bool)"), self.can_generate)
        self.connect(self.lib_template.lineEdit_lib_name, QtCore.SIGNAL("textChanged(QString)"), self.can_generate)
        self.connect(self.lib_template.lineEdit_lib_path, QtCore.SIGNAL("textChanged(QString)"), self.can_generate)

        self.center_on_screen()


    #----------------------------------------------------------------------
    def center_on_screen(self):

        screen = QtGui.QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)


    #----------------------------------------------------------------------
    def set_directory(self):

        target_dir = Dialogs.set_open_dir(self.main)
        if target_dir:
            self.lib_template.lineEdit_lib_path.setText(target_dir)


    #----------------------------------------------------------------------
    def accept(self):

        author = self.lib_template.lineEdit_lib_author.text()
        libname = self.lib_template.lineEdit_lib_name.text()
        libpath = self.lib_template.lineEdit_lib_path.text()
        description = self.lib_template.plainTextEdit_lib_description.toPlainText()
        _8bit = self.lib_template.checkBox_lib8.isChecked()
        _32bit = self.lib_template.checkBox_lib32.isChecked()

        kwargs = locals().copy()
        kwargs.pop("self")
        self.main.new_library(**kwargs)
        self.close()


    #----------------------------------------------------------------------
    def can_generate(self, event):

        libname = self.lib_template.lineEdit_lib_name.text()
        libpath = self.lib_template.lineEdit_lib_path.text()
        _8bit = self.lib_template.checkBox_lib8.isChecked()
        _32bit = self.lib_template.checkBox_lib32.isChecked()

        if re.match("[a-zA-Z_]+[_0-9a-zA-Z]*", libname):
            self.lib_template.pushButton_accept.setEnabled(libname and os.path.isdir(libpath) and (_8bit or _32bit))
        else:
            self.lib_template.pushButton_accept.setEnabled(False)
import os
import codecs
import pickle
import logging
import webbrowser
import shutil
        import time
        import sys
from math import ceil
from PySide2 import QtGui, QtCore, QtWidgets
from ...pinguino_core.pinguino_config import PinguinoConfig
from .core_threads import UpdateAutocompleter  #, PinguinoRequest
from .parser import PinguinoParser
from ..custom_widgets import PinguinoCodeEditor
from .decorators import Decorator
from .dialogs import Dialogs
from ..tools.files import Files
from ..tools.search import Search
from ..tools.project import Project
from ..tools.boards import Boards
from ..tools.source_browser import SourceBrowser
from ..tools.paths import Paths
from .timed_methods import TimedMethods
from ..child_windows.about import About
from ..child_windows.insert_block_dialog import InsertBlock
from ..child_windows.submit_bug import SubmitBug, send_old_submits
from ..child_windows.library_template import LibraryTemplate
            from pinguino import pinguino_reset
#!/usr/bin/env python
#-*- coding: utf-8 -*-


# import requests
# from urllib import request
# import urllib
# import json





# from ..tools.library_manager import LibraryManager
# from ..methods.library_manager import Librarymanager
# from ..widgets.output_widget import START

# from .event_methods import EventMethods

# from ..child_windows.libraries import LibManager
# from ..child_windows.paths import Paths
# from ..child_windows.hex_viewer import HexViewer
# from ..child_windows.environ_viewer import EnvironViewer


########################################################################
class PinguinoComponents(TimedMethods, Search, Project, Files, Boards, SourceBrowser, Paths):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """"""
        Boards.__init__(self)
        Search.__init__(self)
        SourceBrowser.__init__(self)
        Files.__init__(self)
        Project.__init__(self)
        Paths.__init__(self)
        # LibraryManager.__init__(self)
        # super(BoardConfig, self).__init__()



########################################################################
class PinguinoChilds(object):
    """Frames."""


    #----------------------------------------------------------------------
    @Decorator.requiere_open_files()
    @Decorator.requiere_graphical_mode()
    def __show_insert_block__(self):
        self.frame_insert_block = InsertBlock(self.PinguinoKIT)
        self.frame_insert_block.show()


    #----------------------------------------------------------------------
    def __show_about__(self):
        self.frame_about = About()
        self.frame_about.show()


    # #----------------------------------------------------------------------
    # def __show_libmanager__(self):
        # self.frame_stdout = LibManager(self)
        # self.frame_stdout.show()


    # #----------------------------------------------------------------------
    # def __config_paths__(self):
        # self.frame_paths = Paths(self)
        # self.frame_paths.show()


    #----------------------------------------------------------------------
    def __show_submit_bug__(self):

        self.submit_bug = SubmitBug(self)