Exemplo n.º 1
0
    def GetCaptions(self) -> None:
        aCaptions: List[str]
        uCaptions: str

        del self.aDropDownButtons[:]
        if self.uCaption.endswith("[]"):
            aCaptions           = self.uCaption.split(u':::')
            self.uCaption       = aCaptions[0]
            uCaptions           = aCaptions[1]
            self.aCaptions      = Var_GetArray(uCaptions , 1)
            self.aCaptions      = [u"$var("+item+")" for item in self.aCaptions]
        elif u':::' in self.uCaption:
            aCaptions           = self.uCaption.split(u':::')
            self.uCaption       = aCaptions[0]
            self.aCaptions      = aCaptions[1:]
            self.aActionNames   = ReplaceVars(self.uActionName).split(u':::')
            self.uActionName    = u''
            super(cWidgetButton, self).SetCaption(self.uCaption)
        else:
            if self.aCaptions[0].startswith("$DIRLIST["):
                oPath:cPath = cPath(self.aCaptions[0][9:-1])
                self.aCaptions = oPath.GetFolderList()
Exemplo n.º 2
0
    def CreatePopup(self, uValue, fktButttonSelect, fktTextInputSelect):
        """ create the popup """
        self.oContent = GridLayout(cols=1, spacing='5dp')
        scrollview = ScrollView(do_scroll_x=False,
                                bar_width='10dp',
                                scroll_type=['bars', 'content'])
        scrollcontent = GridLayout(cols=1,
                                   spacing='5dp',
                                   size_hint=(None, None))
        scrollcontent.bind(minimum_height=scrollcontent.setter('height'))
        if Globals.uDeviceOrientation == u'landscape':
            self.popup = popup = Popup(content=self.oContent,
                                       title=self.title,
                                       size_hint=(0.5, 0.9),
                                       auto_dismiss=False)
        else:
            self.popup = popup = Popup(content=self.oContent,
                                       title=self.title,
                                       size_hint=(0.9, 0.9),
                                       auto_dismiss=False)

        #we need to open the popup first to get the metrics
        popup.open()
        #Add some space on top
        self.oContent.add_widget(Widget(size_hint_y=None, height=dp(2)))

        # add an inputfield if requested
        if self.bAddInputField:
            self.oTextInput = TextInput(
                text=uValue,
                size_hint_y=None,
                height='30dp',
                multiline=False,
            )
            self.oTextInput.bind(on_text_validate=fktTextInputSelect)
            self.oContent.add_widget(self.oTextInput)
            self.oContent.add_widget(SettingSpacer())

        # we test if we want to show some special list
        if len(self.options) > 0:
            if self.options[0] == "$LANGUAGELIST":
                self.options = GetLanguageList()
                self.oButtonHeigth = dp(30)
            elif self.options[0] == "$GESTURESLIST":
                self.options = GetGestureList()
            elif self.options[0] == "$PAGELIST":
                self.options = GetPageList()
            elif self.options[0] == "$ACTIONLIST":
                self.options = GetActionList()
                self.oButtonHeigth = dp(30)
            elif self.options[0] == "$ACTIONLISTSEND":
                self.options = GetSendActionList()
                self.oButtonHeigth = dp(30)
            elif self.options[0].startswith("$DIRLIST["):
                uPath = self.options[0][9:-1]
                aFiles = cPath(uPath).GetFolderList()
                aRet = []
                for uFile in aFiles:
                    aRet.append(uFile)
                aRet.sort()
                self.options = aRet
            elif self.options[0].startswith("$FILELIST["):
                uPath = self.options[0][10:-1]
                aFiles = cPath(uPath).GetFileList()
                aRet = []
                for uFile in aFiles:
                    aRet.append(uFile)
                aRet.sort()
                self.options = aRet
            elif self.options[0].endswith("[]"):
                aRetTmp = Var_GetArray(uVarName=self.options[0], iLevel=1)
                aRet = [ReplaceVars(u"$var(" + item + ")") for item in aRetTmp]
                aRet.sort()
                self.options = aRet

        #uid = str(self.uid)
        uid = "test"
        for option in self.options:
            state = 'down' if option == uValue else 'normal'
            btn = ToggleButton(text=option,
                               state=state,
                               group=uid,
                               size=(popup.width, self.oButtonHeigth),
                               size_hint=(None, None),
                               text_size=(popup.width, self.oButtonHeigth),
                               valign="middle",
                               halign="center")
            btn.bind(on_release=fktButttonSelect)
            scrollcontent.add_widget(btn)

        # finally, add a cancel button to return on the previous panel
        scrollview.add_widget(scrollcontent)
        self.oContent.add_widget(scrollview)
        self.oContent.add_widget(SettingSpacer())
        self.oButtonCancel = cMultiLineButton(text=ReplaceVars('$lvar(5009)'),
                                              size=(popup.width, dp(50)),
                                              size_hint=(0.9, None),
                                              halign='center',
                                              valign='middle')
        self.oButtonCancel.bind(on_release=popup.dismiss)
        self.oContent.add_widget(self.oButtonCancel)
