]> git.neil.brown.name Git - scribble.git/blobdiff - scribble.py
Fix breakage of "newline" code.
[scribble.git] / scribble.py
index d448006ad2ae045789145bf3d5619a2fd395e7c0..69a6844b0e8c6ae5c1553338e06454cd429ede47 100755 (executable)
@@ -29,6 +29,7 @@ import pygtk
 import gtk
 import os
 import pango
+import gobject
 
 ###########################################################
 # Writing recognistion code
@@ -172,6 +173,7 @@ def LoadDict(dict):
     dict.add('_', "S(4)3,5.S(4)5,3.S(4)3,5")
     dict.add("<left>", "S(4)5,3.S(3)3,5")
     dict.add("<right>","S(4)3,5.S(5)5,3")
+    dict.add("<newline>", "S(4)2,6")
 
 
 class DictSegment:
@@ -684,7 +686,7 @@ class ScribblePad:
         delete = gtk.Button("-") ; delete.show()
         clear = gtk.Button("C") ; clear.show()
         text = gtk.ToggleButton("T") ; text.show(); text.set_sensitive(False)
-        name = gtk.Label("1.2.3.4.5") ; name.show()
+        name = gtk.Button("1.2.3.4.5") ; name.show()
 
         bar.add(back)
         bar.add(fore)
@@ -706,8 +708,10 @@ class ScribblePad:
         delete.connect("clicked", self.delete)
         clear.connect("clicked", self.clear)
         text.connect("toggled", self.text_change)
+        name.connect("clicked", self.setname)
         self.name = name
         self.page = page
+        self.redbutton = red
         self.line = None
         self.lines = []
         self.hist = [] # undo history
@@ -762,6 +766,15 @@ class ScribblePad:
         LoadDict(self.dict)
         self.textstr = None
 
+
+        ctx = page.get_pango_context()
+        fd = ctx.get_font_description()
+        met = ctx.get_metrics(fd)
+        self.lineheight = (met.get_ascent() + met.get_descent()) / pango.SCALE
+        self.lineascent = met.get_ascent() / pango.SCALE
+
+        self.timeout = None
+
     def close_application(self, widget):
         self.save_page()
         gtk.main_quit()
@@ -782,19 +795,47 @@ class ScribblePad:
 
     def press(self, c, ev):
         # Start a new line
+        if self.timeout:
+            gobject.source_remove(self.timeout)
+            self.timeout = None
 
         self.line = [ self.colourname, [int(ev.x), int(ev.y)] ]
         return
     def release(self, c, ev):
         if self.line == None:
             return
+        if self.timeout == None:
+            self.timeout = gobject.timeout_add(20*1000, self.tick)
+            
         if len(self.line) == 2:
             # just set a cursor
             self.flush_text()
-            self.textpos = self.line[1]
-            self.texttoggle.set_sensitive(True)
-            c.window.draw_rectangle(self.colour_textmode, True, int(ev.x),int(ev.y),
-                                    2,2)
+            (lineno,index) = self.find_text(self.line[1])
+            if lineno == None:
+                # new text, 
+                self.textpos = self.line[1]
+                self.texttoggle.set_sensitive(True)
+                self.texttoggle.set_active(True)
+                c.window.draw_rectangle(self.colour_textmode, True, int(ev.x),int(ev.y),
+                                        2,2)
+                self.line = None
+            else:
+                # clicked inside an old text.
+                # shuffle it to the top, open it, edit.
+                self.texttoggle.set_sensitive(True)
+                self.texttoggle.set_active(True)
+                ln = self.lines[lineno]
+                self.lines = self.lines[:lineno] + self.lines[lineno+1:]
+                self.textpos = ln[1]
+                self.textstr = ln[2]
+                if ln[0] == "red":
+                    self.colour = self.colour_red
+                    self.redbutton.set_active(True)
+                else:
+                    self.colour = self.colour_black
+                    self.redbutton.set_active(False)
+                self.textcurs = index + 1
+                self.redraw()
             self.line = None
             return
         if self.texttoggle.get_active():
@@ -829,6 +870,33 @@ class ScribblePad:
             self.line.append([x,y])
         return
 
+    def tick(self):
+        # nothing for 20 seconds, flush the page
+        self.save_page()
+        gobject.source_remove(self.timeout)
+        self.timeout = None
+
+    def find_text(self, pos):
+        x = pos[0]; y = pos[1]
+        for i in range(0, len(self.lines)):
+            p = self.lines[i]
+            if type(p[2]) != str:
+                continue
+            y = pos[1] + self.lineascent
+            if x >= p[1][0] and y >= p[1][1] and y < p[1][1] + self.lineheight:
+                # could be this line - check more precisely
+                layout = self.page.create_pango_layout(p[2])
+                (ink, log) = layout.get_pixel_extents()
+                (ex,ey,ew,eh) = log
+                if x < p[1][0] + ex or x > p[1][0] + ex + ew  or \
+                   y < p[1][1] + ey or \
+                   y > p[1][1] + ey + self.lineheight :
+                    continue
+                # OK, it is in this one.  Find out where.
+                (index, gr) = layout.xy_to_index((x - p[1][0] - ex) * pango.SCALE,
+                                                 (y - p[1][1] - ey - self.lineheight) * pango.SCALE)
+                return (i, index)
+        return (None, None)
     def flush_text(self):
         if self.textstr == None:
             return
