]> git.donarmstrong.com Git - lilypond.git/commitdiff
*** empty log message ***
authorhanwen <hanwen>
Thu, 21 Jul 2005 13:50:36 +0000 (13:50 +0000)
committerhanwen <hanwen>
Thu, 21 Jul 2005 13:50:36 +0000 (13:50 +0000)
ChangeLog
ikebana.py
music.py
notation.py
notationcanvas.py

index 0cdb5ae2159166dd927ba1d780f76b1ab9dca22b..e6a21fd68f1644870fc80c4cd175ad3181d947af 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-07-20  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+
+       * notationcanvas.py (Notation_toolbar.__init__): new class
+       Notation_toolbar: add a row of buttons, flash button when pressed.
+
+2005-07-15  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+
+       * notation.py (talk_to_lilypond): send off lilypond input
+
 2005-07-13  Jan Nieuwenhuizen  <janneke@gnu.org>
 
        * ikebana/notationcanvas.py (Notation_canvas.__init__): White
index 84cffaf54c5e81f9d6c20b1989d4948f7f3380ea..bc16b712f6919e9d4ccf179f30cfcb1d5096014e 100644 (file)
@@ -32,7 +32,21 @@ class NotationApplication:
 
         canvas = self.notation_canvas_controller.canvas
         canvas.show ()
-        win.add (canvas)
+
+        tb_type = notationcanvas.Notation_toolbar 
+        toolbar = tb_type (self.notation_canvas_controller.notation,
+                           self.notation_canvas_controller.check_update
+                           )
+
+        canvas.connect ("key-press-event", toolbar.keypress_callback)
+
+        vbox = gtk.VBox ()
+        vbox.pack_start (canvas, expand=True)
+        vbox.pack_start (toolbar, expand=False)
+        vbox.show ()
+        
+        win.add (vbox)
+        toolbar.show ()
         win.show()
         
         return win
index e0c7477148bf082902e275e160ec7f8a74a5a84d..5fd96f38c36e05775968c8bd0ade63aa10b73d2f 100644 (file)
--- a/music.py
+++ b/music.py
@@ -29,8 +29,15 @@ class Duration:
 
        def length (self):
                dot_fact = ((1 << (1 + self.dots))-1.0)/ (1 << self.dots)
-               
-               return 1.0/(1 << self.duration_log) * dot_fact * self.factor[0]/self.factor[1]
+
+               log = abs (self.duration_log)
+               dur = 1 << log
+               if self.duration_log < 0:
+                       base = 1.0 * dur
+               else:
+                       base = 1.0 / dur
+
+               return base * dot_fact * self.factor[0]/self.factor[1]
        
 class Pitch:
        def __init__ (self):
@@ -110,6 +117,7 @@ class Music_document:
        def __init__ (self):
                self.music = test_expr ()
                self.tag_dict = {}
+               self.touched = True
                
        def recompute (self):
                self.tag_dict = {}
index 84b306247e6df9670ba4876884343fc30c16b73d..a010b57d4274afd4da78d4d3bb4cc27e9d0d7b17 100644 (file)
@@ -8,8 +8,28 @@ import music
 import pango
 import math
 
+
+copy_lilypond_input = 1
+time_sig = (4, 4)
+measure_length = (1.0 * time_sig[0]) / time_sig[1]
+scale = "'((0 . 0) (1 . 0) (2 . -2) (3 . 0) (4 . 0) (5 . -2) (6 . -2))"
+clefsetting = """
+      (context-spec-music
+       (make-property-set 'clefGlyph "clefs.C") 'Staff)
+      (context-spec-music
+       (make-property-set 'clefPosition 0) 'Staff)
+      (context-spec-music
+       (make-property-set 'middleCPosition 0) 'Staff)
+"""
+
+lilypond_input_log_file = open ("input.log", 'w')
+
 def talk_to_lilypond (expression_str):
     """Send a LISP expression to LilyPond, wait for return value."""
+    if copy_lilypond_input:
+        lilypond_input_log_file.write (expression_str)
+        lilypond_input_log_file.flush ()
+    
     sock = socket.socket (socket.AF_INET)
     address = ("localhost", 2904)
     sock.connect (address)
