Пример #1
0
 def actionTriggered(self, name):
     name = name[8:]
     direction = ['_', '', '^'][self.direction() + 1]
     isSpanner = name not in dynamic_marks
     if isSpanner:
         dynamic = dynamic_spanners[name]
     else:
         dynamic = '\\' + name
     cursor = self.mainwindow().textCursor()
     if not cursor.hasSelection():
         # dynamic right before the cursor?
         left = tokeniter.partition(cursor).left
         if not left or not isinstance(left[-1], ly.lex.lilypond.Dynamic):
             # no, find the first pitch
             source = tokeniter.Source.from_cursor(cursor, True, -1)
             for p in music.music_items(source):
                 cursor = source.cursor(p[-1], start=len(p[-1]))
                 break
         cursor.insertText(direction + dynamic)
         self.mainwindow().currentView().setTextCursor(cursor)
     else:
         source = tokeniter.Source.selection(cursor, True)
         cursors = [source.cursor(p[-1], start=len(p[-1]))
             for p in music.music_items(source)]
         if not cursors:
             return
         c1, c2 = cursors[0], cursors[-1]
         # are there dynamics at the cursor? then skip them
         d1 = dynamics(c1)
         if d1:
             c1 = tokeniter.cursor(c1.block(), d1[-1], start=len(d1[-1]))
         with cursortools.compress_undo(cursor):
             if len(cursors) > 1:
                 # dynamics after the end cursor?
                 d2 = dynamics(c2)
                 if isSpanner and not d2:
                     # don't terminate the spanner if there's a dynamic there
                     c2.insertText('\\!')
                 elif set(d1).intersection(dynamic_spanners.values()):
                     # write the dynamic at the end if there's a spanner at start
                     # remove ending \! if there
                     terminator = tokeniter.find("\\!", d2)
                     if terminator:
                         c2 = tokeniter.cursor(c2.block(), terminator)
                     if direction in d1:
                         c2.insertText(dynamic)
                     else:
                         c2.insertText(direction + dynamic)
                     return
             c1.insertText(direction + dynamic)
Пример #2
0
 def actionTriggered(self, name):
     # convert arpeggio_normal to arpeggioNormal, etc.
     name = _arpeggioTypes[name]
     cursor = self.mainwindow().textCursor()
     # which arpeggio type is last used?
     lastused = '\\arpeggioNormal'
     types = set(_arpeggioTypes.values())
     block = cursor.block()
     while block.isValid():
         s = types.intersection(tokeniter.tokens(block))
         if s:
             lastused = s.pop()
             break
         block = block.previous()
     # where to insert
     source = tokeniter.Source.from_cursor(cursor, True, -1)
     with cursortools.compress_undo(cursor):
         for p in music.music_items(source, tokens=source.tokens):
             c = source.cursor(p[-1], start=len(p[-1]))
             c.insertText('\\arpeggio')
             if name != lastused:
                 cursortools.strip_indent(c)
                 import indent
                 indent.insert_text(c, name + '\n')
             # just pick the first place
             return
Пример #3
0
def duration_cursor_items(cursor):
    """Yields two-tuples (cursor, list of duration tokens).
    
    The list of duration tokens may be empty. This can be used to find
    the places to insert or overwrite durations in the selected music.
    
    """
    source = tokeniter.Source.selection(cursor, True)
    for m in music.music_items(source):
        i = iter(m)
        c = QTextCursor(source.block)
        for t in i:
            if isinstance(t, ly.lex.lilypond.Duration):
                l = [t]
                c.setPosition(source.block.position() + t.pos)
                for t in i:
                    if isinstance(t, ly.lex.lilypond.Duration):
                        l.append(t)
                    elif not isinstance(t, ly.lex.Space):
                        break
                c.setPosition(source.block.position() + l[-1].end, c.KeepAnchor)
                break
        else:
            c.setPosition(source.block.position() + t.end)
            l = []
        yield c, l
Пример #4
0
 def actionTriggered(self, name):
     cursor = self.mainwindow().textCursor()
     style = _glissandoStyles[name]
     source = tokeniter.Source.from_cursor(cursor, True, -1)
     for p in music.music_items(source, tokens=source.tokens):
         c = source.cursor(p[-1], start=len(p[-1]))
         if style:
             text = "-\\tweak #'style #'{0} \\glissando".format(style)
         else:
             text = '\\glissando'
         c.insertText(text)
         return
