1 #ifndef _EditorM_h_
2 #define _EditorM_h_
3 /* EditorM.h
4  *
5  * Copyright (C) 1992-2013,2015-2021 Paul Boersma
6  *
7  * This code is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or (at
10  * your option) any later version.
11  *
12  * This code is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  * See the GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this work. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifdef _praatM_h_
22 	#error Include either praatM.h or EditorM.h, but not both.
23 #endif
24 
25 #define EDITOR_ARGS_FORM  EditorCommand cmd, UiForm _sendingForm_, integer _narg_, Stackel _args_, conststring32 _sendingString_, Interpreter interpreter
26 #define EDITOR_ARGS_FORM_FORWARD  cmd, _sendingForm_, _narg_, _args_, _sendingString_, interpreter
27 #define EDITOR_ARGS_CMD  EditorCommand cmd, UiForm, integer, Stackel, conststring32, Interpreter
28 #define EDITOR_ARGS_CMD_FORWARD  cmd, nullptr, 0, nullptr, nullptr, nullptr
29 #define EDITOR_ARGS_DIRECT  EditorCommand, UiForm, integer, Stackel, conststring32, Interpreter
30 #define EDITOR_ARGS_DIRECT_WITH_OUTPUT  EditorCommand, UiForm, integer, Stackel, conststring32, Interpreter interpreter
31 #define EDITOR_ARGS_DIRECT_FORWARD  nullptr, nullptr, 0, nullptr, nullptr, nullptr
32 
33 #define EDITOR_FORM(title, helpTitle)  \
34 	UiField _radio_ = nullptr; \
35 	(void) _radio_; \
36 	if (cmd -> d_uiform) goto _form_inited_; \
37 	cmd -> d_uiform = UiForm_createE (cmd, title, cmd -> itemTitle.get(), helpTitle);
38 
39 #define EDITOR_OK  \
40 	UiForm_finish (cmd -> d_uiform.get()); \
41 _form_inited_: \
42 	if (! _args_ && ! _sendingForm_ && ! _sendingString_) {
43 
44 #define EDITOR_DO  \
45 		UiForm_do (cmd -> d_uiform.get(), false); \
46 	} else if (! _sendingForm_) { \
47 		UiForm_parseStringE (cmd, _narg_, _args_, _sendingString_, interpreter); \
48 	} else {
49 
50 #define EDITOR_END  \
51 	}
52 
53 /*
54 	Functions to define the fields in a form on the basis of the label text
55 	and factory default value.
56 	They are to be called between EDITOR_FORM and EDITOR_OK.
57 */
58 
59 #define REAL_VARIABLE(realVariable) \
60 	static double realVariable;
61 
62 #define REAL_FIELD(realVariable, labelText, defaultStringValue) \
63 	UiForm_addReal (cmd -> d_uiform.get(), & realVariable, nullptr, labelText, defaultStringValue);
64 
65 #define REAL(realVariable, labelText, defaultStringValue) \
66 	REAL_VARIABLE (realVariable) \
67 	REAL_FIELD (realVariable, labelText, defaultStringValue)
68 
69 
70 #define REAL_OR_UNDEFINED_VARIABLE(realVariable) \
71 	static double realVariable;
72 
73 #define REAL_OR_UNDEFINED_FIELD(realVariable, labelText, defaultStringValue) \
74 	UiForm_addRealOrUndefined (cmd -> d_uiform.get(), & realVariable, nullptr, labelText, defaultStringValue);
75 
76 #define REAL_OR_UNDEFINED(realVariable, labelText, defaultStringValue) \
77 	REAL_OR_UNDEFINED_VARIABLE (realVariable) \
78 	REAL_OR_UNDEFINED_FIELD (realVariable, labelText, defaultStringValue)
79 
80 
81 #define POSITIVE_VARIABLE(realVariable) \
82 	static double realVariable;
83 
84 #define POSITIVE_FIELD(realVariable, labelText, defaultStringValue) \
85 	UiForm_addPositive (cmd -> d_uiform.get(), & realVariable, nullptr, labelText, defaultStringValue);
86 
87 #define POSITIVE(realVariable, labelText, defaultStringValue) \
88 	POSITIVE_VARIABLE (realVariable) \
89 	POSITIVE_FIELD (realVariable, labelText, defaultStringValue)
90 
91 
92 #define INTEGER_VARIABLE(integerVariable) \
93 	static integer integerVariable;
94 
95 #define INTEGER_FIELD(integerVariable, labelText, defaultStringValue) \
96 	UiForm_addInteger (cmd -> d_uiform.get(), & integerVariable, nullptr, labelText, defaultStringValue);
97 
98 #define INTEGER(integerVariable, labelText, defaultStringValue) \
99 	INTEGER_VARIABLE (integerVariable) \
100 	INTEGER_FIELD (integerVariable, labelText, defaultStringValue)
101 
102 
103 #define NATURAL_VARIABLE(integerVariable) \
104 	static integer integerVariable;
105 
106 #define NATURAL_FIELD(integerVariable, labelText, defaultStringValue) \
107 	UiForm_addNatural (cmd -> d_uiform.get(), & integerVariable, nullptr, labelText, defaultStringValue);
108 
109 #define NATURAL(integerVariable, labelText, defaultStringValue) \
110 	NATURAL_VARIABLE (integerVariable) \
111 	NATURAL_FIELD (integerVariable, labelText, defaultStringValue)
112 
113 
114 #define WORD_VARIABLE(stringVariable) \
115 	static conststring32 stringVariable;
116 
117 #define WORD_FIELD(stringVariable, labelText, defaultStringValue) \
118 	UiForm_addWord (cmd -> d_uiform.get(), & stringVariable, nullptr, labelText, defaultStringValue);
119 
120 #define WORD(stringVariable, labelText, defaultStringValue) \
121 	WORD_VARIABLE (stringVariable) \
122 	WORD_FIELD (stringVariable, labelText, defaultStringValue)
123 
124 
125 #define SENTENCE_VARIABLE(stringVariable) \
126 	static conststring32 stringVariable;
127 
128 #define SENTENCE_FIELD(stringVariable, labelText, defaultStringValue) \
129 	UiForm_addSentence (cmd -> d_uiform.get(), & stringVariable, nullptr, labelText, defaultStringValue);
130 
131 #define SENTENCE(stringVariable, labelText, defaultStringValue) \
132 	SENTENCE_VARIABLE (stringVariable) \
133 	SENTENCE_FIELD (stringVariable, labelText, defaultStringValue)
134 
135 
136 #define COLOUR_VARIABLE(colourVariable) \
137 	static MelderColour colourVariable;
138 
139 #define COLOUR_FIELD(colourVariable, labelText, defaultStringValue) \
140 	UiForm_addColour (cmd -> d_uiform.get(), & colourVariable, nullptr, labelText, defaultStringValue);
141 
142 #define COLOUR(colourVariable, labelText, defaultStringValue) \
143 	COLOUR_VARIABLE (colourVariable) \
144 	COLOUR_FIELD (colourVariable, labelText, defaultStringValue)
145 
146 
147 #define CHANNEL_VARIABLE(integerVariable) \
148 	static integer integerVariable;
149 
150 #define CHANNEL_FIELD(integerVariable, labelText, defaultStringValue) \
151 	UiForm_addChannel (cmd -> d_uiform.get(), & integerVariable, nullptr, labelText, defaultStringValue);
152 
153 #define CHANNEL(integerVariable, labelText, defaultStringValue) \
154 	CHANNEL_VARIABLE (integerVariable) \
155 	CHANNEL_FIELD (integerVariable, labelText, defaultStringValue)
156 
157 
158 #define BOOLEAN_VARIABLE(booleanVariable) \
159 	static bool booleanVariable;
160 
161 #define BOOLEAN_FIELD(booleanVariable, labelText, defaultBooleanValue) \
162 	UiForm_addBoolean (cmd -> d_uiform.get(), & booleanVariable, nullptr, labelText, defaultBooleanValue);
163 
164 #define BOOLEAN(booleanVariable, labelText, defaultBooleanValue) \
165 	BOOLEAN_VARIABLE (booleanVariable) \
166 	BOOLEAN_FIELD (booleanVariable, labelText, defaultBooleanValue)
167 
168 
169 #define LABEL(labelText) \
170 	UiForm_addLabel (cmd -> d_uiform.get(), nullptr, labelText);
171 
172 
173 #define MUTABLE_LABEL_VARIABLE(stringVariable) \
174 	static conststring32 stringVariable;
175 
176 #define MUTABLE_LABEL_FIELD(stringVariable, labelText) \
177 	UiForm_addLabel (cmd -> d_uiform.get(), & stringVariable, labelText);
178 
179 #define MUTABLE_LABEL(stringVariable, labelText) \
180 	MUTABLE_LABEL_VARIABLE (stringVariable) \
181 	MUTABLE_LABEL_FIELD (stringVariable, labelText)
182 
183 
184 #define TEXTFIELD_VARIABLE(stringVariable) \
185 	static conststring32 stringVariable;
186 
187 #define TEXTFIELD_FIELD(stringVariable, labelText, defaultValue, numberOfLines) \
188 	UiForm_addText (cmd -> d_uiform.get(), & stringVariable, nullptr, labelText, defaultValue, numberOfLines);
189 
190 #define TEXTFIELD(stringVariable, labelText, defaultValue, numberOfLines) \
191 	TEXTFIELD_VARIABLE (stringVariable) \
192 	TEXTFIELD_FIELD (stringVariable, labelText, defaultValue, numberOfLines)
193 
194 
195 #define FORMULA_VARIABLE(stringVariable) \
196 	static conststring32 stringVariable;
197 
198 #define FORMULA_FIELD(stringVariable, labelText, defaultValue) \
199 	UiForm_addFormula (cmd -> d_uiform.get(), & stringVariable, nullptr, labelText, defaultValue);
200 
201 #define FORMULA(stringVariable, labelText, defaultValue) \
202 	FORMULA_VARIABLE (stringVariable) \
203 	FORMULA_FIELD (stringVariable, labelText, defaultValue)
204 
205 
206 #define INFILE_VARIABLE(stringVariable) \
207 	static conststring32 stringVariable;
208 
209 #define INFILE_FIELD(stringVariable, labelText, defaultValue) \
210 	UiForm_addInfile (cmd -> d_uiform.get(), & stringVariable, nullptr, labelText, defaultValue);
211 
212 #define INFILE(stringVariable, labelText, defaultValue) \
213 	INFILE_VARIABLE (stringVariable) \
214 	INFILE_FIELD (stringVariable, labelText, defaultValue)
215 
216 
217 #define OUTFILE_VARIABLE(stringVariable) \
218 	static conststring32 stringVariable;
219 
220 #define OUTFILE_FIELD(stringVariable, labelText, defaultValue) \
221 	UiForm_addOutfile (cmd -> d_uiform.get(), & stringVariable, nullptr, labelText, defaultValue);
222 
223 #define OUTFILE(stringVariable, labelText, defaultValue) \
224 	OUTFILE_VARIABLE (stringVariable) \
225 	OUTFILE_FIELD (stringVariable, labelText, defaultValue)
226 
227 
228 #define FOLDER_VARIABLE(stringVariable) \
229 	static conststring32 stringVariable;
230 
231 #define FOLDER_FIELD(stringVariable, labelText, defaultValue) \
232 	UiForm_addFolder (cmd -> d_uiform.get(), & stringVariable, nullptr, labelText, defaultValue);
233 
234 #define FOLDER(stringVariable, labelText, defaultValue) \
235 	FOLDER_VARIABLE (stringVariable) \
236 	FOLDER_FIELD (stringVariable, labelText, defaultValue)
237 
238 
239 #define REALVECTOR_VARIABLE(realVectorVariable) \
240 	static constVEC realVectorVariable;
241 
242 #define REALVECTOR_FIELD(realVectorVariable, labelText, defaultFormat, defaultStringValue) \
243 	UiForm_addRealVector (cmd -> d_uiform.get(), & realVectorVariable, nullptr, labelText, kUi_realVectorFormat::defaultFormat, defaultStringValue);
244 
245 #define REALVECTOR(realVectorVariable, labelText, defaultFormat, defaultStringValue) \
246 	REALVECTOR_VARIABLE (realVectorVariable) \
247 	REALVECTOR_FIELD (realVectorVariable, labelText, defaultFormat, defaultStringValue)
248 
249 
250 #define NATURALVECTOR_VARIABLE(integerVectorVariable) \
251 	static constINTVEC integerVectorVariable;
252 
253 #define NATURALVECTOR_FIELD(integerVectorVariable, labelText, defaultFormat, defaultStringValue) \
254 	UiForm_addNaturalVector (cmd -> d_uiform.get(), & integerVectorVariable, nullptr, labelText, kUi_integerVectorFormat::defaultFormat, defaultStringValue);
255 
256 #define NATURALVECTOR(integerVectorVariable, labelText, defaultFormat, defaultStringValue) \
257 	NATURALVECTOR_VARIABLE (integerVectorVariable) \
258 	NATURALVECTOR_FIELD (integerVectorVariable, labelText, defaultFormat, defaultStringValue)
259 
260 
261 #define RADIO_VARIABLE(optionVariable) \
262 	static int optionVariable;
263 
264 #define RADIO_FIELD(optionVariable, labelText, defaultValue) \
265 	_radio_ = UiForm_addRadio (cmd -> d_uiform.get(), & optionVariable, nullptr, nullptr, labelText, defaultValue, 1);
266 
267 #define RADIO(optionVariable, labelText, defaultValue) \
268 	RADIO_VARIABLE (optionVariable) \
269 	RADIO_FIELD (optionVariable, labelText, defaultValue)
270 
271 
272 #define RADIOSTR(stringVariable, labelText, defaultValue) \
273 	static conststring32 stringVariable; \
274 	_radio_ = UiForm_addRadio (cmd -> d_uiform.get(), nullptr, & stringVariable, nullptr, labelText, defaultValue, 1);
275 
276 
277 #define RADIOBUTTON(labelText) \
278 	UiRadio_addButton (_radio_, labelText);
279 
280 
281 #define OPTIONMENU_VARIABLE(optionVariable) \
282 	static int optionVariable;
283 
284 #define OPTIONMENU_FIELD(optionVariable, labelText, defaultValue) \
285 	_radio_ = UiForm_addOptionMenu (cmd -> d_uiform.get(), & optionVariable, nullptr, nullptr, labelText, defaultValue, 1);
286 
287 #define OPTIONMENU(optionVariable, labelText, defaultValue) \
288 	OPTIONMENU_VARIABLE (optionVariable) \
289 	OPTIONMENU_FIELD(optionVariable, labelText, defaultValue)
290 
291 
292 #define OPTIONMENUSTR(stringVariable, labelText, defaultValue) \
293 	static conststring32 stringVariable; \
294 	_radio_ = UiForm_addOptionMenu (cmd -> d_uiform.get(), nullptr, & stringVariable, nullptr, labelText, defaultValue, 1);
295 
296 
297 #define OPTION(labelText) \
298 	UiOptionMenu_addButton (_radio_, labelText);
299 
300 
301 #define RADIO_ENUM_VARIABLE(EnumeratedType, enumeratedVariable) \
302 	static enum EnumeratedType enumeratedVariable; \
303 
304 #define RADIO_ENUM_FIELD(EnumeratedType, enumeratedVariable, labelText, defaultValue) \
305 	{/* type checks */ \
306 		enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
307 		_compilerTypeCheckDummy = enumeratedVariable; \
308 		(void) _compilerTypeCheckDummy; \
309 	} \
310 	{/* scope */ \
311 		UiField _radio = UiForm_addRadio (cmd -> d_uiform.get(), (int *) & enumeratedVariable, nullptr, nullptr, labelText, \
312 			(int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
313 		for (int _ienum = (int) EnumeratedType::MIN; _ienum <= (int) EnumeratedType::MAX; _ienum ++) \
314 			UiRadio_addButton (_radio, EnumeratedType##_getText ((enum EnumeratedType) _ienum)); \
315 	}
316 
317 #define RADIO_ENUM(EnumeratedType, enumeratedVariable, labelText, defaultValue) \
318 	RADIO_ENUM_VARIABLE (EnumeratedType, enumeratedVariable) \
319 	RADIO_ENUM_FIELD (EnumeratedType, enumeratedVariable, labelText, defaultValue)
320 
321 
322 #define OPTIONMENU_ENUM_VARIABLE(EnumeratedType, enumeratedVariable) \
323 	static enum EnumeratedType enumeratedVariable; \
324 
325 #define OPTIONMENU_ENUM_FIELD(EnumeratedType, enumeratedVariable, labelText, defaultValue) \
326 	{/* type checks */ \
327 		enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
328 		_compilerTypeCheckDummy = enumeratedVariable; \
329 		(void) _compilerTypeCheckDummy; \
330 	} \
331 	{/* scope */ \
332 		UiField _radio = UiForm_addOptionMenu (cmd -> d_uiform.get(), (int *) & enumeratedVariable, nullptr, nullptr, labelText, \
333 			(int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
334 		for (int _ienum = (int) EnumeratedType::MIN; _ienum <= (int) EnumeratedType::MAX; _ienum ++) \
335 			UiOptionMenu_addButton (_radio, EnumeratedType##_getText ((enum EnumeratedType) _ienum)); \
336 	}
337 
338 #define OPTIONMENU_ENUM(EnumeratedType, enumeratedVariable, labelText, defaultValue) \
339 	OPTIONMENU_ENUM_VARIABLE (EnumeratedType, enumeratedVariable) \
340 	OPTIONMENU_ENUM_FIELD (EnumeratedType, enumeratedVariable, labelText, defaultValue)
341 
342 
343 #define LIST(integerVariable, labelText, strings, defaultValue) \
344 	static integer integerVariable; \
345 	UiForm_addList (cmd -> d_uiform.get(), & integerVariable, nullptr, nullptr, labelText, strings, defaultValue);
346 
347 /*
348 	Seven optional functions to change the content of a field on the basis of the current
349 	editor setting rather than on the basis of the factory default.
350 	They are to be called between EDITOR_OK and EDITOR_DO.
351 */
352 
353 #define SET_REAL(realVariable, realValue) \
354 	UiForm_setReal (cmd -> d_uiform.get(), & realVariable, realValue);
355 
356 #define SET_INTEGER(integerVariable, integerValue)  \
357 	UiForm_setInteger (cmd -> d_uiform.get(), & integerVariable, integerValue);
358 
359 #define SET_INTEGER_AS_STRING(integerVariable, stringValue)  \
360 	UiForm_setIntegerAsString (cmd -> d_uiform.get(), & integerVariable, stringValue);
361 
362 #define SET_BOOLEAN(booleanVariable, booleanValue)  \
363 	UiForm_setBoolean (cmd -> d_uiform.get(), & booleanVariable, booleanValue);
364 
365 #define SET_OPTION(optionVariable, optionValue)  \
366 	UiForm_setOption (cmd -> d_uiform.get(), & optionVariable, optionValue);
367 
368 #define SET_STRING(stringVariable, stringValue) \
369 	UiForm_setString (cmd -> d_uiform.get(), & stringVariable, stringValue);
370 
371 #define SET_ENUM(enumeratedVariable, EnumeratedType, enumeratedValue) \
372 	enumeratedVariable = enumeratedValue /* type check */; \
373 	UiForm_setOption (cmd -> d_uiform.get(), (int *) & enumeratedVariable, (int) enumeratedValue - (int) EnumeratedType::MIN + 1);
374 
375 
376 #define DIALOG  cmd -> d_uiform
377 
378 #define EDITOR_FORM_SAVE(title, helpTitle) \
379 	if (! cmd -> d_uiform) { \
380 		cmd -> d_uiform = UiOutfile_createE (cmd, title, cmd -> itemTitle.get(), helpTitle); \
381 		} if (! _args_ && ! _sendingForm_ && ! _sendingString_) { char32 defaultName [300]; defaultName [0] = U'\0';
382 #define EDITOR_DO_SAVE \
383 	(void) interpreter; \
384 	UiOutfile_do (cmd -> d_uiform.get(), defaultName); } else { MelderFile file; structMelderFile _file2 { }; \
385 	if (_args_) { \
386 		Melder_require (_narg_ == 1, \
387 			U"Command requires exactly 1 argument, the name of the file to write, instead of the given ", _narg_, U" arguments."); \
388 		Melder_require (_args_ [1]. which == Stackel_STRING, \
389 			U"The file name argument should be a string, not ", _args_ [1]. whichText(), U"."); \
390 		Melder_relativePathToFile (_args_ [1]. getString(), & _file2); \
391 		file = & _file2; \
392 	} else if (_sendingString_) { \
393 		Melder_relativePathToFile (_sendingString_, & _file2); \
394 		file = & _file2; \
395 	} else { \
396 		file = UiFile_getFile (cmd -> d_uiform.get()); \
397 	}
398 
399 #define EDITOR_FORM_READ(title, helpTitle) \
400 	if (! cmd -> d_uiform) { \
401 		cmd -> d_uiform = UiInfile_createE (cmd, title, cmd -> itemTitle.get(), helpTitle); \
402 		} if (! _args_ && ! _sendingForm_ && ! _sendingString_) {
403 #define EDITOR_DO_READ \
404 	(void) interpreter; \
405 	UiInfile_do (cmd -> d_uiform.get()); } else { MelderFile file; structMelderFile _file2 { }; \
406 	if (_args_) { \
407 		Melder_require (_narg_ == 1, \
408 			U"Command requires exactly 1 argument, the name of the file to read, instead of the given ", _narg_, U" arguments."); \
409 		Melder_require (_args_ [1]. which == Stackel_STRING, \
410 			U"The file name argument should be a string, not ", _args_ [1]. whichText(), U"."); \
411 		Melder_relativePathToFile (_args_ [1]. getString(), & _file2); \
412 		file = & _file2; \
413 	} else if (_sendingString_) { \
414 		Melder_relativePathToFile (_sendingString_, & _file2); \
415 		file = & _file2; \
416 	} else { \
417 		file = UiFile_getFile (cmd -> d_uiform.get()); \
418 	}
419 
420 #define VOID_EDITOR
421 #define VOID_EDITOR_END
422 
423 #define DATA_BEGIN__  \
424 	Melder_assert (my data);
425 
426 #define PLAY_DATA  \
427 	DATA_BEGIN__
428 #define PLAY_DATA_END
429 
430 #define INFO_EDITOR
431 #define INFO_EDITOR_END  \
432 	if (interpreter) \
433 		interpreter -> returnType = kInterpreter_ReturnType::STRING_;
434 
435 #define INFO_DATA  \
436 	DATA_BEGIN__
437 #define INFO_DATA_END  \
438 	if (interpreter) \
439 		interpreter -> returnType = kInterpreter_ReturnType::STRING_;
440 
441 #define FOR_REAL__(...)  \
442 	if (interpreter) \
443 		interpreter -> returnType = kInterpreter_ReturnType::REAL_; \
444 	Melder_information (result, __VA_ARGS__);
445 
446 #define FOR_INTEGER__(...)  \
447 	if (interpreter) \
448 		interpreter -> returnType = kInterpreter_ReturnType::INTEGER_; \
449 	Melder_information (double (result), __VA_ARGS__);
450 
451 #define FOR_BOOLEAN__(...)  \
452 	if (interpreter) \
453 		interpreter -> returnType = kInterpreter_ReturnType::BOOLEAN_; \
454 	Melder_information (double (result), __VA_ARGS__);
455 
456 #define FOR_COMPLEX__(...)  \
457 	if (interpreter) \
458 		interpreter -> returnType = kInterpreter_ReturnType::STRING_; /* TODO: make true complex types in script */ \
459 	Melder_information (result, __VA_ARGS__);
460 
461 #define FOR_STRING__  \
462 	if (interpreter) \
463 		interpreter -> returnType = kInterpreter_ReturnType::STRING_; \
464 	Melder_information (result);
465 
466 #define QUERY_EDITOR_FOR_REAL
467 #define QUERY_EDITOR_FOR_REAL_END(...)  \
468 	FOR_REAL__ (__VA_ARGS__)
469 
470 #define QUERY_EDITOR_FOR_INTEGER
471 #define QUERY_EDITOR_FOR_INTEGER_END(...)  \
472 	FOR_INTEGER__ (__VA_ARGS__)
473 
474 #define QUERY_EDITOR_FOR_BOOLEAN
475 #define QUERY_EDITOR_FOR_BOOLEAN_END(...)  \
476 	FOR_BOOLEAN__ (__VA_ARGS__)
477 
478 #define QUERY_EDITOR_FOR_STRING
479 #define QUERY_EDITOR_FOR_STRING_END  \
480 	FOR_STRING__
481 
482 #define QUERY_DATA_FOR_REAL  \
483 	DATA_BEGIN__
484 #define QUERY_DATA_FOR_REAL_END(...)  \
485 	FOR_REAL__ (__VA_ARGS__)
486 
487 #define QUERY_DATA_FOR_INTEGER  \
488 	DATA_BEGIN__
489 #define QUERY_DATA_FOR_INTEGER_END(...)  \
490 	FOR_INTEGER__ (__VA_ARGS__)
491 
492 #define QUERY_DATA_FOR_BOOLEAN  \
493 	DATA_BEGIN__
494 #define QUERY_DATA_FOR_BOOLEAN_END(...)  \
495 	FOR_BOOLEAN__ (__VA_ARGS__)
496 
497 #define QUERY_DATA_FOR_STRING  \
498 	DATA_BEGIN__
499 #define QUERY_DATA_FOR_STRING_END  \
500 	FOR_STRING__
501 
502 #define MODIFY_DATA(undoTitle)  \
503 	Editor_save (me, undoTitle);
504 #define MODIFY_DATA_END  \
505 	FunctionEditor_redraw (me); \
506 	Editor_broadcastDataChanged (me);
507 
508 #define CONVERT_DATA_TO_ONE  \
509 	DATA_BEGIN__
510 #define CONVERT_DATA_TO_ONE_END(...)  \
511 	if (interpreter) \
512 		interpreter -> returnType = kInterpreter_ReturnType::OBJECT_; \
513 	Thing_setName (result.get(), __VA_ARGS__); \
514 	Editor_broadcastPublication (me, result.move());
515 
516 #define CREATE_ONE
517 #define CREATE_ONE_END(...)  \
518 	if (interpreter) \
519 		interpreter -> returnType = kInterpreter_ReturnType::OBJECT_; \
520 	Thing_setName (result.get(), __VA_ARGS__); \
521 	Editor_broadcastPublication (me, result.move());
522 
523 #define HELP(title)  \
524 	Melder_help (title);
525 
526 /* End of file EditorM.h */
527 #endif
528