def _up(self, pillow, path):
        data = self._document.get(path, asList=True)
        if data == None:
            return

        sel = PathHelper.getValue(self._document.selection, path + ".*._selection")
        if sel == None or sel == 0:
            return

        data[sel - 1], data[sel] = data[sel], data[sel - 1]
        self._throw(Editor.Out.FieldChanged, Editor.translatePath(self._document, path))
    def __edit(self, pillow, doc):
        if not doc or not self._document:
            return

        if not isinstance(doc, dict):
            try:
                import json

                doc = json.loads(doc)
            except Exception as e:
                print "JSON error " + unicode(e) + " in: " + doc
                return

        for k, v in doc.items():
            self._document.set(k, v)
            self._throw(Editor.Out.FieldChanged, Editor.translatePath(self._document, k))
    def __remove(self, pillow, path, isList=True):
        if not path or not self._document:
            # TODO: debug out
            return

        if isList:
            data = self._document.get(path, asList=True)
        else:
            data = self._document.get(path, asDict=True)

        if data == None:
            # TODO: debug out
            return

        sel = PathHelper.getValue(self._document.selection, path + ".*._selection")
        if sel != None:
            if not isList:
                if not sel in data:
                    return

                keys = sorted(data.keys())
                idx = keys.index(sel)

                if idx == len(keys) - 1:
                    idx -= 1
            else:
                if sel >= len(data):
                    return

            del data[sel]

            self._throw(Editor.Out.FieldChanged, Editor.translatePath(self._document, path))

            if isList and sel == len(data) and sel != 0:
                self._select(None, (path, sel - 1))

            if not isList:
                keys = sorted(data.keys())
                if idx >= 0 and idx < len(keys):
                    self._select(None, (path, keys[idx]))
    def __insert(self, pillow, path, isList=True):
        if not path or not self._document:
            return

        doc = None
        key = "__new__"

        if isinstance(path, tuple) or isinstance(path, list):
            path, doc = path
        elif isinstance(path, dict):
            cfg = path
            path = cfg.get("path", None)
            key = cfg.get("key", None)
            doc = cfg.get("value", None)

        try:
            if isList:
                data = self._document.get(path, asList=True)
            else:
                data = self._document.get(path, asDict=True)
        except Exception as e:
            return

        if data == None:
            if isList:
                data = []
            else:
                data = {}

            try:
                self._document.set(path, data)
            except Exception as e:
                return

        if not isList and key in data:
            return

        try:
            sel = PathHelper.getValue(self._document.selection, path + ".*._selection")
        except SelectionNotSpecified:
            sel = None

        if sel == None:
            if isList:
                sel = len(data)
            else:
                sel = key

        if isList:
            data.insert(sel, doc)
        else:
            data[key] = doc

        self._throw(Editor.Out.FieldChanged, Editor.translatePath(self._document, path))

        if isList:
            self._select(None, (path, sel))

        if not isList:
            sel = key
            self._select(None, (path, sel))

        self._throw(DocumentChanger.Out.RowInserted, (Editor.translatePath(self._document, path), sel))