Exemplo n.º 3
0
    def ExecuteActionForIn(self, oAction: cAction) -> eReturnCode:
        """
        WikiDoc:Doc
        WikiDoc:Context:ActionsDetails
        WikiDoc:Page:Actions-ForIn
        WikiDoc:TOCTitle:forin

        = ForIn =
        Loops through an array of custom vars

        <div style="overflow:auto; ">
        {| class="wikitable"
        ! align="left" | Attribute
        ! align="left" | Description
        |-
        |string
        |forin
        |-
        |varname
        |Variable name to loop through (without brackets)
        |-
        |level
        |the bracket level to use (from left), 1 = leftmost
        |-
        |actionname
        |multi line action / macro name to call for each var
        |-
        |breakvar
        |Break Var to exit the loop, set to 1 to exit the forin loop
        |}</div>
        A short example:
        <div style="overflow-x: auto;"><syntaxhighlight  lang="xml">
        <action name="loop through vars" string="forin" varname="myarray[]"  level="1" actionname="fkt dosomething"/>
        </syntaxhighlight></div>

        Given, you have the following var array

        myarray[1] = "Apple"
        myarray[2] = "Orange"
        myarray[3] = "Cherry"

        This will create the following pars for the first iteration

        Varname:
        $par(forin_value)    = "Apple"
        $par(forin_var)      = "myarray[1]"
        $par(forin_varcore)  = "myarray"
        $par(forin_index)    = "1"

        <div style="overflow-x: auto;"><syntaxhighlight  lang="xml">
        <action name="loop through vars" string="forin" varname="myarray[1]_subelement[]" dstvarname="elementname" level="2" actionname="fkt dosomething"/>
        </syntaxhighlight></div>

        Given, you have the following var array

        myarray[1]_sublement[1] = "Green Apple"
        myarray[1]_sublement[2] = "Red Apple"
        myarray[1]_sublement[3] = "Yellow Apple"
        myarray[2]_sublement[1] = "Green Orange"
        myarray[2]_sublement[2] = "Orange Orange"
        myarray[3]_sublement[1] = "Small Cherry"

        This will create the following subvars for the second iteration. Note, it will iterate only through the Apples, not through the oranges

        Varname:
        $par(forin_value)    = "Red Apple"
        $par(forin_var)      = "myarray[1]_sublement[2]"
        $par(forin_varcore)  = "myarray[1]_sublement"
        $par(forin_index)    = "2"

        WikiDoc:End
        """
        self.oEventDispatcher.LogAction(uTxt=u'ForIn', oAction=oAction)

        uVarName: str = ReplaceVars(oAction.dActionPars.get("varname", ""))
        iLevel: int = ToInt(oAction.dActionPars.get("level", "1"))
        uActionName: str = ReplaceVars(
            oAction.dActionPars.get("actionname", ""))
        uBreakVar: str = ReplaceVars(oAction.dActionPars.get("breakvar", ""))
        aActions: List[cAction] = []
        aVars: List[str] = Var_GetArray(uVarName=uVarName,
                                        iLevel=iLevel,
                                        bSort=True)

        SetVar(uVarName=uBreakVar, oVarValue="0")

        uVar: str
        uVarCore: str
        uVarIndex: str
        iPosStart: int
        iPosEnd: int

        for uVar in aVars:
            uVarCore = u""
            uVarIndex = u""
            iPosStart = Find_nth_Character(uVar, "[", iLevel)
            iPosEnd = Find_nth_Character(uVar, "]", iLevel)
            if iPosEnd > iPosStart:
                uVarCore = uVar[:iPosStart]
                uVarIndex = uVar[iPosStart + 1:iPosEnd]

            if uBreakVar == u'':
                self.oEventDispatcher.AddToSimpleActionList(
                    aActionList=aActions,
                    aActions=[{
                        'name': 'Call ForIn Action',
                        'string': 'call',
                        'actionname': uActionName,
                        "forin_value": GetVar(uVarName=uVar),
                        "forin_var": uVar,
                        "forin_varcore": uVarCore,
                        "forin_index": uVarIndex,
                    }])
            else:
                self.oEventDispatcher.AddToSimpleActionList(
                    aActionList=aActions,
                    aActions=[{
                        'name': 'Call ForIn Action',
                        'string': 'call',
                        'actionname': uActionName,
                        "forin_value": GetVar(uVarName=uVar),
                        "forin_var": uVar,
                        "forin_varcore": uVarCore,
                        "forin_index": uVarIndex,
                        "condition": "$var(" + uBreakVar + ")==0"
                    }])

        self.oEventDispatcher.ExecuteActionsNewQueue(aActions, None)
        return eReturnCode.Nothing
