Exemplo n.º 1
0
    def setUpPaneCtrls(self):
        m1 = self.vPaneWindow
        self.parseTree = treeExplorer.ApiTree(m1, self.xbmcThreads)
        self.parseTree.setOnTreeSelProc(self.onTreeSel)
        self.parseTree.setPopUpMenu(self.popUpMenu)
        self.explorerTree = treeExplorer.treeExplorer(m1, self.addonSettings,
                                                      self.fileGenerator)

        self.addonFilesViewer = addonFilesViewer(m1)
        self.addonFilesViewer.setHyperlinkManager(self.hyperLinkProcessor)
        self.explorerTree.setEditorWidget(self.addonFilesViewer)
        self.addonCtrlSett = addonSettCtrls.vertRadioMenu(master=m1)
        self.leftPnNames = ['parsetree', 'esplorertree']
        self.avLeftPanes = [
            self.parseTree, self.explorerTree, self.addonCtrlSett
        ]
        self.leftPaneVisible.set(True)
        self.regexpEd = RegexpFrame(m1, self.xbmcThreads, self.message)
        self.regexpEd.setDropDownFiler(self.comboBoxFiler)
        self.regexpEd.setPopUpMenu(self.popUpWebMenu)
        self.testFrame = ScrolledList(m1, self.coder)
        self.codeFrame = SintaxEditor.CodeEditor(m1, self.xbmcThreads,
                                                 self.coder)
        xbmcFileW = xmlFileWrapper.threadXmlFileWrapper(
            'NodeSettingFile.xml', self.xbmcThreads)
        self.NodeFrame = xmlFileWrapper.settingsDisplay(master=m1,
                                                        xmlFileW=xbmcFileW)
        self.NodeFrame.setNotifyChange(self.setSaveFlag)
        self.settingsPane = xmlFileWrapper.settingsDisplay(
            master=m1, xmlFileW=self.addonSettings)
        self.settingsPane.setNotifyChange(self.setSaveFlag)
        self.addonCtrlSett.setSettingsPane(self.settingsPane)
        self.kodiFrontEnd = KodiFrontEnd.KodiFrontEnd(
            m1, self.explorerTree.getAddonTemplate, self.fileGenerator)
        self.avRightPanes = [
            self.NodeFrame, self.testFrame, self.codeFrame, self.regexpEd,
            self.addonFilesViewer, self.settingsPane, self.kodiFrontEnd
        ]
        self.viewPanes = []
        self.viewPanes.append([('Design', 0, 0), ('Test', 0, 1),
                               ('Code', 0, 2), ('Regexp Editor', 0, 3)])
        self.viewPanes.append([('Settings', 2, 5), ('Test', 0, 6),
                               ('Addon Explorer', 1, 4)])
        self.actViewPane = len(self.viewPanes) * [0]
Exemplo n.º 2
0
    def setUpPaneCtrls(self):
        m1 = self.vPaneWindow
        self.parseTree = treeExplorer.ApiTree(m1, self.xbmcThreads)
        self.parseTree.setOnTreeSelProc(self.onTreeSel)
        self.parseTree.setPopUpMenu(self.popUpMenu)
        self.explorerTree = treeExplorer.treeExplorer(m1, self.addonSettings, self.fileGenerator)

        self.addonFilesViewer = addonFilesViewer(m1)
        self.addonFilesViewer.setHyperlinkManager(self.hyperLinkProcessor)
        self.explorerTree.setEditorWidget(self.addonFilesViewer)
        self.addonCtrlSett = addonSettCtrls.vertRadioMenu(master=m1)
        self.leftPnNames = ["parsetree", "esplorertree"]
        self.avLeftPanes = [self.parseTree, self.explorerTree, self.addonCtrlSett]
        self.leftPaneVisible.set(True)
        self.regexpEd = RegexpFrame(m1, self.xbmcThreads, self.message)
        self.regexpEd.setDropDownFiler(self.comboBoxFiler)
        self.regexpEd.setPopUpMenu(self.popUpWebMenu)
        self.testFrame = ScrolledList(m1, self.coder)
        self.codeFrame = SintaxEditor.CodeEditor(m1, self.xbmcThreads, self.coder)
        xbmcFileW = xmlFileWrapper.threadXmlFileWrapper("NodeSettingFile.xml", self.xbmcThreads)
        self.NodeFrame = xmlFileWrapper.settingsDisplay(master=m1, xmlFileW=xbmcFileW)
        self.NodeFrame.setNotifyChange(self.setSaveFlag)
        self.settingsPane = xmlFileWrapper.settingsDisplay(master=m1, xmlFileW=self.addonSettings)
        self.settingsPane.setNotifyChange(self.setSaveFlag)
        self.addonCtrlSett.setSettingsPane(self.settingsPane)
        self.kodiFrontEnd = KodiFrontEnd.KodiFrontEnd(m1, self.explorerTree.getAddonTemplate, self.fileGenerator)
        self.avRightPanes = [
            self.NodeFrame,
            self.testFrame,
            self.codeFrame,
            self.regexpEd,
            self.addonFilesViewer,
            self.settingsPane,
            self.kodiFrontEnd,
        ]
        self.viewPanes = []
        self.viewPanes.append([("Design", 0, 0), ("Test", 0, 1), ("Code", 0, 2), ("Regexp Editor", 0, 3)])
        self.viewPanes.append([("Settings", 2, 5), ("Test", 0, 6), ("Addon Explorer", 1, 4)])
        self.actViewPane = len(self.viewPanes) * [0]
Exemplo n.º 3
0
class XbmcAddonIDE(tk.Toplevel):
    PERSPECTIVES = ['Site API', 'Addon']

    def __init__(self, theGlobals=None):
        tk.Toplevel.__init__(self)
        self.protocol('WM_DELETE_WINDOW', self.Close)
        self.perspectiveIndx = tk.StringVar(value=self.PERSPECTIVES[0])
        self.activeViewIndx = tk.StringVar()
        self.activeViewIndx.trace("w", self.setActiveView)
        self.leftPaneIndx = tk.IntVar(value=-1)
        self.leftPaneVisible = tk.BooleanVar()
        self.leftPaneVisible.trace("w", self.setLeftPaneVisibility)
        self.rightPaneIndx = tk.IntVar(value=-1)
        #         self.rightPaneIndx.trace("w", self.setRightPane)
        self.xbmcThreads = menuThreads.menuThreads()
        self.addonSettings = xmlFileWrapper.xmlFileWrapper(
            'addonIdeSettingFile.xml')
        self.coder = addonCoder.Addoncoder(self.xbmcThreads,
                                           self.addonSettings)
        self.fileGenerator = FileGenerator.FileGenerator(
            self.addonSettings, self.xbmcThreads, self.coder)
        self.settings = {}
        self.setGUI()
        self.activeUrl.set('')
        self.newFile()
        self.currentFile = 'default.pck'
        self.title(self.currentFile)

    def initCoder(self, xbmcThreads, modSourceCode=None):
        addon_id = self.getAddonSettings('addon_id')
        self.coder = addonCoder.Addoncoder(xbmcThreads, addon_id)
        self.coder.modSourceCode = modSourceCode or {}

    def checkSaveFlag(self):
        fileName = self.title()
        if fileName.endswith('**'):
            fileName = os.path.basename(
                self.currentFile) if not self.currentFile else 'default.pck'
            ans = tkMessageBox.askyesno(
                'Warning',
                'Do you want to save the changes you made to ' + fileName)
            if ans: self.saveFile()
            else: self.setSaveFlag(False)

    def Close(self):
        self.checkSaveFlag()
        self.destroy()

    def setGUI(self):
        frame = tk.Frame(self)
        frame.pack(fill=tk.BOTH, expand=1)

        menuFrame = tk.Frame(frame)
        menuFrame.pack(side=tk.TOP, fill=tk.X)
        self.menuBar = {}
        menuOp = ['File', 'Get', 'Set', 'View', 'Knoth', 'Coding', 'Tools']
        for elem in menuOp:
            menubutton = tk.Menubutton(menuFrame, text=elem, name=elem.lower())
            menubutton.pack(side=tk.LEFT)
            self.menuBar[elem] = tk.Menu(menubutton, tearoff=False)

        topPane = tk.Frame(menuFrame)
        topPane.pack(side=tk.RIGHT)

        self.activeKnot = tk.StringVar()
        self.activeUrl = tk.StringVar()
        self.message = tk.StringVar()
        self.statusBar = StatusBar(frame, [('ActiveKnot: ', self.activeKnot),
                                           ('KnotData ', self.message),
                                           ('ActiveUrl: ', self.activeUrl)])
        self.statusBar.pack(side=tk.BOTTOM, fill=tk.X, expand=0)

        m1 = tk.PanedWindow(frame, sashrelief=tk.SUNKEN, bd=10)
        m1.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
        self.vPaneWindow = m1
        self.setUpPaneCtrls()

        label = tk.Label(topPane, text='Perspective: ', width=13)
        label.pack(side=tk.LEFT)
        fileChsr = ttk.Combobox(topPane,
                                textvariable=self.perspectiveIndx,
                                value=self.PERSPECTIVES,
                                name='combo')
        fileChsr.pack(side=tk.LEFT)
        cClass = fileChsr.__class__
        cClass.config(fileChsr, state='readonly', takefocus=0)

        label = tk.Label(topPane, text='View: ', width=13)
        label.pack(side=tk.LEFT)
        fileChsr = ttk.Combobox(topPane,
                                textvariable=self.activeViewIndx,
                                name='combo2')
        fileChsr.pack(side=tk.LEFT)
        cClass = fileChsr.__class__
        cClass.config(fileChsr, state='readonly', takefocus=0)

        self.topPane = topPane

        def setPerspectiveViews(*args, **kwargs):
            perspIndx = self.PERSPECTIVES.index(self.perspectiveIndx.get())
            views = [view[0] for view in self.viewPanes[perspIndx]]
            self.topPane.children['combo2'].config(value=views)
            actView = self.actViewPane[perspIndx]
            self.activeViewIndx.set(views[actView])

        setPerspectiveViews()
        self.perspectiveIndx.trace('w', setPerspectiveViews)

        self.menuBuilder()

        for elem in menuOp:
            menubutton = menuFrame.children[elem.lower()]
            menubutton.config(menu=self.menuBar[elem])

    def setUpPaneCtrls(self):
        m1 = self.vPaneWindow
        self.parseTree = treeExplorer.ApiTree(m1, self.xbmcThreads)
        self.parseTree.setOnTreeSelProc(self.onTreeSel)
        self.parseTree.setPopUpMenu(self.popUpMenu)
        self.explorerTree = treeExplorer.treeExplorer(m1, self.addonSettings,
                                                      self.fileGenerator)

        self.addonFilesViewer = addonFilesViewer(m1)
        self.addonFilesViewer.setHyperlinkManager(self.hyperLinkProcessor)
        self.explorerTree.setEditorWidget(self.addonFilesViewer)
        self.addonCtrlSett = addonSettCtrls.vertRadioMenu(master=m1)
        self.leftPnNames = ['parsetree', 'esplorertree']
        self.avLeftPanes = [
            self.parseTree, self.explorerTree, self.addonCtrlSett
        ]
        self.leftPaneVisible.set(True)
        self.regexpEd = RegexpFrame(m1, self.xbmcThreads, self.message)
        self.regexpEd.setDropDownFiler(self.comboBoxFiler)
        self.regexpEd.setPopUpMenu(self.popUpWebMenu)
        self.testFrame = ScrolledList(m1, self.coder)
        self.codeFrame = SintaxEditor.CodeEditor(m1, self.xbmcThreads,
                                                 self.coder)
        xbmcFileW = xmlFileWrapper.threadXmlFileWrapper(
            'NodeSettingFile.xml', self.xbmcThreads)
        self.NodeFrame = xmlFileWrapper.settingsDisplay(master=m1,
                                                        xmlFileW=xbmcFileW)
        self.NodeFrame.setNotifyChange(self.setSaveFlag)
        self.settingsPane = xmlFileWrapper.settingsDisplay(
            master=m1, xmlFileW=self.addonSettings)
        self.settingsPane.setNotifyChange(self.setSaveFlag)
        self.addonCtrlSett.setSettingsPane(self.settingsPane)
        self.kodiFrontEnd = KodiFrontEnd.KodiFrontEnd(
            m1, self.explorerTree.getAddonTemplate, self.fileGenerator)
        self.avRightPanes = [
            self.NodeFrame, self.testFrame, self.codeFrame, self.regexpEd,
            self.addonFilesViewer, self.settingsPane, self.kodiFrontEnd
        ]
        self.viewPanes = []
        self.viewPanes.append([('Design', 0, 0), ('Test', 0, 1),
                               ('Code', 0, 2), ('Regexp Editor', 0, 3)])
        self.viewPanes.append([('Settings', 2, 5), ('Test', 0, 6),
                               ('Addon Explorer', 1, 4)])
        self.actViewPane = len(self.viewPanes) * [0]

    def hyperLinkProcessor(self, texto):
        match = re.search(
            'File "(?P<filename>[^"]+)", line (?P<lineno>[0-9]+)', texto)
        if not match:
            tkMessageBox.showinfo('Hyperlink Not Process', texto)
        else:
            fileName = match.group('filename')
            lineNo = match.group('lineno')
            rootId = self.explorerTree.treeview.get_children()[0]
            baseDirectory = translatePath('special://home/addons/')
            if not fileName.startswith(baseDirectory):
                return tkMessageBox.showerror('Hyperlink Not in actual addon',
                                              texto)
            nodeId = fileName[len(baseDirectory):].replace('\\', '/')
            if not fileName.startswith(os.path.join(baseDirectory, rootId)):
                nodeId = rootId + '/Dependencies/' + fileName[
                    len(baseDirectory):].replace('\\', '/')
                if not self.explorerTree.treeview.exists(nodeId):
                    return tkMessageBox.showerror('Hyperlink Not Found', texto)
            self.explorerTree.treeview.set(nodeId,
                                           column='inspos',
                                           value=lineNo + '.0')
            self.explorerTree.onTreeSelection(nodeId)
            self.addonFilesViewer.focus_force()

    def setActiveView(self, *args, **kwargs):
        refreshFlag = kwargs.get('refreshFlag', False)
        perspIndx = self.PERSPECTIVES.index(self.perspectiveIndx.get())
        activeView = [view[0] for view in self.viewPanes[perspIndx]
                      ].index(self.activeViewIndx.get())
        self.actViewPane[perspIndx] = activeView
        viewName, vwLeftPane, vwRightPane = self.viewPanes[perspIndx][
            activeView]
        leftPaneIndx = self.leftPaneIndx.get()
        if leftPaneIndx != vwLeftPane:
            self.leftPaneIndx.set(vwLeftPane)
            self.setLeftPaneVisibility()
        if refreshFlag or leftPaneIndx != vwLeftPane:
            self.avLeftPanes[vwLeftPane].refreshPaneInfo()
        rightPaneIndx = self.rightPaneIndx.get()
        if rightPaneIndx != vwRightPane:
            self.rightPaneIndx.set(vwRightPane)
            self.setRightPane()
        if refreshFlag or rightPaneIndx != vwRightPane:
            self.avRightPanes[vwRightPane].initFrameExec()

    def setLeftPane(self, *args, **kwargs):
        viewTy = int(self.leftPaneIndx.get())
        panes = self.vPaneWindow.panes()
        pane2 = self.avLeftPanes[viewTy]
        if self.leftPaneVisible.get():
            if len(panes) > 1: self.vPaneWindow.forget(panes[1])
            self.vPaneWindow.add(pane2, after=panes[0])
        else:
            self.vPaneWindow.forget(panes[0])
            self.vPaneWindow.add(pane2)