@@ -838,12 +906,11 @@ class ScribblePad:
         l = [self.colourname, self.textpos, self.textstr]
         self.lines.append(l)
         self.textstr = None
+        self.texttoggle.set_active(False)
 
     def draw_text(self, pos, colour, str, cursor = None):
         layout = self.page.create_pango_layout(str)
-        ctx = self.page.get_pango_context()
-        ascent = ctx.get_metrics(ctx.get_font_description()).get_ascent()
-        self.page.window.draw_layout(colour, pos[0], pos[1] - ascent/pango.SCALE,
+        self.page.window.draw_layout(colour, pos[0], pos[1] - self.lineascent,
                                      layout)
         if cursor != None:
             (strong,weak) = layout.get_cursor_pos(cursor)
@@ -866,6 +933,15 @@ class ScribblePad:
         elif sym == "<right>":
             if self.textcurs < len(self.textstr):
                 self.textcurs += 1
+        elif sym == "<newline>":
+            tail = self.textstr[self.textcurs:]
+            self.textstr = self.textstr[:self.textcurs]
+            self.flush_text()
+            self.texttoggle.set_active(True)
+            self.textcurs = len(tail)
+            self.textstr = tail
+            self.textpos = [ self.textpos[0], self.textpos[1] +
+                             self.lineheight ]
         else:
             self.textstr = self.textstr[0:self.textcurs] + sym + \
                            self.textstr[self.textcurs:]
@@ -898,7 +974,7 @@ class ScribblePad:
     def refresh(self, area, ev):
         self.redraw()
     def redraw(self):
-        self.name.set_text(self.names[self.pagenum])
+        self.name.set_label(self.names[self.pagenum])
         self.page.window.draw_rectangle(self.bg, True, 0, 0,
                                         480,640)
         for l in self.lines:
@@ -915,7 +991,7 @@ class ScribblePad:
             if type(l[2]) == str:
                 self.draw_text(st, col, l[2])
 
-        if self.textstr:
+        if self.textstr != None:
             self.draw_text(self.textpos, self.colour, self.textstr,
                            self.textcurs)
 
@@ -945,6 +1021,10 @@ class ScribblePad:
         else:
             self.colour = self.colour_black
             self.colourname = "black"
+        if self.textstr:
+            self.draw_text(self.textpos, self.colour, self.textstr,
+                           self.textcurs)
+            
         return
     def text_change(self,t):
         self.flush_text()
@@ -965,11 +1045,20 @@ class ScribblePad:
         # New name is either
         #  - take last number and increment it
         #  - add .1
+        self.flush_text()
         if len(self.lines) == 0:
             # don't add after a blank page
             return
         self.save_page()
-        newname = self.names[self.pagenum]
+        newname = self.choose_unique(self.names[self.pagenum])
+
+        self.names = self.names[0:self.pagenum+1] + [ newname ] + \
+                     self.names[self.pagenum+1:]
+        self.pagenum += 1;
+        self.lines = []
+        self.redraw()
+        return
+    def choose_unique(self, newname):
         while newname in self.pages:
             new2 = inc_name(newname)
             if new2 not in self.pages:
@@ -978,14 +1067,9 @@ class ScribblePad:
                 newname = newname + ".1"
             else:
                 newname = newname + ".0.1"
-
-        self.names = self.names[0:self.pagenum+1] + [ newname ] + \
-                     self.names[self.pagenum+1:]
-        self.pagenum += 1;
-        self.lines = []
-        self.redraw()
-        return
+        return newname
     def delete(self,b):
+        self.flush_text()
         if len(self.names) <= 1:
             return
         if len(self.lines) > 0:
@@ -1001,6 +1085,27 @@ class ScribblePad:
         self.redraw()
 
         return
+    def rename(self, newname):
+        # Rename current page and rename the file
+        # Maybe we should resort the name list, but then we need to update
+        # pagenum which is awkward.
+        if self.names[self.pagenum] == newname:
+            return
+        newname = self.choose_unique(newname)
+        oldpath = self.page_dir + "/" + self.names[self.pagenum]
+        newpath = self.page_dir + "/" + newname
+        try :
+            os.rename(oldpath, newpath)
+            self.names[self.pagenum] = newname
+            self.name.set_label(self.names[self.pagenum])
+        except:
+            pass
+
+    def setname(self,b):
+        if self.textstr:
+            if len(self.textstr) > 0:
+                self.rename(self.textstr)
+                
     def clear(self,b):
         while len(self.lines) > 0:
             self.hist.append(self.lines.pop())