Exemplo n.º 4
0
    def ExecuteActionModifyVar(self, oAction: cAction) -> eReturnCode:
        """
        WikiDoc:Doc
        WikiDoc:Context:ActionsDetails
        WikiDoc:Page:Actions-ModifyVar
        WikiDoc:TOCTitle:modifyvar
        = modifyvar =
        Modifies an existing variable. This is an inplace modification, so the given variable will be changed: a=fkt(a). If you need something like a=fkt(b), you need to copy the variable using setvar prior using this functions.
        "Increase" and "decrease" works on  numeric variables only. "Invert" works on numeric (0/1) or on string variables (True/False).
        "Lowercase","Uppercase","Trim" works on string variables
        "Concatenate" , "Getpart", "Format" works on all variable types
        "Getlen" and "Find" are the only sub action, that will not modify the var, it will return the result in a different var
        "Load" and "Save" are options to create persistent variables. You can sav a variable value and reload the value at the next application start.
        Some note on "Getpart", which is to extract a part of string from a string. It follows python rules (eg.: string[start:end]) where start or end could be empty
        "Fromvar" converts a variable name into its variable value.
        "Exists" checks if the variable exist or if a function name with the variable name exists

        <div style="overflow:auto; ">
        {| class="wikitable"
        ! align="left" | Attribute
        ! align="left" | Description
        |-
        |string
        |modifyvar
        |-
        |varname
        |Variable to use/modify
        |-
        |parameter1
        |First parameter for operator
        |-
        |parameter2
        |Second parameter for operator
        |-
        |Operator
        |Operator for the command. Use one of the following keywords
        * "increase"
        * "decrease"
        * "multiply"
        * "divide"
        * "invert"
        * "lowercase"
        * "uppercase"
        * "trim"
        * "concatenate"
        * "getpart"
        * "format"
        * "totime"
        * "getlen"
        * "find"
        * "power"
        * "save"
        * "load"
        * "delete"
        * "round"
        * "fromvar"
        * "hex2int"
        * "hexstringtostring"
        * "stringtohexstring"
        * "loadfile"
        * "tovar"
        * "addtoarray"
        * "removefromarray"
        * "exists"
        |}</div>

        Remarks on some operators

        <div style="overflow:auto; ">
        {| class="wikitable"
        ! align="left" | Operator
        ! align="left" | Parameter1
        ! align="left" | Parameter2
        |-
        |increase
        |The delta value (like a=a+x)
        |Optional: The upper limit
        |-
        |decrease
        |The delta value (like a=a-x)
        |Optional: The lower limit
        |-
        |multiply
        |The Multiplier (like a=a*x)
        |
        |-
        |devide
        |The Devidor (like a=a/x)
        |
        |-
        |power
        |The power (like a=a^x)
        |
        |-
        |concatenate
        |The string / stringvar to add (like a=a+"mystring")
        |
        |-
        |getpart
        |The start position
        |The end position
        |-
        |fromvar (gets the variable content from a variable name given in a variable)
        |The context of the var
        |
        |-
        |delete either deletes a single var or an array if the var name ends with []
        |
        |
        |-
        |tovar (assigns a variable name to a new variable without variable replacement)
        |newvarname: the new var name, where the var name should be assigned to
        |
        |-
        |format
        |The format string, following the python string.format syntax
        e.g.: "(int)FFFF00{0:0>2x}"
        |
        |totime
        |The format string for the python datetime.datetime.strptime function
        e.g.: "%Y-%m-%dT%H:%M:%SZ"
        | Time offset (milliseconds of no unit given)
        |-
        |round
        |The rounding position (eg 0=round to int)
        |
        |-
        |getlen
        |the destination var for the length
        |
        |-
        |save
        |A prefix for the cookie name
        |
        |-
        |load
        |A prefix for the cookie name
        |The default value, if no save value is available
        |-
        |loadfile
        |The filename, from which the content should be loaded into the var
        |The default value, if no save value is available
        |-
        |addtoarray
        |The var value to be added
        |Boolean, if 1, than only add, if value is not already in array
        |-
        |removefromarray
        |The var value to be removed
        |
        |-
        |exist
        |The var name to return, if the var exists (0/1)
        |
        |}</div>

        A short example:
        <div style="overflow-x: auto;"><syntaxhighlight  lang="xml">
        <action name="" string="modifyvar" varname="DIMVALUE" operator="divide" parameter1="6.25"/>
        </syntaxhighlight></div>
        WikiDoc:End
        """

        uVarName: str = ReplaceVars(oAction.dActionPars.get("varname", ""))
        uParameter1: str = oAction.dActionPars.get("parameter1", "")
        uParameter2: str = oAction.dActionPars.get("parameter2", "")
        uOperator: str = ReplaceVars(oAction.dActionPars.get("operator", ""))
        bNoVarDetails: bool = False
        iLevel: int
        aVars: List[str]
        uLast: str
        uMax: str
        uOldVar: str
        uVarName: str
        aVars: List[str]
        uValue: str
        uNewVarName: str
        uTmp: str

        if uOperator == u'increase':
            Var_Increase(uVarName=uVarName,
                         uStep=ReplaceVars(uParameter1),
                         uMax=ReplaceVars(uParameter2))
        elif uOperator == u'decrease':
            Var_Decrease(uVarName=uVarName,
                         uStep=ReplaceVars(uParameter1),
                         uMin=ReplaceVars(uParameter2))
        elif uOperator == u'multiply':
            Var_Multiply(uVarName=uVarName, uFactor=ReplaceVars(uParameter1))
        elif uOperator == u'divide':
            Var_Divide(uVarName=uVarName, uDivisor=ReplaceVars(uParameter1))
        elif uOperator == u'power':
            Var_Power(uVarName=uVarName, uPower=ReplaceVars(uParameter1))
        elif uOperator == u'invert':
            Var_Invert(uVarName=uVarName)
        elif uOperator == u'delete':
            if uVarName.endswith(u'[]'):
                Var_DelArray(uVarName=uVarName)
            else:
                DelVar(uVarName=uVarName)
        elif uOperator == u'round':
            Var_Round(uVarName=uVarName, uPos=uParameter1)
        elif uOperator == u'lowercase':
            Var_LowerCase(uVarName=uVarName)
        elif uOperator == u'uppercase':
            Var_UpperCase(uVarName=uVarName)
        elif uOperator == u'trim':
            Var_Trim(uVarName=uVarName)
        elif uOperator == u'fromvar':
            uOldVar = GetVar(uVarName=uVarName)
            Var_FromVar(uVarName=uVarName, uContext=ReplaceVars(uParameter1))
            Logger.debug(u'FromVar: ' + uVarName + "=" +
                         GetVar(uVarName=uVarName) + u" [" + uOldVar + u"]")
        elif uOperator == u'tovar':
            uVarName = oAction.dActionPars.get("varname", "")
            Var_ToVar(uVarName=uVarName, uNewVarName=uParameter1)
            Logger.debug(u'ToVar: ' + uVarName + "=" + uParameter1)
        elif uOperator == u'concatenate':
            Var_Concatenate(uVarName=uVarName,
                            uAddVar=ReplaceVars(uParameter1))
        elif uOperator == u'getpart':
            Var_Part(uVarName=uVarName, uStart=uParameter1, uEnd=uParameter2)
        elif uOperator == u'getlen':
            Var_Len(uVarName=uVarName, uDestVar=uParameter1)
        elif uOperator == u'find':
            Var_Find(uVarName=uVarName,
                     uFindVar=uParameter1,
                     uDestVar=uParameter2)
        elif uOperator == u'format':
            Var_Format(uVarName=uVarName, uFormat=uParameter1)
        elif uOperator == u'hex2int':
            Var_Hex2Int(uVarName=uVarName)
        elif uOperator == u'hexstringtostring':
            Var_HexStringToString(uVarName=uVarName)
        elif uOperator == u'totime':
            Var_StringToTime(uVarName=uVarName,
                             uFormat=ReplaceVars(uParameter1),
                             uGap=ReplaceVars(uParameter2))
        elif uOperator == u'stringtohexstring':
            Var_StringToHexString(uVarName=uVarName)
        elif uOperator == u'load':
            Var_Load(uVarName=uVarName,
                     uDefault=ReplaceVars(uParameter1),
                     uPrefix=ReplaceVars(uParameter2))
        elif uOperator == u'save':
            Var_Save(uVarName=uVarName, uPrefix=ReplaceVars(uParameter1))
        elif uOperator == u'addtoarray':
            iLevel = uVarName.count('[')
            aVars = sorted(Var_GetArray(uVarName=uVarName, iLevel=iLevel))
            uValue = ReplaceVars(uParameter1)
            if uParameter2 == "1":
                for uTmp in aVars:
                    if GetVar(uVarName=uTmp) == uValue:
                        return eReturnCode.Nothing

            uMax = "1"
            if len(aVars):
                uLast = aVars[-1]
                uMax = uLast[uLast.rfind("[") + 1:][:-1]
                if ToFloat2(uMax):
                    uMax = str(ToInt(uMax) + 1)
                else:
                    Logger.warning(u'addtoarray:' + uVarName +
                                   " Array contains non numeric indices")

            uNewVarName = uVarName[:-2] + "[" + uMax + "]"
            SetVar(uVarName=uNewVarName, oVarValue=uValue)
            Logger.debug(u'addtoarray:' + uNewVarName + "=" + uValue)
        elif uOperator == u'removefromarray':
            iLevel = uVarName.count('[')
            aVars = sorted(Var_GetArray(uVarName=uVarName, iLevel=iLevel))
            uValue = ReplaceVars(uParameter1)
            for uTmp in aVars:
                if GetVar(uVarName=uTmp) == uValue:
                    DelVar(uVarName=uTmp)

        elif uOperator == u'loadfile':
            Var_LoadFile(uVarName=uVarName, uFileName=ReplaceVars(uParameter1))
            bNoVarDetails = True
        elif uOperator == u'exists':
            if ExistVar(
                    uVarName) or uVarName in Globals.oActions.dActionsCommands:
                SetVar(uParameter1, "1")
            else:
                SetVar(uParameter1, "0")
            bNoVarDetails = True
        else:
            LogError(uMsg=u'Action: ModifyVar: Wrong modifier:' + uOperator)
            return eReturnCode.Error
        if bNoVarDetails:
            self.oEventDispatcher.LogAction(uTxt=u'ModifyVar', oAction=oAction)
        else:
            self.oEventDispatcher.LogAction(uTxt=u'ModifyVar',
                                            oAction=oAction,
                                            uAddText="Result:" +
                                            GetVar(uVarName=uVarName))

        return eReturnCode.Nothing