#         if self.xbmcThreads.threadDef:self.initRightPane(param = False)

    def setRightPane(self, *args, **kwargs):
        viewTy = int(self.rightPaneIndx.get())
        panes = self.vPaneWindow.panes()
        pane2 = self.avRightPanes[viewTy]
        if self.leftPaneVisible.get():
            if len(panes) > 1: self.vPaneWindow.forget(panes[1])
            self.vPaneWindow.add(pane2, after=panes[0])
        else:
            self.vPaneWindow.forget(panes[0])
            self.vPaneWindow.add(pane2)


#         if self.xbmcThreads:self.initRightPane(param = False)

    def setLeftPaneVisibility(self, *args, **kwargs):
        nPane = self.leftPaneIndx.get()
        isVisible = self.leftPaneVisible.get()
        panes = self.vPaneWindow.panes()
        if not isVisible and len(panes) > 1:
            self.vPaneWindow.forget(panes[0])
        elif isVisible:
            pane2 = self.avLeftPanes[nPane]
            if len(panes) == 2:
                self.vPaneWindow.forget(panes[0])
                self.vPaneWindow.add(pane2, before=panes[1])
            elif len(panes) == 1:
                self.vPaneWindow.add(pane2, before=panes[0])
            elif len(panes) == 0:
                self.vPaneWindow.add(pane2)

    def dummyCommand(self):
        tkMessageBox.showerror('Not implemented', 'Not yet available')

    def menuBuilder(self):

        self.menuBar['popup'] = tk.Menu(self, tearoff=False)

        menuOpt = []
        menuOpt.append(('cascade', 'Insert New', 0))
        menuOpt.append(('separator', ))
        menuOpt.append(('command', 'Set Regexp', 'Ctrl+G', 0, self.setRegexp))
        menuOpt.append(
            ('command', 'Set NextRegexp', 'Ctrl+N', 0, self.setNextRegexp))
        menuOpt.append(('separator', ))
        menuOpt.append(('command', 'Rename', 'Ctrl+R', 0, self.renameKnot))
        menuOpt.append(('command', 'Delete', 'Ctrl+D', 0, self.deleteKnot))
        menuOpt.append(('separator', ))
        menuOpt.append(('command', 'Transform in a menu node', 'Ctrl+N', 0,
                        self.makeMenuNode))
        menuOpt.append(('separator', ))
        menuOpt.append(('command', 'Edit', 'Ctrl+E', 0, self.editKnot))
        self.makeMenu('popup', menuOpt)

        menuOpt = []
        menuOpt.append(('command', 'Source', 'Ctrl+B', 0, self.newSendOutput))
        menuOpt.append(
            ('command', 'Output', 'Ctrl+A', 0, self.newReceiveInput))
        menuOpt.append(('command', 'Link', 'Ctrl+A', 0, self.newLink))
        self.makeMenu('popup.Insert_New', menuOpt)

        self.menuBar['webpopup'] = tk.Menu(self, tearoff=False)

        menuOpt = []
        menuOpt.append(('command', 'Cut', '', 2, self.dummyCommand))
        menuOpt.append(('command', 'Copy', '', 0, self.dummyCommand))
        menuOpt.append(('command', 'Paste', '', 0, self.dummyCommand))
        menuOpt.append(('separator', ))
        menuOpt.append(('command', 'Send UserForm', '', 0, self.dummyCommand))
        menuOpt.append(('separator', ))
        menuOpt.append(
            ('command', 'Encrypt Rijndael', '', 0, self.dummyCommand))
        menuOpt.append(
            ('command', 'Decrypt Rijndael', '', 0, self.dummyCommand))
        menuOpt.append(('separator', ))
        menuOpt.append(
            ('command', 'Unwise process', '', 0, self.unwiseProcess))
        menuOpt.append(
            ('command', 'Unwise variable', '', 0, self.dummyCommand))
        menuOpt.append(('separator', ))
        menuOpt.append(('command', 'Detect packer', '', 0, self.detectPacker))
        menuOpt.append(('command', 'Unpack', '', 0, self.unPack))
        self.makeMenu('webpopup', menuOpt)

        menuOpt = []
        menuOpt.append(('command', 'New', 'Ctrl+O', 0, self.newFile))
        menuOpt.append(('command', 'Open', 'Ctrl+O', 0, self.__openFile))
        menuOpt.append(('command', 'Save', 'Ctrl+S', 0, self.saveFile))
        menuOpt.append(('command', 'Save as', 'Ctrl+S', 0, self.saveAsFile))
        menuOpt.append(('separator', ))
        menuOpt.append(
            ('command', 'Export to XBMC', 'Ctrl+x', 0, self.onXbmcExport))
        menuOpt.append(
            ('command', 'MakeZip File', 'Ctrl+M', 0, self.onMakeZipFile))
        menuOpt.append(('separator', ))
        menuOpt.append(('command', 'Close', 'Alt+Q', 0, self.Close))
        self.makeMenu('File', menuOpt)

        menuOpt = []
        menuOpt.append(('command', 'File', 'Ctrl+F', 0, self.importFile))
        menuOpt.append(('command', 'Url', 'Ctrl+U', 0, self.importUrl))
        menuOpt.append(('command', 'Clipboard', 'Ctrl+L', 0,
                        self.regexpEd.pasteFromClipboard))
        menuOpt.append(
            ('command', 'Selected Url', 'Ctrl+S', 0, self.selectedURL))
        menuOpt.append(
            ('command', 'Selected Form', 'Ctrl+F', 0, self.selectedForm))
        self.makeMenu('Get', menuOpt)

        menuOpt = []
        menuOpt.append(('command', 'Set Url', 'Ctrl+U', 0, self.setUrl))
        menuOpt.append(('command', 'Set Regexp', 'Ctrl+R', 0, self.setRegexp))
        menuOpt.append(
            ('command', 'Set Header Regexp', 'Ctrl+N', 0,
             lambda param='headregexp': self.setActNodeParam(param)))
        menuOpt.append(
            ('command', 'Set NextRegexp', 'Ctrl+N', 0,
             lambda param='nextregexp': self.setActNodeParam(param)))
        menuOpt.append(('separator', ))
        menuOpt.append(('command', 'Edit', 'Ctrl+E', 0, self.editKnot))
        self.makeMenu('Set', menuOpt)

        menuOpt = []
        menuOpt.append(('command', 'New', 'Ctrl+S', 0, self.newParseKnot))
        menuOpt.append(
            ('command', 'Set ActiveKnoth', 'Ctrl+A', 0, self.setActiveKnot))
        self.makeMenu('Knoth', menuOpt)

        menuOpt = []
        menuOpt.append(
            ('checkbutton', 'ParseTree', self.leftPaneVisible, [False, True]))
        menuOpt.append(('separator', ))
        menuOpt.append(
            ('radiobutton', self.perspectiveIndx, self.PERSPECTIVES))
        menuOpt.append(('separator', ))
        perspIndx = 0
        menuOpt.append(('radiobutton', self.activeViewIndx,
                        [view[0] for view in self.viewPanes[perspIndx]]))
        self.makeMenu('View', menuOpt)

        def miLambda():
            frstIndx, lstIndx = 5, tk.END
            self.menuBar['View'].delete(frstIndx, lstIndx)
            perspIndx = self.PERSPECTIVES.index(self.perspectiveIndx.get())
            for k, view in enumerate(self.viewPanes[perspIndx]):
                self.menuBar['View'].add_radiobutton(
                    label=view[0], variable=self.activeViewIndx, value=k)

        self.menuBar['View'].config(postcommand=miLambda)

        menuOpt = []
        menuOpt.append(('command', 'Addon', 'Ctrl+E', 0,
                        lambda key='2': self.codeAddon(key)))
        menuOpt.append(
            ('command', 'DownThread', 'Ctrl+D', 0, self.codeDownThread))
        menuOpt.append(
            ('command', 'ActiveKnot', 'Ctrl+R', 0, self.codeActiveKnot))
        menuOpt.append(('command', 'SaveCode', 'Ctrl+o', 0, self.saveCode))
        self.makeMenu('Coding', menuOpt)

        menuOpt = []
        menuOpt.append(
            ('command', 'HTML struct', 'Ctrl+R', 0, self.HTMLstruct))
        menuOpt.append(('command', 'Forms', 'Ctrl+F', 0, self.formsDetector))
        menuOpt.append(('separator', ))
        menuOpt.append(
            ('command', 'Detach Window', 'Ctrl+R', 0, self.detachWindow))
        menuOpt.append(('separator', ))
        menuOpt.append(
            ('command', 'Setting', 'Ctrl+S', 0, self.programSettingDialog))
        self.makeMenu('Tools', menuOpt)

    def formsDetector(self):
        baseUrl = self.regexpEd.getActiveUrl()
        content = self.regexpEd.getContent()
        form_xml = formDetector.getFormXmlStr(content)
        if 'category' not in form_xml:
            return tkMessageBox.showinfo('Form Detector',
                                         'No forms in url content')
        browser = AppSettingDialog(self,
                                   form_xml,
                                   isFile=False,
                                   settings={},
                                   title='Form Detector',
                                   dheight=600,
                                   dwidth=400)
        if browser.allSettings:
            formAttr = dict([(key[3:], value)
                             for key, value in browser.allSettings
                             if key.startswith('fa_')])
            formFields = browser.allSettings[len(formAttr):]
            # filterFunc = lambda x: (x[0].startswith('if_') and x[1]) or (not x[0].startswith('if_') and x[1] is not 0)
            filterFunc = lambda x: x[1] is not 0
            formFields = filter(filterFunc, formFields)
            trnValueFnc = lambda x: (x[
                0], formDetector.unescapeXml(x[1].partition('|')[
                    0])) if isinstance(x[1], basestring) else (x[0], 'on')
            formFields = map(trnValueFnc, formFields)
            trnKeyFnc = lambda x: (x[0][3:], '@' + x[1]) if x[0].startswith(
                'if_') else x
            formFields = map(trnKeyFnc, formFields)
            # formFields = [(key, trnFnc(value)) for key, value in browser.allSettings if not (key.startswith('fa_') or value == 0)]
            refererOpt = '-e ' + '"' + baseUrl + '"'
            curlCommand = formDetector.getCurlCommand(baseUrl, formAttr,
                                                      formFields, refererOpt)
            print curlCommand
            self.regexpEd.setActiveUrl(curlCommand)

    def HTMLstruct(self):
        tagSpan = self.regexpEd.getSelRange('actMatch')
        content = self.regexpEd.getContent(*tagSpan)
        try:
            htmlParse = CustomRegEx.ExtRegexParser({},
                                                   []).htmlStruct(content, 0)
        except:
            equis = 'Not HTML conform'
            tkMessageBox.showinfo('Actual match HTMLstruct', equis)
        else:
            fmt = '{:<20} {:<40}'.format
            #             equis = '\n'.join([fmt(x[0].count('.')*'  ' + '*' + x[0].rpartition('.')[2],x[1][:40]) for x in htmlParse])
            equis = [
                fmt(x[0].count('.') * '  ' + '*' + x[0].rpartition('.')[2],
                    x[1][:40]) for x in htmlParse
            ]
            from xbmcgui import Dialog
            k = Dialog().select('Actual match HTMLstruct', equis)

    def detachWindow(self):
        actWin = self.activeViewIndx.get()
        wname, lwpane, rwpane = self.viewPanes[actWin]

    def detectPacker(self):
        content = self.regexpEd.getContent()
        from jsunpack import detect
        result = detect(content)
        if result:
            tkMessageBox.showinfo('Pack content', 'The content is packed')
        else:
            tkMessageBox.showerror('Pack content', 'The content is packed')

    def unPack(self):
        content = self.regexpEd.getContent()
        from jsunpack import unpack
        content = unpack(content)
        self.regexpEd.setContent(content, newUrl=False)

    def unwiseProcess(self):
        content = self.regexpEd.getContent()
        from unwise import unwise_process
        content = unwise_process(content)
        self.regexpEd.setContent(content, newUrl=False)

    def onMakeZipFile(self):
        D = os.path.normpath(self.getAddonSettings(srchSett='script_export'))
        zipFileName = tkFileDialog.asksaveasfilename(
            title='Zip File to create',
            initialdir=D,
            defaultextension='.zip',
            filetypes=[('Zip Files', '*.zip'), ('All Files', '*.*')])
        if zipFileName:
            self.onXbmcExport(zipFileName)
            # Este procedimiento se hce necesario para asegurar que en el android el archivo zip no tenga problemas
            with open(zipFileName, 'r+b') as f:
                data = f.read()
                pos = data.find(
                    '\x50\x4b\x05\x06')  # End of central directory signature
                if (pos > 0):
                    f.seek(pos +
                           22)  # size of 'ZIP end of central directory record'
                    f.truncate()

    def getAddonSettings(self, srchSett=None):
        return self.addonSettings.getParam(srchSett)

    def onXbmcExport(self, name=None):
        errMsg = ''
        if name:
            zipFile = zipfile.ZipFile(name, 'w')
            copySrcFile = zipFile.write
            genFileFromStr = zipFile.writestr
        else:
            baseDirectory = translatePath('special://home/addons')
            copySrcFile = shutil.copyfile

        addonFiles = self.listAddonFiles(name)
        for elem in addonFiles:
            dstFile, mode, srcFile = elem
            if not name:
                dstFile = translatePath('special://home/addons/' + dstFile)
                dstDirectory = os.path.split(dstFile)[0]
                if not os.path.exists(dstDirectory): os.makedirs(dstDirectory)
            try:
                if mode == 'f':
                    copySrcFile(srcFile, dstFile)
                elif mode == 's':
                    srcFile = self.fileGenerator.getSource(srcFile)
                    if name:
                        genFileFromStr(dstFile, srcFile)
                    else:
                        with open(dstFile, 'w') as wfile:
                            wfile.write(srcFile)
            except:
                errFile = dstFile.rpartition('\\')[2]
                errMsg += errFile + '\n'
        if name: zipFile.close()
        addonId = self.getAddonSettings('addon_id')
        addonName = self.getAddonSettings('addon_name')
        if errMsg:
            errMsg = 'During addon creation for ' + addonName + ' (' + addonId + ') , the following source files were not found: \n' + errMsg
            tkMessageBox.showerror('Addon creation', errMsg)
        else:
            errMsg = 'Addon for ' + addonName + ' (' + addonId + ') succesfully created'
            tkMessageBox.showinfo('Addon creation', errMsg)

    def listAddonFiles(self, name=None):
        fileList = self.explorerTree.getAddonTemplate()[1:]
        fileList = [(filePath, fileAttr['type'], fileAttr['source'])
                    for filePath, fileAttr in fileList
                    if 'Dependencies' not in filePath]
        addonListFiles = []
        for filePath, itype, source in fileList:
            itype = {'file': 'f', 'genfile': 's'}[itype]
            if type == 's': source = self.fileGenerator.getSource(source)
            addonListFiles.append((filePath, itype, source))
        return addonListFiles

    def programSettingDialog(self):
        settingObj = AppSettingDialog(self,
                                      'ideProgramSettings.xml',
                                      settings=self.settings,
                                      title='Test Window Case')
        self.settings = settingObj.result
        if settingObj.applySelected: self.setSaveFlag(True)

    def codeAddon(self, key):
        if self.rightPaneIndx.get() != key: return self.rightPaneIndx.set(key)
        execObj = self.xbmcThreads if key in ['0', '3'] else self.coder
        self.avRightPanes[int(key)].initFrameExec(execObj, param=True)

    def codeDownThread(self):
        if self.rightPaneIndx.get() != '2': return self.rightPaneIndx.set('2')
        threadId = self.xbmcThreads.threadDef
        self.codeFrame.setContentToNodeCode(threadId, incDownThread=True)

    def saveCode(self):
        viewTy = int(self.rightPaneIndx.get())
        rPane = self.avRightPanes[viewTy]
        if isinstance(rPane, SintaxEditor.CodeEditor):
            widget = self.codeFrame
            partialMod = True
        elif isinstance(rPane, addonFilesViewer):
            widget = self.addonFilesViewer.sintaxEditor
            partialMod = False
        else:
            return
        modSource, contType, fileId = widget.getContent()
        if contType == 'genfile':
            self.fileGenerator.setSource(fileId, modSource, partialMod)
            if not partialMod:
                modSource = self.fileGenerator.getSource(fileId)
                widget.setContent((modSource, contType, fileId), '1.0')
            else:
                match = re.search('\W*<([^>]+)>\W*', modSource)
                if match:
                    nodeId = match.group(1)
                    if nodeId == self.xbmcThreads.threadDef and nodeId in self.coder.modSourceCode:
                        self.coder.modSourceCode.pop(nodeId)
                        self.xbmcThreads.unlockThread(nodeId)
                self.codeFrame.initFrameExec()
            self.setSaveFlag(True)
        if contType == 'file':
            if os.path.splitext(fileId)[1] in ['.py', '.txt', '.xml']:
                with open(fileId, 'w') as f:
                    f.write(modSource)

    def codeActiveKnot(self):
        if self.rightPaneIndx.get() != '2': return self.rightPaneIndx.set('2')
        threadId = self.xbmcThreads.threadDef
        self.codeFrame.setContentToNodeCode(threadId)

    def makeMenu(self, masterID, menuArrDesc):
        master = self.menuBar[masterID]
        for menuDesc in menuArrDesc:
            menuType = menuDesc[0]
            if menuType == 'command':
                menuType, mLabel, mAccelKey, mUnderline, mCommand = menuDesc
                master.add(menuType,
                           label='{:30s}'.format(mLabel),
                           accelerator=mAccelKey,
                           underline=mUnderline,
                           command=mCommand)
            elif menuType == 'cascade':
                menuType, mLabel, mUnderline = menuDesc
                menuLabel = masterID + '.' + mLabel.replace(' ', '_')
                self.menuBar[menuLabel] = tk.Menu(master, tearoff=False)
                master.add('cascade',
                           label='{:30s}'.format(mLabel),
                           underline=mUnderline,
                           menu=self.menuBar[menuLabel])
            elif menuType == 'radiobutton':
                menuType, radioVar, radioOps = menuDesc
                for k, elem in enumerate(radioOps):
                    master.add_radiobutton(label=elem,
                                           variable=radioVar,
                                           value=k)
            elif menuType == 'checkbutton':
                menuType, checkLabel, checkVar, checkVals = menuDesc
                master.add_checkbutton(label=checkLabel,
                                       variable=checkVar,
                                       onvalue=checkVals[1],
                                       offvalue=checkVals[0])
            else:
                master.add('separator')

    def makeMenuNode(self):
        knotId = self.getActiveKnot()
        if self.xbmcThreads.isthreadLocked(knotId):
            return tkMessageBox.showerror('Access Error',
                                          knotId + ' is a Code locked Node')
        parseKnotId = tkSimpleDialog.askstring('Create Menu Node',
                                               'Menu ID to create:')
        if not parseKnotId: return
        lstChanged = []
        self.xbmcThreads.createThread('list', parseKnotId, parseKnotId)
        menuThread = self.xbmcThreads.threadDef
        url = self.xbmcThreads.getThreadParam(menuThread, 'url')
        regexp = self.xbmcThreads.getThreadParam(menuThread, 'regexp')
        compflags = eval(
            self.xbmcThreads.getThreadParam(menuThread, 'compflags'))
        submenus = self.testFrame.parseUrlContent(url, regexp, compflags)
        for k, elem in enumerate(submenus):
            menuName = elem['label']
            menuId = 'opc{:0>2d}_{:}'.format(k, menuThread.replace(' ', '_'))
            self.xbmcThreads.createThread('list', menuName, menuId)
            self.xbmcThreads.setNextThread(parseKnotId, menuId)
            self.xbmcThreads.setThreadParams(menuId, {'option': k})
            self.xbmcThreads.setNextThread(menuId, menuThread)
            lstChanged.append(menuThread + '_' + menuId + '_' + 'lnk')
        lstChanged = map(self.xbmcThreads.getDotPath, lstChanged)
        self.parseTree.refreshTreeInfo(parseKnotId, lstChanged=lstChanged)
        if lstChanged: self.setSaveFlag(True)

    def editKnot(self):
        knotId = self.getActiveKnot()
        if not knotId: return -1
        if self.xbmcThreads.isthreadLocked(knotId):
            return tkMessageBox.showerror('Access Error',
                                          knotId + ' is a Code locked Node')
        editDlg = EditTransaction(self, self.xbmcThreads)
        self.parseTree.refreshTreeInfo(lstChanged=editDlg.result)
        if editDlg.result: self.setSaveFlag(True)

    def getActiveKnot(self):
        return self.xbmcThreads.threadDef

    def initRightPane(self, param=False):
        viewTy = int(self.rightPaneIndx.get())
        #         execObj = self.xbmcThreads if viewTy in [0,3] else self.coder
        self.avRightPanes[viewTy].initFrameExec()

    def setActiveKnot(self, activeKnotId=None):
        if not activeKnotId:
            activeKnotId = tkSimpleDialog.askstring(
                'Set ActiveKnot', 'Enter the new ActiveKnot:')
        if activeKnotId:
            if self.xbmcThreads.getThreadAttr(
                    activeKnotId,
                    'name') != -1 and self.getActiveKnot() != activeKnotId:
                self.xbmcThreads.threadDef = activeKnotId
                self.initRightPane(param=False)
                self.parseTree.setSelection(activeKnotId, absFlag=False)

    def onTreeSel(self, node=None):
        treeview = self.parseTree.treeview
        iid = treeview.focus()
        parent, sep, threadId = iid.rpartition('.')
        self.setActiveKnot(threadId)

    def comboBoxFilerOLD(self):
        nodeLst = [
            elem for elem in self.xbmcThreads.getSameTypeNodes('media')
            if not elem.endswith('_lnk')
        ]
        getRegEx = self.xbmcThreads.getThreadParam
        lista = [
            '(?#<rexp-' + node + '>)' + getRegEx(node, 'regexp')
            for node in nodeLst
        ]
        lista.extend([
            '(?#<rnxt-' + node + '>)' + getRegEx(node, 'nextregexp')
            for node in nodeLst if getRegEx(node, 'nextregexp')
        ])
        headLst = lambda node: [
            elem.split('<->')
            for elem in getRegEx(node, 'headregexp').split('<=>')
        ]
        for node in nodeLst:
            if not getRegEx(node, 'headregexp'): continue
            lista.extend([
                '(?#<rhead-' + node + '-' + label + '>)' + regexp
                for label, regexp in headLst(node)
            ])
        return sorted(lista)

    def comboBoxFiler(self):
        nodeLst = [
            elem for elem in self.xbmcThreads.getSameTypeNodes('media')
            if not elem.endswith('_lnk')
        ]
        getRegEx = self.xbmcThreads.getThreadParam
        getParent = lambda x: '(?#<rexp-' + self.xbmcThreads.getParent(
            x) + '>)' if self.xbmcThreads.getParent(x) else None
        lista = [[
            '(?#<rexp-' + node + '>)',
            getRegEx(node, 'regexp'),
            getParent(node)
        ] for node in nodeLst]
        lista.extend([[
            '(?#<rnxt-' + node + '>)',
            getRegEx(node, 'nextregexp'), '(?#<rexp-' + node + '>)'
        ] for node in nodeLst if getRegEx(node, 'nextregexp')])
        headLst = lambda node: [
            elem.split('<->')
            for elem in getRegEx(node, 'headregexp').split('<=>')
        ]
        for node in nodeLst:
            if not getRegEx(node, 'headregexp'): continue
            lista.extend(
                [['(?#<rhead-' + node + '-' + label + '>)', regexp, None]
                 for label, regexp in headLst(node)])
        return sorted(lista)

    def popUpMenu(self):
        popUpMenu = self.menuBar['popup']
        treeview = self.parseTree.treeview
        iid = treeview.focus()
        menuState = tk.DISABLED if iid == 'media' else tk.NORMAL
        self.menuBar['popup.Insert_New'].entryconfigure(1, state=menuState)
        return popUpMenu

    def popUpWebMenu(self):
        return self.menuBar['webpopup']

    def setKnotParam(self, paramStr, paramValue):
        if not self.getActiveKnot(): return -1
        knotId = self.getActiveKnot()
        if self.xbmcThreads.isthreadLocked(knotId):
            return tkMessageBox.showerror('Access Error',
                                          knotId + ' is a Code locked Node')
        params = self.xbmcThreads.getThreadAttr(knotId, 'params')
        params[paramStr] = paramValue
        self.setSaveFlag(True)

    def setActNodeParam(self, param):
        if param == 'url':
            self.setKnotParam('url', self.regexpEd.getActiveUrl())
        elif param == 'nextregexp':
            self.setKnotParam('nextregexp', self.regexpEd.getRegexpPattern())
            self.regexpEd.regexpFrame.cbIndex.set('(?#<rnxt-' +
                                                  self.getActiveKnot() + '>)')
        elif param == 'headregexp':
            knotId = self.getActiveKnot()
            headRegExp = self.xbmcThreads.getThreadParam(knotId,
                                                         'headregexp') or ''
            headRegExp += (
                '<=>' if headRegExp else
                '') + 'headervar<->' + self.regexpEd.getRegexpPattern()
            self.setKnotParam('headregexp', headRegExp)
            self.regexpEd.regexpFrame.cbIndex.set('(?#<rhead-' +
                                                  self.getActiveKnot() + '>)')

    def setUrl(self):
        self.setKnotParam('url', self.regexpEd.getActiveUrl())

    def setNextRegexp(self):
        self.setKnotParam('nextregexp', self.regexpEd.getRegexpPattern())

    def setRegexp(self):
        exitFlag = self.setKnotParam('regexp',
                                     self.regexpEd.getRegexpPattern())
        if exitFlag == 'ok': return
        self.setKnotParam('compflags', self.regexpEd.getCompFlags())
        self.regexpEd.regexpFrame.cbIndex.set('(?#<rexp-' +
                                              self.getActiveKnot() + '>)')

    def newSendOutput(self):
        refKnot = self.xbmcThreads.threadDef
        self.newParseKnot(refKnot, outputToRefKnoth=True)

    def newLink(self):
        parseKnotId = tkSimpleDialog.askstring('Create Link',
                                               'ParseKnot ID to link:')
        if parseKnotId:
            self.xbmcThreads.setLinkTie(self.xbmcThreads.threadDef,
                                        parseKnotId)
            lnkNode = parseKnotId + '_' + self.xbmcThreads.threadDef + '_lnk'
            lstChanged = [self.xbmcThreads.getDotPath(lnkNode)]
            self.parseTree.refreshTreeInfo(self.xbmcThreads.threadDef,
                                           lstChanged=lstChanged)
            if lstChanged: self.setSaveFlag(True)

    def newReceiveInput(self):
        refKnot = self.xbmcThreads.threadDef
        self.newParseKnot(refKnot, outputToRefKnoth=False)

    def deleteKnot(self, threadId=None):
        if not threadId: threadId = self.xbmcThreads.threadDef
        lstChanged = [self.xbmcThreads.getDotPath(threadId)]
        if self.xbmcThreads.getThreadAttr(threadId, 'type') == 'thread':
            for lnkId in self.xbmcThreads.getLinks(threadId):
                toNode = self.xbmcThreads.getThreadAttr(lnkId, 'name')
                if self.xbmcThreads.getThreadAttr(toNode, 'type') == 'thread':
                    continue
                lnkRev = self.xbmcThreads.getLinkId(threadId, toNode)
                lstChanged.append(self.xbmcThreads.getDotPath(lnkRev))
        lista = [
            elem for elem in self.xbmcThreads.getSameTypeNodes(threadId)
            if not elem.endswith('_lnk')
        ]
        self.xbmcThreads.deleteNode(threadId)
        self.parseTree.refreshTreeInfo(lstChanged=lstChanged)
        self.coder.modifyCode('delete', *lista)
        if lstChanged: self.setSaveFlag(True)

    def renameKnot(self, threadId=None):
        if not threadId: threadId = self.xbmcThreads.threadDef
        if self.xbmcThreads.isthreadLocked(threadId):
            return tkMessageBox.showerror('Access Error',
                                          threadId + ' is a Code locked Node')
        newKnotId = tkSimpleDialog.askstring('Create new ParseKnotID',
                                             'New ParseKnot ID to rename:')
        lstChanged = [self.xbmcThreads.getDotPath(threadId)]
        self.xbmcThreads.rename(threadId, newKnotId)
        lstChanged.append(self.xbmcThreads.getDotPath(newKnotId))
        self.parseTree.refreshTreeInfo(lstChanged=lstChanged)
        self.coder.modifyCode('rename', threadId, newKnotId)
        if lstChanged: self.setSaveFlag(True)

    def newParseKnot(self, refKnot=None, outputToRefKnoth=True):
        parseKnotId = tkSimpleDialog.askstring('Create ParseKnot',
                                               'ParseKnot ID to create:')
        if not parseKnotId: return
        activeKnoth = self.xbmcThreads.threadDef
        knothType = self.xbmcThreads.getThreadAttr(activeKnoth, 'type')
        if self.xbmcThreads.createThread(iType=knothType,
                                         name=parseKnotId,
                                         menuId=parseKnotId) == -1:
            return
        if refKnot == None:
            refKnot = 'media' if knothType == 'thread' else 'rootmenu'
        lstChangedFlag = refKnot not in ['media', 'rootmenu']

        lstChanged = [] if lstChangedFlag else [
            self.xbmcThreads.getDotPath(parseKnotId)
        ]
        self.xbmcThreads.threadDef = parseKnotId
        if knothType == 'list':
            if refKnot != 'rootmenu':
                if outputToRefKnoth:
                    lstChanged.append(self.xbmcThreads.getDotPath(activeKnoth))
                    if self.xbmcThreads.getThreadAttr(refKnot,
                                                      'up') != 'rootmenu':
                        refKnotUp = self.xbmcThreads.getThreadAttr(
                            refKnot, 'up')
                        self.xbmcThreads.setNextThread(refKnotUp, parseKnotId)
                    self.xbmcThreads.setNextThread(parseKnotId, refKnot)
                    refKnot = parseKnotId
                else:
                    self.xbmcThreads.setNextThread(refKnot, parseKnotId)
                    activeKnoth = parseKnotId
        elif knothType == 'thread':
            self.setKnotParam('url', self.regexpEd.getActiveUrl())
            self.setRegexp()
            if refKnot != 'media':
                if outputToRefKnoth:
                    self.xbmcThreads.setNextThread(parseKnotId, refKnot)
                    activeKnoth = parseKnotId
                else:
                    lstChanged.append(self.xbmcThreads.getDotPath(activeKnoth))
                    if self.xbmcThreads.getThreadAttr(refKnot,
                                                      'up') != 'media':
                        refKnotUp = self.xbmcThreads.getThreadAttr(
                            refKnot, 'up')
                        self.xbmcThreads.setNextThread(parseKnotId, refKnotUp)
                    self.xbmcThreads.setNextThread(refKnot, parseKnotId)
                    refKnot = parseKnotId
        if lstChangedFlag:
            lstChanged.append(self.xbmcThreads.getDotPath(activeKnoth))
        self.parseTree.refreshTreeInfo(parseKnotId, lstChanged=lstChanged)
        self.setSaveFlag(True)

    def setSaveFlag(self, state, lstChanged=None):
        suffix = '  **' if state else ''
        fileName = (self.currentFile
                    if self.currentFile else 'default.pck') + suffix
        self.title(fileName)
        if lstChanged:
            self.parseTree.refreshTreeInfo(lstChanged=lstChanged)

    def importFile(self):
        name = tkFileDialog.askopenfilename(
            filetypes=[('xml Files', '*.xml'), ('Text Files',
                                                '*.txt'), ('All Files',
                                                           '*.*')])
        if name:
            name = 'file:///' + name
            self.importUrl(name)

    def importUrl(self, urlToOpen=None, initialValue=None):
        if not urlToOpen:
            urlToOpen = tkSimpleDialog.askstring('Open URL',
                                                 'URL addres to parse:',
                                                 initialvalue=initialValue
                                                 or '')
        if urlToOpen:
            self.regexpEd.setActiveUrl(urlToOpen)

    def selectedURL(self):
        selRange = self.regexpEd.getSelRange()
        selUrl = self.regexpEd.getContent(*selRange)
        self.importUrl(selUrl)

    def selectedForm(self):
        selForm = self.regexpEd.getContent('1.0', 'end')
        if not (selForm[:5].lower() == '<form'
                and selForm[-8:-1].lower() == '</form>'):
            return tkMessageBox.showerror(
                'Not Form', 'Zoom In to a <form.+?</form> pattern')
        selForm = '<form' + selForm[5:-8] + '</form>'
        activeUrl = self.regexpEd.getActiveUrl()
        formAttr = re.search('<form\s*([^>]+)>', selForm).group(1)
        formAttr = eval("dict(" + ",".join(formAttr.split()) + ")")
        method = '?' if formAttr.get("method", 'GET') == 'GET' else '<post>'
        formUrl = formAttr.get('action', '') or activeUrl

        forInVars = re.findall(r'<input\s*(.+?)[/>]', selForm,
                               re.IGNORECASE | re.DOTALL)
        urlVars = {}
        for inVar in forInVars:
            inVar = inVar.replace('class=', '_class=')
            inAttr = eval("dict(" + ",".join(inVar.split()) + ")")
            key = inAttr.get('name', None) or inAttr.get('id', None)
            if key: urlVars[key] = inAttr.get('value', '')
        methodData = urllib.urlencode(urlVars)
        selUrl = formUrl + method + methodData
        self.importUrl(initialValue=selUrl)

    def newFile(self,
                fileName='',
                threadData=None,
                modSourceCode=None,
                settings=None):
        self.checkSaveFlag()
        self.currentFile = fileName or 'default.pck'
        self.title(self.currentFile)
        threadData = threadData or self.initThreadData()
        self.xbmcThreads.setThreadData(*threadData)
        addonSettings = settings or {}
        if addonSettings.has_key('reset'): addonSettings.pop('reset')
        self.addonSettings.setNonDefaultParams(addonSettings)

        self.coder.modSourceCode = modSourceCode or {}
        self.parseTree.setXbmcThread(self.xbmcThreads)

        self.explorerTree.refreshFlag = True
        self.setActiveView(refreshFlag=True)

    def saveFile(self):
        nameFile = self.currentFile
        self.saveAsFile(nameFile)

    def saveAsFile(self, nameFile=None):
        if not nameFile:
            name = tkFileDialog.asksaveasfilename(title='File Name to save',
                                                  defaultextension='.pck',
                                                  filetypes=[
                                                      ('pck Files', '*.pck'),
                                                      ('All Files', '*.*')
                                                  ])
            if not name: return
        else:
            name = nameFile
        try:
            with open(name, 'wb') as f:
                for objeto in [
                        self.xbmcThreads.getThreadData(),
                        self.addonSettings.getNonDefaultParams(),
                        self.coder.modSourceCode
                ]:
                    objStr = json.dumps(objeto)
                    f.write(objStr + '\n')

        except:
            tkMessageBox.showerror('Error',
                                   'An error was found saving the file')
        else:
            self.currentFile = name if name.endswith('.pck') else name + '.pck'
            self.setSaveFlag(False)

    def __openFile(self):
        self.checkSaveFlag()
        name = tkFileDialog.askopenfilename(
            filetypes=[('pck Files', '*.pck'), ('All Files', '*.*')])
        if name:
            try:
                with open(name, 'rb') as f:
                    kodiThreadData = json.loads(f.readline())
                    settings = json.loads(f.readline())
                    modifiedCode = json.loads(f.readline())
            except IOError:
                tkMessageBox.showerror('Not a valid File',
                                       'File not pck compliant ')
                return
            except ValueError:
                tkMessageBox.showerror(
                    'Not a valid File',
                    'An error has ocurred while reding the file ')
                return
            self.newFile(fileName=name,
                         threadData=kodiThreadData,
                         modSourceCode=modifiedCode,
                         settings=settings)

    def initThreadData(self):
        xbmcMenu = menuThreads.menuThreads()
        params = {
            'url': 'https://www.youtube.com/watch?v=Vw8ViaL7-m4',
            'regexp':
            'onclick="location.href=\'(?P<videourl>.+?)\'"  value="Click Here to Play" />',
            'compflags': 're.DOTALL'
        }
        xbmcMenu.setThreadParams('media', params)

        xbmcMenu.lstChanged = []  # Se borra cualquier actualización del árbol
        # porque este en este punto no existe
        return xbmcMenu.getThreadData()
