1 #ifndef _praat_h_
2 #define _praat_h_
3 /* praat.h
4  *
5  * Copyright (C) 1992-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 #include "Editor.h"
22 #include "Manual.h"
23 #include "Preferences.h"
24 
25 /* The explanations in this header file assume
26 	that you put your extra commands in praat_Sybil.cpp
27 	and the main() function in main_Sybil.cpp,
28 	but these files may have different names if you are not Sybil.
29 	Linking with the rest of Praat will create an executable
30 	that has all the functionality of the basic Praat,
31 	plus everything that you made available in praat_Sybil.cpp.
32 */
33 
34 /* Program example:
35 // File main_Sybil.cpp: //
36 int main (int argc, char **argv)
37 {
38 	praat_init (U"Praat_Sybil", argc, argv);   // Obligatory.
39 	INCLUDE_LIBRARY (praat_Fon_init)   // Optional: inherit phonetic stuff.
40 	INCLUDE_LIBRARY (praat_Sybil_init)   // Optional: add Sybil's things.
41 	INCLUDE_MANPAGES (manual_Sybil)
42 	praat_run ();   // Obligatory.
43 }
44 // File praat_Sybil.cpp: //
45 void praat_Sybil (void)
46 {
47 	...
48 	...
49 }
50 The dots consist of, in any order:
51 	Thing_recognizeClassesByName (...);
52 	Data_recognizeFileType (...);
53 	praat_addMenuCommand (...);
54 	praat_addAction1 (...);
55 All of these statements are optional and may occur more than once.
56 To make any class string-readable, use Thing_recognizeClassesByName ().
57 String-readable classes are known by Thing_newFromClassName () and can therefore
58 be read by Data_readFromTextFile () and Data_readFromBinaryFile ().
59 */
60 void praat_init (conststring32 title, int argc, char **argv);
61 void praat_run ();
62 void praat_setStandAloneScriptText (conststring32 text);   // call before praat_init if you want to create a stand-alone application without Objects and Picture window
63 extern "C" void praatlib_init ();   // for use in an application that uses Praatlib
64 
65 #define praat_addAction1(c1,n1,t,a,f,c)  praat_addAction1_ (c1, n1, t, a, f, c, U"" #c)
66 #define praat_addAction2(c1,n1,c2,n2,t,a,f,c)  praat_addAction2_ (c1, n1, c2, n2, t, a, f, c, U"" #c)
67 #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)
68 #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)
69 
70 void praat_addAction1_ (ClassInfo class1, integer n1,
71 	conststring32 title, conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
72 void praat_addAction2_ (ClassInfo class1, integer n1, ClassInfo class2, integer n2,
73 	conststring32 title, conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
74 void praat_addAction3_ (ClassInfo class1, integer n1, ClassInfo class2, integer n2, ClassInfo class3, integer n3,
75 	conststring32 title, conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
76 void praat_addAction4_ (ClassInfo class1, integer n1, ClassInfo class2, integer n2, ClassInfo class3, integer n3, ClassInfo class4, integer n4,
77 	conststring32 title, conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
78 /*
79 	'title' is the name that will appear in the dynamic menu,
80 		and also the command that is used in command files;
81 		this title is deep-copied.
82 	'callback' refers to a function prototyped like this:
83 		static void DO_Class_action (UiForm sendingForm, int narg, Stackel args, conststring32 sendingString,
84 				Interpreter interpreter, conststring32 invokingButtonTitle, bool modified, void *closure);
85 		this function should throw an exception if the command failed;
86 		this function will be called by 'praat' when the user clicks a menu command,
87 		in which case 'sendingForm', 'args' and 'sendingString' and 'closure' will be null;
88 		it is also called by scripts,
89 		in which case 'args[1..n]' or 'sendingString' is the argument list (after the dots).
90 		When called by Ui (after UiForm_create), 'sendingForm' is the UiForm, and 'closure'
91 		is the closure you passed to UiForm_create (which may be an editor).
92 
93 	The availability of the dynamic commands depends on
94 	the current selection: e.g., if the user has selected three objects
95 	of type Matrix and nothing else, the commands registered with
96 	praat_addAction1 (classMatrix, n, "xxx", "xxxx", x, DO_xxx) are visible,
97 	and those with n=0 or n=3 are executable (the buttons are sensitive)
98 	and, if chosen, performed on each of these three objects;
99 	if the user has selected one object of type Artword and one of type
100 	Speaker, the commands from praat_addAction2 (classArtword, 1, classSpeaker, 1, ...) are executable.
101 	You may want to restrict the availability to one object for commands that write objects to file,
102 	commands that present information in a dialog, or the View & Edit command.
103 */
104 #define praat_INSENSITIVE  GuiMenu_INSENSITIVE
105 #define praat_CHECKBUTTON  GuiMenu_CHECKBUTTON
106 #define praat_TOGGLE_ON  GuiMenu_TOGGLE_ON
107 #define praat_ATTRACTIVE  GuiMenu_ATTRACTIVE
108 #define praat_RADIO_FIRST  GuiMenu_RADIO_FIRST
109 #define praat_RADIO_NEXT  GuiMenu_RADIO_NEXT
110 #define praat_HIDDEN  0x0000'4000
111 #define praat_UNHIDABLE  0x0000'8000
112 #define praat_DEPTH_1  0x0001'0000
113 #define praat_DEPTH_2  0x0002'0000
114 #define praat_DEPTH_3  0x0003'0000
115 #define praat_DEPTH_4  0x0004'0000
116 #define praat_DEPTH_5  0x0005'0000
117 #define praat_DEPTH_6  0x0006'0000
118 #define praat_DEPTH_7  0x0007'0000
119 #define praat_NO_API  0x0008'0000
120 #define praat_FORCE_API  0x0010'0000
121 #define praat_DEPRECATED  (0x0020'0000 | praat_HIDDEN)
122 #define praat_DEPRECATED_2004  (0x0420'0000 | praat_HIDDEN)
123 #define praat_DEPRECATED_2005  (0x0520'0000 | praat_HIDDEN)
124 #define praat_DEPRECATED_2006  (0x0620'0000 | praat_HIDDEN)
125 #define praat_DEPRECATED_2007  (0x0720'0000 | praat_HIDDEN)
126 #define praat_DEPRECATED_2008  (0x0820'0000 | praat_HIDDEN)
127 #define praat_DEPRECATED_2009  (0x0920'0000 | praat_HIDDEN)
128 #define praat_DEPRECATED_2010  (0x0A20'0000 | praat_HIDDEN)
129 #define praat_DEPRECATED_2011  (0x0B20'0000 | praat_HIDDEN)
130 #define praat_DEPRECATED_2012  (0x0C20'0000 | praat_HIDDEN)
131 #define praat_DEPRECATED_2013  (0x0D20'0000 | praat_HIDDEN)
132 #define praat_DEPRECATED_2014  (0x0E20'0000 | praat_HIDDEN)
133 #define praat_DEPRECATED_2015  (0x0F20'0000 | praat_HIDDEN)
134 #define praat_DEPRECATED_2016  (0x1020'0000 | praat_HIDDEN)
135 #define praat_DEPRECATED_2017  (0x1120'0000 | praat_HIDDEN)
136 #define praat_DEPRECATED_2018  (0x1220'0000 | praat_HIDDEN)
137 #define praat_DEPRECATED_2019  (0x1320'0000 | praat_HIDDEN)
138 #define praat_DEPRECATED_2020  (0x1420'0000 | praat_HIDDEN)
139 #define praat_DEPRECATED_2021  (0x1520'0000 | praat_HIDDEN)
140 #define praat_DEPRECATED_2022  (0x1620'0000 | praat_HIDDEN)
141 #define praat_DEPRECATED_2023  (0x1720'0000 | praat_HIDDEN)
142 #define praat_DEPRECATED_2024  (0x1820'0000 | praat_HIDDEN)
143 /*
144 	The following three can also be used, but not for deprecated commands.
145 */
146 //#define GuiMenu_OPTION  (1 << 24)
147 //#define GuiMenu_SHIFT  (1 << 25)
148 //#define GuiMenu_COMMAND  (1 << 26)
149 void praat_removeAction (ClassInfo class1, ClassInfo class2, ClassInfo class3, conststring32 title);
150 	/* 'class2' and 'class3' may be null. */
151 	/* 'title' may be null; reference-copied. */
152 
153 #define praat_addMenuCommand(w,m,t,a,f,c)  praat_addMenuCommand_ (w, m, t, a, f, c, U"" #c)
154 GuiMenuItem praat_addMenuCommand_ (conststring32 window, conststring32 menu, conststring32 title /* cattable */,
155 	conststring32 after, uint32 flags, UiCallback callback, conststring32 nameOfCallback);
156 /* All strings are reference-copied; 'title', 'after', and 'callback' may be null. */
157 
158 #define praat_MAXNUM_EDITORS 5
159 #include "Ui.h"
160 typedef struct {
161 	ClassInfo klas;   // the class
162 	Daata object;   // the instance
163 	autostring32 name;   // the name of the object as it appears in the List
164 	structMelderFile file;   // is this Object associated with a file?
165 	integer id;   // the unique number of the object
166 	bool isSelected;   // is the name of the object inverted in the list?
167 	Editor editors [praat_MAXNUM_EDITORS];   // are there editors open with this Object in it?
168 	bool isBeingCreated;
169 } structPraat_Object, *praat_Object;
170 
171 #define praat_MAXNUM_OBJECTS 10000   /* Maximum number of objects in the list. */
172 typedef struct {   /* Readonly */
173 	MelderString batchName;   /* The name of the command file when called from batch. */
174 	int batch;   /* Was the program called from the command line? */
175 	GuiWindow topShell;   /* The application shell: parent of standard dialogs. */
176 	ManPages manPages;
177 } structPraatApplication, *PraatApplication;
178 typedef struct {   /* Readonly */
179 	integer n;	 /* The current number of objects in the list. */
180 	structPraat_Object list [1 + praat_MAXNUM_OBJECTS];   /* The list of objects: list [1..n]. */
181 	integer totalSelection;   /* The total number of selected objects, <= n. */
182 	integer numberOfSelected [1 + 1000];   /* For each (readable) class. */
183 	integer totalBeingCreated;
184 	integer uniqueId;
185 } structPraatObjects, *PraatObjects;
186 typedef struct {   // read-only
187 	Graphics graphics;   // the Graphics associated with the Picture window
188 	kGraphics_font font;
189 	int lineType;
190 	double fontSize;
191 	MelderColour colour;
192 	double lineWidth, arrowSize, speckleSize, x1NDC, x2NDC, y1NDC, y2NDC;
193 } structPraatPicture, *PraatPicture;
194 /*
195 	The following six cannot be "inline",
196 	because that would cost 42 MB (per architecture)
197 	on the Mac or on Windows (though nothing on Linux),
198 	i.e. a full copy of all three structures.
199 	(ppgb 2021-04-15)
200 */
201 extern structPraatApplication theForegroundPraatApplication;
202 extern PraatApplication theCurrentPraatApplication;
203 extern structPraatObjects theForegroundPraatObjects;
204 extern PraatObjects theCurrentPraatObjects;
205 extern structPraatPicture theForegroundPraatPicture;
206 extern PraatPicture theCurrentPraatPicture;
207 	/* The global objects containing the state of the application; only reachable from interface files. */
208 
209 char32 *praat_name (integer iobject);
210 void praat_write_do (UiForm dia, conststring32 extension);
211 void praat_new (autoDaata me);
212 void praat_new (autoDaata me, const MelderArg& arg);
213 void praat_new (autoDaata me, const MelderArg& arg1, const MelderArg& arg2,
214 	const MelderArg& arg3 = U"", const MelderArg& arg4 = U"", const MelderArg& arg5 = U"");
215 void praat_newWithFile (autoDaata me, MelderFile file, conststring32 name);
216 void praat_name2 (char32 *name, ClassInfo klas1, ClassInfo klas2);
217 
218 #define iam_LOOP(klas)  klas me = static_cast<klas> (OBJECT)
219 #define WHERE(condition)  for (IOBJECT = 1; IOBJECT <= theCurrentPraatObjects -> n; IOBJECT ++) if (condition)
220 #define WHERE_DOWN(condition)  for (IOBJECT = theCurrentPraatObjects -> n; IOBJECT > 0; IOBJECT --) if (condition)
221 #define SELECTED  (theCurrentPraatObjects -> list [IOBJECT]. isSelected)
222 #define LOOP  for (IOBJECT = 1; IOBJECT <= theCurrentPraatObjects -> n; IOBJECT ++) if (SELECTED)
223 #define CLASS  (theCurrentPraatObjects -> list [IOBJECT]. klas)
224 #define OBJECT  (theCurrentPraatObjects -> list [IOBJECT]. object)
225 #define GRAPHICS  theCurrentPraatPicture -> graphics
226 #define FULL_NAME  (theCurrentPraatObjects -> list [IOBJECT]. name.get())
227 #define ID  (theCurrentPraatObjects -> list [IOBJECT]. id)
228 #define ID_AND_FULL_NAME  Melder_cat (ID, U". ", FULL_NAME)
229 #define NAME  praat_name (IOBJECT)
230 
231 /* Used by praat_Sybil.cpp, if you put an Editor on the screen: */
232 void praat_installEditor (Editor editor, integer iobject);
233 /* This routine adds a reference to a new editor (unless it is null) to the screen object
234    which is in the list at position 'iobject'.
235    It sets the destroyCallback and dataChangedCallback as appropriate for Praat:
236    the destroyCallback will set the now dangling reference to nullptr,
237    so that a subsequent click on the "View & Edit" button will create a new editor;
238    the dataChangedCallback will notify an open DataEditor with the same data,
239    after that data will have changed.
240 */
241 void praat_installEditor2 (Editor editor, integer iobject1, integer iobject2);
242 void praat_installEditor3 (Editor editor, integer iobject1, integer iobject2, integer iobject3);
243 void praat_installEditorN (Editor editor, DaataList objects);
244 
245 void praat_dataChanged (Daata object);
246 /* Call this after changing a screen object. */
247 /* Associated editors and data editors will be notified (with Editor_dataChanged). */
248 
249 /* Used by praat.cpp, praat_Basic.cpp, and praat_Sybil.cpp; defined in praat_picture.cpp.
250 */
251 void praat_picture_open ();
252 void praat_picture_close ();
253 /* These two routines should bracket drawing commands. */
254 /* However, they usually do so RAII-wise by being packed into autoPraatPicture (see GRAPHICS_EACH). */
255 
256 /* For main.cpp */
257 
258 #define INCLUDE_LIBRARY(praat_xxx_init)  \
259    { extern void praat_xxx_init (); praat_xxx_init (); }
260 #define INCLUDE_MANPAGES(manual_xxx_init)  \
261    { extern void manual_xxx_init (ManPages me); manual_xxx_init (theCurrentPraatApplication -> manPages); }
262 
263 /* For text-only applications that do not want to see that irritating Picture window. */
264 /* Works only if called before praat_init. */
265 /* The program will crash if you still try to use drawing routines. */
266 void praat_dontUsePictureWindow ();
267 
268 /* Before praat_init: */
269 void praat_setLogo (double width_mm, double height_mm, void (*draw) (Graphics g));
270 
271 /* Removing objects from the list. */
272 /* To remove the selected objects of class Klas from the list: */
273 /*
274 	for (i = praat.n; i >= 1; i --)   // Down!
275 		if (praat.list[i].selected && Thing_isa (praat.list[i].object, classKlas)
276 			praat_removeObject (i);
277 	praat_show ();   // Needed because the selection has changed.
278 */
279 void praat_removeObject (integer i);   // i = 1..praat.n
280 void praat_show ();   // forces an update of the dynamic menu
281 void praat_updateSelection ();
282 	/* If you require the correct selection immediately after calling praat_new. */
283 
284 void praat_addCommandsToEditor (Editor me);
285 
286 autoCollection praat_getSelectedObjects ();
287 
288 struct autoPraatPicture {
autoPraatPictureautoPraatPicture289 	autoPraatPicture () { praat_picture_open (); }
290 	~autoPraatPicture () { praat_picture_close (); }
291 };
292 
293 #if defined (_WIN32)
294 	#define main wingwmain
295 #endif
296 
297 /* End of file praat.h */
298 #endif
299