Exemplo n.º 5
0
    def Create(self, oParent):

        del self.oDropDownButtons[:]
        try:
            if self.uCaption.endswith("[]"):
                aCaptions = self.uCaption.split(u':::')
                self.uCaption = aCaptions[0]
                aCaptions = aCaptions[1]
                self.aCaptions = Var_GetArray(aCaptions, 1)
                self.aCaptions = [
                    u"$var(" + item + ")" for item in self.aCaptions
                ]
            elif u':::' in self.uCaption:
                aCaptions = self.uCaption.split(u':::')
                self.uCaption = aCaptions[0]
                self.aCaptions = aCaptions[1:]
                self.aActionNames = ReplaceVars(self.uActionName).split(u':::')
                self.uActionName = u''
                super(cWidgetButton, self).SetCaption(self.uCaption)
            else:
                if self.aCaptions[0].startswith("$DIRLIST["):
                    oPath = cPath(self.aCaptions[0][9:-1])
                    self.aCaptions = oPath.GetFolderList()

            if len(self.aActionNames) == 1 and len(self.aCaptions) > 1:
                self.aActionNames = [
                    self.aActionNames[0] for x in range(len(self.aCaptions))
                ]

            if len(self.aActionNames) != len(self.aCaptions) and len(
                    self.aCaptions) > 0:
                LogError(
                    u'cWidgetDropDown: [%s] Captions do not match Actions: %s'
                    % (self.uName, self.uActionName))
                bRet = False
            else:
                for num in range(len(self.aCaptions)):
                    oBtn = cWidgetButton()
                    # we cant use the touchbutton object, as Buttonbehaviour not work on buttons on scolllayout
                    #oBtn.ClassName           = Button
                    oBtn.bIsDropButton = True
                    self.oXMLNode.set("caption", self.aCaptions[num])
                    self.oXMLNode.set("type", "BUTTON")
                    # self.oXMLNode.set("action", self.aActionNames[num])
                    self.oXMLNode.set("action", "NoAction")

                    if self.uAnchorName:
                        oTmpAnchor = self.oParentScreenPage.dWidgets.get(
                            self.uAnchorName)
                        oTmpAnchor.iWidth = self.iTmpAnchorWidth
                        oTmpAnchor.iHeight = self.iTmpAnchorHeight

                    oBtn.InitWidgetFromXml(self.oXMLNode,
                                           self.oParentScreenPage,
                                           self.uAnchorName)
                    # oBtn.SetCaption(self.aCaptions[num])
                    oBtn.iAnchorPosX = 0
                    oBtn.iAnchorPosY = 0
                    oBtn.iPosX = 0
                    oBtn.iPosY = 0
                    oBtn.uActionNameDoubleTap = u''
                    oBtn.uActionNameDownOnly = u''
                    oBtn.uActionNameUpOnly = u''
                    oBtn.uActionNameLongTap = u''
                    oBtn.iButtonNum = num

                    self.oDropDownButtons.append(oBtn)

            if self.oObjectDropDown is None:
                super(cWidgetDropDown, self).Create(oParent)

            if self.oObject is not None:
                self.oObjectDropDown = DropDown()
                #self.dismiss_on_select=True

                if self.bSorted:
                    self.oDropDownButtons = sorted(
                        self.oDropDownButtons,
                        key=lambda oDropDownButtons: ReplaceVars(
                            oDropDownButtons.uCaption))

                for oWidget in self.oDropDownButtons:
                    oWidget.Create(oParent)
                    oWidget.oObject.size = self.oObject.size
                    oWidget.oObject.text_size = self.oObject.text_size

                    if oWidget.bIcon and self.bIcon:
                        oWidget.oObject.font_size = self.oObject.font_size

                    if (not oWidget.bIcon) and (not self.bIcon):
                        oWidget.oObject.font_size = self.oObject.font_size

                    oWidget.uName = "*DROPDOWNBUTTON*" + oWidget.uName
                    oBtn = oWidget.oObject
                    oWidget.oParent.remove_widget(oBtn)
                    oBtn.size_hint_y = None
                    oBtn.unbind(on_q_release=oWidget.On_Button_Up)
                    oBtn.bind(on_q_release=self.DropDownSelect)
                    self.oObjectDropDown.add_widget(oBtn)
                self.oObject.bind(on_q_release=self.OpenDropDown)
                self.oObjectDropDown.bind(on_dismiss=self.CloseDropDown)
                return True
            return False
        except Exception as e:
            LogError("Can''t create Dropdown", e)
            return False