@@ -29,9 +49,38 @@ def talk_to_lilypond (expression_str):
 
 def set_measure_number (str, num):
     return """(make-music 'SequentialMusic 'elements (list
+      (context-spec-music
+       (make-property-set 'timeSignatureFraction (cons %d %d)) 'Score)
+      (context-spec-music
+       (make-property-set 'measureLength (ly:make-moment %d %d)) 'Score)
+      (context-spec-music
+       (make-property-set 'beatLength (ly:make-moment 1 %d)) 'Score)
       (context-spec-music
        (make-property-set 'currentBarNumber %d) 'Score)
-    %s))""" % (num,str)
+      (context-spec-music
+       (make-music 'EventChord
+        'elements
+        (list
+         (make-music 'KeyChangeEvent
+          'pitch-alist
+          %s)
+         ))
+       'Staff)
+       
+
+    %s))""" % (time_sig[0], time_sig[1], time_sig[0],
+               time_sig[1], time_sig[1], num, scale, str)
+
+def render_score (filename, ly):
+    print ly
+    str =  '''
+myNotes = %s
+\\score  { \myNotes }
+''' % ly
+    open (filename, 'w').write (str)
+    base = os.path.splitext (filename)[0] + '.ps'
+    os.system ('(lilypond %s && gv %s)&  ' % (filename, base))
+    
 
 class Lilypond_socket_parser:
     """Maintain state of reading multi-line lilypond output for socket transport."""
@@ -63,12 +112,13 @@ class Lilypond_socket_parser:
             return
         elif fields[0] == 'cause':
             self.cause_tag = string.atoi (fields[1])
-            self.name = fields[2]
+            self.name = fields[2][1:-1]
            self.bbox = tuple (map (string.atof, fields[3:]))
             return
 
         return self.interpret_socket_line (offset, self.cause_tag,
-                                          self.bbox, fields)
+                                          self.bbox, self.name,
+                                           fields)
 
 class Notation_controller:
     """Couple Notation and the music model. Stub for now. """
@@ -80,8 +130,9 @@ class Notation_controller:
         self.start_moment = 0.0
         self.stop_moment = 3.0
 
-    def interpret_line (self, offset, cause, bbox, fields):
+    def interpret_line (self, offset, cause, bbox, name, fields):
        notation_item = self.notation.add_item (offset, cause, bbox, fields)
+        notation_item.name = name
     
     def update_notation(self):
        doc = self.document
@@ -93,7 +144,6 @@ class Notation_controller:
                ok = (x.start >= self.start_moment and
                       x.start +x.length() <= self.stop_moment)
                return ok
-
         
        str = expr.lisp_sub_expression (sub)
         str = set_measure_number (str, int (self.start_moment) + 1)
@@ -101,13 +151,21 @@ class Notation_controller:
         self.parse_socket_file (str)
 
     def ensure_visible (self, when):
-        self.start_moment = max (math.floor (when - 1.0), 0.0)
-        self.stop_moment = self.start_moment + 3.0
-       
+        new_start =  max (math.floor (when - measure_length), 0.0)
+        new_stop = new_start + 3 * measure_length
+
+        if new_start <> self.start_moment or new_stop <> self.stop_moment:
+            self.document.touched = True
+            
+        self.start_moment = new_start
+        self.stop_moment = new_stop
+
     def parse_socket_file (self, str):
         self.notation.clear ()
         lines = string.split (str, '\n')
         self.parse_lines (lines)
+        self.notation.touched = True
+        self.document.touched = False
         
     def parse_lines (self, lines):
         for l in lines:
@@ -120,6 +178,7 @@ class Notation_item:
         self.bbox = None
         self.offset = (0,0)
         self.tag = None
+        self.name = ''
         self.args = []
        self.canvas_item = None
        self.music_expression = None
@@ -172,6 +231,7 @@ class Notation_item:
         coords = self.args[2:]
         w = canvas.root ().add (type,
                                 fill_color = 'black',
+                                outline_color = 'black',
                                 width_units = blot,
                                 points = coords)
 
@@ -184,30 +244,26 @@ class Notation_item:
         magnification = 0.5
 
 #ugh: how to get pango_descr_from_string() in pygtk?
-
-       (fam,rest) = tuple (string.split (descr, ','))
+       
+       if descr.find (',') == -1:
+            (fam,rest) = tuple (string.split (descr, ' '))
+        else:
+            (fam,rest) = tuple (string.split (descr, ','))
         size = string.atof (rest)
         w = canvas.root().add (type,
                                fill_color = 'black',
                                family_set = True,
                                family = fam,
-                               anchor = gtk.ANCHOR_WEST,
-                               y_offset = 0.15,
-                               size_points = size  * canvas.pixel_scale * 0.75 * magnification,
+                               anchor = gtk.ANCHOR_SOUTH_WEST,
+                               y_offset = 0.75,
+                               size_points = size  * canvas.pixel_scale * 0.87  * magnification,
                                text = str)
         return w
         
     def create_canvas_item (self, canvas):
-       dispatch_table = {'draw_round_box' : Notation_item.create_round_box_canvas_item,
-                         'drawline': Notation_item.create_line_canvas_item,
-                         'glyphshow': Notation_item.create_glyph_item,
-                          'polygon': Notation_item.create_polygon_item,
-                          'utf-8' : Notation_item.create_text_item,
-                         }
-
        citem = None
        try:
-           method = dispatch_table[self.tag]
+           method = Notation_item.dispatch_table[self.tag]
            citem = method (self, canvas)
            citem.move (*self.offset)
            citem.notation_item = self
@@ -217,6 +273,13 @@ class Notation_item:
            print 'no such key', self.tag
            
        return citem
+
+    dispatch_table = {'draw_round_box' : create_round_box_canvas_item,
+                       'drawline': create_line_canvas_item,
+                       'glyphshow':create_glyph_item,
+                       'polygon': create_polygon_item,
+                       'utf-8' : create_text_item,
+                       }
            
 class Notation:
     """A complete line/system/page of LilyPond output. Consists of a
