changeset 815:d7f1f868eb6c

toplevel window pos is saved in the graph. Patch conflicts no longer break as hard, but they don't exactly reset themselves right yet eiher Ignore-this: 56f96fd0b1a8602abc4e41851685794c
author drewp@bigasterisk.com
date Sat, 20 Oct 2012 21:52:10 +0000
parents 1ae8e6b287e3
children cf19fd45a40e
files bin/keyboardcomposer bin/rdfdb light9/rdfdb/syncedgraph.py light9/rdfdb/web/index.xhtml light9/uihelpers.py
diffstat 5 files changed, 61 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/bin/keyboardcomposer	Sun Sep 30 07:11:49 2012 +0000
+++ b/bin/keyboardcomposer	Sat Oct 20 21:52:10 2012 +0000
@@ -549,11 +549,10 @@
     root = Tk()
     initTkdnd(root.tk, 'tkdnd/trunk/')
 
-    # this has yet to be moved into the session graph
+    session = clientsession.getUri('keyboardcomposer', opts)
+
     tl = toplevelat("Keyboard Composer - %s" % opts.session,
-                    existingtoplevel=root)
-
-    session = clientsession.getUri('keyboardcomposer', opts)
+                    existingtoplevel=root, graph=graph, session=session)
 
     kc = KeyboardComposer(tl, graph, session,
                           hw_sliders=not opts.no_sliders)
--- a/bin/rdfdb	Sun Sep 30 07:11:49 2012 +0000
+++ b/bin/rdfdb	Sat Oct 20 21:52:10 2012 +0000
@@ -16,7 +16,12 @@
 A caller can submit a patch which we'll persist and broadcast to every
 other client.
 
-Global data undo should probably happen within this service.
+Global data undo should probably happen within this service. Some
+operations should not support undo, such as updating the default
+position of a window. How will we separate those? A blacklist of
+subj+pred pairs that don't save undo? Or just save the updates like
+everything else, but when you press undo, there's a way to tell which
+updates *should* be part of your app's undo system?
 
 Maybe some subgraphs are for transient data (e.g. current timecode,
 mouse position in curvecalc) that only some listeners want to hear about.
--- a/light9/rdfdb/syncedgraph.py	Sun Sep 30 07:11:49 2012 +0000
+++ b/light9/rdfdb/syncedgraph.py	Sat Oct 20 21:52:10 2012 +0000
@@ -1,6 +1,6 @@
 from rdflib import ConjunctiveGraph, RDFS, RDF, Graph
 import logging, cyclone.httpclient, traceback, urllib
-from twisted.internet import reactor
+from twisted.internet import reactor, defer
 log = logging.getLogger('syncedgraph')
 from light9.rdfdb.patch import Patch, ALLSTMTS
 from light9.rdfdb.rdflibpatch import patchQuads
@@ -109,8 +109,10 @@
         self._currentSendPatchRequest = None
 
     def sendPatch(self, p):
-        self._patchesToSend.append(p)
+        sendResult = defer.Deferred()
+        self._patchesToSend.append((p, sendResult))
         self._continueSending()
+        return sendResult
 
     def _continueSending(self):
         if not self._patchesToSend or self._currentSendPatchRequest:
@@ -129,14 +131,15 @@
                 for q in p.addQuads: print q
                 print "----"
             else:
-                p = self._patchesToSend.pop(0)
+                p, sendResult = self._patchesToSend.pop(0)
         else:
-            p = self._patchesToSend.pop(0)
+            p, sendResult = self._patchesToSend.pop(0)
             
         self._currentSendPatchRequest = sendPatch(
             self.target, p, senderUpdateUri=self.myUpdateResource)
         self._currentSendPatchRequest.addCallbacks(self._sendPatchDone,
                                                    self._sendPatchErr)
+        self._currentSendPatchRequest.chainDeferred(sendResult)
 
     def _sendPatchDone(self, result):
         self._currentSendPatchRequest = None
