Return the next applet in cyclic order.

        If ``ofsApp=None`` then start cycling at the currently active
        applet. If ``ofsApp`` does not fit the selection criteria,
        then the cycling starts at the next applet in cyclic order
        that does.

        The returned applet is ``numSkip`` items in cyclic order away
        from the offset applet. If ``numSkip`` is positive traverse
        the applet list forwards, otherwise backwards.

        The method supports the following Boolean selection criteria:

        * ``skipInvisible``: ignore all invisible applets.
        * ``skipVisible``: ignore all visible applets.
        * ``skipMiniApplet``: ignore the mini applet applet.

        The ``ofsApp`` parameter can either be an instance of
        ``QtmacsApplet`` or a string denoting an applet ID. In the
        latter case the ``qteGetAppletHandle`` method is used to fetch
        the respective applet instance.

        |Args|

        * ``numSkip`` (**int**): number of applets to skip.
        * ``ofsApp`` (**QtmacsApplet**, **str**): applet from where to
          start counting.
        * ``skipInvisible`` (**bool**): whether or not to skip currently
          not shown applets.
        * ``skipVisible`` (**bool**): whether or not to skip currently
          shown applets.
        * ``skipMiniApplet`` (**bool**): whether or not to skip the mini
          applet.
        * ``windowObj`` (**QtmacsWindow**): the window to use when looking
          for applets. If **None**, then search in all windows.

        |Returns|

        * **QtmacsApplet**: either the next applet that fits the criteria,
          or **None** if no such applet exists.

        |Raises|

        * **QtmacsArgumentError** if at least one argument has an invalid type.

def qteNextApplet(self, numSkip: int=1, ofsApp: (QtmacsApplet, str)=None,
                      skipInvisible: bool=True, skipVisible: bool=False,
                      skipMiniApplet: bool=True,
                      windowObj: QtmacsWindow=None):
        """
        Return the next applet in cyclic order.

        If ``ofsApp=None`` then start cycling at the currently active
        applet. If ``ofsApp`` does not fit the selection criteria,
        then the cycling starts at the next applet in cyclic order
        that does.

        The returned applet is ``numSkip`` items in cyclic order away
        from the offset applet. If ``numSkip`` is positive traverse
        the applet list forwards, otherwise backwards.

        The method supports the following Boolean selection criteria:

        * ``skipInvisible``: ignore all invisible applets.
        * ``skipVisible``: ignore all visible applets.
        * ``skipMiniApplet``: ignore the mini applet applet.

        The ``ofsApp`` parameter can either be an instance of
        ``QtmacsApplet`` or a string denoting an applet ID. In the
        latter case the ``qteGetAppletHandle`` method is used to fetch
        the respective applet instance.

        |Args|

        * ``numSkip`` (**int**): number of applets to skip.
        * ``ofsApp`` (**QtmacsApplet**, **str**): applet from where to
          start counting.
        * ``skipInvisible`` (**bool**): whether or not to skip currently
          not shown applets.
        * ``skipVisible`` (**bool**): whether or not to skip currently
          shown applets.
        * ``skipMiniApplet`` (**bool**): whether or not to skip the mini
          applet.
        * ``windowObj`` (**QtmacsWindow**): the window to use when looking
          for applets. If **None**, then search in all windows.

        |Returns|

        * **QtmacsApplet**: either the next applet that fits the criteria,
          or **None** if no such applet exists.

        |Raises|

        * **QtmacsArgumentError** if at least one argument has an invalid type.
        """
        # If ``applet`` was specified by its ID (ie. a string) then
        # fetch the associated ``QtmacsApplet`` instance. If
        # ``applet`` is already an instance of ``QtmacsApplet`` then
        # use it directly.
        if isinstance(ofsApp, str):
            ofsApp = self.qteGetAppletHandle(ofsApp)

        # Return immediately if the applet list is empty.
        if len(self._qteAppletList) == 0:
            return None

        # Sanity check: if the user requests applets that are neither
        # visible nor invisible then return immediately because no
        # such applet can possibly exist.
        if skipVisible and skipInvisible:
            return None

        # Make a copy of the applet list.
        appList = list(self._qteAppletList)

        # Remove all invisible applets from the list if the
        # skipInvisible flag is set.
        if skipInvisible:
            appList = [app for app in appList if app.qteIsVisible()]

            # From the list of (now guaranteed visible) applets remove
            # all those that are not in the specified window.
            if windowObj is not None:
                appList = [app for app in appList
                           if app.qteParentWindow() == windowObj]

        # Remove all visible applets from the list if the
        # skipInvisible flag is set.
        if skipVisible:
            appList = [app for app in appList if not app.qteIsVisible()]

        # If the mini-buffer is to be skipped remove it (if a custom
        # mini applet even exists).
        if skipMiniApplet:
            if self._qteMiniApplet in appList:
                appList.remove(self._qteMiniApplet)

        # Return immediately if no applet satisfied all criteria.
        if len(appList) == 0:
            return None

        # If no offset applet was given use the currently active one.
        if ofsApp is None:
            ofsApp = self._qteActiveApplet

        if ofsApp in self._qteAppletList:
            # Determine if the offset applet is part of the pruned
            # list.
            if ofsApp in appList:
                # Yes: determine its index in the list.
                ofsIdx = appList.index(ofsApp)
            else:
                # No: traverse all applets until one is found that is
                # also part of the pruned list (start at ofsIdx). Then
                # determine its index in the list.
                ofsIdx = self._qteAppletList.index(ofsApp)
                glob_list = self._qteAppletList[ofsIdx:]
                glob_list += self._qteAppletList[:ofsIdx]

                # Compile the intersection between the global and pruned list.
                ofsIdx = [appList.index(_) for _ in glob_list if _ in appList]
                if len(ofsIdx) == 0:
                    msg = ('No match between global and local applet list'
                           ' --> Bug.')
                    self.qteLogger.error(msg, stack_info=True)
                    return None
                else:
                    # Pick the first match.
                    ofsIdx = ofsIdx[0]
        else:
            # The offset applet does not exist, eg. because the user
            # supplied a handle that does not point to an applet or
            # we are called from qteKillApplet to replace the just
            # removed (and active) applet.
            ofsIdx = 0

        # Compute the index of the next applet and wrap around the
        # list if necessary.
        ofsIdx = (ofsIdx + numSkip) % len(appList)

        # Return a handle to the applet that meets the specified
        # criteria.
        return appList[ofsIdx]