@@ -225,7 +288,9 @@ class Notation:
     def __init__ (self, controller):
         self.items = []
        self.notation_controller = controller
-
+        self.touched = True
+        self.cursor_touched = True
+        
         toplevel = controller.document.music
         self.music_cursor = toplevel.find_first (lambda x: x.name()== "NoteEvent") 
         
@@ -245,11 +310,11 @@ class Notation:
            item.bbox = bbox
            
            self.items.append (item)
-
-    
+            return item
+        
     def clear(self):
         self.items = [] 
-       
+            
     def paint_on_canvas (self,  canvas):
         for w in  canvas.root().item_list:
             if w.notation_item:
@@ -260,6 +325,11 @@ class Notation:
 
         canvas.set_cursor_to_music (self.music_cursor)
 
+    def set_cursor (self, music_expr):
+        self.music_cursor = music_expr
+        self.cursor_touched = True
+        self.ensure_cursor_visible ()
+        
     def cursor_move (self, dir):
         mus = self.music_cursor
         if mus.parent.name() == 'EventChord':
@@ -267,7 +337,7 @@ class Notation:
         
         mus = mus.parent.get_neighbor (mus, dir)
         mus = mus.find_first (lambda x: x.name() in ('NoteEvent', 'RestEvent'))
-        self.music_cursor = mus
+        self.set_cursor (mus)
         
     def insert_at_cursor (self, music, dir):
         mus = self.music_cursor
@@ -275,21 +345,31 @@ class Notation:
             mus = mus.parent
 
        mus.parent.insert_around (mus, music, dir)
+        self.touch_document()
+
+    def touch_document (self):
+        self.get_document ().touched = True
 
+    def check_update (self):
+        if self.get_document().touched:
+            self.notation_controller.update_notation ()
+        
     def backspace (self):
         mus = self.music_cursor
-        if mus.parent.name() == 'EventChord':
+        if mus.parent.name() == 'EventChord' and len (mus.parent.elements) <= 1:
             mus = mus.parent
 
         neighbor = mus.parent.get_neighbor (mus, -1)
         mus.parent.delete_element (neighbor)
-
+        self.touch_document ()
     def change_octave (self, dir):
         if self.music_cursor.name() == 'NoteEvent':
             p = self.music_cursor.pitch
             p.octave += dir 
+        self.touch_document ()
 
-    def change_step (self, step):
+    def set_step (self, step):
+        self.ensure_note ()
         if self.music_cursor.name() == 'NoteEvent':
 
             # relative mode.
@@ -306,6 +386,57 @@ class Notation:
                     p1.octave += 1
                     
             self.music_cursor.pitch = p1
