praat.h 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. #ifndef _praat_h_
  2. #define _praat_h_
  3. /* praat.h
  4. *
  5. * Copyright (C) 1992-2018 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. #include "Editor.h"
  21. #include "Manual.h"
  22. #include "Preferences.h"
  23. /* The explanations in this header file assume
  24. that you put your extra commands in praat_Sybil.cpp
  25. and the main() function in main_Sybil.cpp,
  26. but these files may have different names if you are not Sybil.
  27. Linking with the rest of Praat will create an executable
  28. that has all the functionality of the basic Praat,
  29. plus everything that you made available in praat_Sybil.cpp.
  30. */
  31. /* Program example:
  32. // File main_Sybil.cpp: //
  33. int main (int argc, char **argv)
  34. {
  35. praat_init (U"Praat_Sybil", argc, argv); // Obligatory.
  36. INCLUDE_LIBRARY (praat_Fon_init) // Optional: inherit phonetic stuff.
  37. INCLUDE_LIBRARY (praat_Sybil_init) // Optional: add Sybil's things.
  38. INCLUDE_MANPAGES (manual_Sybil)
  39. praat_run (); // Obligatory.
  40. }
  41. // File praat_Sybil.cpp: //
  42. void praat_Sybil (void)
  43. {
  44. ...
  45. ...
  46. }
  47. The dots consist of, in any order:
  48. Thing_recognizeClassesByName (...);
  49. Data_recognizeFileType (...);
  50. praat_addMenuCommand (...);
  51. praat_addAction1 (...);
  52. All of these statements are optional and may occur more than once.
  53. To make any class string-readable, use Thing_recognizeClassesByName ().
  54. String-readable classes are known by Thing_newFromClassName () and can therefore
  55. be read by Data_readFromTextFile () and Data_readFromBinaryFile ().
  56. */
  57. void praat_init (conststring32 title, int argc, char **argv);
  58. void praat_run ();
  59. void praat_setStandAloneScriptText (conststring32 text); // call before praat_init if you want to create a stand-alone application without Objects and Picture window
  60. extern "C" void praatlib_init (); // for use in an application that uses Praatlib
  61. #define praat_addAction1(c1,n1,t,a,f,c) praat_addAction1_ (c1, n1, t, a, f, c, U"" #c)
  62. #define praat_addAction2(c1,n1,c2,n2,t,a,f,c) praat_addAction2_ (c1, n1, c2, n2, t, a, f, c, U"" #c)
  63. #define praat_addAction3(c1,n1,c2,n2,c3,n3,t,a,f,c) praat_addAction3_ (c1, n1, c2, n2, c3, n3, t, a, f, c, U"" #c)
  64. #define praat_addAction4(c1,n1,c2,n2,c3,n3,c4,n4,t,a,f,c) praat_addAction4_ (c1, n1, c2, n2, c3, n3, c4, n4, t, a, f, c, U"" #c)
  65. void praat_addAction1_ (ClassInfo class1, integer n1,
  66. conststring32 title, conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
  67. void praat_addAction2_ (ClassInfo class1, integer n1, ClassInfo class2, integer n2,
  68. conststring32 title, conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
  69. void praat_addAction3_ (ClassInfo class1, integer n1, ClassInfo class2, integer n2, ClassInfo class3, integer n3,
  70. conststring32 title, conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
  71. void praat_addAction4_ (ClassInfo class1, integer n1, ClassInfo class2, integer n2, ClassInfo class3, integer n3, ClassInfo class4, integer n4,
  72. conststring32 title, conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
  73. /*
  74. 'title' is the name that will appear in the dynamic menu,
  75. and also the command that is used in command files;
  76. this title is reference-copied.
  77. 'callback' refers to a function prototyped like this:
  78. static int DO_Class_action (UiForm sendingForm, int narg, Stackel args, conststring32 sendingString, Interpreter interpreter, void *closure);
  79. this function should throw an exception if the command failed,
  80. and return 1 if the command was executed successfully;
  81. this function will be called by 'praat' when the user clicks a menu command,
  82. in which case 'sendingForm', 'args' and 'sendingString' and 'closure' will be null;
  83. it is also called by scripts,
  84. in which case 'args[1..n]' or 'sendingString' is the argument list (after the dots).
  85. When called by Ui (after UiForm_create), 'sendingForm' is the UiForm, and 'closure'
  86. is the closure you passed to UiForm_create (which may be an editor).
  87. The availability of the dynamic commands depends on
  88. the current selection: e.g., if the user has selected three objects
  89. of type Matrix and nothing else, the commands registered with
  90. praat_addAction1 (classMatrix, n, "xxx", "xxxx", x, DO_xxx) are visible,
  91. and those with n=0 or n=3 are executable (the buttons are sensitive)
  92. and, if chosen, performed on each of these three objects;
  93. if the user has selected one object of type Artword and one of type
  94. Speaker, the commands from praat_addAction2 (classArtword, 1, classSpeaker, 1, ...) are executable.
  95. You may want to restrict the availability to one object for commands that write objects to file,
  96. commands that present information in a dialog, or the View & Edit command.
  97. */
  98. #define praat_INSENSITIVE GuiMenu_INSENSITIVE
  99. #define praat_CHECKBUTTON GuiMenu_CHECKBUTTON
  100. #define praat_TOGGLE_ON GuiMenu_TOGGLE_ON
  101. #define praat_ATTRACTIVE GuiMenu_ATTRACTIVE
  102. #define praat_RADIO_FIRST GuiMenu_RADIO_FIRST
  103. #define praat_RADIO_NEXT GuiMenu_RADIO_NEXT
  104. #define praat_HIDDEN 0x0000'4000
  105. #define praat_UNHIDABLE 0x0000'8000
  106. #define praat_DEPTH_1 0x0001'0000
  107. #define praat_DEPTH_2 0x0002'0000
  108. #define praat_DEPTH_3 0x0003'0000
  109. #define praat_DEPTH_4 0x0004'0000
  110. #define praat_DEPTH_5 0x0005'0000
  111. #define praat_DEPTH_6 0x0006'0000
  112. #define praat_DEPTH_7 0x0007'0000
  113. #define praat_NO_API 0x0008'0000
  114. #define praat_FORCE_API 0x0010'0000
  115. #define praat_DEPRECATED (0x0020'0000 | praat_HIDDEN)
  116. #define praat_DEPRECATED_2004 (0x0420'0000 | praat_HIDDEN)
  117. #define praat_DEPRECATED_2005 (0x0520'0000 | praat_HIDDEN)
  118. #define praat_DEPRECATED_2006 (0x0620'0000 | praat_HIDDEN)
  119. #define praat_DEPRECATED_2007 (0x0720'0000 | praat_HIDDEN)
  120. #define praat_DEPRECATED_2008 (0x0820'0000 | praat_HIDDEN)
  121. #define praat_DEPRECATED_2009 (0x0920'0000 | praat_HIDDEN)
  122. #define praat_DEPRECATED_2010 (0x0A20'0000 | praat_HIDDEN)
  123. #define praat_DEPRECATED_2011 (0x0B20'0000 | praat_HIDDEN)
  124. #define praat_DEPRECATED_2012 (0x0C20'0000 | praat_HIDDEN)
  125. #define praat_DEPRECATED_2013 (0x0D20'0000 | praat_HIDDEN)
  126. #define praat_DEPRECATED_2014 (0x0E20'0000 | praat_HIDDEN)
  127. #define praat_DEPRECATED_2015 (0x0F20'0000 | praat_HIDDEN)
  128. #define praat_DEPRECATED_2016 (0x1020'0000 | praat_HIDDEN)
  129. #define praat_DEPRECATED_2017 (0x1120'0000 | praat_HIDDEN)
  130. /*
  131. The following three can also be used, but not for deprecated commands.
  132. */
  133. //#define GuiMenu_OPTION (1 << 24)
  134. //#define GuiMenu_SHIFT (1 << 25)
  135. //#define GuiMenu_COMMAND (1 << 26)
  136. void praat_removeAction (ClassInfo class1, ClassInfo class2, ClassInfo class3, conststring32 title);
  137. /* 'class2' and 'class3' may be null. */
  138. /* 'title' may be null; reference-copied. */
  139. #define praat_addMenuCommand(w,m,t,a,f,c) praat_addMenuCommand_ (w, m, t, a, f, c, U"" #c)
  140. GuiMenuItem praat_addMenuCommand_ (conststring32 window, conststring32 menu, conststring32 title /* cattable */,
  141. conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
  142. /* All strings are reference-copied; 'title', 'after', and 'callback' may be null. */
  143. #define praat_MAXNUM_EDITORS 5
  144. #include "Ui.h"
  145. typedef struct {
  146. ClassInfo klas; // the class
  147. Daata object; // the instance
  148. autostring32 name; // the name of the object as it appears in the List
  149. structMelderFile file; // is this Object associated with a file?
  150. integer id; // the unique number of the object
  151. bool isSelected; // is the name of the object inverted in the list?
  152. Editor editors [praat_MAXNUM_EDITORS]; // are there editors open with this Object in it?
  153. bool isBeingCreated;
  154. } structPraat_Object, *praat_Object;
  155. #define praat_MAXNUM_OBJECTS 10000 /* Maximum number of objects in the list. */
  156. typedef struct { /* Readonly */
  157. MelderString batchName; /* The name of the command file when called from batch. */
  158. int batch; /* Was the program called from the command line? */
  159. GuiWindow topShell; /* The application shell: parent of standard dialogs. */
  160. ManPages manPages;
  161. } structPraatApplication, *PraatApplication;
  162. typedef struct { /* Readonly */
  163. int n; /* The current number of objects in the list. */
  164. structPraat_Object list [1 + praat_MAXNUM_OBJECTS]; /* The list of objects: list [1..n]. */
  165. int totalSelection; /* The total number of selected objects, <= n. */
  166. int numberOfSelected [1 + 1000]; /* For each (readable) class. */
  167. int totalBeingCreated;
  168. integer uniqueId;
  169. } structPraatObjects, *PraatObjects;
  170. typedef struct { // readonly
  171. Graphics graphics; /* The Graphics associated with the Picture window or HyperPage window or Demo window. */
  172. int font, fontSize, lineType;
  173. Graphics_Colour colour;
  174. double lineWidth, arrowSize, speckleSize, x1NDC, x2NDC, y1NDC, y2NDC;
  175. } structPraatPicture, *PraatPicture;
  176. extern structPraatApplication theForegroundPraatApplication;
  177. extern PraatApplication theCurrentPraatApplication;
  178. extern structPraatObjects theForegroundPraatObjects;
  179. extern PraatObjects theCurrentPraatObjects;
  180. extern structPraatPicture theForegroundPraatPicture;
  181. extern PraatPicture theCurrentPraatPicture;
  182. /* The global objects containing the state of the application; only reachable from interface files. */
  183. char32 *praat_name (int iobject);
  184. void praat_write_do (UiForm dia, conststring32 extension);
  185. void praat_new (autoDaata me);
  186. void praat_new (autoDaata me, const MelderArg& arg);
  187. void praat_new (autoDaata me, const MelderArg& arg1, const MelderArg& arg2,
  188. const MelderArg& arg3 = U"", const MelderArg& arg4 = U"", const MelderArg& arg5 = U"");
  189. void praat_newWithFile (autoDaata me, MelderFile file, conststring32 name);
  190. void praat_name2 (char32 *name, ClassInfo klas1, ClassInfo klas2);
  191. /* Macros for description of forms (dialog boxes, setting windows).
  192. FORM prompts the user for arguments to proc.
  193. Macros for FORM:
  194. FORM (proc, title, helpString)
  195. `proc` is the `cb` argument of the corresponding command call.
  196. `title` is the title of the form, shown in its title bar.
  197. `helpString` may be null.
  198. INTEGER (variable, labelText, defaultStringValue)
  199. NATURAL (variable, labelText, defaultStringValue)
  200. REAL (variable, labelText, defaultStringValue)
  201. REAL_OR_UNDEFINED (variable, labelText, defaultStringValue)
  202. POSITIVE (variable, labelText, defaultStringValue)
  203. WORD (variable, labelText, defaultStringValue)
  204. SENTENCE (variable, labelText, defaultStringValue)
  205. COLOUR (variable, labelText, defaultStringValue)
  206. CHANNEL (variable, labelText, defaultStringValue)
  207. BOOLEAN (variable, labelText, defaultBooleanValue)
  208. the value is 0 (off) or 1 (on).
  209. LABEL (labelText)
  210. TEXTFIELD (variable, labelText, defaultStringValue)
  211. NUMVEC (variable, labelText, defaultStringValue)
  212. NUMMAT (variable, labelText, defaultStringValue)
  213. RADIO (variable, labelText, defaultOptionNumber, base)
  214. this should be followed by two or more RADIOBUTTONs;
  215. the initial value is between base and the number of radio buttons plus base-1.
  216. RADIOBUTTON (labelText)
  217. OPTIONMENU (variable, labelText, defaultOptionNumber)
  218. this should be followed by two or more OPTIONs;
  219. the initial value is between 1 and the number of options.
  220. OPTION (labelText)
  221. LIST (variable, labelText, strings, defaultOptionNumber)
  222. OK
  223. this statement is obligatory.
  224. SET_XXXXXX (name, value)
  225. sets the value of REAL..LIST.
  226. DO
  227. The order of the macros should be:
  228. FORM {
  229. one or more from REAL..LIST
  230. OK
  231. zero or more SETs
  232. DO
  233. ...
  234. }
  235. See Ui.h for more information.
  236. Between DO and `}`, you can throw an exception if anything is wrong;
  237. if everything is all right, you just trickle down to END.
  238. Never do "return", because END will update the selection if an object is created.
  239. */
  240. #ifndef _EditorM_h_
  241. #define FORM(proc,name,helpTitle) \
  242. extern "C" void proc (UiForm sendingForm, integer narg, Stackel args, conststring32 sendingString, Interpreter interpreter, conststring32 invokingButtonTitle, bool modified, void *buttonClosure); \
  243. void proc (UiForm _sendingForm_, integer _narg_, Stackel _args_, conststring32 _sendingString_, Interpreter interpreter, conststring32 _invokingButtonTitle_, bool _modified_, void *_buttonClosure_) { \
  244. int IOBJECT = 0; \
  245. (void) IOBJECT; \
  246. UiField _radio_ = nullptr; \
  247. (void) _radio_; \
  248. static autoUiForm _dia_; \
  249. if (_dia_) goto _dia_inited_; \
  250. _dia_ = UiForm_create (theCurrentPraatApplication -> topShell, name, proc, _buttonClosure_, _invokingButtonTitle_, helpTitle);
  251. #define REAL(realVariable, labelText, defaultStringValue) \
  252. static double realVariable; \
  253. UiForm_addReal (_dia_.get(), & realVariable, U"" #realVariable, labelText, defaultStringValue);
  254. #define REAL_OR_UNDEFINED(realVariable, labelText, defaultStringValue) \
  255. static double realVariable; \
  256. UiForm_addRealOrUndefined (_dia_.get(), & realVariable, U"" #realVariable, labelText, defaultStringValue);
  257. #define POSITIVE(realVariable, labelText, defaultStringValue) \
  258. static double realVariable; \
  259. UiForm_addPositive (_dia_.get(), & realVariable, U"" #realVariable, labelText, defaultStringValue);
  260. #define INTEGER(integerVariable, labelText, defaultStringValue) \
  261. static integer integerVariable; \
  262. UiForm_addInteger (_dia_.get(), & integerVariable, U"" #integerVariable, labelText, defaultStringValue);
  263. #define NATURAL(integerVariable, labelText, defaultStringValue) \
  264. static integer integerVariable; \
  265. UiForm_addNatural (_dia_.get(), & integerVariable, U"" #integerVariable, labelText, defaultStringValue);
  266. #define WORD(stringVariable, labelText, defaultStringValue) \
  267. static conststring32 stringVariable; \
  268. UiForm_addWord (_dia_.get(), & stringVariable, U"" #stringVariable, labelText, defaultStringValue);
  269. #define SENTENCE(stringVariable, labelText, defaultStringValue) \
  270. static conststring32 stringVariable; \
  271. UiForm_addSentence (_dia_.get(), & stringVariable, U"" #stringVariable, labelText, defaultStringValue);
  272. #define BOOLEAN(booleanVariable, labelText, defaultBooleanValue) \
  273. static bool booleanVariable; \
  274. UiForm_addBoolean (_dia_.get(), & booleanVariable, U"" #booleanVariable, labelText, defaultBooleanValue);
  275. #define LABEL(labelText) UiForm_addLabel (_dia_.get(), nullptr, labelText);
  276. #define MUTABLE_LABEL(stringVariable, labelText) \
  277. static conststring32 stringVariable; \
  278. UiForm_addLabel (_dia_.get(), & stringVariable, labelText);
  279. #define TEXTFIELD(stringVariable, labelText, defaultStringValue) \
  280. if (labelText != nullptr) /* an explicit nullptr comparison, because string literals don't convert well to bools */ \
  281. UiForm_addLabel (_dia_.get(), nullptr, labelText); \
  282. static conststring32 stringVariable; \
  283. UiForm_addText (_dia_.get(), & stringVariable, U"" #stringVariable, U"", defaultStringValue);
  284. #define NUMVEC(numericVectorVariable, labelText, defaultStringValue) \
  285. if (labelText != nullptr) /* an explicit nullptr comparison, because string literals don't convert well to bools */ \
  286. UiForm_addLabel (_dia_.get(), nullptr, labelText); \
  287. static constVEC numericVectorVariable; \
  288. UiForm_addNumvec (_dia_.get(), & numericVectorVariable, U"" #numericVectorVariable, U"", defaultStringValue);
  289. #define NUMMAT(numericMatrixVariable, labelText, defaultStringValue) \
  290. if (labelText != nullptr) /* an explicit nullptr comparison, because string literals don't convert well to bools */ \
  291. UiForm_addLabel (_dia_.get(), nullptr, labelText); \
  292. static constMAT numericMatrixVariable; \
  293. UiForm_addNummat (_dia_.get(), & numericMatrixVariable, U"" #numericMatrixVariable, U"", defaultStringValue);
  294. #define RADIO(intVariable, labelText, defaultOptionNumber) \
  295. static int intVariable; \
  296. _radio_ = UiForm_addRadio (_dia_.get(), & intVariable, nullptr, U"" #intVariable, labelText, defaultOptionNumber, 1);
  297. #define RADIOx(intVariable, labelText, defaultOptionNumber, base) \
  298. static int intVariable; \
  299. _radio_ = UiForm_addRadio (_dia_.get(), & intVariable, nullptr, U"" #intVariable, labelText, defaultOptionNumber, base);
  300. #define RADIOSTR(stringVariable, labelText, defaultOptionNumber) \
  301. static conststring32 stringVariable; \
  302. _radio_ = UiForm_addRadio (_dia_.get(), nullptr, & stringVariable, U"" #stringVariable, labelText, defaultOptionNumber, 1);
  303. #define RADIOBUTTON(labelText) \
  304. UiRadio_addButton (_radio_, labelText);
  305. #define OPTIONMENU(intVariable, labelText, defaultOptionNumber) \
  306. static int intVariable; \
  307. _radio_ = UiForm_addOptionMenu (_dia_.get(), & intVariable, nullptr, U"" #intVariable, labelText, defaultOptionNumber, 1);
  308. #define OPTIONMENUx(intVariable, labelText, defaultOptionNumber, base) \
  309. static int intVariable; \
  310. _radio_ = UiForm_addOptionMenu (_dia_.get(), & intVariable, nullptr, U"" #intVariable, labelText, defaultOptionNumber, base);
  311. #define OPTIONMENUSTR(stringVariable, labelText, defaultOptionNumber) \
  312. static conststring32 stringVariable; \
  313. _radio_ = UiForm_addOptionMenu (_dia_.get(), nullptr, & stringVariable, U"" #stringVariable, labelText, defaultOptionNumber, 1);
  314. #define OPTION(labelText) \
  315. UiOptionMenu_addButton (_radio_, labelText);
  316. #define RADIO_ENUM(EnumeratedType, enumeratedVariable, labelText, defaultValue) \
  317. static enum EnumeratedType enumeratedVariable; \
  318. {/* type checks */ \
  319. enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
  320. _compilerTypeCheckDummy = enumeratedVariable; \
  321. (void) _compilerTypeCheckDummy; \
  322. } \
  323. _radio_ = UiForm_addRadio (_dia_.get(), (int *) & enumeratedVariable, nullptr, U"" #enumeratedVariable, labelText, \
  324. (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
  325. for (int ienum = (int) EnumeratedType::MIN; ienum <= (int) EnumeratedType::MAX; ienum ++) \
  326. UiRadio_addButton (_radio_, EnumeratedType##_getText ((enum EnumeratedType) ienum));
  327. #define OPTIONMENU_ENUM(EnumeratedType, enumeratedVariable, labelText, defaultValue) \
  328. static EnumeratedType enumeratedVariable; \
  329. {/* type checks */ \
  330. enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
  331. _compilerTypeCheckDummy = enumeratedVariable; \
  332. (void) _compilerTypeCheckDummy; \
  333. } \
  334. _radio_ = UiForm_addOptionMenu (_dia_.get(), (int *) & enumeratedVariable, nullptr, U"" #enumeratedVariable, labelText, \
  335. (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
  336. for (int ienum = (int) EnumeratedType::MIN; ienum <= (int) EnumeratedType::MAX; ienum ++) \
  337. UiOptionMenu_addButton (_radio_, EnumeratedType##_getText ((enum EnumeratedType) ienum));
  338. #define OPTIONMENU_ENUMSTR(EnumeratedType, enumeratedVariableAsString, labelText, defaultValue) \
  339. static char32 *enumeratedVariableAsString; \
  340. {/* type checks */ \
  341. enum EnumeratedType _compilerTypeCheckDummy = defaultValue; \
  342. _compilerTypeCheckDummy = enumeratedVariable; \
  343. (void) _compilerTypeCheckDummy; \
  344. } \
  345. _radio_ = UiForm_addOptionMenu (_dia_.get(), nullptr, & enumeratedVariableAsString, U"" #enumeratedVariableAsString, labelText, \
  346. (int) defaultValue - (int) EnumeratedType::MIN + 1, (int) EnumeratedType::MIN); \
  347. for (int ienum = (int) EnumeratedType::MIN; ienum <= (int) EnumeratedType::MAX; ienum ++) \
  348. UiOptionMenu_addButton (_radio_, EnumeratedType##_getText ((enum EnumeratedType) ienum));
  349. #define LIST(integerVariable, labelText, strings, defaultOptionNumber) \
  350. static integer integerVariable; \
  351. UiForm_addList (_dia_.get(), & integerVariable, nullptr, U"" #integerVariable, labelText, strings, defaultOptionNumber);
  352. #define LISTSTR(stringVariable, labelText, numberOfStrings, strings, defaultOptionNumber) \
  353. static char32 *stringVariable; \
  354. UiForm_addList (_dia_.get(), nullptr, & stringVariable, U"" #stringVariable, labelText, strings, defaultOptionNumber);
  355. #define FILE_IN(labelText) \
  356. UiForm_addFileIn (_dia_.get(), labelText);
  357. #define FILE_OUT(labelText, defaultStringValue) \
  358. UiForm_addFileOut (_dia_.get(), labelText, defaultStringValue);
  359. #define COLOUR(colourVariable, labelText, defaultStringValue) \
  360. static Graphics_Colour colourVariable; \
  361. UiForm_addColour (_dia_.get(), & colourVariable, U"" #colourVariable, labelText, defaultStringValue);
  362. #define CHANNEL(integerVariable, labelText, defaultStringValue) \
  363. static integer integerVariable; \
  364. UiForm_addChannel (_dia_.get(), & integerVariable, U"" #integerVariable, labelText, defaultStringValue);
  365. #define OK \
  366. UiForm_finish (_dia_.get()); \
  367. _dia_inited_: \
  368. if (_narg_ < 0) UiForm_info (_dia_.get(), _narg_); else if (! _args_ && ! _sendingForm_ && ! _sendingString_) {
  369. #define SET_REAL(realVariable, realValue) \
  370. UiForm_setReal (_dia_.get(), & realVariable, realValue);
  371. #define SET_INTEGER(integerVariable, integerValue) \
  372. UiForm_setInteger (_dia_.get(), & integerVariable, integerValue);
  373. #define SET_BOOLEAN(booleanVariable, booleanValue) \
  374. UiForm_setBoolean (_dia_.get(), & booleanVariable, booleanValue);
  375. #define SET_STRING(stringVariable, stringValue) \
  376. UiForm_setString (_dia_.get(), & stringVariable, stringValue);
  377. #define SET_ENUM(enumeratedVariable, EnumeratedType, enumeratedValue) \
  378. enumeratedVariable = enumeratedValue; /* just for typechecking */ \
  379. UiForm_setOption (_dia_.get(), (int *) & enumeratedVariable, (int) enumeratedValue - (int) EnumeratedType::MIN + 1);
  380. #define DO \
  381. UiForm_do (_dia_.get(), _modified_); \
  382. } else if (! _sendingForm_) { \
  383. trace (U"args ", Melder_pointer (_args_)); \
  384. if (_args_) { \
  385. UiForm_call (_dia_.get(), _narg_, _args_, interpreter); \
  386. } else { \
  387. UiForm_parseString (_dia_.get(), _sendingString_, interpreter); \
  388. } \
  389. } else { \
  390. try { \
  391. {
  392. #define DO_ALTERNATIVE(alternative) \
  393. UiForm_do (_dia_.get(), _modified_); \
  394. } else if (! _sendingForm_) { \
  395. trace (U"alternative args ", Melder_pointer (_args_)); \
  396. try { \
  397. if (_args_) { \
  398. UiForm_call (_dia_.get(), _narg_, _args_, interpreter); \
  399. } else { \
  400. UiForm_parseString (_dia_.get(), _sendingString_, interpreter); \
  401. } \
  402. } catch (MelderError) { \
  403. autostring32 _parkedError = Melder_dup_f (Melder_getError ()); \
  404. Melder_clearError (); \
  405. try { \
  406. alternative (nullptr, _narg_, _args_, _sendingString_, interpreter, _invokingButtonTitle_, _modified_, _buttonClosure_); \
  407. } catch (MelderError) { \
  408. Melder_clearError (); \
  409. Melder_appendError (_parkedError.get()); \
  410. throw; \
  411. } \
  412. } \
  413. } else { \
  414. try { \
  415. {
  416. #define END \
  417. } \
  418. } catch (MelderError) { \
  419. praat_updateSelection (); \
  420. throw; \
  421. } \
  422. praat_updateSelection (); \
  423. } \
  424. }
  425. #define END_NO_NEW_DATA \
  426. } \
  427. } catch (MelderError) { \
  428. throw; \
  429. } \
  430. } \
  431. }
  432. #define DIRECT(proc) \
  433. extern "C" void proc (UiForm, integer, Stackel, conststring32, Interpreter interpreter, conststring32, bool, void *); \
  434. void proc (UiForm, integer, Stackel, conststring32, Interpreter interpreter, conststring32, bool, void *) { \
  435. (void) interpreter; \
  436. int IOBJECT = 0; \
  437. (void) IOBJECT; \
  438. { { \
  439. try {
  440. #define FORM_READ(proc,title,help,allowMult) \
  441. extern "C" void proc (UiForm sendingForm, integer, structStackel args [], conststring32 sendingString, Interpreter, conststring32 invokingButtonTitle, bool, void *okClosure); \
  442. void proc (UiForm _sendingForm_, integer _narg_, structStackel _args_ [], conststring32 _sendingString_, Interpreter, conststring32 _invokingButtonTitle_, bool, void *_okClosure_) { \
  443. { static autoUiForm _dia_; \
  444. if (! _dia_) \
  445. _dia_ = UiInfile_create (theCurrentPraatApplication -> topShell, title, proc, _okClosure_, _invokingButtonTitle_, help, allowMult); \
  446. if (_narg_ < 0) UiForm_info (_dia_.get(), _narg_); else if (! _args_ && ! _sendingForm_ && ! _sendingString_) { \
  447. UiInfile_do (_dia_.get()); \
  448. } else { \
  449. try { \
  450. MelderFile file; \
  451. int IOBJECT = 0; \
  452. (void) IOBJECT; \
  453. structMelderFile _file2 { }; /* don't move this into an inner scope, because the contents of a local variable don't persist into the outer scope */ \
  454. if (_args_) { \
  455. Melder_require (_narg_ == 1, \
  456. U"Command requires exactly 1 argument, the name of the file to read, instead of the given ", _narg_, U" arguments."); \
  457. Melder_require (_args_ [1]. which == Stackel_STRING, \
  458. U"The file name argument should be a string, not ", _args_ [1]. whichText(), U"."); \
  459. Melder_relativePathToFile (_args_ [1]. getString(), & _file2); \
  460. file = & _file2; \
  461. } else if (_sendingString_) { \
  462. Melder_relativePathToFile (_sendingString_, & _file2); \
  463. file = & _file2; \
  464. } else { \
  465. file = UiFile_getFile (_dia_.get()); \
  466. }
  467. #define FORM_SAVE(proc,title,help,ext) \
  468. extern "C" void proc (UiForm sendingForm, integer, structStackel args [], conststring32 sendingString, Interpreter, conststring32 invokingButtonTitle, bool, void *okClosure); \
  469. void proc (UiForm _sendingForm_, integer _narg_, Stackel _args_, conststring32 _sendingString_, Interpreter, conststring32 _invokingButtonTitle_, bool, void *_okClosure_) { \
  470. { static autoUiForm _dia_; \
  471. if (! _dia_) \
  472. _dia_ = UiOutfile_create (theCurrentPraatApplication -> topShell, title, proc, _okClosure_, _invokingButtonTitle_, help); \
  473. if (_narg_ < 0) UiForm_info (_dia_.get(), _narg_); else if (! _args_ && ! _sendingForm_ && ! _sendingString_) { \
  474. praat_write_do (_dia_.get(), ext); \
  475. } else { \
  476. try { \
  477. MelderFile file; \
  478. int IOBJECT = 0; \
  479. (void) IOBJECT; \
  480. structMelderFile _file2 { }; /* don't move this into an inner scope, because the contents of a local variable don't persist into the outer scope */ \
  481. if (_args_) { \
  482. Melder_require (_narg_ == 1, \
  483. U"Command requires exactly 1 argument, the name of the file to write, instead of the given ", _narg_, U" arguments."); \
  484. Melder_require (_args_ [1]. which == Stackel_STRING, \
  485. U"The file name argument should be a string, not ", _args_ [1]. whichText(), U"."); \
  486. Melder_relativePathToFile (_args_ [1]. getString(), & _file2); \
  487. file = & _file2; \
  488. } else if (_sendingString_) { \
  489. Melder_relativePathToFile (_sendingString_, & _file2); \
  490. file = & _file2; \
  491. } else { \
  492. file = UiFile_getFile (_dia_.get()); \
  493. }
  494. #endif // _EditorM_h_
  495. #define iam_LOOP(klas) klas me = static_cast<klas> (OBJECT)
  496. #define WHERE(condition) for (IOBJECT = 1; IOBJECT <= theCurrentPraatObjects -> n; IOBJECT ++) if (condition)
  497. #define WHERE_DOWN(condition) for (IOBJECT = theCurrentPraatObjects -> n; IOBJECT > 0; IOBJECT --) if (condition)
  498. #define SELECTED (theCurrentPraatObjects -> list [IOBJECT]. isSelected)
  499. #define LOOP for (IOBJECT = 1; IOBJECT <= theCurrentPraatObjects -> n; IOBJECT ++) if (SELECTED)
  500. #define CLASS (theCurrentPraatObjects -> list [IOBJECT]. klas)
  501. #define OBJECT (theCurrentPraatObjects -> list [IOBJECT]. object)
  502. #define GRAPHICS theCurrentPraatPicture -> graphics
  503. #define FULL_NAME (theCurrentPraatObjects -> list [IOBJECT]. name.get())
  504. #define ID (theCurrentPraatObjects -> list [IOBJECT]. id)
  505. #define ID_AND_FULL_NAME Melder_cat (ID, U". ", FULL_NAME)
  506. #define NAME praat_name (IOBJECT)
  507. #define CREATE_ONE
  508. #define CREATE_ONE_END(...) praat_new (result.move(), __VA_ARGS__); END
  509. #define FIND_ONE(klas) \
  510. klas me = nullptr; \
  511. LOOP { if (CLASS == class##klas || Thing_isSubclass (CLASS, class##klas)) me = (klas) OBJECT; break; }
  512. #define FIND_ONE_WITH_IOBJECT(klas) \
  513. klas me = nullptr; int _klas_position = 0; \
  514. LOOP { if (CLASS == class##klas) me = (klas) OBJECT, _klas_position = IOBJECT; break; } \
  515. IOBJECT = _klas_position;
  516. #define FIND_TWO(klas1,klas2) \
  517. klas1 me = nullptr; klas2 you = nullptr; \
  518. LOOP { if (CLASS == class##klas1) me = (klas1) OBJECT; else if (CLASS == class##klas2) you = (klas2) OBJECT; \
  519. if (me && you) break; }
  520. #define FIND_TWO_WITH_IOBJECT(klas1,klas2) \
  521. klas1 me = nullptr; klas2 you = nullptr; int _klas1_position = 0; \
  522. LOOP { if (CLASS == class##klas1) me = (klas1) OBJECT, _klas1_position = IOBJECT; \
  523. else if (CLASS == class##klas2) you = (klas2) OBJECT; if (me && you) break; } \
  524. IOBJECT = _klas1_position;
  525. #define FIND_COUPLE(klas) \
  526. klas me = nullptr, you = nullptr; \
  527. LOOP if (CLASS == class##klas || Thing_isSubclass (CLASS, class##klas)) (me ? you : me) = (klas) OBJECT;
  528. #define FIND_COUPLE_AND_ONE(klas1,klas2) \
  529. klas1 me = nullptr, you = nullptr; klas2 him = nullptr; \
  530. LOOP { if (CLASS == class##klas1) (me ? you : me) = (klas1) OBJECT; else if (CLASS == class##klas2) him = (klas2) OBJECT; \
  531. if (me && you && him) break; }
  532. #define FIND_ONE_AND_COUPLE(klas1,klas2) \
  533. klas1 me = nullptr; klas2 you = nullptr, him = nullptr; \
  534. LOOP { if (CLASS == class##klas1) me = (klas1) OBJECT; else if (CLASS == class##klas2) (you ? him : you) = (klas2) OBJECT; \
  535. if (me && you && him) break; }
  536. #define FIND_THREE(klas1,klas2,klas3) \
  537. klas1 me = nullptr; klas2 you = nullptr; klas3 him = nullptr; \
  538. LOOP { if (CLASS == class##klas1) me = (klas1) OBJECT; else if (CLASS == class##klas2) you = (klas2) OBJECT; \
  539. else if (CLASS == class##klas3) him = (klas3) OBJECT; if (me && you && him) break; }
  540. #define FIND_FOUR(klas1,klas2,klas3,klas4) \
  541. klas1 me = nullptr; klas2 you = nullptr; klas3 him = nullptr; klas4 she = nullptr; \
  542. LOOP { if (CLASS == class##klas1) me = (klas1) OBJECT; else if (CLASS == class##klas2) you = (klas2) OBJECT; \
  543. else if (CLASS == class##klas3) him = (klas3) OBJECT; else if (CLASS == class##klas4) she = (klas4) OBJECT; \
  544. if (me && you && him && she) break; }
  545. #define FIND_LIST(klas) \
  546. OrderedOf<struct##klas> list; \
  547. LOOP { iam_LOOP (klas); list. addItem_ref (me); }
  548. #define FIND_TYPED_LIST(klas,listClass) \
  549. auto##listClass list = listClass##_create (); \
  550. LOOP { iam_LOOP (klas); list -> addItem_ref (me); }
  551. #define FIND_ONE_AND_LIST(klas1,klas2) \
  552. OrderedOf<struct##klas2> list; klas1 me = nullptr; \
  553. LOOP { if (CLASS == class##klas2) list. addItem_ref ((klas2) OBJECT); else if (CLASS == class##klas1) me = (klas1) OBJECT; }
  554. #define FIND_ONE_AND_TYPED_LIST(klas1,klas2,listClass) \
  555. auto##listClass list = listClass##_create (); klas1 me = nullptr; \
  556. LOOP { if (CLASS == class##klas2) list -> addItem_ref ((klas2) OBJECT); else if (CLASS == class##klas1) me = (klas1) OBJECT; }
  557. #define FIND_TWO_AND_LIST(klas1,klas2,klas3) \
  558. OrderedOf<struct##klas3> list; klas1 me = nullptr; klas2 you = nullptr; \
  559. LOOP { if (CLASS == class##klas3) list. addItem_ref ((klas3) OBJECT); else if (CLASS == class##klas1) me = (klas1) OBJECT; \
  560. else if (CLASS == class##klas2) you = (klas2) OBJECT; }
  561. #define INFO_NONE
  562. #define INFO_NONE_END END_NO_NEW_DATA
  563. #define INFO_ONE(klas) FIND_ONE (klas)
  564. #define INFO_ONE_END END_NO_NEW_DATA
  565. #define INFO_TWO(klas1,klas2) FIND_TWO (klas1, klas2)
  566. #define INFO_TWO_END END_NO_NEW_DATA
  567. #define INFO_COUPLE(klas) FIND_COUPLE (klas)
  568. #define INFO_COUPLE_END END_NO_NEW_DATA
  569. #define INFO_THREE(klas1,klas2,klas3) FIND_THREE (klas1, klas2, klas3)
  570. #define INFO_THREE_END END_NO_NEW_DATA
  571. #define HELP(page) Melder_help (page); END_NO_NEW_DATA
  572. #define PLAY_EACH(klas) LOOP { iam_LOOP (klas);
  573. #define PLAY_EACH_END } END_NO_NEW_DATA
  574. #define GRAPHICS_NONE autoPraatPicture picture;
  575. #define GRAPHICS_NONE_END END_NO_NEW_DATA
  576. #define GRAPHICS_EACH(klas) autoPraatPicture picture; LOOP { iam_LOOP (klas);
  577. #define GRAPHICS_EACH_END } END_NO_NEW_DATA
  578. #define GRAPHICS_TWO(klas1,klas2) autoPraatPicture picture; FIND_TWO (klas1, klas2)
  579. #define GRAPHICS_TWO_END END_NO_NEW_DATA
  580. #define GRAPHICS_COUPLE(klas) autoPraatPicture picture; FIND_COUPLE (klas)
  581. #define GRAPHICS_COUPLE_END END_NO_NEW_DATA
  582. #define GRAPHICS_COUPLE_AND_ONE(klas1,klas2) autoPraatPicture picture; FIND_COUPLE_AND_ONE (klas1, klas2)
  583. #define GRAPHICS_COUPLE_AND_ONE_END END_NO_NEW_DATA
  584. #define MOVIE_ONE(klas,title,width,height) \
  585. Graphics graphics = Movie_create (title, width, height); \
  586. FIND_ONE (klas)
  587. #define MOVIE_ONE_END END_NO_NEW_DATA
  588. #define MOVIE_TWO(klas1,klas2,title,width,height) \
  589. Graphics graphics = Movie_create (title, width, height); \
  590. FIND_TWO (klas1, klas2)
  591. #define MOVIE_TWO_END END_NO_NEW_DATA
  592. #define MOVIE_THREE(klas1,klas2,klas3,title,width,height) \
  593. Graphics graphics = Movie_create (title, width, height); \
  594. FIND_THREE (klas1, klas2, klas3)
  595. #define MOVIE_THREE_END END_NO_NEW_DATA
  596. #define NUMBER_ONE(klas) FIND_ONE (klas)
  597. #define NUMBER_ONE_END(...) Melder_information (result, __VA_ARGS__); END_NO_NEW_DATA
  598. #define NUMBER_TWO(klas1,klas2) FIND_TWO (klas1, klas2)
  599. #define NUMBER_TWO_END(...) Melder_information (result, __VA_ARGS__); END_NO_NEW_DATA
  600. #define NUMBER_THREE(klas1,klas2,klas3) FIND_THREE (klas1, klas2, klas3)
  601. #define NUMBER_THREE_END(...) Melder_information (result, __VA_ARGS__); END_NO_NEW_DATA
  602. #define NUMBER_COUPLE(klas) FIND_COUPLE (klas)
  603. #define NUMBER_COUPLE_END(...) Melder_information (result, __VA_ARGS__); END_NO_NEW_DATA
  604. #define NUMBER_COUPLE_AND_ONE(klas1,klas2) FIND_COUPLE_AND_ONE (klas1, klas2)
  605. #define NUMBER_COUPLE_AND_ONE_END(...) Melder_information (result, __VA_ARGS__); END_NO_NEW_DATA
  606. #define NUMBER_ONE_AND_LIST(klas1,klas2) FIND_ONE_AND_LIST (klas1, klas2)
  607. #define NUMBER_ONE_AND_LIST_END(...) Melder_information (result, __VA_ARGS__); END_NO_NEW_DATA
  608. #define NUMBER_TWO_AND_LIST(klas1,klas2,klas3) FIND_TWO_AND_LIST (klas1, klas2, klas3)
  609. #define NUMBER_TWO_AND_LIST_END(...) Melder_information (result, __VA_ARGS__); END_NO_NEW_DATA
  610. #define INTEGER_ONE(klas) FIND_ONE (klas)
  611. #define INTEGER_ONE_END(...) Melder_information (result, __VA_ARGS__); END_NO_NEW_DATA
  612. #define STRING_ONE(klas) FIND_ONE (klas)
  613. #define STRING_ONE_END Melder_information (result); END_NO_NEW_DATA
  614. #define NUMVEC_ONE(klas) FIND_ONE (klas)
  615. #define NUMVEC_ONE_END if (interpreter) theInterpreterNumvec = result.move(); else Melder_information (constVEC (result.get())); END_NO_NEW_DATA
  616. #define NUMMAT_ONE(klas) FIND_ONE (klas)
  617. #define NUMMAT_ONE_END if (interpreter) theInterpreterNummat = result.move(); else Melder_information (constMAT (result.get())); END_NO_NEW_DATA
  618. #define MODIFY_EACH(klas) LOOP { iam_LOOP (klas);
  619. #define MODIFY_EACH_END praat_dataChanged (me); } END_NO_NEW_DATA
  620. #define MODIFY_EACH_WEAK(klas) LOOP { iam_LOOP (klas); try {
  621. #define MODIFY_EACH_WEAK_END praat_dataChanged (me); } catch (MelderError) { praat_dataChanged (me); throw; } } END_NO_NEW_DATA
  622. #define MODIFY_FIRST_OF_TWO(klas1,klas2) FIND_TWO (klas1, klas2)
  623. #define MODIFY_FIRST_OF_TWO_END praat_dataChanged (me); END_NO_NEW_DATA
  624. #define MODIFY_FIRST_OF_TWO_WEAK(klas1,klas2) FIND_TWO (klas1, klas2) try {
  625. #define MODIFY_FIRST_OF_TWO_WEAK_END praat_dataChanged (me); } catch (MelderError) { praat_dataChanged (me); throw; } END_NO_NEW_DATA
  626. #define MODIFY_FIRST_OF_THREE(klas1,klas2,klas3) FIND_THREE (klas1, klas2, klas3)
  627. #define MODIFY_FIRST_OF_THREE_END praat_dataChanged (me); END_NO_NEW_DATA
  628. #define MODIFY_FIRST_OF_ONE_AND_COUPLE(klas1,klas2) FIND_ONE_AND_COUPLE (klas1, klas2)
  629. #define MODIFY_FIRST_OF_ONE_AND_COUPLE_END praat_dataChanged (me); END_NO_NEW_DATA
  630. #define MODIFY_FIRST_OF_ONE_AND_COUPLE_WEAK(klas1,klas2) FIND_ONE_AND_COUPLE (klas1, klas2) try {
  631. #define MODIFY_FIRST_OF_ONE_AND_COUPLE_WEAK_END praat_dataChanged (me); } catch (MelderError) { praat_dataChanged (me); throw; } END_NO_NEW_DATA
  632. #define MODIFY_FIRST_OF_ONE_AND_LIST(klas1,klas2) FIND_ONE_AND_LIST (klas1, klas2)
  633. #define MODIFY_FIRST_OF_ONE_AND_LIST_END praat_dataChanged (me); END_NO_NEW_DATA
  634. #define CONVERT_EACH(klas) LOOP { iam_LOOP (klas);
  635. #define CONVERT_EACH_END(...) praat_new (result.move(), __VA_ARGS__); } END
  636. #define CONVERT_TWO(klas1,klas2) FIND_TWO (klas1, klas2)
  637. #define CONVERT_TWO_END(...) praat_new (result.move(), __VA_ARGS__); END
  638. #define CONVERT_COUPLE(klas) FIND_COUPLE (klas)
  639. #define CONVERT_COUPLE_END(...) praat_new (result.move(), __VA_ARGS__); END
  640. #define CONVERT_COUPLE_AND_ONE(klas1,klas2) FIND_COUPLE_AND_ONE (klas1,klas2)
  641. #define CONVERT_COUPLE_AND_ONE_END(...) praat_new (result.move(), __VA_ARGS__); END
  642. #define CONVERT_THREE(klas1,klas2,klas3) FIND_THREE (klas1, klas2, klas3)
  643. #define CONVERT_THREE_END(...) praat_new (result.move(), __VA_ARGS__); END
  644. #define CONVERT_FOUR(klas1,klas2,klas3,klas4) FIND_FOUR (klas1, klas2, klas3, klas4)
  645. #define CONVERT_FOUR_END(...) praat_new (result.move(), __VA_ARGS__); END
  646. #define CONVERT_LIST(klas) FIND_LIST (klas)
  647. #define CONVERT_LIST_END(...) praat_new (result.move(), __VA_ARGS__); END
  648. #define CONVERT_TYPED_LIST(klas,listClass) FIND_TYPED_LIST (klas,listClass)
  649. #define CONVERT_TYPED_LIST_END(...) praat_new (result.move(), __VA_ARGS__); END
  650. #define CONVERT_ONE_AND_LIST(klas1,klas2) FIND_ONE_AND_LIST (klas1, klas2)
  651. #define CONVERT_ONE_AND_LIST_END(...) praat_new (result.move(), __VA_ARGS__); END
  652. #define CONVERT_ONE_AND_TYPED_LIST(klas1,klas2,listClass) FIND_ONE_AND_TYPED_LIST (klas1, klas2, listClass)
  653. #define CONVERT_ONE_AND_TYPED_LIST_END(...) praat_new (result.move(), __VA_ARGS__); END
  654. #define READ_ONE
  655. #define READ_ONE_END praat_newWithFile (result.move(), file, MelderFile_name (file)); END
  656. #define SAVE_ONE(klas) FIND_ONE (klas)
  657. #define SAVE_ONE_END END_NO_NEW_DATA
  658. #define SAVE_LIST(klas) FIND_LIST (klas)
  659. #define SAVE_LIST_END END_NO_NEW_DATA
  660. #define SAVE_TYPED_LIST(klas,listClass) FIND_TYPED_LIST (klas, listClass)
  661. #define SAVE_TYPED_LIST_END END_NO_NEW_DATA
  662. /* Used by praat_Sybil.cpp, if you put an Editor on the screen: */
  663. int praat_installEditor (Editor editor, int iobject);
  664. /* This routine adds a reference to a new editor (unless it is null) to the screen object
  665. which is in the list at position 'iobject'.
  666. It sets the destroyCallback and dataChangedCallback as appropriate for Praat:
  667. the destroyCallback will set the now dangling reference to nullptr,
  668. so that a subsequent click on the "View & Edit" button will create a new editor;
  669. the dataChangedCallback will notify an open DataEditor with the same data,
  670. after that data will have changed.
  671. Return value: normally 1, but 0 if 'editor' is null.
  672. A typical calling sequence is:
  673. DIRECT (WINDOW_Spectrogram_viewAndEdit) {
  674. if (praat.batch) Melder_throw (U"Cannot view or edit a Spectrogram from batch.");
  675. else WHERE (SELECTED)
  676. praat_installEditor
  677. (SpectrogramEditor_create (praat.topShell, ID_AND_FULL_NAME, OBJECT), IOBJECT);
  678. END }
  679. */
  680. int praat_installEditor2 (Editor editor, int iobject1, int iobject2);
  681. int praat_installEditor3 (Editor editor, int iobject1, int iobject2, int iobject3);
  682. int praat_installEditorN (Editor editor, DaataList objects);
  683. void praat_dataChanged (Daata object);
  684. /* Call this after changing a screen object. */
  685. /* Associated editors and data editors will be notified (with Editor_dataChanged). */
  686. /* Used by praat.cpp, praat_Basic.cpp, and praat_Sybil.cpp; defined in praat_picture.cpp.
  687. */
  688. void praat_picture_open ();
  689. void praat_picture_close ();
  690. /* These two routines should bracket drawing commands. */
  691. /* However, they usually do so RAII-wise by being packed into autoPraatPicture (see GRAPHICS_EACH). */
  692. /* For main.cpp */
  693. #define INCLUDE_LIBRARY(praat_xxx_init) \
  694. { extern void praat_xxx_init (); praat_xxx_init (); }
  695. #define INCLUDE_MANPAGES(manual_xxx_init) \
  696. { extern void manual_xxx_init (ManPages me); manual_xxx_init (theCurrentPraatApplication -> manPages); }
  697. /* For text-only applications that do not want to see that irritating Picture window. */
  698. /* Works only if called before praat_init. */
  699. /* The program will crash if you still try to use drawing routines. */
  700. void praat_dontUsePictureWindow ();
  701. /* Before praat_init: */
  702. void praat_setLogo (double width_mm, double height_mm, void (*draw) (Graphics g));
  703. /* Removing objects from the list. */
  704. /* To remove the selected objects of class Klas from the list: */
  705. /*
  706. for (i = praat.n; i >= 1; i --) // Down!
  707. if (praat.list[i].selected && Thing_isa (praat.list[i].object, classKlas)
  708. praat_removeObject (i);
  709. praat_show (); // Needed because the selection has changed.
  710. */
  711. void praat_removeObject (int i); // i = 1..praat.n
  712. void praat_show (); // forces an update of the dynamic menu
  713. void praat_updateSelection ();
  714. /* If you require the correct selection immediately after calling praat_new. */
  715. void praat_addCommandsToEditor (Editor me);
  716. autoCollection praat_getSelectedObjects ();
  717. struct autoPraatPicture {
  718. autoPraatPicture () { praat_picture_open (); }
  719. ~autoPraatPicture () { praat_picture_close (); }
  720. };
  721. #if defined (_WIN32)
  722. #define main wingwmain
  723. #endif
  724. /* End of file praat.h */
  725. #endif