1# This file is part of the Frescobaldi project, http://www.frescobaldi.org/
2#
3# Copyright (c) 2011 - 2014 by Wilbert Berendsen
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License
7# as published by the Free Software Foundation; either version 2
8# of the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18# See http://www.gnu.org/licenses/ for more information.
19
20"""
21All completions data.
22"""
23
24
25import itertools
26
27from PyQt5.QtCore import Qt
28from PyQt5.QtGui import QFont, QFontDatabase
29
30import listmodel
31import ly.words
32import ly.data
33import ly.pitch
34
35from . import util
36
37
38# some groups of basic lilypond commands
39
40# markup (toplevel, book and bookpart)
41markup = (
42    'markup',
43    'markuplines',
44    'markuplist',
45    'pageBreak',
46    'noPageBreak',
47    'noPageTurn',
48)
49
50# these can occur (almost) everywhere
51everywhere = (
52    'pointAndClickOn',
53    'pointAndClickOff',
54    'include',
55)
56
57# commands that change input mode, can introduce a music expression
58inputmodes = (
59    'chords',
60    'chordmode {',
61    'drums',
62    'drummode {',
63    'figures',
64    'figuremode {',
65    'lyrics',
66    'lyricmode {',
67    'addlyrics {',
68)
69
70# commands that only occur at the global file level
71toplevel = (
72    'defineBarLine',
73    'language',
74    'version',
75    'sourcefileline',
76    'sourcefilename',
77)
78
79# other commands that can start a music expression
80start_music = (
81    'repeat',
82    'alternative {',
83    'relative',
84    'transpose',
85    'partcombine',
86    'keepWithTag #\'',
87    'removeWithTag #\'',
88    'new',
89    'context',
90    'with',
91)
92
93# tweak commands may be assigned, in toplevel
94tweaks = (
95    'once',
96    'override',
97    'revert',
98    'set',
99    'unset',
100)
101
102# modes book, bookpart and score
103modes = (
104    'book {',
105    'bookpart {',
106    'score {',
107)
108
109# blocks: paper, header, layout
110blocks = (
111    'paper {',
112    'header {',
113    'layout {',
114)
115
116# commands that are used in context definitions
117cmds_context = (
118    'override',
119    'consists',
120    'remove',
121    'RemoveEmptyStaves',
122    'accepts',
123    'alias',
124    'defaultchild',
125    'denies',
126    'name',
127)
128
129# in \with { } a smaller set
130cmds_with = cmds_context[:3]
131
132
133# variables that make sense to be set at toplevel
134toplevel_variables = (
135    'pipeSymbol',
136    'showFirstLength',
137    'showLastLength',
138)
139
140
141# stuff inside \score {}
142score = sorted(
143    everywhere + inputmodes + start_music + blocks[1:] + (
144    'midi {',
145))
146
147
148# stuff inside \bookpart {}
149bookpart = sorted(
150    everywhere + inputmodes + markup + start_music + modes[2:] + blocks
151)
152
153
154# stuff inside \book {}
155book = sorted(
156    everywhere + inputmodes + markup + start_music
157    + modes[1:] + blocks + (
158    'bookOutputName',
159    'bookOutputSuffix',
160))
161
162
163lilypond_markup = listmodel.ListModel(['\\markup'])
164
165lilypond_markup_commands = listmodel.ListModel(
166    sorted(ly.words.markupcommands),
167    display = util.command)
168
169lilypond_header_variables = listmodel.ListModel(
170    sorted(ly.words.headervariables, key=lambda i: i[:3]), edit = util.variable)
171
172lilypond_paper_variables = listmodel.ListModel(
173    sorted(ly.words.papervariables), edit = util.variable)
174
175lilypond_layout_variables = listmodel.ListModel([
176        '\\context {',
177        '\\override',
178        '\\set',
179        '\\hide',
180        '\\omit',
181        '\\accidentalStyle',
182        ] + sorted(ly.words.layoutvariables),
183    edit = util.cmd_or_var)
184
185lilypond_midi_variables = listmodel.ListModel(
186    ['\\context {', '\\override', '\\set', '\\tempo',] +
187    sorted(ly.words.midivariables),
188    edit = util.cmd_or_var)
189
190lilypond_contexts = listmodel.ListModel(sorted(ly.words.contexts))
191
192lilypond_grobs = listmodel.ListModel(ly.data.grobs())
193
194lilypond_contexts_and_grobs = listmodel.ListModel(
195    sorted(ly.words.contexts) + ly.data.grobs())
196
197lilypond_context_properties = listmodel.ListModel(
198    ly.data.context_properties())
199
200lilypond_contexts_and_properties = listmodel.ListModel(
201    sorted(ly.words.contexts) + ly.data.context_properties())
202
203lilypond_context_contents = listmodel.ListModel(sorted(itertools.chain(
204    util.make_cmds(ly.words.contexts),
205    ly.data.context_properties(),
206    util.make_cmds(cmds_context),
207    )), edit = util.cmd_or_var)
208
209lilypond_with_contents = listmodel.ListModel(sorted(itertools.chain(
210    ly.data.context_properties(),
211    util.make_cmds(cmds_with),
212    )), edit = util.cmd_or_var)
213
214lilypond_toplevel = listmodel.ListModel(sorted(itertools.chain(util.make_cmds(
215    toplevel + everywhere + inputmodes + markup + start_music + tweaks
216    + modes + blocks
217    ), toplevel_variables)), edit = util.cmd_or_var)
218
219lilypond_book = listmodel.ListModel(book, display = util.command)
220
221lilypond_bookpart = listmodel.ListModel(bookpart, display = util.command)
222
223lilypond_score = listmodel.ListModel(score, display = util.command)
224
225lilypond_engravers = listmodel.ListModel(ly.data.engravers())
226
227def lilypond_grob_properties(grob, hash_quote=True):
228    display = (lambda item: "#'" + item) if hash_quote else (lambda item: item)
229    return listmodel.ListModel(ly.data.grob_properties(grob),
230        display = display)
231
232lilypond_all_grob_properties = listmodel.ListModel(ly.data.all_grob_properties(),
233    display = lambda item: "#'" + item)
234
235lilypond_all_grob_properties_and_grob_names = listmodel.ListModel(
236    ly.data.all_grob_properties() + ly.data.grobs())
237
238lilypond_markup_properties = listmodel.ListModel(
239    sorted(set(sum(map(ly.data.grob_interface_properties, (
240        # see lilypond docs about \markup \override
241        'font-interface',
242        'text-interface',
243        'instrument-specific-markup-interface',
244    )), []))))
245
246lilypond_modes = listmodel.ListModel(ly.words.modes, display = util.command)
247
248lilypond_clefs = listmodel.ListModel(ly.words.clefs_plain)
249
250lilypond_accidental_styles = listmodel.ListModel(ly.words.accidentalstyles)
251
252lilypond_accidental_styles_contexts = listmodel.ListModel(
253    ly.words.contexts + ly.words.accidentalstyles)
254
255lilypond_repeat_types = listmodel.ListModel(ly.words.repeat_types)
256
257music_glyphs = listmodel.ListModel(ly.data.music_glyphs())
258
259midi_instruments = listmodel.ListModel(ly.words.midi_instruments)
260
261language_names = listmodel.ListModel(sorted(ly.pitch.pitchInfo))
262
263def font_names():
264    model = listmodel.ListModel(sorted(QFontDatabase().families()))
265    model.setRoleFunction(Qt.FontRole, QFont)
266    return model
267
268