+            self.touch_document ()
+
+        else:
+            print 'not a NoteEvent'
+
+    def add_step (self, step):
+        self.ensure_note ()
+        if self.music_cursor.name() == 'NoteEvent':
+
+            # relative mode.
+            p = self.music_cursor.pitch
+            p1 = p.copy()
+            p1.step = step
+            
+            orig_steps = p.steps ()
+            new_steps = p1.steps ()
+            diff = new_steps - orig_steps
+            if diff >= 4:
+                    p1.octave -= 1
+            elif diff <= -4:
+                    p1.octave += 1
+
+            new_ev = music.NoteEvent()
+            new_ev.pitch = p1
+            new_ev.duration = self.music_cursor.duration.copy()
+
+            self.music_cursor.parent.insert_around (self.music_cursor,
+                                                    new_ev, 1)
+            self.music_cursor = new_ev
+            self.touch_document ()
+        else:
+            print 'not a NoteEvent'
+
+    def change_step (self, dstep):
+        self.ensure_note ()
+        if self.music_cursor.name() == 'NoteEvent':
+
+            # relative mode.
+            p = self.music_cursor.pitch
+            p1 = p.copy()
+            p1.step += dstep
+
+            if p1.step > 6:
+                p1.step -= 7
+                p1.octave += 1
+            elif p1.step < 0:
+                p1.step += 7
+                p1.octave -= 1
+                
+            self.music_cursor.pitch = p1
+            self.touch_document ()
 
         else:
             print 'not a NoteEvent'
@@ -319,7 +450,9 @@ class Notation:
             dl += dir
             if dl <= 6 and dl >= -3:
                 dur.duration_log = dl
-            
+                
+            self.touch_document ()
+
 
     def ensure_note (self):
         if self.music_cursor.name() == 'RestEvent':
@@ -328,6 +461,7 @@ class Notation:
             m.parent.insert_around (None, note, 1)
             m.parent.delete_element (m)
             self.music_cursor = note
+            self.touch_document ()
             
     def ensure_rest (self):
         if self.music_cursor.name() == 'NoteEvent':
@@ -336,6 +470,7 @@ class Notation:
             m.parent.insert_around (None, rest, 1)
             m.parent.delete_element (m)
             self.music_cursor = rest  
+            self.touch_document ()
             
     def change_dots (self):
         if self.music_cursor.name() == 'NoteEvent':
@@ -344,6 +479,7 @@ class Notation:
                 p.dots = 0
             elif p.dots == 0:
                 p.dots = 1
+            self.touch_document ()
             
     def ensure_cursor_visible(self):
         self.notation_controller.document.recompute()
@@ -356,8 +492,35 @@ class Notation:
             new_alt = p.alteration + dir
             if abs (new_alt) <= 4: 
                 p.alteration = new_alt
+            self.touch_document ()
 
     def print_score(self):
         doc = self.notation_controller.document
         ly = doc.music.ly_expression()
-        print ly
+        render_score('score.ly', ly) 
+
+    def add_note (self):
+        if self.music_cursor.name () == 'NoteEvent':
+            note = music.NoteEvent ()
+            note.pitch = self.music_cursor.pitch.copy()
+            note.duration = self.music_cursor.duration.copy()
+            
+            ch = music.EventChord ()
+            ch.insert_around (None, note, 0)
+            
+            self.insert_at_cursor (ch, 1)
+            self.cursor_move (1)
+            self.touch_document ()
+
+        elif self.music_cursor.name () == 'RestEvent':
+            rest = music.RestEvent ()
+            rest.duration = self.music_cursor.duration.copy()
+            
+            ch = music.EventChord ()
+            ch.insert_around (None, rest, 0)
+            
+            self.insert_at_cursor (ch, 1)
+            self.cursor_move (1)
+            self.touch_document ()
+            
+
index 0df4df2c769bf149fe38fee9c367d596fb85edd5..77c8242babfdacd2f7d334dbeea45667f7e28884 100644 (file)
@@ -2,14 +2,125 @@ import gtk
 import gnomecanvas
 import music
 