Exemplo n.º 4
0
class XbmcAddonIDE(tk.Toplevel):
    PERSPECTIVES = ["Site API", "Addon"]

    def __init__(self, theGlobals=None):
        tk.Toplevel.__init__(self)
        self.protocol("WM_DELETE_WINDOW", self.Close)
        self.perspectiveIndx = tk.StringVar(value=self.PERSPECTIVES[0])
        self.activeViewIndx = tk.StringVar()
        self.activeViewIndx.trace("w", self.setActiveView)
        self.leftPaneIndx = tk.IntVar(value=-1)
        self.leftPaneVisible = tk.BooleanVar()
        self.leftPaneVisible.trace("w", self.setLeftPaneVisibility)
        self.rightPaneIndx = tk.IntVar(value=-1)
        #         self.rightPaneIndx.trace("w", self.setRightPane)
        self.xbmcThreads = menuThreads.menuThreads()
        self.addonSettings = xmlFileWrapper.xmlFileWrapper("addonIdeSettingFile.xml")
        self.coder = addonCoder.Addoncoder(self.xbmcThreads, self.addonSettings)
        self.fileGenerator = FileGenerator.FileGenerator(self.addonSettings, self.xbmcThreads, self.coder)
        self.settings = {}
        self.setGUI()
        self.activeUrl.set("")
        self.newFile()
        self.currentFile = "default.pck"
        self.title(self.currentFile)

    def initCoder(self, xbmcThreads, modSourceCode=None):
        addon_id = self.getAddonSettings("addon_id")
        self.coder = addonCoder.Addoncoder(xbmcThreads, addon_id)
        self.coder.modSourceCode = modSourceCode or {}

    def checkSaveFlag(self):
        fileName = self.title()
        if fileName.endswith("**"):
            fileName = os.path.basename(self.currentFile) if not self.currentFile else "default.pck"
            ans = tkMessageBox.askyesno("Warning", "Do you want to save the changes you made to " + fileName)
            if ans:
                self.saveFile()
            else:
                self.setSaveFlag(False)

    def Close(self):
        self.checkSaveFlag()
        self.destroy()

    def setGUI(self):
        frame = tk.Frame(self)
        frame.pack(fill=tk.BOTH, expand=1)

        menuFrame = tk.Frame(frame)
        menuFrame.pack(side=tk.TOP, fill=tk.X)
        self.menuBar = {}
        menuOp = ["File", "Get", "Set", "View", "Knoth", "Coding", "Tools"]
        for elem in menuOp:
            menubutton = tk.Menubutton(menuFrame, text=elem, name=elem.lower())
            menubutton.pack(side=tk.LEFT)
            self.menuBar[elem] = tk.Menu(menubutton, tearoff=False)

        topPane = tk.Frame(menuFrame)
        topPane.pack(side=tk.RIGHT)

        self.activeKnot = tk.StringVar()
        self.activeUrl = tk.StringVar()
        self.message = tk.StringVar()
        self.statusBar = StatusBar(
            frame, [("ActiveKnot: ", self.activeKnot), ("KnotData ", self.message), ("ActiveUrl: ", self.activeUrl)]
        )
        self.statusBar.pack(side=tk.BOTTOM, fill=tk.X, expand=0)

        m1 = tk.PanedWindow(frame, sashrelief=tk.SUNKEN, bd=10)
        m1.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
        self.vPaneWindow = m1
        self.setUpPaneCtrls()

        label = tk.Label(topPane, text="Perspective: ", width=13)
        label.pack(side=tk.LEFT)
        fileChsr = ttk.Combobox(topPane, textvariable=self.perspectiveIndx, value=self.PERSPECTIVES, name="combo")
        fileChsr.pack(side=tk.LEFT)
        cClass = fileChsr.__class__
        cClass.config(fileChsr, state="readonly", takefocus=0)

        label = tk.Label(topPane, text="View: ", width=13)
        label.pack(side=tk.LEFT)
        fileChsr = ttk.Combobox(topPane, textvariable=self.activeViewIndx, name="combo2")
        fileChsr.pack(side=tk.LEFT)
        cClass = fileChsr.__class__
        cClass.config(fileChsr, state="readonly", takefocus=0)

        self.topPane = topPane

        def setPerspectiveViews(*args, **kwargs):
            perspIndx = self.PERSPECTIVES.index(self.perspectiveIndx.get())
            views = [view[0] for view in self.viewPanes[perspIndx]]
            self.topPane.children["combo2"].config(value=views)
            actView = self.actViewPane[perspIndx]
            self.activeViewIndx.set(views[actView])

        setPerspectiveViews()
        self.perspectiveIndx.trace("w", setPerspectiveViews)

        self.menuBuilder()

        for elem in menuOp:
            menubutton = menuFrame.children[elem.lower()]
            menubutton.config(menu=self.menuBar[elem])

    def setUpPaneCtrls(self):
        m1 = self.vPaneWindow
        self.parseTree = treeExplorer.ApiTree(m1, self.xbmcThreads)
        self.parseTree.setOnTreeSelProc(self.onTreeSel)
        self.parseTree.setPopUpMenu(self.popUpMenu)
        self.explorerTree = treeExplorer.treeExplorer(m1, self.addonSettings, self.fileGenerator)

        self.addonFilesViewer = addonFilesViewer(m1)
        self.addonFilesViewer.setHyperlinkManager(self.hyperLinkProcessor)
        self.explorerTree.setEditorWidget(self.addonFilesViewer)
        self.addonCtrlSett = addonSettCtrls.vertRadioMenu(master=m1)
        self.leftPnNames = ["parsetree", "esplorertree"]
        self.avLeftPanes = [self.parseTree, self.explorerTree, self.addonCtrlSett]
        self.leftPaneVisible.set(True)
        self.regexpEd = RegexpFrame(m1, self.xbmcThreads, self.message)
        self.regexpEd.setDropDownFiler(self.comboBoxFiler)
        self.regexpEd.setPopUpMenu(self.popUpWebMenu)
        self.testFrame = ScrolledList(m1, self.coder)
        self.codeFrame = SintaxEditor.CodeEditor(m1, self.xbmcThreads, self.coder)
        xbmcFileW = xmlFileWrapper.threadXmlFileWrapper("NodeSettingFile.xml", self.xbmcThreads)
        self.NodeFrame = xmlFileWrapper.settingsDisplay(master=m1, xmlFileW=xbmcFileW)
        self.NodeFrame.setNotifyChange(self.setSaveFlag)
        self.settingsPane = xmlFileWrapper.settingsDisplay(master=m1, xmlFileW=self.addonSettings)
        self.settingsPane.setNotifyChange(self.setSaveFlag)
        self.addonCtrlSett.setSettingsPane(self.settingsPane)
        self.kodiFrontEnd = KodiFrontEnd.KodiFrontEnd(m1, self.explorerTree.getAddonTemplate, self.fileGenerator)
        self.avRightPanes = [
            self.NodeFrame,
            self.testFrame,
            self.codeFrame,
            self.regexpEd,
            self.addonFilesViewer,
            self.settingsPane,
            self.kodiFrontEnd,
        ]
        self.viewPanes = []
        self.viewPanes.append([("Design", 0, 0), ("Test", 0, 1), ("Code", 0, 2), ("Regexp Editor", 0, 3)])
        self.viewPanes.append([("Settings", 2, 5), ("Test", 0, 6), ("Addon Explorer", 1, 4)])
        self.actViewPane = len(self.viewPanes) * [0]

    def hyperLinkProcessor(self, texto):
        match = re.search('File "(?P<filename>[^"]+)", line (?P<lineno>[0-9]+)', texto)
        if not match:
            tkMessageBox.showinfo("Hyperlink Not Process", texto)
        else:
            fileName = match.group("filename")
            lineNo = match.group("lineno")
            rootId = self.explorerTree.treeview.get_children()[0]
            baseDirectory = translatePath("special://home/addons/")
            if not fileName.startswith(baseDirectory):
                return tkMessageBox.showerror("Hyperlink Not in actual addon", texto)
            nodeId = fileName[len(baseDirectory) :].replace("\\", "/")
            if not fileName.startswith(os.path.join(baseDirectory, rootId)):
                nodeId = rootId + "/Dependencies/" + fileName[len(baseDirectory) :].replace("\\", "/")
                if not self.explorerTree.treeview.exists(nodeId):
                    return tkMessageBox.showerror("Hyperlink Not Found", texto)
            self.explorerTree.treeview.set(nodeId, column="inspos", value=lineNo + ".0")
            self.explorerTree.onTreeSelection(nodeId)
            self.addonFilesViewer.focus_force()

    def setActiveView(self, *args, **kwargs):
        refreshFlag = kwargs.get("refreshFlag", False)
        perspIndx = self.PERSPECTIVES.index(self.perspectiveIndx.get())
        activeView = [view[0] for view in self.viewPanes[perspIndx]].index(self.activeViewIndx.get())
        self.actViewPane[perspIndx] = activeView
        viewName, vwLeftPane, vwRightPane = self.viewPanes[perspIndx][activeView]
        leftPaneIndx = self.leftPaneIndx.get()
        if leftPaneIndx != vwLeftPane:
            self.leftPaneIndx.set(vwLeftPane)
            self.setLeftPaneVisibility()
        if refreshFlag or leftPaneIndx != vwLeftPane:
            self.avLeftPanes[vwLeftPane].refreshPaneInfo()
        rightPaneIndx = self.rightPaneIndx.get()
        if rightPaneIndx != vwRightPane:
            self.rightPaneIndx.set(vwRightPane)
            self.setRightPane()
        if refreshFlag or rightPaneIndx != vwRightPane:
            self.avRightPanes[vwRightPane].initFrameExec()

    def setLeftPane(self, *args, **kwargs):
        viewTy = int(self.leftPaneIndx.get())
        panes = self.vPaneWindow.panes()
        pane2 = self.avLeftPanes[viewTy]
        if self.leftPaneVisible.get():
            if len(panes) > 1:
                self.vPaneWindow.forget(panes[1])
            self.vPaneWindow.add(pane2, after=panes[0])
        else:
            self.vPaneWindow.forget(panes[0])
            self.vPaneWindow.add(pane2)

    #         if self.xbmcThreads.threadDef:self.initRightPane(param = False)

    def setRightPane(self, *args, **kwargs):
        viewTy = int(self.rightPaneIndx.get())
        panes = self.vPaneWindow.panes()
        pane2 = self.avRightPanes[viewTy]
        if self.leftPaneVisible.get():
            if len(panes) > 1:
                self.vPaneWindow.forget(panes[1])
            self.vPaneWindow.add(pane2, after=panes[0])
        else:
            self.vPaneWindow.forget(panes[0])
            self.vPaneWindow.add(pane2)

    #         if self.xbmcThreads:self.initRightPane(param = False)

    def setLeftPaneVisibility(self, *args, **kwargs):
        nPane = self.leftPaneIndx.get()
        isVisible = self.leftPaneVisible.get()
        panes = self.vPaneWindow.panes()
        if not isVisible and len(panes) > 1:
            self.vPaneWindow.forget(panes[0])
        elif isVisible:
            pane2 = self.avLeftPanes[nPane]
            if len(panes) == 2:
                self.vPaneWindow.forget(panes[0])
                self.vPaneWindow.add(pane2, before=panes[1])
            elif len(panes) == 1:
                self.vPaneWindow.add(pane2, before=panes[0])
            elif len(panes) == 0:
                self.vPaneWindow.add(pane2)

    def dummyCommand(self):
        tkMessageBox.showerror("Not implemented", "Not yet available")

    def menuBuilder(self):

        self.menuBar["popup"] = tk.Menu(self, tearoff=False)

        menuOpt = []
        menuOpt.append(("cascade", "Insert New", 0))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Set Regexp", "Ctrl+G", 0, self.setRegexp))
        menuOpt.append(("command", "Set NextRegexp", "Ctrl+N", 0, self.setNextRegexp))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Rename", "Ctrl+R", 0, self.renameKnot))
        menuOpt.append(("command", "Delete", "Ctrl+D", 0, self.deleteKnot))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Transform in a menu node", "Ctrl+N", 0, self.makeMenuNode))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Edit", "Ctrl+E", 0, self.editKnot))
        self.makeMenu("popup", menuOpt)

        menuOpt = []
        menuOpt.append(("command", "Source", "Ctrl+B", 0, self.newSendOutput))
        menuOpt.append(("command", "Output", "Ctrl+A", 0, self.newReceiveInput))
        menuOpt.append(("command", "Link", "Ctrl+A", 0, self.newLink))
        self.makeMenu("popup.Insert_New", menuOpt)

        self.menuBar["webpopup"] = tk.Menu(self, tearoff=False)

        menuOpt = []
        menuOpt.append(("command", "Cut", "", 2, self.dummyCommand))
        menuOpt.append(("command", "Copy", "", 0, self.dummyCommand))
        menuOpt.append(("command", "Paste", "", 0, self.dummyCommand))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Send UserForm", "", 0, self.dummyCommand))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Encrypt Rijndael", "", 0, self.dummyCommand))
        menuOpt.append(("command", "Decrypt Rijndael", "", 0, self.dummyCommand))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Unwise process", "", 0, self.unwiseProcess))
        menuOpt.append(("command", "Unwise variable", "", 0, self.dummyCommand))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Detect packer", "", 0, self.detectPacker))
        menuOpt.append(("command", "Unpack", "", 0, self.unPack))
        self.makeMenu("webpopup", menuOpt)

        menuOpt = []
        menuOpt.append(("command", "New", "Ctrl+O", 0, self.newFile))
        menuOpt.append(("command", "Open", "Ctrl+O", 0, self.__openFile))
        menuOpt.append(("command", "Save", "Ctrl+S", 0, self.saveFile))
        menuOpt.append(("command", "Save as", "Ctrl+S", 0, self.saveAsFile))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Export to XBMC", "Ctrl+x", 0, self.onXbmcExport))
        menuOpt.append(("command", "MakeZip File", "Ctrl+M", 0, self.onMakeZipFile))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Close", "Alt+Q", 0, self.Close))
        self.makeMenu("File", menuOpt)

        menuOpt = []
        menuOpt.append(("command", "File", "Ctrl+F", 0, self.importFile))
        menuOpt.append(("command", "Url", "Ctrl+U", 0, self.importUrl))
        menuOpt.append(("command", "Clipboard", "Ctrl+L", 0, self.regexpEd.pasteFromClipboard))
        menuOpt.append(("command", "Selected Url", "Ctrl+S", 0, self.selectedURL))
        menuOpt.append(("command", "Selected Form", "Ctrl+F", 0, self.selectedForm))
        self.makeMenu("Get", menuOpt)

        menuOpt = []
        menuOpt.append(("command", "Set Url", "Ctrl+U", 0, self.setUrl))
        menuOpt.append(("command", "Set Regexp", "Ctrl+R", 0, self.setRegexp))
        menuOpt.append(
            ("command", "Set Header Regexp", "Ctrl+N", 0, lambda param="headregexp": self.setActNodeParam(param))
        )
        menuOpt.append(
            ("command", "Set NextRegexp", "Ctrl+N", 0, lambda param="nextregexp": self.setActNodeParam(param))
        )
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Edit", "Ctrl+E", 0, self.editKnot))
        self.makeMenu("Set", menuOpt)

        menuOpt = []
        menuOpt.append(("command", "New", "Ctrl+S", 0, self.newParseKnot))
        menuOpt.append(("command", "Set ActiveKnoth", "Ctrl+A", 0, self.setActiveKnot))
        self.makeMenu("Knoth", menuOpt)

        menuOpt = []
        menuOpt.append(("checkbutton", "ParseTree", self.leftPaneVisible, [False, True]))
        menuOpt.append(("separator",))
        menuOpt.append(("radiobutton", self.perspectiveIndx, self.PERSPECTIVES))
        menuOpt.append(("separator",))
        perspIndx = 0
        menuOpt.append(("radiobutton", self.activeViewIndx, [view[0] for view in self.viewPanes[perspIndx]]))
        self.makeMenu("View", menuOpt)

        def miLambda():
            frstIndx, lstIndx = 5, tk.END
            self.menuBar["View"].delete(frstIndx, lstIndx)
            perspIndx = self.PERSPECTIVES.index(self.perspectiveIndx.get())
            for k, view in enumerate(self.viewPanes[perspIndx]):
                self.menuBar["View"].add_radiobutton(label=view[0], variable=self.activeViewIndx, value=k)

        self.menuBar["View"].config(postcommand=miLambda)

        menuOpt = []
        menuOpt.append(("command", "Addon", "Ctrl+E", 0, lambda key="2": self.codeAddon(key)))
        menuOpt.append(("command", "DownThread", "Ctrl+D", 0, self.codeDownThread))
        menuOpt.append(("command", "ActiveKnot", "Ctrl+R", 0, self.codeActiveKnot))
        menuOpt.append(("command", "SaveCode", "Ctrl+o", 0, self.saveCode))
        self.makeMenu("Coding", menuOpt)

        menuOpt = []
        menuOpt.append(("command", "HTML struct", "Ctrl+R", 0, self.HTMLstruct))
        menuOpt.append(("command", "Forms", "Ctrl+F", 0, self.formsDetector))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Detach Window", "Ctrl+R", 0, self.detachWindow))
        menuOpt.append(("separator",))
        menuOpt.append(("command", "Setting", "Ctrl+S", 0, self.programSettingDialog))
        self.makeMenu("Tools", menuOpt)

    def formsDetector(self):
        baseUrl = self.regexpEd.getActiveUrl()
        content = self.regexpEd.getContent()
        form_xml = formDetector.getFormXmlStr(content)
        if "category" not in form_xml:
            return tkMessageBox.showinfo("Form Detector", "No forms in url content")
        browser = AppSettingDialog(
            self, form_xml, isFile=False, settings={}, title="Form Detector", dheight=600, dwidth=400
        )
        if browser.allSettings:
            formAttr = dict([(key[3:], value) for key, value in browser.allSettings if key.startswith("fa_")])
            formFields = browser.allSettings[len(formAttr) :]
            # filterFunc = lambda x: (x[0].startswith('if_') and x[1]) or (not x[0].startswith('if_') and x[1] is not 0)
            filterFunc = lambda x: x[1] is not 0
            formFields = filter(filterFunc, formFields)
            trnValueFnc = (
                lambda x: (x[0], formDetector.unescapeXml(x[1].partition("|")[0]))
                if isinstance(x[1], basestring)
                else (x[0], "on")
            )
            formFields = map(trnValueFnc, formFields)
            trnKeyFnc = lambda x: (x[0][3:], "@" + x[1]) if x[0].startswith("if_") else x
            formFields = map(trnKeyFnc, formFields)
            # formFields = [(key, trnFnc(value)) for key, value in browser.allSettings if not (key.startswith('fa_') or value == 0)]
            refererOpt = "-e " + '"' + baseUrl + '"'
            curlCommand = formDetector.getCurlCommand(baseUrl, formAttr, formFields, refererOpt)
            print curlCommand
            self.regexpEd.setActiveUrl(curlCommand)

    def HTMLstruct(self):
        tagSpan = self.regexpEd.getSelRange("actMatch")
        content = self.regexpEd.getContent(*tagSpan)
        try:
            htmlParse = CustomRegEx.ExtRegexParser({}, []).htmlStruct(content, 0)
        except:
            equis = "Not HTML conform"
            tkMessageBox.showinfo("Actual match HTMLstruct", equis)
        else:
            fmt = "{:<20} {:<40}".format
            #             equis = '\n'.join([fmt(x[0].count('.')*'  ' + '*' + x[0].rpartition('.')[2],x[1][:40]) for x in htmlParse])
            equis = [fmt(x[0].count(".") * "  " + "*" + x[0].rpartition(".")[2], x[1][:40]) for x in htmlParse]
            from xbmcgui import Dialog

            k = Dialog().select("Actual match HTMLstruct", equis)

    def detachWindow(self):
        actWin = self.activeViewIndx.get()
        wname, lwpane, rwpane = self.viewPanes[actWin]

    def detectPacker(self):
        content = self.regexpEd.getContent()
        from jsunpack import detect

        result = detect(content)
        if result:
            tkMessageBox.showinfo("Pack content", "The content is packed")
        else:
            tkMessageBox.showerror("Pack content", "The content is packed")

    def unPack(self):
        content = self.regexpEd.getContent()
        from jsunpack import unpack

        content = unpack(content)
        self.regexpEd.setContent(content, newUrl=False)

    def unwiseProcess(self):
        content = self.regexpEd.getContent()
        from unwise import unwise_process

        content = unwise_process(content)
        self.regexpEd.setContent(content, newUrl=False)

    def onMakeZipFile(self):
        D = os.path.normpath(self.getAddonSettings(srchSett="script_export"))
        zipFileName = tkFileDialog.asksaveasfilename(
            title="Zip File to create",
            initialdir=D,
            defaultextension=".zip",
            filetypes=[("Zip Files", "*.zip"), ("All Files", "*.*")],
        )
        if zipFileName:
            self.onXbmcExport(zipFileName)
            # Este procedimiento se hce necesario para asegurar que en el android el archivo zip no tenga problemas
            with open(zipFileName, "r+b") as f:
                data = f.read()
                pos = data.find("\x50\x4b\x05\x06")  # End of central directory signature
                if pos > 0:
                    f.seek(pos + 22)  # size of 'ZIP end of central directory record'
                    f.truncate()

    def getAddonSettings(self, srchSett=None):
        return self.addonSettings.getParam(srchSett)

    def onXbmcExport(self, name=None):
        errMsg = ""
        if name:
            zipFile = zipfile.ZipFile(name, "w")
            copySrcFile = zipFile.write
            genFileFromStr = zipFile.writestr
        else:
            baseDirectory = translatePath("special://home/addons")
            copySrcFile = shutil.copyfile

        addonFiles = self.listAddonFiles(name)
        for elem in addonFiles:
            dstFile, mode, srcFile = elem
            if not name:
                dstFile = translatePath("special://home/addons/" + dstFile)
                dstDirectory = os.path.split(dstFile)[0]
                if not os.path.exists(dstDirectory):
                    os.makedirs(dstDirectory)
            try:
                if mode == "f":
                    copySrcFile(srcFile, dstFile)
                elif mode == "s":
                    srcFile = self.fileGenerator.getSource(srcFile)
                    if name:
                        genFileFromStr(dstFile, srcFile)
                    else:
                        with open(dstFile, "w") as wfile:
                            wfile.write(srcFile)
            except:
                errFile = dstFile.rpartition("\\")[2]
                errMsg += errFile + "\n"
        if name:
            zipFile.close()
        addonId = self.getAddonSettings("addon_id")
        addonName = self.getAddonSettings("addon_name")
        if errMsg:
            errMsg = (
                "During addon creation for "
                + addonName
                + " ("
                + addonId
                + ") , the following source files were not found: \n"
                + errMsg
            )
            tkMessageBox.showerror("Addon creation", errMsg)
        else:
            errMsg = "Addon for " + addonName + " (" + addonId + ") succesfully created"
            tkMessageBox.showinfo("Addon creation", errMsg)

    def listAddonFiles(self, name=None):
        fileList = self.explorerTree.getAddonTemplate()[1:]
        fileList = [
            (filePath, fileAttr["type"], fileAttr["source"])
            for filePath, fileAttr in fileList
            if "Dependencies" not in filePath
        ]
        addonListFiles = []
        for filePath, itype, source in fileList:
            itype = {"file": "f", "genfile": "s"}[itype]
            if type == "s":
                source = self.fileGenerator.getSource(source)
            addonListFiles.append((filePath, itype, source))
        return addonListFiles

    def programSettingDialog(self):
        settingObj = AppSettingDialog(self, "ideProgramSettings.xml", settings=self.settings, title="Test Window Case")
        self.settings = settingObj.result
        if settingObj.applySelected:
            self.setSaveFlag(True)

    def codeAddon(self, key):
        if self.rightPaneIndx.get() != key:
            return self.rightPaneIndx.set(key)
        execObj = self.xbmcThreads if key in ["0", "3"] else self.coder
        self.avRightPanes[int(key)].initFrameExec(execObj, param=True)

    def codeDownThread(self):
        if self.rightPaneIndx.get() != "2":
            return self.rightPaneIndx.set("2")
        threadId = self.xbmcThreads.threadDef
        self.codeFrame.setContentToNodeCode(threadId, incDownThread=True)

    def saveCode(self):
        viewTy = int(self.rightPaneIndx.get())
        rPane = self.avRightPanes[viewTy]
        if isinstance(rPane, SintaxEditor.CodeEditor):
            widget = self.codeFrame
            partialMod = True
        elif isinstance(rPane, addonFilesViewer):
            widget = self.addonFilesViewer.sintaxEditor
            partialMod = False
        else:
            return
        modSource, contType, fileId = widget.getContent()
        if contType == "genfile":
            self.fileGenerator.setSource(fileId, modSource, partialMod)
            if not partialMod:
                modSource = self.fileGenerator.getSource(fileId)
                widget.setContent((modSource, contType, fileId), "1.0")
            else:
                match = re.search("\W*<([^>]+)>\W*", modSource)
                if match:
                    nodeId = match.group(1)
                    if nodeId == self.xbmcThreads.threadDef and nodeId in self.coder.modSourceCode:
                        self.coder.modSourceCode.pop(nodeId)
                        self.xbmcThreads.unlockThread(nodeId)
                self.codeFrame.initFrameExec()
            self.setSaveFlag(True)
        if contType == "file":
            if os.path.splitext(fileId)[1] in [".py", ".txt", ".xml"]:
                with open(fileId, "w") as f:
                    f.write(modSource)

    def codeActiveKnot(self):
        if self.rightPaneIndx.get() != "2":
            return self.rightPaneIndx.set("2")
        threadId = self.xbmcThreads.threadDef
        self.codeFrame.setContentToNodeCode(threadId)

    def makeMenu(self, masterID, menuArrDesc):
        master = self.menuBar[masterID]
        for menuDesc in menuArrDesc:
            menuType = menuDesc[0]
            if menuType == "command":
                menuType, mLabel, mAccelKey, mUnderline, mCommand = menuDesc
                master.add(
                    menuType,
                    label="{:30s}".format(mLabel),
                    accelerator=mAccelKey,
                    underline=mUnderline,
                    command=mCommand,
                )
            elif menuType == "cascade":
                menuType, mLabel, mUnderline = menuDesc
                menuLabel = masterID + "." + mLabel.replace(" ", "_")
                self.menuBar[menuLabel] = tk.Menu(master, tearoff=False)
                master.add("cascade", label="{:30s}".format(mLabel), underline=mUnderline, menu=self.menuBar[menuLabel])
            elif menuType == "radiobutton":
                menuType, radioVar, radioOps = menuDesc
                for k, elem in enumerate(radioOps):
                    master.add_radiobutton(label=elem, variable=radioVar, value=k)
            elif menuType == "checkbutton":
                menuType, checkLabel, checkVar, checkVals = menuDesc
                master.add_checkbutton(label=checkLabel, variable=checkVar, onvalue=checkVals[1], offvalue=checkVals[0])
            else:
                master.add("separator")

    def makeMenuNode(self):
        knotId = self.getActiveKnot()
        if self.xbmcThreads.isthreadLocked(knotId):
            return tkMessageBox.showerror("Access Error", knotId + " is a Code locked Node")
        parseKnotId = tkSimpleDialog.askstring("Create Menu Node", "Menu ID to create:")
        if not parseKnotId:
            return
        lstChanged = []
        self.xbmcThreads.createThread("list", parseKnotId, parseKnotId)
        menuThread = self.xbmcThreads.threadDef
        url = self.xbmcThreads.getThreadParam(menuThread, "url")
        regexp = self.xbmcThreads.getThreadParam(menuThread, "regexp")
        compflags = eval(self.xbmcThreads.getThreadParam(menuThread, "compflags"))
        submenus = self.testFrame.parseUrlContent(url, regexp, compflags)
        for k, elem in enumerate(submenus):
            menuName = elem["label"]
            menuId = "opc{:0>2d}_{:}".format(k, menuThread.replace(" ", "_"))
            self.xbmcThreads.createThread("list", menuName, menuId)
            self.xbmcThreads.setNextThread(parseKnotId, menuId)
            self.xbmcThreads.setThreadParams(menuId, {"option": k})
            self.xbmcThreads.setNextThread(menuId, menuThread)
            lstChanged.append(menuThread + "_" + menuId + "_" + "lnk")
        lstChanged = map(self.xbmcThreads.getDotPath, lstChanged)
        self.parseTree.refreshTreeInfo(parseKnotId, lstChanged=lstChanged)
        if lstChanged:
            self.setSaveFlag(True)

    def editKnot(self):
        knotId = self.getActiveKnot()
        if not knotId:
            return -1
        if self.xbmcThreads.isthreadLocked(knotId):
            return tkMessageBox.showerror("Access Error", knotId + " is a Code locked Node")
        editDlg = EditTransaction(self, self.xbmcThreads)
        self.parseTree.refreshTreeInfo(lstChanged=editDlg.result)
        if editDlg.result:
            self.setSaveFlag(True)

    def getActiveKnot(self):
        return self.xbmcThreads.threadDef

    def initRightPane(self, param=False):
        viewTy = int(self.rightPaneIndx.get())
        #         execObj = self.xbmcThreads if viewTy in [0,3] else self.coder
        self.avRightPanes[viewTy].initFrameExec()

    def setActiveKnot(self, activeKnotId=None):
        if not activeKnotId:
            activeKnotId = tkSimpleDialog.askstring("Set ActiveKnot", "Enter the new ActiveKnot:")
        if activeKnotId:
            if self.xbmcThreads.getThreadAttr(activeKnotId, "name") != -1 and self.getActiveKnot() != activeKnotId:
                self.xbmcThreads.threadDef = activeKnotId
                self.initRightPane(param=False)
                self.parseTree.setSelection(activeKnotId, absFlag=False)

    def onTreeSel(self, node=None):
        treeview = self.parseTree.treeview
        iid = treeview.focus()
        parent, sep, threadId = iid.rpartition(".")
        self.setActiveKnot(threadId)

    def comboBoxFilerOLD(self):
        nodeLst = [elem for elem in self.xbmcThreads.getSameTypeNodes("media") if not elem.endswith("_lnk")]
        getRegEx = self.xbmcThreads.getThreadParam
        lista = ["(?#<rexp-" + node + ">)" + getRegEx(node, "regexp") for node in nodeLst]
        lista.extend(
            [
                "(?#<rnxt-" + node + ">)" + getRegEx(node, "nextregexp")
                for node in nodeLst
                if getRegEx(node, "nextregexp")
            ]
        )
        headLst = lambda node: [elem.split("<->") for elem in getRegEx(node, "headregexp").split("<=>")]
        for node in nodeLst:
            if not getRegEx(node, "headregexp"):
                continue
            lista.extend(["(?#<rhead-" + node + "-" + label + ">)" + regexp for label, regexp in headLst(node)])
        return sorted(lista)

    def comboBoxFiler(self):
        nodeLst = [elem for elem in self.xbmcThreads.getSameTypeNodes("media") if not elem.endswith("_lnk")]
        getRegEx = self.xbmcThreads.getThreadParam
        getParent = (
            lambda x: "(?#<rexp-" + self.xbmcThreads.getParent(x) + ">)" if self.xbmcThreads.getParent(x) else None
        )
        lista = [["(?#<rexp-" + node + ">)", getRegEx(node, "regexp"), getParent(node)] for node in nodeLst]
        lista.extend(
            [
                ["(?#<rnxt-" + node + ">)", getRegEx(node, "nextregexp"), "(?#<rexp-" + node + ">)"]
                for node in nodeLst
                if getRegEx(node, "nextregexp")
            ]
        )
        headLst = lambda node: [elem.split("<->") for elem in getRegEx(node, "headregexp").split("<=>")]
        for node in nodeLst:
            if not getRegEx(node, "headregexp"):
                continue
            lista.extend([["(?#<rhead-" + node + "-" + label + ">)", regexp, None] for label, regexp in headLst(node)])
        return sorted(lista)

    def popUpMenu(self):
        popUpMenu = self.menuBar["popup"]
        treeview = self.parseTree.treeview
        iid = treeview.focus()
        menuState = tk.DISABLED if iid == "media" else tk.NORMAL
        self.menuBar["popup.Insert_New"].entryconfigure(1, state=menuState)
        return popUpMenu

    def popUpWebMenu(self):
        return self.menuBar["webpopup"]

    def setKnotParam(self, paramStr, paramValue):
        if not self.getActiveKnot():
            return -1
        knotId = self.getActiveKnot()
        if self.xbmcThreads.isthreadLocked(knotId):
            return tkMessageBox.showerror("Access Error", knotId + " is a Code locked Node")
        params = self.xbmcThreads.getThreadAttr(knotId, "params")
        params[paramStr] = paramValue
        self.setSaveFlag(True)

    def setActNodeParam(self, param):
        if param == "url":
            self.setKnotParam("url", self.regexpEd.getActiveUrl())
        elif param == "nextregexp":
            self.setKnotParam("nextregexp", self.regexpEd.getRegexpPattern())
            self.regexpEd.regexpFrame.cbIndex.set("(?#<rnxt-" + self.getActiveKnot() + ">)")
        elif param == "headregexp":
            knotId = self.getActiveKnot()
            headRegExp = self.xbmcThreads.getThreadParam(knotId, "headregexp") or ""
            headRegExp += ("<=>" if headRegExp else "") + "headervar<->" + self.regexpEd.getRegexpPattern()
            self.setKnotParam("headregexp", headRegExp)
            self.regexpEd.regexpFrame.cbIndex.set("(?#<rhead-" + self.getActiveKnot() + ">)")

    def setUrl(self):
        self.setKnotParam("url", self.regexpEd.getActiveUrl())

    def setNextRegexp(self):
        self.setKnotParam("nextregexp", self.regexpEd.getRegexpPattern())

    def setRegexp(self):
        exitFlag = self.setKnotParam("regexp", self.regexpEd.getRegexpPattern())
        if exitFlag == "ok":
            return
        self.setKnotParam("compflags", self.regexpEd.getCompFlags())
        self.regexpEd.regexpFrame.cbIndex.set("(?#<rexp-" + self.getActiveKnot() + ">)")

    def newSendOutput(self):
        refKnot = self.xbmcThreads.threadDef
        self.newParseKnot(refKnot, outputToRefKnoth=True)

    def newLink(self):
        parseKnotId = tkSimpleDialog.askstring("Create Link", "ParseKnot ID to link:")
        if parseKnotId:
            self.xbmcThreads.setLinkTie(self.xbmcThreads.threadDef, parseKnotId)
            lnkNode = parseKnotId + "_" + self.xbmcThreads.threadDef + "_lnk"
            lstChanged = [self.xbmcThreads.getDotPath(lnkNode)]
            self.parseTree.refreshTreeInfo(self.xbmcThreads.threadDef, lstChanged=lstChanged)
            if lstChanged:
                self.setSaveFlag(True)

    def newReceiveInput(self):
        refKnot = self.xbmcThreads.threadDef
        self.newParseKnot(refKnot, outputToRefKnoth=False)

    def deleteKnot(self, threadId=None):
        if not threadId:
            threadId = self.xbmcThreads.threadDef
        lstChanged = [self.xbmcThreads.getDotPath(threadId)]
        if self.xbmcThreads.getThreadAttr(threadId, "type") == "thread":
            for lnkId in self.xbmcThreads.getLinks(threadId):
                toNode = self.xbmcThreads.getThreadAttr(lnkId, "name")
                if self.xbmcThreads.getThreadAttr(toNode, "type") == "thread":
                    continue
                lnkRev = self.xbmcThreads.getLinkId(threadId, toNode)
                lstChanged.append(self.xbmcThreads.getDotPath(lnkRev))
        lista = [elem for elem in self.xbmcThreads.getSameTypeNodes(threadId) if not elem.endswith("_lnk")]
        self.xbmcThreads.deleteNode(threadId)
        self.parseTree.refreshTreeInfo(lstChanged=lstChanged)
        self.coder.modifyCode("delete", *lista)
        if lstChanged:
            self.setSaveFlag(True)

    def renameKnot(self, threadId=None):
        if not threadId:
            threadId = self.xbmcThreads.threadDef
        if self.xbmcThreads.isthreadLocked(threadId):
            return tkMessageBox.showerror("Access Error", threadId + " is a Code locked Node")
        newKnotId = tkSimpleDialog.askstring("Create new ParseKnotID", "New ParseKnot ID to rename:")
        lstChanged = [self.xbmcThreads.getDotPath(threadId)]
        self.xbmcThreads.rename(threadId, newKnotId)
        lstChanged.append(self.xbmcThreads.getDotPath(newKnotId))
        self.parseTree.refreshTreeInfo(lstChanged=lstChanged)
        self.coder.modifyCode("rename", threadId, newKnotId)
        if lstChanged:
            self.setSaveFlag(True)

    def newParseKnot(self, refKnot=None, outputToRefKnoth=True):
        parseKnotId = tkSimpleDialog.askstring("Create ParseKnot", "ParseKnot ID to create:")
        if not parseKnotId:
            return
        activeKnoth = self.xbmcThreads.threadDef
        knothType = self.xbmcThreads.getThreadAttr(activeKnoth, "type")
        if self.xbmcThreads.createThread(iType=knothType, name=parseKnotId, menuId=parseKnotId) == -1:
            return
        if refKnot == None:
            refKnot = "media" if knothType == "thread" else "rootmenu"
        lstChangedFlag = refKnot not in ["media", "rootmenu"]

        lstChanged = [] if lstChangedFlag else [self.xbmcThreads.getDotPath(parseKnotId)]
        self.xbmcThreads.threadDef = parseKnotId
        if knothType == "list":
            if refKnot != "rootmenu":
                if outputToRefKnoth:
                    lstChanged.append(self.xbmcThreads.getDotPath(activeKnoth))
                    if self.xbmcThreads.getThreadAttr(refKnot, "up") != "rootmenu":
                        refKnotUp = self.xbmcThreads.getThreadAttr(refKnot, "up")
                        self.xbmcThreads.setNextThread(refKnotUp, parseKnotId)
                    self.xbmcThreads.setNextThread(parseKnotId, refKnot)
                    refKnot = parseKnotId
                else:
                    self.xbmcThreads.setNextThread(refKnot, parseKnotId)
                    activeKnoth = parseKnotId
        elif knothType == "thread":
            self.setKnotParam("url", self.regexpEd.getActiveUrl())
            self.setRegexp()
            if refKnot != "media":
                if outputToRefKnoth:
                    self.xbmcThreads.setNextThread(parseKnotId, refKnot)
                    activeKnoth = parseKnotId
                else:
                    lstChanged.append(self.xbmcThreads.getDotPath(activeKnoth))
                    if self.xbmcThreads.getThreadAttr(refKnot, "up") != "media":
                        refKnotUp = self.xbmcThreads.getThreadAttr(refKnot, "up")
                        self.xbmcThreads.setNextThread(parseKnotId, refKnotUp)
                    self.xbmcThreads.setNextThread(refKnot, parseKnotId)
                    refKnot = parseKnotId
        if lstChangedFlag:
            lstChanged.append(self.xbmcThreads.getDotPath(activeKnoth))
        self.parseTree.refreshTreeInfo(parseKnotId, lstChanged=lstChanged)
        self.setSaveFlag(True)

    def setSaveFlag(self, state, lstChanged=None):
        suffix = "  **" if state else ""
        fileName = (self.currentFile if self.currentFile else "default.pck") + suffix
        self.title(fileName)
        if lstChanged:
            self.parseTree.refreshTreeInfo(lstChanged=lstChanged)

    def importFile(self):
        name = tkFileDialog.askopenfilename(
            filetypes=[("xml Files", "*.xml"), ("Text Files", "*.txt"), ("All Files", "*.*")]
        )
        if name:
            name = "file:///" + name
            self.importUrl(name)

    def importUrl(self, urlToOpen=None, initialValue=None):
        if not urlToOpen:
            urlToOpen = tkSimpleDialog.askstring("Open URL", "URL addres to parse:", initialvalue=initialValue or "")
        if urlToOpen:
            self.regexpEd.setActiveUrl(urlToOpen)

    def selectedURL(self):
        selRange = self.regexpEd.getSelRange()
        selUrl = self.regexpEd.getContent(*selRange)
        self.importUrl(selUrl)

    def selectedForm(self):
        selForm = self.regexpEd.getContent("1.0", "end")
        if not (selForm[:5].lower() == "<form" and selForm[-8:-1].lower() == "</form>"):
            return tkMessageBox.showerror("Not Form", "Zoom In to a <form.+?</form> pattern")
        selForm = "<form" + selForm[5:-8] + "</form>"
        activeUrl = self.regexpEd.getActiveUrl()
        formAttr = re.search("<form\s*([^>]+)>", selForm).group(1)
        formAttr = eval("dict(" + ",".join(formAttr.split()) + ")")
        method = "?" if formAttr.get("method", "GET") == "GET" else "<post>"
        formUrl = formAttr.get("action", "") or activeUrl

        forInVars = re.findall(r"<input\s*(.+?)[/>]", selForm, re.IGNORECASE | re.DOTALL)
        urlVars = {}
        for inVar in forInVars:
            inVar = inVar.replace("class=", "_class=")
            inAttr = eval("dict(" + ",".join(inVar.split()) + ")")
            key = inAttr.get("name", None) or inAttr.get("id", None)
            if key:
                urlVars[key] = inAttr.get("value", "")
        methodData = urllib.urlencode(urlVars)
        selUrl = formUrl + method + methodData
        self.importUrl(initialValue=selUrl)

    def newFile(self, fileName="", threadData=None, modSourceCode=None, settings=None):
        self.checkSaveFlag()
        self.currentFile = fileName or "default.pck"
        self.title(self.currentFile)
        threadData = threadData or self.initThreadData()
        self.xbmcThreads.setThreadData(*threadData)
        addonSettings = settings or {}
        if addonSettings.has_key("reset"):
            addonSettings.pop("reset")
        self.addonSettings.setNonDefaultParams(addonSettings)

        self.coder.modSourceCode = modSourceCode or {}
        self.parseTree.setXbmcThread(self.xbmcThreads)

        self.explorerTree.refreshFlag = True
        self.setActiveView(refreshFlag=True)

    def saveFile(self):
        nameFile = self.currentFile
        self.saveAsFile(nameFile)

    def saveAsFile(self, nameFile=None):
        if not nameFile:
            name = tkFileDialog.asksaveasfilename(
                title="File Name to save",
                defaultextension=".pck",
                filetypes=[("pck Files", "*.pck"), ("All Files", "*.*")],
            )
            if not name:
                return
        else:
            name = nameFile
        try:
            with open(name, "wb") as f:
                for objeto in [
                    self.xbmcThreads.getThreadData(),
                    self.addonSettings.getNonDefaultParams(),
                    self.coder.modSourceCode,
                ]:
                    objStr = json.dumps(objeto)
                    f.write(objStr + "\n")

        except:
            tkMessageBox.showerror("Error", "An error was found saving the file")
        else:
            self.currentFile = name if name.endswith(".pck") else name + ".pck"
            self.setSaveFlag(False)

    def __openFile(self):
        self.checkSaveFlag()
        name = tkFileDialog.askopenfilename(filetypes=[("pck Files", "*.pck"), ("All Files", "*.*")])
        if name:
            try:
                with open(name, "rb") as f:
                    kodiThreadData = json.loads(f.readline())
                    settings = json.loads(f.readline())
                    modifiedCode = json.loads(f.readline())
            except IOError:
                tkMessageBox.showerror("Not a valid File", "File not pck compliant ")
                return
            except ValueError:
                tkMessageBox.showerror("Not a valid File", "An error has ocurred while reding the file ")
                return
            self.newFile(fileName=name, threadData=kodiThreadData, modSourceCode=modifiedCode, settings=settings)

    def initThreadData(self):
        xbmcMenu = menuThreads.menuThreads()
        params = {
            "url": "https://www.youtube.com/watch?v=Vw8ViaL7-m4",
            "regexp": 'onclick="location.href=\'(?P<videourl>.+?)\'"  value="Click Here to Play" />',
            "compflags": "re.DOTALL",
        }
        xbmcMenu.setThreadParams("media", params)

        xbmcMenu.lstChanged = []  # Se borra cualquier actualización del árbol
        # porque este en este punto no existe
        return xbmcMenu.getThreadData()