--- a/light9/rdfdb/web/index.xhtml	Sun Sep 30 07:11:49 2012 +0000
+++ b/light9/rdfdb/web/index.xhtml	Sat Oct 20 21:52:10 2012 +0000
@@ -28,6 +28,13 @@
       // <![CDATA[
       $(function(){
 
+          function collapseCuries(s) {
+              return s
+                  .replace(/<http:\/\/www.w3.org\/2001\/XMLSchema#/g, function (match, short) { return "xsd:"+short; })
+                  .replace(/<http:\/\/light9.bigasterisk.com\/(.*?)>/g, function (match, short) { return "light9:"+short; })
+                  .replace(/<http:\/\/light9.bigasterisk.com\/show\/dance2012\/sessions\/(.*?)>/g, function (match, short) { return "kcsession:"+short });
+          }
+
           function onMessage(d) {
               if (d.clients !== undefined) {
                   $("#clients").empty().text(JSON.stringify(d.clients));
@@ -36,8 +43,8 @@
                   $("#patches").prepend(
                       $("<fieldset>").addClass("patch")
                           .append($("<legend>").text("Patch"))
-                          .append($("<div>").addClass("deletes").text(d.patch.deletes))
-                          .append($("<div>").addClass("adds").text(d.patch.adds))
+                          .append($("<div>").addClass("deletes").text(collapseCuries(d.patch.deletes)))
+                          .append($("<div>").addClass("adds").text(collapseCuries(d.patch.adds)))
                   );
               }
 
--- a/light9/uihelpers.py	Sun Sep 30 07:11:49 2012 +0000
+++ b/light9/uihelpers.py	Sat Oct 20 21:52:10 2012 +0000
@@ -1,9 +1,10 @@
 """all the tiny tk helper functions"""
 
 from __future__ import nested_scopes
-from Tkinter import *
-from Tix import *
-from types import StringType
+#from Tkinter import Button
+from rdflib import Literal
+from Tix import Button, Toplevel, Tk, IntVar, Entry, DoubleVar
+from light9.namespaces import L9
 
 windowlocations = {
     'sub' : '425x738+00+00',
@@ -32,21 +33,45 @@
         # it's ok if there's no saved geometry
         pass
 
-def toplevelat(name, existingtoplevel=None):
+def toplevelat(name, existingtoplevel=None, graph=None, session=None):
     tl = existingtoplevel or Toplevel()
     tl.title(name)
 
-    try:
-        f=open(".light9-window-geometry-%s" % name.replace(' ','_'))
-        windowlocations[name]=f.read() # file has no newline
-    except:
-        # it's ok if there's no saved geometry
-        pass
+    lastSaved = [None]
+    setOnce = [False]
+    def setPosFromGraphOnce():
+        """
+        the graph is probably initially empty, but as soon as it gives
+        us one window position, we stop reading them
+        """
+        if setOnce[0]:
+            return
+        geo = graph.value(session, L9.windowGeometry)
+
+        if geo is not None and geo != lastSaved[0]:
+            setOnce[0] = True
+            tl.geometry(geo)
+            lastSaved[0] = geo
+
+    def savePos():
+        geo = tl.geometry()
+        # todo: need a way to filter out the startup window sizes that
+        # weren't set by the user
+        if geo.startswith("1x1") or geo.startswith(("378x85", "378x86")):
+            return
+        if geo == lastSaved[0]:
+            return
+        lastSaved[0] = geo
+        graph.patchObject(session, session, L9.windowGeometry, Literal(geo))
+
+    if graph is not None and session is not None:
+        graph.addHandler(setPosFromGraphOnce)
 
     if name in windowlocations:
         tl.geometry(positionOnCurrentDesktop(windowlocations[name]))
 
-    tl._toplevelat_funcid = tl.bind("<Configure>",lambda ev,tl=tl,name=name: toplevel_savegeometry(tl,name))
+    if graph is not None:
+        tl._toplevelat_funcid = tl.bind("<Configure>",lambda ev,tl=tl,name=name: savePos())
 
     return tl