+
+class Notation_toolbar (gtk.HBox):
+       def __init__ (self, notation, check_refresh_callback):
+               gtk.HBox.__init__ (self)
+               self.button_dict = {}
+               self.key_dict = {}
+               self.notation = notation
+               self.add_buttons ()
+               self.check_refresh_callback = check_refresh_callback
+               
+       def click_callback (self, widget):
+               if not self.button_dict.has_key (widget):
+                       print 'no such widget?'
+                       return False
+
+               cb = self.button_dict[widget]
+               cb()
+               self.check_refresh_callback()
+               return True
+
+       def keypress_callback (self, widget, event):
+               key =  event.keyval
+               name = gtk.gdk.keyval_name (key)
+
+               if event.get_state () & gtk.gdk.SHIFT_MASK:
+                       name = 'Shift+' + name 
+               if event.get_state () & gtk.gdk.CONTROL_MASK:
+                       name = 'Ctrl+' + name
+               if not self.key_dict.has_key (name):
+                       print 'no such key?', name
+                       return False
+
+               button = self.key_dict[name]
+               button.do_activate (button)
+               return True
+       
+       def add_button (self, text, key, callback):
+               b = gtk.Button (text)
+               self.pack_start (b, expand=True)
+               b.connect ('clicked', self.click_callback)
+               b.set_focus_on_click (False)
+               self.key_dict[key] = b
+               self.button_dict[b] = callback
+               b.show ()
+
+       def add_buttons (self):
+               for (key_name, text, func) in \
+                       [('Left', '<-',
+                         lambda: self.notation.cursor_move (-1)),
+                        ('Right', '->',
+                         lambda: self.notation.cursor_move (1)),
+                        ('space', 'next',
+                         lambda: self.notation.add_note ()),
+                        ('BackSpace', 'backspace',
+                         lambda: self.notation.backspace ()),
+                        ('Shift+Up', '#',
+                         lambda: self.notation.change_alteration (2)),
+                        ('Shift+Down', 'b',
+                         lambda: self.notation.change_alteration (-2)),
+                        ('Up', 'up',
+                         lambda: self.notation.change_step (1)),
+                        ('Down', 'down',
+                         lambda: self.notation.change_step (-1)),
+                        ('apostrophe', 'oct up',
+                         lambda: self.notation.change_octave (1)),
+                        ('comma', 'oct down',
+                         lambda: self.notation.change_octave (-1)),
+                        ('period', '.',
+                         lambda: self.notation.change_dots ()),
+                        ('slash', 'shorter',
+                         lambda: self.notation.change_duration_log (1)),
+                        ('Shift+asterisk', 'longer',
+                         lambda: self.notation.change_duration_log (-1)),
+                        ('p', 'LilyPond',
+                         lambda: self.notation.print_score()),
+                        ('q', 'quit',
+                         lambda: gtk.main_quit()),
+                        ('r', 'rest',
+                         lambda: self.notation.ensure_rest ()),
+                        ('Shift+C', '+C',
+                         lambda: self.notation.add_step (0)),
+                        ('Shift+D', '+D',
+                         lambda: self.notation.add_step (1)),
+                        ('Shift+E', '+E',
+                         lambda: self.notation.add_step (2)),
+                        ('Shift+F', '+F',
+                         lambda: self.notation.add_step (3)),
+                        ('Shift+G', '+G',
+                         lambda: self.notation.add_step (4)),
+                        ('Shift+A', '+A',
+                         lambda: self.notation.add_step (5)),
+                        ('Shift+B', '+B',
+                         lambda: self.notation.add_step (6)),
+                        ('c', 'C',
+                         lambda: self.notation.set_step (0)),
+                        ('d', 'D',
+                         lambda: self.notation.set_step (1)),
+                        ('e', 'E',
+                         lambda: self.notation.set_step (2)),
+                        ('f', 'F',
+                         lambda: self.notation.set_step (3)),
+                        ('g', 'G',
+                         lambda: self.notation.set_step (4)),
+                        ('a', 'A',
+                         lambda: self.notation.set_step (5)),
+                        ('b', 'B',
+                         lambda: self.notation.set_step (6))]:
+                       
+                       self.add_button (text, key_name, func)
+
+
 class Notation_canvas (gnomecanvas.Canvas):
        """The canvas for drawing notation symbols."""
        
-       def __init__ (self):
+       def __init__ (self, canvas_controller):
                gnomecanvas.Canvas.__init__ (self,
                                             #aa=True
                                             )
-               w,h = 800,400
+               (w,h) = (800,400)
                self.set_size_request (w, h) 
                self.set_scroll_region (0, 0, w, h)
                root = self.root ()
@@ -19,13 +130,14 @@ class Notation_canvas (gnomecanvas.Canvas):
                i = root.add (gnomecanvas.CanvasRect, x2 = w, y2 = -h,
                              fill_color = 'white', outline_color = 'white')
                i.notation_item = None
+               self.notation_canvas_controller = canvas_controller
                self.create_cursor ()
                
        def create_cursor (self):
                type = gnomecanvas.CanvasRect
                w = self.root ().add (type,
-                                     fill_color = 'None',
-                                     outline_color = 'blue')
+                                     fill_color = 'lightblue',
+                                     outline_color = 'lightblue')
                w.notation_item = None
                
                self.cursor_widget = w
