def test_03_edit(self):
        global factory
        peers = ["EditDocument", "DocumentCache", "DocumentDatabase", "CouchDB"]

        for p in peers:
            factory.peer(p, "room01")

        CredentialsParty()

        valueDeferred = defer.Deferred()

        def valueCallback(value):
            if value == "Hello Jan":
                try:
                    valueDeferred.callback(value)
                except:
                    pass

        setRODeferred = defer.Deferred()

        def roCallback(readOnly):
            if not readOnly:
                try:
                    setRODeferred.callback(readOnly)
                except:
                    pass

        from wallaby.pf.peer.viewer import Viewer
        from wallaby.pf.peer.editor import Editor

        Viewer("room01", valueCallback, "text")
        editor = Editor("room01", path="text", setReadOnlyCallback=roCallback)

        House.initializeAll()
        Peer.initializeAll()
        yield sleep(0.1)

        from wallaby.pf.peer.editDocument import EditDocument

        room = House.get("room01")
        room.throw(EditDocument.In.LoadAndEdit, self._docId)

        yield setRODeferred
        editor.changeValue("Hello Jan")

        value = yield valueDeferred
        self.assertEqual(value, "Hello Jan")

        room.throw(EditDocument.In.Save, self._docId)

        from wallaby.pf.peer.database import Database

        docId = yield room.catchNow(Database.Out.DocumentSaved)
        self.assertEqual(docId, self._docId)

        doc = yield self._db.get(self._docId)
        self.assertEqual(doc["text"], "Hello Jan")

        House.destroyRoom("room01")
        House.destroyRoom("__CREDENTIALS__")
    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))