Пример #5
0
    def actionTriggered(self, name):
        d = ['_', '', '^'][self.direction()+1]
        single = ''
        if name == "grace_grace":
            inner = ''
            outer = '\\grace { ', ' }'
            single = '\\grace '
        elif name == "grace_beam":
            inner = d + '[', ']'
            outer = '\\grace { ', ' }'
        elif name == "grace_accia":
            inner = ''
            outer = '\\acciaccatura { ', ' }'
            single = '\\acciaccatura '
        elif name == "grace_appog":
            inner = ''
            outer = '\\appoggiatura { ', ' }'
            single = '\\appoggiatura '
        elif name == "grace_slash":
            inner = d + '[', ']'
            outer = '\\slashedGrace { ', ' }'
        elif name == "grace_after":
            inner = d + '{ '
            outer = '\\afterGrace ', ' }'        		

        cursor = self.mainwindow().textCursor()
        with cursortools.compress_undo(cursor):
            if inner:     
            	for i, ci in zip(inner, spanner_positions(cursor)):
                	ci.insertText(i)
            if cursor.hasSelection():
            	ins = self.mainwindow().textCursor()      
            	ins.setPosition(cursor.selectionStart())
            	ins.insertText(outer[0])
            	ins.setPosition(cursor.selectionEnd())
            	ins.insertText(outer[1])
            else:
            	if single:
            		cursor.insertText(single)
            	else:
            		source = tokeniter.Source.from_cursor(cursor, True, -1)
            		music_list = list(music.music_items(source, tokens=source.tokens))
            		try:
            			m = music_list[2][0]
            			after = source.cursor(m, 1)
            		except IndexError:            			
            			after = self.mainwindow().textCursor()
            			after.movePosition(cursor.EndOfLine)   		
            		after.insertText(outer[1])
            		cursor.insertText(outer[0])
Пример #6
0
def spanner_positions(cursor):
    if cursor.hasSelection():
        source = tokeniter.Source.selection(cursor, True)
        tokens = None
    else:
        source = tokeniter.Source.fromCursor(cursor, True, -1)
        tokens = source.tokens # only current line
    
    positions = [source.cursor(p[-1], start=len(p[-1]))
        for p in music.music_items(source, tokens=tokens)]
    
    if cursor.hasSelection():
        del positions[1:-1]
    else:
        del positions[2:]
    return positions
Пример #7
0
def spanner_positions(cursor):
    """Return a list with 0 to 2 QTextCursor instances.
    
    At the first cursor a starting spanner item can be inserted, at the
    second an ending item.
    
    """ 
    if cursor.hasSelection():
        source = tokeniter.Source.selection(cursor, True)
        tokens = None
    else:
        source = tokeniter.Source.from_cursor(cursor, True, -1)
        tokens = source.tokens # only current line
    
    positions = [source.cursor(p[-1], start=len(p[-1]))
        for p in music.music_items(source, tokens=tokens)]
    
    if cursor.hasSelection():
        del positions[1:-1]
    else:
        del positions[2:]
    return positions
Пример #8
0
def articulation_positions(cursor):
    """Returns a list of positions where an articulation can be added.
    
    Every position is given as a QTextCursor instance.
    If the cursor has a selection, all positions in the selection are returned.
    
    """
    if cursor.hasSelection():
        source = tokeniter.Source.selection(cursor, True)
        tokens = None
        rests = False
    else:
        source = tokeniter.Source.fromCursor(cursor, True, -1)
        tokens = source.tokens # only current line
        rests = True
    
    positions = []
    for p in music.music_items(source, tokens=tokens):
        if not rests and isinstance(p[0], ly.lex.lilypond.Rest):
            continue
        positions.append(source.cursor(p[-1], start=len(p[-1])))
        if not cursor.hasSelection():
            break # leave if first found, that's enough
    return positions
Пример #9
0
def duration_items(cursor, *classes):
    """Yields block, list where tokens in list are instance of *classes."""
    source = tokeniter.Source.selection(cursor, True)
    for m in music.music_items(source):
        yield source.block, [token for token in m if isinstance(token, classes)]