@@ -49,20 +161,20 @@ class Notation_canvas (gnomecanvas.Canvas):
                        
                item.set (fill_color = color)
                
-       def item_event (self, widget, event=None):
-               if 0:
-                       pass
-               elif event.type == gtk.gdk.ENTER_NOTIFY:
-                       self.item_set_active_state(widget, True)
-                       return True
-               elif event.type == gtk.gdk.LEAVE_NOTIFY:
-                       self.item_set_active_state(widget, False)
-                       return True
+       def click_event (self, widget, event = None):
+               if event <> None and event.type == gtk.gdk.BUTTON_PRESS:
+                       if event.button == 1 and widget.notation_item.name in ('Rest', 'NoteHead'):
+                               
+                               notat = self.notation_canvas_controller.notation
+                               notat.set_cursor (widget.notation_item.music_expression)
+                               self.notation_canvas_controller.check_update()
+                               
+                               return True
                return False
        
        def register_notation_canvas_item (self, citem):
                if citem.notation_item and citem.notation_item.music_expression:
-                       citem.connect ("event", self.item_event)
+                       citem.connect ("event", self.click_event)
 
        def set_cursor_to_music (self, music_expression):
                c_items = [it for it in self.root().item_list if
@@ -70,6 +182,8 @@ class Notation_canvas (gnomecanvas.Canvas):
                            and it.notation_item.music_expression
                                == music_expression)]
 
+               c_items = filter (lambda it: it.notation_item.name in ('NoteHead', 'Rest'),
+                                 c_items) 
                if c_items:
                        self.set_cursor (c_items[0].notation_item)
 
@@ -77,76 +191,18 @@ class Notation_canvas_controller:
        """The connection between canvas and the abstract notation graphics."""
 
        def __init__ (self, notation):
-               self.canvas = Notation_canvas ()
+               self.canvas = Notation_canvas (self)
                self.notation = notation
-               self.canvas.connect ("key-press-event", self.keypress)
-
+               
        def update_cursor (self):
                self.canvas.set_cursor_to_music (self.notation.music_cursor)
 
        def update_canvas (self):
                self.notation.paint_on_canvas (self.canvas)
-       
-       def add_note (self):
-               note = music.NoteEvent ()
-               if self.notation.music_cursor.name () == 'NoteEvent':
-                       note.pitch = self.notation.music_cursor.pitch.copy()
-                       note.pitch.alteration = 0
-                       note.duration = self.notation.music_cursor.duration.copy()
-               
-               ch = music.EventChord ()
-               ch.insert_around (None, note, 0)
-               
-               self.notation.insert_at_cursor (ch, 1)
-               self.notation.cursor_move (1)
-               
-       def keypress (self, widget, event):
-               key =  event.keyval
-               name = gtk.gdk.keyval_name (key)
 
-               if 0:
-                       pass
-               elif name == 'Left':
-                       self.notation.cursor_move (-1)
-                       self.update_cursor ()
-                       
-               elif name == 'Right':
-                       self.notation.cursor_move (1)
+       def check_update (self):
+               self.notation.check_update ()
+               if self.notation.touched:
+                       self.update_canvas ()
+               elif self.notation.cursor_touched:
                        self.update_cursor ()
-               elif name == 'space':
-                       self.add_note ()
-               elif name == 'apostrophe':
-                       self.notation.change_octave (1)
-               elif name == 'comma':
-                       self.notation.change_octave (-1)
-               elif name == 'BackSpace':
-                       self.notation.backspace ()
-               elif name == 'plus':
-                       self.notation.change_alteration (2)
-               elif name == 'minus':
-                       self.notation.change_alteration (-2)
-               elif name == 'period':
-                       self.notation.change_dots ()
-               elif name == 'slash':
-                       self.notation.change_duration_log (1)
-               elif name == 'asterisk':
-                       self.notation.change_duration_log (-1)
-               elif name == 'p':
-                       self.notation.print_score()
-               elif name == 'q':
-                       gtk.main_quit()
-               elif name == 'r':
-                       self.notation.ensure_rest ()
-               elif len (name) == 1 and name in 'abcdefg':
-                       step = (ord (name) - ord ('a') + 5) % 7
-                       self.notation.ensure_note ()
-                       self.notation.change_step (step)
-               else:
-                       print 'Unknown key %s' % name
-                       return False
-               
-               self.notation.ensure_cursor_visible ()
-               self.notation.notation_controller.update_notation ()
-               self.notation.paint_on_canvas (self.canvas)
-               return True
-