Exemplo n.º 6
0
    def ExecuteActionForIn(self, oAction):
        """
        WikiDoc:Doc
        WikiDoc:Context:ActionsDetails
        WikiDoc:Page:Actions-ForIn
        WikiDoc:TOCTitle:forin

        = ForIn =
        Loops through an array of custom vars

        <div style="overflow:auto; ">
        {| class="wikitable"
        ! align="left" | Attribute
        ! align="left" | Description
        |-
        |string
        |forin
        |-
        |varname
        |Variable name to loop through (without brackets)
        |-
        |dstvarname
        |DestVarName for each element
        |-
        |level
        |the bracket level to use (from left), 1 = leftmost
        |-
        |actionname
        |multi line action / macro name to call for each var
        |-
        |breakvar
        |Break Var to exit the loop, set to 1 to exit the forin loop
        |}</div>
        A short example:
        <div style="overflow-x: auto;"><syntaxhighlight  lang="xml">
        <action name="loop through vars" string="forin" varname="myarray[]" dstvarname="elementname" level="1" actionname="fkt dosomething"/>
        </syntaxhighlight></div>

        Given, you have the following var array

        myarray[1] = "Apple"
        myarray[2] = "Orange"
        myarray[3] = "Cherry"

        This will create the following subvars for the first iteration

        Varname:
        elementname_value    = "Apple"
        elementname_var      = "myarray[1]"
        elementname_varcore  = "myarray"
        elementname_index    = "1"

        <div style="overflow-x: auto;"><syntaxhighlight  lang="xml">
        <action name="loop through vars" string="forin" varname="myarray[1]_subelement[]" dstvarname="elementname" level="2" actionname="fkt dosomething"/>
        </syntaxhighlight></div>

        Given, you have the following var array

        myarray[1]_sublement[1] = "Green Apple"
        myarray[1]_sublement[2] = "Red Apple"
        myarray[1]_sublement[3] = "Yellow Apple"
        myarray[2]_sublement[1] = "Green Orange"
        myarray[2]_sublement[2] = "Orange Orange"
        myarray[3]_sublement[1] = "Small Cherry"

        This will create the following subvars for the second iteration. Note, it will iterate onlky through the Apples, not through the oranges

        Varname:
        elementname_value    = "Red Apple"
        elementname_var      = "myarray[1]_sublement[2]"
        elementname_varcore  = "myarray[1]_sublement"
        elementname_index    = "2"

        WikiDoc:End
        """
        self.oEvenDispatcher.LogAction(u'ForIn', oAction)

        uVarName = ReplaceVars(oAction.dActionPars.get("varname", ""))
        uDstVarName = ReplaceVars(oAction.dActionPars.get("dstvarname", ""))
        iLevel = ToInt(oAction.dActionPars.get("level", "1"))
        uActionName = ReplaceVars(oAction.dActionPars.get("actionname", ""))
        uBreakVar = ReplaceVars(
            oAction.dActionPars.get("breakvar", "ForInBreakVar"))

        self.oEvenDispatcher.bDoNext = True

        aActions = []

        aVars = sorted(Var_GetArray(uVarName=uVarName, iLevel=iLevel))

        SetVar(uVarName=uBreakVar, oVarValue="0")

        for uVar in aVars:
            uVarCore = u""
            uVarIndex = u""
            iPosStart = Find_nth_Character(uVar, "[", iLevel)
            iPosEnd = Find_nth_Character(uVar, "]", iLevel)
            if iPosEnd > iPosStart:
                uVarCore = uVar[:iPosStart]
                uVarIndex = uVar[iPosStart + 1:iPosEnd]

            self.oEvenDispatcher.AddToSimpleActionList(
                aActions, [{
                    'name': 'Set Var Value',
                    'string': 'setvar',
                    'varname': uDstVarName + "_value",
                    'varvalue': GetVar(uVarName=uVar)
                }, {
                    'name': 'Set Var Name',
                    'string': 'setvar',
                    'varname': uDstVarName + "_var",
                    'varvalue': uVar
                }, {
                    'name': 'Set Core Var Name',
                    'string': 'setvar',
                    'varname': uDstVarName + "_varcore",
                    'varvalue': uVarCore
                }, {
                    'name': 'Set Var Index',
                    'string': 'setvar',
                    'varname': uDstVarName + "_index",
                    'varvalue': uVarIndex
                }, {
                    'name': 'Call Action',
                    'string': 'call',
                    'actionname': uActionName
                }, {
                    'name': 'Exit ForIn if requested',
                    'string': 'goto',
                    'label': 'label_exitforinloop',
                    'condition': '$var(' + uBreakVar + ')!=0'
                }])

        self.oEvenDispatcher.AddToSimpleActionList(
            aActions, [{
                'string': 'noaction',
                'name': 'label_exitforinloop'
            }])
        self.oEvenDispatcher.ExecuteActionsNewQueue(aActions, None)
        return -2